### Build Bitswap Transfer Example Source: https://github.com/ipfs/boxo/blob/main/examples/bitswap-transfer/README.md Navigate to the example directory and build the Go program. ```bash > cd bitswap-transfer/ > go build ``` -------------------------------- ### Install go-ipfs-posinfo Source: https://github.com/ipfs/boxo/blob/main/filestore/posinfo/README.md Use this command to get the go-ipfs-posinfo library. Ensure you have a Go environment set up. ```bash go get github.com/ipfs/go-ipfs-posinfo ``` -------------------------------- ### Start a Basic IPFS Gateway Source: https://github.com/ipfs/boxo/blob/main/gateway/README.md Demonstrates how to initialize and start a basic IPFS gateway server. Requires an IPFSBackend implementation. ```go conf := gateway.Config{} // Initialize an IPFSBackend interface for both an online and offline versions. // The offline version should not make any network request for missing content. ipfsBackend := ... // Create http mux and setup path gateway handler. mux := http.NewServeMux() handler := gateway.NewHandler(conf, ipfsBackend) handler = gateway.NewHeaders(nil).ApplyCors().Wrap(handler) mux.Handle("/ipfs/", handler) mux.Handle("/ipns/", handler) // Start the server on :8080 and voilá! You have a basic IPFS gateway running // in http://localhost:8080. _ = http.ListenAndServe(":8080", mux) ``` -------------------------------- ### Install Go Dependencies Source: https://github.com/ipfs/boxo/blob/main/pinning/remote/client/openapi/README.md Install necessary dependencies for the Go client. Ensure these are available in your project. ```shell go get github.com/stretchr/testify/assert go get golang.org/x/oauth2 go get golang.org/x/net/context ``` -------------------------------- ### Run Bitswap Transfer Server Source: https://github.com/ipfs/boxo/blob/main/examples/bitswap-transfer/README.md Start the Bitswap transfer example in server mode to host a UnixFS file. The output will provide the Multiaddress and Peer ID for clients to connect. ```bash > ./bitswap-transfer 2023/01/30 21:34:11 I am /ip4/127.0.0.1/tcp/53935/p2p/QmUtp8xEVgWC5dNPthF2g37eVvCdrqY1FPxLxXZoKkPbdp 2023/01/30 21:34:11 hosting UnixFS file with CID: bafybeiecq2irw4fl5vunnxo6cegoutv4de63h7n27tekkjtak3jrvrzzhe 2023/01/30 21:34:11 listening for inbound connections and Bitswap requests 2023/01/30 21:34:11 Now run "./bitswap-transfer -d /ip4/127.0.0.1/tcp/53935/p2p/QmUtp8xEVgWC5dNPthF2g37eVvCdrqY1FPxLxXZoKkPbdp" on a different terminal ``` -------------------------------- ### Start the Gateway with a CAR File Source: https://github.com/ipfs/boxo/blob/main/examples/gateway/car-file/README.md Launch the gateway executable, specifying the CAR file to use and the port to listen on. ```bash ./gateway -c data.car -p 8040 ``` -------------------------------- ### Build the Delegated Routing Client Source: https://github.com/ipfs/boxo/blob/main/examples/routing/delegated-routing-client/README.md Compile the Go project to create the command-line executable. Ensure you have Go installed and the source code is available. ```bash > go build -o delegated-routing-client ``` -------------------------------- ### Initialize Autoconf Client and Get Configuration Source: https://github.com/ipfs/boxo/blob/main/autoconf/README.md Demonstrates how to create a new autoconf client with custom options and retrieve configuration. Use this for applications needing immediate access to configuration. ```go func main() { client, err := autoconf.NewClient( autoconf.WithCacheDir("/app/data/autoconf"), autoconf.WithUserAgent("myapp/1.2.3"), autoconf.WithTimeout(autoconf.DefaultTimeout), ) if err != nil { // handle } // Use turn-key solution with refresh - never fails, always returns usable config config := client.MustGetConfigWithRefresh(context.Background(), autoconfURL, autoconf.DefaultRefreshInterval, autoconf.GetMainnetFallbackConfig) // Access all config types nativelySupported := []string{"AminoDHT"} // Systems your node runs locally (natively) bootstrapPeers := config.GetBootstrapPeers(nativelySupported...) // Bootstrap every native system delegatedEndpoints := config.GetDelegatedEndpoints(nativelySupported...) dnsResolvers := config.GetDNSResolvers() fmt.Printf("Bootstrap peers: %v\n", bootstrapPeers) fmt.Printf("Delegated endpoints: %v\n", delegatedEndpoints) fmt.Printf("DNS resolvers: %v\n", dnsResolvers) } ``` -------------------------------- ### Initialize and Manage IPFS Peering Service Source: https://context7.com/ipfs/boxo/llms.txt Sets up a service to maintain persistent connections to specified peers. Add peers using `AddPeer` and start the service with `Start`. Ensure the libp2p host is properly initialized. ```go import ( "fmt" "github.com/ipfs/boxo/peering" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" ) h, _ := libp2p.New() deferr h.Close() ps := peering.NewPeeringService(h) // Add peers to maintain persistent connections to addr, _ := multiaddr.NewMultiaddr("/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ") info, _ := peer.AddrInfoFromP2pAddr(addr) ps.AddPeer(*info) // Start the peering service (connects immediately and reconnects on disconnect) if err := ps.Start(); err != nil { panic(err) } deferr ps.Stop() fmt.Println("peering service state:", ps.State()) // "running" // The service will automatically reconnect with exponential back-off (up to 10 min) ``` -------------------------------- ### Start IPFS Daemon with OTLP Exporter Source: https://github.com/ipfs/boxo/blob/main/docs/tracing.md Initializes and starts an IPFS daemon configured to send traces to a Jaeger collector using the OTLP exporter. Ensure the Jaeger container is running and accessible. ```console $ OTEL_EXPORTER_OTLP_INSECURE=true OTEL_TRACES_EXPORTER=otlp ipfs daemon --init ``` -------------------------------- ### Modify go.mod for Boxo Examples Source: https://github.com/ipfs/boxo/blob/main/examples/README.md To use Boxo examples in your own product, remove the local replacement directive from go.mod and update to the latest Boxo version. ```bash > go mod edit -dropreplace=github.com/ipfs/boxo > go get github.com/ipfs/boxo@latest > go mod tidy ``` -------------------------------- ### Run Bitswap Transfer Client Source: https://github.com/ipfs/boxo/blob/main/examples/bitswap-transfer/README.md Execute the Bitswap transfer example in client mode, providing the Multiaddress of the server to download the UnixFS file. ```bash > ./bitswap-transfer -d /ip4/127.0.0.1/tcp/53935/p2p/QmUtp8xEVgWC5dNPthF2g37eVvCdrqY1FPxLxXZoKkPbdp ``` -------------------------------- ### Blockstore Operations Source: https://context7.com/ipfs/boxo/llms.txt Demonstrates how to create and use a blockstore for storing and retrieving IPFS blocks. It covers initialization, putting, getting, checking for existence, and enumerating all keys. ```APIDOC ## Blockstore Operations ### Description This section details the usage of the `blockstore` package for managing content-addressed block storage. It shows how to initialize a blockstore, store blocks using `Put`, retrieve them with `Get`, check for their presence using `Has`, and list all stored keys via `AllKeysChan`. ### Usage Example ```go import ( "context" "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-datastore" dsync "github.com/ipfs/go-datastore/sync" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ) ctx := context.Background() // Create an in-memory thread-safe datastore ds := dsync.MutexWrap(datastore.NewMapDatastore()) // Create the blockstore; keys are namespaced under /blocks bs := blockstore.NewBlockstore(ds) // Wrap with identity CID support (no actual storage needed for identity CIDs) bs = blockstore.NewIdStore(bs) // Store a block rawData := []byte("hello IPFS") blk, _ := blocks.NewBlockWithCid(rawData, cid.NewCidV1(cid.Raw, mustSum(rawData))) _ = bs.Put(ctx, blk) // Retrieve a block retrieved, err := bs.Get(ctx, blk.Cid()) if err != nil { panic(err) } fmt.Println(string(retrieved.RawData())) // "hello IPFS" // Check existence has, _ := bs.Has(ctx, blk.Cid()) fmt.Println(has) // true // Enumerate all CIDs ch, _ := bs.AllKeysChan(ctx) for c := range ch { fmt.Println(c) } ``` ``` -------------------------------- ### Run Jaeger All-in-One Docker Image Source: https://github.com/ipfs/boxo/blob/main/docs/tracing.md Starts a Jaeger all-in-one Docker container with OTLP enabled. This is useful for local development and testing of tracing configurations. ```console $ docker run -d --rm --name jaeger \ -e COLLECTOR_OTLP_ENABLED=true \ -p 5775:5775/udp \ -p 6831:6831/udp \ -p 6832:6832/udp \ -p 5778:5778 \ -p 16686:16686 \ -p 14250:14250 \ -p 14268:14268 \ -p 14269:14269 \ -p 4317:4317 \ -p 4318:4318 \ -p 9411:9411 \ jaegertracing/all-in-one ``` -------------------------------- ### Create and Interact with IPFS Merkle DAG Service Source: https://context7.com/ipfs/boxo/llms.txt Demonstrates creating a DAGService, adding nodes, retrieving them, linking nodes, and walking the DAG. Requires blockstore and blockservice setup. ```go import ( "context" "github.com/ipfs/boxo/blockservice" "github.com/ipfs/boxo/blockstore" "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/go-datastore" dsync "github.com/ipfs/go-datastore/sync" ipldformat "github.com/ipfs/go-ipld-format" ) ctx := context.Background() ds := dsync.MutexWrap(datastore.NewMapDatastore()) bs := blockstore.NewBlockstore(ds) b বৃত্ত := blockservice.New(bs, offline.Exchange(bs)) dagSvc := merkledag.NewDAGService(bsvc) // Create a new ProtoNode with some data nd := merkledag.NewRawNode([]byte("hello dag")) _ = dagSvc.Add(ctx, nd) fmt.Println("stored CID:", nd.Cid()) // Retrieve the node retrieved, err := dagSvc.Get(ctx, nd.Cid()) if err != nil { panic(err) } fmt.Println("data:", string(retrieved.RawData())) // "hello dag" // Link two nodes together parent := &merkledag.ProtoNode{} _ = parent.AddNodeLink("child", nd) _ = dagSvc.Add(ctx, parent) // Use a DAG session for efficient batch fetching (reuses session internally) sesGetter := merkledag.NewSession(ctx, dagSvc) child, err := sesGetter.Get(ctx, nd.Cid()) if err != nil { panic(err) } _ = child // Walk all nodes in a DAG _ = ipldformat.Walk(ctx, dagSvc, parent.Cid(), func(nd ipldformat.Node) ([]*ipldformat.Link, error) { fmt.Println("visiting:", nd.Cid()) return nd.Links(), nil }) ``` -------------------------------- ### Configure OpenTelemetry Trace Exporters in Go Source: https://context7.com/ipfs/boxo/llms.txt Reads OTEL_TRACES_EXPORTER and related environment variables to set up OpenTelemetry trace exporters. Supported exporters include otlp, stdout, file, and none. This example uses stdout for demonstration. ```go import ( "context" "fmt" "os" "github.com/ipfs/boxo/tracing" "go.opentelemetry.io/otel/sdk/trace" ) ctx := context.Background() // Configure via environment (set before calling): // OTEL_TRACES_EXPORTER=otlp // OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf // OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 os.Setenv("OTEL_TRACES_EXPORTER", "stdout") // use stdout for this example exporters, err := tracing.NewSpanExporters(ctx) if err != nil { panic(err) } // Wire exporters into the OpenTelemetry SDK var spanProcessors []trace.SpanProcessor for _, exporter := range exporters { spanProcessors = append(spanProcessors, trace.NewBatchSpanProcessor(exporter)) } tp := trace.NewTracerProvider( trace.WithSampler(trace.AlwaysSample()), ) for _, sp := range spanProcessors { tp.RegisterSpanProcessor(sp) } // Use the tracer tracer := tp.Tracer("myapp") _, span := tracer.Start(ctx, "my-operation") span.End() fmt.Println("trace exported") // Shutdown cleanly defer tp.Shutdown(ctx) ``` -------------------------------- ### Access DNSLink Website via Gateway Source: https://github.com/ipfs/boxo/blob/main/examples/gateway/proxy-blocks/README.md Fetch a DNSLink website by setting the 'Host' header to the FQDN with DNSLink configured. This example shows fetching the Wikipedia homepage. ```bash $ curl -sH 'Host: en.wikipedia-on-ipfs.org' 'http://127.0.0.1:8080/wiki/' | head -3 Wikipedia, the free encyclopedia ``` -------------------------------- ### Autoconf Background Updates with Explicit Stop() Source: https://github.com/ipfs/boxo/blob/main/autoconf/README.md Provides manual control over the background updater lifecycle. Use this pattern when explicit control over starting and stopping the updater is required. ```go func main() { client, err := autoconf.NewClient( autoconf.WithCacheDir("/app/data/autoconf"), autoconf.WithUserAgent("myapp/1.2.3"), ) if err != nil { log.Fatal(err) } // Start with background context since we'll use Stop() config, err := client.Start(context.Background()) if err != nil { log.Fatal(err) } // Ensure clean shutdown defer client.Stop() // Set up signal handling sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) // Your application logic here... <-sigCh // Stop() will be called by defer, ensuring graceful shutdown } ``` -------------------------------- ### Generate Go Client for Pinning Services API Source: https://github.com/ipfs/boxo/blob/main/pinning/remote/client/README.md Use this command to generate the Go client code. Ensure you have openapi-generator installed. The generated code may require manual editing for HTTP error codes. ```bash openapi-generator generate -g go-experimental -i https://raw.githubusercontent.com/ipfs/pinning-services-api-spec/master/ipfs-pinning-service.yaml -o openapi rm openapi/go.mod openapi/go.sum ``` -------------------------------- ### gateway.NewBlocksBackend Source: https://context7.com/ipfs/boxo/llms.txt Creates a standard IPFS gateway backend that reads blocks from a blockservice and serves files and directories using the IPLD/UnixFS stack. It supports various gateway methods like Get, Head, GetCAR, ResolvePath, and IPNS/DNSLink record resolution. ```APIDOC ## gateway.NewBlocksBackend ### Description Creates a standard IPFS gateway backend that reads blocks from a blockservice and serves files and directories using the IPLD/UnixFS stack. It implements all gateway backend methods: `Get`, `GetAll`, `GetBlock`, `Head`, `GetCAR`, `ResolvePath`, `ResolveMutable`, `GetIPNSRecord`, and `GetDNSLinkRecord`. ### Usage ```go import ( "github.com/ipfs/boxo/blockservice" "github.com/ipfs/boxo/gateway" "github.com/ipfs/boxo/namesys" "github.com/libp2p/go-libp2p/core/routing" ) bsc := mustMakeBlockService() // blockservice backed by Bitswap vs := mustMakeValueStore() // routing.ValueStore (DHT) ns, _ := namesys.NewNameSystem(vs, namesys.WithCache(128)) backend, err := gateway.NewBlocksBackend(bsvc, gateway.WithNameSystem(ns), // enables /ipns/ path resolution ) if err != nil { panic(err) } // backend satisfies the full gateway.IPFSBackend interface: // - GET /ipfs/ -> backend.Get(ctx, path.ImmutablePath{...}) // - GET /ipns/ -> backend.ResolveMutable then backend.Get // - GET /ipfs/?format=car -> backend.GetCAR(ctx, path, CarParams{Scope: DagScopeAll}) ``` ``` -------------------------------- ### Create and Use a Blockstore in Go Source: https://context7.com/ipfs/boxo/llms.txt Demonstrates creating an in-memory thread-safe datastore, initializing a blockstore, storing, retrieving, and enumerating blocks. Use this for local block storage and retrieval. ```go import ( "context" "fmt" "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-datastore" dsync "github.com/ipfs/go-datastore/sync" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ) ctx := context.Background() // Create an in-memory thread-safe datastore ds := dsync.MutexWrap(datastore.NewMapDatastore()) // Create the blockstore; keys are namespaced under /blocks bs := blockstore.NewBlockstore(ds) // Wrap with identity CID support (no actual storage needed for identity CIDs) bs = blockstore.NewIdStore(bs) // Store a block rawData := []byte("hello IPFS") blk, _ := blocks.NewBlockWithCid(rawData, cid.NewCidV1(cid.Raw, mustSum(rawData))) _ = bs.Put(ctx, blk) // Retrieve a block retrieved, err := bs.Get(ctx, blk.Cid()) if err != nil { panic(err) } fmt.Println(string(retrieved.RawData())) // "hello IPFS" // Check existence has, _ := bs.Has(ctx, blk.Cid()) fmt.Println(has) // true // Enumerate all CIDs ch, _ := bs.AllKeysChan(ctx) for c := range ch { fmt.Println(c) } ``` -------------------------------- ### Get Pin Source: https://github.com/ipfs/boxo/blob/main/pinning/remote/client/openapi/README.md Retrieves the details of a specific pin object using its request ID. ```APIDOC ## GET /pins/{requestid} ### Description Get pin object. ### Method GET ### Endpoint /pins/{requestid} ### Parameters #### Path Parameters - **requestid** (string) - Required - The unique identifier of the pin to retrieve. ### Response #### Success Response (200) - **id** (string) - The unique identifier for the pin. - **cid** (string) - The IPFS Content Identifier (CID) that is pinned. - **name** (string) - The name of the pin. - **status** (string) - The status of the pin (e.g., Pinned, Pinning, Failed). - **created_date** (string) - The date and time when the pin was created. ``` -------------------------------- ### Build the Gateway Source: https://github.com/ipfs/boxo/blob/main/examples/gateway/car-file/README.md Compile the Go project to create an executable binary for the gateway. ```bash > go build -o gateway ``` -------------------------------- ### Create Default Autoconf Client Source: https://github.com/ipfs/boxo/blob/main/autoconf/README.md Use this method for a turn-key solution with default options, including mainnet URL and fallback mechanisms. It ensures graceful fallbacks and never fails. ```go import "github.com/ipfs/boxo/autoconf" // Create a client with default options (uses mainnet URL and fallback) client, err := autoconf.NewClient() if err != nil { // handle } // Cache-first approach: use cached config, no network requests config := client.GetCached() // Use the config data nativelySupported := []string{"AminoDHT"} // Systems your node runs locally (natively) bootstrapPeers := config.GetBootstrapPeers(nativelySupported...) // Bootstrap every native system delegatedEndpoints := config.GetDelegatedEndpoints(nativelySupported...) // Excludes native systems dnsResolvers := config.GetDNSResolvers() fmt.Printf("Bootstrap peers: %v\n", bootstrapPeers) fmt.Printf("Delegated endpoints: %v\n", delegatedEndpoints) fmt.Printf("DNS resolvers: %v\n", dnsResolvers) ``` -------------------------------- ### Pin Getters and Setters Source: https://github.com/ipfs/boxo/blob/main/pinning/remote/client/openapi/docs/Pin.md Provides methods to get and set the properties of a Pin object. ```APIDOC ## Pin Getters and Setters ### GetCid `func (o *Pin) GetCid() string` Returns the Cid field if non-nil, zero value otherwise. ### GetCidOk `func (o *Pin) GetCidOk() (*string, bool)` Returns a tuple with the Cid field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetCid `func (o *Pin) SetCid(v string)` Sets the Cid field to the given value. ### GetName `func (o *Pin) GetName() string` Returns the Name field if non-nil, zero value otherwise. ### GetNameOk `func (o *Pin) GetNameOk() (*string, bool)` Returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName `func (o *Pin) SetName(v string)` Sets the Name field to the given value. ### HasName `func (o *Pin) HasName() bool` Returns a boolean if the Name field has been set. ### GetOrigins `func (o *Pin) GetOrigins() []string` Returns the Origins field if non-nil, zero value otherwise. ### GetOriginsOk `func (o *Pin) GetOriginsOk() (*[]string, bool)` Returns a tuple with the Origins field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetOrigins `func (o *Pin) SetOrigins(v []string)` Sets the Origins field to the given value. ### HasOrigins `func (o *Pin) HasOrigins() bool` Returns a boolean if the Origins field has been set. ### GetMeta `func (o *Pin) GetMeta() map[string]string` Returns the Meta field if non-nil, zero value otherwise. ### GetMetaOk `func (o *Pin) GetMetaOk() (*map[string]string, bool)` Returns a tuple with the Meta field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetMeta `func (o *Pin) SetMeta(v map[string]string)` Sets the Meta field to the given value. ### HasMeta `func (o *Pin) HasMeta() bool` Returns a boolean if the Meta field has been set. ``` -------------------------------- ### Get A Block Synchronously Source: https://github.com/ipfs/boxo/blob/main/bitswap/README.md Retrieves a single block synchronously using its Content Identifier (CID). ```APIDOC ## Get A Block Synchronously ### Description Retrieves a single block synchronously from the network. ### Method `GetBlock` ### Parameters #### Context - `ctx` (context.Context) - The context for this request, which can be canceled to cancel the request. #### Content Identifier - `c` (cid.Cid) - The content ID of the block you're requesting. ### Response #### Success Response - `block` (*blocks.Block) - The requested block. - `err` (error) - An error if the block could not be retrieved. ### Code Example ```golang var c cid.Cid var ctx context.Context var exchange bitswap.Bitswap block, err := exchange.GetBlock(ctx, c) ``` ``` -------------------------------- ### Create and Use a Blockservice in Go Source: https://context7.com/ipfs/boxo/llms.txt Shows how to create a BlockService that retrieves blocks from a local blockstore or a remote exchange. It also demonstrates batch retrieval using sessions for efficiency. Use this for hybrid local/remote block retrieval. ```go import ( "context" "fmt" "github.com/ipfs/boxo/blockservice" "github.com/ipfs/boxo/blockstore" "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/go-datastore" dsync "github.com/ipfs/go-datastore/sync" "github.com/ipfs/go-cid" ) ctx := context.Background() ds := dsync.MutexWrap(datastore.NewMapDatastore()) bs := blockstore.NewBlockstore(ds) // Offline mode: only serves blocks that are already in the blockstore exch := offline.Exchange(bs) bsvc := blockservice.New(bs, exch) defer bsvc.Close() // Add a block blk := mustMakeBlock([]byte("block data")) _ = bsvc.AddBlock(ctx, blk) // Retrieve a block – checks local store first, then exchange retrieved, err := bsvc.GetBlock(ctx, blk.Cid()) if err != nil { panic(err) } fmt.Println(string(retrieved.RawData())) // "block data" // Batch retrieval via a session (shares want-list coalescing) ses := blockservice.NewSession(ctx, bsvc) cids := []cid.Cid{blk.Cid()} ch := ses.GetBlocks(ctx, cids) for b := range ch { fmt.Printf("got block %s\n", b.Cid()) } // Embed a session into a context so sub-calls reuse the same session sessCtx := blockservice.ContextWithSession(ctx, bsvc) b2, _ := bsvc.GetBlock(sessCtx, blk.Cid()) // reuses the embedded session _ = b2 ``` -------------------------------- ### Initialize and Use IPFS Content Provider System Source: https://context7.com/ipfs/boxo/llms.txt Creates a provider system for managing CIDs to announce to the IPFS network. Use `provider.Online` to integrate with a content router. Configure reprovide intervals and worker counts as needed. ```go import ( "context" "github.com/ipfs/boxo/provider" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" dsync "github.com/ipfs/go-datastore/sync" ) ctx := context.Background() dataStore := dsync.MutexWrap(datastore.NewMapDatastore()) // router implements provider.Provide (and optionally provider.ProvideMany) router := mustMakeContentRouter() sys, err := provider.New(dataStore, provider.Online(router), provider.ReprovideInterval(0), // 0 = no automatic reprovide; use DefaultReproviderInterval (22h) for production provider.WorkerCount(32), ) if err != nil { panic(err) } deferr sys.Close() // Announce a newly added CID immediately c, _ := cid.Parse("bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi") if err := sys.Provide(ctx, c, true); err != nil { fmt.Println("provide error:", err) } // Set the function that lists all CIDs for periodic reprovide sys.SetKeyProvider(func(ctx context.Context) (<-chan cid.Cid, error) { ch := make(chan cid.Cid, 1) go func() { ch <- c close(ch) }() return ch, nil }) // Trigger a manual reprovide cycle if err := sys.Reprovide(ctx); err != nil { fmt.Println("reprovide error:", err) } stat, _ := sys.Stat() fmt.Printf("total reprovides: %d, avg duration: %s\n", stat.TotalReprovides, stat.AvgReprovideDuration) ``` -------------------------------- ### Get Several Blocks Asynchronously Source: https://github.com/ipfs/boxo/blob/main/bitswap/README.md Retrieves multiple blocks asynchronously using a slice of Content Identifiers (CIDs). ```APIDOC ## Get Several Blocks Asynchronously ### Description Retrieves multiple blocks asynchronously from the network. ### Method `GetBlocks` ### Parameters #### Context - `ctx` (context.Context) - The context for this request, which can be canceled to cancel the request. #### Content Identifiers - `cids` ([]cid.Cid) - A slice of content IDs for the blocks you're requesting. ### Response #### Success Response - `blockChannel` (<-chan *blocks.Block) - A channel that yields the requested blocks. - `err` (error) - An error if the retrieval process could not be initiated. ### Code Example ```golang var cids []cid.Cid var ctx context.Context var exchange bitswap.Bitswap blockChannel, err := exchange.GetBlocks(ctx, cids) ``` ``` -------------------------------- ### Get A Block Synchronously Source: https://github.com/ipfs/boxo/blob/main/bitswap/README.md Retrieves a single block synchronously using its CID. The request can be canceled via the context. ```golang var c cid.Cid var ctx context.Context var exchange bitswap.Bitswap block, err := exchange.GetBlock(ctx, c) ``` -------------------------------- ### Build the CAR File Fetcher Source: https://github.com/ipfs/boxo/blob/main/examples/car-file-fetcher/README.md Compile the Go project to create the executable binary for the CAR file fetcher. ```bash > go build -o fetcher ``` -------------------------------- ### Create and Use Bitswap Client/Server Source: https://context7.com/ipfs/boxo/llms.txt Initializes a combined Bitswap client and server. Requires a libp2p host, blockstore, and optionally content discovery. Used for fetching and serving blocks over the network. ```go import ( "context" bsnet "github.com/ipfs/boxo/bitswap/network/bsnet" "github.com/ipfs/boxo/bitswap" "github.com/ipfs/boxo/blockservice" "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-datastore" dsync "github.com/ipfs/go-datastore/sync" "github.com/libp2p/go-libp2p" ) ctx := context.Background() // Create a libp2p host h, _ := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0")) defer h.Close() // Create blockstore ds := dsync.MutexWrap(datastore.NewMapDatastore()) bs := blockstore.NewIdStore(blockstore.NewBlockstore(ds)) // Create Bitswap network and exchange n := bsnet.NewFromIpfsHost(h) // nil discovery = no DHT routing; use a real routing.ContentDiscovery for production bswap := bitswap.New(ctx, n, nil, bs) n.Start(bswap) defer bswap.Close() // Wire into a BlockService bsvc := blockservice.New(bs, bswap) defersvc.Close() // Fetch a block from the network (requires a connected peer that has it) c, _ := cid.Parse("bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi") blk, err := bsvc.GetBlock(ctx, c) if err != nil { fmt.Println("block not found:", err) } else { fmt.Printf("got %d bytes\n", len(blk.RawData())) } // Inspect stats stat, _ := bswap.Stat() fmt.Printf("blocks received: %d, blocks sent: %d\n", stat.BlocksReceived, stat.BlocksSent) ``` -------------------------------- ### Get Pin Object Source: https://github.com/ipfs/boxo/blob/main/pinning/remote/client/openapi/docs/PinsApi.md Retrieve a specific pin object using its unique request ID. The response includes the pin's status. ```go package main import ( "context" "fmt" "os" openapiclient "./openapi" ) func main() { requestid := "requestid_example" // string | configuration := openapiclient.NewConfiguration() api_client := openapiclient.NewAPIClient(configuration) resp, r, err := api_client.PinsApi.PinsRequestidGet(context.Background(), requestid).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsRequestidGet``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } // response from `PinsRequestidGet`: PinStatus fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsRequestidGet`: %v\n", resp) } ``` -------------------------------- ### Create Autoconf Client with Custom Options Source: https://github.com/ipfs/boxo/blob/main/autoconf/README.md Provides fine-grained control over client configuration, including custom URLs, refresh intervals, cache directories, user agents, timeouts, and explicit fallback mechanisms. It also supports optional callbacks for background refresh events. ```go // Create client with custom options client, err := autoconf.NewClient( autoconf.WithURL("https://conf.ipfs-mainnet.org/autoconf.json"), autoconf.WithRefreshInterval(24*time.Hour), autoconf.WithCacheDir("/path/to/cache"), autoconf.WithUserAgent("my-app/1.0"), autoconf.WithCacheSize(autoconf.DefaultCacheSize), autoconf.WithTimeout(autoconf.DefaultTimeout), autoconf.WithFallback(autoconf.GetMainnetFallbackConfig), // Explicit fallback // Optional callbacks for background refresh checks autoconf.WithOnNewVersion(func(oldVer, newVer int64, url string) { log.Printf("Config updated from v%d to v%d at %s", oldVer, newVer, url) // Trigger application restart or reload config }), autoconf.WithOnRefresh(func(resp *autoconf.Response) { log.Printf("Config refreshed: v%s at %s", resp.Version, resp.FetchTime) // Could persist metadata or trigger dependent operations }), autoconf.WithOnRefreshError(func(err error) { log.Printf("Refresh failed: %v", err) // Could send alert or switch to backup endpoint }), ) if err != nil { // handle } ``` -------------------------------- ### Run Go Tests Source: https://github.com/ipfs/boxo/blob/main/autoconf/README.md Execute the test suite for the package using the go test command. ```bash go test . ``` -------------------------------- ### Initializing a Bitswap Exchange Source: https://github.com/ipfs/boxo/blob/main/bitswap/README.md Demonstrates how to initialize a new Bitswap exchange instance using the provided network abstraction and blockstore. ```APIDOC ## Initializing a Bitswap Exchange ### Description Initializes a new Bitswap exchange instance. ### Parameters #### Context - `ctx` (context.Context) - The parent context for all of Bitswap. #### Network Abstraction - `network` (*bsnet.IpfsNetwork) - A network abstraction provided to Bitswap on top of libp2p & content routing. #### Blockstore - `bstore` (blockstore.Blockstore) - An IPFS blockstore. ### Code Example ```golang import ( "context" bitswap "github.com/ipfs/boxo/bitswap" bsnet "github.com/ipfs/boxo/bitswap/network" blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/libp2p/go-libp2p-core/routing" "github.com/libp2p/go-libp2p-core/host" ) var ctx context.Context var host host.Host var router routing.ContentRouting var bstore blockstore.Blockstore network := bsnet.NewFromIpfsHost(host, router) exchange := bitswap.New(ctx, network, bstore) ``` ``` -------------------------------- ### Get IPNS Record with Delegated Routing Client Source: https://github.com/ipfs/boxo/blob/main/examples/routing/delegated-routing-client/README.md Retrieve an IPNS record for a given IPNS name. This command requires the client to be pointed at a compatible HTTP endpoint. ```console $ ./delegated-routing-client -e http://127.0.0.1:8080 -ipns /ipns/k51qzi5uqu5diuz0h5tjqama8qbmyxusvqz2hfgn5go5l07l9k2ubqa09m7toe /ipns/k51qzi5uqu5diuz0h5tjqama8qbmyxusvqz2hfgn5go5l07l9k2ubqa09m7toe Value: /ipfs/QmUGMoVz62ZARyxkrdEiwmFZanTwVWLLu6EAWvbWHNcwR8 ``` -------------------------------- ### Get Several Blocks Asynchronously Source: https://github.com/ipfs/boxo/blob/main/bitswap/README.md Retrieves multiple blocks asynchronously using a slice of CIDs. Returns a channel for blocks and an error. The request can be canceled via the context. ```golang var cids []cid.Cid var ctx context.Context var exchange bitswap.Bitswap blockChannel, err := exchange.GetBlocks(ctx, cids) ``` -------------------------------- ### Select Server Configuration Source: https://github.com/ipfs/boxo/blob/main/pinning/remote/client/openapi/README.md Configure the server index to use a different server than the default (index 0). ```go ctx := context.WithValue(context.Background(), sw.ContextServerIndex, 1) ``` -------------------------------- ### Autoconf Background Updates with Context Lifecycle Source: https://github.com/ipfs/boxo/blob/main/autoconf/README.md Recommended for service integration, this pattern starts background configuration updates managed by a context. The updater stops automatically when the context is cancelled. ```go func runService(ctx context.Context) error { client, err := autoconf.NewClient( autoconf.WithCacheDir("/app/data/autoconf"), autoconf.WithUserAgent("myapp/1.2.3"), autoconf.WithRefreshInterval(12*time.Hour), // Custom callbacks for monitoring autoconf.WithOnNewVersion(func(oldVer, newVer int64, url string) { metrics.RecordConfigUpdate(oldVer, newVer) log.Infof("New config version %d available", newVer) }), autoconf.WithOnRefreshError(func(err error) { metrics.RecordConfigError() alerting.SendAlert("AutoConf refresh failed", err) }), ) if err != nil { return err } // Start primes cache and starts background updater // Updater will stop automatically when ctx is cancelled config, err := client.Start(ctx) if err != nil { return err } // Use the config immediately bootstrapPeers := config.GetBootstrapPeers("AminoDHT") // Your service logic here... // When ctx is cancelled, the updater stops automatically return nil } ``` -------------------------------- ### Create an IPNS Record in Go Source: https://github.com/ipfs/boxo/blob/main/ipns/README.md Demonstrates how to create a new IPNS record using a private key, a target path, and validity periods. This is useful for publishing content under a stable IPNS name. ```go import ( "crypto/rand" time "time" "github.com/ipfs/boxo/ipns" "github.com/ipfs/boxo/path" ic "github.com/libp2p/go-libp2p/core/crypto" ) func main() { // Create a private key to sign your IPNS record. Most of the time, you // will want to retrieve an already-existing key from Kubo, for example. sk, _, err := ic.GenerateEd25519Key(rand.Reader) if err != nil { panic(err) } // Define the path this record will point to. path, err := path.NewPath("/ipfs/bafkqac3jobxhgidsn5rww4yk") if err != nil { panic(err) } // Until when the record is valid. eol := time.Now().Add(time.Hour) // For how long should caches cache the record. ttl := time.Second * 20 record, err := ipns.NewRecord(sk, path, 1, eol, ttl) if err != nil { panic(err) } // Now you have an IPNS Record. } ``` -------------------------------- ### Get Cached or Refresh Autoconf Config Source: https://github.com/ipfs/boxo/blob/main/autoconf/README.md This method attempts to refresh the configuration from the network and falls back to the cache or defaults if the refresh fails. It guarantees a non-nil config object. ```go // With refresh: attempt network update, fall back to cache or defaults config := client.GetCachedOrRefresh(ctx) // Access config the same way - guaranteed to never be nil nativelySupported := []string{"AminoDHT"} // Systems your node runs locally (natively) bootstrapPeers := config.GetBootstrapPeers(nativelySupported...) // Bootstrap every native system fmt.Printf("Bootstrap peers: %v\n", bootstrapPeers) ``` -------------------------------- ### Initialize and Use IPFS Network Auto-Configuration Client Source: https://context7.com/ipfs/boxo/llms.txt Creates a client to fetch and cache IPFS network configurations from an HTTP endpoint. Configure cache directory, refresh interval, and callbacks for refresh events and errors. ```go import ( "fmt" "github.com/ipfs/boxo/autoconf" ) client, err := autoconf.NewClient( autoconf.WithCacheDir("/tmp/ipfs-autoconf"), autoconf.WithRefreshInterval(autoconf.DefaultRefreshInterval), // 24h autoconf.WithOnRefresh(func(resp *autoconf.Response) { fmt.Printf("config refreshed: version %d\n", resp.Version) }), autoconf.WithOnRefreshError(func(err error) { fmt.Println("refresh failed:", err) }), ) if err != nil { panic(err) } // Fetch the current IPFS network configuration (uses cache if fresh) conf, err := client.GetConfig() if err != nil { // Falls back to bundled mainnet defaults if network is unreachable panic(err) } fmt.Println("bootstrap peers:", conf.Bootstrap) fmt.Println("delegated routing endpoints:", conf.DelegatedRouting) // Start background refresh if err := client.StartBackgroundRefresh(); err != nil { panic(err) } deferr client.StopBackgroundRefresh() ``` -------------------------------- ### Create IPFS HTTP Gateway Handler Source: https://context7.com/ipfs/boxo/llms.txt Sets up a compliant HTTP handler for serving IPFS content. Requires a block service and configuration. Demonstrates adding middleware for hostname, subdomains, DNSLink, and CORS headers. ```go import ( "net/http" "github.com/ipfs/boxo/blockservice" "github.com/ipfs/boxo/gateway" "github.com/ipfs/boxo/gateway/assets" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) // bsvc is a blockservice.BlockService (e.g., backed by Bitswap) bsvc := mustMakeBlockService() // Create the gateway backend backend, err := gateway.NewBlocksBackend(bsvc) if err != nil { panic(err) } // Configure the gateway conf := gateway.Config{ DeserializedResponses: true, // serve files/dirs in addition to trustless formats NoDNSLink: false, RetrievalTimeout: gateway.DefaultRetrievalTimeout, // 30s MaxConcurrentRequests: gateway.DefaultMaxConcurrentRequests, // 4096 DiagnosticServiceURL: gateway.DefaultDiagnosticServiceURL, PublicGateways: map[string]*gateway.PublicGateway{ "localhost": { Paths: []string{"/ipfs", "/ipns"}, UseSubdomains: true, DeserializedResponses: true, }, }, Menu: []assets.MenuItem{ {URL: "https://ipfs.io", Title: "IPFS"}, }, } // Build the core handler (includes rate-limit and timeout middleware) gwHandler := gateway.NewHandler(conf, backend) mux := http.NewServeMux() mux.Handle("/ipfs/", gwHandler) mux.Handle("/ipns/", gwHandler) mux.Handle("/debug/metrics/prometheus", promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{})) // Wrap with hostname/subdomain/DNSLink middleware hostnameHandler := gateway.NewHostnameHandler(conf, backend, mux) // Add default CORS headers finalHandler := gateway.NewHeaders(nil).ApplyCors().Wrap(hostnameHandler) http.ListenAndServe(":8080", finalHandler) ```