@didcid/keymaster 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +199 -0
- package/dist/esm/cli.js +1213 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/types/cli.d.ts +2 -0
- package/package.json +10 -3
package/dist/esm/cli.js
ADDED
|
@@ -0,0 +1,1213 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import dotenv from 'dotenv';
|
|
6
|
+
import Keymaster from './keymaster.js';
|
|
7
|
+
import GatekeeperClient from '@didcid/gatekeeper/client';
|
|
8
|
+
import CipherNode from '@didcid/cipher/node';
|
|
9
|
+
import WalletJson from './db/json.js';
|
|
10
|
+
import WalletSQLite from './db/sqlite.js';
|
|
11
|
+
dotenv.config();
|
|
12
|
+
let keymaster;
|
|
13
|
+
const UPDATE_OK = "OK";
|
|
14
|
+
const UPDATE_FAILED = "Update failed";
|
|
15
|
+
program
|
|
16
|
+
.version('0.2.0')
|
|
17
|
+
.description('Keymaster CLI - Archon wallet management tool')
|
|
18
|
+
.configureHelp({ sortSubcommands: true });
|
|
19
|
+
// Wallet commands
|
|
20
|
+
program
|
|
21
|
+
.command('create-wallet')
|
|
22
|
+
.description('Create a new wallet (or show existing wallet)')
|
|
23
|
+
.action(async () => {
|
|
24
|
+
try {
|
|
25
|
+
const wallet = await keymaster.loadWallet();
|
|
26
|
+
console.log(JSON.stringify(wallet, null, 4));
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.error(error.error || error.message || error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
program
|
|
33
|
+
.command('new-wallet')
|
|
34
|
+
.description('Create a new wallet')
|
|
35
|
+
.action(async () => {
|
|
36
|
+
try {
|
|
37
|
+
await keymaster.newWallet("", true);
|
|
38
|
+
const wallet = await keymaster.loadWallet();
|
|
39
|
+
console.log(JSON.stringify(wallet, null, 4));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error(error.error || error.message || error);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
program
|
|
46
|
+
.command('check-wallet')
|
|
47
|
+
.description('Validate DIDs in wallet')
|
|
48
|
+
.action(async () => {
|
|
49
|
+
try {
|
|
50
|
+
const { checked, invalid, deleted } = await keymaster.checkWallet();
|
|
51
|
+
if (invalid === 0 && deleted === 0) {
|
|
52
|
+
console.log(`${checked} DIDs checked, no problems found`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log(`${checked} DIDs checked, ${invalid} invalid DIDs found, ${deleted} deleted DIDs found`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(error.error || error.message || error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
program
|
|
63
|
+
.command('fix-wallet')
|
|
64
|
+
.description('Remove invalid DIDs from the wallet')
|
|
65
|
+
.action(async () => {
|
|
66
|
+
try {
|
|
67
|
+
const { idsRemoved, ownedRemoved, heldRemoved, namesRemoved } = await keymaster.fixWallet();
|
|
68
|
+
console.log(`${idsRemoved} IDs and ${ownedRemoved} owned DIDs and ${heldRemoved} held DIDs and ${namesRemoved} names were removed`);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error(error.error || error.message || error);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
program
|
|
75
|
+
.command('import-wallet <recovery-phrase>')
|
|
76
|
+
.description('Create new wallet from a recovery phrase')
|
|
77
|
+
.action(async (recoveryPhrase) => {
|
|
78
|
+
try {
|
|
79
|
+
const wallet = await keymaster.newWallet(recoveryPhrase);
|
|
80
|
+
console.log(JSON.stringify(wallet, null, 4));
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.error(error.error || error.message || error);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
program
|
|
87
|
+
.command('show-wallet')
|
|
88
|
+
.description('Show wallet')
|
|
89
|
+
.action(async () => {
|
|
90
|
+
try {
|
|
91
|
+
const wallet = await keymaster.loadWallet();
|
|
92
|
+
console.log(JSON.stringify(wallet, null, 4));
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error(error.error || error.message || error);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
program
|
|
99
|
+
.command('backup-wallet-file <file>')
|
|
100
|
+
.description('Backup wallet to file')
|
|
101
|
+
.action(async (file) => {
|
|
102
|
+
try {
|
|
103
|
+
const wallet = await keymaster.exportEncryptedWallet();
|
|
104
|
+
fs.writeFileSync(file, JSON.stringify(wallet, null, 4));
|
|
105
|
+
console.log(UPDATE_OK);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error(error.error || error.message || error);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
program
|
|
112
|
+
.command('restore-wallet-file <file>')
|
|
113
|
+
.description('Restore wallet from backup file')
|
|
114
|
+
.action(async (file) => {
|
|
115
|
+
try {
|
|
116
|
+
const contents = fs.readFileSync(file).toString();
|
|
117
|
+
const wallet = JSON.parse(contents);
|
|
118
|
+
const ok = await keymaster.saveWallet(wallet, true);
|
|
119
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error(error.error || error.message || error);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
program
|
|
126
|
+
.command('show-mnemonic')
|
|
127
|
+
.description('Show recovery phrase for wallet')
|
|
128
|
+
.action(async () => {
|
|
129
|
+
try {
|
|
130
|
+
const mnemonic = await keymaster.decryptMnemonic();
|
|
131
|
+
console.log(mnemonic);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
console.error(error.error || error.message || error);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
program
|
|
138
|
+
.command('backup-wallet-did')
|
|
139
|
+
.description('Backup wallet to encrypted DID and seed bank')
|
|
140
|
+
.action(async () => {
|
|
141
|
+
try {
|
|
142
|
+
const did = await keymaster.backupWallet();
|
|
143
|
+
console.log(did);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error(error.error || error.message || error);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
program
|
|
150
|
+
.command('recover-wallet-did [did]')
|
|
151
|
+
.description('Recover wallet from seed bank or encrypted DID')
|
|
152
|
+
.action(async (did) => {
|
|
153
|
+
try {
|
|
154
|
+
const wallet = await keymaster.recoverWallet(did);
|
|
155
|
+
console.log(JSON.stringify(wallet, null, 4));
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error(error.error || error.message || error);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
// Identity commands
|
|
162
|
+
program
|
|
163
|
+
.command('create-id <name>')
|
|
164
|
+
.description('Create a new decentralized ID')
|
|
165
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
166
|
+
.action(async (name, options) => {
|
|
167
|
+
try {
|
|
168
|
+
const { registry } = options;
|
|
169
|
+
const did = await keymaster.createId(name, { registry });
|
|
170
|
+
console.log(did);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error(error.error || error.message || error);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
program
|
|
177
|
+
.command('resolve-id')
|
|
178
|
+
.description('Resolves the current ID')
|
|
179
|
+
.action(async () => {
|
|
180
|
+
try {
|
|
181
|
+
const current = await keymaster.getCurrentId();
|
|
182
|
+
if (!current) {
|
|
183
|
+
console.error('No current ID set');
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const doc = await keymaster.resolveDID(current);
|
|
187
|
+
console.log(JSON.stringify(doc, null, 4));
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
console.error(error.error || error.message || error);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
program
|
|
194
|
+
.command('backup-id')
|
|
195
|
+
.description('Backup the current ID to its registry')
|
|
196
|
+
.action(async () => {
|
|
197
|
+
try {
|
|
198
|
+
const ok = await keymaster.backupId();
|
|
199
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
console.error(error.error || error.message || error);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
program
|
|
206
|
+
.command('recover-id <did>')
|
|
207
|
+
.description('Recovers the ID from the DID')
|
|
208
|
+
.action(async (did) => {
|
|
209
|
+
try {
|
|
210
|
+
const response = await keymaster.recoverId(did);
|
|
211
|
+
console.log(response);
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
console.error(error.error || error.message || error);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
program
|
|
218
|
+
.command('remove-id <name>')
|
|
219
|
+
.description('Deletes named ID')
|
|
220
|
+
.action(async (name) => {
|
|
221
|
+
try {
|
|
222
|
+
await keymaster.removeId(name);
|
|
223
|
+
console.log(`ID ${name} removed`);
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
console.error(error.error || error.message || error);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
program
|
|
230
|
+
.command('rename-id <oldName> <newName>')
|
|
231
|
+
.description('Renames the ID')
|
|
232
|
+
.action(async (oldName, newName) => {
|
|
233
|
+
try {
|
|
234
|
+
const ok = await keymaster.renameId(oldName, newName);
|
|
235
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
console.error(error.error || error.message || error);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
program
|
|
242
|
+
.command('list-ids')
|
|
243
|
+
.description('List IDs and show current ID')
|
|
244
|
+
.action(async () => {
|
|
245
|
+
try {
|
|
246
|
+
const current = await keymaster.getCurrentId();
|
|
247
|
+
const ids = await keymaster.listIds();
|
|
248
|
+
for (const id of ids) {
|
|
249
|
+
if (id === current) {
|
|
250
|
+
console.log(id, ' <<< current');
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
console.log(id);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.error(error.error || error.message || error);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
program
|
|
262
|
+
.command('use-id <name>')
|
|
263
|
+
.description('Set the current ID')
|
|
264
|
+
.action(async (name) => {
|
|
265
|
+
try {
|
|
266
|
+
await keymaster.setCurrentId(name);
|
|
267
|
+
console.log(UPDATE_OK);
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
console.error(error.error || error.message || error);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
program
|
|
274
|
+
.command('rotate-keys')
|
|
275
|
+
.description('Generates new set of keys for current ID')
|
|
276
|
+
.action(async () => {
|
|
277
|
+
try {
|
|
278
|
+
const ok = await keymaster.rotateKeys();
|
|
279
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
console.error(error.error || error.message || error);
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
// DID commands
|
|
286
|
+
program
|
|
287
|
+
.command('resolve-did <did> [confirm]')
|
|
288
|
+
.description('Return document associated with DID')
|
|
289
|
+
.action(async (did, confirm) => {
|
|
290
|
+
try {
|
|
291
|
+
const doc = await keymaster.resolveDID(did, { confirm: !!confirm });
|
|
292
|
+
console.log(JSON.stringify(doc, null, 4));
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
console.error(`cannot resolve ${did}`);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
program
|
|
299
|
+
.command('resolve-did-version <did> <version>')
|
|
300
|
+
.description('Return specified version of document associated with DID')
|
|
301
|
+
.action(async (did, version) => {
|
|
302
|
+
try {
|
|
303
|
+
const doc = await keymaster.resolveDID(did, { versionSequence: parseInt(version, 10) });
|
|
304
|
+
console.log(JSON.stringify(doc, null, 4));
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
console.error(`cannot resolve ${did}`);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
program
|
|
311
|
+
.command('revoke-did <did>')
|
|
312
|
+
.description('Permanently revoke a DID')
|
|
313
|
+
.action(async (did) => {
|
|
314
|
+
try {
|
|
315
|
+
const ok = await keymaster.revokeDID(did);
|
|
316
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
console.error(`cannot revoke ${did}`);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
// Encryption commands
|
|
323
|
+
program
|
|
324
|
+
.command('encrypt-message <message> <did>')
|
|
325
|
+
.description('Encrypt a message for a DID')
|
|
326
|
+
.action(async (msg, did) => {
|
|
327
|
+
try {
|
|
328
|
+
const cipherDid = await keymaster.encryptMessage(msg, did);
|
|
329
|
+
console.log(cipherDid);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
console.error(error.error || error.message || error);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
program
|
|
336
|
+
.command('encrypt-file <file> <did>')
|
|
337
|
+
.description('Encrypt a file for a DID')
|
|
338
|
+
.action(async (file, did) => {
|
|
339
|
+
try {
|
|
340
|
+
const contents = fs.readFileSync(file).toString();
|
|
341
|
+
const cipherDid = await keymaster.encryptMessage(contents, did);
|
|
342
|
+
console.log(cipherDid);
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
console.error(error.error || error.message || error);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
program
|
|
349
|
+
.command('decrypt-did <did>')
|
|
350
|
+
.description('Decrypt an encrypted message DID')
|
|
351
|
+
.action(async (did) => {
|
|
352
|
+
try {
|
|
353
|
+
const plaintext = await keymaster.decryptMessage(did);
|
|
354
|
+
console.log(plaintext);
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
console.error(`cannot decrypt ${did}`);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
program
|
|
361
|
+
.command('decrypt-json <did>')
|
|
362
|
+
.description('Decrypt an encrypted JSON DID')
|
|
363
|
+
.action(async (did) => {
|
|
364
|
+
try {
|
|
365
|
+
const json = await keymaster.decryptJSON(did);
|
|
366
|
+
console.log(JSON.stringify(json, null, 4));
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
console.error(`cannot decrypt ${did}`);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
// Signing commands
|
|
373
|
+
program
|
|
374
|
+
.command('sign-file <file>')
|
|
375
|
+
.description('Sign a JSON file')
|
|
376
|
+
.action(async (file) => {
|
|
377
|
+
try {
|
|
378
|
+
const contents = fs.readFileSync(file).toString();
|
|
379
|
+
const json = await keymaster.addProof(JSON.parse(contents));
|
|
380
|
+
console.log(JSON.stringify(json, null, 4));
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
console.error(error.error || error.message || error);
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
program
|
|
387
|
+
.command('verify-file <file>')
|
|
388
|
+
.description('Verify the proof in a JSON file')
|
|
389
|
+
.action(async (file) => {
|
|
390
|
+
try {
|
|
391
|
+
const json = JSON.parse(fs.readFileSync(file).toString());
|
|
392
|
+
const isValid = await keymaster.verifyProof(json);
|
|
393
|
+
console.log(`proof in ${file}`, isValid ? 'is valid' : 'is NOT valid');
|
|
394
|
+
}
|
|
395
|
+
catch (error) {
|
|
396
|
+
console.error(error.error || error.message || error);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
// Challenge commands
|
|
400
|
+
program
|
|
401
|
+
.command('create-challenge [file]')
|
|
402
|
+
.description('Create a challenge (optionally from a file)')
|
|
403
|
+
.option('-n, --name <name>', 'DID name')
|
|
404
|
+
.action(async (file, options) => {
|
|
405
|
+
try {
|
|
406
|
+
const { name } = options;
|
|
407
|
+
const challenge = file ? JSON.parse(fs.readFileSync(file).toString()) : undefined;
|
|
408
|
+
const did = await keymaster.createChallenge(challenge, { name });
|
|
409
|
+
console.log(did);
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
console.error(error.error || error.message || error);
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
program
|
|
416
|
+
.command('create-challenge-cc <did>')
|
|
417
|
+
.description('Create a challenge from a credential DID')
|
|
418
|
+
.option('-n, --name <name>', 'DID name')
|
|
419
|
+
.action(async (credentialDID, options) => {
|
|
420
|
+
try {
|
|
421
|
+
const { name } = options;
|
|
422
|
+
const challenge = { credentials: [{ schema: credentialDID }] };
|
|
423
|
+
const did = await keymaster.createChallenge(challenge, { name });
|
|
424
|
+
console.log(did);
|
|
425
|
+
}
|
|
426
|
+
catch (error) {
|
|
427
|
+
console.error(error.error || error.message || error);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
program
|
|
431
|
+
.command('create-response <challenge>')
|
|
432
|
+
.description('Create a response to a challenge')
|
|
433
|
+
.action(async (challenge) => {
|
|
434
|
+
try {
|
|
435
|
+
const did = await keymaster.createResponse(challenge);
|
|
436
|
+
console.log(did);
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
console.error(error.error || error.message || error);
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
program
|
|
443
|
+
.command('verify-response <response>')
|
|
444
|
+
.description('Decrypt and validate a response to a challenge')
|
|
445
|
+
.action(async (response) => {
|
|
446
|
+
try {
|
|
447
|
+
const vp = await keymaster.verifyResponse(response);
|
|
448
|
+
console.log(JSON.stringify(vp, null, 4));
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
console.error(error.error || error.message || error);
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
// Credential commands
|
|
455
|
+
program
|
|
456
|
+
.command('bind-credential <schema> <subject>')
|
|
457
|
+
.description('Create bound credential for a user')
|
|
458
|
+
.action(async (schema, subject) => {
|
|
459
|
+
try {
|
|
460
|
+
const vc = await keymaster.bindCredential(subject, { schema });
|
|
461
|
+
console.log(JSON.stringify(vc, null, 4));
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
console.error(error.error || error.message || error);
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
program
|
|
468
|
+
.command('issue-credential <file>')
|
|
469
|
+
.description('Sign and encrypt a bound credential file')
|
|
470
|
+
.option('-n, --name <name>', 'DID name')
|
|
471
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
472
|
+
.action(async (file, options) => {
|
|
473
|
+
try {
|
|
474
|
+
const { name, registry } = options;
|
|
475
|
+
const vc = JSON.parse(fs.readFileSync(file).toString());
|
|
476
|
+
const did = await keymaster.issueCredential(vc, { registry, name });
|
|
477
|
+
console.log(did);
|
|
478
|
+
}
|
|
479
|
+
catch (error) {
|
|
480
|
+
console.error(error.error || error.message || error);
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
program
|
|
484
|
+
.command('list-issued')
|
|
485
|
+
.description('List issued credentials')
|
|
486
|
+
.action(async () => {
|
|
487
|
+
try {
|
|
488
|
+
const response = await keymaster.listIssued();
|
|
489
|
+
console.log(JSON.stringify(response, null, 4));
|
|
490
|
+
}
|
|
491
|
+
catch (error) {
|
|
492
|
+
console.error(error.error || error.message || error);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
program
|
|
496
|
+
.command('revoke-credential <did>')
|
|
497
|
+
.description('Revokes a verifiable credential')
|
|
498
|
+
.action(async (did) => {
|
|
499
|
+
try {
|
|
500
|
+
const ok = await keymaster.revokeCredential(did);
|
|
501
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
502
|
+
}
|
|
503
|
+
catch (error) {
|
|
504
|
+
console.error(error.error || error.message || error);
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
program
|
|
508
|
+
.command('accept-credential <did>')
|
|
509
|
+
.description('Save verifiable credential for current ID')
|
|
510
|
+
.option('-n, --name <name>', 'DID name')
|
|
511
|
+
.action(async (did, options) => {
|
|
512
|
+
const { name } = options;
|
|
513
|
+
try {
|
|
514
|
+
const ok = await keymaster.acceptCredential(did);
|
|
515
|
+
if (ok) {
|
|
516
|
+
console.log(UPDATE_OK);
|
|
517
|
+
if (name) {
|
|
518
|
+
await keymaster.addName(name, did);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
console.log(UPDATE_FAILED);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
catch (error) {
|
|
526
|
+
console.error(error.error || error.message || error);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
program
|
|
530
|
+
.command('list-credentials')
|
|
531
|
+
.description('List credentials by current ID')
|
|
532
|
+
.action(async () => {
|
|
533
|
+
try {
|
|
534
|
+
const held = await keymaster.listCredentials();
|
|
535
|
+
console.log(JSON.stringify(held, null, 4));
|
|
536
|
+
}
|
|
537
|
+
catch (error) {
|
|
538
|
+
console.error(error.error || error.message || error);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
program
|
|
542
|
+
.command('get-credential <did>')
|
|
543
|
+
.description('Get credential by DID')
|
|
544
|
+
.action(async (did) => {
|
|
545
|
+
try {
|
|
546
|
+
const credential = await keymaster.getCredential(did);
|
|
547
|
+
console.log(JSON.stringify(credential, null, 4));
|
|
548
|
+
}
|
|
549
|
+
catch (error) {
|
|
550
|
+
console.error(error.error || error.message || error);
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
program
|
|
554
|
+
.command('publish-credential <did>')
|
|
555
|
+
.description('Publish the existence of a credential to the current user manifest')
|
|
556
|
+
.action(async (did) => {
|
|
557
|
+
try {
|
|
558
|
+
const response = await keymaster.publishCredential(did, { reveal: false });
|
|
559
|
+
console.log(JSON.stringify(response, null, 4));
|
|
560
|
+
}
|
|
561
|
+
catch (error) {
|
|
562
|
+
console.error(error.error || error.message || error);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
program
|
|
566
|
+
.command('reveal-credential <did>')
|
|
567
|
+
.description('Reveal a credential to the current user manifest')
|
|
568
|
+
.action(async (did) => {
|
|
569
|
+
try {
|
|
570
|
+
const response = await keymaster.publishCredential(did, { reveal: true });
|
|
571
|
+
console.log(JSON.stringify(response, null, 4));
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
console.error(error.error || error.message || error);
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
program
|
|
578
|
+
.command('unpublish-credential <did>')
|
|
579
|
+
.description('Remove a credential from the current user manifest')
|
|
580
|
+
.action(async (did) => {
|
|
581
|
+
try {
|
|
582
|
+
const response = await keymaster.unpublishCredential(did);
|
|
583
|
+
console.log(response);
|
|
584
|
+
}
|
|
585
|
+
catch (error) {
|
|
586
|
+
console.error(error.error || error.message || error);
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
// Name commands
|
|
590
|
+
program
|
|
591
|
+
.command('add-name <name> <did>')
|
|
592
|
+
.description('Add a name for a DID')
|
|
593
|
+
.action(async (name, did) => {
|
|
594
|
+
try {
|
|
595
|
+
await keymaster.addName(name, did);
|
|
596
|
+
console.log(UPDATE_OK);
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
console.error(error.error || error.message || error);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
program
|
|
603
|
+
.command('get-name <name>')
|
|
604
|
+
.description('Get DID assigned to name')
|
|
605
|
+
.action(async (name) => {
|
|
606
|
+
try {
|
|
607
|
+
const did = await keymaster.getName(name);
|
|
608
|
+
console.log(did || `${name} not found`);
|
|
609
|
+
}
|
|
610
|
+
catch (error) {
|
|
611
|
+
console.error(error.error || error.message || error);
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
program
|
|
615
|
+
.command('remove-name <name>')
|
|
616
|
+
.description('Removes a name for a DID')
|
|
617
|
+
.action(async (name) => {
|
|
618
|
+
try {
|
|
619
|
+
await keymaster.removeName(name);
|
|
620
|
+
console.log(UPDATE_OK);
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
console.error(error.error || error.message || error);
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
program
|
|
627
|
+
.command('list-names')
|
|
628
|
+
.description('List DID names (aliases)')
|
|
629
|
+
.action(async () => {
|
|
630
|
+
try {
|
|
631
|
+
const names = await keymaster.listNames();
|
|
632
|
+
if (names) {
|
|
633
|
+
console.log(JSON.stringify(names, null, 4));
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
console.log("No names defined");
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
catch (error) {
|
|
640
|
+
console.error(error.error || error.message || error);
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
// Group commands
|
|
644
|
+
program
|
|
645
|
+
.command('create-group <groupName>')
|
|
646
|
+
.description('Create a new group')
|
|
647
|
+
.option('-n, --name <name>', 'DID name')
|
|
648
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
649
|
+
.action(async (groupName, options) => {
|
|
650
|
+
try {
|
|
651
|
+
const { name, registry } = options;
|
|
652
|
+
const did = await keymaster.createGroup(groupName, { name, registry });
|
|
653
|
+
console.log(did);
|
|
654
|
+
}
|
|
655
|
+
catch (error) {
|
|
656
|
+
console.error(error.error || error.message || error);
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
program
|
|
660
|
+
.command('list-groups')
|
|
661
|
+
.description('List groups owned by current ID')
|
|
662
|
+
.action(async () => {
|
|
663
|
+
try {
|
|
664
|
+
const groups = await keymaster.listGroups();
|
|
665
|
+
console.log(JSON.stringify(groups, null, 4));
|
|
666
|
+
}
|
|
667
|
+
catch (error) {
|
|
668
|
+
console.error(error.error || error.message || error);
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
program
|
|
672
|
+
.command('get-group <did>')
|
|
673
|
+
.description('Get group by DID')
|
|
674
|
+
.action(async (did) => {
|
|
675
|
+
try {
|
|
676
|
+
const group = await keymaster.getGroup(did);
|
|
677
|
+
console.log(JSON.stringify(group, null, 4));
|
|
678
|
+
}
|
|
679
|
+
catch (error) {
|
|
680
|
+
console.error(error.error || error.message || error);
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
program
|
|
684
|
+
.command('add-group-member <group> <member>')
|
|
685
|
+
.description('Add a member to a group')
|
|
686
|
+
.action(async (group, member) => {
|
|
687
|
+
try {
|
|
688
|
+
const response = await keymaster.addGroupMember(group, member);
|
|
689
|
+
console.log(response);
|
|
690
|
+
}
|
|
691
|
+
catch (error) {
|
|
692
|
+
console.error(error.error || error.message || error);
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
program
|
|
696
|
+
.command('remove-group-member <group> <member>')
|
|
697
|
+
.description('Remove a member from a group')
|
|
698
|
+
.action(async (group, member) => {
|
|
699
|
+
try {
|
|
700
|
+
const response = await keymaster.removeGroupMember(group, member);
|
|
701
|
+
console.log(response);
|
|
702
|
+
}
|
|
703
|
+
catch (error) {
|
|
704
|
+
console.error(error.error || error.message || error);
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
program
|
|
708
|
+
.command('test-group <group> [member]')
|
|
709
|
+
.description('Determine if a member is in a group')
|
|
710
|
+
.action(async (group, member) => {
|
|
711
|
+
try {
|
|
712
|
+
const response = await keymaster.testGroup(group, member);
|
|
713
|
+
console.log(response);
|
|
714
|
+
}
|
|
715
|
+
catch (error) {
|
|
716
|
+
console.error(error.error || error.message || error);
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
// Schema commands
|
|
720
|
+
program
|
|
721
|
+
.command('create-schema <file>')
|
|
722
|
+
.description('Create a schema from a file')
|
|
723
|
+
.option('-n, --name <name>', 'DID name')
|
|
724
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
725
|
+
.action(async (file, options) => {
|
|
726
|
+
try {
|
|
727
|
+
const { name, registry } = options;
|
|
728
|
+
const schema = JSON.parse(fs.readFileSync(file).toString());
|
|
729
|
+
const did = await keymaster.createSchema(schema, { name, registry });
|
|
730
|
+
console.log(did);
|
|
731
|
+
}
|
|
732
|
+
catch (error) {
|
|
733
|
+
console.error(error.error || error.message || error);
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
program
|
|
737
|
+
.command('list-schemas')
|
|
738
|
+
.description('List schemas owned by current ID')
|
|
739
|
+
.action(async () => {
|
|
740
|
+
try {
|
|
741
|
+
const schemas = await keymaster.listSchemas();
|
|
742
|
+
console.log(JSON.stringify(schemas, null, 4));
|
|
743
|
+
}
|
|
744
|
+
catch (error) {
|
|
745
|
+
console.error(error.error || error.message || error);
|
|
746
|
+
}
|
|
747
|
+
});
|
|
748
|
+
program
|
|
749
|
+
.command('get-schema <did>')
|
|
750
|
+
.description('Get schema by DID')
|
|
751
|
+
.action(async (did) => {
|
|
752
|
+
try {
|
|
753
|
+
const schema = await keymaster.getSchema(did);
|
|
754
|
+
console.log(JSON.stringify(schema, null, 4));
|
|
755
|
+
}
|
|
756
|
+
catch (error) {
|
|
757
|
+
console.error(error.error || error.message || error);
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
program
|
|
761
|
+
.command('create-schema-template <schema>')
|
|
762
|
+
.description('Create a template from a schema')
|
|
763
|
+
.action(async (schema) => {
|
|
764
|
+
try {
|
|
765
|
+
const template = await keymaster.createTemplate(schema);
|
|
766
|
+
console.log(JSON.stringify(template, null, 4));
|
|
767
|
+
}
|
|
768
|
+
catch (error) {
|
|
769
|
+
console.error(error.error || error.message || error);
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
// Asset commands
|
|
773
|
+
program
|
|
774
|
+
.command('create-asset')
|
|
775
|
+
.description('Create an empty asset')
|
|
776
|
+
.option('-n, --name <name>', 'DID name')
|
|
777
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
778
|
+
.action(async (options) => {
|
|
779
|
+
try {
|
|
780
|
+
const { name, registry } = options;
|
|
781
|
+
const did = await keymaster.createAsset({}, { name, registry });
|
|
782
|
+
console.log(did);
|
|
783
|
+
}
|
|
784
|
+
catch (error) {
|
|
785
|
+
console.error(error.error || error.message || error);
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
program
|
|
789
|
+
.command('create-asset-json <file>')
|
|
790
|
+
.description('Create an asset from a JSON file')
|
|
791
|
+
.option('-n, --name <name>', 'DID name')
|
|
792
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
793
|
+
.action(async (file, options) => {
|
|
794
|
+
try {
|
|
795
|
+
const { name, registry } = options;
|
|
796
|
+
const data = JSON.parse(fs.readFileSync(file).toString());
|
|
797
|
+
const did = await keymaster.createAsset(data, { name, registry });
|
|
798
|
+
console.log(did);
|
|
799
|
+
}
|
|
800
|
+
catch (error) {
|
|
801
|
+
console.error(error.error || error.message || error);
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
program
|
|
805
|
+
.command('create-asset-image <file>')
|
|
806
|
+
.description('Create an asset from an image file')
|
|
807
|
+
.option('-n, --name <name>', 'DID name')
|
|
808
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
809
|
+
.action(async (file, options) => {
|
|
810
|
+
try {
|
|
811
|
+
const { name, registry } = options;
|
|
812
|
+
const data = fs.readFileSync(file);
|
|
813
|
+
const did = await keymaster.createImage(data, { name, registry });
|
|
814
|
+
console.log(did);
|
|
815
|
+
}
|
|
816
|
+
catch (error) {
|
|
817
|
+
console.error(error.error || error.message || error);
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
program
|
|
821
|
+
.command('create-asset-document <file>')
|
|
822
|
+
.description('Create an asset from a document file')
|
|
823
|
+
.option('-n, --name <name>', 'DID name')
|
|
824
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
825
|
+
.action(async (file, options) => {
|
|
826
|
+
try {
|
|
827
|
+
const { name, registry } = options;
|
|
828
|
+
const data = fs.readFileSync(file);
|
|
829
|
+
const filename = file.split('/').pop();
|
|
830
|
+
const did = await keymaster.createDocument(data, { filename, name, registry });
|
|
831
|
+
console.log(did);
|
|
832
|
+
}
|
|
833
|
+
catch (error) {
|
|
834
|
+
console.error(error.error || error.message || error);
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
program
|
|
838
|
+
.command('get-asset <id>')
|
|
839
|
+
.description('Get asset by name or DID')
|
|
840
|
+
.action(async (id) => {
|
|
841
|
+
try {
|
|
842
|
+
const asset = await keymaster.resolveAsset(id);
|
|
843
|
+
console.log(JSON.stringify(asset, null, 4));
|
|
844
|
+
}
|
|
845
|
+
catch (error) {
|
|
846
|
+
console.error(error.error || error.message || error);
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
program
|
|
850
|
+
.command('update-asset-json <id> <file>')
|
|
851
|
+
.description('Update an asset from a JSON file')
|
|
852
|
+
.action(async (id, file) => {
|
|
853
|
+
try {
|
|
854
|
+
const data = JSON.parse(fs.readFileSync(file).toString());
|
|
855
|
+
const ok = await keymaster.updateAsset(id, data);
|
|
856
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
857
|
+
}
|
|
858
|
+
catch (error) {
|
|
859
|
+
console.error(error.error || error.message || error);
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
program
|
|
863
|
+
.command('update-asset-image <id> <file>')
|
|
864
|
+
.description('Update an asset from an image file')
|
|
865
|
+
.action(async (id, file) => {
|
|
866
|
+
try {
|
|
867
|
+
const data = fs.readFileSync(file);
|
|
868
|
+
const ok = await keymaster.updateImage(id, data);
|
|
869
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
870
|
+
}
|
|
871
|
+
catch (error) {
|
|
872
|
+
console.error(error.error || error.message || error);
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
program
|
|
876
|
+
.command('update-asset-document <id> <file>')
|
|
877
|
+
.description('Update an asset from a document file')
|
|
878
|
+
.action(async (id, file) => {
|
|
879
|
+
try {
|
|
880
|
+
const data = fs.readFileSync(file);
|
|
881
|
+
const filename = file.split('/').pop();
|
|
882
|
+
const ok = await keymaster.updateDocument(id, data, { filename });
|
|
883
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
884
|
+
}
|
|
885
|
+
catch (error) {
|
|
886
|
+
console.error(error.error || error.message || error);
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
program
|
|
890
|
+
.command('transfer-asset <id> <controller>')
|
|
891
|
+
.description('Transfer asset to a new controller')
|
|
892
|
+
.action(async (id, controller) => {
|
|
893
|
+
try {
|
|
894
|
+
const ok = await keymaster.transferAsset(id, controller);
|
|
895
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
896
|
+
}
|
|
897
|
+
catch (error) {
|
|
898
|
+
console.error(error.error || error.message || error);
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
program
|
|
902
|
+
.command('clone-asset <id>')
|
|
903
|
+
.description('Clone an asset')
|
|
904
|
+
.option('-n, --name <name>', 'DID name')
|
|
905
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
906
|
+
.action(async (id, options) => {
|
|
907
|
+
try {
|
|
908
|
+
const { name, registry } = options;
|
|
909
|
+
const did = await keymaster.cloneAsset(id, { name, registry });
|
|
910
|
+
console.log(did);
|
|
911
|
+
}
|
|
912
|
+
catch (error) {
|
|
913
|
+
console.error(error.error || error.message || error);
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
program
|
|
917
|
+
.command('set-property <id> <key> [value]')
|
|
918
|
+
.description('Assign a key-value pair to an asset')
|
|
919
|
+
.action(async (id, key, value) => {
|
|
920
|
+
try {
|
|
921
|
+
const data = await keymaster.resolveAsset(id);
|
|
922
|
+
if (value) {
|
|
923
|
+
try {
|
|
924
|
+
data[key] = JSON.parse(value);
|
|
925
|
+
}
|
|
926
|
+
catch {
|
|
927
|
+
data[key] = value;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
else {
|
|
931
|
+
delete data[key];
|
|
932
|
+
}
|
|
933
|
+
const ok = await keymaster.updateAsset(id, data);
|
|
934
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
935
|
+
}
|
|
936
|
+
catch (error) {
|
|
937
|
+
console.error(error.error || error.message || error);
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
program
|
|
941
|
+
.command('list-assets')
|
|
942
|
+
.description('List assets owned by current ID')
|
|
943
|
+
.action(async () => {
|
|
944
|
+
try {
|
|
945
|
+
const assets = await keymaster.listAssets();
|
|
946
|
+
console.log(JSON.stringify(assets, null, 4));
|
|
947
|
+
}
|
|
948
|
+
catch (error) {
|
|
949
|
+
console.error(error.error || error.message || error);
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
// Poll commands
|
|
953
|
+
program
|
|
954
|
+
.command('create-poll-template')
|
|
955
|
+
.description('Create a poll template')
|
|
956
|
+
.action(async () => {
|
|
957
|
+
try {
|
|
958
|
+
const template = await keymaster.pollTemplate();
|
|
959
|
+
console.log(JSON.stringify(template, null, 4));
|
|
960
|
+
}
|
|
961
|
+
catch (error) {
|
|
962
|
+
console.error(error.error || error.message || error);
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
program
|
|
966
|
+
.command('create-poll <file>')
|
|
967
|
+
.description('Create a poll')
|
|
968
|
+
.option('-n, --name <name>', 'DID name')
|
|
969
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
970
|
+
.action(async (file, options) => {
|
|
971
|
+
try {
|
|
972
|
+
const { name, registry } = options;
|
|
973
|
+
const poll = JSON.parse(fs.readFileSync(file).toString());
|
|
974
|
+
const did = await keymaster.createPoll(poll, { name, registry });
|
|
975
|
+
console.log(did);
|
|
976
|
+
}
|
|
977
|
+
catch (error) {
|
|
978
|
+
console.error(error.error || error.message || error);
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
program
|
|
982
|
+
.command('view-poll <poll>')
|
|
983
|
+
.description('View poll details')
|
|
984
|
+
.action(async (poll) => {
|
|
985
|
+
try {
|
|
986
|
+
const response = await keymaster.viewPoll(poll);
|
|
987
|
+
console.log(JSON.stringify(response, null, 4));
|
|
988
|
+
}
|
|
989
|
+
catch (error) {
|
|
990
|
+
console.error(error.error || error.message || error);
|
|
991
|
+
}
|
|
992
|
+
});
|
|
993
|
+
program
|
|
994
|
+
.command('vote-poll <poll> <vote> [spoil]')
|
|
995
|
+
.description('Vote in a poll')
|
|
996
|
+
.action(async (poll, vote, spoil) => {
|
|
997
|
+
try {
|
|
998
|
+
const did = await keymaster.votePoll(poll, vote, spoil);
|
|
999
|
+
console.log(did);
|
|
1000
|
+
}
|
|
1001
|
+
catch (error) {
|
|
1002
|
+
console.error(error.error || error.message || error);
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
program
|
|
1006
|
+
.command('update-poll <ballot>')
|
|
1007
|
+
.description('Add a ballot to the poll')
|
|
1008
|
+
.action(async (ballot) => {
|
|
1009
|
+
try {
|
|
1010
|
+
const ok = await keymaster.updatePoll(ballot);
|
|
1011
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1012
|
+
}
|
|
1013
|
+
catch (error) {
|
|
1014
|
+
console.error(error.error || error.message || error);
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
program
|
|
1018
|
+
.command('publish-poll <poll>')
|
|
1019
|
+
.description('Publish results to poll, hiding ballots')
|
|
1020
|
+
.action(async (poll) => {
|
|
1021
|
+
try {
|
|
1022
|
+
const ok = await keymaster.publishPoll(poll);
|
|
1023
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1024
|
+
}
|
|
1025
|
+
catch (error) {
|
|
1026
|
+
console.error(error.error || error.message || error);
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
program
|
|
1030
|
+
.command('reveal-poll <poll>')
|
|
1031
|
+
.description('Publish results to poll, revealing ballots')
|
|
1032
|
+
.action(async (poll) => {
|
|
1033
|
+
try {
|
|
1034
|
+
const ok = await keymaster.publishPoll(poll, { reveal: true });
|
|
1035
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1036
|
+
}
|
|
1037
|
+
catch (error) {
|
|
1038
|
+
console.error(error.error || error.message || error);
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
program
|
|
1042
|
+
.command('unpublish-poll <poll>')
|
|
1043
|
+
.description('Remove results from poll')
|
|
1044
|
+
.action(async (poll) => {
|
|
1045
|
+
try {
|
|
1046
|
+
const ok = await keymaster.unpublishPoll(poll);
|
|
1047
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1048
|
+
}
|
|
1049
|
+
catch (error) {
|
|
1050
|
+
console.error(error.error || error.message || error);
|
|
1051
|
+
}
|
|
1052
|
+
});
|
|
1053
|
+
// Vault commands
|
|
1054
|
+
program
|
|
1055
|
+
.command('create-vault')
|
|
1056
|
+
.description('Create a vault')
|
|
1057
|
+
.option('-n, --name <name>', 'DID name')
|
|
1058
|
+
.option('-r, --registry <registry>', 'registry to use')
|
|
1059
|
+
.option('-s, --secretMembers', 'keep member list secret from each other')
|
|
1060
|
+
.action(async (options) => {
|
|
1061
|
+
try {
|
|
1062
|
+
const did = await keymaster.createVault(options);
|
|
1063
|
+
console.log(did);
|
|
1064
|
+
}
|
|
1065
|
+
catch (error) {
|
|
1066
|
+
console.error(error.error || error.message || error);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
program
|
|
1070
|
+
.command('list-vault-items <id>')
|
|
1071
|
+
.description('List items in the vault')
|
|
1072
|
+
.action(async (id) => {
|
|
1073
|
+
try {
|
|
1074
|
+
const items = await keymaster.listVaultItems(id);
|
|
1075
|
+
console.log(JSON.stringify(items, null, 4));
|
|
1076
|
+
}
|
|
1077
|
+
catch (error) {
|
|
1078
|
+
console.error(error.error || error.message || error);
|
|
1079
|
+
}
|
|
1080
|
+
});
|
|
1081
|
+
program
|
|
1082
|
+
.command('add-vault-member <id> <member>')
|
|
1083
|
+
.description('Add a member to a vault')
|
|
1084
|
+
.action(async (id, member) => {
|
|
1085
|
+
try {
|
|
1086
|
+
const ok = await keymaster.addVaultMember(id, member);
|
|
1087
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1088
|
+
}
|
|
1089
|
+
catch (error) {
|
|
1090
|
+
console.error(error.error || error.message || error);
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
program
|
|
1094
|
+
.command('remove-vault-member <id> <member>')
|
|
1095
|
+
.description('Remove a member from a vault')
|
|
1096
|
+
.action(async (id, member) => {
|
|
1097
|
+
try {
|
|
1098
|
+
const ok = await keymaster.removeVaultMember(id, member);
|
|
1099
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1100
|
+
}
|
|
1101
|
+
catch (error) {
|
|
1102
|
+
console.error(error.error || error.message || error);
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
program
|
|
1106
|
+
.command('list-vault-members <id>')
|
|
1107
|
+
.description('List members of a vault')
|
|
1108
|
+
.action(async (id) => {
|
|
1109
|
+
try {
|
|
1110
|
+
const members = await keymaster.listVaultMembers(id);
|
|
1111
|
+
console.log(JSON.stringify(members, null, 4));
|
|
1112
|
+
}
|
|
1113
|
+
catch (error) {
|
|
1114
|
+
console.error(error.error || error.message || error);
|
|
1115
|
+
}
|
|
1116
|
+
});
|
|
1117
|
+
program
|
|
1118
|
+
.command('add-vault-item <id> <file>')
|
|
1119
|
+
.description('Add an item (file) to a vault')
|
|
1120
|
+
.action(async (id, file) => {
|
|
1121
|
+
try {
|
|
1122
|
+
const data = fs.readFileSync(file);
|
|
1123
|
+
const name = file.split('/').pop();
|
|
1124
|
+
const ok = await keymaster.addVaultItem(id, name, data);
|
|
1125
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1126
|
+
}
|
|
1127
|
+
catch (error) {
|
|
1128
|
+
console.error(error.error || error.message || error);
|
|
1129
|
+
}
|
|
1130
|
+
});
|
|
1131
|
+
program
|
|
1132
|
+
.command('remove-vault-item <id> <item>')
|
|
1133
|
+
.description('Remove an item from a vault')
|
|
1134
|
+
.action(async (id, item) => {
|
|
1135
|
+
try {
|
|
1136
|
+
const ok = await keymaster.removeVaultItem(id, item);
|
|
1137
|
+
console.log(ok ? UPDATE_OK : UPDATE_FAILED);
|
|
1138
|
+
}
|
|
1139
|
+
catch (error) {
|
|
1140
|
+
console.error(error.error || error.message || error);
|
|
1141
|
+
}
|
|
1142
|
+
});
|
|
1143
|
+
program
|
|
1144
|
+
.command('get-vault-item <id> <item> <file>')
|
|
1145
|
+
.description('Save an item from a vault to a file')
|
|
1146
|
+
.action(async (id, item, file) => {
|
|
1147
|
+
try {
|
|
1148
|
+
const data = await keymaster.getVaultItem(id, item);
|
|
1149
|
+
if (data) {
|
|
1150
|
+
fs.writeFileSync(file, data);
|
|
1151
|
+
console.log(`Data written to ${file}`);
|
|
1152
|
+
}
|
|
1153
|
+
else {
|
|
1154
|
+
console.error(`Item ${item} not found in vault`);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
catch (error) {
|
|
1158
|
+
console.error(error.error || error.message || error);
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
1161
|
+
// Initialize and run
|
|
1162
|
+
async function run() {
|
|
1163
|
+
// Handle --help and --version without full initialization
|
|
1164
|
+
if (process.argv.includes('--help') || process.argv.includes('-h') ||
|
|
1165
|
+
process.argv.includes('--version') || process.argv.includes('-V') ||
|
|
1166
|
+
process.argv.length <= 2) {
|
|
1167
|
+
program.parse(process.argv);
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
const gatekeeperURL = process.env.ARCHON_GATEKEEPER_URL || 'http://localhost:4224';
|
|
1171
|
+
const walletPath = process.env.ARCHON_WALLET_PATH || './wallet.json';
|
|
1172
|
+
const walletType = process.env.ARCHON_WALLET_TYPE || 'json';
|
|
1173
|
+
const passphrase = process.env.ARCHON_PASSPHRASE;
|
|
1174
|
+
const defaultRegistry = process.env.ARCHON_DEFAULT_REGISTRY;
|
|
1175
|
+
if (!passphrase) {
|
|
1176
|
+
console.error('Error: ARCHON_PASSPHRASE environment variable is required');
|
|
1177
|
+
console.error('Set it with: export ARCHON_PASSPHRASE=your-passphrase');
|
|
1178
|
+
process.exit(1);
|
|
1179
|
+
}
|
|
1180
|
+
try {
|
|
1181
|
+
// Initialize gatekeeper client
|
|
1182
|
+
const gatekeeper = new GatekeeperClient();
|
|
1183
|
+
await gatekeeper.connect({
|
|
1184
|
+
url: gatekeeperURL,
|
|
1185
|
+
waitUntilReady: true,
|
|
1186
|
+
intervalSeconds: 3,
|
|
1187
|
+
chatty: false,
|
|
1188
|
+
becomeChattyAfter: 2
|
|
1189
|
+
});
|
|
1190
|
+
// Initialize wallet
|
|
1191
|
+
let wallet;
|
|
1192
|
+
if (walletType === 'sqlite') {
|
|
1193
|
+
wallet = await WalletSQLite.create(walletPath);
|
|
1194
|
+
}
|
|
1195
|
+
else {
|
|
1196
|
+
// WalletJson expects (filename, folder) - parse the path
|
|
1197
|
+
const walletDir = path.dirname(walletPath);
|
|
1198
|
+
const walletFile = path.basename(walletPath);
|
|
1199
|
+
wallet = new WalletJson(walletFile, walletDir);
|
|
1200
|
+
}
|
|
1201
|
+
// Initialize cipher
|
|
1202
|
+
const cipher = new CipherNode();
|
|
1203
|
+
// Initialize keymaster
|
|
1204
|
+
keymaster = new Keymaster({ gatekeeper, wallet, cipher, defaultRegistry, passphrase });
|
|
1205
|
+
program.parse(process.argv);
|
|
1206
|
+
}
|
|
1207
|
+
catch (error) {
|
|
1208
|
+
console.error('Failed to initialize:', error.message || error);
|
|
1209
|
+
process.exit(1);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
run();
|
|
1213
|
+
//# sourceMappingURL=cli.js.map
|