@vultisig/cli 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @vultisig/cli
2
2
 
3
+ ## 2.11.0
4
+
5
+ ### Patch Changes
6
+
7
+ - [#899](https://github.com/vultisig/vultisig-sdk/pull/899) [`00ede74`](https://github.com/vultisig/vultisig-sdk/commit/00ede74e6db1bd08ded0b25cc32c1f477e6b0d22) Thanks [@neavra](https://github.com/neavra)! - agent: resolve the vault password from the keyring/env chain before prompting
8
+
9
+ `vultisig agent` (including `agent ask` and `--via-agent`) now resolves the vault
10
+ password from the in-memory cache → OS keyring (`vsig auth setup`) →
11
+ `VAULT_PASSWORDS`/`VAULT_PASSWORD` env chain before falling back to an
12
+ interactive prompt. Headless operators who configured the keyring or env no
13
+ longer have to pass `--password` on argv (which exposed the secret to `ps` and
14
+ shell history). `--password` still works but is de-emphasized and now emits a
15
+ stderr warning pointing at the keyring/env path.
16
+
17
+ - Updated dependencies [[`9e72781`](https://github.com/vultisig/vultisig-sdk/commit/9e7278125bd8bc722a26ab3a1f91ba1be03054d1)]:
18
+ - @vultisig/core-chain@2.20.0
19
+ - @vultisig/sdk@2.11.0
20
+ - @vultisig/rujira@44.0.0
21
+
3
22
  ## 2.10.0
4
23
 
5
24
  ### Patch Changes
package/README.md CHANGED
@@ -60,6 +60,7 @@ vultisig create fast --name "My Wallet" --password "mypassword" --email user@exa
60
60
  ```
61
61
 
62
62
  You'll be prompted to:
63
+
63
64
  1. Enter the verification code sent to your email
64
65
 
65
66
  ### Create a Secure Vault (Multi-Device)
@@ -69,16 +70,19 @@ vultisig create secure --name "Team Wallet" --shares 3
69
70
  ```
70
71
 
71
72
  This creates a secure vault with configurable N-of-M threshold:
73
+
72
74
  1. A QR code displays in your terminal
73
75
  2. Other participants scan with Vultisig mobile app (iOS/Android)
74
76
  3. Once all devices join, keygen runs automatically
75
77
  4. Vault is created and ready to use
76
78
 
77
79
  **Secure vault options:**
80
+
78
81
  - `--shares <n>` - Number of participating devices (default: 3)
79
82
  - `--threshold <n>` - Signing threshold (default: 2)
80
83
 
81
84
  **Example session:**
85
+
82
86
  ```bash
83
87
  $ vultisig create secure --name "Team Wallet" --shares 3
84
88
 
@@ -115,6 +119,7 @@ vultisig create-from-seedphrase secure --name "Team Wallet" --shares 3
115
119
  ```
116
120
 
117
121
  **Import options:**
122
+
118
123
  - `--mnemonic <words>` - Recovery phrase (space-separated words)
119
124
  - `--discover-chains` - Scan chains for existing balances before import
120
125
  - `--chains <chains>` - Specific chains to enable (comma-separated)
@@ -125,6 +130,7 @@ When `--mnemonic` is not provided, you'll be prompted to enter it securely (mask
125
130
  > **Note:** Phantom wallet uses a non-standard derivation path for Solana. If your seedphrase was originally created in Phantom and you're importing Solana funds, use `--use-phantom-solana-path`. When using `--discover-chains`, this is auto-detected.
126
131
 
127
132
  **Example session:**
133
+
128
134
  ```bash
129
135
  $ vultisig create-from-seedphrase fast --name "My Wallet" --email user@example.com --password "mypassword" --discover-chains
130
136
 
@@ -213,34 +219,37 @@ vultisig -i
213
219
 
214
220
  ### Vault Management
215
221
 
216
- | Command | Description |
217
- |---------|-------------|
218
- | `create fast` | Create a new fast vault (server-assisted 2-of-2) |
219
- | `create secure` | Create a secure vault (multi-device MPC) |
220
- | `import <file>` | Import vault from .vult file |
221
- | `delete [vault]` | Delete a vault from local storage |
222
- | `create-from-seedphrase fast` | Import seedphrase as FastVault (2-of-2) |
223
- | `create-from-seedphrase secure` | Import seedphrase as SecureVault (N-of-M) |
224
- | `join secure` | Join an existing SecureVault creation session |
225
- | `export [path]` | Export vault to file |
226
- | `verify <vaultId>` | Verify vault with email code |
227
- | `vaults` | List all stored vaults |
228
- | `switch <vaultId>` | Switch to a different vault |
229
- | `rename <newName>` | Rename the active vault |
230
- | `info` | Show detailed vault information |
222
+ | Command | Description |
223
+ | ------------------------------- | ------------------------------------------------ |
224
+ | `create fast` | Create a new fast vault (server-assisted 2-of-2) |
225
+ | `create secure` | Create a secure vault (multi-device MPC) |
226
+ | `import <file>` | Import vault from .vult file |
227
+ | `delete [vault]` | Delete a vault from local storage |
228
+ | `create-from-seedphrase fast` | Import seedphrase as FastVault (2-of-2) |
229
+ | `create-from-seedphrase secure` | Import seedphrase as SecureVault (N-of-M) |
230
+ | `join secure` | Join an existing SecureVault creation session |
231
+ | `export [path]` | Export vault to file |
232
+ | `verify <vaultId>` | Verify vault with email code |
233
+ | `vaults` | List all stored vaults |
234
+ | `switch <vaultId>` | Switch to a different vault |
235
+ | `rename <newName>` | Rename the active vault |
236
+ | `info` | Show detailed vault information |
231
237
 
232
238
  **Create fast options:**
239
+
233
240
  - `--name <name>` - Vault name (required)
234
241
  - `--password <password>` - Vault password (required)
235
242
  - `--email <email>` - Email for verification (required)
236
243
 
237
244
  **Create secure options:**
245
+
238
246
  - `--name <name>` - Vault name (required)
239
247
  - `--password <password>` - Vault password (optional)
240
248
  - `--shares <n>` - Number of devices (default: 3)
241
249
  - `--threshold <n>` - Signing threshold (default: 2)
242
250
 
243
251
  **Delete options:**
252
+
244
253
  - `[vault]` - Vault name or ID to delete (defaults to active vault)
245
254
  - `-y, --yes` - Skip confirmation prompt
246
255
 
@@ -259,6 +268,7 @@ vultisig delete "Test Vault" --yes
259
268
  ```
260
269
 
261
270
  **Join secure options:**
271
+
262
272
  - `--qr <payload>` - QR code payload from initiator (vultisig://...)
263
273
  - `--qr-file <path>` - Read QR payload from file
264
274
  - `--mnemonic <words>` - Seedphrase (required for seedphrase-based sessions)
@@ -266,6 +276,7 @@ vultisig delete "Test Vault" --yes
266
276
  - `--devices <n>` - Total devices in session (default: 2)
267
277
 
268
278
  **Create-from-seedphrase fast options:**
279
+
269
280
  - `--name <name>` - Vault name (required)
270
281
  - `--email <email>` - Email for verification (required)
271
282
  - `--password <password>` - Vault password (required)
@@ -275,6 +286,7 @@ vultisig delete "Test Vault" --yes
275
286
  - `--use-phantom-solana-path` - Use Phantom wallet derivation path for Solana
276
287
 
277
288
  **Create-from-seedphrase secure options:**
289
+
278
290
  - `--name <name>` - Vault name (required)
279
291
  - `--shares <n>` - Number of devices (default: 3)
280
292
  - `--threshold <n>` - Signing threshold (default: ceil((shares+1)/2))
@@ -285,6 +297,7 @@ vultisig delete "Test Vault" --yes
285
297
  - `--use-phantom-solana-path` - Use Phantom wallet derivation path for Solana
286
298
 
287
299
  **Export options:**
300
+
288
301
  - `[path]` - Output file or directory (defaults to SDK-generated filename in current directory)
289
302
  - `--password <password>` - Password to unlock encrypted vaults
290
303
  - `--exportPassword <password>` - Password to encrypt the export file (defaults to `--password` if provided)
@@ -309,27 +322,27 @@ vultisig export
309
322
 
310
323
  ### Wallet Operations
311
324
 
312
- | Command | Description |
313
- |---------|-------------|
314
- | `balance [chain]` | Show balance for a chain or all chains |
315
- | `send <chain> <to> <amount>` | Send tokens to an address |
316
- | `addresses` | Show all vault addresses |
317
- | `portfolio` | Show total portfolio value |
325
+ | Command | Description |
326
+ | ---------------------------- | -------------------------------------- |
327
+ | `balance [chain]` | Show balance for a chain or all chains |
328
+ | `send <chain> <to> <amount>` | Send tokens to an address |
329
+ | `addresses` | Show all vault addresses |
330
+ | `portfolio` | Show total portfolio value |
318
331
 
319
332
  ### Chain & Token Management
320
333
 
321
- | Command | Description |
322
- |---------|-------------|
323
- | `chains` | List and manage chains (--add, --remove) |
324
- | `tokens <chain>` | List and manage tokens for a chain |
334
+ | Command | Description |
335
+ | ---------------- | ---------------------------------------- |
336
+ | `chains` | List and manage chains (--add, --remove) |
337
+ | `tokens <chain>` | List and manage tokens for a chain |
325
338
 
326
339
  ### Swap Operations
327
340
 
328
- | Command | Description |
329
- |---------|-------------|
330
- | `swap-chains` | List chains that support swaps |
331
- | `swap-quote <from> <to> <amount>` | Get a swap quote |
332
- | `swap <from> <to> <amount>` | Execute a swap |
341
+ | Command | Description |
342
+ | --------------------------------- | ------------------------------ |
343
+ | `swap-chains` | List chains that support swaps |
344
+ | `swap-quote <from> <to> <amount>` | Get a swap quote |
345
+ | `swap <from> <to> <amount>` | Execute a swap |
333
346
 
334
347
  ```bash
335
348
  # Get a swap quote
@@ -349,11 +362,11 @@ Swap quotes and previews show your VULT discount tier when affiliate fees are ap
349
362
 
350
363
  ### Advanced Operations
351
364
 
352
- | Command | Description |
353
- |---------|-------------|
354
- | `sign` | Sign pre-hashed bytes for custom transactions |
355
- | `broadcast` | Broadcast a pre-signed raw transaction |
356
- | `tx-status <chain> <txHash>` | Check transaction confirmation status |
365
+ | Command | Description |
366
+ | ---------------------------- | --------------------------------------------- |
367
+ | `sign` | Sign pre-hashed bytes for custom transactions |
368
+ | `broadcast` | Broadcast a pre-signed raw transaction |
369
+ | `tx-status <chain> <txHash>` | Check transaction confirmation status |
357
370
 
358
371
  #### Transaction Status
359
372
 
@@ -371,6 +384,7 @@ vultisig tx-status ethereum 0x9f8e7d6c... -o json
371
384
  ```
372
385
 
373
386
  **Output:**
387
+
374
388
  ```
375
389
  ✓ Transaction status: success
376
390
  Status: success
@@ -379,6 +393,7 @@ Explorer: https://etherscan.io/tx/0x9f8e7d6c...
379
393
  ```
380
394
 
381
395
  **JSON output:**
396
+
382
397
  ```json
383
398
  {
384
399
  "chain": "ethereum",
@@ -409,6 +424,7 @@ vultisig sign --chain ethereum --bytes "..." -o json
409
424
  ```
410
425
 
411
426
  **Output:**
427
+
412
428
  ```
413
429
  Signature: <base64-encoded signature>
414
430
  Recovery: 0
@@ -416,6 +432,7 @@ Format: ecdsa
416
432
  ```
417
433
 
418
434
  **JSON output:**
435
+
419
436
  ```json
420
437
  {
421
438
  "signature": "<base64>",
@@ -443,6 +460,7 @@ vultisig broadcast --chain sui --raw-tx '{"unsignedTx":"...","signature":"..."}'
443
460
  ```
444
461
 
445
462
  **Output:**
463
+
446
464
  ```
447
465
  TX Hash: 0x9f8e7d6c...
448
466
  Explorer: https://etherscan.io/tx/0x9f8e7d6c...
@@ -450,17 +468,17 @@ Explorer: https://etherscan.io/tx/0x9f8e7d6c...
450
468
 
451
469
  **Supported broadcast formats by chain:**
452
470
 
453
- | Chain | `--raw-tx` Format |
454
- |-------|-------------------|
455
- | EVM (Ethereum, Polygon, etc.) | Hex-encoded signed tx |
456
- | UTXO (Bitcoin, Litecoin, etc.) | Hex-encoded raw tx |
457
- | Solana | Base64-encoded tx bytes |
458
- | Sui | JSON: `{"unsignedTx":"...","signature":"..."}` |
459
- | Cosmos | JSON: `{"tx_bytes":"..."}` or base64 |
460
- | TON | Base64 BOC |
461
- | Polkadot | Hex-encoded extrinsic |
462
- | Ripple | Hex-encoded tx blob |
463
- | Tron | JSON tx object |
471
+ | Chain | `--raw-tx` Format |
472
+ | ------------------------------ | ---------------------------------------------- |
473
+ | EVM (Ethereum, Polygon, etc.) | Hex-encoded signed tx |
474
+ | UTXO (Bitcoin, Litecoin, etc.) | Hex-encoded raw tx |
475
+ | Solana | Base64-encoded tx bytes |
476
+ | Sui | JSON: `{"unsignedTx":"...","signature":"..."}` |
477
+ | Cosmos | JSON: `{"tx_bytes":"..."}` or base64 |
478
+ | TON | Base64 BOC |
479
+ | Polkadot | Hex-encoded extrinsic |
480
+ | Ripple | Hex-encoded tx blob |
481
+ | Tron | JSON tx object |
464
482
 
465
483
  #### Example: Custom EVM Transaction
466
484
 
@@ -614,6 +632,7 @@ vultisig create fast --name "Agent Wallet" --password "$VAULT_PASSWORD" --email
614
632
  ```
615
633
 
616
634
  JSON output for two-step create:
635
+
617
636
  ```json
618
637
  {
619
638
  "vaultId": "023118...",
@@ -626,23 +645,33 @@ JSON output for two-step create:
626
645
 
627
646
  #### Agent Ask (One-Shot Mode)
628
647
 
629
- Send a single natural-language message and get a structured response. Designed for AI-to-AI communication:
648
+ Send a single natural-language message and get a structured response. Designed for AI-to-AI communication.
649
+
650
+ **Password resolution:** `agent ask` unlocks the vault from the keyring/env chain before prompting, so a headless operator never has to put the password on argv. Set it up **once** — store it in the OS keyring with `vsig auth setup` (recommended), or export `VAULT_PASSWORD` (or `VAULT_PASSWORDS="VaultName:pw ..."` for multiple vaults) — then run `agent ask` with **no** `--password`. The `--password` flag still works as a fallback but is discouraged: it exposes the secret to `ps` and shell history, and triggers a stderr warning.
630
651
 
631
652
  ```bash
632
- # Simple query
633
- vultisig agent ask "What is my ETH balance?" --password "$VAULT_PASSWORD"
653
+ # Recommended: store the password once, then no --password on each call
654
+ vsig auth setup # stores in the OS keyring
655
+ # or: export VAULT_PASSWORD="..."
656
+
657
+ # Simple query (password resolved from keyring/env)
658
+ vultisig agent ask "What is my ETH balance?"
634
659
 
635
660
  # Execute a transaction
636
- vultisig agent ask "Send 0.01 ETH to 0x742d..." --password "$VAULT_PASSWORD"
661
+ vultisig agent ask "Send 0.01 ETH to 0x742d..."
637
662
 
638
663
  # Continue a conversation (multi-turn)
639
- vultisig agent ask "Now swap it to USDC" --session abc123 --password "$VAULT_PASSWORD"
664
+ vultisig agent ask "Now swap it to USDC" --session abc123
640
665
 
641
666
  # JSON output (for parsing)
642
- vultisig agent ask "Check my portfolio" --password "$VAULT_PASSWORD" --json
667
+ vultisig agent ask "Check my portfolio" --json
668
+
669
+ # Fallback only — exposes the secret to `ps`/shell history (emits a warning)
670
+ vultisig agent ask "What is my ETH balance?" --password "$VAULT_PASSWORD"
643
671
  ```
644
672
 
645
673
  **Text output (default):**
674
+
646
675
  ```
647
676
  session:abc123-def456
648
677
 
@@ -653,12 +682,21 @@ explorer:https://etherscan.io/tx/0x9f8e7d6c...
653
682
  ```
654
683
 
655
684
  **JSON output (`--json`):**
685
+
656
686
  ```json
657
687
  {
658
688
  "session_id": "abc123-def456",
659
689
  "response": "Your ETH balance is 1.5 ETH ($3,750.00 USD).",
660
690
  "tool_calls": [
661
- { "action": "get_balances", "success": true, "data": { "balances": [{ "chain": "Ethereum", "symbol": "ETH", "amount": "1.5", "decimals": 18, "raw_amount": "1500000000000000000" }] } }
691
+ {
692
+ "action": "get_balances",
693
+ "success": true,
694
+ "data": {
695
+ "balances": [
696
+ { "chain": "Ethereum", "symbol": "ETH", "amount": "1.5", "decimals": 18, "raw_amount": "1500000000000000000" }
697
+ ]
698
+ }
699
+ }
662
700
  ],
663
701
  "transactions": [
664
702
  { "hash": "0x9f8e7d6c...", "chain": "ethereum", "explorerUrl": "https://etherscan.io/tx/0x9f8e7d6c..." }
@@ -678,28 +716,29 @@ Each entry in `tool_calls` may include `code` when `success` is false (same valu
678
716
 
679
717
  Orchestrators should branch on `code`. The message in `error` / `message` stays human-readable and may change between releases.
680
718
 
681
- | Code | Typical meaning |
682
- |------|-----------------|
683
- | `BACKEND_UNREACHABLE` | Agent health check failed or backend not responding |
684
- | `AUTH_FAILED` | Auth/token failure, HTTP 401/403, or wrong vault password |
685
- | `VAULT_LOCKED` | Encrypted vault needs unlock (password) |
686
- | `PASSWORD_REQUIRED` | Password was not supplied when required (e.g. pipe mode or signing) |
687
- | `CONFIRMATION_REQUIRED` | User confirmation needed (pipe mode; message prefix `CONFIRMATION_REQUIRED:`) |
688
- | `ACTION_NOT_IMPLEMENTED` | Local executor does not implement this action type |
689
- | `INVALID_INPUT` | Bad parameters, unknown chain, malformed NDJSON input, etc. |
690
- | `NETWORK_ERROR` | RPC/fetch connectivity (includes many SDK `VaultError` network cases) |
691
- | `TIMEOUT` | Deadline exceeded, or abort where the message indicates a timeout |
692
- | `TRANSACTION_FAILED` | Build/broadcast/gas errors mapped from the SDK |
693
- | `SIGNING_FAILED` | MPC/signing failed |
694
- | `SESSION_NOT_INITIALIZED` | Internal session state error |
695
- | `UNKNOWN_ERROR` | Unclassified failure (default for opaque SSE `error` events). Plain `AbortError` without “timeout” in the message maps here. |
719
+ | Code | Typical meaning |
720
+ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
721
+ | `BACKEND_UNREACHABLE` | Agent health check failed or backend not responding |
722
+ | `AUTH_FAILED` | Auth/token failure, HTTP 401/403, or wrong vault password |
723
+ | `VAULT_LOCKED` | Encrypted vault needs unlock (password) |
724
+ | `PASSWORD_REQUIRED` | Password was not supplied when required (e.g. pipe mode or signing) |
725
+ | `CONFIRMATION_REQUIRED` | User confirmation needed (pipe mode; message prefix `CONFIRMATION_REQUIRED:`) |
726
+ | `ACTION_NOT_IMPLEMENTED` | Local executor does not implement this action type |
727
+ | `INVALID_INPUT` | Bad parameters, unknown chain, malformed NDJSON input, etc. |
728
+ | `NETWORK_ERROR` | RPC/fetch connectivity (includes many SDK `VaultError` network cases) |
729
+ | `TIMEOUT` | Deadline exceeded, or abort where the message indicates a timeout |
730
+ | `TRANSACTION_FAILED` | Build/broadcast/gas errors mapped from the SDK |
731
+ | `SIGNING_FAILED` | MPC/signing failed |
732
+ | `SESSION_NOT_INITIALIZED` | Internal session state error |
733
+ | `UNKNOWN_ERROR` | Unclassified failure (default for opaque SSE `error` events). Plain `AbortError` without “timeout” in the message maps here. |
696
734
 
697
735
  SSE `error` events may optionally include a `code` field from the backend; if it matches one of the values above, it is passed through unchanged. Otherwise the CLI infers a code from the message.
698
736
 
699
737
  **Agent ask options:**
738
+
700
739
  - `--session <id>` - Continue an existing conversation
701
740
  - `--backend-url <url>` - Agent backend URL (default: https://abe.vultisig.com)
702
- - `--password <password>` - Vault password for signing
741
+ - `--password <password>` - Vault password (fallback only; prefer the keyring/`VAULT_PASSWORD` env — see **Password resolution** above)
703
742
  - `--verbose` - Show tool calls and debug info on stderr
704
743
  - `--json` - Output structured JSON
705
744
 
@@ -711,15 +750,18 @@ For interactive TUI or piped agent-to-agent communication:
711
750
  # Interactive TUI with chat interface
712
751
  vultisig agent
713
752
 
714
- # Pipe mode for agent-to-agent (NDJSON)
715
- vultisig agent --via-agent --password "$VAULT_PASSWORD"
753
+ # Pipe mode for agent-to-agent (NDJSON) — password resolved from keyring/env
754
+ vultisig agent --via-agent
716
755
  ```
717
756
 
757
+ The vault password is resolved from the keyring/env chain (`vsig auth setup` or `VAULT_PASSWORD`) the same way as `agent ask`; in `--via-agent` mode it can also be supplied over the pipe protocol (see below). `--password` remains a discouraged fallback.
758
+
718
759
  **Agent chat options:**
760
+
719
761
  - `--via-agent` - NDJSON pipe mode for agent-to-agent communication (24h password cache)
720
762
  - `--verbose` - Show detailed tool call parameters
721
763
  - `--backend-url <url>` - Agent backend URL
722
- - `--password <password>` - Vault password
764
+ - `--password <password>` - Vault password (fallback only; prefer the keyring/`VAULT_PASSWORD` env)
723
765
  - `--password-ttl <ms>` - Password cache TTL (default: 5min, 24h for `--via-agent`)
724
766
  - `--session-id <id>` - Resume an existing session
725
767
 
@@ -729,27 +771,27 @@ The pipe interface uses NDJSON (one JSON object per line) on stdin/stdout. Desig
729
771
 
730
772
  **Input commands** (send on stdin):
731
773
 
732
- | Type | Fields | Purpose |
733
- |------|--------|---------|
734
- | `message` | `content: string` | Send a natural-language message |
735
- | `confirm` | `confirmed: boolean` | Respond to a confirmation request |
736
- | `password` | `password: string` | Provide vault password when requested |
774
+ | Type | Fields | Purpose |
775
+ | ---------- | -------------------- | ------------------------------------- |
776
+ | `message` | `content: string` | Send a natural-language message |
777
+ | `confirm` | `confirmed: boolean` | Respond to a confirmation request |
778
+ | `password` | `password: string` | Provide vault password when requested |
737
779
 
738
780
  **Output events** (emitted on stdout):
739
781
 
740
- | Type | Fields | When |
741
- |------|--------|------|
742
- | `ready` | `vault, addresses` | Session initialized, addresses for all chains |
743
- | `session` | `id` | Conversation ID for resuming later |
744
- | `history` | `messages[]` | Previous messages when resuming a session |
745
- | `text_delta` | `delta` | Streaming text chunk from the agent |
746
- | `tool_call` | `id, action, params?, status` | Action started (`running`) |
747
- | `tool_result` | `id, action, success, data?, error?, code?` | Action completed (`code` when `success` is false) |
748
- | `tx_status` | `tx_hash, chain, status, explorer_url?` | Transaction broadcast/confirmed/failed |
749
- | `assistant` | `content` | Full assistant response |
750
- | `suggestions` | `suggestions[]` | Suggested follow-up actions |
751
- | `error` | `message, code` | Error or control signal (`PASSWORD_REQUIRED`, `CONFIRMATION_REQUIRED: …`; always includes stable `code`) |
752
- | `done` | `{}` | Response cycle complete |
782
+ | Type | Fields | When |
783
+ | ------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
784
+ | `ready` | `vault, addresses` | Session initialized, addresses for all chains |
785
+ | `session` | `id` | Conversation ID for resuming later |
786
+ | `history` | `messages[]` | Previous messages when resuming a session |
787
+ | `text_delta` | `delta` | Streaming text chunk from the agent |
788
+ | `tool_call` | `id, action, params?, status` | Action started (`running`) |
789
+ | `tool_result` | `id, action, success, data?, error?, code?` | Action completed (`code` when `success` is false) |
790
+ | `tx_status` | `tx_hash, chain, status, explorer_url?` | Transaction broadcast/confirmed/failed |
791
+ | `assistant` | `content` | Full assistant response |
792
+ | `suggestions` | `suggestions[]` | Suggested follow-up actions |
793
+ | `error` | `message, code` | Error or control signal (`PASSWORD_REQUIRED`, `CONFIRMATION_REQUIRED: …`; always includes stable `code`) |
794
+ | `done` | `{}` | Response cycle complete |
753
795
 
754
796
  **Example session:**
755
797
 
@@ -782,13 +824,13 @@ vultisig agent sessions delete abc123
782
824
 
783
825
  #### Agent Command Summary
784
826
 
785
- | Command | Description |
786
- |---------|-------------|
787
- | `agent ask <message>` | One-shot: send message, get response, exit |
788
- | `agent` | Interactive TUI chat interface |
789
- | `agent --via-agent` | NDJSON pipe mode for agent-to-agent |
790
- | `agent sessions list` | List chat sessions |
791
- | `agent sessions delete <id>` | Delete a session |
827
+ | Command | Description |
828
+ | ---------------------------- | ------------------------------------------ |
829
+ | `agent ask <message>` | One-shot: send message, get response, exit |
830
+ | `agent` | Interactive TUI chat interface |
831
+ | `agent --via-agent` | NDJSON pipe mode for agent-to-agent |
832
+ | `agent sessions list` | List chat sessions |
833
+ | `agent sessions delete <id>` | Delete a session |
792
834
 
793
835
  #### Environment Variables for Automation
794
836
 
@@ -808,12 +850,12 @@ VULTISIG_SILENT=1
808
850
 
809
851
  ### Settings
810
852
 
811
- | Command | Description |
812
- |---------|-------------|
813
- | `currency [code]` | View or set currency preference |
814
- | `server` | Check server connectivity |
815
- | `discount` | Show your VULT discount tier for swap fees |
816
- | `address-book` | Manage saved addresses |
853
+ | Command | Description |
854
+ | ----------------- | ------------------------------------------ |
855
+ | `currency [code]` | View or set currency preference |
856
+ | `server` | Check server connectivity |
857
+ | `discount` | Show your VULT discount tier for swap fees |
858
+ | `address-book` | Manage saved addresses |
817
859
 
818
860
  #### Discount Tiers
819
861
 
@@ -828,6 +870,7 @@ vultisig discount --refresh
828
870
  ```
829
871
 
830
872
  **Output:**
873
+
831
874
  ```text
832
875
  +----------------------------------------+
833
876
  | VULT Discount Tier |
@@ -845,41 +888,41 @@ vultisig discount --refresh
845
888
 
846
889
  **Tier levels:**
847
890
 
848
- | Tier | VULT Required | Swap Fee | Discount |
849
- |------|---------------|----------|----------|
850
- | None | 0 | 50 bps | - |
851
- | Bronze | 1,500 | 45 bps | 5 bps |
852
- | Silver | 3,000 | 40 bps | 10 bps |
853
- | Gold | 7,500 | 30 bps | 20 bps |
854
- | Platinum | 15,000 | 25 bps | 25 bps |
855
- | Diamond | 100,000 | 15 bps | 35 bps |
856
- | Ultimate | 1,000,000 | 0 bps | 50 bps |
891
+ | Tier | VULT Required | Swap Fee | Discount |
892
+ | -------- | ------------- | -------- | -------- |
893
+ | None | 0 | 50 bps | - |
894
+ | Bronze | 1,500 | 45 bps | 5 bps |
895
+ | Silver | 3,000 | 40 bps | 10 bps |
896
+ | Gold | 7,500 | 30 bps | 20 bps |
897
+ | Platinum | 15,000 | 25 bps | 25 bps |
898
+ | Diamond | 100,000 | 15 bps | 35 bps |
899
+ | Ultimate | 1,000,000 | 0 bps | 50 bps |
857
900
 
858
901
  Thorguard NFT holders receive a free tier upgrade (up to gold tier).
859
902
 
860
903
  ### CLI Management
861
904
 
862
- | Command | Description |
863
- |---------|-------------|
864
- | `version` | Show detailed version info |
865
- | `update` | Check for updates |
866
- | `completion` | Generate shell completion |
905
+ | Command | Description |
906
+ | ------------ | -------------------------- |
907
+ | `version` | Show detailed version info |
908
+ | `update` | Check for updates |
909
+ | `completion` | Generate shell completion |
867
910
 
868
911
  ### Interactive Shell Commands
869
912
 
870
- | Command | Description |
871
- |---------|-------------|
872
- | `vault <name>` | Switch to a different vault |
873
- | `vaults` | List all vaults |
874
- | `create` | Create a new vault |
875
- | `import <file>` | Import vault from file |
876
- | `delete [name]` | Delete a vault |
877
- | `lock` | Lock vault (clear cached password) |
878
- | `unlock` | Unlock vault (cache password) |
879
- | `status` | Show vault status |
880
- | `help` | Show available commands |
881
- | `.clear` | Clear the screen |
882
- | `.exit` | Exit the shell |
913
+ | Command | Description |
914
+ | --------------- | ---------------------------------- |
915
+ | `vault <name>` | Switch to a different vault |
916
+ | `vaults` | List all vaults |
917
+ | `create` | Create a new vault |
918
+ | `import <file>` | Import vault from file |
919
+ | `delete [name]` | Delete a vault |
920
+ | `lock` | Lock vault (clear cached password) |
921
+ | `unlock` | Unlock vault (cache password) |
922
+ | `status` | Show vault status |
923
+ | `help` | Show available commands |
924
+ | `.clear` | Clear the screen |
925
+ | `.exit` | Exit the shell |
883
926
 
884
927
  ## Global Options
885
928
 
@@ -920,6 +963,7 @@ Use `-o json` or `--output json` to get structured JSON output. JSON mode automa
920
963
  # Get balance as JSON
921
964
  vultisig balance ethereum -o json
922
965
  ```
966
+
923
967
  ```json
924
968
  {
925
969
  "chain": "ethereum",
@@ -935,6 +979,7 @@ vultisig balance ethereum -o json
935
979
  # Get all balances as JSON
936
980
  vultisig balance -o json
937
981
  ```
982
+
938
983
  ```json
939
984
  {
940
985
  "balances": [
@@ -948,6 +993,7 @@ vultisig balance -o json
948
993
  # Get portfolio as JSON
949
994
  vultisig portfolio -o json
950
995
  ```
996
+
951
997
  ```json
952
998
  {
953
999
  "portfolio": {
@@ -962,11 +1008,10 @@ vultisig portfolio -o json
962
1008
  # List vaults as JSON
963
1009
  vultisig vaults -o json
964
1010
  ```
1011
+
965
1012
  ```json
966
1013
  {
967
- "vaults": [
968
- { "id": "abc123", "name": "Main Wallet", "isActive": true }
969
- ],
1014
+ "vaults": [{ "id": "abc123", "name": "Main Wallet", "isActive": true }],
970
1015
  "activeVaultId": "abc123"
971
1016
  }
972
1017
  ```
@@ -975,6 +1020,7 @@ vultisig vaults -o json
975
1020
  # Get swap quote as JSON
976
1021
  vultisig swap-quote ethereum thorchain 0.1 -o json
977
1022
  ```
1023
+
978
1024
  ```json
979
1025
  {
980
1026
  "quote": {
@@ -988,6 +1034,7 @@ vultisig swap-quote ethereum thorchain 0.1 -o json
988
1034
  ```
989
1035
 
990
1036
  JSON output is ideal for:
1037
+
991
1038
  - Scripting and automation
992
1039
  - Parsing output programmatically
993
1040
  - Integration with other tools (e.g., `jq`):
@@ -1056,6 +1103,7 @@ Configuration is stored in `~/.vultisig/`:
1056
1103
  ## Supported Chains
1057
1104
 
1058
1105
  40+ blockchains including:
1106
+
1059
1107
  - **EVM**: Ethereum, Polygon, Arbitrum, Optimism, BSC, Base, Avalanche
1060
1108
  - **UTXO**: Bitcoin, Litecoin, Dogecoin, Dash, Zcash
1061
1109
  - **Cosmos**: Cosmos Hub, THORChain, Maya, Dydx, Kujira
@@ -1063,22 +1111,23 @@ Configuration is stored in `~/.vultisig/`:
1063
1111
 
1064
1112
  ## Exit Codes
1065
1113
 
1066
- | Code | Meaning |
1067
- |------|---------|
1068
- | 0 | Success |
1069
- | 1 | General error |
1070
- | 2 | Invalid usage |
1071
- | 3 | Configuration error |
1072
- | 4 | Authentication error |
1073
- | 5 | Network error |
1074
- | 6 | Vault error |
1075
- | 7 | Transaction error |
1114
+ | Code | Meaning |
1115
+ | ---- | -------------------- |
1116
+ | 0 | Success |
1117
+ | 1 | General error |
1118
+ | 2 | Invalid usage |
1119
+ | 3 | Configuration error |
1120
+ | 4 | Authentication error |
1121
+ | 5 | Network error |
1122
+ | 6 | Vault error |
1123
+ | 7 | Transaction error |
1076
1124
 
1077
1125
  ## Troubleshooting
1078
1126
 
1079
1127
  ### "No active vault" error
1080
1128
 
1081
1129
  Create or import a vault first:
1130
+
1082
1131
  ```bash
1083
1132
  vultisig create fast --name "My Wallet" --password "mypassword" --email user@example.com
1084
1133
  # or
package/dist/index.js CHANGED
@@ -5188,6 +5188,13 @@ function getCachedPassword(vaultId, vaultName) {
5188
5188
  if (passwordCache.has(vaultId)) return passwordCache.get(vaultId);
5189
5189
  return null;
5190
5190
  }
5191
+ function clearCachedPassword(vaultIdOrName) {
5192
+ if (vaultIdOrName) {
5193
+ passwordCache.delete(vaultIdOrName);
5194
+ } else {
5195
+ passwordCache.clear();
5196
+ }
5197
+ }
5191
5198
  function parseVaultPasswords() {
5192
5199
  const passwordMap = /* @__PURE__ */ new Map();
5193
5200
  const passwordsEnv = process.env.VAULT_PASSWORDS;
@@ -5232,7 +5239,7 @@ async function promptForPassword(vaultName, vaultId) {
5232
5239
  ]);
5233
5240
  return password;
5234
5241
  }
5235
- async function getPassword(vaultId, vaultName) {
5242
+ async function resolvePasswordNonInteractive(vaultId, vaultName) {
5236
5243
  const cachedPassword = getCachedPassword(vaultId, vaultName);
5237
5244
  if (cachedPassword) {
5238
5245
  return cachedPassword;
@@ -5252,6 +5259,13 @@ async function getPassword(vaultId, vaultName) {
5252
5259
  if (vaultName) cachePassword(vaultName, envPassword);
5253
5260
  return envPassword;
5254
5261
  }
5262
+ return null;
5263
+ }
5264
+ async function getPassword(vaultId, vaultName) {
5265
+ const resolved = await resolvePasswordNonInteractive(vaultId, vaultName);
5266
+ if (resolved) {
5267
+ return resolved;
5268
+ }
5255
5269
  if (isSilent() || isJsonOutput() || isNonInteractive()) {
5256
5270
  throw new Error(
5257
5271
  "Password required but not provided. Set VAULT_PASSWORD or VAULT_PASSWORDS environment variable, or use --password flag."
@@ -12163,6 +12177,66 @@ var AgentSession = class {
12163
12177
  this.executor.setPassword(config.password);
12164
12178
  }
12165
12179
  }
12180
+ /**
12181
+ * Unlock the vault before auth when it's encrypted. Resolve the password from
12182
+ * the keyring/env chain (in-memory cache → OS keyring → VAULT_PASSWORDS/
12183
+ * VAULT_PASSWORD env) BEFORE prompting, so a headless operator who set up the
12184
+ * keyring or env never has to put a funds-controlling secret on argv. argv
12185
+ * `--password` (config.password) still works but is de-emphasized: it lands
12186
+ * the secret in `ps`/shell history, so its use warns. Only when the chain
12187
+ * resolves nothing do we fall back to the mode's own interactive prompt (TUI
12188
+ * readline / via-agent protocol; ask-mode throws). A stale stored password is
12189
+ * cleared and re-prompted in interactive modes rather than stranding init.
12190
+ */
12191
+ async unlockEncryptedVault(ui) {
12192
+ if (!this.vault.isEncrypted) {
12193
+ return;
12194
+ }
12195
+ let password;
12196
+ let fromStoredChain = false;
12197
+ if (this.config.password) {
12198
+ process.stderr.write(
12199
+ "Warning: passing the vault password via --password exposes it to `ps` and shell history. Prefer the OS keyring (`vsig auth setup`) or the VAULT_PASSWORD env var.\n"
12200
+ );
12201
+ password = this.config.password;
12202
+ } else {
12203
+ const resolved = await resolvePasswordNonInteractive(this.vault.id, this.vault.name);
12204
+ if (resolved !== null) {
12205
+ password = resolved;
12206
+ fromStoredChain = true;
12207
+ } else {
12208
+ password = await ui.requestPassword();
12209
+ }
12210
+ }
12211
+ try {
12212
+ await this.vault.unlock?.(password);
12213
+ } catch (unlockErr) {
12214
+ if (!fromStoredChain) throw unlockErr;
12215
+ password = await this.recoverFromStaleStoredPassword(ui);
12216
+ }
12217
+ this.executor.setPassword(password);
12218
+ }
12219
+ /**
12220
+ * The stored (keyring/env) password was rejected by unlock. Drop it so it
12221
+ * isn't reused, then recover: ask mode has no interactive prompt (its
12222
+ * requestPassword throws the misleading "use --password flag"), so surface the
12223
+ * real cause; interactive modes (TUI / via-agent) re-prompt once and cache the
12224
+ * winner. Returns the password that successfully unlocked the vault.
12225
+ */
12226
+ async recoverFromStaleStoredPassword(ui) {
12227
+ clearCachedPassword(this.vault.id);
12228
+ if (this.vault.name) clearCachedPassword(this.vault.name);
12229
+ if (this.config.askMode) {
12230
+ throw new Error(
12231
+ `Stored vault password (keyring/env) was rejected for "${this.vault.name || this.vault.id}". Update it with \`vsig auth setup\` or the VAULT_PASSWORD env var, or pass --password.`
12232
+ );
12233
+ }
12234
+ const password = await ui.requestPassword();
12235
+ await this.vault.unlock?.(password);
12236
+ cachePassword(this.vault.id, password);
12237
+ if (this.vault.name) cachePassword(this.vault.name, password);
12238
+ return password;
12239
+ }
12166
12240
  /**
12167
12241
  * Initialize the session: health check, authenticate, create conversation.
12168
12242
  */
@@ -12172,11 +12246,7 @@ var AgentSession = class {
12172
12246
  throw new Error(`Agent backend unreachable at ${this.config.backendUrl}`);
12173
12247
  }
12174
12248
  try {
12175
- if (this.vault.isEncrypted) {
12176
- const password = this.config.password || await ui.requestPassword();
12177
- await this.vault.unlock?.(password);
12178
- this.executor.setPassword(password);
12179
- }
12249
+ await this.unlockEncryptedVault(ui);
12180
12250
  const cached = loadCachedToken(this.publicKey);
12181
12251
  if (cached) {
12182
12252
  this.client.setAuthToken(cached);
@@ -13459,7 +13529,7 @@ var cachedVersion = null;
13459
13529
  function getVersion() {
13460
13530
  if (cachedVersion) return cachedVersion;
13461
13531
  if (true) {
13462
- cachedVersion = "2.10.0";
13532
+ cachedVersion = "2.11.0";
13463
13533
  return cachedVersion;
13464
13534
  }
13465
13535
  try {
@@ -16152,7 +16222,10 @@ rujiraCmd.command("withdraw <asset> <amount> <l1Address>").description("Withdraw
16152
16222
  }
16153
16223
  )
16154
16224
  );
16155
- var agentCmd = program.command("agent").description("AI-powered chat interface for wallet operations").option("--via-agent", "Use NDJSON pipe mode for agent-to-agent communication").option("--verbose", "Show detailed tool call parameters and debug output").option("--backend-url <url>", "Agent backend URL (default: https://abe.vultisig.com)").option("--password <password>", "Vault password for signing operations").option("--password-ttl <ms>", "Password cache TTL in milliseconds (default: 300000, 86400000/24h for --via-agent)").option("--session-id <id>", "Resume an existing session").option("--notification-url <url>", "Notification service URL for push notifications").option("--profile <api_id>", "Billing profile slug sent as X-Vultisig-Abe-Profile header").action(
16225
+ var agentCmd = program.command("agent").description("AI-powered chat interface for wallet operations").option("--via-agent", "Use NDJSON pipe mode for agent-to-agent communication").option("--verbose", "Show detailed tool call parameters and debug output").option("--backend-url <url>", "Agent backend URL (default: https://abe.vultisig.com)").option(
16226
+ "--password <password>",
16227
+ "Vault password (fallback; prefer the OS keyring via `vsig auth setup` or the VAULT_PASSWORD env var \u2014 --password is exposed to `ps`/shell history)"
16228
+ ).option("--password-ttl <ms>", "Password cache TTL in milliseconds (default: 300000, 86400000/24h for --via-agent)").option("--session-id <id>", "Resume an existing session").option("--notification-url <url>", "Notification service URL for push notifications").option("--profile <api_id>", "Billing profile slug sent as X-Vultisig-Abe-Profile header").action(
16156
16229
  async (options) => {
16157
16230
  const MAX_TTL = 864e5;
16158
16231
  let passwordTTL;
@@ -16179,7 +16252,10 @@ var agentCmd = program.command("agent").description("AI-powered chat interface f
16179
16252
  });
16180
16253
  }
16181
16254
  );
16182
- agentCmd.command("ask <message>").description("Send a single message and get the response (for AI agent integration)").option("--session <id>", "Continue an existing conversation").option("--backend-url <url>", "Agent backend URL (default: https://abe.vultisig.com)").option("--password <password>", "Vault password for signing operations").option("--verbose", "Show tool calls and debug info on stderr").option("--json", "Output structured JSON (deprecated: use --output json)").option("--profile <api_id>", "Billing profile slug sent as X-Vultisig-Abe-Profile header").option(
16255
+ agentCmd.command("ask <message>").description("Send a single message and get the response (for AI agent integration)").option("--session <id>", "Continue an existing conversation").option("--backend-url <url>", "Agent backend URL (default: https://abe.vultisig.com)").option(
16256
+ "--password <password>",
16257
+ "Vault password (fallback; prefer the OS keyring via `vsig auth setup` or the VAULT_PASSWORD env var \u2014 --password is exposed to `ps`/shell history)"
16258
+ ).option("--verbose", "Show tool calls and debug info on stderr").option("--json", "Output structured JSON (deprecated: use --output json)").option("--profile <api_id>", "Billing profile slug sent as X-Vultisig-Abe-Profile header").option(
16183
16259
  "--yes",
16184
16260
  "Auto-approve signing/broadcast. Required for unattended signing; default is to NOT broadcast and report the proposed transaction instead."
16185
16261
  ).addHelpText(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/cli",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "The self-custody MPC wallet CLI for AI coding agents (Claude Code, Cursor, OpenCode). Natural-language agent mode, 36+ chains, DKLS23 threshold signatures. Seedless.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -74,9 +74,9 @@
74
74
  "@napi-rs/keyring": "^1.3.0",
75
75
  "@noble/hashes": "^2.2.0",
76
76
  "@vultisig/client-shared": "^0.2.17",
77
- "@vultisig/core-chain": "^2.19.0",
78
- "@vultisig/rujira": "^43.0.0",
79
- "@vultisig/sdk": "^2.10.0",
77
+ "@vultisig/core-chain": "^2.20.0",
78
+ "@vultisig/rujira": "^44.0.0",
79
+ "@vultisig/sdk": "^2.11.0",
80
80
  "chalk": "^5.6.2",
81
81
  "cli-table3": "^0.6.5",
82
82
  "commander": "^15.0.0",