@did-btcr2/cli 0.15.0 → 0.17.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 (76) hide show
  1. package/README.md +47 -6
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cjs/index.js +836 -122
  4. package/dist/esm/src/cli.js +7 -4
  5. package/dist/esm/src/cli.js.map +1 -1
  6. package/dist/esm/src/commands/config.js +11 -15
  7. package/dist/esm/src/commands/config.js.map +1 -1
  8. package/dist/esm/src/commands/create.js +4 -1
  9. package/dist/esm/src/commands/create.js.map +1 -1
  10. package/dist/esm/src/commands/deactivate.js +3 -1
  11. package/dist/esm/src/commands/deactivate.js.map +1 -1
  12. package/dist/esm/src/commands/index.js +2 -0
  13. package/dist/esm/src/commands/index.js.map +1 -1
  14. package/dist/esm/src/commands/init.js +69 -0
  15. package/dist/esm/src/commands/init.js.map +1 -0
  16. package/dist/esm/src/commands/keystore.js +180 -0
  17. package/dist/esm/src/commands/keystore.js.map +1 -0
  18. package/dist/esm/src/commands/profile.js +1 -1
  19. package/dist/esm/src/commands/profile.js.map +1 -1
  20. package/dist/esm/src/commands/update.js +3 -1
  21. package/dist/esm/src/commands/update.js.map +1 -1
  22. package/dist/esm/src/config.js +109 -31
  23. package/dist/esm/src/config.js.map +1 -1
  24. package/dist/esm/src/keystore/file-key-store.js +388 -32
  25. package/dist/esm/src/keystore/file-key-store.js.map +1 -1
  26. package/dist/esm/src/keystore/passphrase.js +53 -10
  27. package/dist/esm/src/keystore/passphrase.js.map +1 -1
  28. package/dist/esm/src/keystore/paths.js +6 -18
  29. package/dist/esm/src/keystore/paths.js.map +1 -1
  30. package/dist/esm/src/keystore/session.js +250 -0
  31. package/dist/esm/src/keystore/session.js.map +1 -0
  32. package/dist/esm/src/paths.js +71 -0
  33. package/dist/esm/src/paths.js.map +1 -0
  34. package/dist/esm/src/types.js.map +1 -1
  35. package/dist/types/src/cli.d.ts.map +1 -1
  36. package/dist/types/src/commands/config.d.ts.map +1 -1
  37. package/dist/types/src/commands/create.d.ts.map +1 -1
  38. package/dist/types/src/commands/deactivate.d.ts.map +1 -1
  39. package/dist/types/src/commands/index.d.ts +2 -0
  40. package/dist/types/src/commands/index.d.ts.map +1 -1
  41. package/dist/types/src/commands/init.d.ts +13 -0
  42. package/dist/types/src/commands/init.d.ts.map +1 -0
  43. package/dist/types/src/commands/keystore.d.ts +11 -0
  44. package/dist/types/src/commands/keystore.d.ts.map +1 -0
  45. package/dist/types/src/commands/update.d.ts.map +1 -1
  46. package/dist/types/src/config.d.ts +38 -14
  47. package/dist/types/src/config.d.ts.map +1 -1
  48. package/dist/types/src/keystore/file-key-store.d.ts +102 -10
  49. package/dist/types/src/keystore/file-key-store.d.ts.map +1 -1
  50. package/dist/types/src/keystore/passphrase.d.ts +26 -1
  51. package/dist/types/src/keystore/passphrase.d.ts.map +1 -1
  52. package/dist/types/src/keystore/paths.d.ts +6 -10
  53. package/dist/types/src/keystore/paths.d.ts.map +1 -1
  54. package/dist/types/src/keystore/session.d.ts +105 -0
  55. package/dist/types/src/keystore/session.d.ts.map +1 -0
  56. package/dist/types/src/paths.d.ts +64 -0
  57. package/dist/types/src/paths.d.ts.map +1 -0
  58. package/dist/types/src/types.d.ts +53 -0
  59. package/dist/types/src/types.d.ts.map +1 -1
  60. package/package.json +3 -3
  61. package/src/cli.ts +8 -3
  62. package/src/commands/config.ts +12 -14
  63. package/src/commands/create.ts +4 -1
  64. package/src/commands/deactivate.ts +3 -1
  65. package/src/commands/index.ts +2 -0
  66. package/src/commands/init.ts +80 -0
  67. package/src/commands/keystore.ts +232 -0
  68. package/src/commands/profile.ts +1 -1
  69. package/src/commands/update.ts +3 -1
  70. package/src/config.ts +118 -35
  71. package/src/keystore/file-key-store.ts +498 -43
  72. package/src/keystore/passphrase.ts +71 -8
  73. package/src/keystore/paths.ts +6 -19
  74. package/src/keystore/session.ts +303 -0
  75. package/src/paths.ts +92 -0
  76. package/src/types.ts +16 -1
@@ -1,6 +1,8 @@
1
1
  import { type BitcoinApiConfig, type CasConfig, type DidBtcr2Api } from '@did-btcr2/api';
