From d95d1a4b98ec02e8b48496c8c370a455c82b9b1d Mon Sep 17 00:00:00 2001 From: Oli Evans Date: Mon, 27 Nov 2023 14:28:30 +0000 Subject: [PATCH] feat!: upgrade `proof ls` (#136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Screenshot 2023-11-25 at 22 09 32 - `w3 proof ls` now shows lots more info with ucan flavour properties so it matches what you'd see in the spec or at https://ucan.xyz/validator/ - and with a relative date help for `exp` e.g `# expires in one year`. - and in valid yaml you can pate into a dingus (tho... what isn't valid yaml). - and in colour! (optional) - `--no-color` works automagically with chalk, so no additional plumbing is needed to disable it - audience is removed as it is always the did of the current agent, so is redundent. - `w3 proof ls --json` now returns **all** the info about the proofs. I need this for debugging, and it's neat to be able to dig into them with `jq` - this is a breaking change as it changes the json output format to use the default ucan/ipld flavour property names rather than custom ones. - e.g. `att` instead of `capabilities`. `/` for the root cid, rather than `cid` **w3 proof ls --json** ```shell # all issuers $ w3 proof ls --json | jq '.iss' "did:mailto:protocol.ai:oli" "did:web:web3.storage" "did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp" "did:key:z6MkhfzTwZJ28aRobCp76uXRqzsjH6GNu18WFwMumkAF5ojW" "did:key:z6Mku56ywWspVnzkcVQbeSkw6egVRSNKVSYgS38HhKcUJRiN" "did:key:z6Mktg5HxV1fifagzK8tnXXgCDsw1o4ekQHQpp9DKbLkh9hU" "did:web:web3.storage" # all space names $ ❯ w3 proof ls --json | jq '.fct[].space.name | select(.)' "clean" "toots" "fruits" "veg" # all ucan cids $ w3 proof ls --json | jq '.["/"]' "bafyreiaxpxm7oqdesq3nbjzcku3qqsb5onx25ab2tp23fl3edmjwllemgm" "bafyreifwqxlcwwwb4xll3deyq6zlvui26k5bq2oq4rcaam4pmg5rfmtqnu" "bafyreid2kvymk6nearlhg262zigjxitcl77ncsavcin2twdmhqmrlhxwui" "bafyreibpxq7zqbmphfprnn7qotfaowryr63nh5sg6kk75zmm3hsx6vhdfy" "bafyreietbar6chzhwp6bbxor6qydxkyhela7xpo2zmdmjbycoabgzxuexi" "bafyreigu6g2psglmekpfo73zapgebs5sbydcctibgq6obwilbvepap3l3a" "bafyreifwqxlcwwwb4xll3deyq6zlvui26k5bq2oq4rcaam4pmg5rfmtqnu" ``` **w3 proof ls** ```yaml # bafyreiaxpxm7oqdesq3nbjzcku3qqsb5onx25ab2tp23fl3edmjwllemgm iss: did:mailto:protocol.ai:oli att: - can: * with: ucan:* fct: - {"access/confirm":{"/":"bafyreidaljxvbccdts7dwoogds57a37y5fxy4b6wiq5h7oaz5npihtsgcq"},"access/request":{"/":"bafyreiabnffvury7onrouhhbsj6pi3de7oejxazkuoxbrjkl4vxuvdxjmm"}} # bafyreifwqxlcwwwb4xll3deyq6zlvui26k5bq2oq4rcaam4pmg5rfmtqnu iss: did:web:web3.storage att: - can: ucan/attest with: did:web:web3.storage nb: {"proof":{"/":"bafyreiaxpxm7oqdesq3nbjzcku3qqsb5onx25ab2tp23fl3edmjwllemgm"}} fct: - {"access/confirm":{"/":"bafyreidaljxvbccdts7dwoogds57a37y5fxy4b6wiq5h7oaz5npihtsgcq"},"access/request":{"/":"bafyreiabnffvury7onrouhhbsj6pi3de7oejxazkuoxbrjkl4vxuvdxjmm"}} # bafyreid2kvymk6nearlhg262zigjxitcl77ncsavcin2twdmhqmrlhxwui iss: did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp exp: 1731519367 # expires in a year att: - can: space/* with: did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp - can: store/* with: did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp - can: upload/* with: did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp - can: access/* with: did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp - can: filecoin/* with: did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp - can: usage/* with: did:key:z6MknD58DihJ7j3XdPZLuJPVPt8LC8BtdTULatbWmoqr8Awp fct: - {"space":{"name":"clean"}} ``` License: MIT --------- Signed-off-by: Oli Evans --- index.js | 39 +++++++++++++++++++++------------------ package-lock.json | 6 ++++++ package.json | 1 + test/bin.spec.js | 8 ++++---- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/index.js b/index.js index 6dab1e1..d046274 100644 --- a/index.js +++ b/index.js @@ -22,6 +22,7 @@ import * as ucanto from '@ucanto/core' import chalk from 'chalk' export * as Coupon from './coupon.js' export { Account, Space } +import ago from 's-ago' /** * @@ -474,33 +475,35 @@ export async function listProofs(opts) { const proofs = client.proofs() if (opts.json) { for (const proof of proofs) { - console.log( - JSON.stringify({ - cid: proof.cid.toString(), - issuer: proof.issuer.did(), - capabilities: proof.capabilities.map((c) => ({ - with: c.with, - can: c.can, - })), - }) - ) + console.log(JSON.stringify(proof)) } } else { for (const proof of proofs) { - console.log(proof.cid.toString()) - console.log(` issuer: ${proof.issuer.did()}`) - console.log(` audience: ${proof.audience.did()}`) + console.log(chalk.dim(`# ${proof.cid.toString()}`)) + console.log(`iss: ${chalk.cyanBright(proof.issuer.did())}`) + if (proof.expiration !== Infinity) { + console.log(`exp: ${chalk.yellow(proof.expiration)} ${chalk.dim(` # expires ${ago(new Date(proof.expiration * 1000))}`)}`) + } + console.log('att:') for (const capability of proof.capabilities) { - console.log(` with: ${capability.with}`) - console.log(` can: ${capability.can}`) + console.log(` - can: ${chalk.magentaBright(capability.can)}`) + console.log(` with: ${chalk.green(capability.with)}`) + if (capability.nb) { + console.log(` nb: ${JSON.stringify(capability.nb)}`) + } + } + if (proof.facts.length > 0) { + console.log('fct:') } + for (const fact of proof.facts) { + console.log(` - ${JSON.stringify(fact)}`) + } + console.log('') } + console.log(chalk.dim(`# ${proofs.length} proof${proofs.length === 1 ? '' : 's'} for ${client.agent.did()}`)) } } -/** - * - */ export async function whoami() { const client = await getClient() console.log(client.did()) diff --git a/package-lock.json b/package-lock.json index 8eb1bd1..81cf3fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "open": "^9.1.0", "ora": "^7.0.1", "pretty-tree": "^1.0.0", + "s-ago": "^2.2.0", "sade": "^1.8.1", "update-notifier": "^6.0.2" }, @@ -5977,6 +5978,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/s-ago": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/s-ago/-/s-ago-2.2.0.tgz", + "integrity": "sha512-t6Q/aFCCJSBf5UUkR/WH0mDHX8EGm2IBQ7nQLobVLsdxOlkryYMbOlwu2D4Cf7jPUp0v1LhfPgvIZNoi9k8lUA==" + }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", diff --git a/package.json b/package.json index e905c08..d61fb7f 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "open": "^9.1.0", "ora": "^7.0.1", "pretty-tree": "^1.0.0", + "s-ago": "^2.2.0", "sade": "^1.8.1", "update-notifier": "^6.0.2" }, diff --git a/test/bin.spec.js b/test/bin.spec.js index 6931a42..de6246a 100644 --- a/test/bin.spec.js +++ b/test/bin.spec.js @@ -967,10 +967,10 @@ export const testProof = { .env(env.bob) .join() const proofData = JSON.parse(proofList.output) - assert.equal(proofData.issuer, aliceDID) - assert.equal(proofData.capabilities.length, 1) - assert.equal(proofData.capabilities[0].with, spaceDID) - assert.equal(proofData.capabilities[0].can, 'store/*') + assert.equal(proofData.iss, aliceDID) + assert.equal(proofData.att.length, 1) + assert.equal(proofData.att[0].with, spaceDID) + assert.equal(proofData.att[0].can, 'store/*') }), }