@did-btcr2/cli 0.14.0 → 0.16.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/README.md +106 -17
- package/dist/.tsbuildinfo +1 -1
- package/dist/cjs/index.js +1160 -131
- package/dist/esm/src/cli.js +29 -5
- package/dist/esm/src/cli.js.map +1 -1
- package/dist/esm/src/commands/config.js +130 -18
- package/dist/esm/src/commands/config.js.map +1 -1
- package/dist/esm/src/commands/create.js +13 -1
- package/dist/esm/src/commands/create.js.map +1 -1
- package/dist/esm/src/commands/deactivate.js +16 -2
- package/dist/esm/src/commands/deactivate.js.map +1 -1
- package/dist/esm/src/commands/index.js +2 -0
- package/dist/esm/src/commands/index.js.map +1 -1
- package/dist/esm/src/commands/init.js +63 -0
- package/dist/esm/src/commands/init.js.map +1 -0
- package/dist/esm/src/commands/keystore.js +81 -0
- package/dist/esm/src/commands/keystore.js.map +1 -0
- package/dist/esm/src/commands/profile.js +6 -4
- package/dist/esm/src/commands/profile.js.map +1 -1
- package/dist/esm/src/commands/update.js +16 -2
- package/dist/esm/src/commands/update.js.map +1 -1
- package/dist/esm/src/config-schema.js +149 -0
- package/dist/esm/src/config-schema.js.map +1 -0
- package/dist/esm/src/config.js +579 -55
- package/dist/esm/src/config.js.map +1 -1
- package/dist/esm/src/keystore/file-key-store.js +340 -32
- package/dist/esm/src/keystore/file-key-store.js.map +1 -1
- package/dist/esm/src/keystore/passphrase.js +40 -10
- package/dist/esm/src/keystore/passphrase.js.map +1 -1
- package/dist/esm/src/keystore/paths.js +6 -17
- package/dist/esm/src/keystore/paths.js.map +1 -1
- package/dist/esm/src/output.js +49 -0
- package/dist/esm/src/output.js.map +1 -1
- package/dist/esm/src/paths.js +59 -0
- package/dist/esm/src/paths.js.map +1 -0
- package/dist/esm/src/types.js +11 -0
- package/dist/esm/src/types.js.map +1 -1
- package/dist/types/src/cli.d.ts.map +1 -1
- package/dist/types/src/commands/config.d.ts.map +1 -1
- package/dist/types/src/commands/create.d.ts.map +1 -1
- package/dist/types/src/commands/deactivate.d.ts.map +1 -1
- package/dist/types/src/commands/index.d.ts +2 -0
- package/dist/types/src/commands/index.d.ts.map +1 -1
- package/dist/types/src/commands/init.d.ts +13 -0
- package/dist/types/src/commands/init.d.ts.map +1 -0
- package/dist/types/src/commands/keystore.d.ts +10 -0
- package/dist/types/src/commands/keystore.d.ts.map +1 -0
- package/dist/types/src/commands/profile.d.ts.map +1 -1
- package/dist/types/src/commands/update.d.ts.map +1 -1
- package/dist/types/src/config-schema.d.ts +24 -0
- package/dist/types/src/config-schema.d.ts.map +1 -0
- package/dist/types/src/config.d.ts +252 -14
- package/dist/types/src/config.d.ts.map +1 -1
- package/dist/types/src/keystore/file-key-store.d.ts +86 -10
- package/dist/types/src/keystore/file-key-store.d.ts.map +1 -1
- package/dist/types/src/keystore/passphrase.d.ts +16 -1
- package/dist/types/src/keystore/passphrase.d.ts.map +1 -1
- package/dist/types/src/keystore/paths.d.ts +6 -10
- package/dist/types/src/keystore/paths.d.ts.map +1 -1
- package/dist/types/src/output.d.ts +22 -0
- package/dist/types/src/output.d.ts.map +1 -1
- package/dist/types/src/paths.d.ts +54 -0
- package/dist/types/src/paths.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +70 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/cli.ts +32 -4
- package/src/commands/config.ts +143 -18
- package/src/commands/create.ts +16 -1
- package/src/commands/deactivate.ts +24 -2
- package/src/commands/index.ts +2 -0
- package/src/commands/init.ts +74 -0
- package/src/commands/keystore.ts +98 -0
- package/src/commands/profile.ts +6 -4
- package/src/commands/update.ts +24 -2
- package/src/config-schema.ts +178 -0
- package/src/config.ts +752 -58
- package/src/keystore/file-key-store.ts +455 -43
- package/src/keystore/passphrase.ts +48 -8
- package/src/keystore/paths.ts +6 -18
- package/src/output.ts +53 -0
- package/src/paths.ts +79 -0
- package/src/types.ts +34 -0
package/README.md
CHANGED
|
@@ -36,11 +36,13 @@ npx @did-btcr2/cli resolve -i did:btcr2:k1qq...
|
|
|
36
36
|
|
|
37
37
|
| Command | Alias | Description |
|
|
38
38
|
|---|---|---|
|
|
39
|
+
| `init` | - | Set up the btcr2 home: create the directory, a default config, and establish the keystore |
|
|
39
40
|
| `create` | - | Create an identifier and initial DID document |
|
|
40
41
|
| `resolve` | `read` | Resolve a DID document |
|
|
41
42
|
| `update` | - | Update a DID document (signs via the keystore) |
|
|
42
43
|
| `deactivate` | `delete` | Deactivate a DID permanently (signs via the keystore) |
|
|
43
|
-
| `key` | - | Manage keypairs in the
|
|
44
|
+
| `key` | - | Manage keypairs in the keystore |
|
|
45
|
+
| `keystore` | - | Establish, inspect, and re-key the keystore |
|
|
44
46
|
| `config` | - | Read and write CLI configuration |
|
|
45
47
|
| `profile` | - | Manage configuration profiles |
|
|
46
48
|
| `completion` | - | Print a shell completion script |
|
|
@@ -87,16 +89,38 @@ Required flags: `-s/--source-document`, `--source-version-id`, `-p/--patches`, `
|
|
|
87
89
|
| `-m, --verification-method-id <id>` | DID document verification method ID |
|
|
88
90
|
| `-b, --beacon-id <json>` | Beacon ID as a JSON string |
|
|
89
91
|
| `--publish-to-cas <mode>` | Publish update artifacts to a writable CAS before broadcast: `auto`, `always`, or `never` (default: `never`). See [Publishing updates to CAS](#publishing-updates-to-cas) |
|
|
92
|
+
| `--fee-rate <satsPerVByte>` | Fee rate in sats/vByte for the beacon transaction (default: `5`). Raise it under congestion so the transaction confirms (also `BTCR2_FEE_RATE`, profile `btc.feeRate`) |
|
|
93
|
+
| `--change-address <address>` | Send transaction change to this address instead of the beacon address, so a DID's announcements are not linked on-chain (profile `btc.changeAddress`) |
|
|
90
94
|
|
|
91
95
|
### deactivate (alias: delete)
|
|
92
96
|
|
|
93
97
|
Permanently deactivates a DID. This is irreversible. Deactivation applies the `{ "op": "add", "path": "/deactivated", "value": true }` patch and routes through the same signed-update path as `update`, so it also signs via the keystore.
|
|
94
98
|
|
|
95
|
-
Required flags: `-s/--source-document`, `--source-version-id`, `-m/--verification-method-id`, `-b/--beacon-id`. Optional: `--publish-to-cas <mode>` (same as `update`).
|
|
99
|
+
Required flags: `-s/--source-document`, `--source-version-id`, `-m/--verification-method-id`, `-b/--beacon-id`. Optional: `--publish-to-cas <mode>`, `--fee-rate <satsPerVByte>`, `--change-address <address>` (same as `update`).
|
|
100
|
+
|
|
101
|
+
### init
|
|
102
|
+
|
|
103
|
+
`btcr2 init` is the one-command setup: it creates the btcr2 home directory, writes a default config if none exists, and establishes the keystore if none exists. It is idempotent (existing files are left untouched unless `--force`).
|
|
104
|
+
|
|
105
|
+
| Flag | Description |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `--dev` | Establish an **unencrypted** dev keystore (plaintext keys, no passphrase). Testnet/regtest only; mainnet operations are refused |
|
|
108
|
+
| `--force` | Re-create the config and keystore even if they already exist |
|
|
109
|
+
|
|
110
|
+
By default `init` establishes an **encrypted** keystore and prompts (with confirmation) for a passphrase up front, so the first `key generate` never seals the keystore under an unconfirmed, mistyped passphrase. Supply the passphrase non-interactively with `BTCR2_KEYSTORE_PASSPHRASE` or `--passphrase-file` for scripted setup.
|
|
111
|
+
|
|
112
|
+
The workshop happy path:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
btcr2 init --dev --network mutinynet # (or: btcr2 init for an encrypted keystore)
|
|
116
|
+
btcr2 key generate --set-active
|
|
117
|
+
btcr2 create --network mutinynet
|
|
118
|
+
# ...fund the beacon, resolve, update, deactivate...
|
|
119
|
+
```
|
|
96
120
|
|
|
97
121
|
### key
|
|
98
122
|
|
|
99
|
-
Manage keypairs in the
|
|
123
|
+
Manage keypairs in the keystore. All subcommands operate offline (no Bitcoin connection).
|
|
100
124
|
|
|
101
125
|
| Subcommand | Alias | Description |
|
|
102
126
|
|---|---|---|
|
|
@@ -110,6 +134,18 @@ Manage keypairs in the encrypted keystore. All subcommands operate offline (no B
|
|
|
110
134
|
|
|
111
135
|
A key reference is a full URN, a unique `name` tag, or a unique fingerprint prefix.
|
|
112
136
|
|
|
137
|
+
### keystore
|
|
138
|
+
|
|
139
|
+
Establish, inspect, and re-key the keystore. These operate on the keystore file directly (no Bitcoin connection).
|
|
140
|
+
|
|
141
|
+
| Subcommand | Alias | Description |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `keystore init` | - | Establish the keystore (encrypted by default; prompts and confirms the passphrase). `--dev` creates an unencrypted dev keystore; `--force` re-establishes an existing one (discards its keys) |
|
|
144
|
+
| `keystore status` | - | Show the resolved path, protection mode (`encrypted`/`dev`/`absent`), whether a passphrase is established, and the key count. Never decrypts or prompts |
|
|
145
|
+
| `keystore change-passphrase` | `passwd` | Re-seal every key under a new passphrase (encrypted keystores only). Prompts for the current passphrase, then a new one (with confirmation) |
|
|
146
|
+
|
|
147
|
+
**Encrypted vs dev keystores.** An encrypted keystore seals each secret with argon2id + XChaCha20-Poly1305 under one passphrase, and records a verifier so a mistyped passphrase fails loudly (with `Incorrect passphrase`) instead of sealing a key under an unknown or divergent passphrase. A **dev keystore** (`--dev`) stores secrets in plaintext and never prompts: it is for disposable testnet/regtest keys only, and the CLI **hard-refuses** to sign or generate a mainnet (`bitcoin`) key with one.
|
|
148
|
+
|
|
113
149
|
### config
|
|
114
150
|
|
|
115
151
|
Read and write CLI configuration.
|
|
@@ -117,10 +153,14 @@ Read and write CLI configuration.
|
|
|
117
153
|
| Subcommand | Alias | Description |
|
|
118
154
|
|---|---|---|
|
|
119
155
|
| `config init` | - | Create a default config file with one profile per network. `--force` overwrites |
|
|
120
|
-
| `config get [path]` | - | Print a value at a dotted path, or the whole config |
|
|
121
|
-
| `config set <path> <value>` | - | Set a value at a dotted path (value parsed as JSON when valid, else a string) |
|
|
156
|
+
| `config get [path]` | - | Print a value at a dotted path, or the whole config. Secret values are redacted; `--show-secrets` reveals them |
|
|
157
|
+
| `config set <path> <value>` | - | Set a value at a dotted path (value parsed as JSON when valid, else a string). An invalid enum for a known key is rejected; an unknown path warns but writes |
|
|
122
158
|
| `config unset <path>` | - | Delete a value at a dotted path |
|
|
123
|
-
| `config list` | `ls` | Print the entire config file |
|
|
159
|
+
| `config list` | `ls` | Print the entire config file. Secret values are redacted; `--show-secrets` reveals them |
|
|
160
|
+
| `config validate` | - | Report unknown keys, invalid enum values, and an unsupported schema version |
|
|
161
|
+
| `config effective` | - | Print the resolved connection config with per-value provenance (`flag`/`env`/`file`/`default`). `-n, --network <n>` selects the network; `--show-secrets` reveals the RPC password |
|
|
162
|
+
| `config path` | - | Print the resolved home directory, config-file, and keystore paths |
|
|
163
|
+
| `config doctor` | - | Probe reachability of the resolved endpoints (read-only; touches the network). `-n, --network <n>` selects the network |
|
|
124
164
|
|
|
125
165
|
### profile
|
|
126
166
|
|
|
@@ -214,18 +254,24 @@ Override precedence, highest wins: CLI flags, then environment variables, then c
|
|
|
214
254
|
| Flag | Description |
|
|
215
255
|
|---|---|
|
|
216
256
|
| `-v, --version` | Output the current version |
|
|
217
|
-
| `-o, --output <format>` | Output format: `json` or `text` (default: `text`) |
|
|
257
|
+
| `-o, --output <format>` | Output format: `json` or `text` (default: config `defaults.output`, else `text`) |
|
|
218
258
|
| `--verbose` | Verbose output |
|
|
219
259
|
| `--quiet` | Suppress non-essential output |
|
|
220
|
-
|
|
|
260
|
+
| `--home <dir>` | btcr2 home directory holding `config.json` + `keystore.json` (default: `~/.btcr2`, `%LOCALAPPDATA%\btcr2` on Windows; overrides `$BTCR2_HOME`) |
|
|
261
|
+
| `-c, --config <path>` | Path to config file (default: `<home>/config.json`) |
|
|
221
262
|
| `--profile <name>` | Config profile name (default: auto-detected from network) |
|
|
222
263
|
| `--btc-rest <url>` | Override Bitcoin REST endpoint (Esplora API) |
|
|
223
264
|
| `--btc-rpc-url <url>` | Override Bitcoin Core RPC endpoint |
|
|
224
265
|
| `--btc-rpc-user <user>` | Bitcoin Core RPC username |
|
|
225
|
-
| `--btc-rpc-pass <pass>` | Bitcoin Core RPC password |
|
|
266
|
+
| `--btc-rpc-pass <pass>` | Bitcoin Core RPC password (accepts an `env:<VAR>` or `file:<path>` secret reference) |
|
|
267
|
+
| `--btc-rpc-wallet <name>` | Bitcoin Core wallet name for wallet-scoped RPCs (`/wallet/<name>`) |
|
|
268
|
+
| `--btc-rpc-header <header>` | Extra Bitcoin Core RPC header `"Key: Value"` (repeatable) |
|
|
269
|
+
| `--btc-rest-header <header>` | Extra Bitcoin REST header `"Key: Value"` (repeatable), e.g. an API key |
|
|
270
|
+
| `--btc-timeout <ms>` | Bitcoin REST/RPC request timeout in milliseconds (default: unbounded) |
|
|
226
271
|
| `--cas-gateway <url>` | IPFS HTTP gateway for CAS reads (read-only) |
|
|
227
272
|
| `--cas-rpc-url <url>` | IPFS HTTP RPC endpoint for a writable CAS (reads + writes; enables `--publish-to-cas`) |
|
|
228
|
-
| `--
|
|
273
|
+
| `--cas-timeout <ms>` | CAS request timeout in milliseconds (default: `30000`; `0` disables) |
|
|
274
|
+
| `--keystore <path>` | Path to the keystore file (default: `<home>/keystore.json`) |
|
|
229
275
|
| `--passphrase-file <path>` | Read the keystore passphrase from a file (unattended use) |
|
|
230
276
|
| `--signing-key <ref>` | Key for create/update/deactivate signing: a URN, fingerprint prefix, or name |
|
|
231
277
|
|
|
@@ -237,35 +283,78 @@ Override precedence, highest wins: CLI flags, then environment variables, then c
|
|
|
237
283
|
| `BTCR2_BTC_RPC_URL` | `--btc-rpc-url` |
|
|
238
284
|
| `BTCR2_BTC_RPC_USER` | `--btc-rpc-user` |
|
|
239
285
|
| `BTCR2_BTC_RPC_PASS` | `--btc-rpc-pass` |
|
|
286
|
+
| `BTCR2_BTC_RPC_PASS_FILE` | file whose contents are the RPC password |
|
|
240
287
|
| `BTCR2_CAS_GATEWAY` | `--cas-gateway` |
|
|
241
288
|
| `BTCR2_CAS_RPC_URL` | `--cas-rpc-url` |
|
|
289
|
+
| `BTCR2_BTC_TIMEOUT` | `--btc-timeout` |
|
|
290
|
+
| `BTCR2_CAS_TIMEOUT` | `--cas-timeout` |
|
|
291
|
+
| `BTCR2_FEE_RATE` | `--fee-rate` |
|
|
292
|
+
| `BTCR2_OUTPUT` | `-o, --output` |
|
|
293
|
+
| `BTCR2_HOME` | `--home` |
|
|
294
|
+
| `BTCR2_KEYSTORE_PASSPHRASE` | keystore passphrase (unattended use) |
|
|
295
|
+
|
|
296
|
+
### Home directory
|
|
297
|
+
|
|
298
|
+
The CLI keeps its config and keystore side by side in one home directory, resolved as `--home <dir>`, then `$BTCR2_HOME`, then the platform default: `~/.btcr2` on Linux/macOS and `%LOCALAPPDATA%\btcr2` on Windows. Both files live directly under it (`<home>/config.json`, `<home>/keystore.json`); `btcr2 config path` prints the resolved locations. `--config` and `--keystore` still override each file individually, so the historical XDG split can be reproduced explicitly.
|
|
242
299
|
|
|
243
300
|
### Config file
|
|
244
301
|
|
|
245
|
-
Default location:
|
|
302
|
+
Default location: `<home>/config.json`. A malformed config file fails loudly (the CLI never silently falls back to public endpoints, and never overwrites an unparseable file).
|
|
246
303
|
|
|
247
|
-
Profiles are matched by network name when `--profile` is not specified. For example, resolving a regtest DID automatically selects the `"regtest"` profile.
|
|
304
|
+
Profiles are matched by network name when `--profile` is not specified. For example, resolving a regtest DID automatically selects the `"regtest"` profile. A profile that is not named after a network can declare its network with a `network` field.
|
|
248
305
|
|
|
249
306
|
```json
|
|
250
307
|
{
|
|
308
|
+
"schemaVersion": 1,
|
|
309
|
+
"defaults": {
|
|
310
|
+
"profile": "production",
|
|
311
|
+
"network": "bitcoin",
|
|
312
|
+
"output": "text"
|
|
313
|
+
},
|
|
251
314
|
"profiles": {
|
|
252
315
|
"regtest": {
|
|
253
316
|
"btc": {
|
|
254
317
|
"rest": "http://localhost:3000",
|
|
255
318
|
"rpcUrl": "http://localhost:18443",
|
|
256
319
|
"rpcUser": "polaruser",
|
|
257
|
-
"rpcPass": "polarpass"
|
|
320
|
+
"rpcPass": "polarpass",
|
|
321
|
+
"wallet": "primary",
|
|
322
|
+
"feeRate": 5,
|
|
323
|
+
"timeoutMs": 30000
|
|
258
324
|
}
|
|
259
325
|
},
|
|
260
|
-
"
|
|
261
|
-
"
|
|
262
|
-
"
|
|
326
|
+
"production": {
|
|
327
|
+
"network": "bitcoin",
|
|
328
|
+
"btc": {
|
|
329
|
+
"rest": "https://my-mempool/api",
|
|
330
|
+
"headers": { "Authorization": "Bearer <api-key>" },
|
|
331
|
+
"feeRate": 20
|
|
332
|
+
},
|
|
333
|
+
"cas": { "gateway": "https://ipfs.io", "rpcUrl": "http://127.0.0.1:5001", "timeoutMs": 30000 },
|
|
334
|
+
"identity": { "keystore": "/secure/prod-keystore.json", "default": "did:btcr2:...#key-0" }
|
|
263
335
|
}
|
|
264
336
|
}
|
|
265
337
|
}
|
|
266
338
|
```
|
|
267
339
|
|
|
268
|
-
|
|
340
|
+
Field notes:
|
|
341
|
+
|
|
342
|
+
- **`defaults`**: `profile` selects the active profile; `network` fixes the network `create` encodes when `-n` is absent; `output` sets the default output format. `schemaVersion` is stamped on every write; a file written by a newer CLI is refused.
|
|
343
|
+
- **`btc`**: `rest`/`rpcUrl`/`rpcUser`/`rpcPass` are endpoints and credentials; `wallet` targets a Bitcoin Core wallet (`/wallet/<name>`); `headers`/`rpcHeaders` add REST/RPC headers; `feeRate` (sats/vByte), `changeAddress`, and `timeoutMs` set broadcast and request behavior. The RPC url, user, and pass are resolved as one atomic unit, so a URL from a higher-precedence layer never inherits credentials from a lower one.
|
|
344
|
+
- **`cas`**: `gateway` is a read-only IPFS HTTP gateway; `cas.rpcUrl` is a writable IPFS HTTP RPC endpoint (enables `--publish-to-cas`; `rpcUrl` wins over `gateway`); `timeoutMs` bounds CAS operations (`0` disables).
|
|
345
|
+
- **`identity`**: `keystore` points the profile at its own keystore file, and `default` is the profile's default signing key. Both fall **below** the corresponding `--keystore` / `--signing-key` flags.
|
|
346
|
+
|
|
347
|
+
Use `config validate` to check a file, and `config effective` to see the resolved values with their provenance.
|
|
348
|
+
|
|
349
|
+
### RPC password and secrets
|
|
350
|
+
|
|
351
|
+
`config get` and `config list` redact secret-looking values (RPC password and any `pass`/`secret`/`token` key) by default; pass `--show-secrets` to reveal them.
|
|
352
|
+
|
|
353
|
+
An `rpcPass` written directly into `config.json` is stored in cleartext (the file is mode 0600 but not encrypted). For anything sensitive, keep the secret out of the file with a reference or an RPC-URL-embedded credential:
|
|
354
|
+
|
|
355
|
+
- `"rpcPass": "env:MY_RPC_PASS"` reads the password from the `MY_RPC_PASS` environment variable.
|
|
356
|
+
- `"rpcPass": "file:/run/secrets/rpc-pass"` reads it from a file (a single trailing newline is trimmed).
|
|
357
|
+
- `BTCR2_BTC_RPC_PASS_FILE=/run/secrets/rpc-pass` names a file to read when no other RPC password source applies.
|
|
269
358
|
|
|
270
359
|
### Defaults
|
|
271
360
|
|