2
2
  import type { BroadcastOptions } from '@did-btcr2/method';
3
- import { type NetworkOption, type OutputFormat } from './types.js';
3
+ import { defaultConfigPath } from './paths.js';
4
+ import { type KeystoreProtectionLabel, type NetworkOption, type OutputFormat } from './types.js';
5
+ export { defaultConfigPath };
4
6
  /**
5
7
  * Endpoint overrides provided via CLI flags, env vars, or config file.
6
8
  * These override the per-network defaults the SDK applies
@@ -28,9 +30,11 @@ export type ConnectionOverrides = {
28
30
  btcRpcWallet?: string;
29
31
  /** Extra Bitcoin Core RPC headers as raw `Key: Value` flag values (repeatable). */
30
32
  btcRpcHeader?: string[];
33
+ /** CLI home root from `--home`. Colocates config.json + keystore.json (ADR 079). */
34
+ home?: string;
31
35
  config?: string;
32
36
  profile?: string;
33
- /** Keystore file path. Overrides the default `$XDG_DATA_HOME/btcr2/keystore.json`. */
37
+ /** Keystore file path. Overrides the home default `<home>/keystore.json`. */
34
38
  keystore?: string;
35
39
  /** Path to a file holding the keystore passphrase (for unattended use). */
36
40
  passphraseFile?: string;
@@ -123,6 +127,13 @@ export declare const CONFIG_SCHEMA_VERSION = 1;
123
127
  * absent file (ENOENT) still starts from `{}`.
124
128
  */
125
129
  export declare function writeConfigFile(path: string, mutate: (raw: Record<string, unknown>) => void): void;
130
+ /**
131
+ * Writes a default config scaffold to `path`: schema version, a `text` output
132
+ * default, and one empty profile per supported network. Shared by `config init`
133
+ * and `btcr2 init` so the seeded config is identical. Writes atomically (file
134
+ * 0600, dir 0700); the caller decides whether to overwrite an existing file.
135
+ */
136
+ export declare function writeDefaultConfigFile(path: string): void;
126
137
  /** Reads the value at a dotted path (e.g. `profiles.regtest.btc.rest`). */
127
138
  export declare function getConfigPath(config: Record<string, unknown>, path: string): unknown;
128
139
  /** Sets the value at a dotted path, creating intermediate objects. */
