Skip to content

fil-forge/ucantone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

204 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ucantone logo

ucantone

Ucanto for UCAN 1.0.

Usage

API Reference

pkg.go.dev/github.com/fil-forge/ucantone

Examples

Principals

See examples in principals_test.go

principal, err := did.Parse("did:key:z6MkfBSb2hC6g3UGnqNmWfmGvPdfMorBpT2osm9bk9b4Cyqu")
fmt.Println("DID:", principal)
// generate a new ed25519 issuer
issuer, err := ed25519.GenerateIssuer()
fmt.Println("DID:", issuer.DID())

// this principal can sign
sig := issuer.Sign([]byte{1, 2, 3})
fmt.Printf("Signature: 0x%x\n", sig)

// and has a private key (use format utility to multibase base64pad encode)
fmt.Println("Private Key:", multikey.FormatSigner(issuer))

// which can be stored and decoded later...
issuer2, err := ed25519.Decode(issuer.Bytes())

Delegation

See examples in delegations_test.go

dlg, err = delegation.Delegate(
  alice,                              // issuer
  bob,                                // audience (receiver)
  mailer,                             // subject
  command.MustParse("/message/send"), // command
  // policy (alice delegates bob capability to use the email service, but only
  // allows bob to send to example.com email addresses)
  delegation.WithPolicyBuilder(
    policy.All(".to", policy.Like(".", "*@example.com")),
  ),
)

Invocation

See examples in invocations_test.go

inv, err := invocation.Invoke(
  alice,
  mailer,
  command.MustParse("/message/send"),
  datamodel.Map{
    "from":    "alice@example.com",
    "to":      "bob@example.com",
    "message": "Hello Bob!",
  },
  invocation.WithProofs(dlg.Link()),
)

Command definition

See examples in command_definition_test.go

// Note: must be CBOR marshalable
type MessageSendArguments struct {
	To      []string `cborgen:"to"`
	Message string `cborgen:"message"`
}

type MessageSendOK struct {
  Delivered bool `cborgen:"delivered"`
}

cmd := command.MustParse("/message/send")
messageSend := binding.Bind[*MessageSendArguments, *MessageSendOK](cmd)

// delegate the capability
dlg, err := messageSend.Delegate(mailer, alice, mailer)

// invoke the capability
invocation, err := messageSend.Invoke(
  alice,
  mailer,
  &MessageSendArguments{
    To: []string{"bob@example.com"},
    Message: "Hello Bob, How do you do?",
  }
  invocation.WithProofs(dlg.Link()),
)

// later, after execution:
ok, err := messageSend.Unpack(receipt)
fmt.Println(ok.Delivered)

Container

See examples in container_test.go

ct := container.New(
  container.WithDelegations(dlg0, dlg1),
  container.WithInvocations(inv0),
  // container.WithReceipts(...),
)

// Various encoding options are available, the following (Base64Gzip) is good
// for when you want to add the container to a HTTP header.
buf, err := container.Encode(container.Base64Gzip, ct)

Server

See examples in server_test.go

echo, err := command.Parse("/example/echo")
serviceID, err := ed25519.GenerateIssuer()

ucanSrv := server.NewHTTP(serviceID)

// Register an echo handler that returns the invocation arguments as the result
ucanSrv.Handle(echo, func(req execution.Request, res execution.Response) error {
  return res.SetSuccess(req.Invocation().Arguments())
})

http.ListenAndServe(":3000", ucanSrv)

Client

See examples in server_test.go

// delegate echo capability to alice
dlg, err := delegation.Delegate(serviceID, alice, serviceID, echo)

// invoke (exercise) the capability
inv, err := invocation.Invoke(
  alice,
  serviceID,
  echo,
  datamodel.Map{"message": "Hello, UCAN!"},
  invocation.WithProofs(dlg.Link()),
)

c, err := client.NewHTTP(serviceURL)

// create an execution request and send it to the service, passing the
// invocation and the delegation as proof we are authorized
req := execution.NewRequest(context.Background(), inv, execution.WithDelegations(dlg))
resp, err := c.Execute(req)

if out := resp.Receipt().Out(); out.IsOK() {
  ok, _ := out.Unpack()
  fmt.Printf("Echo response: %+v\n", ok)
} else {
  _, x := out.Unpack()
  fmt.Printf("Invocation failed: %v\n", x)
}

Contributing

Feel free to join in. All welcome. Please open an issue!

License

Dual-licensed under MIT OR Apache 2.0

About

🎵 Ucanto for UCAN 1.0

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors