@xyo-network/wallet-xl1-cli 0.1.20 → 0.1.22
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 +207 -9
- package/dist/bin/wallet.mjs +81058 -70628
- package/dist/node/signing-types.d.ts +76 -0
- package/dist/node/signing.d.ts +9 -0
- package/dist/node/signing.mjs +169134 -0
- package/package.json +34 -9
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ The Aries CLI uses this same package for `aries wallet ...`, so the standalone a
|
|
|
17
17
|
|
|
18
18
|
### Prerequisites
|
|
19
19
|
|
|
20
|
-
- Node.js `>=
|
|
20
|
+
- Node.js `>=22.19.0`
|
|
21
21
|
- A package manager such as `npm`, `pnpm`, or `yarn`
|
|
22
22
|
|
|
23
23
|
### Global Install
|
|
@@ -59,6 +59,58 @@ aries wallet balance 0
|
|
|
59
59
|
aries wallet send 0x0000000000000000000000000000000000000000 1.25 --milli --json
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
## Requester-scoped Node signing
|
|
63
|
+
|
|
64
|
+
The supported `@xyo-network/wallet-xl1-cli/signing` entry exposes public wallet
|
|
65
|
+
summaries and short-lived, account-bound signing sessions. Install the package
|
|
66
|
+
locally with its `@xyo-network/xl1-sdk` peer. Consumers select the requester ID,
|
|
67
|
+
exact wallet ID, derivation offset, expected account, chain ID, and independently
|
|
68
|
+
verified genesis hash. The wallet itself confirms that selection and prompts on
|
|
69
|
+
the trusted terminal for its password; this API does not accept a password,
|
|
70
|
+
mnemonic, root wallet, or caller-provided signer.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { listSigningWallets, openWalletSigningSession } from '@xyo-network/wallet-xl1-cli/signing'
|
|
74
|
+
|
|
75
|
+
const wallets = listSigningWallets()
|
|
76
|
+
const session = await openWalletSigningSession(selection)
|
|
77
|
+
try {
|
|
78
|
+
const snapshot = await session.snapshot()
|
|
79
|
+
const signed = await session.signTransaction({ requestId, transaction })
|
|
80
|
+
// Persist signed bytes in the participant publication journal before broadcasting.
|
|
81
|
+
} finally {
|
|
82
|
+
await session.close()
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Here `selection` is the complete explicit binding and `transaction` is an SDK
|
|
87
|
+
unsigned hydrated transaction. The session signs without publishing bodies or
|
|
88
|
+
broadcasting. It supports secp256k1 wallets; post-quantum transaction signing is
|
|
89
|
+
not qualified. Sessions expire within five minutes. Lock, close, password
|
|
90
|
+
replacement, and wallet replacement revoke authority for new signing.
|
|
91
|
+
|
|
92
|
+
The wallet persists request intent and encrypted signed results in `signing.json`
|
|
93
|
+
under its existing guarded store lease. Retrying the same request returns the
|
|
94
|
+
same bytes. `signingOutcome(requestId)` recovers a retained result through a fresh
|
|
95
|
+
authorized session with the same complete binding. An uncertain intent blocks
|
|
96
|
+
new same-account signing; an error, timeout, or `4001` is never proof that no
|
|
97
|
+
signature exists. Existing CLI `tx sign` and `send` use this same signing ledger,
|
|
98
|
+
with publication remaining a separate command step. Legacy offline signing has
|
|
99
|
+
an explicitly unasserted genesis scope; it cannot authorize public requester
|
|
100
|
+
sessions. This does not reconstruct pre-upgrade or external-key signing history.
|
|
101
|
+
|
|
102
|
+
Run the isolated packed public import, type, real terminal prompt, and process
|
|
103
|
+
recovery fixture from the repository root after both wallet package builds:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
node packages/wallet-cli/scripts/verifySigningPacked.mjs /absolute/fresh/evidence-directory
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The terminal fixture currently qualifies macOS. It creates only a temporary
|
|
110
|
+
public deterministic wallet. Its strict consumer type check uses `skipLibCheck`;
|
|
111
|
+
the full dependency declaration check is retained separately because upstream SDK
|
|
112
|
+
declarations currently fail that broader check.
|
|
113
|
+
|
|
62
114
|
## Wallet Storage
|
|
63
115
|
|
|
64
116
|
Wallet CLI data is stored under `~/.xl1/wallet/cli` by default.
|
|
@@ -67,7 +119,8 @@ Wallet CLI data is stored under `~/.xl1/wallet/cli` by default.
|
|
|
67
119
|
| --- | --- |
|
|
68
120
|
| `XL1_WALLET_HOME` | Overrides the wallet storage directory. |
|
|
69
121
|
| `ARIES_WALLET_HOME` | Legacy fallback storage override. Used only when `XL1_WALLET_HOME` is not set. |
|
|
70
|
-
| `ARIES_WALLET_PASSWORD` | Supplies the wallet password
|
|
122
|
+
| `ARIES_WALLET_PASSWORD` | Supplies the wallet password. A nonempty value is validated before any cached session is used. For a new store, it sets the initial password. |
|
|
123
|
+
| `ARIES_WALLET_NON_INTERACTIVE=1` | Refuses terminal password and recovery-phrase prompts. Private-key access requires an unlocked session or `ARIES_WALLET_PASSWORD`; import requires `--phrase-stdin` or `--phrase`. |
|
|
71
124
|
|
|
72
125
|
Wallet seed phrases are encrypted at rest. Commands that need private key access prompt for the wallet password unless `ARIES_WALLET_PASSWORD` is set.
|
|
73
126
|
|
|
@@ -97,10 +150,45 @@ xl1-wallet network use xl1-sequence
|
|
|
97
150
|
Add a local or custom network:
|
|
98
151
|
|
|
99
152
|
```sh
|
|
100
|
-
xl1-wallet network add local http://127.0.0.1:8080/rpc --label "Local XL1" --chain-id
|
|
153
|
+
xl1-wallet network add local http://127.0.0.1:8080/rpc --label "Local XL1" --chain-id 1234
|
|
101
154
|
xl1-wallet network use local
|
|
102
155
|
```
|
|
103
156
|
|
|
157
|
+
Adding a network preserves the current selection and rejects duplicate IDs.
|
|
158
|
+
New IDs must be nonblank, contain no control characters, fit within 256 UTF-8
|
|
159
|
+
bytes, and not begin with `-`. Optional labels are preserved exactly and may
|
|
160
|
+
contain up to 1024 UTF-8 bytes. Optional chain IDs use the XL1 protocol's
|
|
161
|
+
nonempty lowercase hexadecimal form without a `0x` prefix; there is no fixed
|
|
162
|
+
length requirement. The chain ID is stored metadata: adding a network does not
|
|
163
|
+
probe the endpoint or verify its chain.
|
|
164
|
+
|
|
165
|
+
For endpoints containing path or query credentials, pass the complete URL via
|
|
166
|
+
private stdin instead of a positional argument. Stdin must contain only the URL
|
|
167
|
+
as UTF-8, with no trailing newline, and is limited to 16 KiB. URLs must be complete
|
|
168
|
+
HTTP or HTTPS URLs without controls or fragments. Local HTTP endpoints are
|
|
169
|
+
supported. URL username/password information is rejected because the RPC fetch
|
|
170
|
+
transport does not support it.
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
printf '%s' "$RPC_URL" | xl1-wallet network inspect-add custom \
|
|
174
|
+
--rpc-url-stdin --label="Custom XL1" --chain-id=1234 --json
|
|
175
|
+
printf '%s' "$RPC_URL" | xl1-wallet network add custom \
|
|
176
|
+
--rpc-url-stdin --label="Custom XL1" --chain-id=1234 \
|
|
177
|
+
--expected-state="$REVIEWED_STATE_HASH" --json
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`inspect-add` validates the proposed entry and returns its ID, label, optional
|
|
181
|
+
chain ID, current active ID, canonical wallet root, and `stateHash`. Use that
|
|
182
|
+
hash as `REVIEWED_STATE_HASH` for the corresponding add. Inspection does not
|
|
183
|
+
create `networks.json`; the add writes defaults and the custom entry atomically
|
|
184
|
+
under the wallet store lease. If any wallet file changes after review, the
|
|
185
|
+
guarded add fails and must be reviewed again. `--rpc-url-stdin` and a positional
|
|
186
|
+
URL are mutually exclusive.
|
|
187
|
+
|
|
188
|
+
Network list and add support `--json`. Network summaries and
|
|
189
|
+
success messages omit the entire RPC URL, including its hostname. The URL is
|
|
190
|
+
stored in the private wallet configuration for RPC use.
|
|
191
|
+
|
|
104
192
|
Remove a custom network:
|
|
105
193
|
|
|
106
194
|
```sh
|
|
@@ -115,15 +203,16 @@ xl1-wallet network remove local
|
|
|
115
203
|
| --- | --- |
|
|
116
204
|
| `xl1-wallet create` | Create a new wallet. |
|
|
117
205
|
| `xl1-wallet import` | Import a recovery phrase. |
|
|
118
|
-
| `xl1-wallet export` | Print a wallet recovery phrase
|
|
206
|
+
| `xl1-wallet export` | Print a wallet recovery phrase using a password or unlocked session. |
|
|
119
207
|
| `xl1-wallet list` | List wallets in the current wallet home. |
|
|
120
208
|
| `xl1-wallet use <id>` | Set the active wallet. |
|
|
121
209
|
| `xl1-wallet rename <id> <label>` | Rename a wallet. |
|
|
122
|
-
| `xl1-wallet remove
|
|
123
|
-
| `xl1-wallet reset` | Delete
|
|
210
|
+
| `xl1-wallet remove [id]` | Authenticate and remove a wallet; `--wallet-id` targets an exact ID. |
|
|
211
|
+
| `xl1-wallet reset` | Delete known wallet files after confirmation, preserving unrelated files. |
|
|
124
212
|
| `xl1-wallet unlock` | Cache an encrypted wallet session for a limited time. |
|
|
125
213
|
| `xl1-wallet lock` | Clear the cached wallet session. |
|
|
126
|
-
| `xl1-wallet password change` | Change the
|
|
214
|
+
| `xl1-wallet password change` | Change the shared password for every wallet in the store. |
|
|
215
|
+
| `xl1-wallet lifecycle preview --json` | Inspect the canonical store path, state fingerprint, wallets, and known files. |
|
|
127
216
|
|
|
128
217
|
Examples:
|
|
129
218
|
|
|
@@ -135,17 +224,63 @@ xl1-wallet import --label quant-recovery --phrase "..." --algorithm ml-dsa-65
|
|
|
135
224
|
xl1-wallet list
|
|
136
225
|
xl1-wallet use <wallet-id>
|
|
137
226
|
xl1-wallet export --id <wallet-id>
|
|
227
|
+
xl1-wallet export --wallet-id <exact-wallet-id> --json
|
|
138
228
|
```
|
|
139
229
|
|
|
140
230
|
`create` and `import` default to `--algorithm secp256k1`. Use `--algorithm ml-dsa-65` for `QuantHDWallet` wallets, which derive `qm65...` bech32m addresses. Wallet-signed JWT commands require secp256k1 because ML-DSA-65 does not yet have a standardized JOSE algorithm.
|
|
141
|
-
Wallet labels must be unique. If `create` is run without `--label`, the CLI uses the first available `wallet#` label, starting with `wallet0`.
|
|
231
|
+
Wallet labels must be unique, nonblank, and free of NUL characters. Other label text, including surrounding spaces, is preserved. If `create` is run without `--label`, the CLI uses the first available `wallet#` label, starting with `wallet0`.
|
|
232
|
+
Commands accepting a wallet ID or label prefer an exact ID match before looking
|
|
233
|
+
for a matching label.
|
|
234
|
+
|
|
235
|
+
For unattended imports, `--phrase-stdin` reads raw UTF-8 from standard input
|
|
236
|
+
until EOF, up to 16 KiB, and trims surrounding whitespace. It is mutually
|
|
237
|
+
exclusive with `--phrase`. The algorithm, label, and recovery phrase are
|
|
238
|
+
validated before the command initializes a password or stores a wallet.
|
|
239
|
+
|
|
240
|
+
`export --wallet-id` accepts only an exact stored ID and cannot be combined
|
|
241
|
+
with `--id`. The existing `--id` option also accepts labels; omitting both
|
|
242
|
+
options reveals the active wallet.
|
|
243
|
+
|
|
244
|
+
`create --json` and `export --json` emit only
|
|
245
|
+
`{id, label, algorithm, mnemonic}` to stdout. This output contains the recovery
|
|
246
|
+
phrase. `import --json` emits only `{id, label, algorithm}` and does not include
|
|
247
|
+
the phrase. Text output remains the default.
|
|
248
|
+
|
|
249
|
+
Password change requires the current password even with an unlocked session.
|
|
250
|
+
`ARIES_WALLET_PASSWORD` supplies only that current password. For automation,
|
|
251
|
+
`password change --new-password-stdin --json` reads the new password as raw UTF-8
|
|
252
|
+
until EOF, preserving all whitespace, with a 4096-byte limit and no NUL
|
|
253
|
+
characters. Its JSON result is `{changed: true}`. Interactive mode asks for and
|
|
254
|
+
confirms the new password separately. Rotation clears the cached session.
|
|
255
|
+
|
|
256
|
+
`remove --wallet-id=<exact-id> --json` returns `{id, label, removed: true}`.
|
|
257
|
+
The named selector cannot be combined with the positional ID/label. A supplied
|
|
258
|
+
wrong password fails even if an unlocked session exists.
|
|
259
|
+
|
|
260
|
+
Password change, removal, and reset accept `--expected-state=<stateHash>` from
|
|
261
|
+
`lifecycle preview --json`. The CLI checks this fingerprint under its filesystem
|
|
262
|
+
lease before writing; a changed store requires a new review. Preview returns
|
|
263
|
+
`{root, stateHash, wallets, files}` without credentials. If wallet metadata is
|
|
264
|
+
corrupt, `wallets` is `null` with a `metadataError`, so reset can still be reviewed.
|
|
265
|
+
|
|
266
|
+
Updated CLI processes share a canonical-path filesystem lease. Overlapping
|
|
267
|
+
operations report a busy store; a killed owner's lease expires after 30 seconds.
|
|
268
|
+
Older CLI versions and other programs that ignore the lease are not coordinated.
|
|
269
|
+
Password rotation, removal, and reset commit a durable roll-forward journal
|
|
270
|
+
before replacing data files. The journal contains encrypted wallet records and
|
|
271
|
+
password-verifier metadata, never plaintext passwords or recovery phrases.
|
|
272
|
+
The next leased operation completes a valid pending transaction before reading
|
|
273
|
+
the store. After an interrupted rotation, try the new password first. Individual
|
|
274
|
+
files and journals are limited to 16 MiB. File data is synced; directory syncing
|
|
275
|
+
is best effort on Windows where unsupported. A corrupt or unrecoverable journal
|
|
276
|
+
blocks operations, including reset: preserve its files for repair.
|
|
142
277
|
|
|
143
278
|
### Accounts
|
|
144
279
|
|
|
145
280
|
| Command | Description |
|
|
146
281
|
| --- | --- |
|
|
147
282
|
| `xl1-wallet account derive <offset>` | Derive and store an account at an offset. |
|
|
148
|
-
| `xl1-wallet account list` | List stored accounts for the active wallet. |
|
|
283
|
+
| `xl1-wallet account list [--wallet <id-or-label>]` | List stored accounts for the active or specified wallet. |
|
|
149
284
|
| `xl1-wallet account show <offset>` | Show a derived account address. |
|
|
150
285
|
| `xl1-wallet account label <offset> <label>` | Label an account. |
|
|
151
286
|
| `xl1-wallet account remove <offset>` | Remove a stored account record. |
|
|
@@ -156,8 +291,17 @@ Examples:
|
|
|
156
291
|
xl1-wallet account derive 0 --label main
|
|
157
292
|
xl1-wallet account show 0
|
|
158
293
|
xl1-wallet account list
|
|
294
|
+
xl1-wallet account derive 4 --wallet-id <wallet-id> --label savings
|
|
159
295
|
```
|
|
160
296
|
|
|
297
|
+
Account `show`, `derive`, `label`, and `remove` accept `--wallet-id` to target an
|
|
298
|
+
exact stored wallet without changing the active wallet. Labels are not accepted
|
|
299
|
+
by this option. Omitting it keeps the active-wallet default. Desktop account
|
|
300
|
+
changes require an explicit wallet ID so a reviewed change stays attached to
|
|
301
|
+
the intended wallet. Account removal only removes address-book metadata;
|
|
302
|
+
the key remains derivable and funds are unaffected. Account labeling validates
|
|
303
|
+
the derivation path before saving it.
|
|
304
|
+
|
|
161
305
|
### Balances And Transfers
|
|
162
306
|
|
|
163
307
|
| Command | Description |
|
|
@@ -276,6 +420,60 @@ xl1-wallet backup import wallet-metadata.json
|
|
|
276
420
|
xl1-wallet reset
|
|
277
421
|
```
|
|
278
422
|
|
|
423
|
+
Metadata backups retain the version 1 `network.xyo.wallet.backup` format. They
|
|
424
|
+
contain address-book offsets and labels, and contact addresses, labels, and
|
|
425
|
+
timestamps. They do not contain recovery phrases, passwords, session credentials,
|
|
426
|
+
or network configuration. Imports merge metadata: incoming defined account labels
|
|
427
|
+
and contact labels win, existing account labels survive when incoming labels are omitted, and existing
|
|
428
|
+
contact creation timestamps are preserved. Contact update timestamps never move
|
|
429
|
+
backward when importing an older backup.
|
|
430
|
+
|
|
431
|
+
Review an import or export before applying it:
|
|
432
|
+
|
|
433
|
+
```sh
|
|
434
|
+
xl1-wallet backup inspect wallet-metadata.json --direction=import --json
|
|
435
|
+
xl1-wallet backup inspect wallet-metadata.json --direction=export --json
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
The JSON result is `{root, stateHash, path, fileStateHash, exists, addressBooks,
|
|
439
|
+
accounts, contacts}`. `root` and `path` are canonical absolute paths. Counts refer
|
|
440
|
+
to incoming backup entries for import, or the stored metadata to export. The
|
|
441
|
+
inspection exposes only paths, counts, existence, and hashes. To require exactly
|
|
442
|
+
the reviewed wallet and file states, pass both hashes to the subsequent command:
|
|
443
|
+
|
|
444
|
+
```sh
|
|
445
|
+
xl1-wallet backup import wallet-metadata.json \
|
|
446
|
+
--expected-state=<stateHash> --expected-file-state=<fileStateHash> --json
|
|
447
|
+
xl1-wallet backup export wallet-metadata.json --overwrite \
|
|
448
|
+
--expected-state=<stateHash> --expected-file-state=<fileStateHash> --json
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Import returns `{imported: true, addressBooks, accounts, contacts}`; export returns
|
|
452
|
+
`{exported: true, addressBooks, accounts, contacts}`. Existing export destinations
|
|
453
|
+
require `--overwrite`. New exports never overwrite a file created concurrently.
|
|
454
|
+
Exports use private `0600` temporary files, fsync, and atomic publication. Imports
|
|
455
|
+
commit address books and contacts together through the wallet recovery journal
|
|
456
|
+
and never modify their source backup. Cooperating CLI processes coordinate by
|
|
457
|
+
wallet root and export destination, including exports from different wallet roots.
|
|
458
|
+
|
|
459
|
+
Files must be regular files of at most 16 MiB, with one filesystem link. Symlinks,
|
|
460
|
+
directories, special files, wallet storage files, and wallet transaction or lease
|
|
461
|
+
paths are rejected. The parent directory must already exist. Version 1 schemas
|
|
462
|
+
and fields are validated strictly; unknown entries, duplicate books/accounts or
|
|
463
|
+
contacts, invalid legacy or quant addresses, and prototype keys are rejected.
|
|
464
|
+
Labels preserve every string accepted by existing version 1 authoring commands,
|
|
465
|
+
including empty, multiline, and long values, within the overall file size limit.
|
|
466
|
+
Offsets use decimal HD path segments up to `2147483647`, optional hardened
|
|
467
|
+
apostrophes and `m/`, at most 32 segments and 512 characters. Timestamps use UTC
|
|
468
|
+
ISO format with milliseconds, as produced by the CLI.
|
|
469
|
+
|
|
470
|
+
For noninteractive reset, pass both `--confirm=RESET` and `--yes`; `--json`
|
|
471
|
+
returns `{reset: true, removedFiles: number}`. No password is required. Reset
|
|
472
|
+
removes only `password.json`, `phrases.json`, `active.json`, `address-books.json`,
|
|
473
|
+
`contacts.json`, `networks.json`, `session.json`, and `.machine-id`. It preserves
|
|
474
|
+
the directory and unrelated files, and refuses to recurse into a directory
|
|
475
|
+
occupying one of those filenames.
|
|
476
|
+
|
|
279
477
|
## Output And Automation
|
|
280
478
|
|
|
281
479
|
Most commands print readable text by default. Commands intended for automation, such as `send`, also support JSON output:
|