@did-btcr2/cli 0.20.0 → 0.22.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.
Files changed (50) hide show
  1. package/README.md +44 -27
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cjs/index.js +237 -175
  4. package/dist/esm/src/cli.js +3 -2
  5. package/dist/esm/src/cli.js.map +1 -1
  6. package/dist/esm/src/commands/completion.js +1 -1
  7. package/dist/esm/src/commands/completion.js.map +1 -1
  8. package/dist/esm/src/commands/deactivate.js +11 -88
  9. package/dist/esm/src/commands/deactivate.js.map +1 -1
  10. package/dist/esm/src/commands/identifier.js +110 -0
  11. package/dist/esm/src/commands/identifier.js.map +1 -0
  12. package/dist/esm/src/commands/index.js +1 -0
  13. package/dist/esm/src/commands/index.js.map +1 -1
  14. package/dist/esm/src/commands/resolve.js +4 -37
  15. package/dist/esm/src/commands/resolve.js.map +1 -1
  16. package/dist/esm/src/commands/update.js +15 -85
  17. package/dist/esm/src/commands/update.js.map +1 -1
  18. package/dist/esm/src/commands/write.js +119 -0
  19. package/dist/esm/src/commands/write.js.map +1 -0
  20. package/dist/esm/src/resolution-options.js +47 -0
  21. package/dist/esm/src/resolution-options.js.map +1 -0
  22. package/dist/esm/src/types.js.map +1 -1
  23. package/dist/types/src/cli.d.ts +1 -1
  24. package/dist/types/src/cli.d.ts.map +1 -1
  25. package/dist/types/src/commands/deactivate.d.ts +1 -1
  26. package/dist/types/src/commands/deactivate.d.ts.map +1 -1
  27. package/dist/types/src/commands/identifier.d.ts +12 -0
  28. package/dist/types/src/commands/identifier.d.ts.map +1 -0
  29. package/dist/types/src/commands/index.d.ts +1 -0
  30. package/dist/types/src/commands/index.d.ts.map +1 -1
  31. package/dist/types/src/commands/resolve.d.ts.map +1 -1
  32. package/dist/types/src/commands/update.d.ts +1 -1
  33. package/dist/types/src/commands/update.d.ts.map +1 -1
  34. package/dist/types/src/commands/write.d.ts +47 -0
  35. package/dist/types/src/commands/write.d.ts.map +1 -0
  36. package/dist/types/src/resolution-options.d.ts +21 -0
  37. package/dist/types/src/resolution-options.d.ts.map +1 -0
  38. package/dist/types/src/types.d.ts +37 -7
  39. package/dist/types/src/types.d.ts.map +1 -1
  40. package/package.json +4 -4
  41. package/src/cli.ts +3 -1
  42. package/src/commands/completion.ts +1 -1
  43. package/src/commands/deactivate.ts +14 -142
  44. package/src/commands/identifier.ts +156 -0
  45. package/src/commands/index.ts +1 -0
  46. package/src/commands/resolve.ts +8 -64
  47. package/src/commands/update.ts +19 -139
  48. package/src/commands/write.ts +198 -0
  49. package/src/resolution-options.ts +67 -0
  50. package/src/types.ts +34 -7
@@ -1,98 +1,21 @@
1
- import { KeyManagerSigner } from '@did-btcr2/key-manager';
2
- import { assertKeystoreAllowedForNetwork, deriveNetwork, resolveBroadcastOptions, resolveSigningKeyRef } from '../config.js';
3
- import { CLIError } from '../error.js';
4
1
  import { printWatchHint } from '../hints.js';
5
- import { resolveKeyRef } from '../keystore/resolve-key-ref.js';
6
2
  import { formatResult } from '../output.js';
