Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: import space from base64 string #122

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ cli
.action(registerSpace)

cli
.command('space add <proof>')
.command('space add [proof]')
.option('--base64', 'provide proof as base64 encoded string')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it would be helpful for noobs to know more about what is expected as the bytes that are base64d. iirc the idea is we accept any UCAN serialization? but esp car files?
(e.g. do you want base64(cidOfProofCar) or base64(proofCarWithDagUcanCbor)) ?

.describe(
'Add a space to the agent. The proof is a CAR encoded delegation to _this_ agent.'
)
Expand Down
18 changes: 12 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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())
Copy link
Contributor Author

@olizilla olizilla Nov 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reckon space add should set the current space. It was annoying to have to do that manually after calling space add. This is what space create does, so this would be consistent.

console.log(space.did())
}

Expand Down Expand Up @@ -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}`)
Expand Down Expand Up @@ -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)
}
Expand Down
46 changes: 34 additions & 12 deletions lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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]
Expand Down