@@ -170,15 +181,6 @@ export declare const ENV_VARS: {
170
181
  * Only defined (non-empty) values are included.
171
182
  */
172
183
  export declare function readEnvOverrides(): ConnectionOverrides;
173
- /**
174
- * Default config file path following the XDG Base Directory Specification.
175
- *
176
- * Resolution order:
177
- * 1. `$XDG_CONFIG_HOME/btcr2/config.json`
178
- * 2. `%APPDATA%/btcr2/config.json` (Windows)
179
- * 3. `~/.config/btcr2/config.json` (fallback)
180
- */
181
- export declare function defaultConfigPath(): string;
182
184
  /**
183
185
  * Reads and JSON-parses a config file without applying the schema-version
184
186
  * ceiling check. Returns `undefined` only for a genuinely absent file (ENOENT).
@@ -245,6 +247,7 @@ export declare function profileNetworkMismatch(network: NetworkOption, overrides
245
247
  export declare function resolveOutputFormat(options: {
246
248
  output?: string;
247
249
  config?: string;
250
+ home?: string;
248
251
  }): OutputFormat;
249
252
  /**
250
253
  * Resolves the Bitcoin and CAS connection config for a network by merging,
@@ -364,12 +367,33 @@ export declare function runDoctor(network: NetworkOption, overrides?: Connection
364
367
  * CLI flags -> env vars -> config file profile -> network defaults.
365
368
  */
366
369
  export declare function defaultApiFactory(network?: NetworkOption, overrides?: ConnectionOverrides): DidBtcr2Api;
370
+ /**
371
+ * The protection mode of the resolved keystore, read without decrypting or
372
+ * prompting: `encrypted`, `dev` (plaintext), or `absent`. Used by `keystore
373
+ * status`, `config path`, and the mainnet guard.
374
+ */
375
+ export declare function resolveKeystoreProtection(overrides?: ConnectionOverrides): KeystoreProtectionLabel;
376
+ /**
377
+ * Hard-refuses using an unencrypted dev keystore for a mainnet operation (ADR
378
+ * 080). A plaintext key must never sign or seal a `bitcoin` did:btcr2; the check
379
+ * reads only the keystore's protection header, so it never decrypts or prompts.
380
+ * A no-op for every other network and for encrypted/absent keystores.
381
+ */
382
+ export declare function assertKeystoreAllowedForNetwork(network: NetworkOption, overrides?: ConnectionOverrides): void;
367
383
  /**
368
384
  * Resolves the keystore file path: the `--keystore` flag, else the active
369
- * profile's `identity.keystore`, else the default XDG keystore path. The flag
370
- * always wins over the profile default.
385
+ * profile's `identity.keystore`, else the default `<home>/keystore.json` (ADR
386
+ * 079). The flag always wins over the profile default and never reads the config.
387
+ *
388
+ * A malformed config aborts loudly by default so a keystore-mutating command
389
+ * never silently reads or writes the wrong store. Pass `lenient: true` only for
390
+ * diagnostic/recovery commands (`config path`, `keystore status`) that must still
391
+ * report a path instead of crashing on the very config you ran them to fix; those
392
+ * fall back to the home default when the profile identity cannot be read.
371
393
  */
372
- export declare function resolveKeystorePath(overrides?: ConnectionOverrides): string;
394
+ export declare function resolveKeystorePath(overrides?: ConnectionOverrides, options?: {
395
+ lenient?: boolean;
396
+ }): string;
373
397
  /**
374
398
  * Resolves the signing-key reference for update/deactivate: the `--signing-key`
375
399
  * flag, else the active profile's `identity.default`, else `undefined` (letting
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/config.ts"],"names":[],"mappings":"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"}
@@ -1,33 +1,61 @@
1
1
  import type { KeyEntry, KeyIdentifier, KeyValueStore } from '@did-btcr2/key-manager';
2
+ import type { KeystoreProtectionLabel } from '../types.js';
2
3
  import type { ArgonParams } from './envelope.js';
3
4
  import { type LockOptions } from './lock.js';
4
5
  /** Current on-disk keystore file format version. */
5
6
  export declare const KEYSTORE_VERSION: 1;
7
+ /**
8
+ * How a keystore protects its secrets on disk:
9
+ * - `passphrase`: each secret is sealed in its own argon2id + XChaCha20-Poly1305
10
+ * envelope, all opened by one shared, verifier-checked passphrase.
11
+ * - `none`: a dev keystore; secrets are stored as plaintext bytes. Never prompts;
12
+ * refused for mainnet (ADR 080). For disposable testnet material only.
13
+ */
14
+ export type KeystoreProtection = 'passphrase' | 'none';
6
15
  /** Options for constructing a {@link FileKeyStore}. */
7
16
  export type FileKeyStoreOptions = {
8
17
  /** Keystore file path. Defaults to {@link defaultKeystorePath}. */
9
18
  path?: string;
10
- /** Supplies the passphrase lazily, called only when a secret must be sealed or opened. */
11
- getPassphrase: () => string;
19
+ /**
20
+ * Supplies the passphrase lazily, called only when a secret must be sealed or
21
+ * opened. `confirm` is passed as `true` only while establishing a fresh
22
+ * encrypted keystore's passphrase, so the provider prompts twice and requires
23
+ * a match; it is a no-op for non-interactive sources.
24
+ */
25
+ getPassphrase: (opts?: {
26
+ confirm?: boolean;
27
+ }) => string;
12
28
  /** argon2id cost parameters used when sealing new secrets. Defaults to {@link DEFAULT_ARGON_PARAMS}. */
13
29
  argonParams?: ArgonParams;
14
30
  /** Tuning for the cross-process write lock. Defaults documented on {@link LockOptions}. */
15
31
  lock?: LockOptions;
32
+ /**
33
+ * Protection mode to use when *establishing* a fresh keystore. Defaults to
34
+ * `passphrase` (encrypted). Ignored for an existing keystore, whose on-disk
35
+ * `protection` always wins.
36
+ */
37
+ protection?: KeystoreProtection;
16
38
  };
17
39
  /**
18
- * A Node-only, file-backed {@link KeyValueStore} that encrypts secret keys at
40
+ * A Node-only, file-backed {@link KeyValueStore} that protects secret keys at
19
41
  * rest. It satisfies the synchronous store contract by caching the parsed file
20
42
  * in memory at construction and flushing the whole file atomically on every
21
43
  * mutation.
22
44
  *
45
+ * Encrypted keystores seal each secret in its own argon2id + XChaCha20-Poly1305
46
+ * envelope under one shared passphrase, and store a `verifier` sentinel so a
47
+ * candidate passphrase is checked before it is used (ADR 080): the first
48
+ * passphrase is established with a confirm prompt, and every later use is
49
+ * verified, so a typo is a loud failure rather than a key sealed under an
50
+ * unknown or divergent passphrase. Dev keystores (`protection: 'none'`) store
51
+ * secrets as plaintext and never prompt; they are refused for mainnet by the
52
+ * command layer.
53
+ *
23
54
  * Every mutation runs under an exclusive cross-process lock and, inside that
24
- * lock, reloads the file from disk before applying its change and flushing.
25
- * Caching at construction and flushing the whole file is otherwise a lost-update
26
- * race: two `btcr2` processes that each load, then each write, would have the
27
- * second overwrite the first. The lock serializes the writers and the reload
28
- * merges any change the other made, so concurrent invocations compose instead of
29
- * clobbering. Reads stay lock-free: an atomic rename means a concurrent reader
30
- * always sees a complete file, old or new.
55
+ * lock, reloads the file from disk before applying its change and flushing, so
56
+ * concurrent `btcr2` invocations compose instead of clobbering. Reads stay
57
+ * lock-free: an atomic rename means a concurrent reader always sees a complete
58
+ * file, old or new.
31
59
  *
32
60
  * Secrets are materialized only through {@link FileKeyStore.get}. The
33
61
  * {@link FileKeyStore.list} and {@link FileKeyStore.entries} projections omit
@@ -60,5 +88,69 @@ export declare class FileKeyStore implements KeyValueStore<KeyIdentifier, KeyEnt
60
88
  * clears it. Throws if the identifier is not a known key.
61
89
  */
62
90
  setActive(id: KeyIdentifier | undefined): void;
91
+ /** The keystore's protection mode. */
92
+ get protection(): KeystoreProtection;
93
+ /**
94
+ * Re-seals every sealed secret and the verifier under a new passphrase (ADR
95
+ * 080), returning the number of secrets re-sealed. Verifies the current
96
+ * passphrase against the verifier first. Refused on a dev keystore, which has
97
+ * no passphrase.
98
+ */
99
+ changePassphrase(oldPassphrase: string, newPassphrase: string): number;
100
+ }
101
+ /** A no-decrypt, no-prompt summary of a keystore file for `keystore status`. */
102
+ export interface KeystoreSummary {
103
+ protection: KeystoreProtectionLabel;
104
+ established: boolean;
105
+ keyCount: number;
106
+ active: string | undefined;
107
+ }
108
+ /**
109
+ * Summarizes a keystore file by structure alone: protection mode, whether a
110
+ * passphrase is established, key count, and active key. Never decrypts, never
111
+ * prompts, and never throws (a missing or unreadable file reports `absent`), so
112
+ * it is safe for `keystore status`, `config path`, and the mainnet dev-keystore
113
+ * guard.
114
+ */
115
+ export declare function keystoreSummary(path: string): KeystoreSummary;
116
+ /** The protection label of a keystore file, without decrypting or prompting. */
117
+ export declare function keystoreProtection(path: string): KeystoreProtectionLabel;
118
+ /**
119
+ * A stable fingerprint of a keystore's passphrase verifier, or `undefined` when
120
+ * the file is absent, unparsable, or carries no verifier. Compared by equality
121
+ * to detect a rotated passphrase (`change-passphrase`, `init --force`) or a
122
+ * re-established keystore, so a cached session (ADR 081) stops matching a
123
+ * keystore whose passphrase has changed. Never decrypts, never throws.
124
+ */
125
+ export declare function keystoreVerifierId(path: string): string | undefined;
126
+ /**
127
+ * Checks a candidate passphrase against the keystore's verifier without
128
+ * constructing a store or opening any key. Returns `false` for an absent,
129
+ * unparsable, dev, or verifier-less keystore and for a wrong passphrase; `true`
130
+ * only when the passphrase opens the verifier sentinel. Never throws. Used by
131
+ * `keystore unlock` (ADR 081) to refuse caching a wrong passphrase.
132
+ */
133
+ export declare function verifyKeystorePassphrase(path: string, passphrase: string): boolean;
134
+ /** Options for {@link initKeystore}. */
135
+ export interface InitKeystoreOptions {
136
+ protection: KeystoreProtection;
137
+ getPassphrase: (opts?: {
138
+ confirm?: boolean;
139
+ }) => string;
140
+ argonParams?: ArgonParams;
63
141
  }