7
- /** The JSON Patch that marks a DID document as permanently deactivated. */
8
- const DEACTIVATION_PATCH = [{ op: 'add', path: '/deactivated', value: true }];
3
+ import { prepareWrite, registerWriteOptions } from './write.js';
9
4
  export function registerDeactivateCommand(program, factory, globals) {
10
- program
5
+ const command = program
11
6
  .command('deactivate')
12
7
  .alias('delete')
13
8
  .description('Deactivate the did:btcr2 identifier permanently. This is irreversible.')
14
- .requiredOption('-s, --source-document <json>', 'Current DID document as JSON string', parseJsonArg('--source-document'))
15
- .requiredOption('--source-version-id <number>', 'Current version ID of the DID document')
16
- .requiredOption('-m, --verification-method-id <id>', 'DID document verification method ID used to sign the deactivation')
17
- .requiredOption('-b, --beacon-id <json>', 'Beacon ID as a JSON string', parseJsonArg('--beacon-id'))
18
- .option('--publish-to-cas <mode>', 'Publish update artifacts to a writable CAS before broadcast: auto|always|never. '
19
- + 'CAS publication is optional; the default distributes the returned artifacts via sidecar.', parsePublishToCasMode, 'never')
20
- .option('--fee-rate <satsPerVByte>', 'Fee rate in sats/vByte for the beacon transaction (default: 5). '
21
- + 'Raise it under congestion so the transaction confirms.')
22
- .option('--change-address <address>', 'Send transaction change to this address instead of the beacon address, '
23
- + 'so a DID\'s announcements are not linked on-chain (ADR 044).')
9
+ .requiredOption('-i, --identifier <identifier>', 'did:btcr2 identifier to deactivate');
10
+ registerWriteOptions(command)
24
11
  .action(async (options) => {
25
- if (!/^\d+$/.test(options.sourceVersionId)) {
26
- throw new CLIError('--source-version-id must be a non-negative integer.', 'INVALID_ARGUMENT_ERROR', { value: options.sourceVersionId });
27
- }
28
- const parsed = {
29
- sourceDocument: options.sourceDocument,
30
- patches: DEACTIVATION_PATCH,
31
- sourceVersionId: Number(options.sourceVersionId),
32
- verificationMethodId: options.verificationMethodId,
33
- beaconId: options.beaconId,
34
- };
35
- const did = parsed.sourceDocument?.id;
36
- if (!did) {
37
- throw new CLIError('Source document must contain an "id" field.', 'INVALID_ARGUMENT_ERROR', options);
38
- }
39
- // Deactivation is an update that applies the deactivation patch. The core
40
- // method has no separate deactivate path, so this routes through update.
41
- const network = deriveNetwork(did);
42
- // Refuse to sign a mainnet deactivation with an unencrypted dev keystore (ADR 080).
43
- assertKeystoreAllowedForNetwork(network, globals());
44
- const api = factory(network, globals());
45
- const keyId = resolveKeyRef(api.kms.kms, resolveSigningKeyRef(globals()));
46
- const signer = new KeyManagerSigner(api.kms.kms, keyId);
47
- // Resolve fee-rate/change-address through the flag -> env -> profile chain
48
- // into beacon broadcast options. Undefined when neither is set, so the
49
- // SDK defaults (5 sat/vB, change back to the beacon address) still apply.
50
- const broadcastOptions = resolveBroadcastOptions(network, globals(), {
51
- feeRate: options.feeRate,
52
- changeAddress: options.changeAddress,
53
- });
54
- // CAS publication is optional and never required: every beacon update can
55
- // be completed and shared via sidecar alone. It is opt-in and defaults to
56
- // 'never'; pass --publish-to-cas auto|always to publish the signed update
57
- // (and, for CAS beacons, the announcement) to a writable CAS configured
58
- // via --cas-rpc-url. The returned artifacts (txid, announcement, proof)
59
- // are always printed for sidecar distribution regardless.
60
- const data = await api.btcr2.update({
61
- sourceDocument: parsed.sourceDocument,
62
- patches: parsed.patches,
63
- sourceVersionId: parsed.sourceVersionId,
64
- verificationMethodId: parsed.verificationMethodId,
65
- beaconId: parsed.beaconId,
66
- signer,
67
- publishToCas: options.publishToCas,
68
- ...(broadcastOptions ? { broadcastOptions } : {}),
69
- });
70
- console.log(formatResult({ action: 'deactivate', data }, globals()));
71
- printWatchHint(globals(), network, data.txid);
12
+ const g = globals();
13
+ const { network, api, params } = await prepareWrite(options, factory, g);
14
+ // The api supplies the deactivation patch (ADR 094) and refuses a
15
+ // document that is deactivated already (ADR 100).
16
+ const data = await api.deactivateDid(params);
17
+ console.log(formatResult({ action: 'deactivate', data }, g));
18
+ printWatchHint(g, network, data.txid);
72
19
  });
73
20
  }
