diff --git a/packages/daf-cli/README.md b/packages/daf-cli/README.md index 763ade92b..37bbed284 100644 --- a/packages/daf-cli/README.md +++ b/packages/daf-cli/README.md @@ -6,6 +6,33 @@ npm -g i daf-cli ``` +## Functionality + +- [x] Identity manager + - [x] List managed identities + - [x] Create identity + - [x] Delete identity + - [x] List available identity controller types +- [x] DID Document resolver + - [x] Resolve using internal (JS) resolver + - [x] Resolve using external universal resolver +- [x] Services + - [x] Sync latest messages (Trust Graph) + - [x] Subscribe to new messages (Trust Graph) +- [x] Verifiable Credentials + - [x] Create Verifiable Credential + - [x] Send Verifiable Credential (DIDComm / TrustGraph) + - [ ] Create Verifiable Presentation + - [ ] Send Verifiable Presentation (DIDComm / TrustGraph) +- [x] Data Store Explorer + - [x] List known identities + - [x] List messages + - [x] List credentials +- [ ] Selective Disclosure Request + - [ ] Create and send SDR + - [ ] Display received SDR + - [ ] Create and send VP as a selective disclosure response + ## Usage ``` @@ -17,56 +44,21 @@ Options: Commands: identity-manager [options] Manage identities resolve Resolve DID Document -``` - -### Identity manager - -``` -daf identity-manager -h - -Usage: daf identity-manager [options] - -Manage identities - -Options: - -l, --list List managed identities - -t, --types List available identity controller types - -c, --create Create identity - -d, --delete Delete identity - -h, --help output usage information -``` -### W3C Credentials - -``` -Usage: daf credential [options] - -Manage W3C Verifiable Credentials - -Options: - -c, --create Create new credential - -s, --send Send - -q, --qrcode Show qrcode - -r, --receiver Credential subject - -h, --help output usage information -``` - -### Services - -Listen for new messages - -``` -daf listen + credential [options] Manage W3C Verifiable Credentials + listen Receive new messages and listen for new ones + data-explorer [options] Explore data store ``` #### Using custom TGE - Send: + ``` DAF_TG_URI=https://custom-tge.eu.ngrok.io/graphql daf credential -c -s ``` Receive: + ``` DEBUG=* DAF_TG_URI=https://custom-tge.eu.ngrok.io/graphql DAF_TG_WSURI=wss://custom-tge.eu.ngrok.io/graphql daf listen ``` @@ -86,13 +78,14 @@ DAF_UNIVERSAL_RESOLVER_URL=https://uniresolver.io/1.0/identifiers/ daf resolve d ``` ## Configuration - ENV | Default | Description ----|---|--- - `DEBUG` | `undefined` | Use `*` to see all debug info. [More options](https://github.com/visionmedia/debug#environment-variables) - `DAF_IDENTITY_STORE` | `~/.daf/identity-store.json` | Identity keyPair storage - `DAF_DATA_STORE` | `~/.daf/data-store.sqlite3` | Sqlite3 database containing messages, credentials, presentations, etc. - `DAF_ENCRYPTION_STORE` | `~/.daf/encryption-store.json` | Encryption keyPair storage. Used for DIDComm - `DAF_INFURA_ID` | `5ffc47f65c4042ce847ef66a3fa70d4c` | Used for calls to the Ethereum blockchain - `DAF_UNIVERSAL_RESOLVER_URL` | `undefined` | Example `https://uniresolver.io/1.0/identifiers/`. If not provided - will use internal resolver - `DAF_TG_URI` | `https://edge.uport.me/graphql` | Trust Graph Endpoint URL - `DAF_TG_WSURI` | `undefined` | Trust Graph Endpoint WebSocket URL \ No newline at end of file + +| ENV | Default | Description | +| ---------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `DEBUG` | `undefined` | Use `*` to see all debug info. [More options](https://github.com/visionmedia/debug#environment-variables) | +| `DAF_IDENTITY_STORE` | `~/.daf/identity-store.json` | Identity keyPair storage | +| `DAF_DATA_STORE` | `~/.daf/data-store.sqlite3` | Sqlite3 database containing messages, credentials, presentations, etc. | +| `DAF_ENCRYPTION_STORE` | `~/.daf/encryption-store.json` | Encryption keyPair storage. Used for DIDComm | +| `DAF_INFURA_ID` | `5ffc47f65c4042ce847ef66a3fa70d4c` | Used for calls to the Ethereum blockchain | +| `DAF_UNIVERSAL_RESOLVER_URL` | `undefined` | Example `https://uniresolver.io/1.0/identifiers/`. If not provided - will use internal resolver | +| `DAF_TG_URI` | `https://edge.uport.me/graphql` | Trust Graph Endpoint URL | +| `DAF_TG_WSURI` | `undefined` | Trust Graph Endpoint WebSocket URL | diff --git a/packages/daf-cli/package.json b/packages/daf-cli/package.json index 673835da8..be03858e8 100644 --- a/packages/daf-cli/package.json +++ b/packages/daf-cli/package.json @@ -28,6 +28,7 @@ "daf-sodium-fs": "^0.0.26", "daf-trust-graph": "^0.0.26", "daf-w3c": "^0.0.26", + "date-fns": "^2.8.1", "debug": "^4.1.1", "inquirer": "^7.0.0", "qrcode-terminal": "^0.12.0", diff --git a/packages/daf-cli/src/cli.ts b/packages/daf-cli/src/cli.ts index 296e05c58..806302c08 100644 --- a/packages/daf-cli/src/cli.ts +++ b/packages/daf-cli/src/cli.ts @@ -3,8 +3,9 @@ import './identity-manager' import './did-resolver' import './credential' import './services' +import './data-explorer' program.parse(process.argv) if (!process.argv.slice(2).length) { program.outputHelp() -} \ No newline at end of file +} diff --git a/packages/daf-cli/src/data-explorer.ts b/packages/daf-cli/src/data-explorer.ts new file mode 100644 index 000000000..2e5d82708 --- /dev/null +++ b/packages/daf-cli/src/data-explorer.ts @@ -0,0 +1,126 @@ +import { core, dataStore } from './setup' +import program from 'commander' +import inquirer from 'inquirer' +import { formatDistanceToNow } from 'date-fns' +import { printTable } from 'console-table-printer' + +program + .command('data-explorer') + .description('Explore data store') + .option('-i, --identities', 'List known identities') + .option('-m, --messages', 'List messages') + .action(async cmd => { + if (cmd.identities) { + const dids = await dataStore.allIdentities() + if (dids.length === 0) { + console.error('No dids') + process.exit() + } + + const identities = [] + for (const did of dids) { + const shortId = await dataStore.shortId(did.did) + identities.push({ + did: did.did, + shortId, + }) + } + + const answers = await inquirer.prompt([ + { + type: 'list', + name: 'sub', + choices: identities.map(identity => ({ + value: identity.did, + name: `${identity.did} - ${identity.shortId}`, + })), + message: 'Identity', + }, + { + type: 'list', + name: 'type', + choices: ['Sent Messages', 'Received Messages', 'Credentials'], + message: 'List', + }, + ]) + + switch (answers.type) { + case 'Sent Messages': + showMessageList(await dataStore.findMessages({ iss: answers.sub })) + break + case 'Received Messages': + showMessageList(await dataStore.findMessages({ sub: answers.sub })) + break + case 'Credentials': + showCredentials(answers.sub) + break + } + } + }) + +const showMessageList = async (messages: any) => { + if (messages.length === 0) { + console.error('No messages') + process.exit() + } + + const answers = await inquirer.prompt([ + { + type: 'list', + name: 'hash', + choices: messages.map((item: any) => ({ + name: `${formatDistanceToNow(item.nbf * 1000)} ${item.type}`, + value: item.hash, + })), + message: 'Message', + }, + ]) + showMessage(answers.hash) +} + +const showMessage = async (hash: string) => { + const message = await dataStore.findMessage(hash) + console.log(message) + + const table = [] + const credentials = await dataStore.credentialsForMessageHash(hash) + if (credentials.length > 0) { + for (const credential of credentials) { + const fields = await dataStore.credentialsFieldsForClaimHash(credential.hash) + const issuer = await dataStore.shortId(credential.iss.did) + const subject = await dataStore.shortId(credential.sub.did) + for (const field of fields) { + table.push({ + from: issuer, + to: subject, + type: field.type, + value: field.value, + }) + } + } + console.log('\nVerifiable Credentials:') + printTable(table) + } +} + +const showCredentials = async (did: string) => { + const table = [] + const credentials = await dataStore.findCredentials({ sub: did }) + if (credentials.length > 0) { + for (const credential of credentials) { + const fields = await dataStore.credentialsFieldsForClaimHash(credential.hash) + const issuer = await dataStore.shortId(credential.iss.did) + const subject = await dataStore.shortId(credential.sub.did) + for (const field of fields) { + table.push({ + from: issuer, + to: subject, + type: field.type, + value: field.value, + }) + } + } + console.log('\nVerifiable Credentials:') + printTable(table) + } +} diff --git a/yarn.lock b/yarn.lock index 679110b06..178822646 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2901,6 +2901,11 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" +date-fns@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.8.1.tgz#2109362ccb6c87c3ca011e9e31f702bc09e4123b" + integrity sha512-EL/C8IHvYRwAHYgFRse4MGAPSqlJVlOrhVYZ75iQBKrnv+ZedmYsgwH3t+BCDuZDXpoo07+q9j4qgSSOa7irJg== + dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"