142
+ /**
143
+ * Establishes a fresh keystore file (ADR 080). An encrypted keystore prompts
144
+ * (with confirm) for the passphrase and writes the verifier; a dev keystore
145
+ * writes a plaintext-mode header with no passphrase. The caller is responsible
146
+ * for refusing to overwrite an existing keystore; this always writes the file.
147
+ */
148
+ export declare function initKeystore(path: string, options: InitKeystoreOptions): void;
149
+ /**
150
+ * Re-seals every secret in an encrypted keystore under a new passphrase (ADR
151
+ * 080), returning the count re-sealed. The old and new passphrases are supplied
152
+ * explicitly, so the store's own passphrase provider is never invoked (a wrong
153
+ * current passphrase is caught by the verifier). Refused on a dev keystore.
154
+ */
155
+ export declare function changeKeystorePassphrase(path: string, oldPassphrase: string, newPassphrase: string, argonParams?: ArgonParams): number;
64
156
  //# sourceMappingURL=file-key-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-key-store.d.ts","sourceRoot":"","sources":["../../../../src/keystore/file-key-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAIrF,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAG3D,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAwB3C,uDAAuD;AACvD,MAAM,MAAM,mBAAmB,GAAG;IAChC,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,wGAAwG;IACxG,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,2FAA2F;IAC3F,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,YAAa,YAAW,aAAa,CAAC,aAAa,EAAE,QAAQ,CAAC;;gBAS7D,OAAO,EAAE,mBAAmB;IAiHxC,GAAG,CAAC,EAAE,EAAE,aAAa,GAAG,QAAQ,GAAG,SAAS;IA0B5C,GAAG,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO;IAI/B,GAAG,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI;IAgB7C,MAAM,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO;IAWlC,KAAK,IAAI,IAAI;IAOb,iFAAiF;IACjF,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC;IAIvB;;;;;;OAMG;IACH,OAAO,IAAI,KAAK,CAAC,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAW3C,KAAK,IAAI,IAAI;IAQb,wEAAwE;IACxE,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B;;;OAGG;IACH,SAAS,CAAC,EAAE,EAAE,aAAa,GAAG,SAAS,GAAG,IAAI;CAU/C"}