74
- /**
75
- * Commander argParser for `--publish-to-cas`. Validates the value is one of the
76
- * three {@link PublishToCasMode} policies, erroring at parse time otherwise.
77
- */
78
- function parsePublishToCasMode(value) {
79
- if (value !== 'auto' && value !== 'always' && value !== 'never') {
80
- throw new CLIError('--publish-to-cas must be one of "auto", "always", or "never".', 'INVALID_ARGUMENT_ERROR', { value });
81
- }
82
- return value;
83
- }
84
- /**
85
- * Returns a commander argParser that validates JSON.
86
- * Errors at parse time with a clear flag reference.
87
- */
88
- function parseJsonArg(flagName) {
89
- return (value) => {
90
- try {
91
- return JSON.parse(value);
92
- }
93
- catch {
94
- throw new CLIError(`Invalid JSON for ${flagName}. Must be a valid JSON string.`, 'INVALID_ARGUMENT_ERROR', { flagName, value });
95
- }
96
- };
97
- }
98
21
  //# sourceMappingURL=deactivate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"deactivate.js","sourceRoot":"","sources":["../../../../src/commands/deactivate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,+BAA+B,EAAE,aAAa,EAAE,uBAAuB,EAAE,oBAAoB,EAAmB,MAAM,cAAc,CAAC;AAC9I,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,2EAA2E;AAC3E,MAAM,kBAAkB,GAAG,CAAC,EAAE,EAAE,EAAE,KAAc,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAEvF,MAAM,UAAU,yBAAyB,CACvC,OAAiB,EACjB,OAAoB,EACpB,OAA6B;IAE7B,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,KAAK,CAAC,QAAQ,CAAC;SACf,WAAW,CAAC,wEAAwE,CAAC;SACrF,cAAc,CACb,8BAA8B,EAC9B,qCAAqC,EACrC,YAAY,CAAC,mBAAmB,CAAC,CAClC;SACA,cAAc,CACb,8BAA8B,EAC9B,wCAAwC,CACzC;SACA,cAAc,CACb,mCAAmC,EACnC,mEAAmE,CACpE;SACA,cAAc,CACb,wBAAwB,EACxB,4BAA4B,EAC5B,YAAY,CAAC,aAAa,CAAC,CAC5B;SACA,MAAM,CACL,yBAAyB,EACzB,kFAAkF;UAC9E,0FAA0F,EAC9F,qBAAqB,EACrB,OAAO,CACR;SACA,MAAM,CACL,2BAA2B,EAC3B,kEAAkE;UAC9D,wDAAwD,CAC7D;SACA,MAAM,CACL,4BAA4B,EAC5B,yEAAyE;UACrE,8DAA8D,CACnE;SACA,MAAM,CAAC,KAAK,EAAE,OAQd,EAAE,EAAE;QACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,QAAQ,CAChB,qDAAqD,EACrD,wBAAwB,EACxB,EAAE,KAAK,EAAE,OAAO,CAAC,eAAe,EAAE,CACnC,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAyB;YACnC,cAAc,EAAS,OAAO,CAAC,cAAwD;YACvF,OAAO,EAAgB,kBAAkB;YACzC,eAAe,EAAQ,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;YACtD,oBAAoB,EAAG,OAAO,CAAC,oBAAoB;YACnD,QAAQ,EAAe,OAAO,CAAC,QAA4C;SAC5E,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,QAAQ,CAChB,6CAA6C,EAC7C,wBAAwB,EACxB,OAAO,CACR,CAAC;QACJ,CAAC;QACD,0EAA0E;QAC1E,yEAAyE;QACzE,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QACnC,oFAAoF;QACpF,+BAA+B,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,2EAA2E;QAC3E,uEAAuE;QACvE,0EAA0E;QAC1E,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;YACnE,OAAO,EAAS,OAAO,CAAC,OAAO;YAC/B,aAAa,EAAG,OAAO,CAAC,aAAa;SACtC,CAAC,CAAC;QACH,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,wEAAwE;QACxE,wEAAwE;QACxE,0DAA0D;QAC1D,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;YAClC,cAAc,EAAS,MAAM,CAAC,cAAc;YAC5C,OAAO,EAAgB,MAAM,CAAC,OAAO;YACrC,eAAe,EAAQ,MAAM,CAAC,eAAe;YAC7C,oBAAoB,EAAG,MAAM,CAAC,oBAAoB;YAClD,QAAQ,EAAe,MAAM,CAAC,QAAQ;YACtC,MAAM;YACN,YAAY,EAAW,OAAO,CAAC,YAAY;YAC3C,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACrE,cAAc,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAAC,KAAa;IAC1C,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QAChE,MAAM,IAAI,QAAQ,CAChB,+DAA+D,EAC/D,wBAAwB,EACxB,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAO,CAAC,KAAa,EAAW,EAAE;QAChC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,QAAQ,CAChB,oBAAoB,QAAQ,gCAAgC,EAC5D,wBAAwB,EACxB,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"deactivate.js","sourceRoot":"","sources":["../../../../src/commands/deactivate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAmB,MAAM,YAAY,CAAC;AAEjF,MAAM,UAAU,yBAAyB,CACvC,OAAiB,EACjB,OAAoB,EACpB,OAA6B;IAE7B,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,YAAY,CAAC;SACrB,KAAK,CAAC,QAAQ,CAAC;SACf,WAAW,CAAC,wEAAwE,CAAC;SACrF,cAAc,CAAC,+BAA+B,EAAE,oCAAoC,CAAC,CAAC;IACzF,oBAAoB,CAAC,OAAO,CAAC;SAC1B,MAAM,CAAC,KAAK,EAAE,OAAmB,EAAE,EAAE;QACpC,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACzE,kEAAkE;QAClE,kDAAkD;QAClD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7D,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { Identifier } from '@did-btcr2/api';
