Go Client

Guppy

⚠️

The Go client is under heavy development and is not as fully featured as the JS client.

You can easily integrate Storacha into your Go apps using guppy, our Go client for the Storacha Network.

In this guide, we'll walk through the following steps:

  1. Installing the client library
  2. Generating a DID
  3. Obtaining proofs
  4. Loading your private key and proofs
  5. Uploading a CAR file

Install

You'll need Go (opens in a new tab) version 1.24.4 or higher.

In addition to the client library you're also likely to need elements of go-ucanto - a library for performing UCAN RPC calls. Add the libraries to your project's dependencies:

go get github.com/storacha/guppy
go get github.com/storacha/go-ucanto

Generate a DID

Currently the best way to generate a DID (decentralized identifier) is to use the JS CLI:

Install CLI

npm install -g @storacha/cli

Generate a DID

storacha key create

Output should look something like:

# did:key:z6Mkh9TtUbFJcUHhMmS9dEbqpBbHPbL9oxg1zziWn1CYCNZ2
MgCb+bRGl02JqlWMPUxCyntxlYj0T/zLtR2tn8LFvw6+Yke0BKAP/OUu2tXpd+tniEoOzB3pxqxHZpRhrZl1UYUeraT0=
💡

Save the private key (starting Mg...) to a file private.key.

Obtain Proofs

Proofs are delegations to your DID enabling it to perform tasks. Currently the best way to obtain proofs that will allow you to interact with the Storacha API is to use the JS CLI:

Install CLI

npm install -g @storacha/cli

Generate a DID

Generate a DID and make a note of it (the string starting with did:key:...)

Create a Space

storacha space create [NAME]

Delegate Capabilities to Your DID

storacha delegation create -c 'space/blob/add' -c space/index/add -c 'upload/add' -c 'filecoin/offer' [DID] -o proof.ucan
💡

Make a note of the space DID from above. You'll need it later.

Load Private Key and Proofs

To interact with the Storacha API you need your private key to sign UCAN invocations and a proof that your key has been delegated capabilities to perform tasks:

package main
 
import (
  "ioutil"
 
  "github.com/storacha/go-ucanto/did"
  "github.com/storacha/go-ucanto/principal/ed25519/signer"
  "github.com/storacha/guppy/pkg/delegation"
)
 
// space that the client will interact with
space, _ := did.Parse("did:key:z6MkwDuRThQcyWjqNsK54yKAmzfsiH6BTkASyiucThMtHt1y")
 
// private key to sign UCAN invocations with
priv, _ := ioutil.ReadFile("path/to/private.key")
issuer, _ := signer.Parse(priv)
 
// UCAN proof(s) that the signer can perform tasks in this space (a delegation chain)
prfbytes, _ := ioutil.ReadFile("path/to/proof.ucan")
proof, _ := delegation.ExtractProof(prfbytes)

Upload a CAR

Once you have loaded your space DID, your private key and your delegation proofs, you can upload a CAR (content addressed archive file) to Storacha.

🚫

The following code sample is out of date. An update is coming soon.

package main
 
import (
	"bytes"
	"fmt"
	"net/http"
 
	"github.com/ipfs/go-cid"
	"github.com/ipld/go-ipld-prime/linking/cid"
	"github.com/multiformats/go-multihash"
	"github.com/storacha/guppy/capability/storeadd"
	"github.com/storachas/guppy/client"
)
 
func main() {
  data, _ := ioutil.ReadFile("path/to/my.car")
 
  // generate the CID for the CAR
  mh, _ := multihash.Sum(data, multihash.SHA2_256, -1)
  link := cidlink.Link{Cid: cid.NewCidV1(0x0202, mh)}
 
  rcpt, _ := client.StoreAdd(
    issuer,
    space,
    &storeadd.Caveat{Link: link, Size: len(data)},
    client.WithProofs(proofs),
  )
 
  // "upload" means it needs to be uploaded, "done" means it is already done!
  if rcpt.Out().Ok().Status == "upload" {
    hr, _ := http.NewRequest("PUT", *rcpt.Out().Ok().Url, bytes.NewReader(data))
 
    hdr := map[string][]string{}
    for k, v := range rcpt.Out().Ok().Headers.Values {
      hdr[k] = []string{v}
    }
 
    hr.Header = hdr
    hr.ContentLength = len(data)
    httpClient := http.Client{}
    res, _ := httpClient.Do(hr)
    res.Body.Close()
  }
 
  fmt.Println(link.String())
}
⚠️

Maximum upload size is 4,261,412,864 bytes (around 4GB). To upload CAR files larger than this, please use the sharding utility (opens in a new tab) to split the CAR into multiple shards.

A DAG can be sharded amongst multiple CAR files (see maximum upload size above). To tie together multiple stored CAR files to a content root CID you can register an "upload". An "upload" is a content root CID + a set of CAR shards that it is contained within.

You can register an upload with just one "shard". It is best practice to always register an upload even if there is only 1 shard.

Registering an upload is simple:

rcpt, _ := client.UploadAdd(
  issuer,
  space,
  &uploadadd.Caveat{Root: root, Shards: shards},
  client.WithProofs(proofs),
)