1
+ {"version":3,"file":"file-key-store.d.ts","sourceRoot":"","sources":["../../../../src/keystore/file-key-store.ts"],"names":[],"mappings":"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"}
@@ -8,13 +8,38 @@ export type PassphraseOptions = {
8
8
  prompt?: string;
9
9
  /** When true, prompt twice and require the entries to match (for a new keystore). */
10
10
  confirm?: boolean;
11
+ /**
12
+ * When true, skip the environment variable and passphrase file and require a
13
+ * fresh terminal entry. Used for the *new* passphrase in `change-passphrase`,
14
+ * where the env var / file holds the *current* passphrase and must not silently
15
+ * satisfy the new one (which would make the change a no-op).
16
+ */
17
+ forcePrompt?: boolean;
18
+ /**
19
+ * An optional non-interactive source consulted *after* the env var and
20
+ * passphrase file and *before* the terminal prompt (and before the "no TTY"
21
+ * failure). The session unlock agent (ADR 081) wires this to a cached
22
+ * passphrase, so a returning command consumes the session instead of
23
+ * prompting, and a non-interactive follow-on command does not hard-fail. It
24
+ * returns `undefined` when no session is available. Skipped when `forcePrompt`
25
+ * is set, and never wired during passphrase establishment (`confirm`).
26
+ */
27
+ beforePrompt?: () => string | undefined;
11
28
  };
12
29
  /**
13
30
  * Acquires a passphrase without ever reading it from a command-line flag value
14
31
  * (which would leak into process listings and shell history). Resolution order:
15
32
  * the {@link ENV_KEYSTORE_PASSPHRASE} environment variable, a passphrase file,
16
33
  * then a non-echoing terminal prompt. Throws if none is available and standard
17
- * input is not a terminal.
34
+ * input is not a terminal. When `forcePrompt` is set, the env var and file are
35
+ * skipped and a terminal entry is required.
18
36
  */
19
37
  export declare function acquirePassphrase(options?: PassphraseOptions): string;
38
+ /**
39
+ * Removes the last whole UTF-8 character from an accumulating byte array in
40
+ * place: pops any trailing continuation bytes (0b10xxxxxx) then the leading
41
+ * byte. Exported for testing; a backspace mid-entry must not strand a fragment
42
+ * that later decodes to U+FFFD.
43
+ */
44
+ export declare function dropLastUtf8Char(bytes: number[]): void;
20
45
  //# sourceMappingURL=passphrase.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"passphrase.d.ts","sourceRoot":"","sources":["../../../../src/keystore/passphrase.ts"],"names":[],"mappings":"AAGA,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE,wDAAwD;AACxD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wFAAwF;IACxF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAyBzE"}
1
+ {"version":3,"file":"passphrase.d.ts","sourceRoot":"","sources":["../../../../src/keystore/passphrase.ts"],"names":[],"mappings":"AAGA,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE,wDAAwD;AACxD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wFAAwF;IACxF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAwCzE;AAuBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAGtD"}
@@ -1,13 +1,9 @@
1
1
  /**
2
- * Default keystore file path, following the XDG Base Directory Specification's
3
- * data directory. Secret key material is data a user accumulates, so it lives
4
- * under the data directory, kept separate from the configuration directory used
5
- * for portable settings.
6
- *
7
- * Resolution order:
8
- * 1. `$XDG_DATA_HOME/btcr2/keystore.json`
9
- * 2. `%LOCALAPPDATA%/btcr2/keystore.json` (Windows)
10
- * 3. `~/.local/share/btcr2/keystore.json` (fallback)
2
+ * The default keystore path now lives alongside the config file under a single
3
+ * CLI home root (`<home>/keystore.json`, ADR 079). The implementation lives in
4
+ * `../paths.ts` (the single source of truth for on-disk state locations); it is
5
+ * re-exported here so existing `./paths.js` importers in the keystore layer keep
6
+ * their import surface.
11
7
  */