2
+ import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { CLIError } from '../error.js';
5
+ import { formatResult } from '../output.js';
6
+ /**
7
+ * Registers the `identifier` command group. `decode` prints the components of
8
+ * a did:btcr2 identifier. `validate` checks that an identifier conforms to the
9
+ * specification and prints a report. Both commands are offline and
10
+ * keystore-free: they use the api with no Bitcoin connection, no CAS, and no
11
+ * key material.
12
+ */
13
+ export function registerIdentifierCommand(program, factory, globals) {
14
+ const identifier = program
15
+ .command('identifier')
16
+ .description('Decode and validate did:btcr2 identifiers (offline).');
17
+ const print = (result) => console.log(formatResult(result, globals()));
18
+ identifier
19
+ .command('decode <did>')
20
+ .description('Print the components of a did:btcr2 identifier.')
21
+ .option('--initial-document', 'Add the initial DID document. An external identifier (x) needs --genesis-document.', false)
22
+ .option('--genesis-document <path>', 'Path to the JSON genesis document of an external identifier (x). Requires --initial-document.')
23
+ .action(async (did, options) => {
24
+ if (options.genesisDocument !== undefined && !options.initialDocument) {
25
+ throw new CLIError('--genesis-document requires --initial-document.', 'INVALID_ARGUMENT_ERROR');
26
+ }
27
+ assertValidIdentifier(did);
28
+ const api = factory();
29
+ const components = api.did.decode(did);
30
+ if (options.genesisDocument !== undefined && components.hrp === 'k') {
31
+ throw new CLIError('--genesis-document applies only to external identifiers (x).', 'INVALID_ARGUMENT_ERROR', { did });
32
+ }
33
+ const data = {
34
+ did,
35
+ idType: components.idType,
36
+ hrp: components.hrp,
37
+ version: components.version,
38
+ network: components.network,
39
+ genesisBytes: bytesToHex(components.genesisBytes),
40
+ };
41
+ if (options.initialDocument) {
42
+ if (components.hrp === 'x' && options.genesisDocument === undefined) {
43
+ throw new CLIError('An external identifier (x) needs --genesis-document <path> for --initial-document.', 'INVALID_ARGUMENT_ERROR', { did });
44
+ }
45
+ const genesisDocument = options.genesisDocument === undefined
46
+ ? undefined
47
+ : await readGenesisDocument(options.genesisDocument);
48
+ data.initialDocument = api.btcr2.getInitialDocument(did, genesisDocument);
49
+ }
50
+ print({ action: 'identifier-decode', data });
51
+ });
52
+ identifier
53
+ .command('validate <did>')
54
+ .description('Check that a did:btcr2 identifier conforms to the specification. Exit code 1 if it does not.')
55
+ .option('-b, --bytes <hex>', 'Genesis bytes as a hex string that the identifier must encode: the 33-byte public key (k) '
56
+ + 'or the 32-byte genesis document hash (x). Adds the genesisBytesMatch check.')
57
+ .option('--genesis-document <path>', 'Path to the JSON genesis document of an external identifier (x). Adds the genesisDocument check.')
58
+ .action(async (did, options) => {
59
+ const genesisBytes = options.bytes === undefined ? undefined : parseHexBytes(options.bytes);
60
+ let genesisDocument;
61
+ if (options.genesisDocument !== undefined) {
62
+ // Refuse the flag for a KEY identifier before the file read. An invalid
63
+ // identifier passes through: the report names its failed check.
64
+ if (Identifier.isValid(did) && Identifier.decode(did).hrp === 'k') {
65
+ throw new CLIError('--genesis-document applies only to external identifiers (x).', 'INVALID_ARGUMENT_ERROR', { did });
66
+ }
67
+ genesisDocument = await readGenesisDocument(options.genesisDocument);
68
+ }
69
+ const report = factory().did.validate(did, { genesisBytes, genesisDocument });
70
+ print({ action: 'identifier-validate', data: report });
71
+ if (!report.valid)
72
+ process.exitCode = 1;
73
+ });
74
+ }
75
+ /**
76
+ * Throws a `CLIError` that names the failed check if the identifier is not
77
+ * valid. The Bech32m decoder alone throws a raw error with a stack; this
78
+ * guard gives `decode` one message shape for every failure.
79
+ */
80
+ function assertValidIdentifier(did) {
81
+ const report = Identifier.validate(did);
82
+ if (report.valid)
83
+ return;
84
+ const failed = report.checks[report.checks.length - 1];
85
+ throw new CLIError(`Invalid identifier (${failed.name} check): ${failed.detail ?? 'failed'}`, 'INVALID_ARGUMENT_ERROR', { did, check: failed.name });
86
+ }
87
+ /** Parses the `--bytes` hex string. The length is a validation result, not an argument error. */
88
+ function parseHexBytes(value) {
89
+ try {
90
+ return hexToBytes(value.trim());
91
+ }
92
+ catch {
93
+ throw new CLIError('Invalid bytes: not valid hex.', 'INVALID_ARGUMENT_ERROR', { bytes: value });
94
+ }
95
+ }
96
+ /** Reads and parses the genesis document file. The content must be a JSON object. */
97
+ async function readGenesisDocument(path) {
98
+ let parsed;
99
+ try {
100
+ parsed = JSON.parse(await readFile(path, 'utf-8'));
101
+ }
102
+ catch {
103
+ throw new CLIError('Invalid genesis document path. Must be a valid path to a JSON file.', 'INVALID_ARGUMENT_ERROR', { genesisDocument: path });
104
+ }
105
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
106
+ throw new CLIError('Invalid genesis document. The file must contain a JSON object.', 'INVALID_ARGUMENT_ERROR', { genesisDocument: path });
107
+ }
108
+ return parsed;
109
+ }
110
+ //# sourceMappingURL=identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../src/commands/identifier.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ export { registerCreateCommand } from './create.js';
4
4
  export { registerResolveCommand } from './resolve.js';
5
5
  export { registerUpdateCommand } from './update.js';
6
6
  export { registerDeactivateCommand } from './deactivate.js';
7
+ export { registerIdentifierCommand } from './identifier.js';
7
8
  export { registerKeyCommand } from './key.js';
8
9
  export { registerKeystoreCommand } from './keystore.js';
9
10
  export { registerConfigCommand } from './config.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,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,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,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,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,8 +1,7 @@
1
- import { DEFAULT_MIN_CONF, Identifier } from '@did-btcr2/api';
2
- import { readFile } from 'node:fs/promises';
1
+ import { Identifier } from '@did-btcr2/api';
3
2
  import { deriveNetwork } from '../config.js';
4
- import { CLIError } from '../error.js';
5
3
  import { formatResult } from '../output.js';
