From 870b05f1b1d967b811cb73f7f3e2112c2e7314c9 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 22 Oct 2024 13:21:25 +0100 Subject: [PATCH] feat: add delegation format and parse utility functions --- core/delegation/delegation.go | 36 ++++++++++++++++++++++++++++++ core/delegation/delegation_test.go | 22 ++++++++++++++++++ go.mod | 1 + 3 files changed, 59 insertions(+) diff --git a/core/delegation/delegation.go b/core/delegation/delegation.go index 32e9c33..9f8f6e9 100644 --- a/core/delegation/delegation.go +++ b/core/delegation/delegation.go @@ -7,6 +7,10 @@ import ( "iter" "sync" + "github.com/ipfs/go-cid" + "github.com/multiformats/go-multibase" + "github.com/multiformats/go-multicodec" + "github.com/multiformats/go-multihash" "github.com/storacha/go-ucanto/core/car" "github.com/storacha/go-ucanto/core/dag/blockstore" adm "github.com/storacha/go-ucanto/core/delegation/datamodel" @@ -206,3 +210,35 @@ func Extract(b []byte) (Delegation, error) { return NewDelegationView(model.Ucan0_9_1, br) } + +func Format(dlg Delegation) (string, error) { + bytes, err := io.ReadAll(dlg.Archive()) + if err != nil { + return "", fmt.Errorf("archiving delegation: %w", err) + } + digest, err := multihash.Sum(bytes, uint64(multicodec.Identity), -1) + if err != nil { + return "", fmt.Errorf("creating multihash: %w", err) + } + return cid.NewCidV1(uint64(multicodec.Car), digest).StringOfBase(multibase.Base64pad) +} + +func Parse(input string) (Delegation, error) { + cid, err := cid.Decode(input) + if err != nil { + return nil, fmt.Errorf("decoding CID: %w", err) + } + codec := multicodec.Code(cid.Prefix().Codec) + if codec != multicodec.Car { + return nil, fmt.Errorf("non CAR codec found: %s", codec.String()) + } + mhinfo, err := multihash.Decode(cid.Hash()) + if err != nil { + return nil, fmt.Errorf("decoding multihash: %w", err) + } + mhcodec := multicodec.Code(mhinfo.Code) + if mhcodec != multicodec.Identity { + return nil, fmt.Errorf("non identity multihash: %s", mhcodec.String()) + } + return Extract(mhinfo.Digest) +} diff --git a/core/delegation/delegation_test.go b/core/delegation/delegation_test.go index c577f7c..451ad45 100644 --- a/core/delegation/delegation_test.go +++ b/core/delegation/delegation_test.go @@ -1,6 +1,7 @@ package delegation import ( + "fmt" "testing" "github.com/storacha/go-ucanto/core/ipld/block" @@ -34,3 +35,24 @@ func TestAttach(t *testing.T) { } require.True(t, found) } + +func TestFormatParse(t *testing.T) { + dlg, err := Delegate( + fixtures.Alice, + fixtures.Bob, + []ucan.Capability[ucan.NoCaveats]{ + ucan.NewCapability("test/proof", fixtures.Alice.DID().String(), ucan.NoCaveats{}), + }, + ) + require.NoError(t, err) + + formatted, err := Format(dlg) + require.NoError(t, err) + + fmt.Println(formatted) + + parsed, err := Parse(formatted) + require.NoError(t, err) + + require.Equal(t, dlg.Link(), parsed.Link()) +} diff --git a/go.mod b/go.mod index 0a144e7..bfc454a 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/ipld/go-ipld-prime v0.21.1-0.20240917223228-6148356a4c2e github.com/multiformats/go-base32 v0.1.0 github.com/multiformats/go-multibase v0.2.0 + github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 github.com/multiformats/go-varint v0.0.7 github.com/pkg/errors v0.9.1