12
- export declare function defaultKeystorePath(): string;
8
+ export { defaultKeystorePath } from '../paths.js';
13
9
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../../src/keystore/paths.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAK5C"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../../src/keystore/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The session unlock agent (ADR 081). `keystore unlock` caches the verified
3
+ * keystore passphrase in a single `<home>/session.json`, and subsequent commands
4
+ * read it in place of a prompt until it expires or `keystore lock` revokes it.
5
+ *
6
+ * This is an on-disk v1 design. The cached passphrase is base64url-*encoded*, not
7
+ * encrypted: its only protection at rest is the file's `0600` mode. That is the
8
+ * deliberate, documented cost of a portable, minimal-diff convenience; a future
9
+ * in-memory agent (v2) that never persists the secret is the real fix. Every read
10
+ * here is defensive and never throws, so a bad or hostile session degrades to a
11
+ * passphrase prompt rather than a crash.
12
+ */
13
+ /** Current session-file format version. */
14
+ export declare const SESSION_VERSION: 1;
15
+ /** Default session lifetime: one hour. */
16
+ export declare const DEFAULT_SESSION_TTL_MS: number;
17
+ /** Hard cap on a cached-passphrase lifetime: 24 hours. A longer TTL is refused. */
18
+ export declare const MAX_SESSION_TTL_MS: number;
19
+ /** Environment variable supplying a default TTL below the `--ttl` flag. */
20
+ export declare const ENV_KEYSTORE_TTL = "BTCR2_KEYSTORE_TTL";
21
+ /**
22
+ * The on-disk session file. `passphrase` is base64url(utf8(passphrase)): an
23
+ * encoding, not encryption. `keystore` binds the session to one keystore, and
24
+ * `verifierId` (a hash of that keystore's verifier) invalidates the session when
25
+ * the passphrase is rotated. `allowMainnet` records whether the operator unlocked
26
+ * with `--allow-mainnet`; a session without it is withheld from a `bitcoin`
27
+ * operation so mainnet keeps per-use authentication (ADR 081). No derived key,
28
+ * keystore ciphertext, or signing-key bytes ever appear here.
29
+ */
30
+ export interface SessionFile {
31
+ v: typeof SESSION_VERSION;
32
+ keystore: string;
33
+ verifierId: string;
34
+ passphrase: string;
35
+ allowMainnet: boolean;
36
+ createdAt: number;
37
+ expiresAt: number;
38
+ ttlSeconds: number;
39
+ }
40
+ /** Inputs for {@link writeSession}. */
41
+ export interface WriteSessionInput {
42
+ /** The keystore this session unlocks (stored resolved/normalized). */
43
+ keystorePath: string;
44
+ /** Fingerprint of the keystore verifier, from `keystoreVerifierId`. */
45
+ verifierId: string;
46
+ /** The verified passphrase to cache. */
47
+ passphrase: string;
48
+ /** Lifetime in milliseconds. */
49
+ ttlMs: number;
50
+ /**
51
+ * Whether this session may be consumed for a mainnet (`bitcoin`) operation,
52
+ * from the `unlock --allow-mainnet` flag. Defaults to `false` (deny), so
53
+ * mainnet operations fall through to a per-use passphrase prompt (ADR 081).
54
+ */
55
+ allowMainnet?: boolean;
56
+ }
57
+ /**
58
+ * Writes the session file atomically at `0600` (temp sibling + rename), returning
59
+ * the written record so the caller can report expiry without re-reading. The
60
+ * caller is responsible for verifying the passphrase first; this only persists it.
61
+ */
62
+ export declare function writeSession(sessionPath: string, input: WriteSessionInput): SessionFile;
63
+ /**
64
+ * Deletes the session file and any crash-orphaned `writeFileAtomic` temp sibling
65
+ * (each of which would hold a plaintext passphrase). Idempotent; needs no
66
+ * passphrase. Returns whether a session file was present. Unlink is best-effort:
67
+ * it removes the name, it does not securely erase the bytes (see ADR 081).
68
+ */
69
+ export declare function clearSession(sessionPath: string): boolean;
70
+ /**
71
+ * Returns the cached passphrase for `keystorePath` when a live, matching session
72
+ * exists, else `undefined`. Never throws. A session that is expired, stale (the
73
+ * keystore passphrase rotated), future-dated, or malformed is pruned on read; a
74
+ * live session bound to a *different* keystore is left in place (it prompts for
75
+ * the current keystore instead).
76
+ *
77
+ * `isMainnetOperation` gates the one case the network is known at consumption: a
78
+ * live session that was not unlocked with `--allow-mainnet` is withheld from a
79
+ * `bitcoin` operation (returning `undefined` so the caller falls through to a
80
+ * per-use prompt) but *not* pruned, since it remains valid for the non-mainnet
81
+ * operations the operator unlocked for (ADR 081).
82
+ */
83
+ export declare function readLiveSessionPassphrase(sessionPath: string, keystorePath: string, currentVerifierId: string | undefined, isMainnetOperation?: boolean): string | undefined;
84
+ /** Public, redacted view of the session state for `keystore status`. Never emits the passphrase. */
85
+ export interface SessionStatus {
86
+ active: boolean;
87
+ expiresAt?: number;
88
+ secondsRemaining?: number;
89
+ /** Whether the session may sign a mainnet operation prompt-free (unlocked with `--allow-mainnet`). */
90
+ allowMainnet?: boolean;
91
+ }
92
+ /**
93
+ * Reports whether a live session exists for `keystorePath` and its remaining
94
+ * lifetime, without decrypting, prompting, throwing, or emitting the passphrase.
95
+ * An expired, foreign, stale, or malformed session reports inactive. Read-only:
96
+ * unlike {@link readLiveSessionPassphrase}, it does not prune.
97
+ */
98
+ export declare function readSessionStatus(sessionPath: string, keystorePath: string, currentVerifierId: string | undefined): SessionStatus;
99
+ /**
100
+ * Parses a TTL string into milliseconds: a bare integer is seconds; an `s`, `m`,
101
+ * or `h` suffix scales it. Returns `undefined` for any malformed input. The
102
+ * caller applies the default, the 24h cap, and the `<= 0` rejection.
103
+ */
104
+ export declare function parseTtlToMs(raw: string): number | undefined;
105
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../../src/keystore/session.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;GAWG;AAEH,2CAA2C;AAC3C,eAAO,MAAM,eAAe,EAAG,CAAU,CAAC;AAE1C,0CAA0C;AAC1C,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AACrD,mFAAmF;AACnF,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AACtD,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAc,OAAO,eAAe,CAAC;IACtC,QAAQ,EAAO,MAAM,CAAC;IACtB,UAAU,EAAK,MAAM,CAAC;IACtB,UAAU,EAAK,MAAM,CAAC;IACtB,YAAY,EAAG,OAAO,CAAC;IACvB,SAAS,EAAM,MAAM,CAAC;IACtB,SAAS,EAAM,MAAM,CAAC;IACtB,UAAU,EAAK,MAAM,CAAC;CACvB;AAED,uCAAuC;AACvC,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,YAAY,EAAI,MAAM,CAAC;IACvB,uEAAuE;IACvE,UAAU,EAAM,MAAM,CAAC;IACvB,wCAAwC;IACxC,UAAU,EAAM,MAAM,CAAC;IACvB,gCAAgC;IAChC,KAAK,EAAW,MAAM,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAG,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,WAAW,CAevF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAWzD;AAqBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAU,MAAM,EAC3B,YAAY,EAAS,MAAM,EAC3B,iBAAiB,EAAI,MAAM,GAAG,SAAS,EACvC,kBAAkB,UAAQ,GACzB,MAAM,GAAG,SAAS,CAqBpB;AAED,oGAAoG;AACpG,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAc,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAU,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAG,MAAM,CAAC;IAC3B,sGAAsG;IACtG,YAAY,CAAC,EAAO,OAAO,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAS,MAAM,EAC1B,YAAY,EAAQ,MAAM,EAC1B,iBAAiB,EAAG,MAAM,GAAG,SAAS,GACrC,aAAa,CAUf;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO5D"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * State-location overrides that influence where the CLI keeps its home
3
+ * directory and its two state files. A subset of the broader
4
+ * `ConnectionOverrides`, restated here so this module (the single source of
5
+ * truth for on-disk locations) has no runtime dependency on `config.ts`.
6
+ */
7
+ export interface PathOverrides {
8
+ /** Explicit home root from the `--home` flag. Wins over `$BTCR2_HOME`. */
9
+ home?: string;
10
+ /** Explicit config-file path from the `--config` flag. Overrides the home default. */
11
+ config?: string;
12
+ /** Explicit keystore path from the `--keystore` flag. Overrides the home default. */
13
+ keystore?: string;
14
+ }
15
+ /** Environment variable naming the CLI home directory (all state colocated). */
16
+ export declare const ENV_HOME = "BTCR2_HOME";
17
+ /** The config and keystore file names, kept side by side under the home root. */
18
+ export declare const CONFIG_FILENAME = "config.json";
19
+ export declare const KEYSTORE_FILENAME = "keystore.json";
20
+ /** The session file name, holding the unlock agent's cached passphrase (ADR 081). */
21
+ export declare const SESSION_FILENAME = "session.json";
22
+ /**
23
+ * Resolves the CLI home directory: the single root that holds `config.json` and
24
+ * `keystore.json` side by side (ADR 079). Resolution order, highest wins:
25
+ *
26
+ * 1. `--home <dir>` (the {@link PathOverrides.home} flag)
27
+ * 2. `$BTCR2_HOME`
28
+ * 3. the platform default (see {@link platformDefaultHome})
29
+ *
30
+ * A blank value at any layer defers to the next, mirroring the `blankToUndef`
31
+ * treatment every other precedence layer uses, so an exported-but-empty
32
+ * `BTCR2_HOME` does not resolve the home to a bare relative path.
33
+ */
34
+ export declare function resolveHome(overrides?: PathOverrides): string;
35
+ /**
36
+ * The default home when no `--home` / `$BTCR2_HOME` override is present, chosen
37
+ * per OS so the location is idiomatic while staying a single colocated dir:
38
+ *
39
+ * - Windows: `%LOCALAPPDATA%\btcr2` (fallback `%APPDATA%\btcr2`, then the user
40
+ * profile), the native place for per-user application state.
41
+ * - Linux / macOS: `~/.btcr2`, the short, teachable dot-directory in the same
42
+ * family as `~/.ssh`, `~/.aws`, and `~/.gnupg`.
43
+ */
44
+ export declare function platformDefaultHome(): string;
45
+ /**
46
+ * Default config-file path: `<home>/config.json`. The `--config` flag, when
47
+ * present, overrides it wholesale (it names a specific file, not a home).
48
+ */
49
+ export declare function defaultConfigPath(overrides?: PathOverrides): string;
50
+ /**
51
+ * Default keystore path: `<home>/keystore.json`. The `--keystore` flag and a
52
+ * profile's `identity.keystore` (resolved in `config.ts`) override it; this
53
+ * function is the final fallback in that chain.
54
+ */
55
+ export declare function defaultKeystorePath(overrides?: PathOverrides): string;
56
+ /**
57
+ * Session file path: `<home>/session.json`, where the unlock agent caches the
58
+ * keystore passphrase (ADR 081). Deliberately derived from the home root alone,
59
+ * never from `--config` / `--keystore` or the config file, so `keystore lock`
60
+ * can revoke a session even under a malformed config, and so the read and write
61
+ * paths always agree on one location per home.
62
+ */
63
+ export declare function defaultSessionPath(overrides?: PathOverrides): string;
64
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/paths.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,IAAI,CAAC,EAAO,MAAM,CAAC;IACnB,sFAAsF;IACtF,MAAM,CAAC,EAAK,MAAM,CAAC;IACnB,qFAAqF;IACrF,QAAQ,CAAC,EAAG,MAAM,CAAC;CACpB;AAED,gFAAgF;AAChF,eAAO,MAAM,QAAQ,eAAe,CAAC;AAErC,iFAAiF;AACjF,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAC7C,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AACjD,qFAAqF;AACrF,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,MAAM,CAI7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAQ5C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,MAAM,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,MAAM,CAErE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,MAAM,CAEpE"}
@@ -4,8 +4,15 @@ import type { Btcr2DidDocument, ResolutionOptions } from '@did-btcr2/method';
4
4
  import type { DidResolutionResult } from '@web5/dids';
