@did-btcr2/cli 0.10.2 → 0.11.0
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/dist/.tsbuildinfo +1 -1
- package/dist/cjs/index.js +889 -43
- package/dist/esm/src/cli.js +30 -12
- package/dist/esm/src/cli.js.map +1 -1
- package/dist/esm/src/commands/completion.js +36 -0
- package/dist/esm/src/commands/completion.js.map +1 -0
- package/dist/esm/src/commands/config.js +69 -0
- package/dist/esm/src/commands/config.js.map +1 -0
- package/dist/esm/src/commands/deactivate.js +21 -8
- package/dist/esm/src/commands/deactivate.js.map +1 -1
- package/dist/esm/src/commands/index.js +4 -0
- package/dist/esm/src/commands/index.js.map +1 -1
- package/dist/esm/src/commands/key.js +175 -0
- package/dist/esm/src/commands/key.js.map +1 -0
- package/dist/esm/src/commands/profile.js +63 -0
- package/dist/esm/src/commands/profile.js.map +1 -0
- package/dist/esm/src/commands/update.js +19 -9
- package/dist/esm/src/commands/update.js.map +1 -1
- package/dist/esm/src/config.js +100 -13
- package/dist/esm/src/config.js.map +1 -1
- package/dist/esm/src/keystore/atomic.js +64 -0
- package/dist/esm/src/keystore/atomic.js.map +1 -0
- package/dist/esm/src/keystore/envelope.js +123 -0
- package/dist/esm/src/keystore/envelope.js.map +1 -0
- package/dist/esm/src/keystore/error.js +16 -0
- package/dist/esm/src/keystore/error.js.map +1 -0
- package/dist/esm/src/keystore/file-backed-key-manager.js +78 -0
- package/dist/esm/src/keystore/file-backed-key-manager.js.map +1 -0
- package/dist/esm/src/keystore/file-key-store.js +184 -0
- package/dist/esm/src/keystore/file-key-store.js.map +1 -0
- package/dist/esm/src/keystore/passphrase.js +87 -0
- package/dist/esm/src/keystore/passphrase.js.map +1 -0
- package/dist/esm/src/keystore/paths.js +20 -0
- package/dist/esm/src/keystore/paths.js.map +1 -0
- package/dist/esm/src/keystore/resolve-key-ref.js +47 -0
- package/dist/esm/src/keystore/resolve-key-ref.js.map +1 -0
- package/dist/types/src/cli.d.ts +6 -2
- package/dist/types/src/cli.d.ts.map +1 -1
- package/dist/types/src/commands/completion.d.ts +5 -0
- package/dist/types/src/commands/completion.d.ts.map +1 -0
- package/dist/types/src/commands/config.d.ts +5 -0
- package/dist/types/src/commands/config.d.ts.map +1 -0
- package/dist/types/src/commands/deactivate.d.ts.map +1 -1
- package/dist/types/src/commands/index.d.ts +4 -0
- package/dist/types/src/commands/index.d.ts.map +1 -1
- package/dist/types/src/commands/key.d.ts +10 -0
- package/dist/types/src/commands/key.d.ts.map +1 -0
- package/dist/types/src/commands/profile.d.ts +5 -0
- package/dist/types/src/commands/profile.d.ts.map +1 -0
- package/dist/types/src/commands/update.d.ts.map +1 -1
- package/dist/types/src/config.d.ts +50 -7
- package/dist/types/src/config.d.ts.map +1 -1
- package/dist/types/src/keystore/atomic.d.ts +19 -0
- package/dist/types/src/keystore/atomic.d.ts.map +1 -0
- package/dist/types/src/keystore/envelope.d.ts +64 -0
- package/dist/types/src/keystore/envelope.d.ts.map +1 -0
- package/dist/types/src/keystore/error.d.ts +14 -0
- package/dist/types/src/keystore/error.d.ts.map +1 -0
- package/dist/types/src/keystore/file-backed-key-manager.d.ts +41 -0
- package/dist/types/src/keystore/file-backed-key-manager.d.ts.map +1 -0
- package/dist/types/src/keystore/file-key-store.d.ts +52 -0
- package/dist/types/src/keystore/file-key-store.d.ts.map +1 -0
- package/dist/types/src/keystore/passphrase.d.ts +20 -0
- package/dist/types/src/keystore/passphrase.d.ts.map +1 -0
- package/dist/types/src/keystore/paths.d.ts +13 -0
- package/dist/types/src/keystore/paths.d.ts.map +1 -0
- package/dist/types/src/keystore/resolve-key-ref.d.ts +19 -0
- package/dist/types/src/keystore/resolve-key-ref.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +91 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +9 -4
- package/src/cli.ts +36 -11
- package/src/commands/completion.ts +40 -0
- package/src/commands/config.ts +84 -0
- package/src/commands/deactivate.ts +25 -12
- package/src/commands/index.ts +4 -0
- package/src/commands/key.ts +193 -0
- package/src/commands/profile.ts +65 -0
- package/src/commands/update.ts +23 -13
- package/src/config.ts +144 -22
- package/src/keystore/atomic.ts +73 -0
- package/src/keystore/envelope.ts +172 -0
- package/src/keystore/error.ts +16 -0
- package/src/keystore/file-backed-key-manager.ts +99 -0
- package/src/keystore/file-key-store.ts +242 -0
- package/src/keystore/passphrase.ts +99 -0
- package/src/keystore/paths.ts +20 -0
- package/src/keystore/resolve-key-ref.ts +62 -0
- package/src/types.ts +30 -11
package/dist/esm/src/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { DidMethodError } from '@did-btcr2/common';
|
|
1
2
|
import { Command, CommanderError } from 'commander';
|
|
2
|
-
import { registerCreateCommand, registerDeactivateCommand, registerResolveCommand, registerUpdateCommand, } from './commands/index.js';
|
|
3
|
-
import { defaultApiFactory } from './config.js';
|
|
4
|
-
import { CLIError } from './error.js';
|
|
3
|
+
import { registerCompletionCommand, registerConfigCommand, registerCreateCommand, registerDeactivateCommand, registerKeyCommand, registerProfileCommand, registerResolveCommand, registerUpdateCommand, } from './commands/index.js';
|
|
4
|
+
import { defaultApiFactory, keystoreApiFactory } from './config.js';
|
|
5
5
|
import { VERSION } from './version.js';
|
|
6
6
|
/**
|
|
7
7
|
* CLI tool for the did:btcr2 method.
|
|
@@ -16,9 +16,13 @@ export class DidBtcr2Cli {
|
|
|
16
16
|
* {@link defaultApiFactory} which uses public endpoints (mempool.space)
|
|
17
17
|
* for known networks and localhost Polar for regtest.
|
|
18
18
|
*
|
|
19
|
-
* @param factory - Optional API factory
|
|
19
|
+
* @param factory - Optional API factory for keystore-free commands (create,
|
|
20
|
+
* resolve). Defaults to {@link defaultApiFactory}.
|
|
21
|
+
* @param keystoreFactory - Optional keystore-aware API factory for commands
|
|
22
|
+
* that need a signing identity (key, update, deactivate). Defaults to
|
|
23
|
+
* {@link keystoreApiFactory}.
|
|
20
24
|
*/
|
|
21
|
-
constructor(factory = defaultApiFactory) {
|
|
25
|
+
constructor(factory = defaultApiFactory, keystoreFactory = keystoreApiFactory) {
|
|
22
26
|
this.program = new Command('btcr2')
|
|
23
27
|
.version(`btcr2 ${VERSION}`, '-v, --version', 'Output the current version')
|
|
24
28
|
.description('CLI tool for the did:btcr2 method')
|
|
@@ -31,12 +35,19 @@ export class DidBtcr2Cli {
|
|
|
31
35
|
.option('--btc-rpc-url <url>', 'Override Bitcoin Core RPC endpoint')
|
|
32
36
|
.option('--btc-rpc-user <user>', 'Bitcoin Core RPC username')
|
|
33
37
|
.option('--btc-rpc-pass <pass>', 'Bitcoin Core RPC password')
|
|
34
|
-
.option('--cas-gateway <url>', 'IPFS HTTP gateway for CAS reads')
|
|
38
|
+
.option('--cas-gateway <url>', 'IPFS HTTP gateway for CAS reads')
|
|
39
|
+
.option('--keystore <path>', 'Path to the keystore file (default: $XDG_DATA_HOME/btcr2/keystore.json)')
|
|
40
|
+
.option('--passphrase-file <path>', 'Read the keystore passphrase from a file (unattended use)')
|
|
41
|
+
.option('--signing-key <ref>', 'Key for update/deactivate signing: a URN, fingerprint prefix, or name');
|
|
35
42
|
const globals = () => this.program.opts();
|
|
36
43
|
registerCreateCommand(this.program, factory, globals);
|
|
37
44
|
registerResolveCommand(this.program, factory, globals);
|
|
38
|
-
registerUpdateCommand(this.program,
|
|
39
|
-
registerDeactivateCommand(this.program,
|
|
45
|
+
registerUpdateCommand(this.program, keystoreFactory, globals);
|
|
46
|
+
registerDeactivateCommand(this.program, keystoreFactory, globals);
|
|
47
|
+
registerKeyCommand(this.program, keystoreFactory, globals);
|
|
48
|
+
registerConfigCommand(this.program, globals);
|
|
49
|
+
registerProfileCommand(this.program, globals);
|
|
50
|
+
registerCompletionCommand(this.program, globals);
|
|
40
51
|
}
|
|
41
52
|
/**
|
|
42
53
|
* Runs the CLI with the provided argv or process.argv.
|
|
@@ -51,7 +62,7 @@ export class DidBtcr2Cli {
|
|
|
51
62
|
this.program.outputHelp();
|
|
52
63
|
}
|
|
53
64
|
catch (error) {
|
|
54
|
-
handleError(error);
|
|
65
|
+
handleError(error, Boolean(this.program.opts().verbose));
|
|
55
66
|
}
|
|
56
67
|
}
|
|
57
68
|
}
|
|
@@ -69,16 +80,23 @@ function normalizeArgv(argv) {
|
|
|
69
80
|
}
|
|
70
81
|
/**
|
|
71
82
|
* Handles errors thrown during CLI execution.
|
|
83
|
+
*
|
|
84
|
+
* Known method errors ({@link DidMethodError} and its subclasses, including
|
|
85
|
+
* {@link CLIError} and the keystore errors) print only their message, never the
|
|
86
|
+
* stack or the structured `data` payload, so internal shapes are not leaked.
|
|
87
|
+
* The full error object and stack are shown only under `--verbose`.
|
|
88
|
+
*
|
|
72
89
|
* @param {unknown} error - The error to handle.
|
|
90
|
+
* @param {boolean} verbose - Whether to print the full error object and stack.
|
|
73
91
|
* @returns {void}
|
|
74
92
|
*/
|
|
75
|
-
function handleError(error) {
|
|
93
|
+
function handleError(error, verbose) {
|
|
76
94
|
if (error instanceof CommanderError &&
|
|
77
95
|
(error.code === 'commander.helpDisplayed' || error.code === 'commander.help')) {
|
|
78
96
|
return;
|
|
79
97
|
}
|
|
80
|
-
if (error instanceof
|
|
81
|
-
console.error(error.message);
|
|
98
|
+
if (error instanceof DidMethodError) {
|
|
99
|
+
console.error(verbose ? error : error.message);
|
|
82
100
|
process.exitCode ??= 1;
|
|
83
101
|
return;
|
|
84
102
|
}
|
package/dist/esm/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CLIError } from '../error.js';
|
|
2
|
+
const COMMANDS = 'create resolve read update deactivate delete key config profile completion';
|
|
3
|
+
/** Registers the `completion` command, which prints a shell completion script to stdout. */
|
|
4
|
+
export function registerCompletionCommand(program, _globals) {
|
|
5
|
+
program
|
|
6
|
+
.command('completion [shell]')
|
|
7
|
+
.description('Print a shell completion script (bash, zsh, or fish) to stdout.')
|
|
8
|
+
.action((shell = 'bash') => {
|
|
9
|
+
console.log(completionScript(shell));
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/** Returns a completion script for the given shell. */
|
|
13
|
+
function completionScript(shell) {
|
|
14
|
+
switch (shell) {
|
|
15
|
+
case 'bash':
|
|
16
|
+
return [
|
|
17
|
+
'# btcr2 bash completion. Install with: eval "$(btcr2 completion bash)"',
|
|
18
|
+
'_btcr2() { COMPREPLY=( $(compgen -W "' + COMMANDS + '" -- "${COMP_WORDS[COMP_CWORD]}") ); }',
|
|
19
|
+
'complete -F _btcr2 btcr2',
|
|
20
|
+
].join('\n');
|
|
21
|
+
case 'zsh':
|
|
22
|
+
return [
|
|
23
|
+
'# btcr2 zsh completion. Install with: eval "$(btcr2 completion zsh)"',
|
|
24
|
+
'_btcr2() { compadd ' + COMMANDS + ' }',
|
|
25
|
+
'compdef _btcr2 btcr2',
|
|
26
|
+
].join('\n');
|
|
27
|
+
case 'fish':
|
|
28
|
+
return [
|
|
29
|
+
'# btcr2 fish completion. Save to ~/.config/fish/completions/btcr2.fish',
|
|
30
|
+
'complete -c btcr2 -f -a "' + COMMANDS + '"',
|
|
31
|
+
].join('\n');
|
|
32
|
+
default:
|
|
33
|
+
throw new CLIError(`Unsupported shell "${shell}". Use bash, zsh, or fish.`, 'INVALID_ARGUMENT_ERROR', { shell });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../../src/commands/completion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,MAAM,QAAQ,GAAG,4EAA4E,CAAC;AAE9F,4FAA4F;AAC5F,MAAM,UAAU,yBAAyB,CAAC,OAAgB,EAAE,QAA6B;IACvF,OAAO;SACJ,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CAAC,iEAAiE,CAAC;SAC9E,MAAM,CAAC,CAAC,KAAK,GAAG,MAAM,EAAE,EAAE;QACzB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACP,CAAC;AAED,uDAAuD;AACvD,SAAS,gBAAgB,CAAC,KAAa;IACrC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,MAAM;YACT,OAAO;gBACL,wEAAwE;gBACxE,uCAAuC,GAAG,QAAQ,GAAG,wCAAwC;gBAC7F,0BAA0B;aAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,KAAK,KAAK;YACR,OAAO;gBACL,sEAAsE;gBACtE,qBAAqB,GAAG,QAAQ,GAAG,IAAI;gBACvC,sBAAsB;aACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,KAAK,MAAM;YACT,OAAO;gBACL,wEAAwE;gBACxE,2BAA2B,GAAG,QAAQ,GAAG,GAAG;aAC7C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf;YACE,MAAM,IAAI,QAAQ,CAAC,sBAAsB,KAAK,4BAA4B,EAAE,wBAAwB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACrH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { CONFIG_SCHEMA_VERSION, defaultConfigPath, getConfigPath, readConfigFile, setConfigPath, unsetConfigPath, writeConfigFile, } from '../config.js';
|
|
4
|
+
import { CLIError } from '../error.js';
|
|
5
|
+
import { ensureDir, writeFileAtomic } from '../keystore/atomic.js';
|
|
6
|
+
import { formatResult } from '../output.js';
|
|
7
|
+
import { SUPPORTED_NETWORKS } from '../types.js';
|
|
8
|
+
/** Registers the `config` command group for reading and writing CLI configuration. */
|
|
9
|
+
export function registerConfigCommand(program, globals) {
|
|
10
|
+
const config = program.command('config').description('Read and write CLI configuration.');
|
|
11
|
+
const path = () => globals().config ?? defaultConfigPath();
|
|
12
|
+
const print = (result) => console.log(formatResult(result, globals()));
|
|
13
|
+
config
|
|
14
|
+
.command('init')
|
|
15
|
+
.description('Create a default config file with one profile per network.')
|
|
16
|
+
.option('--force', 'Overwrite an existing config file.', false)
|
|
17
|
+
.action((options) => {
|
|
18
|
+
const p = path();
|
|
19
|
+
if (existsSync(p) && !options.force) {
|
|
20
|
+
throw new CLIError(`Config already exists at ${p}. Use --force to overwrite.`, 'INVALID_ARGUMENT_ERROR', { path: p });
|
|
21
|
+
}
|
|
22
|
+
const scaffold = {
|
|
23
|
+
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
24
|
+
defaults: { output: 'text' },
|
|
25
|
+
profiles: Object.fromEntries(SUPPORTED_NETWORKS.map(n => [n, {}])),
|
|
26
|
+
};
|
|
27
|
+
ensureDir(dirname(p), 0o700);
|
|
28
|
+
writeFileAtomic(p, `${JSON.stringify(scaffold, null, 2)}\n`, 0o600);
|
|
29
|
+
print({ action: 'config-init', data: { path: p } });
|
|
30
|
+
});
|
|
31
|
+
config
|
|
32
|
+
.command('get [path]')
|
|
33
|
+
.description('Print a value at a dotted path, or the whole config.')
|
|
34
|
+
.action((dotted) => {
|
|
35
|
+
const file = (readConfigFile(path()) ?? {});
|
|
36
|
+
print({ action: 'config-get', data: (dotted ? getConfigPath(file, dotted) : file) ?? null });
|
|
37
|
+
});
|
|
38
|
+
config
|
|
39
|
+
.command('set <path> <value>')
|
|
40
|
+
.description('Set a value at a dotted path. The value is parsed as JSON when valid, else stored as a string.')
|
|
41
|
+
.action((dotted, value) => {
|
|
42
|
+
writeConfigFile(path(), raw => setConfigPath(raw, dotted, parseValue(value)));
|
|
43
|
+
print({ action: 'config-set', data: { path: dotted } });
|
|
44
|
+
});
|
|
45
|
+
config
|
|
46
|
+
.command('unset <path>')
|
|
47
|
+
.description('Delete a value at a dotted path.')
|
|
48
|
+
.action((dotted) => {
|
|
49
|
+
writeConfigFile(path(), raw => unsetConfigPath(raw, dotted));
|
|
50
|
+
print({ action: 'config-unset', data: { path: dotted } });
|
|
51
|
+
});
|
|
52
|
+
config
|
|
53
|
+
.command('list')
|
|
54
|
+
.alias('ls')
|
|
55
|
+
.description('Print the entire config file.')
|
|
56
|
+
.action(() => {
|
|
57
|
+
print({ action: 'config-list', data: readConfigFile(path()) ?? {} });
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/** Parses a value as JSON when valid, otherwise treats it as a plain string. */
|
|
61
|
+
function parseValue(value) {
|
|
62
|
+
try {
|
|
63
|
+
return JSON.parse(value);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/commands/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,sFAAsF;AACtF,MAAM,UAAU,qBAAqB,CAAC,OAAgB,EAAE,OAA4B;IAClF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC;IAC1F,MAAM,IAAI,GAAG,GAAW,EAAE,CAAC,OAAO,EAAE,CAAC,MAAM,IAAI,iBAAiB,EAAE,CAAC;IACnE,MAAM,KAAK,GAAG,CAAC,MAAqB,EAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAE5F,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CAAC,SAAS,EAAE,oCAAoC,EAAE,KAAK,CAAC;SAC9D,MAAM,CAAC,CAAC,OAA4B,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;QACjB,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,MAAM,IAAI,QAAQ,CAAC,4BAA4B,CAAC,6BAA6B,EAAE,wBAAwB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QACxH,CAAC;QACD,MAAM,QAAQ,GAAG;YACf,aAAa,EAAG,qBAAqB;YACrC,QAAQ,EAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;YAClC,QAAQ,EAAQ,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAE,CAAC,EAAE,EAAE,CAAE,CAAC,CAAC;SAC3E,CAAC;QACF,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC7B,eAAe,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpE,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEL,MAAM;SACH,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,CAAC,MAAe,EAAE,EAAE;QAC1B,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAA4B,CAAC;QACvE,KAAK,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEL,MAAM;SACH,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CAAC,gGAAgG,CAAC;SAC7G,MAAM,CAAC,CAAC,MAAc,EAAE,KAAa,EAAE,EAAE;QACxC,eAAe,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9E,KAAK,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEL,MAAM;SACH,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,kCAAkC,CAAC;SAC/C,MAAM,CAAC,CAAC,MAAc,EAAE,EAAE;QACzB,eAAe,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7D,KAAK,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,KAAK,CAAC,IAAI,CAAC;SACX,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,GAAG,EAAE;QACX,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACP,CAAC;AAED,gFAAgF;AAChF,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { KeyManagerSigner } from '@did-btcr2/key-manager';
|
|
1
2
|
import { deriveNetwork } from '../config.js';
|
|
2
3
|
import { CLIError } from '../error.js';
|
|
4
|
+
import { resolveKeyRef } from '../keystore/resolve-key-ref.js';
|
|
5
|
+
import { formatResult } from '../output.js';
|
|
3
6
|
/** The JSON Patch that marks a DID document as permanently deactivated. */
|
|
4
7
|
const DEACTIVATION_PATCH = [{ op: 'add', path: '/deactivated', value: true }];
|
|
5
8
|
export function registerDeactivateCommand(program, factory, globals) {
|
|
@@ -12,6 +15,9 @@ export function registerDeactivateCommand(program, factory, globals) {
|
|
|
12
15
|
.requiredOption('-m, --verification-method-id <id>', 'DID document verification method ID used to sign the deactivation')
|
|
13
16
|
.requiredOption('-b, --beacon-id <json>', 'Beacon ID as a JSON string', parseJsonArg('--beacon-id'))
|
|
14
17
|
.action(async (options) => {
|
|
18
|
+
if (!/^\d+$/.test(options.sourceVersionId)) {
|
|
19
|
+
throw new CLIError('--source-version-id must be a non-negative integer.', 'INVALID_ARGUMENT_ERROR', { value: options.sourceVersionId });
|
|
20
|
+
}
|
|
15
21
|
const parsed = {
|
|
16
22
|
sourceDocument: options.sourceDocument,
|
|
17
23
|
patches: DEACTIVATION_PATCH,
|
|
@@ -23,14 +29,21 @@ export function registerDeactivateCommand(program, factory, globals) {
|
|
|
23
29
|
if (!did) {
|
|
24
30
|
throw new CLIError('Source document must contain an "id" field.', 'INVALID_ARGUMENT_ERROR', options);
|
|
25
31
|
}
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
// Deactivation is an update that applies the deactivation patch. The core
|
|
33
|
+
// method has no separate deactivate path, so this routes through update.
|
|
34
|
+
const network = deriveNetwork(did);
|
|
35
|
+
const api = factory(network, globals());
|
|
36
|
+
const keyId = resolveKeyRef(api.kms.kms, globals().signingKey);
|
|
37
|
+
const signer = new KeyManagerSigner(api.kms.kms, keyId);
|
|
38
|
+
const data = await api.btcr2.update({
|
|
39
|
+
sourceDocument: parsed.sourceDocument,
|
|
40
|
+
patches: parsed.patches,
|
|
41
|
+
sourceVersionId: parsed.sourceVersionId,
|
|
42
|
+
verificationMethodId: parsed.verificationMethodId,
|
|
43
|
+
beaconId: parsed.beaconId,
|
|
44
|
+
signer,
|
|
45
|
+
});
|
|
46
|
+
console.log(formatResult({ action: 'deactivate', data }, globals()));
|
|
34
47
|
});
|
|
35
48
|
}
|
|
36
49
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deactivate.js","sourceRoot":"","sources":["../../../../src/commands/deactivate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deactivate.js","sourceRoot":"","sources":["../../../../src/commands/deactivate.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,4 +2,8 @@ export { registerCreateCommand } from './create.js';
|
|
|
2
2
|
export { registerResolveCommand } from './resolve.js';
|
|
3
3
|
export { registerUpdateCommand } from './update.js';
|
|
4
4
|
export { registerDeactivateCommand } from './deactivate.js';
|
|
5
|
+
export { registerKeyCommand } from './key.js';
|
|
6
|
+
export { registerConfigCommand } from './config.js';
|
|
7
|
+
export { registerProfileCommand } from './profile.js';
|
|
8
|
+
export { registerCompletionCommand } from './completion.js';
|
|
5
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { SchnorrKeyPair } from '@did-btcr2/keypair';
|
|
2
|
+
import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js';
|
|
3
|
+
import { closeSync, openSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { CLIError } from '../error.js';
|
|
5
|
+
import { resolveKeyRef } from '../keystore/resolve-key-ref.js';
|
|
6
|
+
import { formatResult } from '../output.js';
|
|
7
|
+
/**
|
|
8
|
+
* Registers the `key` command group for managing keypairs in the encrypted
|
|
9
|
+
* keystore. All subcommands operate offline (no Bitcoin connection) through the
|
|
10
|
+
* keystore-backed KeyManager injected by the factory.
|
|
11
|
+
*/
|
|
12
|
+
export function registerKeyCommand(program, factory, globals) {
|
|
13
|
+
const key = program.command('key').description('Manage keypairs in the encrypted keystore.');
|
|
14
|
+
const print = (result) => console.log(formatResult(result, globals()));
|
|
15
|
+
key
|
|
16
|
+
.command('generate')
|
|
17
|
+
.description('Generate a new keypair and store it.')
|
|
18
|
+
.option('--name <name>', 'A human-friendly name, stored as a tag and usable as a key reference.')
|
|
19
|
+
.option('--set-active', 'Make this the active key.', false)
|
|
20
|
+
.action((options) => {
|
|
21
|
+
const api = factory(undefined, globals());
|
|
22
|
+
assertNameAvailable(api.kms.kms, options.name);
|
|
23
|
+
const setActive = options.setActive ?? false;
|
|
24
|
+
const id = api.kms.generateKey({ ...(options.name && { tags: { name: options.name } }), setActive });
|
|
25
|
+
print({ action: 'key-generate', data: { keyId: id, publicKey: bytesToHex(api.kms.getPublicKey(id)), active: setActive } });
|
|
26
|
+
});
|
|
27
|
+
key
|
|
28
|
+
.command('list')
|
|
29
|
+
.alias('ls')
|
|
30
|
+
.description('List stored keys.')
|
|
31
|
+
.action(() => {
|
|
32
|
+
const kms = factory(undefined, globals()).kms.kms;
|
|
33
|
+
const active = kms.activeKeyId;
|
|
34
|
+
const data = kms.listKeys().map(id => {
|
|
35
|
+
const entry = kms.getEntry(id);
|
|
36
|
+
return {
|
|
37
|
+
keyId: id,
|
|
38
|
+
fingerprint: id.split(':').pop() ?? id,
|
|
39
|
+
...(entry.tags?.name && { name: entry.tags.name }),
|
|
40
|
+
active: id === active,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
print({ action: 'key-list', data });
|
|
44
|
+
});
|
|
45
|
+
key
|
|
46
|
+
.command('show <ref>')
|
|
47
|
+
.description('Show a key\'s public material and tags. Never prints the secret.')
|
|
48
|
+
.action((ref) => {
|
|
49
|
+
const kms = factory(undefined, globals()).kms.kms;
|
|
50
|
+
const id = resolveKeyRef(kms, ref);
|
|
51
|
+
const entry = kms.getEntry(id);
|
|
52
|
+
print({ action: 'key-show', data: { keyId: id, publicKey: bytesToHex(entry.publicKey), ...(entry.tags && { tags: entry.tags }) } });
|
|
53
|
+
});
|
|
54
|
+
key
|
|
55
|
+
.command('import')
|
|
56
|
+
.description('Import a key: a secret from a hex file, or a public key as watch-only.')
|
|
57
|
+
.option('--secret-file <path>', 'Path to a file containing a 32-byte secret key as hex.')
|
|
58
|
+
.option('--public <hex>', 'A 33-byte compressed public key as hex (imported watch-only).')
|
|
59
|
+
.option('--name <name>', 'A human-friendly name, stored as a tag.')
|
|
60
|
+
.option('--set-active', 'Make this the active key.', false)
|
|
61
|
+
.action((options) => {
|
|
62
|
+
if (Boolean(options.secretFile) === Boolean(options.public)) {
|
|
63
|
+
throw new CLIError('Provide exactly one of --secret-file or --public.', 'INVALID_ARGUMENT_ERROR');
|
|
64
|
+
}
|
|
65
|
+
const api = factory(undefined, globals());
|
|
66
|
+
assertNameAvailable(api.kms.kms, options.name);
|
|
67
|
+
const keyPair = options.secretFile
|
|
68
|
+
? new SchnorrKeyPair({ secretKey: readHexFile(options.secretFile, 32, '--secret-file') })
|
|
69
|
+
: new SchnorrKeyPair({ publicKey: parseHex(options.public ?? '', 33, '--public') });
|
|
70
|
+
const setActive = options.setActive ?? false;
|
|
71
|
+
const id = api.kms.import(keyPair, { ...(options.name && { tags: { name: options.name } }), setActive });
|
|
72
|
+
print({ action: 'key-import', data: { keyId: id, publicKey: bytesToHex(api.kms.getPublicKey(id)), watchOnly: !options.secretFile, active: setActive } });
|
|
73
|
+
});
|
|
74
|
+
key
|
|
75
|
+
.command('export <ref>')
|
|
76
|
+
.description('Export a key. Public material by default; --secret writes the secret to a file.')
|
|
77
|
+
.option('--secret', 'Export the secret key. Requires --out.', false)
|
|
78
|
+
.option('--out <path>', 'Write the exported secret to this file (created 0600).')
|
|
79
|
+
.action((ref, options) => {
|
|
80
|
+
const api = factory(undefined, globals());
|
|
81
|
+
const id = resolveKeyRef(api.kms.kms, ref);
|
|
82
|
+
if (!options.secret) {
|
|
83
|
+
print({ action: 'key-export', data: { keyId: id, publicKey: bytesToHex(api.kms.getPublicKey(id)) } });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!options.out) {
|
|
87
|
+
throw new CLIError('Exporting a secret requires --out <file> so it is not written to the terminal.', 'INVALID_ARGUMENT_ERROR');
|
|
88
|
+
}
|
|
89
|
+
const keyPair = api.kms.export(id);
|
|
90
|
+
if (!keyPair.hasSecretKey) {
|
|
91
|
+
throw new CLIError(`Key ${id} is watch-only and has no secret to export.`, 'INVALID_ARGUMENT_ERROR', { keyId: id });
|
|
92
|
+
}
|
|
93
|
+
process.stderr.write('warning: writing an unencrypted secret key to disk. Protect this file and delete it when done.\n');
|
|
94
|
+
writeSecretFile(options.out, bytesToHex(keyPair.secretKey.bytes));
|
|
95
|
+
print({ action: 'key-export', data: { keyId: id, secretWrittenTo: options.out } });
|
|
96
|
+
});
|
|
97
|
+
key
|
|
98
|
+
.command('delete <ref>')
|
|
99
|
+
.alias('rm')
|
|
100
|
+
.description('Delete a key from the keystore.')
|
|
101
|
+
.option('--force', 'Delete even if it is the active key.', false)
|
|
102
|
+
.action((ref, options) => {
|
|
103
|
+
const api = factory(undefined, globals());
|
|
104
|
+
const id = resolveKeyRef(api.kms.kms, ref);
|
|
105
|
+
api.kms.removeKey(id, { force: options.force ?? false });
|
|
106
|
+
print({ action: 'key-delete', data: { keyId: id, deleted: true } });
|
|
107
|
+
});
|
|
108
|
+
key
|
|
109
|
+
.command('use <ref>')
|
|
110
|
+
.description('Set the active key, persisted across invocations.')
|
|
111
|
+
.action((ref) => {
|
|
112
|
+
const api = factory(undefined, globals());
|
|
113
|
+
const id = resolveKeyRef(api.kms.kms, ref);
|
|
114
|
+
api.kms.setActive(id);
|
|
115
|
+
print({ action: 'key-use', data: { keyId: id, active: true } });
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/** Throws if a name tag is already used by another key. */
|
|
119
|
+
function assertNameAvailable(kms, name) {
|
|
120
|
+
if (!name)
|
|
121
|
+
return;
|
|
122
|
+
if (kms.listKeys().some(id => kms.getEntry(id).tags?.name === name)) {
|
|
123
|
+
throw new CLIError(`A key named "${name}" already exists.`, 'INVALID_ARGUMENT_ERROR', { name });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Parses and length-checks a hex string into bytes. */
|
|
127
|
+
function parseHex(hex, expectedBytes, label) {
|
|
128
|
+
let bytes;
|
|
129
|
+
try {
|
|
130
|
+
bytes = hexToBytes(hex.trim());
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new CLIError(`Invalid hex for ${label}.`, 'INVALID_ARGUMENT_ERROR', { label });
|
|
134
|
+
}
|
|
135
|
+
if (bytes.length !== expectedBytes) {
|
|
136
|
+
throw new CLIError(`${label} must be ${expectedBytes} bytes (${expectedBytes * 2} hex chars), got ${bytes.length}.`, 'INVALID_ARGUMENT_ERROR', { label });
|
|
137
|
+
}
|
|
138
|
+
return bytes;
|
|
139
|
+
}
|
|
140
|
+
/** Reads a file and parses its contents as length-checked hex bytes. */
|
|
141
|
+
function readHexFile(path, expectedBytes, label) {
|
|
142
|
+
let content;
|
|
143
|
+
try {
|
|
144
|
+
content = readFileSync(path, 'utf-8');
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
throw new CLIError(`Cannot read ${label} at ${path}.`, 'INVALID_ARGUMENT_ERROR', { label, path });
|
|
148
|
+
}
|
|
149
|
+
return parseHex(content, expectedBytes, label);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Writes an exported secret to a new file, created exclusively (O_CREAT|O_EXCL,
|
|
153
|
+
* mode 0600). The exclusive flag refuses to clobber an existing file or follow
|
|
154
|
+
* a pre-placed symlink, so the secret never lands in a loose-permissions or
|
|
155
|
+
* redirected target.
|
|
156
|
+
*/
|
|
157
|
+
function writeSecretFile(path, contents) {
|
|
158
|
+
let fd;
|
|
159
|
+
try {
|
|
160
|
+
fd = openSync(path, 'wx', 0o600);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (error.code === 'EEXIST') {
|
|
164
|
+
throw new CLIError(`Refusing to overwrite existing file ${path}. Choose a new --out path.`, 'INVALID_ARGUMENT_ERROR', { path });
|
|
165
|
+
}
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
writeFileSync(fd, contents);
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
closeSync(fd);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../../../src/commands/key.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { defaultConfigPath, readConfigFile, writeConfigFile } from '../config.js';
|
|
2
|
+
import { CLIError } from '../error.js';
|
|
3
|
+
import { formatResult } from '../output.js';
|
|
4
|
+
/** Registers the `profile` command group for managing configuration profiles. */
|
|
5
|
+
export function registerProfileCommand(program, globals) {
|
|
6
|
+
const profile = program.command('profile').description('Manage configuration profiles.');
|
|
7
|
+
const path = () => globals().config ?? defaultConfigPath();
|
|
8
|
+
const print = (result) => console.log(formatResult(result, globals()));
|
|
9
|
+
profile
|
|
10
|
+
.command('add <name>')
|
|
11
|
+
.description('Add an empty profile.')
|
|
12
|
+
.action((name) => {
|
|
13
|
+
writeConfigFile(path(), raw => {
|
|
14
|
+
if (raw.profiles === undefined || raw.profiles === null)
|
|
15
|
+
raw.profiles = {};
|
|
16
|
+
const profiles = raw.profiles;
|
|
17
|
+
if (profiles[name])
|
|
18
|
+
throw new CLIError(`Profile "${name}" already exists.`, 'INVALID_ARGUMENT_ERROR', { name });
|
|
19
|
+
profiles[name] = {};
|
|
20
|
+
});
|
|
21
|
+
print({ action: 'profile-add', data: { profile: name } });
|
|
22
|
+
});
|
|
23
|
+
profile
|
|
24
|
+
.command('use <name>')
|
|
25
|
+
.description('Set the active profile (writes defaults.profile).')
|
|
26
|
+
.action((name) => {
|
|
27
|
+
writeConfigFile(path(), raw => {
|
|
28
|
+
if (raw.defaults === undefined || raw.defaults === null)
|
|
29
|
+
raw.defaults = {};
|
|
30
|
+
raw.defaults.profile = name;
|
|
31
|
+
});
|
|
32
|
+
print({ action: 'profile-use', data: { profile: name } });
|
|
33
|
+
});
|
|
34
|
+
profile
|
|
35
|
+
.command('show [name]')
|
|
36
|
+
.description('Show a profile (defaults to the active profile).')
|
|
37
|
+
.action((name) => {
|
|
38
|
+
const file = readConfigFile(path()) ?? {};
|
|
39
|
+
const target = name ?? file.defaults?.profile;
|
|
40
|
+
if (!target) {
|
|
41
|
+
throw new CLIError('No profile specified and no active profile is set.', 'INVALID_ARGUMENT_ERROR');
|
|
42
|
+
}
|
|
43
|
+
const data = file.profiles?.[target];
|
|
44
|
+
if (!data) {
|
|
45
|
+
throw new CLIError(`Profile "${target}" not found.`, 'INVALID_ARGUMENT_ERROR', { profile: target });
|
|
46
|
+
}
|
|
47
|
+
print({ action: 'profile-show', data: { profile: target, ...data } });
|
|
48
|
+
});
|
|
49
|
+
profile
|
|
50
|
+
.command('remove <name>')
|
|
51
|
+
.alias('rm')
|
|
52
|
+
.description('Remove a profile.')
|
|
53
|
+
.action((name) => {
|
|
54
|
+
writeConfigFile(path(), raw => {
|
|
55
|
+
const profiles = raw.profiles;
|
|
56
|
+
if (!profiles?.[name])
|
|
57
|
+
throw new CLIError(`Profile "${name}" not found.`, 'INVALID_ARGUMENT_ERROR', { name });
|
|
58
|
+
delete profiles[name];
|
|
59
|
+
});
|
|
60
|
+
print({ action: 'profile-remove', data: { profile: name } });
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../../../../src/commands/profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { KeyManagerSigner } from '@did-btcr2/key-manager';
|
|
1
2
|
import { deriveNetwork } from '../config.js';
|
|
2
3
|
import { CLIError } from '../error.js';
|
|
4
|
+
import { resolveKeyRef } from '../keystore/resolve-key-ref.js';
|
|
5
|
+
import { formatResult } from '../output.js';
|
|
3
6
|
export function registerUpdateCommand(program, factory, globals) {
|
|
4
7
|
program
|
|
5
8
|
.command('update')
|
|
@@ -10,6 +13,9 @@ export function registerUpdateCommand(program, factory, globals) {
|
|
|
10
13
|
.requiredOption('-m, --verification-method-id <id>', 'DID document verification method ID')
|
|
11
14
|
.requiredOption('-b, --beacon-id <json>', 'Beacon ID as a JSON string', parseJsonArg('--beacon-id'))
|
|
12
15
|
.action(async (options) => {
|
|
16
|
+
if (!/^\d+$/.test(options.sourceVersionId)) {
|
|
17
|
+
throw new CLIError('--source-version-id must be a non-negative integer.', 'INVALID_ARGUMENT_ERROR', { value: options.sourceVersionId });
|
|
18
|
+
}
|
|
13
19
|
const parsed = {
|
|
14
20
|
sourceDocument: options.sourceDocument,
|
|
15
21
|
patches: options.patches,
|
|
@@ -21,15 +27,19 @@ export function registerUpdateCommand(program, factory, globals) {
|
|
|
21
27
|
if (!did) {
|
|
22
28
|
throw new CLIError('Source document must contain an "id" field.', 'INVALID_ARGUMENT_ERROR', options);
|
|
23
29
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const network = deriveNetwork(did);
|
|
31
|
+
const api = factory(network, globals());
|
|
32
|
+
const keyId = resolveKeyRef(api.kms.kms, globals().signingKey);
|
|
33
|
+
const signer = new KeyManagerSigner(api.kms.kms, keyId);
|
|
34
|
+
const data = await api.btcr2.update({
|
|
35
|
+
sourceDocument: parsed.sourceDocument,
|
|
36
|
+
patches: parsed.patches,
|
|
37
|
+
sourceVersionId: parsed.sourceVersionId,
|
|
38
|
+
verificationMethodId: parsed.verificationMethodId,
|
|
39
|
+
beaconId: parsed.beaconId,
|
|
40
|
+
signer,
|
|
41
|
+
});
|
|
42
|
+
console.log(formatResult({ action: 'update', data }, globals()));
|
|
33
43
|
});
|
|
34
44
|
}
|
|
35
45
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../../src/commands/update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../../src/commands/update.ts"],"names":[],"mappings":"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"}
|