{"id":19032523,"url":"https://github.com/storacha/go-ucanto","last_synced_at":"2025-12-15T16:57:15.456Z","repository":{"id":194759637,"uuid":"691280856","full_name":"storacha/go-ucanto","owner":"storacha","description":"🐧 Ucanto UCAN RPC in Go","archived":false,"fork":false,"pushed_at":"2025-04-08T14:04:42.000Z","size":730,"stargazers_count":9,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-18T01:48:11.301Z","etag":null,"topics":["auth","decentralized","ipld","rpc","ucan"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/storacha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-13T21:30:16.000Z","updated_at":"2025-04-08T13:58:01.000Z","dependencies_parsed_at":"2023-12-11T16:28:10.219Z","dependency_job_id":"275209be-1f13-45b7-8e5a-abb23c4b0cce","html_url":"https://github.com/storacha/go-ucanto","commit_stats":null,"previous_names":["alanshaw/go-ucanto","storacha-network/go-ucanto","storacha/go-ucanto"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storacha%2Fgo-ucanto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storacha%2Fgo-ucanto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storacha%2Fgo-ucanto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storacha%2Fgo-ucanto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/storacha","download_url":"https://codeload.github.com/storacha/go-ucanto/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250472033,"owners_count":21436069,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auth","decentralized","ipld","rpc","ucan"],"created_at":"2024-11-08T21:29:06.762Z","updated_at":"2025-12-15T16:57:15.446Z","avatar_url":"https://github.com/storacha.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-ucanto\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/storacha/go-ucanto)](https://goreportcard.com/report/github.com/storacha/go-ucanto)\n\nUcanto UCAN RPC in Golang.\n\n## Install\n\n```console\ngo get github.com/storacha/go-ucanto\n```\n\n## Usage\n\n### Client\n\n```go\npackage main\n\nimport (\n  \"...\"\n)\n\n// service URL \u0026 DID\nserviceURL, _ := url.Parse(\"https://up.web3.storage\")\nservicePrincipal, _ := did.Parse(\"did:web:web3.storage\")\n\n// HTTP transport and CAR encoding\nchannel := http.NewHTTPChannel(serviceURL)\nconn, _ := client.NewConnection(servicePrincipal, channel)\n\n// private key to sign UCANs with\npriv, _ := ioutil.ReadFile(\"path/to/private.key\")\nsigner, _ := ed25519.Parse(priv)\n\naudience := servicePrincipal\n\ntype StoreAddCaveats struct {\n\tLink ipld.Link\n\tSize int\n}\n\nfunc (c StoreAddCaveats) ToIPLD() (datamodel.Node, error) {\n\treturn ipld.WrapWithRecovery(\u0026c, StoreAddType())\n}\n\nfunc StoreAddType() ipldschema.Type {\n\tts, _ := ipldprime.LoadSchemaBytes([]byte(`\n\t\ttype StoreAdd struct {\n\t\t\tlink Link\n\t\t\tsize Int\n\t\t}\n\t`))\n\treturn ts.TypeByName(\"StoreAdd\")\n}\n\ncapability := ucan.NewCapability(\n\t\"store/add\",\n\tdid.Parse(\"did:key:z6MkwDuRThQcyWjqNsK54yKAmzfsiH6BTkASyiucThMtHt1T\").String(),\n\tStoreAddCaveats{\n\t\t// TODO\n\t},\n)\n\n// create invocation(s) to perform a task with granted capabilities\ninv, _ := invocation.Invoke(signer, audience, capability, delegation.WithProofs(...))\ninvocations := []invocation.Invocation{inv}\n\n// send the invocation(s) to the service\nresp, _ := client.Execute(context.Background(), invocations, conn)\n\n// define datamodels for ok and error outcome\ntype OkModel struct {\n  Status string\n}\ntype ErrModel struct {\n\tMessage string\n}\n\n// create new receipt reader, passing the IPLD schema for the result and the\n// ok and error types\nreader, _ := receipt.NewReceiptReader[OkModel, ErrModel]([]byte(`\n\ttype Result union {\n\t\t| Ok \"ok\"\n\t\t| Err \"error\"\n\t} representation keyed\n\n\ttype Ok struct {\n\t\tstatus String\n\t}\n\n\ttype Err struct {\n\t\tmessage String\n\t}\n`))\n\n// get the receipt link for the invocation from the response\nrcptlnk, _ := resp.Get(invocations[0].Link())\n// read the receipt for the invocation from the response\nrcpt, _ := reader.Read(rcptlnk, res.Blocks())\n\nfmt.Println(rcpt.Out().Ok())\n```\n\n### Server\n\n```go\npackage main\n\nimport (\n\t\"...\"\n)\n\ntype TestEcho struct {\n\tEcho string\n}\n\nfunc (c TestEcho) ToIPLD() (ipld.Node, error) {\n\treturn ipld.WrapWithRecovery(\u0026c, EchoType())\n}\n\nfunc EchoType() ipldschema.Type {\n\tts, _ := ipldprime.LoadSchemaBytes([]byte(`\n\t\ttype TestEcho struct {\n\t\t\techo String\n\t\t}\n\t`))\n\treturn ts.TypeByName(\"TestEcho\")\n}\n\nfunc createServer(signer principal.Signer) (server.ServerView, error) {\n\t// Capability definition(s)\n\ttestecho := validator.NewCapability(\n\t\t\"test/echo\",\n\t\tschema.DIDString(),\n\t\tschema.Struct[TestEcho](EchoType(), nil),\n\t\tvalidator.DefaultDerives,\n\t)\n\n\treturn server.NewServer(\n\t\tsigner,\n\t\t// Handler definitions\n\t\tserver.WithServiceMethod(\n\t\t\ttestecho.Can(),\n\t\t\tserver.Provide(\n\t\t\t\ttestecho,\n\t\t\t\tfunc(ctx context.Context, cap ucan.Capability[TestEcho], inv invocation.Invocation, ictx server.InvocationContext) (TestEcho, receipt.Effects, error) {\n\t\t\t\t\treturn TestEcho{Echo: cap.Nb().Echo}, nil, nil\n\t\t\t\t},\n\t\t\t),\n\t\t),\n\t)\n}\n\nfunc main() {\n\tsigner, _ := ed25519.Generate()\n\tserver, _ := createServer(signer)\n\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tres, _ := server.Request(r.Context(), uhttp.NewHTTPRequest(r.Body, r.Header))\n\n\t\tfor key, vals := range res.Headers() {\n\t\t\tfor _, v := range vals {\n\t\t\t\tw.Header().Add(key, v)\n\t\t\t}\n\t\t}\n\n\t\tif res.Status() != 0 {\n\t\t\tw.WriteHeader(res.Status())\n\t\t}\n\n\t\tio.Copy(w, res.Body())\n\t})\n\n\tlistener, _ := net.Listen(\"tcp\", \":0\")\n\n\tport := listener.Addr().(*net.TCPAddr).Port\n\tfmt.Printf(\"{\\\"id\\\":\\\"%s\\\",\\\"url\\\":\\\"http://127.0.0.1:%d\\\"}\\n\", signer.DID().String(), port)\n\n\thttp.Serve(listener, nil)\n}\n```\n\n## API\n\n[pkg.go.dev Reference](https://pkg.go.dev/github.com/storacha/go-ucanto)\n\n## Related\n\n* [Ucanto in Javascript](https://github.com/storacha/ucanto)\n\n## Contributing\n\nFeel free to join in. All welcome. Please [open an issue](https://github.com/storacha/go-ucanto/issues)!\n\n## License\n\nDual-licensed under [MIT + Apache 2.0](LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstoracha%2Fgo-ucanto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstoracha%2Fgo-ucanto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstoracha%2Fgo-ucanto/lists"}