diff --git a/bin.js b/bin.js index 590b914..2730838 100755 --- a/bin.js +++ b/bin.js @@ -121,7 +121,8 @@ cli .action(registerSpace) cli - .command('space add ') + .command('space add [proof]') + .option('--base64', 'provide proof as base64 encoded string') .describe( 'Add a space to the agent. The proof is a CAR encoded delegation to _this_ agent.' ) diff --git a/index.js b/index.js index 9ab30ce..ba06e29 100644 --- a/index.js +++ b/index.js @@ -11,8 +11,9 @@ import { checkPathsExist, filesize, filesizeMB, - readProof, uploadListResponseToString, + proofFromString, + proofFromPath } from './lib.js' import * as ucanto from '@ucanto/core' import * as DidMailto from '@web3-storage/did-mailto' @@ -284,11 +285,16 @@ export async function registerSpace(opts) { /** * @param {string} proofPath + * @param {object} opts + * @param {string} opts.base64 */ -export async function addSpace(proofPath) { +export async function addSpace(proofPath, opts) { const client = await getClient() - const delegation = await readProof(proofPath) - const space = await client.addSpace(delegation) + const proof = opts.base64 + ? await proofFromString(opts.base64) + : await proofFromPath(proofPath) + const space = await client.addSpace(proof) + await client.setCurrentSpace(space.did()) console.log(space.did()) } @@ -445,7 +451,7 @@ export async function revokeDelegation(delegationCid, opts) { let proof try { if (opts.proof) { - proof = await readProof(opts.proof) + proof = await proofFromPath(opts.proof) } } catch (/** @type {any} */ err) { console.log(`Error: reading proof: ${err.message}`) @@ -479,7 +485,7 @@ export async function addProof(proofPath, opts) { const client = await getClient() let proof try { - proof = await readProof(proofPath) + proof = await proofFromPath(proofPath) if (!opts?.['dry-run']) { await client.addProof(proof) } diff --git a/lib.js b/lib.js index 2bc0ec4..9f62387 100644 --- a/lib.js +++ b/lib.js @@ -126,27 +126,18 @@ export function getClient() { } /** - * @param {string} path Path to the proof file. + * @param {CarReader} reader */ -export async function readProof(path) { - try { - await fs.promises.access(path, fs.constants.R_OK) - } catch (/** @type {any} */ err) { - console.error(`Error: failed to read proof: ${err.message}`) - process.exit(1) - } - +export async function proofFromCar(reader) { const blocks = [] try { - const reader = await CarReader.fromIterable(fs.createReadStream(path)) for await (const block of reader.blocks()) { blocks.push(block) } } catch (/** @type {any} */ err) { - console.error(`Error: failed to parse proof: ${err.message}`) + console.error(`Error: failed to iterate proof: ${err.message}`) process.exit(1) } - try { // @ts-expect-error return importDAG(blocks) @@ -156,6 +147,37 @@ export async function readProof(path) { } } +/** @param {string} data Base64 encoded CAR file */ +export async function proofFromString (data) { + let reader + try { + const bytes = Buffer.from(data, 'base64') + reader = await CarReader.fromBytes(bytes) + } catch (/** @type {any} */ err) { + console.error(`Error: failed to parse proof: ${err.message}`) + process.exit(1) + } + return proofFromCar(reader) +} + +/** @param {string} path Path to the proof file. */ +export async function proofFromPath (path) { + try { + await fs.promises.access(path, fs.constants.R_OK) + } catch (/** @type {any} */ err) { + console.error(`Error: failed to read proof: ${err.message}`) + process.exit(1) + } + let reader + try { + reader = await CarReader.fromIterable(fs.createReadStream(path)) + } catch (/** @type {any} */ err) { + console.error(`Error: failed to parse proof: ${err.message}`) + process.exit(1) + } + return proofFromCar(reader) +} + /** * @param {UploadListSuccess} res * @param {object} [opts]