@vultisig/cli 0.22.3 → 0.22.4

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,14 @@
1
1
  # @vultisig/cli
2
2
 
3
+ ## 0.22.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#422](https://github.com/vultisig/vultisig-sdk/pull/422) [`a0a8496`](https://github.com/vultisig/vultisig-sdk/commit/a0a8496b0b87722910bfb9f44c940c4981b25faf) Thanks [@neavra](https://github.com/neavra)! - CLI agent executor now recognizes the mcp-ts `execute_*` tx_ready envelope shape (`txArgs.tx`) for `execute_send` and `execute_contract_call`. Previously the executor only handled mcp-go's older shapes (`swap_tx` / `send_tx` / `tx`) and silently skipped every mcp-ts payload, leaving local-dev parity broken against production. Multi-leg `execute_swap` envelopes (carrying `approvalTxArgs`) are explicitly rejected for now — multi-leg sequencing is a follow-up.
8
+
9
+ - Updated dependencies [[`6b75472`](https://github.com/vultisig/vultisig-sdk/commit/6b7547288f8594fcf8a9c71e46a5163d6b6cd727), [`613004f`](https://github.com/vultisig/vultisig-sdk/commit/613004f5fbce2658a439296ca249d3e031a58078), [`2e1bfb8`](https://github.com/vultisig/vultisig-sdk/commit/2e1bfb85417787a7cc5d497d35f6e76d2bb5a41a)]:
10
+ - @vultisig/core-chain@1.6.0
11
+
3
12
  ## 0.22.3
4
13
 
5
14
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1654,7 +1654,7 @@ var thorchainMidgardBaseUrl, POOL_ID_RE, assertValidPoolId, isValidPoolId, norma
1654
1654
  var init_pools = __esm({
1655
1655
  "../../packages/core/chain/dist/chains/cosmos/thor/lp/pools.js"() {
1656
1656
  init_queryUrl();
1657
- thorchainMidgardBaseUrl = "https://midgard.thorchain.network";
1657
+ thorchainMidgardBaseUrl = "https://gateway.liquify.com/chain/thorchain_midgard";
1658
1658
  POOL_ID_RE = /^[A-Z0-9]+\.[A-Z0-9]+(-[A-Z0-9]+)?$/;
1659
1659
  assertValidPoolId = (pool) => {
1660
1660
  if (typeof pool !== "string" || pool.length === 0) {
@@ -1864,7 +1864,7 @@ var init_cosmosRpcUrl = __esm({
1864
1864
  Terra: "https://terra-lcd.publicnode.com",
1865
1865
  TerraClassic: "https://terra-classic-lcd.publicnode.com",
1866
1866
  Noble: "https://noble-api.polkachu.com",
1867
- THORChain: "https://thornode.thorchain.network",
1867
+ THORChain: "https://gateway.liquify.com/chain/thorchain_api",
1868
1868
  MayaChain: "https://mayanode.mayachain.info",
1869
1869
  Akash: "https://akash-rest.publicnode.com"
1870
1870
  };
@@ -5931,6 +5931,7 @@ function sseErrorToMessage(value) {
5931
5931
  var AgentClient = class {
5932
5932
  baseUrl;
5933
5933
  authToken = null;
5934
+ profile = "";
5934
5935
  verbose = false;
5935
5936
  constructor(baseUrl) {
5936
5937
  this.baseUrl = baseUrl.replace(/\/+$/, "");
@@ -5938,13 +5939,21 @@ var AgentClient = class {
5938
5939
  setAuthToken(token) {
5939
5940
  this.authToken = token;
5940
5941
  }
5942
+ /** Set the billing-profile slug sent as X-Vultisig-Abe-Profile on every
5943
+ * request. Empty falls back to the backend's default profile. */
5944
+ setProfile(profile) {
5945
+ this.profile = profile;
5946
+ }
5947
+ profileHeader() {
5948
+ return this.profile ? { "X-Vultisig-Abe-Profile": this.profile } : {};
5949
+ }
5941
5950
  // ============================================================================
5942
5951
  // Authentication
5943
5952
  // ============================================================================
5944
5953
  async authenticate(req) {
5945
5954
  const res = await fetch(`${this.baseUrl}/auth/token`, {
5946
5955
  method: "POST",
5947
- headers: { "Content-Type": "application/json" },
5956
+ headers: { "Content-Type": "application/json", ...this.profileHeader() },
5948
5957
  body: JSON.stringify(req)
5949
5958
  });
5950
5959
  if (!res.ok) {
@@ -6001,7 +6010,8 @@ var AgentClient = class {
6001
6010
  headers: {
6002
6011
  "Content-Type": "application/json",
6003
6012
  Accept: "text/event-stream",
6004
- ...this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {}
6013
+ ...this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {},
6014
+ ...this.profileHeader()
6005
6015
  },
6006
6016
  body: JSON.stringify(req),
6007
6017
  signal
@@ -6176,18 +6186,6 @@ var AgentClient = class {
6176
6186
  }
6177
6187
  }
6178
6188
  // ============================================================================
6179
- // Calldata
6180
- // ============================================================================
6181
- async getCalldata(id) {
6182
- const res = await fetch(`${this.baseUrl}/agent/calldata/${id}`, {
6183
- headers: this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {}
6184
- });
6185
- if (!res.ok) {
6186
- throw new Error(`Failed to resolve calldata_id ${id}: ${res.status} ${res.statusText}`);
6187
- }
6188
- return res.json();
6189
- }
6190
- // ============================================================================
6191
6189
  // Private helpers
6192
6190
  // ============================================================================
6193
6191
  async post(path4, body) {
@@ -6195,7 +6193,8 @@ var AgentClient = class {
6195
6193
  method: "POST",
6196
6194
  headers: {
6197
6195
  "Content-Type": "application/json",
6198
- ...this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {}
6196
+ ...this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {},
6197
+ ...this.profileHeader()
6199
6198
  },
6200
6199
  body: JSON.stringify(body)
6201
6200
  });
@@ -6210,7 +6209,8 @@ var AgentClient = class {
6210
6209
  method: "DELETE",
6211
6210
  headers: {
6212
6211
  "Content-Type": "application/json",
6213
- ...this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {}
6212
+ ...this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {},
6213
+ ...this.profileHeader()
6214
6214
  },
6215
6215
  body: JSON.stringify(body)
6216
6216
  });
@@ -6531,12 +6531,9 @@ function sleep2(ms) {
6531
6531
 
6532
6532
  // src/agent/types.ts
6533
6533
  var AUTO_EXECUTE_ACTIONS = /* @__PURE__ */ new Set([
6534
- "add_chain",
6535
- "add_coin",
6536
- "remove_coin",
6537
- "remove_chain",
6538
- "address_book_add",
6539
- "address_book_remove",
6534
+ "vault_chain",
6535
+ "vault_coin",
6536
+ "address_book",
6540
6537
  "get_address_book",
6541
6538
  "get_balances",
6542
6539
  "search_token",
@@ -6597,8 +6594,6 @@ var AgentExecutor = class _AgentExecutor {
6597
6594
  /** Held chain lock release functions, keyed by chain name */
6598
6595
  chainLockReleases = /* @__PURE__ */ new Map();
6599
6596
  evmLastBroadcast = /* @__PURE__ */ new Map();
6600
- /** Backend client for resolving calldata_id references. */
6601
- backendClient = null;
6602
6597
  constructor(vault, verbose = false, vaultId, vultisig) {
6603
6598
  this.vault = vault;
6604
6599
  this.verbose = verbose;
@@ -6610,9 +6605,6 @@ var AgentExecutor = class _AgentExecutor {
6610
6605
  setPassword(password) {
6611
6606
  this.password = password;
6612
6607
  }
6613
- setBackendClient(client) {
6614
- this.backendClient = client;
6615
- }
6616
6608
  /**
6617
6609
  * Store a server-built transaction (from tx_ready SSE event).
6618
6610
  * This allows sign_tx to find and sign it when the backend requests signing.
@@ -6625,7 +6617,15 @@ var AgentExecutor = class _AgentExecutor {
6625
6617
  `[executor] storeServerTransaction called, keys: ${Object.keys(txReadyData || {}).join(",")}
6626
6618
  `
6627
6619
  );
6628
- const nestedTx = txReadyData?.swap_tx || txReadyData?.send_tx || txReadyData?.tx;
6620
+ if (txReadyData?.approvalTxArgs) {
6621
+ if (this.verbose)
6622
+ process.stderr.write(
6623
+ `[executor] skipping multi-leg execute_swap envelope (approvalTxArgs present): not yet supported in sdk-cli \u2014 Phase B
6624
+ `
6625
+ );
6626
+ return false;
6627
+ }
6628
+ const nestedTx = extractNestedTx(txReadyData);
6629
6629
  if (nestedTx?.status === "error" || nestedTx?.error) {
6630
6630
  if (this.verbose)
6631
6631
  process.stderr.write(`[executor] skipping error tx_ready: ${nestedTx.error || "unknown error"}
@@ -6633,7 +6633,8 @@ var AgentExecutor = class _AgentExecutor {
6633
6633
  return false;
6634
6634
  }
6635
6635
  if (!nestedTx) {
6636
- if (this.verbose) process.stderr.write(`[executor] storeServerTransaction: no swap_tx/send_tx/tx found in data
6636
+ if (this.verbose)
6637
+ process.stderr.write(`[executor] storeServerTransaction: no swap_tx/send_tx/tx/txArgs.tx found in data
6637
6638
  `);
6638
6639
  return false;
6639
6640
  }
@@ -6691,14 +6692,10 @@ var AgentExecutor = class _AgentExecutor {
6691
6692
  switch (action.type) {
6692
6693
  case "get_balances":
6693
6694
  return this.getBalances(params);
6694
- case "add_chain":
6695
- return this.addChain(params);
6696
- case "remove_chain":
6697
- return this.removeChain(params);
6698
- case "add_coin":
6699
- return this.addCoin(params);
6700
- case "remove_coin":
6701
- return this.removeCoin(params);
6695
+ case "vault_chain":
6696
+ return this.vaultChain(params);
6697
+ case "vault_coin":
6698
+ return this.vaultCoin(params);
6702
6699
  case "build_send_tx":
6703
6700
  return this.buildSendTx(params);
6704
6701
  case "build_swap_tx":
@@ -6710,10 +6707,8 @@ var AgentExecutor = class _AgentExecutor {
6710
6707
  return this.signTx(params);
6711
6708
  case "get_address_book":
6712
6709
  return this.getAddressBook(params);
6713
- case "address_book_add":
6714
- return this.addAddressBookEntry(params);
6715
- case "address_book_remove":
6716
- return this.removeAddressBookEntry(params);
6710
+ case "address_book":
6711
+ return this.addressBook(params);
6717
6712
  case "search_token":
6718
6713
  return this.searchToken(params);
6719
6714
  case "list_vaults":
@@ -6764,7 +6759,35 @@ var AgentExecutor = class _AgentExecutor {
6764
6759
  // ============================================================================
6765
6760
  // Chain & Token Management
6766
6761
  // ============================================================================
6767
- async addChain(params) {
6762
+ // vault_chain dispatcher — backend shape:
6763
+ // { action: "add" | "remove", chains: [{ chain }] }
6764
+ // Single-chain (`chain` only) and legacy string arrays are tolerated for
6765
+ // forward compatibility / hand-rolled callers.
6766
+ async vaultChain(params) {
6767
+ const action = params.action;
6768
+ switch (action) {
6769
+ case "add":
6770
+ return this.addChainImpl(params);
6771
+ case "remove":
6772
+ return this.removeChainImpl(params);
6773
+ default:
6774
+ throw new Error(`vault_chain: unknown action: ${action ?? "(missing)"}`);
6775
+ }
6776
+ }
6777
+ // vault_coin dispatcher — backend shape:
6778
+ // { action: "add" | "remove", coins: [{ chain, ticker, contract_address?, decimals?, ... }] }
6779
+ async vaultCoin(params) {
6780
+ const action = params.action;
6781
+ switch (action) {
6782
+ case "add":
6783
+ return this.addCoinImpl(params);
6784
+ case "remove":
6785
+ return this.removeCoinImpl(params);
6786
+ default:
6787
+ throw new Error(`vault_coin: unknown action: ${action ?? "(missing)"}`);
6788
+ }
6789
+ }
6790
+ async addChainImpl(params) {
6768
6791
  const chains = params.chains;
6769
6792
  if (chains && Array.isArray(chains)) {
6770
6793
  const results = [];
@@ -6785,21 +6808,33 @@ var AgentExecutor = class _AgentExecutor {
6785
6808
  const address = await this.vault.address(chain);
6786
6809
  return { chain: chain.toString(), address, added: true };
6787
6810
  }
6788
- async removeChain(params) {
6811
+ async removeChainImpl(params) {
6812
+ const chains = params.chains;
6813
+ if (chains && Array.isArray(chains)) {
6814
+ const results = [];
6815
+ for (const c of chains) {
6816
+ const name = typeof c === "string" ? c : c.chain;
6817
+ const chain2 = resolveChain(name);
6818
+ if (!chain2) throw new Error(`Unknown chain: ${name}`);
6819
+ await this.vault.removeChain(chain2);
6820
+ results.push({ chain: chain2.toString() });
6821
+ }
6822
+ return { removed: results };
6823
+ }
6789
6824
  const chainName = params.chain;
6790
6825
  const chain = resolveChain(chainName);
6791
6826
  if (!chain) throw new Error(`Unknown chain: ${chainName}`);
6792
6827
  await this.vault.removeChain(chain);
6793
6828
  return { chain: chain.toString(), removed: true };
6794
6829
  }
6795
- async addCoin(params) {
6796
- const tokens = params.tokens;
6797
- if (tokens && Array.isArray(tokens)) {
6830
+ async addCoinImpl(params) {
6831
+ const coins = params.coins ?? params.tokens;
6832
+ if (coins && Array.isArray(coins)) {
6798
6833
  const results = [];
6799
- for (const t of tokens) {
6834
+ for (const t of coins) {
6800
6835
  const chain2 = resolveChain(t.chain);
6801
6836
  if (!chain2) throw new Error(`Unknown chain: ${t.chain}`);
6802
- const symbol2 = t.symbol || t.ticker || "";
6837
+ const symbol2 = t.ticker || t.symbol || "";
6803
6838
  await this.vault.addToken(chain2, {
6804
6839
  id: t.contract_address || t.contractAddress || "",
6805
6840
  symbol: symbol2,
@@ -6815,7 +6850,7 @@ var AgentExecutor = class _AgentExecutor {
6815
6850
  const chainName = params.chain;
6816
6851
  const chain = resolveChain(chainName);
6817
6852
  if (!chain) throw new Error(`Unknown chain: ${chainName}`);
6818
- const symbol = params.symbol || params.ticker;
6853
+ const symbol = params.ticker || params.symbol;
6819
6854
  await this.vault.addToken(chain, {
6820
6855
  id: params.contract_address || params.contractAddress || "",
6821
6856
  symbol,
@@ -6826,11 +6861,31 @@ var AgentExecutor = class _AgentExecutor {
6826
6861
  });
6827
6862
  return { chain: chain.toString(), symbol, added: true };
6828
6863
  }
6829
- async removeCoin(params) {
6864
+ async removeCoinImpl(params) {
6865
+ const coins = params.coins ?? params.tokens;
6866
+ if (coins && Array.isArray(coins)) {
6867
+ const results = [];
6868
+ for (const t of coins) {
6869
+ const chain2 = resolveChain(t.chain);
6870
+ if (!chain2) throw new Error(`Unknown chain: ${t.chain}`);
6871
+ const tokenId2 = t.contract_address || t.contractAddress || t.token_id || t.id;
6872
+ if (!tokenId2) {
6873
+ throw new Error(
6874
+ `vault_coin remove: missing contract_address for ${t.ticker || t.symbol || "coin"} on ${t.chain}`
6875
+ );
6876
+ }
6877
+ await this.vault.removeToken(chain2, tokenId2);
6878
+ results.push({ chain: chain2.toString(), tokenId: tokenId2 });
6879
+ }
6880
+ return { removed: results };
6881
+ }
6830
6882
  const chainName = params.chain;
6831
6883
  const chain = resolveChain(chainName);
6832
6884
  if (!chain) throw new Error(`Unknown chain: ${chainName}`);
6833
- const tokenId = params.token_id || params.id || params.contract_address;
6885
+ const tokenId = params.contract_address || params.contractAddress || params.token_id || params.id;
6886
+ if (!tokenId) {
6887
+ throw new Error(`vault_coin remove: missing contract_address for coin on ${chainName}`);
6888
+ }
6834
6889
  await this.vault.removeToken(chain, tokenId);
6835
6890
  return { chain: chain.toString(), removed: true };
6836
6891
  }
@@ -7192,17 +7247,6 @@ var AgentExecutor = class _AgentExecutor {
7192
7247
  return _AgentExecutor.THORCHAIN_RUNE_DEPOSIT_ADDRESS;
7193
7248
  }
7194
7249
  async buildTx(params) {
7195
- if (params.calldata_id && !params.data && this.backendClient) {
7196
- const id = params.calldata_id;
7197
- if (this.verbose) process.stderr.write(`[executor] resolving calldata_id ${id}
7198
- `);
7199
- const entry = await this.backendClient.getCalldata(id);
7200
- params = { ...params, data: entry.data };
7201
- if (!params.to && entry.to) params = { ...params, to: entry.to };
7202
- delete params.calldata_id;
7203
- if (this.verbose) process.stderr.write(`[executor] calldata_id resolved, data len=${entry.data.length}
7204
- `);
7205
- }
7206
7250
  if (params.function_name && params.contract_address) {
7207
7251
  return this.buildContractCallTx(params);
7208
7252
  }
@@ -7240,7 +7284,9 @@ var AgentExecutor = class _AgentExecutor {
7240
7284
  `build_custom_tx requires function_name and params for contract calls. Got: ${provided}. Missing: function_name, params.`
7241
7285
  );
7242
7286
  }
7243
- return this.buildSendTx(params);
7287
+ throw new Error(
7288
+ `build_custom_tx: unrecognized params shape. Expected function_name + contract_address for ABI-encoding. Server-built calldata should arrive via tx_ready, not via action params. Got keys: ${Object.keys(params).join(", ")}`
7289
+ );
7244
7290
  }
7245
7291
  /**
7246
7292
  * Build, sign, and broadcast an EVM contract call transaction from structured params.
@@ -7364,12 +7410,12 @@ var AgentExecutor = class _AgentExecutor {
7364
7410
  * Uses vault.prepareSendTx with memo field to carry the calldata.
7365
7411
  */
7366
7412
  async signServerTx(serverTxData, defaultChain, params) {
7367
- const swapTx = serverTxData.swap_tx || serverTxData.send_tx || serverTxData.tx;
7413
+ const swapTx = extractNestedTx(serverTxData);
7368
7414
  if (!swapTx?.to) {
7369
7415
  throw new Error("Server transaction missing required fields (to)");
7370
7416
  }
7371
- const chainName = params.chain || serverTxData.chain || serverTxData.from_chain;
7372
- const chainId = serverTxData.chain_id || swapTx.chainId;
7417
+ const chainName = params.chain || serverTxData.chain || serverTxData.from_chain || serverTxData.txArgs?.chain;
7418
+ const chainId = serverTxData.chain_id || serverTxData.txArgs?.chain_id || swapTx.chainId;
7373
7419
  let chain = defaultChain;
7374
7420
  if (chainName) {
7375
7421
  chain = resolveChain(chainName) || defaultChain;
@@ -7816,13 +7862,81 @@ var AgentExecutor = class _AgentExecutor {
7816
7862
  }
7817
7863
  return await this.vultisig.getAddressBook(chain);
7818
7864
  }
7819
- async addAddressBookEntry(_params) {
7820
- throw new Error("address_book_add is not yet implemented locally. The backend may handle this action server-side.");
7865
+ // address_book dispatcher — backend shape:
7866
+ // { action: "add" | "remove", entry: { name, chain, address } }
7867
+ async addressBook(params) {
7868
+ const action = params.action;
7869
+ switch (action) {
7870
+ case "add":
7871
+ return this.addAddressBookImpl(params);
7872
+ case "remove":
7873
+ return this.removeAddressBookImpl(params);
7874
+ default:
7875
+ throw new Error(`address_book: unknown action: ${action ?? "(missing)"}`);
7876
+ }
7821
7877
  }
7822
- async removeAddressBookEntry(_params) {
7823
- throw new Error(
7824
- "address_book_remove is not yet implemented locally. The backend may handle this action server-side."
7825
- );
7878
+ async addAddressBookImpl(params) {
7879
+ if (!this.vultisig) {
7880
+ throw new Error(
7881
+ "address_book add requires the CLI SDK instance. Ensure AgentConfig.vultisig is set when creating the session."
7882
+ );
7883
+ }
7884
+ const entry = params.entry;
7885
+ if (!entry || typeof entry !== "object") {
7886
+ throw new Error("address_book add: missing entry");
7887
+ }
7888
+ const chainName = entry.chain;
7889
+ const chain = chainName ? resolveChain(chainName) : void 0;
7890
+ if (!chain) throw new Error(`address_book add: unknown chain: ${chainName ?? "(missing)"}`);
7891
+ const address = entry.address;
7892
+ if (!address) throw new Error("address_book add: entry.address is required");
7893
+ const name = entry.name ?? "";
7894
+ await this.vultisig.addAddressBookEntry([
7895
+ {
7896
+ chain,
7897
+ address,
7898
+ name,
7899
+ source: "saved",
7900
+ dateAdded: Date.now()
7901
+ }
7902
+ ]);
7903
+ return { added: { chain: chain.toString(), address, name } };
7904
+ }
7905
+ async removeAddressBookImpl(params) {
7906
+ if (!this.vultisig) {
7907
+ throw new Error(
7908
+ "address_book remove requires the CLI SDK instance. Ensure AgentConfig.vultisig is set when creating the session."
7909
+ );
7910
+ }
7911
+ const entry = params.entry;
7912
+ if (!entry || typeof entry !== "object") {
7913
+ throw new Error("address_book remove: missing entry");
7914
+ }
7915
+ const chainName = entry.chain;
7916
+ const chain = chainName ? resolveChain(chainName) : void 0;
7917
+ if (!chain) throw new Error(`address_book remove: unknown chain: ${chainName ?? "(missing)"}`);
7918
+ let address = entry.address;
7919
+ if (!address) {
7920
+ const name = entry.name;
7921
+ if (!name) {
7922
+ throw new Error("address_book remove: entry.address or entry.name is required");
7923
+ }
7924
+ const book = await this.vultisig.getAddressBook(chain);
7925
+ const lower = name.toLowerCase();
7926
+ const matches = book.saved.filter((e) => e.name.toLowerCase() === lower && e.chain === chain);
7927
+ if (matches.length === 0) {
7928
+ throw new Error(`address_book remove: no saved entry named "${name}" on ${chainName}`);
7929
+ }
7930
+ if (matches.length > 1) {
7931
+ const addrs = matches.map((m) => m.address).join(", ");
7932
+ throw new Error(
7933
+ `address_book remove: ambiguous name "${name}" on ${chainName} \u2014 multiple addresses: ${addrs}. Specify entry.address explicitly.`
7934
+ );
7935
+ }
7936
+ address = matches[0].address;
7937
+ }
7938
+ await this.vultisig.removeAddressBookEntry([{ chain, address }]);
7939
+ return { removed: { chain: chain.toString(), address } };
7826
7940
  }
7827
7941
  // ============================================================================
7828
7942
  // Token Search & Other
@@ -7983,13 +8097,24 @@ function resolveChainFromTxReady(txReadyData) {
7983
8097
  const chain = resolveChainId(txReadyData.chain_id);
7984
8098
  if (chain) return chain;
7985
8099
  }
7986
- const swapTx = txReadyData.swap_tx || txReadyData.send_tx || txReadyData.tx;
8100
+ if (txReadyData.txArgs?.chain) {
8101
+ const chain = resolveChain(txReadyData.txArgs.chain);
8102
+ if (chain) return chain;
8103
+ }
8104
+ if (txReadyData.txArgs?.chain_id) {
8105
+ const chain = resolveChainId(txReadyData.txArgs.chain_id);
8106
+ if (chain) return chain;
8107
+ }
8108
+ const swapTx = extractNestedTx(txReadyData);
7987
8109
  if (swapTx?.chainId) {
7988
8110
  const chain = resolveChainId(swapTx.chainId);
7989
8111
  if (chain) return chain;
7990
8112
  }
7991
8113
  return null;
7992
8114
  }
8115
+ function extractNestedTx(txReadyData) {
8116
+ return txReadyData?.swap_tx || txReadyData?.send_tx || txReadyData?.tx || txReadyData?.txArgs?.tx;
8117
+ }
7993
8118
  function resolveChainId(chainId) {
7994
8119
  const id = typeof chainId === "string" ? parseInt(chainId, 10) : chainId;
7995
8120
  if (isNaN(id)) return null;
@@ -8384,12 +8509,9 @@ import { join as join2 } from "node:path";
8384
8509
  import { MemoryStorage, PushNotificationService } from "@vultisig/sdk";
8385
8510
  var CLIENT_SIDE_TOOL_DISPATCH = {
8386
8511
  sign_typed_data: "sign_typed_data",
8387
- add_coin: "add_coin",
8388
- remove_coin: "remove_coin",
8389
- add_chain: "add_chain",
8390
- remove_chain: "remove_chain",
8391
- address_book_add: "address_book_add",
8392
- address_book_remove: "address_book_remove"
8512
+ vault_coin: "vault_coin",
8513
+ vault_chain: "vault_chain",
8514
+ address_book: "address_book"
8393
8515
  };
8394
8516
  var MAX_MESSAGE_LOOP_DEPTH = 16;
8395
8517
  function actionResultToRecentAction(r) {
@@ -8419,6 +8541,9 @@ var AgentSession = class {
8419
8541
  this.config = config;
8420
8542
  this.client = new AgentClient(config.backendUrl);
8421
8543
  this.client.verbose = !!config.verbose;
8544
+ if (config.profile) {
8545
+ this.client.setProfile(config.profile);
8546
+ }
8422
8547
  this.executor = new AgentExecutor(vault, !!config.verbose, vault.publicKeys.ecdsa, config.vultisig);
8423
8548
  this.publicKey = vault.publicKeys.ecdsa;
8424
8549
  if (config.password) {
@@ -8447,7 +8572,6 @@ var AgentSession = class {
8447
8572
  this.client.setAuthToken(auth.token);
8448
8573
  saveCachedToken(this.publicKey, auth.token, auth.expiresAt);
8449
8574
  }
8450
- this.executor.setBackendClient(this.client);
8451
8575
  } catch (err) {
8452
8576
  throw new Error(`Authentication failed: ${err.message}`);
8453
8577
  }
@@ -9204,7 +9328,8 @@ async function executeAgent(ctx2, options) {
9204
9328
  viaAgent: options.viaAgent,
9205
9329
  sessionId: options.sessionId,
9206
9330
  verbose: options.verbose,
9207
- notificationUrl: options.notificationUrl || process.env.VULTISIG_NOTIFICATION_URL || ""
9331
+ notificationUrl: options.notificationUrl || process.env.VULTISIG_NOTIFICATION_URL || "",
9332
+ profile: options.profile ?? process.env.VULTISIG_AGENT_PROFILE ?? ""
9208
9333
  };
9209
9334
  const session = new AgentSession(vault, config);
9210
9335
  if (options.viaAgent) {
@@ -9247,7 +9372,8 @@ async function executeAgentAsk(ctx2, message, options) {
9247
9372
  password: options.password,
9248
9373
  sessionId: options.session,
9249
9374
  verbose: options.verbose,
9250
- askMode: true
9375
+ askMode: true,
9376
+ profile: options.profile ?? process.env.VULTISIG_AGENT_PROFILE ?? ""
9251
9377
  };
9252
9378
  const session = new AgentSession(vault, config);
9253
9379
  const ask = new AskInterface(session, !!config.verbose);
@@ -9377,7 +9503,7 @@ var cachedVersion = null;
9377
9503
  function getVersion() {
9378
9504
  if (cachedVersion) return cachedVersion;
9379
9505
  if (true) {
9380
- cachedVersion = "0.22.3";
9506
+ cachedVersion = "0.22.4";
9381
9507
  return cachedVersion;
9382
9508
  }
9383
9509
  try {
@@ -12071,7 +12197,7 @@ rujiraCmd.command("withdraw <asset> <amount> <l1Address>").description("Withdraw
12071
12197
  }
12072
12198
  )
12073
12199
  );
12074
- 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").action(
12200
+ 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(
12075
12201
  async (options) => {
12076
12202
  const MAX_TTL = 864e5;
12077
12203
  let passwordTTL;
@@ -12093,16 +12219,18 @@ var agentCmd = program.command("agent").description("AI-powered chat interface f
12093
12219
  backendUrl: options.backendUrl,
12094
12220
  password: options.password,
12095
12221
  sessionId: options.sessionId,
12096
- notificationUrl: options.notificationUrl
12222
+ notificationUrl: options.notificationUrl,
12223
+ profile: options.profile
12097
12224
  });
12098
12225
  }
12099
12226
  );
12100
- 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)").addHelpText(
12227
+ 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").addHelpText(
12101
12228
  "after",
12102
12229
  `
12103
12230
  Examples:
12104
12231
  vultisig agent ask "What is my ETH balance?" --output json
12105
- vultisig agent ask "Send 0.1 ETH to 0x..." --session abc123 --yes`
12232
+ vultisig agent ask "Send 0.1 ETH to 0x..." --session abc123
12233
+ vultisig agent ask "..." --profile station-wallet`
12106
12234
  ).action(
12107
12235
  async (message, options) => {
12108
12236
  const parentOpts = agentCmd.opts();
@@ -12111,7 +12239,8 @@ Examples:
12111
12239
  ...options,
12112
12240
  backendUrl: options.backendUrl || parentOpts.backendUrl,
12113
12241
  password: options.password || parentOpts.password,
12114
- verbose: options.verbose || parentOpts.verbose
12242
+ verbose: options.verbose || parentOpts.verbose,
12243
+ profile: options.profile ?? parentOpts.profile
12115
12244
  });
12116
12245
  }
12117
12246
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/cli",
3
- "version": "0.22.3",
3
+ "version": "0.22.4",
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": {
@@ -71,11 +71,11 @@
71
71
  "@cosmjs/encoding": "^0.38.1",
72
72
  "@cosmjs/proto-signing": "^0.38.1",
73
73
  "@cosmjs/stargate": "^0.38.1",
74
- "@napi-rs/keyring": "^1.2.0",
74
+ "@napi-rs/keyring": "^1.3.0",
75
75
  "@noble/hashes": "^2.0.1",
76
76
  "@vultisig/client-shared": "^0.2.6",
77
- "@vultisig/core-chain": "^1.5.1",
78
- "@vultisig/rujira": "^17.0.0",
77
+ "@vultisig/core-chain": "^1.6.0",
78
+ "@vultisig/rujira": "^17.0.1",
79
79
  "@vultisig/sdk": "^0.22.3",
80
80
  "chalk": "^5.6.2",
81
81
  "cli-table3": "^0.6.5",
@@ -94,7 +94,7 @@
94
94
  "@types/ws": "^8.18.1",
95
95
  "esbuild": "^0.27.4",
96
96
  "tsx": "^4.21.0",
97
- "typescript": "^5.9.3",
97
+ "typescript": "^6.0.3",
98
98
  "vitest": "^4.1.5"
99
99
  },
100
100
  "engines": {