@vultisig/cli 0.7.0 → 0.8.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 (3) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/index.js +317 -162
  3. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @vultisig/cli
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#127](https://github.com/vultisig/vultisig-sdk/pull/127) [`073ca14`](https://github.com/vultisig/vultisig-sdk/commit/073ca141f78fe47af857c70b2f555f50210e4916) Thanks [@RaghavSood](https://github.com/RaghavSood)! - Add agent session management: `vultisig agent sessions list` and `vultisig agent sessions delete <id>`. Display session ID and conversation history when resuming sessions with `--session-id`. Replace `--conversation` flag with `--session-id`.
8
+
9
+ - [#125](https://github.com/vultisig/vultisig-sdk/pull/125) [`7677523`](https://github.com/vultisig/vultisig-sdk/commit/76775232866dccf4e1e85aa0fe0d91c2fd8fdddb) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Use production notification API base path `/notification` (aligned with iOS), extend `PushNotificationService` for web device registration and WebSocket flows, export `computeNotificationVaultId`, add notification mock E2E tests, and ship a `live-web-push-e2e` harness for browser Web Push verification.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [[`da88c6f`](https://github.com/vultisig/vultisig-sdk/commit/da88c6f06b8d74ccb5642f793e386d85ff6f30b1), [`4b29636`](https://github.com/vultisig/vultisig-sdk/commit/4b29636514edccf0980eddf5e8fffacfcb31c88f), [`7677523`](https://github.com/vultisig/vultisig-sdk/commit/76775232866dccf4e1e85aa0fe0d91c2fd8fdddb)]:
14
+ - @vultisig/sdk@0.8.0
15
+ - @vultisig/rujira@4.0.0
16
+
3
17
  ## 0.7.0
4
18
 
5
19
  ### Minor Changes
package/dist/index.js CHANGED
@@ -1434,7 +1434,7 @@ var init_sha3 = __esm({
1434
1434
  import "dotenv/config";
1435
1435
  import { promises as fs3 } from "node:fs";
1436
1436
  import { parseKeygenQR, Vultisig as Vultisig7 } from "@vultisig/sdk";
1437
- import chalk14 from "chalk";
1437
+ import chalk15 from "chalk";
1438
1438
  import { program } from "commander";
1439
1439
  import inquirer8 from "inquirer";
1440
1440
 
@@ -4097,6 +4097,10 @@ function displayDiscountTier(tierInfo) {
4097
4097
  printResult("");
4098
4098
  }
4099
4099
 
4100
+ // src/commands/agent.ts
4101
+ import chalk9 from "chalk";
4102
+ import Table from "cli-table3";
4103
+
4100
4104
  // src/agent/auth.ts
4101
4105
  init_sha3();
4102
4106
  import { randomBytes } from "node:crypto";
@@ -4581,6 +4585,7 @@ var AgentExecutor = class {
4581
4585
  return;
4582
4586
  }
4583
4587
  const chain = resolveChainFromTxReady(txReadyData) || Chain9.Ethereum;
4588
+ this.pendingPayloads.clear();
4584
4589
  this.pendingPayloads.set("latest", {
4585
4590
  payload: { __serverTx: true, ...txReadyData },
4586
4591
  coin: { chain, address: "", decimals: 18, ticker: "" },
@@ -4798,6 +4803,7 @@ var AgentExecutor = class {
4798
4803
  const amount = parseAmount(amountStr, balance.decimals);
4799
4804
  const memo = params.memo;
4800
4805
  const payload = await this.vault.prepareSendTx({ coin, receiver: toAddress, amount, memo });
4806
+ this.pendingPayloads.clear();
4801
4807
  const payloadId = `tx_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
4802
4808
  this.pendingPayloads.set(payloadId, { payload, coin, chain, timestamp: Date.now() });
4803
4809
  this.pendingPayloads.set("latest", { payload, coin, chain, timestamp: Date.now() });
@@ -4849,6 +4855,7 @@ var AgentExecutor = class {
4849
4855
  });
4850
4856
  const chain = fromChain;
4851
4857
  const payload = swapResult.keysignPayload;
4858
+ this.pendingPayloads.clear();
4852
4859
  const payloadId = `swap_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
4853
4860
  this.pendingPayloads.set(payloadId, { payload, coin: { chain, address: "", decimals: 18, ticker: fromSymbol }, chain, timestamp: Date.now() });
4854
4861
  this.pendingPayloads.set("latest", { payload, coin: { chain, address: "", decimals: 18, ticker: fromSymbol }, chain, timestamp: Date.now() });
@@ -4951,7 +4958,7 @@ var AgentExecutor = class {
4951
4958
  /**
4952
4959
  * Sign and broadcast an SDK-built transaction (keysign payload from local build methods).
4953
4960
  */
4954
- async signSdkTx(payload, chain, payloadId) {
4961
+ async signSdkTx(payload, chain, _payloadId) {
4955
4962
  if (this.vault.isEncrypted && !this.vault.isUnlocked?.()) {
4956
4963
  if (this.password) {
4957
4964
  await this.vault.unlock?.(this.password);
@@ -4971,10 +4978,7 @@ var AgentExecutor = class {
4971
4978
  keysignPayload: payload,
4972
4979
  signature
4973
4980
  });
4974
- this.pendingPayloads.delete(payloadId);
4975
- if (payloadId !== "latest") {
4976
- this.pendingPayloads.delete("latest");
4977
- }
4981
+ this.pendingPayloads.clear();
4978
4982
  const explorerUrl = Vultisig6.getTxExplorerUrl(chain, txHash);
4979
4983
  return {
4980
4984
  tx_hash: txHash,
@@ -5042,7 +5046,7 @@ var AgentExecutor = class {
5042
5046
  keysignPayload,
5043
5047
  signature
5044
5048
  });
5045
- this.pendingPayloads.delete("latest");
5049
+ this.pendingPayloads.clear();
5046
5050
  const explorerUrl = Vultisig6.getTxExplorerUrl(chain, txHash);
5047
5051
  return {
5048
5052
  tx_hash: txHash,
@@ -5491,6 +5495,17 @@ var PipeInterface = class {
5491
5495
  terminal: false
5492
5496
  });
5493
5497
  this.emit({ type: "ready", vault: vaultName, addresses });
5498
+ const sessionId = this.session.getConversationId();
5499
+ if (sessionId) {
5500
+ this.emit({ type: "session", id: sessionId });
5501
+ }
5502
+ const history = this.session.getHistoryMessages();
5503
+ if (history.length > 0) {
5504
+ this.emit({
5505
+ type: "history",
5506
+ messages: history.filter((m) => m.content_type !== "action_result").map((m) => ({ role: m.role, content: m.content, created_at: m.created_at }))
5507
+ });
5508
+ }
5494
5509
  const lines = [];
5495
5510
  let inputDone = false;
5496
5511
  let processing = false;
@@ -5633,6 +5648,7 @@ var AgentSession = class {
5633
5648
  publicKey;
5634
5649
  cachedContext = null;
5635
5650
  abortController = null;
5651
+ historyMessages = [];
5636
5652
  constructor(vault, config) {
5637
5653
  this.vault = vault;
5638
5654
  this.config = config;
@@ -5669,8 +5685,26 @@ var AgentSession = class {
5669
5685
  } catch (err) {
5670
5686
  throw new Error(`Authentication failed: ${err.message}`);
5671
5687
  }
5672
- if (this.config.conversationId) {
5673
- this.conversationId = this.config.conversationId;
5688
+ if (this.config.sessionId) {
5689
+ this.conversationId = this.config.sessionId;
5690
+ try {
5691
+ const conv = await this.client.getConversation(this.conversationId, this.publicKey);
5692
+ this.historyMessages = conv.messages || [];
5693
+ } catch (err) {
5694
+ if (err.message?.includes("401") || err.message?.includes("403")) {
5695
+ clearCachedToken(this.publicKey);
5696
+ const auth = await authenticateVault(this.client, this.vault, this.config.password);
5697
+ this.client.setAuthToken(auth.token);
5698
+ saveCachedToken(this.publicKey, auth.token, auth.expiresAt);
5699
+ const conv = await this.client.getConversation(this.conversationId, this.publicKey);
5700
+ this.historyMessages = conv.messages || [];
5701
+ } else {
5702
+ this.conversationId = null;
5703
+ this.historyMessages = [];
5704
+ const conv = await this.client.createConversation(this.publicKey);
5705
+ this.conversationId = conv.id;
5706
+ }
5707
+ }
5674
5708
  } else {
5675
5709
  const conv = await this.client.createConversation(this.publicKey);
5676
5710
  this.conversationId = conv.id;
@@ -5680,6 +5714,9 @@ var AgentSession = class {
5680
5714
  getConversationId() {
5681
5715
  return this.conversationId;
5682
5716
  }
5717
+ getHistoryMessages() {
5718
+ return this.historyMessages;
5719
+ }
5683
5720
  getVaultAddresses() {
5684
5721
  return this.cachedContext?.addresses || {};
5685
5722
  }
@@ -5785,15 +5822,14 @@ var AgentSession = class {
5785
5822
  } else if (responseText) {
5786
5823
  ui.onAssistantMessage(responseText);
5787
5824
  }
5788
- const nonSignActions = streamResult.actions.filter((a) => a.type !== "sign_tx");
5789
- const backendSignActions = streamResult.actions.filter((a) => a.type === "sign_tx");
5790
- if (nonSignActions.length > 0) {
5791
- const results = await this.executeActions(nonSignActions, ui);
5825
+ const actions = streamResult.actions.filter((a) => a.type !== "sign_tx");
5826
+ if (actions.length > 0) {
5827
+ const results = await this.executeActions(actions, ui);
5792
5828
  const hasBuildSuccess = results.some(
5793
5829
  (r) => r.success && r.action.startsWith("build_")
5794
5830
  );
5795
5831
  if (hasBuildSuccess && this.executor.hasPendingTransaction()) {
5796
- if (this.config.verbose) process.stderr.write(`[session] build_* action produced pending tx, auto-chaining sign_tx
5832
+ if (this.config.verbose) process.stderr.write(`[session] build_* action produced pending tx, auto-signing client-side
5797
5833
  `);
5798
5834
  const signAction = {
5799
5835
  id: `tx_sign_${Date.now()}`,
@@ -5803,11 +5839,11 @@ var AgentSession = class {
5803
5839
  auto_execute: true
5804
5840
  };
5805
5841
  const signResults = await this.executeActions([signAction], ui);
5806
- const allResults = [...results, ...signResults];
5807
- for (const result of allResults) {
5808
- await this.processMessageLoop(null, [result], ui);
5842
+ const signResult = signResults[0];
5843
+ if (signResult) {
5844
+ await this.processMessageLoop(null, [signResult], ui);
5845
+ return;
5809
5846
  }
5810
- return;
5811
5847
  }
5812
5848
  if (results.length > 0) {
5813
5849
  for (const result of results) {
@@ -5833,27 +5869,6 @@ var AgentSession = class {
5833
5869
  }
5834
5870
  return;
5835
5871
  }
5836
- } else if (backendSignActions.length > 0 && this.executor.hasPendingTransaction()) {
5837
- if (this.config.verbose) process.stderr.write(`[session] Backend sent sign_tx action, using it
5838
- `);
5839
- const results = await this.executeActions(backendSignActions, ui);
5840
- if (results.length > 0) {
5841
- for (const result of results) {
5842
- await this.processMessageLoop(null, [result], ui);
5843
- }
5844
- return;
5845
- }
5846
- } else if (backendSignActions.length > 0 && !this.executor.hasPendingTransaction()) {
5847
- if (this.config.verbose) process.stderr.write(`[session] Backend sent sign_tx but no pending tx, reporting error
5848
- `);
5849
- const errorResult = {
5850
- action: "sign_tx",
5851
- action_id: backendSignActions[0].id,
5852
- success: false,
5853
- error: "No pending transaction. The swap transaction data was not received."
5854
- };
5855
- await this.processMessageLoop(null, [errorResult], ui);
5856
- return;
5857
5872
  }
5858
5873
  ui.onDone();
5859
5874
  }
@@ -5911,6 +5926,7 @@ var AgentSession = class {
5911
5926
  this.cancel();
5912
5927
  this.cachedContext = null;
5913
5928
  this.conversationId = null;
5929
+ this.historyMessages = [];
5914
5930
  }
5915
5931
  };
5916
5932
  function parseInlineToolCalls(text) {
@@ -6021,6 +6037,15 @@ var ChatTUI = class {
6021
6037
  */
6022
6038
  async start() {
6023
6039
  this.printHeader();
6040
+ const sessionId = this.session.getConversationId();
6041
+ if (sessionId) {
6042
+ console.log(chalk8.gray(` Session: ${sessionId}`));
6043
+ console.log("");
6044
+ }
6045
+ const history = this.session.getHistoryMessages();
6046
+ if (history.length > 0) {
6047
+ this.printHistory(history);
6048
+ }
6024
6049
  this.printHelp();
6025
6050
  this.showPrompt();
6026
6051
  this.rl.on("line", async (line) => {
@@ -6229,6 +6254,30 @@ var ChatTUI = class {
6229
6254
  console.log(chalk8.bold.cyan(` \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`));
6230
6255
  console.log("");
6231
6256
  }
6257
+ printHistory(messages) {
6258
+ console.log(chalk8.gray(" \u2500\u2500 Session History \u2500\u2500"));
6259
+ console.log("");
6260
+ for (const msg of messages) {
6261
+ if (msg.content_type === "action_result") continue;
6262
+ const ts = this.formatHistoryTimestamp(msg.created_at);
6263
+ if (msg.role === "user") {
6264
+ console.log(`${chalk8.gray(ts)} ${chalk8.green.bold("You")}: ${msg.content}`);
6265
+ } else if (msg.role === "assistant") {
6266
+ console.log(`${chalk8.gray(ts)} ${chalk8.cyan.bold("Agent")}: ${renderMarkdown(msg.content)}`);
6267
+ }
6268
+ }
6269
+ console.log("");
6270
+ console.log(chalk8.gray(" \u2500\u2500 End of History \u2500\u2500"));
6271
+ console.log("");
6272
+ }
6273
+ formatHistoryTimestamp(iso) {
6274
+ try {
6275
+ const d = new Date(iso);
6276
+ return `[${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}]`;
6277
+ } catch {
6278
+ return "[--:--:--]";
6279
+ }
6280
+ }
6232
6281
  printHelp() {
6233
6282
  console.log(chalk8.gray(" Commands: /help, /clear, /quit"));
6234
6283
  console.log(chalk8.gray(" Press Ctrl+C to cancel a response, or to exit"));
@@ -6277,7 +6326,7 @@ async function executeAgent(ctx2, options) {
6277
6326
  vaultName: vault.name,
6278
6327
  password: options.password,
6279
6328
  viaAgent: options.viaAgent,
6280
- conversationId: options.conversationId,
6329
+ sessionId: options.sessionId,
6281
6330
  verbose: options.verbose
6282
6331
  };
6283
6332
  const session = new AgentSession(vault, config);
@@ -6304,6 +6353,79 @@ async function executeAgent(ctx2, options) {
6304
6353
  }
6305
6354
  }
6306
6355
  }
6356
+ async function executeAgentSessionsList(ctx2, options) {
6357
+ const vault = await ctx2.ensureActiveVault();
6358
+ const backendUrl = options.backendUrl || process.env.VULTISIG_AGENT_URL || "http://localhost:9998";
6359
+ const client = await createAuthenticatedClient(backendUrl, vault, options.password);
6360
+ const publicKey = vault.publicKeys.ecdsa;
6361
+ const PAGE_SIZE = 100;
6362
+ const allConversations = [];
6363
+ let totalCount = 0;
6364
+ let skip = 0;
6365
+ while (true) {
6366
+ const page = await client.listConversations(publicKey, skip, PAGE_SIZE);
6367
+ totalCount = page.total_count;
6368
+ allConversations.push(...page.conversations);
6369
+ if (allConversations.length >= totalCount || page.conversations.length < PAGE_SIZE) break;
6370
+ skip += PAGE_SIZE;
6371
+ }
6372
+ if (isJsonOutput()) {
6373
+ outputJson({
6374
+ sessions: allConversations.map((c) => ({
6375
+ id: c.id,
6376
+ title: c.title,
6377
+ created_at: c.created_at,
6378
+ updated_at: c.updated_at
6379
+ })),
6380
+ total_count: totalCount
6381
+ });
6382
+ return;
6383
+ }
6384
+ if (allConversations.length === 0) {
6385
+ printResult("No sessions found.");
6386
+ return;
6387
+ }
6388
+ const table = new Table({
6389
+ head: [chalk9.cyan("ID"), chalk9.cyan("Title"), chalk9.cyan("Created"), chalk9.cyan("Updated")]
6390
+ });
6391
+ for (const conv of allConversations) {
6392
+ table.push([
6393
+ conv.id,
6394
+ conv.title || chalk9.gray("(untitled)"),
6395
+ formatDate(conv.created_at),
6396
+ formatDate(conv.updated_at)
6397
+ ]);
6398
+ }
6399
+ printResult(table.toString());
6400
+ printResult(chalk9.gray(`
6401
+ ${totalCount} session(s) total`));
6402
+ }
6403
+ async function executeAgentSessionsDelete(ctx2, sessionId, options) {
6404
+ const vault = await ctx2.ensureActiveVault();
6405
+ const backendUrl = options.backendUrl || process.env.VULTISIG_AGENT_URL || "http://localhost:9998";
6406
+ const client = await createAuthenticatedClient(backendUrl, vault, options.password);
6407
+ const publicKey = vault.publicKeys.ecdsa;
6408
+ await client.deleteConversation(sessionId, publicKey);
6409
+ if (isJsonOutput()) {
6410
+ outputJson({ deleted: sessionId });
6411
+ return;
6412
+ }
6413
+ printResult(chalk9.green(`Session ${sessionId} deleted.`));
6414
+ }
6415
+ async function createAuthenticatedClient(backendUrl, vault, password) {
6416
+ const client = new AgentClient(backendUrl);
6417
+ const auth = await authenticateVault(client, vault, password);
6418
+ client.setAuthToken(auth.token);
6419
+ return client;
6420
+ }
6421
+ function formatDate(iso) {
6422
+ try {
6423
+ const d = new Date(iso);
6424
+ return d.toLocaleDateString() + " " + d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
6425
+ } catch {
6426
+ return iso;
6427
+ }
6428
+ }
6307
6429
 
6308
6430
  // src/interactive/completer.ts
6309
6431
  import { Chain as Chain10 } from "@vultisig/sdk";
@@ -6465,7 +6587,7 @@ function findChainByName(name) {
6465
6587
  }
6466
6588
 
6467
6589
  // src/interactive/event-buffer.ts
6468
- import chalk9 from "chalk";
6590
+ import chalk10 from "chalk";
6469
6591
  var EventBuffer = class {
6470
6592
  eventBuffer = [];
6471
6593
  isCommandRunning = false;
@@ -6505,17 +6627,17 @@ var EventBuffer = class {
6505
6627
  displayEvent(message, type) {
6506
6628
  switch (type) {
6507
6629
  case "success":
6508
- console.log(chalk9.green(message));
6630
+ console.log(chalk10.green(message));
6509
6631
  break;
6510
6632
  case "warning":
6511
- console.log(chalk9.yellow(message));
6633
+ console.log(chalk10.yellow(message));
6512
6634
  break;
6513
6635
  case "error":
6514
- console.error(chalk9.red(message));
6636
+ console.error(chalk10.red(message));
6515
6637
  break;
6516
6638
  case "info":
6517
6639
  default:
6518
- console.log(chalk9.blue(message));
6640
+ console.log(chalk10.blue(message));
6519
6641
  break;
6520
6642
  }
6521
6643
  }
@@ -6526,13 +6648,13 @@ var EventBuffer = class {
6526
6648
  if (this.eventBuffer.length === 0) {
6527
6649
  return;
6528
6650
  }
6529
- console.log(chalk9.gray("\n--- Background Events ---"));
6651
+ console.log(chalk10.gray("\n--- Background Events ---"));
6530
6652
  this.eventBuffer.forEach((event) => {
6531
6653
  const timeStr = event.timestamp.toLocaleTimeString();
6532
6654
  const message = `[${timeStr}] ${event.message}`;
6533
6655
  this.displayEvent(message, event.type);
6534
6656
  });
6535
- console.log(chalk9.gray("--- End Events ---\n"));
6657
+ console.log(chalk10.gray("--- End Events ---\n"));
6536
6658
  }
6537
6659
  /**
6538
6660
  * Setup all vault event listeners
@@ -6642,13 +6764,13 @@ var EventBuffer = class {
6642
6764
 
6643
6765
  // src/interactive/session.ts
6644
6766
  import { fiatCurrencies as fiatCurrencies3 } from "@vultisig/sdk";
6645
- import chalk11 from "chalk";
6767
+ import chalk12 from "chalk";
6646
6768
  import ora3 from "ora";
6647
6769
  import * as readline3 from "readline";
6648
6770
 
6649
6771
  // src/interactive/shell-commands.ts
6650
- import chalk10 from "chalk";
6651
- import Table from "cli-table3";
6772
+ import chalk11 from "chalk";
6773
+ import Table2 from "cli-table3";
6652
6774
  import inquirer6 from "inquirer";
6653
6775
  import ora2 from "ora";
6654
6776
  function formatTimeRemaining(ms) {
@@ -6664,25 +6786,25 @@ function formatTimeRemaining(ms) {
6664
6786
  async function executeLock(ctx2) {
6665
6787
  const vault = ctx2.getActiveVault();
6666
6788
  if (!vault) {
6667
- console.log(chalk10.red("No active vault."));
6668
- console.log(chalk10.yellow('Use "vault <name>" to switch to a vault first.'));
6789
+ console.log(chalk11.red("No active vault."));
6790
+ console.log(chalk11.yellow('Use "vault <name>" to switch to a vault first.'));
6669
6791
  return;
6670
6792
  }
6671
6793
  ctx2.lockVault(vault.id);
6672
- console.log(chalk10.green("\n+ Vault locked"));
6673
- console.log(chalk10.gray("Password cache cleared. You will need to enter the password again."));
6794
+ console.log(chalk11.green("\n+ Vault locked"));
6795
+ console.log(chalk11.gray("Password cache cleared. You will need to enter the password again."));
6674
6796
  }
6675
6797
  async function executeUnlock(ctx2) {
6676
6798
  const vault = ctx2.getActiveVault();
6677
6799
  if (!vault) {
6678
- console.log(chalk10.red("No active vault."));
6679
- console.log(chalk10.yellow('Use "vault <name>" to switch to a vault first.'));
6800
+ console.log(chalk11.red("No active vault."));
6801
+ console.log(chalk11.yellow('Use "vault <name>" to switch to a vault first.'));
6680
6802
  return;
6681
6803
  }
6682
6804
  if (ctx2.isVaultUnlocked(vault.id)) {
6683
6805
  const timeRemaining = ctx2.getUnlockTimeRemaining(vault.id);
6684
- console.log(chalk10.yellow("\nVault is already unlocked."));
6685
- console.log(chalk10.gray(`Time remaining: ${formatTimeRemaining(timeRemaining)}`));
6806
+ console.log(chalk11.yellow("\nVault is already unlocked."));
6807
+ console.log(chalk11.gray(`Time remaining: ${formatTimeRemaining(timeRemaining)}`));
6686
6808
  return;
6687
6809
  }
6688
6810
  const { password } = await inquirer6.prompt([
@@ -6699,19 +6821,19 @@ async function executeUnlock(ctx2) {
6699
6821
  ctx2.cachePassword(vault.id, password);
6700
6822
  const timeRemaining = ctx2.getUnlockTimeRemaining(vault.id);
6701
6823
  spinner.succeed("Vault unlocked");
6702
- console.log(chalk10.green(`
6824
+ console.log(chalk11.green(`
6703
6825
  + Vault unlocked for ${formatTimeRemaining(timeRemaining)}`));
6704
6826
  } catch (err) {
6705
6827
  spinner.fail("Failed to unlock vault");
6706
- console.error(chalk10.red(`
6828
+ console.error(chalk11.red(`
6707
6829
  x ${err.message}`));
6708
6830
  }
6709
6831
  }
6710
6832
  async function executeStatus(ctx2) {
6711
6833
  const vault = ctx2.getActiveVault();
6712
6834
  if (!vault) {
6713
- console.log(chalk10.red("No active vault."));
6714
- console.log(chalk10.yellow('Use "vault <name>" to switch to a vault first.'));
6835
+ console.log(chalk11.red("No active vault."));
6836
+ console.log(chalk11.yellow('Use "vault <name>" to switch to a vault first.'));
6715
6837
  return;
6716
6838
  }
6717
6839
  const isUnlocked = ctx2.isVaultUnlocked(vault.id);
@@ -6742,30 +6864,30 @@ async function executeStatus(ctx2) {
6742
6864
  displayStatus(status);
6743
6865
  }
6744
6866
  function displayStatus(status) {
6745
- console.log(chalk10.cyan("\n+----------------------------------------+"));
6746
- console.log(chalk10.cyan("| Vault Status |"));
6747
- console.log(chalk10.cyan("+----------------------------------------+\n"));
6748
- console.log(chalk10.bold("Vault:"));
6749
- console.log(` Name: ${chalk10.green(status.name)}`);
6867
+ console.log(chalk11.cyan("\n+----------------------------------------+"));
6868
+ console.log(chalk11.cyan("| Vault Status |"));
6869
+ console.log(chalk11.cyan("+----------------------------------------+\n"));
6870
+ console.log(chalk11.bold("Vault:"));
6871
+ console.log(` Name: ${chalk11.green(status.name)}`);
6750
6872
  console.log(` ID: ${status.id}`);
6751
- console.log(` Type: ${chalk10.yellow(status.type)}`);
6752
- console.log(chalk10.bold("\nSecurity:"));
6873
+ console.log(` Type: ${chalk11.yellow(status.type)}`);
6874
+ console.log(chalk11.bold("\nSecurity:"));
6753
6875
  if (status.isUnlocked) {
6754
- console.log(` Status: ${chalk10.green("Unlocked")} ${chalk10.green("\u{1F513}")}`);
6876
+ console.log(` Status: ${chalk11.green("Unlocked")} ${chalk11.green("\u{1F513}")}`);
6755
6877
  console.log(` Expires: ${status.timeRemainingFormatted}`);
6756
6878
  } else {
6757
- console.log(` Status: ${chalk10.yellow("Locked")} ${chalk10.yellow("\u{1F512}")}`);
6879
+ console.log(` Status: ${chalk11.yellow("Locked")} ${chalk11.yellow("\u{1F512}")}`);
6758
6880
  }
6759
- console.log(` Encrypted: ${status.isEncrypted ? chalk10.green("Yes") : chalk10.gray("No")}`);
6760
- console.log(` Backed Up: ${status.isBackedUp ? chalk10.green("Yes") : chalk10.yellow("No")}`);
6761
- console.log(chalk10.bold("\nMPC Configuration:"));
6881
+ console.log(` Encrypted: ${status.isEncrypted ? chalk11.green("Yes") : chalk11.gray("No")}`);
6882
+ console.log(` Backed Up: ${status.isBackedUp ? chalk11.green("Yes") : chalk11.yellow("No")}`);
6883
+ console.log(chalk11.bold("\nMPC Configuration:"));
6762
6884
  console.log(` Library: ${status.libType}`);
6763
- console.log(` Threshold: ${chalk10.cyan(status.threshold)} of ${chalk10.cyan(status.totalSigners)}`);
6764
- console.log(chalk10.bold("\nSigning Modes:"));
6885
+ console.log(` Threshold: ${chalk11.cyan(status.threshold)} of ${chalk11.cyan(status.totalSigners)}`);
6886
+ console.log(chalk11.bold("\nSigning Modes:"));
6765
6887
  status.availableSigningModes.forEach((mode) => {
6766
6888
  console.log(` - ${mode}`);
6767
6889
  });
6768
- console.log(chalk10.bold("\nDetails:"));
6890
+ console.log(chalk11.bold("\nDetails:"));
6769
6891
  console.log(` Chains: ${status.chains}`);
6770
6892
  console.log(` Currency: ${status.currency.toUpperCase()}`);
6771
6893
  console.log(` Created: ${new Date(status.createdAt).toLocaleString()}`);
@@ -6773,8 +6895,8 @@ function displayStatus(status) {
6773
6895
  `);
6774
6896
  }
6775
6897
  function showHelp() {
6776
- const table = new Table({
6777
- head: [chalk10.bold("Available Commands")],
6898
+ const table = new Table2({
6899
+ head: [chalk11.bold("Available Commands")],
6778
6900
  colWidths: [50],
6779
6901
  chars: {
6780
6902
  mid: "",
@@ -6788,7 +6910,7 @@ function showHelp() {
6788
6910
  }
6789
6911
  });
6790
6912
  table.push(
6791
- [chalk10.bold("Vault Management:")],
6913
+ [chalk11.bold("Vault Management:")],
6792
6914
  [" vaults - List all vaults"],
6793
6915
  [" vault <name> - Switch to vault"],
6794
6916
  [" import <file> - Import vault from file"],
@@ -6797,7 +6919,7 @@ function showHelp() {
6797
6919
  [" info - Show vault details"],
6798
6920
  [" export [path] - Export vault to file"],
6799
6921
  [""],
6800
- [chalk10.bold("Wallet Operations:")],
6922
+ [chalk11.bold("Wallet Operations:")],
6801
6923
  [" balance [chain] - Show balances"],
6802
6924
  [" send <chain> <to> <amount> - Send transaction"],
6803
6925
  [" tx-status <chain> <txHash> - Check transaction status"],
@@ -6806,22 +6928,22 @@ function showHelp() {
6806
6928
  [" chains [--add/--remove/--add-all] - Manage chains"],
6807
6929
  [" tokens <chain> - Manage tokens"],
6808
6930
  [""],
6809
- [chalk10.bold("Swap Operations:")],
6931
+ [chalk11.bold("Swap Operations:")],
6810
6932
  [" swap-chains - List swap-enabled chains"],
6811
6933
  [" swap-quote <from> <to> <amount> - Get quote"],
6812
6934
  [" swap <from> <to> <amount> - Execute swap"],
6813
6935
  [""],
6814
- [chalk10.bold("Session Commands (shell only):")],
6936
+ [chalk11.bold("Session Commands (shell only):")],
6815
6937
  [" lock - Lock vault"],
6816
6938
  [" unlock - Unlock vault"],
6817
6939
  [" status - Show vault status"],
6818
6940
  [""],
6819
- [chalk10.bold("Settings:")],
6941
+ [chalk11.bold("Settings:")],
6820
6942
  [" currency [code] - View/set currency"],
6821
6943
  [" server - Check server status"],
6822
6944
  [" address-book - Manage saved addresses"],
6823
6945
  [""],
6824
- [chalk10.bold("Help & Navigation:")],
6946
+ [chalk11.bold("Help & Navigation:")],
6825
6947
  [" help, ? - Show this help"],
6826
6948
  [" .clear - Clear screen"],
6827
6949
  [" .exit - Exit shell"]
@@ -6959,12 +7081,12 @@ var ShellSession = class {
6959
7081
  */
6960
7082
  async start() {
6961
7083
  console.clear();
6962
- console.log(chalk11.cyan.bold("\n=============================================="));
6963
- console.log(chalk11.cyan.bold(" Vultisig Interactive Shell"));
6964
- console.log(chalk11.cyan.bold("==============================================\n"));
7084
+ console.log(chalk12.cyan.bold("\n=============================================="));
7085
+ console.log(chalk12.cyan.bold(" Vultisig Interactive Shell"));
7086
+ console.log(chalk12.cyan.bold("==============================================\n"));
6965
7087
  await this.loadAllVaults();
6966
7088
  this.displayVaultList();
6967
- console.log(chalk11.gray('Type "help" for available commands, "exit" to quit\n'));
7089
+ console.log(chalk12.gray('Type "help" for available commands, "exit" to quit\n'));
6968
7090
  this.promptLoop().catch(() => {
6969
7091
  });
6970
7092
  }
@@ -6998,12 +7120,12 @@ var ShellSession = class {
6998
7120
  const now = Date.now();
6999
7121
  if (now - this.lastSigintTime < this.DOUBLE_CTRL_C_TIMEOUT) {
7000
7122
  rl.close();
7001
- console.log(chalk11.yellow("\nGoodbye!"));
7123
+ console.log(chalk12.yellow("\nGoodbye!"));
7002
7124
  this.ctx.dispose();
7003
7125
  process.exit(0);
7004
7126
  }
7005
7127
  this.lastSigintTime = now;
7006
- console.log(chalk11.yellow("\n(Press Ctrl+C again to exit)"));
7128
+ console.log(chalk12.yellow("\n(Press Ctrl+C again to exit)"));
7007
7129
  rl.close();
7008
7130
  resolve("");
7009
7131
  });
@@ -7098,7 +7220,7 @@ var ShellSession = class {
7098
7220
  stopAllSpinners();
7099
7221
  process.stdout.write("\x1B[?25h");
7100
7222
  process.stdout.write("\r\x1B[K");
7101
- console.log(chalk11.yellow("\nCancelling operation..."));
7223
+ console.log(chalk12.yellow("\nCancelling operation..."));
7102
7224
  };
7103
7225
  const cleanup = () => {
7104
7226
  process.removeListener("SIGINT", onSigint);
@@ -7135,10 +7257,10 @@ var ShellSession = class {
7135
7257
  stopAllSpinners();
7136
7258
  process.stdout.write("\x1B[?25h");
7137
7259
  process.stdout.write("\r\x1B[K");
7138
- console.log(chalk11.yellow("Operation cancelled"));
7260
+ console.log(chalk12.yellow("Operation cancelled"));
7139
7261
  return;
7140
7262
  }
7141
- console.error(chalk11.red(`
7263
+ console.error(chalk12.red(`
7142
7264
  Error: ${error2.message}`));
7143
7265
  }
7144
7266
  }
@@ -7171,7 +7293,7 @@ Error: ${error2.message}`));
7171
7293
  break;
7172
7294
  case "rename":
7173
7295
  if (args.length === 0) {
7174
- console.log(chalk11.yellow("Usage: rename <newName>"));
7296
+ console.log(chalk12.yellow("Usage: rename <newName>"));
7175
7297
  return;
7176
7298
  }
7177
7299
  await executeRename(this.ctx, args.join(" "));
@@ -7247,41 +7369,41 @@ Error: ${error2.message}`));
7247
7369
  // Exit
7248
7370
  case "exit":
7249
7371
  case "quit":
7250
- console.log(chalk11.yellow("\nGoodbye!"));
7372
+ console.log(chalk12.yellow("\nGoodbye!"));
7251
7373
  this.ctx.dispose();
7252
7374
  process.exit(0);
7253
7375
  break;
7254
7376
  // eslint requires break even after process.exit
7255
7377
  default:
7256
- console.log(chalk11.yellow(`Unknown command: ${command}`));
7257
- console.log(chalk11.gray('Type "help" for available commands'));
7378
+ console.log(chalk12.yellow(`Unknown command: ${command}`));
7379
+ console.log(chalk12.gray('Type "help" for available commands'));
7258
7380
  break;
7259
7381
  }
7260
7382
  }
7261
7383
  // ===== Command Helpers =====
7262
7384
  async switchVault(args) {
7263
7385
  if (args.length === 0) {
7264
- console.log(chalk11.yellow("Usage: vault <name>"));
7265
- console.log(chalk11.gray('Run "vaults" to see available vaults'));
7386
+ console.log(chalk12.yellow("Usage: vault <name>"));
7387
+ console.log(chalk12.gray('Run "vaults" to see available vaults'));
7266
7388
  return;
7267
7389
  }
7268
7390
  const vaultName = args.join(" ");
7269
7391
  const vault = this.ctx.findVaultByName(vaultName);
7270
7392
  if (!vault) {
7271
- console.log(chalk11.red(`Vault not found: ${vaultName}`));
7272
- console.log(chalk11.gray('Run "vaults" to see available vaults'));
7393
+ console.log(chalk12.red(`Vault not found: ${vaultName}`));
7394
+ console.log(chalk12.gray('Run "vaults" to see available vaults'));
7273
7395
  return;
7274
7396
  }
7275
7397
  await this.ctx.setActiveVault(vault);
7276
- console.log(chalk11.green(`
7398
+ console.log(chalk12.green(`
7277
7399
  + Switched to: ${vault.name}`));
7278
7400
  const isUnlocked = this.ctx.isVaultUnlocked(vault.id);
7279
- const status = isUnlocked ? chalk11.green("Unlocked") : chalk11.yellow("Locked");
7401
+ const status = isUnlocked ? chalk12.green("Unlocked") : chalk12.yellow("Locked");
7280
7402
  console.log(`Status: ${status}`);
7281
7403
  }
7282
7404
  async importVault(args) {
7283
7405
  if (args.length === 0) {
7284
- console.log(chalk11.yellow("Usage: import <file>"));
7406
+ console.log(chalk12.yellow("Usage: import <file>"));
7285
7407
  return;
7286
7408
  }
7287
7409
  const filePath = args.join(" ");
@@ -7296,45 +7418,45 @@ Error: ${error2.message}`));
7296
7418
  async createVault(args) {
7297
7419
  const type = args[0]?.toLowerCase();
7298
7420
  if (!type || type !== "fast" && type !== "secure") {
7299
- console.log(chalk11.yellow("Usage: create <fast|secure>"));
7300
- console.log(chalk11.gray(" create fast - Create a fast vault (server-assisted 2-of-2)"));
7301
- console.log(chalk11.gray(" create secure - Create a secure vault (multi-device MPC)"));
7421
+ console.log(chalk12.yellow("Usage: create <fast|secure>"));
7422
+ console.log(chalk12.gray(" create fast - Create a fast vault (server-assisted 2-of-2)"));
7423
+ console.log(chalk12.gray(" create secure - Create a secure vault (multi-device MPC)"));
7302
7424
  return;
7303
7425
  }
7304
7426
  let vault;
7305
7427
  if (type === "fast") {
7306
7428
  const name = await this.prompt("Vault name");
7307
7429
  if (!name) {
7308
- console.log(chalk11.red("Name is required"));
7430
+ console.log(chalk12.red("Name is required"));
7309
7431
  return;
7310
7432
  }
7311
7433
  const password = await this.promptPassword("Vault password");
7312
7434
  if (!password) {
7313
- console.log(chalk11.red("Password is required"));
7435
+ console.log(chalk12.red("Password is required"));
7314
7436
  return;
7315
7437
  }
7316
7438
  const email = await this.prompt("Email for verification");
7317
7439
  if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
7318
- console.log(chalk11.red("Valid email is required"));
7440
+ console.log(chalk12.red("Valid email is required"));
7319
7441
  return;
7320
7442
  }
7321
7443
  vault = await this.withCancellation((signal) => executeCreateFast(this.ctx, { name, password, email, signal }));
7322
7444
  } else {
7323
7445
  const name = await this.prompt("Vault name");
7324
7446
  if (!name) {
7325
- console.log(chalk11.red("Name is required"));
7447
+ console.log(chalk12.red("Name is required"));
7326
7448
  return;
7327
7449
  }
7328
7450
  const sharesStr = await this.prompt("Total shares (devices)", "3");
7329
7451
  const shares = parseInt(sharesStr, 10);
7330
7452
  if (isNaN(shares) || shares < 2) {
7331
- console.log(chalk11.red("Must have at least 2 shares"));
7453
+ console.log(chalk12.red("Must have at least 2 shares"));
7332
7454
  return;
7333
7455
  }
7334
7456
  const thresholdStr = await this.prompt("Signing threshold", "2");
7335
7457
  const threshold = parseInt(thresholdStr, 10);
7336
7458
  if (isNaN(threshold) || threshold < 1 || threshold > shares) {
7337
- console.log(chalk11.red(`Threshold must be between 1 and ${shares}`));
7459
+ console.log(chalk12.red(`Threshold must be between 1 and ${shares}`));
7338
7460
  return;
7339
7461
  }
7340
7462
  const password = await this.promptPassword("Vault password (optional, press Enter to skip)");
@@ -7356,37 +7478,37 @@ Error: ${error2.message}`));
7356
7478
  async importSeedphrase(args) {
7357
7479
  const type = args[0]?.toLowerCase();
7358
7480
  if (!type || type !== "fast" && type !== "secure") {
7359
- console.log(chalk11.cyan("Usage: create-from-seedphrase <fast|secure>"));
7360
- console.log(chalk11.gray(" fast - Import with VultiServer (2-of-2)"));
7361
- console.log(chalk11.gray(" secure - Import with device coordination (N-of-M)"));
7481
+ console.log(chalk12.cyan("Usage: create-from-seedphrase <fast|secure>"));
7482
+ console.log(chalk12.gray(" fast - Import with VultiServer (2-of-2)"));
7483
+ console.log(chalk12.gray(" secure - Import with device coordination (N-of-M)"));
7362
7484
  return;
7363
7485
  }
7364
- console.log(chalk11.cyan("\nEnter your recovery phrase (words separated by spaces):"));
7486
+ console.log(chalk12.cyan("\nEnter your recovery phrase (words separated by spaces):"));
7365
7487
  const mnemonic = await this.promptPassword("Seedphrase");
7366
7488
  const validation = await this.ctx.sdk.validateSeedphrase(mnemonic);
7367
7489
  if (!validation.valid) {
7368
- console.log(chalk11.red(`Invalid seedphrase: ${validation.error}`));
7490
+ console.log(chalk12.red(`Invalid seedphrase: ${validation.error}`));
7369
7491
  if (validation.invalidWords?.length) {
7370
- console.log(chalk11.yellow(`Invalid words: ${validation.invalidWords.join(", ")}`));
7492
+ console.log(chalk12.yellow(`Invalid words: ${validation.invalidWords.join(", ")}`));
7371
7493
  }
7372
7494
  return;
7373
7495
  }
7374
- console.log(chalk11.green(`\u2713 Valid ${validation.wordCount}-word seedphrase`));
7496
+ console.log(chalk12.green(`\u2713 Valid ${validation.wordCount}-word seedphrase`));
7375
7497
  let vault;
7376
7498
  if (type === "fast") {
7377
7499
  const name = await this.prompt("Vault name");
7378
7500
  if (!name) {
7379
- console.log(chalk11.red("Name is required"));
7501
+ console.log(chalk12.red("Name is required"));
7380
7502
  return;
7381
7503
  }
7382
7504
  const password = await this.promptPassword("Vault password");
7383
7505
  if (!password) {
7384
- console.log(chalk11.red("Password is required"));
7506
+ console.log(chalk12.red("Password is required"));
7385
7507
  return;
7386
7508
  }
7387
7509
  const email = await this.prompt("Email for verification");
7388
7510
  if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
7389
- console.log(chalk11.red("Valid email is required"));
7511
+ console.log(chalk12.red("Valid email is required"));
7390
7512
  return;
7391
7513
  }
7392
7514
  const discoverStr = await this.prompt("Discover chains with balances? (y/n)", "y");
@@ -7404,19 +7526,19 @@ Error: ${error2.message}`));
7404
7526
  } else {
7405
7527
  const name = await this.prompt("Vault name");
7406
7528
  if (!name) {
7407
- console.log(chalk11.red("Name is required"));
7529
+ console.log(chalk12.red("Name is required"));
7408
7530
  return;
7409
7531
  }
7410
7532
  const sharesStr = await this.prompt("Total shares (devices)", "3");
7411
7533
  const shares = parseInt(sharesStr, 10);
7412
7534
  if (isNaN(shares) || shares < 2) {
7413
- console.log(chalk11.red("Must have at least 2 shares"));
7535
+ console.log(chalk12.red("Must have at least 2 shares"));
7414
7536
  return;
7415
7537
  }
7416
7538
  const thresholdStr = await this.prompt("Signing threshold", "2");
7417
7539
  const threshold = parseInt(thresholdStr, 10);
7418
7540
  if (isNaN(threshold) || threshold < 1 || threshold > shares) {
7419
- console.log(chalk11.red(`Threshold must be between 1 and ${shares}`));
7541
+ console.log(chalk12.red(`Threshold must be between 1 and ${shares}`));
7420
7542
  return;
7421
7543
  }
7422
7544
  const password = await this.promptPassword("Vault password (optional, Enter to skip)");
@@ -7460,8 +7582,8 @@ Error: ${error2.message}`));
7460
7582
  }
7461
7583
  }
7462
7584
  if (!fiatCurrencies3.includes(currency)) {
7463
- console.log(chalk11.red(`Invalid currency: ${currency}`));
7464
- console.log(chalk11.yellow(`Supported currencies: ${fiatCurrencies3.join(", ")}`));
7585
+ console.log(chalk12.red(`Invalid currency: ${currency}`));
7586
+ console.log(chalk12.yellow(`Supported currencies: ${fiatCurrencies3.join(", ")}`));
7465
7587
  return;
7466
7588
  }
7467
7589
  const raw = args.includes("--raw");
@@ -7469,7 +7591,7 @@ Error: ${error2.message}`));
7469
7591
  }
7470
7592
  async runSend(args) {
7471
7593
  if (args.length < 3) {
7472
- console.log(chalk11.yellow("Usage: send <chain> <to> <amount> [--token <tokenId>] [--memo <memo>]"));
7594
+ console.log(chalk12.yellow("Usage: send <chain> <to> <amount> [--token <tokenId>] [--memo <memo>]"));
7473
7595
  return;
7474
7596
  }
7475
7597
  const [chainStr, to, amount, ...rest] = args;
@@ -7489,7 +7611,7 @@ Error: ${error2.message}`));
7489
7611
  await this.withAbortHandler((signal) => executeSend(this.ctx, { chain, to, amount, tokenId, memo, signal }));
7490
7612
  } catch (err) {
7491
7613
  if (err.message === "Transaction cancelled by user" || err.message === "Operation cancelled" || err.message === "Operation aborted") {
7492
- console.log(chalk11.yellow("\nTransaction cancelled"));
7614
+ console.log(chalk12.yellow("\nTransaction cancelled"));
7493
7615
  return;
7494
7616
  }
7495
7617
  throw err;
@@ -7497,7 +7619,7 @@ Error: ${error2.message}`));
7497
7619
  }
7498
7620
  async runTxStatus(args) {
7499
7621
  if (args.length < 2) {
7500
- console.log(chalk11.yellow("Usage: tx-status <chain> <txHash> [--no-wait]"));
7622
+ console.log(chalk12.yellow("Usage: tx-status <chain> <txHash> [--no-wait]"));
7501
7623
  return;
7502
7624
  }
7503
7625
  const [chainStr, txHash, ...rest] = args;
@@ -7515,8 +7637,8 @@ Error: ${error2.message}`));
7515
7637
  } else if (args[i] === "--add" && i + 1 < args.length) {
7516
7638
  const chain = findChainByName(args[i + 1]);
7517
7639
  if (!chain) {
7518
- console.log(chalk11.red(`Unknown chain: ${args[i + 1]}`));
7519
- console.log(chalk11.gray("Use tab completion to see available chains"));
7640
+ console.log(chalk12.red(`Unknown chain: ${args[i + 1]}`));
7641
+ console.log(chalk12.gray("Use tab completion to see available chains"));
7520
7642
  return;
7521
7643
  }
7522
7644
  addChain = chain;
@@ -7524,8 +7646,8 @@ Error: ${error2.message}`));
7524
7646
  } else if (args[i] === "--remove" && i + 1 < args.length) {
7525
7647
  const chain = findChainByName(args[i + 1]);
7526
7648
  if (!chain) {
7527
- console.log(chalk11.red(`Unknown chain: ${args[i + 1]}`));
7528
- console.log(chalk11.gray("Use tab completion to see available chains"));
7649
+ console.log(chalk12.red(`Unknown chain: ${args[i + 1]}`));
7650
+ console.log(chalk12.gray("Use tab completion to see available chains"));
7529
7651
  return;
7530
7652
  }
7531
7653
  removeChain = chain;
@@ -7536,7 +7658,7 @@ Error: ${error2.message}`));
7536
7658
  }
7537
7659
  async runTokens(args) {
7538
7660
  if (args.length === 0) {
7539
- console.log(chalk11.yellow("Usage: tokens <chain> [--add <address>] [--remove <tokenId>]"));
7661
+ console.log(chalk12.yellow("Usage: tokens <chain> [--add <address>] [--remove <tokenId>]"));
7540
7662
  return;
7541
7663
  }
7542
7664
  const chainStr = args[0];
@@ -7557,7 +7679,7 @@ Error: ${error2.message}`));
7557
7679
  async runSwapQuote(args) {
7558
7680
  if (args.length < 3) {
7559
7681
  console.log(
7560
- chalk11.yellow("Usage: swap-quote <fromChain> <toChain> <amount> [--from-token <addr>] [--to-token <addr>]")
7682
+ chalk12.yellow("Usage: swap-quote <fromChain> <toChain> <amount> [--from-token <addr>] [--to-token <addr>]")
7561
7683
  );
7562
7684
  return;
7563
7685
  }
@@ -7581,7 +7703,7 @@ Error: ${error2.message}`));
7581
7703
  async runSwap(args) {
7582
7704
  if (args.length < 3) {
7583
7705
  console.log(
7584
- chalk11.yellow(
7706
+ chalk12.yellow(
7585
7707
  "Usage: swap <fromChain> <toChain> <amount> [--from-token <addr>] [--to-token <addr>] [--slippage <pct>]"
7586
7708
  )
7587
7709
  );
@@ -7612,7 +7734,7 @@ Error: ${error2.message}`));
7612
7734
  );
7613
7735
  } catch (err) {
7614
7736
  if (err.message === "Swap cancelled by user" || err.message === "Operation cancelled" || err.message === "Operation aborted") {
7615
- console.log(chalk11.yellow("\nSwap cancelled"));
7737
+ console.log(chalk12.yellow("\nSwap cancelled"));
7616
7738
  return;
7617
7739
  }
7618
7740
  throw err;
@@ -7674,24 +7796,24 @@ Error: ${error2.message}`));
7674
7796
  }
7675
7797
  getPrompt() {
7676
7798
  const vault = this.ctx.getActiveVault();
7677
- if (!vault) return chalk11.cyan("wallet> ");
7799
+ if (!vault) return chalk12.cyan("wallet> ");
7678
7800
  const isUnlocked = this.ctx.isVaultUnlocked(vault.id);
7679
- const status = isUnlocked ? chalk11.green("\u{1F513}") : chalk11.yellow("\u{1F512}");
7680
- return chalk11.cyan(`wallet[${vault.name}]${status}> `);
7801
+ const status = isUnlocked ? chalk12.green("\u{1F513}") : chalk12.yellow("\u{1F512}");
7802
+ return chalk12.cyan(`wallet[${vault.name}]${status}> `);
7681
7803
  }
7682
7804
  displayVaultList() {
7683
7805
  const vaults = Array.from(this.ctx.getVaults().values());
7684
7806
  const activeVault = this.ctx.getActiveVault();
7685
7807
  if (vaults.length === 0) {
7686
- console.log(chalk11.yellow('No vaults found. Use "create" or "import <file>" to add a vault.\n'));
7808
+ console.log(chalk12.yellow('No vaults found. Use "create" or "import <file>" to add a vault.\n'));
7687
7809
  return;
7688
7810
  }
7689
- console.log(chalk11.cyan("Loaded Vaults:\n"));
7811
+ console.log(chalk12.cyan("Loaded Vaults:\n"));
7690
7812
  vaults.forEach((vault) => {
7691
7813
  const isActive = vault.id === activeVault?.id;
7692
7814
  const isUnlocked = this.ctx.isVaultUnlocked(vault.id);
7693
- const activeMarker = isActive ? chalk11.green(" (active)") : "";
7694
- const lockIcon = isUnlocked ? chalk11.green("\u{1F513}") : chalk11.yellow("\u{1F512}");
7815
+ const activeMarker = isActive ? chalk12.green(" (active)") : "";
7816
+ const lockIcon = isUnlocked ? chalk12.green("\u{1F513}") : chalk12.yellow("\u{1F512}");
7695
7817
  console.log(` ${lockIcon} ${vault.name}${activeMarker} - ${vault.type}`);
7696
7818
  });
7697
7819
  console.log();
@@ -7699,10 +7821,10 @@ Error: ${error2.message}`));
7699
7821
  };
7700
7822
 
7701
7823
  // src/lib/errors.ts
7702
- import chalk12 from "chalk";
7824
+ import chalk13 from "chalk";
7703
7825
 
7704
7826
  // src/lib/version.ts
7705
- import chalk13 from "chalk";
7827
+ import chalk14 from "chalk";
7706
7828
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
7707
7829
  import { homedir as homedir2 } from "os";
7708
7830
  import { join as join2 } from "path";
@@ -7710,7 +7832,7 @@ var cachedVersion = null;
7710
7832
  function getVersion() {
7711
7833
  if (cachedVersion) return cachedVersion;
7712
7834
  if (true) {
7713
- cachedVersion = "0.7.0";
7835
+ cachedVersion = "0.8.0";
7714
7836
  return cachedVersion;
7715
7837
  }
7716
7838
  try {
@@ -7807,7 +7929,7 @@ function formatVersionShort() {
7807
7929
  }
7808
7930
  function formatVersionDetailed() {
7809
7931
  const lines = [];
7810
- lines.push(chalk13.bold(`Vultisig CLI v${getVersion()}`));
7932
+ lines.push(chalk14.bold(`Vultisig CLI v${getVersion()}`));
7811
7933
  lines.push("");
7812
7934
  lines.push(` Node.js: ${process.version}`);
7813
7935
  lines.push(` Platform: ${process.platform}-${process.arch}`);
@@ -8197,14 +8319,15 @@ async function findVaultByNameOrId(sdk, nameOrId) {
8197
8319
  if (byPartialId) return byPartialId;
8198
8320
  return null;
8199
8321
  }
8200
- async function init(vaultOverride, unlockPassword) {
8322
+ async function init(vaultOverride, unlockPassword, passwordTTL) {
8201
8323
  if (!ctx) {
8202
8324
  const vaultSelector = vaultOverride || process.env.VULTISIG_VAULT;
8203
8325
  if (unlockPassword && vaultSelector) {
8204
8326
  cachePassword(vaultSelector, unlockPassword);
8205
8327
  }
8206
8328
  const sdk = new Vultisig7({
8207
- onPasswordRequired: createPasswordCallback()
8329
+ onPasswordRequired: createPasswordCallback(),
8330
+ ...passwordTTL !== void 0 ? { passwordCache: { defaultTTL: passwordTTL } } : {}
8208
8331
  });
8209
8332
  await sdk.initialize();
8210
8333
  ctx = new CLIContext(sdk);
@@ -8712,24 +8835,56 @@ rujiraCmd.command("withdraw <asset> <amount> <l1Address>").description("Withdraw
8712
8835
  }
8713
8836
  )
8714
8837
  );
8715
- 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: http://localhost:9998)").option("--password <password>", "Vault password for signing operations").option("--conversation <id>", "Resume an existing conversation").action(async (options) => {
8716
- const context = await init(program.opts().vault, options.password);
8838
+ 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: http://localhost:9998)").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").action(async (options) => {
8839
+ const MAX_TTL = 864e5;
8840
+ let passwordTTL;
8841
+ if (options.passwordTtl) {
8842
+ const parsed = parseInt(options.passwordTtl, 10);
8843
+ if (Number.isNaN(parsed) || parsed < 0) {
8844
+ throw new Error(`Invalid --password-ttl value: "${options.passwordTtl}". Expected a non-negative integer in milliseconds.`);
8845
+ }
8846
+ passwordTTL = parsed;
8847
+ } else if (options.viaAgent) {
8848
+ passwordTTL = MAX_TTL;
8849
+ }
8850
+ const context = await init(program.opts().vault, options.password, passwordTTL);
8717
8851
  await executeAgent(context, {
8718
8852
  viaAgent: options.viaAgent,
8719
8853
  verbose: options.verbose,
8720
8854
  backendUrl: options.backendUrl,
8721
8855
  password: options.password,
8722
- conversationId: options.conversation
8856
+ sessionId: options.sessionId
8723
8857
  });
8724
8858
  });
8859
+ var sessionsCmd = agentCmd.command("sessions").description("Manage agent chat sessions");
8860
+ sessionsCmd.command("list").description("List chat sessions for the current vault").option("--backend-url <url>", "Agent backend URL (default: http://localhost:9998)").option("--password <password>", "Vault password for authentication").action(
8861
+ withExit(async (options) => {
8862
+ const parentOpts = agentCmd.opts();
8863
+ const context = await init(program.opts().vault, options.password || parentOpts.password);
8864
+ await executeAgentSessionsList(context, {
8865
+ backendUrl: options.backendUrl || parentOpts.backendUrl,
8866
+ password: options.password || parentOpts.password
8867
+ });
8868
+ })
8869
+ );
8870
+ sessionsCmd.command("delete <id>").description("Delete a chat session").option("--backend-url <url>", "Agent backend URL (default: http://localhost:9998)").option("--password <password>", "Vault password for authentication").action(
8871
+ withExit(async (id, options) => {
8872
+ const parentOpts = agentCmd.opts();
8873
+ const context = await init(program.opts().vault, options.password || parentOpts.password);
8874
+ await executeAgentSessionsDelete(context, id, {
8875
+ backendUrl: options.backendUrl || parentOpts.backendUrl,
8876
+ password: options.password || parentOpts.password
8877
+ });
8878
+ })
8879
+ );
8725
8880
  program.command("version").description("Show detailed version information").action(
8726
8881
  withExit(async () => {
8727
8882
  printResult(formatVersionDetailed());
8728
8883
  const result = await checkForUpdates();
8729
8884
  if (result?.updateAvailable && result.latestVersion) {
8730
8885
  info("");
8731
- info(chalk14.yellow(`Update available: ${result.currentVersion} -> ${result.latestVersion}`));
8732
- info(chalk14.gray(`Run "${getUpdateCommand()}" to update`));
8886
+ info(chalk15.yellow(`Update available: ${result.currentVersion} -> ${result.latestVersion}`));
8887
+ info(chalk15.gray(`Run "${getUpdateCommand()}" to update`));
8733
8888
  }
8734
8889
  })
8735
8890
  );
@@ -8738,22 +8893,22 @@ program.command("update").description("Check for updates and show update command
8738
8893
  info("Checking for updates...");
8739
8894
  const result = await checkForUpdates();
8740
8895
  if (!result) {
8741
- printResult(chalk14.gray("Update checking is disabled"));
8896
+ printResult(chalk15.gray("Update checking is disabled"));
8742
8897
  return;
8743
8898
  }
8744
8899
  if (result.updateAvailable && result.latestVersion) {
8745
8900
  printResult("");
8746
- printResult(chalk14.green(`Update available: ${result.currentVersion} -> ${result.latestVersion}`));
8901
+ printResult(chalk15.green(`Update available: ${result.currentVersion} -> ${result.latestVersion}`));
8747
8902
  printResult("");
8748
8903
  if (options.check) {
8749
8904
  printResult(`Run "${getUpdateCommand()}" to update`);
8750
8905
  } else {
8751
8906
  const updateCmd = getUpdateCommand();
8752
8907
  printResult(`To update, run:`);
8753
- printResult(chalk14.cyan(` ${updateCmd}`));
8908
+ printResult(chalk15.cyan(` ${updateCmd}`));
8754
8909
  }
8755
8910
  } else {
8756
- printResult(chalk14.green(`You're on the latest version (${result.currentVersion})`));
8911
+ printResult(chalk15.green(`You're on the latest version (${result.currentVersion})`));
8757
8912
  }
8758
8913
  })
8759
8914
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/cli",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Command-line wallet for Vultisig - multi-chain MPC wallet management",
5
5
  "type": "module",
6
6
  "bin": {
@@ -53,8 +53,8 @@
53
53
  "@cosmjs/proto-signing": "^0.38.1",
54
54
  "@cosmjs/stargate": "^0.38.1",
55
55
  "@noble/hashes": "^2.0.1",
56
- "@vultisig/rujira": "^3.0.0",
57
- "@vultisig/sdk": "^0.7.0",
56
+ "@vultisig/rujira": "^4.0.0",
57
+ "@vultisig/sdk": "^0.8.0",
58
58
  "chalk": "^5.6.2",
59
59
  "cli-table3": "^0.6.5",
60
60
  "commander": "^14.0.3",