5
5
  import type { DoctorReport, EffectiveConfig } from './config.js';
6
6
  import type { ConfigIssue } from './config-schema.js';
7
+ import type { SessionStatus } from './keystore/session.js';
7
8
  export type NetworkOption = 'bitcoin' | 'testnet3' | 'testnet4' | 'signet' | 'mutinynet' | 'regtest';
8
9
  export type OutputFormat = 'json' | 'text';
10
+ /**
11
+ * How a keystore protects its secrets, as reported by `keystore status` and
12
+ * `btcr2 init`: `encrypted` (passphrase-sealed), `dev` (plaintext, testnet-only),
13
+ * or `absent` (no keystore file yet).
14
+ */
15
+ export type KeystoreProtectionLabel = 'encrypted' | 'dev' | 'absent';
9
16
  export declare const SUPPORTED_NETWORKS: NetworkOption[];
10
17
  /**
11
18
  * Normalizes a blank value (empty or whitespace-only) to `undefined`, so a
@@ -88,6 +95,15 @@ export type CommandResult = {
88
95
  keyId: string;
89
96
  active: true;
90
97
  };
98
+ } | {
99
+ action: 'init';
100
+ data: {
101
+ home: string;
102
+ config: string;
103
+ keystore: string;
104
+ created: string[];
105
+ protection: KeystoreProtectionLabel;
106
+ };
91
107
  } | {
92
108
  action: 'config-init';
93
109
  data: {
@@ -121,12 +137,48 @@ export type CommandResult = {
121
137
  } | {
122
138
  action: 'config-path';
123
139
  data: {
140
+ home: string;
124
141
  config: string;
125
142
  keystore: string;
126
143
  };
127
144
  } | {
128
145
  action: 'config-doctor';
129
146
  data: DoctorReport;
147
+ } | {
148
+ action: 'keystore-init';
149
+ data: {
150
+ path: string;
151
+ protection: 'encrypted' | 'dev';
152
+ };
153
+ } | {
154
+ action: 'keystore-status';
155
+ data: {
156
+ path: string;
157
+ protection: KeystoreProtectionLabel;
158
+ established: boolean;
159
+ keyCount: number;
160
+ active: string | undefined;
161
+ session: SessionStatus;
162
+ };
163
+ } | {
164
+ action: 'keystore-change-passphrase';
165
+ data: {
166
+ path: string;
167
+ rekeyed: number;
168
+ };
169
+ } | {
170
+ action: 'keystore-unlock';
171
+ data: {
172
+ keystore: string;
173
+ expiresAt: number;
174
+ ttlSeconds: number;
175
+ };
176
+ } | {
177
+ action: 'keystore-lock';
178
+ data: {
179
+ path: string;
180
+ cleared: boolean;
181
+ };
130
182
  } | {
131
183
  action: 'profile-add';
132
184
  data: {
@@ -150,6 +202,7 @@ export interface GlobalOptions {
150
202
  output: OutputFormat;
151
203
  verbose: boolean;
152
204
  quiet: boolean;
205
+ home?: string;
153
206
  config?: string;
154
207
  profile?: string;
155
208
  btcRest?: string;