diff --git a/packages/api/src/utils/w3up.js b/packages/api/src/utils/w3up.js index 0dd0d10b72..003460955d 100644 --- a/packages/api/src/utils/w3up.js +++ b/packages/api/src/utils/w3up.js @@ -4,8 +4,9 @@ import { StoreMemory } from '@web3-storage/access/stores/store-memory' import { CID } from 'multiformats/cid' import { base64 } from 'multiformats/bases/base64' import { identity } from 'multiformats/hashes/identity' -import { CarReader } from '@ipld/car' +import { CarReader, CarWriter } from '@ipld/car' import { importDAG } from '@ucanto/core/delegation' +import * as ucanto from '@ucanto/core' /** * @param {object} env @@ -70,3 +71,33 @@ export async function readProofFromBytes(bytes) { throw err } } + +/** + * @param {import('@ucanto/interface').Delegation} delegation - delegation to encode + */ +export async function encodeDelegationAsCid(delegation) { + const { writer, out } = CarWriter.create() + /** @type {Array} */ + const carChunks = [] + await Promise.all([ + // write delegation blocks + (async () => { + for (const block of delegation.export()) { + // @ts-expect-error different Block types + await writer.put(block) + } + await writer.close() + })(), + // read out + (async () => { + for await (const chunk of out) { + carChunks.push(chunk) + } + })(), + ]) + // now get car chunks + const car = new Blob(carChunks) + const bytes = new Uint8Array(await car.arrayBuffer()) + const cid = CID.createV1(ucanto.CAR.code, identity.digest(bytes)) + return cid +} diff --git a/packages/api/test/nfts-upload.spec.js b/packages/api/test/nfts-upload.spec.js index e2a4caad54..c1ef8de7c0 100644 --- a/packages/api/test/nfts-upload.spec.js +++ b/packages/api/test/nfts-upload.spec.js @@ -27,9 +27,14 @@ import path from 'node:path' import { FormData } from 'undici' import { createCarCid } from '../src/utils/car.js' import { createServer } from 'node:http' +import { ed25519 } from '@ucanto/principal' +import { delegate } from '@ucanto/core' +import { encodeDelegationAsCid } from '../src/utils/w3up.js' const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const nftStorageSpace = ed25519.generate() +const nftStorageApiPrincipal = ed25519.generate() const mockW3up = createListeningMockW3up() test.before(async (t) => { @@ -38,9 +43,20 @@ test.before(async (t) => { overrides: { LINKDEX_URL: linkdexUrl, W3UP_URL: (await mockW3up).url.toString(), - W3_NFTSTORAGE_SPACE: `did:key:zTodo`, - W3_NFTSTORAGE_PRINCIPAL: 'zTodo', - W3_NFTSTORAGE_PROOF: 'zTodo', + W3_NFTSTORAGE_SPACE: (await nftStorageSpace).did(), + W3_NFTSTORAGE_PRINCIPAL: (await nftStorageApiPrincipal).did(), + W3_NFTSTORAGE_PROOF: ( + await encodeDelegationAsCid( + await delegate({ + issuer: await nftStorageSpace, + audience: await nftStorageApiPrincipal, + capabilities: [ + { can: 'store/add', with: (await nftStorageSpace).did() }, + { can: 'upload/add', with: (await nftStorageSpace).did() }, + ], + }) + ) + ).toString(), }, }) })