4
+ import { MIN_CONF_HELP, parseMinConf, readResolutionOptions } from '../resolution-options.js';
6
5
  export function registerResolveCommand(program, factory, globals) {
7
6
  program
8
7
  .command('resolve')
@@ -11,8 +10,7 @@ export function registerResolveCommand(program, factory, globals) {
11
10
  .requiredOption('-i, --identifier <identifier>', 'did:btcr2 identifier')
12
11
  .option('-r, --resolution-options <json>', 'JSON string containing resolution options')
13
12
  .option('-p, --resolution-options-path <path>', 'Path to a JSON file containing resolution options')
14
- .option('--min-conf <n>', 'Minimum block confirmations a beacon signal needs before resolution applies it '
15
- + `(positive integer, default: ${DEFAULT_MIN_CONF}). Overrides minConf inside -r/-p`, parseMinConf)
13
+ .option('--min-conf <n>', MIN_CONF_HELP, parseMinConf)
16
14
  .action(async (options) => {
17
15
  const parsed = await validateResolveOptions(options);
18
16
  const network = deriveNetwork(parsed.identifier);
@@ -25,38 +23,7 @@ export function registerResolveCommand(program, factory, globals) {
25
23
  async function validateResolveOptions(options) {
26
24
  // Validate identifier format early
27
25
  Identifier.decode(options.identifier);
28
- let resolutionOptions = undefined;
29
- if (options.resolutionOptions) {
30
- try {
31
- resolutionOptions = JSON.parse(options.resolutionOptions);
32
- }
33
- catch {
34
- throw new CLIError('Invalid resolution options. Must be a valid JSON string.', 'INVALID_ARGUMENT_ERROR', options);
35
- }
36
- }
37
- else if (options.resolutionOptionsPath) {
38
- try {
39
- const content = await readFile(options.resolutionOptionsPath, 'utf-8');
40
- resolutionOptions = JSON.parse(content);
41
- }
42
- catch {
43
- throw new CLIError('Invalid resolution options path. Must be a valid path to a JSON file.', 'INVALID_ARGUMENT_ERROR', options);
44
- }
45
- }
46
- // The flag wins over a minConf inside the JSON options.
47
- if (options.minConf !== undefined) {
48
- resolutionOptions = { ...(resolutionOptions ?? {}), minConf: options.minConf };
49
- }
26
+ const resolutionOptions = await readResolutionOptions(options);
50
27
  return { identifier: options.identifier, options: resolutionOptions };
51
28
  }
52
- /**
53
- * Commander argParser for `--min-conf`. Accepts a positive integer (minimum 1),
54
- * the domain the specification gives `minConf`. Errors at parse time otherwise.
55
- */
56
- function parseMinConf(value) {
57
- if (!/^[1-9]\d*$/.test(value)) {
58
- throw new CLIError('--min-conf must be a positive integer (minimum 1).', 'INVALID_ARGUMENT_ERROR', { value });
59
- }
60
- return Number(value);
61
- }
62
29
  //# sourceMappingURL=resolve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../../src/commands/resolve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../../src/commands/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAmB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,qBAAqB,EAA8B,MAAM,0BAA0B,CAAC;AAG1H,MAAM,UAAU,sBAAsB,CACpC,OAAiB,EACjB,OAAoB,EACpB,OAA6B;IAE7B,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,KAAK,CAAC,MAAM,CAAC;SACb,WAAW,CAAC,6CAA6C,CAAC;SAC1D,cAAc,CAAC,+BAA+B,EAAE,sBAAsB,CAAC;SACvE,MAAM,CAAC,iCAAiC,EAAE,2CAA2C,CAAC;SACtF,MAAM,CAAC,sCAAsC,EAAE,mDAAmD,CAAC;SACnG,MAAM,CAAC,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC;SACrD,MAAM,CAAC,KAAK,EAAE,OAAuD,EAAE,EAAE;QACxE,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACrE,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,SAAkB,EAAE,IAAI,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,OAAuD;IAEvD,mCAAmC;IACnC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,iBAAiB,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AACxE,CAAC"}
@@ -1,94 +1,24 @@
1
- import { KeyManagerSigner } from '@did-btcr2/key-manager';
2
- import { assertKeystoreAllowedForNetwork, deriveNetwork, resolveBroadcastOptions, resolveSigningKeyRef } from '../config.js';
3
- import { CLIError } from '../error.js';
4
1
  import { printWatchHint } from '../hints.js';
5
- import { resolveKeyRef } from '../keystore/resolve-key-ref.js';
6
2
  import { formatResult } from '../output.js';
3
+ import { parseJsonArg, prepareWrite, registerWriteOptions } from './write.js';
7
4
  export function registerUpdateCommand(program, factory, globals) {
8
- program
5
+ const command = program
9
6
  .command('update')
10
7
  .description('Update a did:btcr2 document.')
11
- .requiredOption('-s, --source-document <json>', 'Source DID document as JSON string', parseJsonArg('--source-document'))
12
- .requiredOption('--source-version-id <number>', 'Source version ID as a number')
13
- .requiredOption('-p, --patches <json>', 'JSON Patch operations as a JSON string array', parseJsonArg('--patches'))
14
- .requiredOption('-m, --verification-method-id <id>', 'DID document verification method ID')
15
- .requiredOption('-b, --beacon-id <json>', 'Beacon ID as a JSON string', parseJsonArg('--beacon-id'))
16
- .option('--publish-to-cas <mode>', 'Publish update artifacts to a writable CAS before broadcast: auto|always|never. '
17
- + 'CAS publication is optional; the default distributes the returned artifacts via sidecar.', parsePublishToCasMode, 'never')
18
- .option('--fee-rate <satsPerVByte>', 'Fee rate in sats/vByte for the beacon transaction (default: 5). '
19
- + 'Raise it under congestion so the transaction confirms.')
20
- .option('--change-address <address>', 'Send transaction change to this address instead of the beacon address, '
21
- + 'so a DID\'s announcements are not linked on-chain (ADR 044).')
8
+ .requiredOption('-i, --identifier <identifier>', 'did:btcr2 identifier to update')
9
+ .requiredOption('-p, --patches <json>', 'JSON Patch operations as a JSON string array', parseJsonArg('--patches'));
10
+ registerWriteOptions(command)
22
11
  .action(async (options) => {
23
- if (!/^\d+$/.test(options.sourceVersionId)) {
24
- throw new CLIError('--source-version-id must be a non-negative integer.', 'INVALID_ARGUMENT_ERROR', { value: options.sourceVersionId });
25
- }
26
- const parsed = {
27
- sourceDocument: options.sourceDocument,
28
- patches: options.patches,
29
- sourceVersionId: Number(options.sourceVersionId),
30
- verificationMethodId: options.verificationMethodId,
31
- beaconId: options.beaconId,
32
- };
33
- const did = parsed.sourceDocument?.id;
34
- if (!did) {
35
- throw new CLIError('Source document must contain an "id" field.', 'INVALID_ARGUMENT_ERROR', options);
36
- }
37
- const network = deriveNetwork(did);
38
- // Refuse to sign a mainnet update with an unencrypted dev keystore (ADR 080).
39
- assertKeystoreAllowedForNetwork(network, globals());
40
- const api = factory(network, globals());
41
- const keyId = resolveKeyRef(api.kms.kms, resolveSigningKeyRef(globals()));
42
- const signer = new KeyManagerSigner(api.kms.kms, keyId);
43
- // Resolve fee-rate/change-address through the flag -> env -> profile chain
44
- // into beacon broadcast options. Undefined when neither is set, so the
45
- // SDK defaults (5 sat/vB, change back to the beacon address) still apply.
46
- const broadcastOptions = resolveBroadcastOptions(network, globals(), {
47
- feeRate: options.feeRate,
48
- changeAddress: options.changeAddress,
49
- });
50
- // CAS publication is optional and never required: every beacon update can
51
- // be completed and shared via sidecar alone. It is opt-in and defaults to
52
- // 'never'; pass --publish-to-cas auto|always to publish the signed update
53
- // (and, for CAS beacons, the announcement) to a writable CAS configured
54
- // via --cas-rpc-url. The returned artifacts (txid, announcement, proof)
55
- // are always printed for sidecar distribution regardless.
56
- const data = await api.btcr2.update({
57
- sourceDocument: parsed.sourceDocument,
58
- patches: parsed.patches,
59
- sourceVersionId: parsed.sourceVersionId,
60
- verificationMethodId: parsed.verificationMethodId,
61
- beaconId: parsed.beaconId,
62
- signer,
63
- publishToCas: options.publishToCas,
64
- ...(broadcastOptions ? { broadcastOptions } : {}),
65
- });
66
- console.log(formatResult({ action: 'update', data }, globals()));
67
- printWatchHint(globals(), network, data.txid);
12
+ const g = globals();
13
+ const { network, api, params } = await prepareWrite(options, factory, g);
14
+ // The api resolves the source document if the source pair is absent,
15
+ // derives an omitted verification method and beacon, and publishes to
16
+ // the CAS only under --publish-to-cas auto|always. The returned
17
+ // artifacts (txid, signed update, announcement, proof) are printed for
18
+ // sidecar distribution in every case.
19
+ const data = await api.updateDid({ ...params, patches: options.patches });
20
+ console.log(formatResult({ action: 'update', data }, g));
21
+ printWatchHint(g, network, data.txid);
68
22
  });
69
23
  }
70
- /**
71
- * Commander argParser for `--publish-to-cas`. Validates the value is one of the
72
- * three {@link PublishToCasMode} policies, erroring at parse time otherwise.
73
- */
74
- function parsePublishToCasMode(value) {
75
- if (value !== 'auto' && value !== 'always' && value !== 'never') {
76
- throw new CLIError('--publish-to-cas must be one of "auto", "always", or "never".', 'INVALID_ARGUMENT_ERROR', { value });
77
- }
78
- return value;
79
- }
80
- /**
81
- * Returns a commander argParser that validates JSON.
82
- * Errors at parse time with a clear flag reference.
83
- */
84
- function parseJsonArg(flagName) {
85
- return (value) => {
86
- try {
87
- return JSON.parse(value);
88
- }
89
- catch {
90
- throw new CLIError(`Invalid JSON for ${flagName}. Must be a valid JSON string.`, 'INVALID_ARGUMENT_ERROR', { flagName, value });
91
- }
92
- };
93
- }
94
24
  //# sourceMappingURL=update.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../../src/commands/update.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../../src/commands/update.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAmB,MAAM,YAAY,CAAC;AAE/F,MAAM,UAAU,qBAAqB,CACnC,OAAiB,EACjB,OAAoB,EACpB,OAA6B;IAE7B,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8BAA8B,CAAC;SAC3C,cAAc,CAAC,+BAA+B,EAAE,gCAAgC,CAAC;SACjF,cAAc,CACb,sBAAsB,EACtB,8CAA8C,EAC9C,YAAY,CAAC,WAAW,CAAC,CAC1B,CAAC;IACJ,oBAAoB,CAAC,OAAO,CAAC;SAC1B,MAAM,CAAC,KAAK,EAAE,OAA0C,EAAE,EAAE;QAC3D,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACzE,qEAAqE;QACrE,sEAAsE;QACtE,gEAAgE;QAChE,uEAAuE;QACvE,sCAAsC;QACtC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAA2B,EAAE,CAAC,CAAC;QAC9F,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,119 @@
1
+ import { KeyManagerSigner } from '@did-btcr2/key-manager';
2
+ import { assertKeystoreAllowedForNetwork, deriveNetwork, resolveBroadcastOptions, resolveSigningKeyRef, } from '../config.js';
3
+ import { CLIError } from '../error.js';
4
+ import { resolveKeyRef } from '../keystore/resolve-key-ref.js';
5
+ import { MIN_CONF_HELP, parseMinConf, readResolutionOptions } from '../resolution-options.js';
6
+ /**
7
+ * Registers the flags that `update` and `deactivate` share. Each command
8
+ * registers `-i/--identifier` (and `update` its `-p/--patches`) before it
9
+ * calls this function, so those flags lead the help output.
10
+ */
11
+ export function registerWriteOptions(command) {
12
+ return command
13
+ .option('-s, --source-document <json>', 'Source DID document as a JSON string. Requires --source-version-id. '
14
+ + 'Omit both to resolve the current document first', parseJsonArg('--source-document'))
15
+ .option('--source-version-id <number>', 'Version ID of the source document, a non-negative integer. Requires --source-document', parseSourceVersionId)
16
+ .option('-m, --verification-method-id <id>', 'Verification method that signs the update '
17
+ + '(default: the one method of the document that publishes the signing key)')
18
+ .option('-b, --beacon-id <id>', 'Beacon service that announces the update, as a DID URL '
19
+ + '(default: the only beacon of the document, else the one beacon with a spendable UTXO)')
20
+ .option('-r, --resolution-options <json>', 'Resolution options as a JSON string, for the resolution of the source document')
21
+ .option('--resolution-options-path <path>', 'Path to a JSON file with resolution options, for the resolution of the source document')
22
+ .option('--min-conf <n>', MIN_CONF_HELP, parseMinConf)
23
+ .option('--publish-to-cas <mode>', 'Publish update artifacts to a writable CAS before broadcast: auto|always|never. '
24
+ + 'CAS publication is optional; the default distributes the returned artifacts via sidecar.', parsePublishToCasMode, 'never')
25
+ .option('--fee-rate <satsPerVByte>', 'Fee rate in sats/vByte for the beacon transaction (default: 5). '
26
+ + 'Raise it under congestion so the transaction confirms.')
27
+ .option('--change-address <address>', 'Send transaction change to this address instead of the beacon address, '
28
+ + 'so a DID\'s announcements are not linked on-chain (ADR 044).');
29
+ }
30
+ /**
31
+ * Validates the shared write flags, derives the network from the identifier,
32
+ * applies the mainnet keystore guard, builds the signer, and returns the
33
+ * parameters for `updateDid` and `deactivateDid`.
34
+ *
35
+ * The checks run in this order, before any key material is read:
36
+ * 1. The identifier decodes and names a supported network.
37
+ * 2. `--source-document` and `--source-version-id` come together or not at
38
+ * all (ADR 101). The api refuses a half pair too; the cli names the flags.
39
+ * 3. The resolution flags come only without the source pair. The api ignores
40
+ * `resolutionOptions` when the pair is supplied (ADR 098). A silent ignore
41
+ * of `--min-conf` would mislead.
42
+ * 4. A mainnet write is refused with an unencrypted dev keystore (ADR 080).
43
+ */
44
+ export async function prepareWrite(options, factory, g) {
45
+ const did = options.identifier;
46
+ const network = deriveNetwork(did);
47
+ const hasDocument = options.sourceDocument !== undefined;
48
+ const hasVersion = options.sourceVersionId !== undefined;
49
+ if (hasDocument !== hasVersion) {
50
+ throw new CLIError('Provide both --source-document and --source-version-id, or neither. '
51
+ + 'Omit both to resolve the current document first.', 'INVALID_ARGUMENT_ERROR', { did });
52
+ }
53
+ const hasResolutionFlags = options.resolutionOptions !== undefined
54
+ || options.resolutionOptionsPath !== undefined
55
+ || options.minConf !== undefined;
56
+ if (hasDocument && hasResolutionFlags) {
57
+ throw new CLIError('--resolution-options, --resolution-options-path, and --min-conf apply only when '
58
+ + '--source-document and --source-version-id are omitted. A supplied source pair skips resolution.', 'INVALID_ARGUMENT_ERROR', { did });
59
+ }
60
+ assertKeystoreAllowedForNetwork(network, g);
61
+ const resolutionOptions = await readResolutionOptions(options);
62
+ const api = factory(network, g);
63
+ const keyId = resolveKeyRef(api.kms.kms, resolveSigningKeyRef(g));
64
+ const signer = new KeyManagerSigner(api.kms.kms, keyId);
65
+ // Resolve fee-rate/change-address through the flag, env, and profile layers
66
+ // into beacon broadcast options. Undefined when no layer sets one, so the
67
+ // SDK defaults (5 sat/vB, change back to the beacon address) still apply.
68
+ const broadcastOptions = resolveBroadcastOptions(network, g, {
69
+ feeRate: options.feeRate,
70
+ changeAddress: options.changeAddress,
71
+ });
72
+ return {
73
+ network,
74
+ api,
75
+ params: {
76
+ did,
77
+ signer,
78
+ sourceDocument: options.sourceDocument,
79
+ sourceVersionId: options.sourceVersionId,
80
+ verificationMethodId: options.verificationMethodId,
81
+ beaconId: options.beaconId,
82
+ resolutionOptions,
83
+ publishToCas: options.publishToCas,
84
+ broadcastOptions,
85
+ },
86
+ };
87
+ }
88
+ /** Commander argParser for `--source-version-id`: digits only, a non-negative integer. */
89
+ function parseSourceVersionId(value) {
90
+ if (!/^\d+$/.test(value)) {
91
+ throw new CLIError('--source-version-id must be a non-negative integer.', 'INVALID_ARGUMENT_ERROR', { value });
92
+ }
93
+ return Number(value);
94
+ }
95
+ /**
96
+ * Commander argParser for `--publish-to-cas`. Validates the value is one of the
97
+ * three {@link PublishToCasMode} policies, erroring at parse time otherwise.
98
+ */
99
+ function parsePublishToCasMode(value) {
100
+ if (value !== 'auto' && value !== 'always' && value !== 'never') {
101
+ throw new CLIError('--publish-to-cas must be one of "auto", "always", or "never".', 'INVALID_ARGUMENT_ERROR', { value });
102
+ }
103
+ return value;
104
+ }
105
+ /**
106
+ * Returns a commander argParser that validates JSON.
107
+ * Errors at parse time with a clear flag reference.
108
+ */
109
+ export function parseJsonArg(flagName) {
110
+ return (value) => {
111
+ try {
112
+ return JSON.parse(value);
113
+ }
114
+ catch {
115
+ throw new CLIError(`Invalid JSON for ${flagName}. Must be a valid JSON string.`, 'INVALID_ARGUMENT_ERROR', { flagName, value });
116
+ }
117
+ };
118
+ }
119
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../../../src/commands/write.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EACL,+BAA+B,EAC/B,aAAa,EACb,uBAAuB,EACvB,oBAAoB,GAErB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,qBAAqB,EAA8B,MAAM,0BAA0B,CAAC;AAe1H;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO,OAAO;SACX,MAAM,CACL,8BAA8B,EAC9B,sEAAsE;UAClE,iDAAiD,EACrD,YAAY,CAAC,mBAAmB,CAAC,CAClC;SACA,MAAM,CACL,8BAA8B,EAC9B,uFAAuF,EACvF,oBAAoB,CACrB;SACA,MAAM,CACL,mCAAmC,EACnC,4CAA4C;UACxC,0EAA0E,CAC/E;SACA,MAAM,CACL,sBAAsB,EACtB,yDAAyD;UACrD,uFAAuF,CAC5F;SACA,MAAM,CACL,iCAAiC,EACjC,gFAAgF,CACjF;SACA,MAAM,CACL,kCAAkC,EAClC,wFAAwF,CACzF;SACA,MAAM,CAAC,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC;SACrD,MAAM,CACL,yBAAyB,EACzB,kFAAkF;UAC9E,0FAA0F,EAC9F,qBAAqB,EACrB,OAAO,CACR;SACA,MAAM,CACL,2BAA2B,EAC3B,kEAAkE;UAC9D,wDAAwD,CAC7D;SACA,MAAM,CACL,4BAA4B,EAC5B,yEAAyE;UACrE,8DAA8D,CACnE,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAoB,EACpB,OAAoB,EACpB,CAAuB;IAEvB,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC;IAC/B,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC;IACzD,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC;IACzD,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,IAAI,QAAQ,CAChB,sEAAsE;cAClE,kDAAkD,EACtD,wBAAwB,EACxB,EAAE,GAAG,EAAE,CACR,CAAC;IACJ,CAAC;IACD,MAAM,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,KAAK,SAAS;WAC7D,OAAO,CAAC,qBAAqB,KAAK,SAAS;WAC3C,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC;IACnC,IAAI,WAAW,IAAI,kBAAkB,EAAE,CAAC;QACtC,MAAM,IAAI,QAAQ,CAChB,kFAAkF;cAC9E,iGAAiG,EACrG,wBAAwB,EACxB,EAAE,GAAG,EAAE,CACR,CAAC;IACJ,CAAC;IACD,+BAA+B,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC5C,MAAM,iBAAiB,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxD,4EAA4E;IAC5E,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,OAAO,EAAE,CAAC,EAAE;QAC3D,OAAO,EAAS,OAAO,CAAC,OAAO;QAC/B,aAAa,EAAG,OAAO,CAAC,aAAa;KACtC,CAAC,CAAC;IACH,OAAO;QACL,OAAO;QACP,GAAG;QACH,MAAM,EAAG;YACP,GAAG;YACH,MAAM;YACN,cAAc,EAAS,OAAO,CAAC,cAA8C;YAC7E,eAAe,EAAQ,OAAO,CAAC,eAAe;YAC9C,oBAAoB,EAAG,OAAO,CAAC,oBAAoB;YACnD,QAAQ,EAAe,OAAO,CAAC,QAAQ;YACvC,iBAAiB;YACjB,YAAY,EAAW,OAAO,CAAC,YAAY;YAC3C,gBAAgB;SACjB;KACF,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,SAAS,oBAAoB,CAAC,KAAa;IACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,QAAQ,CAChB,qDAAqD,EACrD,wBAAwB,EACxB,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAAC,KAAa;IAC1C,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QAChE,MAAM,IAAI,QAAQ,CAChB,+DAA+D,EAC/D,wBAAwB,EACxB,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,CAAC,KAAa,EAAW,EAAE;QAChC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,QAAQ,CAChB,oBAAoB,QAAQ,gCAAgC,EAC5D,wBAAwB,EACxB,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}