Files
ucan/token/read.go
Prad Nukala 36717a0826
Some checks failed
go continuous benchmark / Run Go continuous benchmark (push) Has been cancelled
Go Test / ubuntu (go 1.22.x) (push) Has been cancelled
Go Test / ubuntu (go 1.23.x) (push) Has been cancelled
refactor(token): migrate from ucan-wg to code.sonr.org/go
2026-01-08 15:46:02 -05:00

127 lines
3.7 KiB
Go

package token
import (
"fmt"
"io"
"code.sonr.org/go/did-it"
"github.com/ipfs/go-cid"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/codec"
"github.com/ipld/go-ipld-prime/codec/dagcbor"
"github.com/ipld/go-ipld-prime/codec/dagjson"
"github.com/ipld/go-ipld-prime/datamodel"
"code.sonr.org/go/ucan/token/delegation"
"code.sonr.org/go/ucan/token/internal/envelope"
"code.sonr.org/go/ucan/token/invocation"
)
// FromSealed decodes an arbitrary token type from the binary data,
// verifies that the envelope's signature is correct based on the public
// key taken from the issuer (iss) field and calculates the CID of the
// incoming data.
// Supported and returned types are:
// - delegation.Token
// - invocation.Token
func FromSealed(data []byte, resolvOpts ...did.ResolutionOption) (Token, cid.Cid, error) {
tkn, err := FromDagCbor(data, resolvOpts...)
if err != nil {
return nil, cid.Undef, err
}
id, err := envelope.CIDFromBytes(data)
if err != nil {
return nil, cid.Undef, err
}
return tkn, id, nil
}
// FromSealedReader is the same as Unseal but accepts an io.Reader.
func FromSealedReader(r io.Reader, resolvOpts ...did.ResolutionOption) (Token, cid.Cid, error) {
cidReader := envelope.NewCIDReader(r)
tkn, err := FromDagCborReader(cidReader, resolvOpts...)
if err != nil {
return nil, cid.Undef, err
}
id, err := cidReader.CID()
if err != nil {
return nil, cid.Undef, err
}
return tkn, id, nil
}
// Decode unmarshals the input data using the format specified by the
// provided codec.Decoder into an arbitrary UCAN token.
// An error is returned if the conversion fails, or if the resulting
// Token is invalid.
// Supported and returned types are:
// - delegation.Token
// - invocation.Token
func Decode(b []byte, decFn codec.Decoder, resolvOpts ...did.ResolutionOption) (Token, error) {
node, err := ipld.Decode(b, decFn)
if err != nil {
return nil, err
}
return fromIPLD(node, resolvOpts...)
}
// DecodeReader is the same as Decode, but accept an io.Reader.
func DecodeReader(r io.Reader, decFn codec.Decoder, resolvOpts ...did.ResolutionOption) (Token, error) {
node, err := ipld.DecodeStreaming(r, decFn)
if err != nil {
return nil, err
}
return fromIPLD(node, resolvOpts...)
}
// FromDagCbor unmarshals an arbitrary DagCbor encoded UCAN token.
// An error is returned if the conversion fails, or if the resulting
// Token is invalid.
// Supported and returned types are:
// - delegation.Token
// - invocation.Token
func FromDagCbor(b []byte, resolvOpts ...did.ResolutionOption) (Token, error) {
return Decode(b, dagcbor.Decode, resolvOpts...)
}
// FromDagCborReader is the same as FromDagCbor, but accept an io.Reader.
func FromDagCborReader(r io.Reader, resolvOpts ...did.ResolutionOption) (Token, error) {
return DecodeReader(r, dagcbor.Decode, resolvOpts...)
}
// FromDagJson unmarshals an arbitrary DagJson encoded UCAN token.
// An error is returned if the conversion fails, or if the resulting
// Token is invalid.
// Supported and returned types are:
// - delegation.Token
// - invocation.Token
func FromDagJson(b []byte, resolvOpts ...did.ResolutionOption) (Token, error) {
return Decode(b, dagjson.Decode, resolvOpts...)
}
// FromDagJsonReader is the same as FromDagJson, but accept an io.Reader.
func FromDagJsonReader(r io.Reader, resolvOpts ...did.ResolutionOption) (Token, error) {
return DecodeReader(r, dagjson.Decode, resolvOpts...)
}
func fromIPLD(node datamodel.Node, resolvOpts ...did.ResolutionOption) (Token, error) {
tag, err := envelope.FindTag(node)
if err != nil {
return nil, err
}
switch tag {
case delegation.Tag:
return delegation.FromIPLD(node, resolvOpts...)
case invocation.Tag:
return invocation.FromIPLD(node, resolvOpts...)
default:
return nil, fmt.Errorf(`unknown tag "%s"`, tag)
}
}