@vultisig/cli 0.22.5 → 0.22.7

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 +10 -0
  2. package/dist/index.js +850 -31
  3. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @vultisig/cli
2
2
 
3
+ ## 0.22.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [#457](https://github.com/vultisig/vultisig-sdk/pull/457) [`680119e`](https://github.com/vultisig/vultisig-sdk/commit/680119e7392921b8aeaf859c85e811fb40a25054) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Add regression tests and drift guards for Bitcoin PSBT compilation, ChainKind signing-input alignment, generated protobuf headers, and CLI agent action names aligned with AGENTS.md.
8
+
9
+ - Updated dependencies [[`680119e`](https://github.com/vultisig/vultisig-sdk/commit/680119e7392921b8aeaf859c85e811fb40a25054), [`5102976`](https://github.com/vultisig/vultisig-sdk/commit/5102976d7c13fa9578bbbc6e5122526cefc1ec66), [`b36eb62`](https://github.com/vultisig/vultisig-sdk/commit/b36eb62842051b8b2bae06f1e123a5ebcf6cad88)]:
10
+ - @vultisig/sdk@0.22.7
11
+ - @vultisig/core-chain@1.7.1
12
+
3
13
  ## 0.22.5
4
14
 
5
15
  ### Patch Changes
package/dist/index.js CHANGED
@@ -5395,8 +5395,399 @@ function getNativeTokenDecimals(chain) {
5395
5395
  return decimals[chain] || 18;
5396
5396
  }
5397
5397
 
5398
+ // ../../packages/core/chain/dist/Chain.js
5399
+ var EthereumL2Chain = {
5400
+ Arbitrum: "Arbitrum",
5401
+ Base: "Base",
5402
+ Blast: "Blast",
5403
+ Optimism: "Optimism",
5404
+ Zksync: "Zksync",
5405
+ Mantle: "Mantle"
5406
+ };
5407
+ var EvmChain = {
5408
+ ...EthereumL2Chain,
5409
+ Avalanche: "Avalanche",
5410
+ CronosChain: "CronosChain",
5411
+ BSC: "BSC",
5412
+ Ethereum: "Ethereum",
5413
+ Polygon: "Polygon",
5414
+ Hyperliquid: "Hyperliquid",
5415
+ Sei: "Sei"
5416
+ };
5417
+ var UtxoChain;
5418
+ (function(UtxoChain2) {
5419
+ UtxoChain2["Bitcoin"] = "Bitcoin";
5420
+ UtxoChain2["BitcoinCash"] = "Bitcoin-Cash";
5421
+ UtxoChain2["Litecoin"] = "Litecoin";
5422
+ UtxoChain2["Dogecoin"] = "Dogecoin";
5423
+ UtxoChain2["Dash"] = "Dash";
5424
+ UtxoChain2["Zcash"] = "Zcash";
5425
+ })(UtxoChain || (UtxoChain = {}));
5426
+ var cosmosChainsByKind = {
5427
+ ibcEnabled: {
5428
+ Cosmos: "Cosmos",
5429
+ Osmosis: "Osmosis",
5430
+ Dydx: "Dydx",
5431
+ Kujira: "Kujira",
5432
+ Terra: "Terra",
5433
+ TerraClassic: "TerraClassic",
5434
+ Noble: "Noble",
5435
+ Akash: "Akash"
5436
+ },
5437
+ vaultBased: {
5438
+ THORChain: "THORChain",
5439
+ MayaChain: "MayaChain"
5440
+ }
5441
+ };
5442
+ var IbcEnabledCosmosChain = cosmosChainsByKind.ibcEnabled;
5443
+ var VaultBasedCosmosChain = cosmosChainsByKind.vaultBased;
5444
+ var CosmosChain = {
5445
+ ...IbcEnabledCosmosChain,
5446
+ ...VaultBasedCosmosChain
5447
+ };
5448
+ var OtherChain;
5449
+ (function(OtherChain2) {
5450
+ OtherChain2["Sui"] = "Sui";
5451
+ OtherChain2["Solana"] = "Solana";
5452
+ OtherChain2["Polkadot"] = "Polkadot";
5453
+ OtherChain2["Bittensor"] = "Bittensor";
5454
+ OtherChain2["Ton"] = "Ton";
5455
+ OtherChain2["Ripple"] = "Ripple";
5456
+ OtherChain2["Tron"] = "Tron";
5457
+ OtherChain2["Cardano"] = "Cardano";
5458
+ OtherChain2["QBTC"] = "QBTC";
5459
+ })(OtherChain || (OtherChain = {}));
5460
+ var Chain9 = {
5461
+ ...EvmChain,
5462
+ ...UtxoChain,
5463
+ ...CosmosChain,
5464
+ ...OtherChain
5465
+ };
5466
+ var UtxoBasedChain = [
5467
+ ...Object.values(UtxoChain),
5468
+ OtherChain.Cardano
5469
+ ];
5470
+ var defaultChains = [
5471
+ Chain9.Bitcoin,
5472
+ Chain9.Ethereum,
5473
+ Chain9.THORChain,
5474
+ Chain9.Solana,
5475
+ Chain9.BSC
5476
+ ];
5477
+
5478
+ // ../../packages/core/chain/dist/ChainKind.js
5479
+ var chainKindRecord = {
5480
+ [EvmChain.Arbitrum]: "evm",
5481
+ [EvmChain.Avalanche]: "evm",
5482
+ [EvmChain.Base]: "evm",
5483
+ [EvmChain.CronosChain]: "evm",
5484
+ [EvmChain.BSC]: "evm",
5485
+ [EvmChain.Blast]: "evm",
5486
+ [EvmChain.Ethereum]: "evm",
5487
+ [EvmChain.Optimism]: "evm",
5488
+ [EvmChain.Polygon]: "evm",
5489
+ [EvmChain.Zksync]: "evm",
5490
+ [EvmChain.Mantle]: "evm",
5491
+ [EvmChain.Hyperliquid]: "evm",
5492
+ [EvmChain.Sei]: "evm",
5493
+ [UtxoChain.Bitcoin]: "utxo",
5494
+ [UtxoChain.BitcoinCash]: "utxo",
5495
+ [UtxoChain.Litecoin]: "utxo",
5496
+ [UtxoChain.Dogecoin]: "utxo",
5497
+ [UtxoChain.Dash]: "utxo",
5498
+ [UtxoChain.Zcash]: "utxo",
5499
+ [CosmosChain.THORChain]: "cosmos",
5500
+ [CosmosChain.Cosmos]: "cosmos",
5501
+ [CosmosChain.Osmosis]: "cosmos",
5502
+ [CosmosChain.MayaChain]: "cosmos",
5503
+ [CosmosChain.Dydx]: "cosmos",
5504
+ [CosmosChain.Kujira]: "cosmos",
5505
+ [CosmosChain.Terra]: "cosmos",
5506
+ [CosmosChain.TerraClassic]: "cosmos",
5507
+ [CosmosChain.Noble]: "cosmos",
5508
+ [CosmosChain.Akash]: "cosmos",
5509
+ [OtherChain.Sui]: "sui",
5510
+ [OtherChain.Solana]: "solana",
5511
+ [OtherChain.Polkadot]: "polkadot",
5512
+ [OtherChain.Bittensor]: "bittensor",
5513
+ [OtherChain.Ton]: "ton",
5514
+ [OtherChain.Ripple]: "ripple",
5515
+ [OtherChain.Tron]: "tron",
5516
+ [OtherChain.Cardano]: "cardano",
5517
+ [OtherChain.QBTC]: "qbtc"
5518
+ };
5519
+ function getChainKind(chain) {
5520
+ return chainKindRecord[chain];
5521
+ }
5522
+
5523
+ // ../../packages/lib/utils/dist/record/recordMap.js
5524
+ function recordMap(record, fn) {
5525
+ return Object.fromEntries(Object.entries(record).map(([key, value]) => [
5526
+ key,
5527
+ fn(value, key)
5528
+ ]));
5529
+ }
5530
+
5531
+ // ../../packages/lib/utils/dist/record/makeRecord/index.js
5532
+ var makeRecord = (keys, getValue) => {
5533
+ const record = {};
5534
+ keys.forEach((key, index) => {
5535
+ record[key] = getValue(key, index);
5536
+ });
5537
+ return record;
5538
+ };
5539
+
5540
+ // ../../packages/core/chain/dist/chains/cosmos/thor/kujira-merge/index.js
5541
+ var kujiraCoinsMigratedToThorChain = [
5542
+ "kuji",
5543
+ "rkuji",
5544
+ "fuzn",
5545
+ "nstk",
5546
+ "wink",
5547
+ "lvn"
5548
+ ];
5549
+ var kujiraCoinsMigratedToThorChainMetadata = {
5550
+ kuji: {
5551
+ ticker: "KUJI",
5552
+ logo: "kuji",
5553
+ priceProviderId: "kujira"
5554
+ },
5555
+ rkuji: {
5556
+ ticker: "rKUJI",
5557
+ logo: "rkuji.png",
5558
+ priceProviderId: "kujira"
5559
+ },
5560
+ fuzn: {
5561
+ ticker: "FUZN",
5562
+ logo: "fuzn.png",
5563
+ priceProviderId: "fuzion"
5564
+ },
5565
+ lvn: {
5566
+ ticker: "LVN",
5567
+ logo: "levana",
5568
+ priceProviderId: "levana-protocol"
5569
+ },
5570
+ nstk: {
5571
+ ticker: "NSTK",
5572
+ logo: "nstk.png",
5573
+ priceProviderId: "unstake-fi"
5574
+ },
5575
+ wink: {
5576
+ ticker: "WINK",
5577
+ logo: "wink.png",
5578
+ priceProviderId: "winkhub"
5579
+ }
5580
+ };
5581
+ var kujiraCoinMigratedToThorChainDestinationId = makeRecord(kujiraCoinsMigratedToThorChain, (id) => `thor.${id}`);
5582
+
5583
+ // ../../packages/core/chain/dist/coin/chainFeeCoin.js
5584
+ var ether = {
5585
+ ticker: "ETH",
5586
+ logo: "eth",
5587
+ decimals: 18,
5588
+ priceProviderId: "ethereum"
5589
+ };
5590
+ var leanChainFeeCoin = {
5591
+ [Chain9.Bitcoin]: {
5592
+ ticker: "BTC",
5593
+ logo: "btc",
5594
+ decimals: 8,
5595
+ priceProviderId: "bitcoin"
5596
+ },
5597
+ [Chain9.BitcoinCash]: {
5598
+ ticker: "BCH",
5599
+ logo: "bch",
5600
+ decimals: 8,
5601
+ priceProviderId: "bitcoin-cash"
5602
+ },
5603
+ [Chain9.Litecoin]: {
5604
+ ticker: "LTC",
5605
+ logo: "ltc",
5606
+ decimals: 8,
5607
+ priceProviderId: "litecoin"
5608
+ },
5609
+ [Chain9.Dogecoin]: {
5610
+ ticker: "DOGE",
5611
+ logo: "doge",
5612
+ decimals: 8,
5613
+ priceProviderId: "dogecoin"
5614
+ },
5615
+ [Chain9.Dash]: {
5616
+ ticker: "DASH",
5617
+ logo: "dash",
5618
+ decimals: 8,
5619
+ priceProviderId: "dash"
5620
+ },
5621
+ [Chain9.Ripple]: {
5622
+ ticker: "XRP",
5623
+ logo: "xrp",
5624
+ decimals: 6,
5625
+ priceProviderId: "ripple"
5626
+ },
5627
+ [Chain9.THORChain]: {
5628
+ ticker: "RUNE",
5629
+ logo: "rune",
5630
+ decimals: 8,
5631
+ priceProviderId: "thorchain"
5632
+ },
5633
+ [Chain9.MayaChain]: {
5634
+ ticker: "CACAO",
5635
+ logo: "cacao",
5636
+ decimals: 10,
5637
+ priceProviderId: "cacao"
5638
+ },
5639
+ [Chain9.Solana]: {
5640
+ ticker: "SOL",
5641
+ logo: "solana",
5642
+ decimals: 9,
5643
+ priceProviderId: "solana"
5644
+ },
5645
+ [Chain9.Ton]: {
5646
+ ticker: "TON",
5647
+ logo: "ton",
5648
+ decimals: 9,
5649
+ priceProviderId: "the-open-network"
5650
+ },
5651
+ [Chain9.Ethereum]: ether,
5652
+ [Chain9.Avalanche]: {
5653
+ ticker: "AVAX",
5654
+ logo: "avax",
5655
+ decimals: 18,
5656
+ priceProviderId: "avalanche-2"
5657
+ },
5658
+ [Chain9.BSC]: {
5659
+ ticker: "BNB",
5660
+ logo: "bsc",
5661
+ decimals: 18,
5662
+ priceProviderId: "binancecoin"
5663
+ },
5664
+ [Chain9.Polygon]: {
5665
+ ticker: "POL",
5666
+ logo: "polygon",
5667
+ decimals: 18,
5668
+ priceProviderId: "polygon-ecosystem-token"
5669
+ },
5670
+ [Chain9.CronosChain]: {
5671
+ ticker: "CRO",
5672
+ logo: "cro",
5673
+ decimals: 18,
5674
+ priceProviderId: "crypto-com-chain"
5675
+ },
5676
+ [Chain9.Dydx]: {
5677
+ ticker: "DYDX",
5678
+ logo: "dydx",
5679
+ decimals: 18,
5680
+ priceProviderId: "dydx-chain"
5681
+ },
5682
+ [Chain9.Kujira]: {
5683
+ ...kujiraCoinsMigratedToThorChainMetadata.kuji,
5684
+ decimals: 6
5685
+ },
5686
+ [Chain9.Terra]: {
5687
+ ticker: "LUNA",
5688
+ logo: "luna",
5689
+ decimals: 6,
5690
+ priceProviderId: "terra-luna-2"
5691
+ },
5692
+ [Chain9.TerraClassic]: {
5693
+ ticker: "LUNC",
5694
+ logo: "lunc",
5695
+ decimals: 6,
5696
+ priceProviderId: "terra-luna"
5697
+ },
5698
+ [Chain9.Sui]: {
5699
+ ticker: "SUI",
5700
+ logo: "sui",
5701
+ decimals: 9,
5702
+ priceProviderId: "sui"
5703
+ },
5704
+ [Chain9.Polkadot]: {
5705
+ ticker: "DOT",
5706
+ logo: "dot",
5707
+ decimals: 10,
5708
+ priceProviderId: "polkadot"
5709
+ },
5710
+ [Chain9.Bittensor]: {
5711
+ ticker: "TAO",
5712
+ logo: "bittensor",
5713
+ decimals: 9,
5714
+ priceProviderId: "bittensor"
5715
+ },
5716
+ [Chain9.Noble]: {
5717
+ ticker: "USDC",
5718
+ logo: "noble",
5719
+ decimals: 6,
5720
+ priceProviderId: "usd-coin"
5721
+ },
5722
+ [Chain9.Akash]: {
5723
+ ticker: "AKT",
5724
+ logo: "akash",
5725
+ decimals: 6,
5726
+ priceProviderId: "akash-network"
5727
+ },
5728
+ [Chain9.Cosmos]: {
5729
+ ticker: "ATOM",
5730
+ logo: "atom",
5731
+ decimals: 6,
5732
+ priceProviderId: "cosmos"
5733
+ },
5734
+ [Chain9.Osmosis]: {
5735
+ ticker: "OSMO",
5736
+ logo: "osmo",
5737
+ decimals: 6,
5738
+ priceProviderId: "osmosis"
5739
+ },
5740
+ [Chain9.Tron]: {
5741
+ ticker: "TRX",
5742
+ logo: "tron",
5743
+ decimals: 6,
5744
+ priceProviderId: "tron"
5745
+ },
5746
+ ...recordMap(EthereumL2Chain, () => ether),
5747
+ [Chain9.Zcash]: {
5748
+ ticker: "ZEC",
5749
+ logo: "zec",
5750
+ decimals: 8,
5751
+ priceProviderId: "zcash"
5752
+ },
5753
+ [Chain9.Cardano]: {
5754
+ ticker: "ADA",
5755
+ logo: "ada",
5756
+ decimals: 6,
5757
+ priceProviderId: "cardano"
5758
+ },
5759
+ [Chain9.Mantle]: {
5760
+ ticker: "MNT",
5761
+ logo: "mantle",
5762
+ decimals: 18,
5763
+ priceProviderId: "mantle"
5764
+ },
5765
+ [Chain9.Hyperliquid]: {
5766
+ ticker: "HYPE",
5767
+ logo: "hyperliquid",
5768
+ decimals: 18,
5769
+ priceProviderId: "hyperliquid"
5770
+ },
5771
+ [Chain9.Sei]: {
5772
+ ticker: "SEI",
5773
+ logo: "sei",
5774
+ decimals: 18,
5775
+ priceProviderId: "sei-network"
5776
+ },
5777
+ [Chain9.QBTC]: {
5778
+ ticker: "QBTC",
5779
+ logo: "qbtc",
5780
+ decimals: 6,
5781
+ priceProviderId: "qbtc-testnet"
5782
+ }
5783
+ };
5784
+ var chainFeeCoin = recordMap(leanChainFeeCoin, (coin, chain) => ({
5785
+ ...coin,
5786
+ chain
5787
+ }));
5788
+
5398
5789
  // src/agent/executor.ts
5399
- import { Chain as Chain9, Vultisig as VultisigSdk } from "@vultisig/sdk";
5790
+ import { Chain as Chain10, VaultError as VaultError3, VaultErrorCode as VaultErrorCode3, Vultisig as VultisigSdk } from "@vultisig/sdk";
5400
5791
 
5401
5792
  // ../../node_modules/viem/_esm/index.js
5402
5793
  init_formatUnits();
@@ -5557,6 +5948,45 @@ function sleep2(ms) {
5557
5948
  }
5558
5949
 
5559
5950
  // src/agent/executor.ts
5951
+ var THOR_MEMO_CHAIN_TO_ENUM = {
5952
+ BTC: Chain10.Bitcoin,
5953
+ ETH: Chain10.Ethereum,
5954
+ BSC: Chain10.BSC,
5955
+ AVAX: Chain10.Avalanche,
5956
+ BASE: Chain10.Base,
5957
+ // L2 — THORChain routinely quotes Base destinations (PR #439 review finding 1)
5958
+ ARB: Chain10.Arbitrum,
5959
+ // L1-via-bridge path (PR #439 review finding 1)
5960
+ BCH: Chain10.BitcoinCash,
5961
+ LTC: Chain10.Litecoin,
5962
+ DOGE: Chain10.Dogecoin,
5963
+ GAIA: Chain10.Cosmos,
5964
+ THOR: Chain10.THORChain,
5965
+ RUNE: Chain10.THORChain,
5966
+ XRP: Chain10.Ripple,
5967
+ DASH: Chain10.Dash,
5968
+ ZEC: Chain10.Zcash,
5969
+ MAYA: Chain10.MayaChain,
5970
+ CACAO: Chain10.MayaChain
5971
+ };
5972
+ var THOR_MEMO_ASSET_SHORTCUTS = {
5973
+ b: "BTC.BTC",
5974
+ e: "ETH.ETH",
5975
+ s: "BSC.BNB",
5976
+ a: "AVAX.AVAX",
5977
+ c: "BCH.BCH",
5978
+ l: "LTC.LTC",
5979
+ d: "DOGE.DOGE",
5980
+ g: "GAIA.ATOM",
5981
+ r: "THOR.RUNE",
5982
+ x: "XRP.XRP",
5983
+ cacao: "MAYA.CACAO",
5984
+ dash: "DASH.DASH",
5985
+ zec: "ZEC.ZEC"
5986
+ // BASE / ARB don't have documented single-letter shortcuts; THORChain
5987
+ // emits these as the full CHAIN.ASSET form in memos. Listed in
5988
+ // THOR_MEMO_CHAIN_TO_ENUM only.
5989
+ };
5560
5990
  var EVM_CHAINS = /* @__PURE__ */ new Set([
5561
5991
  "Ethereum",
5562
5992
  "BSC",
@@ -5592,6 +6022,12 @@ var AgentExecutor = class {
5592
6022
  /** Owning SDK (optional); used for address book backed by app storage */
5593
6023
  vultisig;
5594
6024
  pendingPayloads = /* @__PURE__ */ new Map();
6025
+ /**
6026
+ * Buffered legs for a 2-leg mcp-ts execute_* envelope (approve + main).
6027
+ * Populated by storeServerTransaction when both `approvalTxArgs` and
6028
+ * `txArgs` are present; consumed and cleared by signMultiLeg.
6029
+ */
6030
+ pendingLegs = [];
5595
6031
  password = null;
5596
6032
  verbose;
5597
6033
  stateStore = null;
@@ -5621,13 +6057,46 @@ var AgentExecutor = class {
5621
6057
  `[executor] storeServerTransaction called, keys: ${Object.keys(txReadyData || {}).join(",")}
5622
6058
  `
5623
6059
  );
5624
- if (txReadyData?.approvalTxArgs) {
5625
- if (this.verbose)
5626
- process.stderr.write(
5627
- `[executor] skipping multi-leg execute_swap envelope (approvalTxArgs present): not yet supported in sdk-cli \u2014 Phase B
6060
+ if (txReadyData?.approvalTxArgs && txReadyData?.txArgs) {
6061
+ const approvalChain = resolveChainFromTxReady(txReadyData.approvalTxArgs);
6062
+ const mainChain = resolveChainFromTxReady(txReadyData.txArgs);
6063
+ const parentChain = resolveChainFromTxReady(txReadyData);
6064
+ if (!approvalChain || !mainChain || approvalChain !== mainChain || parentChain && parentChain !== approvalChain) {
6065
+ if (this.verbose)
6066
+ process.stderr.write(
6067
+ `[executor] rejecting multi-leg envelope with inconsistent chain metadata: parent=${parentChain ?? "unresolved"} approval=${approvalChain ?? "unresolved"} main=${mainChain ?? "unresolved"}
5628
6068
  `
5629
- );
5630
- return false;
6069
+ );
6070
+ return false;
6071
+ }
6072
+ const chain2 = approvalChain;
6073
+ if (!EVM_CHAINS.has(chain2)) {
6074
+ if (this.verbose)
6075
+ process.stderr.write(
6076
+ `[executor] rejecting multi-leg envelope on non-EVM chain ${chain2}: signMultiLeg is EVM-only
6077
+ `
6078
+ );
6079
+ return false;
6080
+ }
6081
+ this.pendingLegs = [
6082
+ {
6083
+ txArgs: txReadyData.approvalTxArgs,
6084
+ parent: txReadyData,
6085
+ kind: "approve"
6086
+ },
6087
+ { txArgs: txReadyData.txArgs, parent: txReadyData, kind: "main" }
6088
+ ];
6089
+ this.pendingPayloads.clear();
6090
+ this.pendingPayloads.set("latest", {
6091
+ payload: { __serverTx: true, __multiLeg: true, ...txReadyData },
6092
+ coin: { chain: chain2, address: "", decimals: 18, ticker: "" },
6093
+ chain: chain2,
6094
+ timestamp: Date.now()
6095
+ });
6096
+ if (this.verbose)
6097
+ process.stderr.write(`[executor] stored multi-leg envelope: chain=${chain2}, legs=2 (approve, main)
6098
+ `);
6099
+ return true;
5631
6100
  }
5632
6101
  const nestedTx = extractNestedTx(txReadyData);
5633
6102
  if (nestedTx?.status === "error" || nestedTx?.error) {
@@ -5636,13 +6105,34 @@ var AgentExecutor = class {
5636
6105
  `);
5637
6106
  return false;
5638
6107
  }
6108
+ if (!nestedTx && txReadyData && typeof txReadyData === "object") {
6109
+ const txArgs = txReadyData.txArgs;
6110
+ if (txArgs && typeof txArgs === "object" && typeof txArgs.to === "string" && typeof txArgs.amount === "string") {
6111
+ const chain2 = resolveChainFromTxReady(txReadyData) || Chain10.Ethereum;
6112
+ if (getChainKind(chain2) !== "evm") {
6113
+ this.pendingPayloads.clear();
6114
+ this.pendingPayloads.set("latest", {
6115
+ payload: { __serverTx: true, ...txReadyData },
6116
+ coin: { chain: chain2, address: "", decimals: 18, ticker: "" },
6117
+ chain: chain2,
6118
+ timestamp: Date.now()
6119
+ });
6120
+ if (this.verbose)
6121
+ process.stderr.write(
6122
+ `[executor] Stored non-EVM server tx for chain ${chain2} (kind=${getChainKind(chain2)})
6123
+ `
6124
+ );
6125
+ return true;
6126
+ }
6127
+ }
6128
+ }
5639
6129
  if (!nestedTx) {
5640
6130
  if (this.verbose)
5641
6131
  process.stderr.write(`[executor] storeServerTransaction: no swap_tx/send_tx/tx/txArgs.tx found in data
5642
6132
  `);
5643
6133
  return false;
5644
6134
  }
5645
- const chain = resolveChainFromTxReady(txReadyData) || Chain9.Ethereum;
6135
+ const chain = resolveChainFromTxReady(txReadyData) || Chain10.Ethereum;
5646
6136
  this.pendingPayloads.clear();
5647
6137
  this.pendingPayloads.set("latest", {
5648
6138
  payload: { __serverTx: true, ...txReadyData },
@@ -5871,7 +6361,16 @@ var AgentExecutor = class {
5871
6361
  throw new Error("Pending transaction is not a server-built tx (no __serverTx flag).");
5872
6362
  }
5873
6363
  let result;
5874
- if (chain === "Solana" && (payload.swap_tx || payload.provider)) {
6364
+ if (payload.__multiLeg) {
6365
+ if (this.pendingLegs.length !== 2) {
6366
+ throw new VaultError3(
6367
+ VaultErrorCode3.InvalidConfig,
6368
+ `signMultiLeg: expected 2 pending legs, got ${this.pendingLegs.length}`
6369
+ );
6370
+ }
6371
+ result = await this.signMultiLeg(payload, chain, {});
6372
+ }
6373
+ if (!result && chain === "Solana" && (payload.swap_tx || payload.provider)) {
5875
6374
  try {
5876
6375
  result = await this.buildAndSignSolanaSwapLocally(payload);
5877
6376
  } catch (e) {
@@ -5890,10 +6389,170 @@ var AgentExecutor = class {
5890
6389
  });
5891
6390
  }
5892
6391
  /**
5893
- * Sign and broadcast a server-built transaction (raw EVM tx from tx_ready SSE).
5894
- * Uses vault.prepareSendTx with memo field to carry the calldata.
6392
+ * Dispatch a server-built tx_ready envelope to the chain-kind-specific
6393
+ * signer. EVM stays in `signEvmServerTx` (the existing PR #422 + PR #435
6394
+ * code, with EVM nonce/lock plumbing). Non-EVM kinds parse the envelope
6395
+ * via `parseNonEvmEnvelope` and route through `vault.send`, which is
6396
+ * already chain-agnostic via `VaultBase.prepareSendTx` virtuals.
6397
+ *
6398
+ * Phase D — see task `100526-sdk-cli-non-evm-signing.md`.
5895
6399
  */
5896
6400
  async signServerTx(serverTxData, defaultChain, params) {
6401
+ const chain = resolveChainFromTxReady(serverTxData) || defaultChain;
6402
+ const chainKind = getChainKind(chain);
6403
+ if (chainKind === "evm") {
6404
+ return this.signEvmServerTx(serverTxData, defaultChain, params);
6405
+ }
6406
+ return this.signNonEvmServerTx(serverTxData, chain);
6407
+ }
6408
+ /**
6409
+ * Non-EVM signing path: parse the agent's tx_ready envelope into a
6410
+ * `vault.send`-shaped argument bag and call through. The SDK already
6411
+ * handles per-chain prepare/sign/broadcast internally via
6412
+ * `VaultBase.prepareSendTx` virtuals — sdk-cli only owns envelope
6413
+ * parsing here, not chain-specific signing logic.
6414
+ *
6415
+ * THORChain / MayaChain MsgDeposit envelopes (msg_type='deposit',
6416
+ * to='') are routed through `vault.swap` because the agent's intent
6417
+ * is a swap — the memo (`=:CHAIN.ASSET:DEST::v0:slippage`) carries
6418
+ * the routing. We parse the memo to reconstruct vault.swap's
6419
+ * fromChain / fromSymbol / toChain / toSymbol / amount args. The SDK
6420
+ * then builds the MsgDeposit cosmos tx internally. Vultiagent uses an
6421
+ * equivalent custom helper (`buildSignBroadcastThorchainLpDeposit`);
6422
+ * we reuse the public `vault.swap` surface to avoid expanding the SDK.
6423
+ */
6424
+ async signNonEvmServerTx(serverTxData, chain) {
6425
+ if (this.vault.isEncrypted && !this.vault.isUnlocked?.()) {
6426
+ if (this.password) {
6427
+ await this.vault.unlock?.(this.password);
6428
+ }
6429
+ }
6430
+ const txArgs = serverTxData?.txArgs ?? {};
6431
+ if (typeof txArgs.chain === "string" && txArgs.chain !== chain) {
6432
+ throw new VaultError3(
6433
+ VaultErrorCode3.InvalidConfig,
6434
+ `signNonEvmServerTx: dispatcher chain '${chain}' disagrees with envelope chain '${txArgs.chain}'`
6435
+ );
6436
+ }
6437
+ if (txArgs.msg_type === "deposit" && (chain === Chain10.THORChain || chain === Chain10.MayaChain)) {
6438
+ return this.signThorMsgDepositSwap(serverTxData, chain);
6439
+ }
6440
+ const args = parseNonEvmEnvelope(serverTxData, chain);
6441
+ if (this.verbose)
6442
+ process.stderr.write(
6443
+ `[sign_non_evm_server_tx] chain=${chain}, to=${args.to}, amount=${args.amount}${args.symbol ? ` ${args.symbol}` : ""}, memo=${args.memo ? `"${args.memo}"` : "(none)"}
6444
+ `
6445
+ );
6446
+ const result = await this.vault.send({
6447
+ chain,
6448
+ to: args.to,
6449
+ amount: args.amount,
6450
+ symbol: args.symbol,
6451
+ memo: args.memo
6452
+ });
6453
+ if (result.dryRun) {
6454
+ throw new VaultError3(
6455
+ VaultErrorCode3.InvalidConfig,
6456
+ "signNonEvmServerTx: vault.send unexpectedly returned dryRun result"
6457
+ );
6458
+ }
6459
+ this.pendingPayloads.clear();
6460
+ const broadcast = result;
6461
+ const explorerUrl = VultisigSdk.getTxExplorerUrl(chain, broadcast.txHash);
6462
+ return {
6463
+ tx_hash: broadcast.txHash,
6464
+ chain: chain.toString(),
6465
+ status: "pending",
6466
+ explorer_url: explorerUrl
6467
+ };
6468
+ }
6469
+ /**
6470
+ * Sign and broadcast a THORChain / MayaChain MsgDeposit-style swap
6471
+ * envelope by reconstructing `vault.swap` args from the memo.
6472
+ *
6473
+ * The agent emits envelopes shaped:
6474
+ * { txArgs: { chain: 'THORChain', tx_encoding: 'cosmos-msg',
6475
+ * to: '', amount: '<base>', denom: 'rune',
6476
+ * memo: '=:DEST_CHAIN.DEST_ASSET:DEST_ADDR::v0:slippage_bps',
6477
+ * msg_type: 'deposit' } }
6478
+ *
6479
+ * The memo is THORChain's standard swap memo. We parse out the
6480
+ * destination chain + asset, look up the corresponding `Chain` enum,
6481
+ * then call `vault.swap` which builds the MsgDeposit internally.
6482
+ *
6483
+ * IMPORTANT — destination address handling: `vault.swap` re-derives the
6484
+ * destination address from `vault.address(toChain)` when fetching the
6485
+ * native swap quote (see `findSwapQuote` → `getNativeSwapQuote` —
6486
+ * `destination: to.address`). It does NOT honor the destination address
6487
+ * encoded in the envelope's memo. As a fund-safety guard we therefore
6488
+ * require the memo's destination address to match the vault's own
6489
+ * destination address (self-swap) and throw otherwise — see Phase D
6490
+ * review F1. Cross-account routing must wait on a Phase E SDK extension
6491
+ * that lets `vault.swap` accept a user-supplied destination.
6492
+ */
6493
+ async signThorMsgDepositSwap(serverTxData, chain) {
6494
+ const txArgs = serverTxData?.txArgs ?? {};
6495
+ const memo = typeof txArgs.memo === "string" ? txArgs.memo : "";
6496
+ const parsed = parseThorSwapMemo(memo);
6497
+ const toChain = THOR_MEMO_CHAIN_TO_ENUM[parsed.destChainCode];
6498
+ if (!toChain) {
6499
+ throw new VaultError3(
6500
+ VaultErrorCode3.UnsupportedChain,
6501
+ `signThorMsgDepositSwap: unsupported destination chain code '${parsed.destChainCode}' in memo '${memo}'.`
6502
+ );
6503
+ }
6504
+ const vaultDestAddress = await this.vault.address(toChain);
6505
+ const normalizeForCompare = (addr) => EVM_CHAINS.has(toChain) ? addr.toLowerCase() : addr;
6506
+ if (parsed.destAddress && normalizeForCompare(parsed.destAddress) !== normalizeForCompare(vaultDestAddress)) {
6507
+ throw new VaultError3(
6508
+ VaultErrorCode3.NotImplemented,
6509
+ `signThorMsgDepositSwap: memo destination '${parsed.destAddress}' does not match vault address '${vaultDestAddress}' on ${toChain}. Phase D only supports self-swaps; cross-account routing requires a Phase E SDK extension that passes the user-supplied destination through to vault.swap.`
6510
+ );
6511
+ }
6512
+ const fromSymbol = chain === Chain10.THORChain ? "RUNE" : "CACAO";
6513
+ const amountRaw = typeof txArgs.amount === "string" ? txArgs.amount : void 0;
6514
+ if (!amountRaw) {
6515
+ throw new VaultError3(
6516
+ VaultErrorCode3.InvalidConfig,
6517
+ `signThorMsgDepositSwap: missing or non-string 'amount' field on ${chain} envelope`
6518
+ );
6519
+ }
6520
+ const amountDecimal = convertBaseUnitsToDecimal(chain, amountRaw, "signThorMsgDepositSwap");
6521
+ if (this.verbose)
6522
+ process.stderr.write(
6523
+ `[sign_thor_msg_deposit_swap] ${fromSymbol}@${chain} \u2192 ${parsed.destAsset}@${toChain}, amount=${amountDecimal}, memo='${memo}'
6524
+ `
6525
+ );
6526
+ const result = await this.vault.swap({
6527
+ fromChain: chain,
6528
+ fromSymbol,
6529
+ toChain,
6530
+ toSymbol: parsed.destAsset,
6531
+ amount: amountDecimal
6532
+ });
6533
+ if (result.dryRun) {
6534
+ throw new VaultError3(
6535
+ VaultErrorCode3.InvalidConfig,
6536
+ "signThorMsgDepositSwap: vault.swap unexpectedly returned dryRun result"
6537
+ );
6538
+ }
6539
+ this.pendingPayloads.clear();
6540
+ const broadcast = result;
6541
+ const explorerUrl = VultisigSdk.getTxExplorerUrl(chain, broadcast.txHash);
6542
+ return {
6543
+ tx_hash: broadcast.txHash,
6544
+ chain: chain.toString(),
6545
+ status: "pending",
6546
+ explorer_url: explorerUrl
6547
+ };
6548
+ }
6549
+ /**
6550
+ * Sign and broadcast a server-built EVM transaction (raw EVM tx from
6551
+ * tx_ready SSE). Uses vault.prepareSendTx with memo field to carry the
6552
+ * calldata, plus EVM-specific nonce/lock plumbing that Phase B's
6553
+ * `signMultiLeg` depends on for back-to-back approve+main broadcasts.
6554
+ */
6555
+ async signEvmServerTx(serverTxData, defaultChain, params) {
5897
6556
  const swapTx = extractNestedTx(serverTxData);
5898
6557
  if (!swapTx?.to) {
5899
6558
  throw new Error("Server transaction missing required fields (to)");
@@ -5987,6 +6646,97 @@ var AgentExecutor = class {
5987
6646
  throw err;
5988
6647
  }
5989
6648
  }
6649
+ /**
6650
+ * Sign and broadcast a 2-leg ERC-20 approve + main flow originating from
6651
+ * mcp-ts `execute_*` envelopes that carry both `approvalTxArgs` and
6652
+ * `txArgs`. Mirrors vultiagent's `useTransactionFlow`: leg 1 (approve) is
6653
+ * signed and broadcast first, the receipt is awaited, then leg 2 (main)
6654
+ * is signed and broadcast. Fails closed if the approve doesn't confirm
6655
+ * — the main leg is NEVER broadcast against a stale or failed allowance.
6656
+ *
6657
+ * Phase B is intentionally EVM-only; non-EVM 2-leg flows are not a real
6658
+ * shape on mcp-ts today (Pattern 1 / Pattern 2 multi-leg flows are split
6659
+ * server-side via sequence_id and don't traverse this path).
6660
+ */
6661
+ async signMultiLeg(_payload, chain, params) {
6662
+ const [approveLeg, mainLeg] = this.pendingLegs;
6663
+ try {
6664
+ const approveEnvelope = {
6665
+ ...approveLeg.parent,
6666
+ txArgs: approveLeg.txArgs,
6667
+ approvalTxArgs: void 0,
6668
+ __multiLeg: void 0,
6669
+ swap_tx: void 0,
6670
+ send_tx: void 0,
6671
+ tx: void 0
6672
+ };
6673
+ const approveResult = await this.signServerTx(approveEnvelope, chain, params);
6674
+ const approveTxHash = approveResult.tx_hash;
6675
+ if (!approveTxHash) {
6676
+ throw new VaultError3(VaultErrorCode3.BroadcastFailed, "signMultiLeg: approve leg returned no tx_hash");
6677
+ }
6678
+ if (this.verbose)
6679
+ process.stderr.write(`[signMultiLeg] approve broadcast: ${approveTxHash}, waiting for receipt...
6680
+ `);
6681
+ try {
6682
+ await this.waitForEvmReceipt(chain, approveTxHash, { timeoutSec: 90 });
6683
+ } catch (err) {
6684
+ throw new VaultError3(
6685
+ VaultErrorCode3.Timeout,
6686
+ `signMultiLeg: approve leg ${approveTxHash} did not confirm: ${err?.message ?? err}`,
6687
+ err instanceof Error ? err : void 0
6688
+ );
6689
+ }
6690
+ if (this.verbose) process.stderr.write(`[signMultiLeg] approve confirmed, broadcasting main leg
6691
+ `);
6692
+ const mainEnvelope = {
6693
+ ...mainLeg.parent,
6694
+ txArgs: mainLeg.txArgs,
6695
+ approvalTxArgs: void 0,
6696
+ __multiLeg: void 0,
6697
+ swap_tx: void 0,
6698
+ send_tx: void 0,
6699
+ tx: void 0
6700
+ };
6701
+ const mainResult = await this.signServerTx(mainEnvelope, chain, params);
6702
+ return {
6703
+ tx_hash: mainResult.tx_hash,
6704
+ approval_tx_hash: approveTxHash,
6705
+ chain: mainResult.chain,
6706
+ status: "pending",
6707
+ explorer_url: mainResult.explorer_url
6708
+ };
6709
+ } finally {
6710
+ this.pendingLegs = [];
6711
+ }
6712
+ }
6713
+ /**
6714
+ * Poll vault.getTxStatus until the EVM tx confirms or the timeout fires.
6715
+ * Mirrors VaultBase's private `waitForConfirmation` (used by `vault.swap`
6716
+ * for its own approve-before-swap flow) — kept at the executor layer here
6717
+ * so we can stub it from unit tests without exposing private SDK methods.
6718
+ *
6719
+ * Throws on timeout or on receipt status === 'error' (revert). Returns on
6720
+ * success.
6721
+ */
6722
+ async waitForEvmReceipt(chain, txHash, opts) {
6723
+ const intervalMs = 3e3;
6724
+ const deadline = Date.now() + opts.timeoutSec * 1e3;
6725
+ while (Date.now() < deadline) {
6726
+ try {
6727
+ const result = await this.vault.getTxStatus({ chain, txHash });
6728
+ if (result?.status === "success") return;
6729
+ if (result?.status === "error") {
6730
+ throw new VaultError3(VaultErrorCode3.BroadcastFailed, `approve tx reverted (${txHash})`);
6731
+ }
6732
+ } catch (e) {
6733
+ if (e instanceof VaultError3 && e.code === VaultErrorCode3.BroadcastFailed) throw e;
6734
+ if (e?.message?.includes("reverted")) throw e;
6735
+ }
6736
+ await new Promise((r) => setTimeout(r, intervalMs));
6737
+ }
6738
+ throw new VaultError3(VaultErrorCode3.Timeout, `approve tx ${txHash} not confirmed within ${opts.timeoutSec}s`);
6739
+ }
5990
6740
  /**
5991
6741
  * Build, sign, and broadcast a Solana swap locally using the SDK's swap flow.
5992
6742
  * Uses swap params from the tx_ready event to call vault.getSwapQuote → prepareSwapTx.
@@ -6305,11 +7055,11 @@ var AgentExecutor = class {
6305
7055
  `);
6306
7056
  const chainName = params.chain;
6307
7057
  const chainId = domain.chainId;
6308
- let chain = Chain9.Ethereum;
7058
+ let chain = Chain10.Ethereum;
6309
7059
  if (chainName) {
6310
- chain = resolveChain(chainName) || Chain9.Ethereum;
7060
+ chain = resolveChain(chainName) || Chain10.Ethereum;
6311
7061
  } else if (chainId) {
6312
- chain = resolveChainId(chainId) || Chain9.Ethereum;
7062
+ chain = resolveChainId(chainId) || Chain10.Ethereum;
6313
7063
  }
6314
7064
  const sigResult = await this.vault.signBytes({
6315
7065
  data: eip712Hash,
@@ -6414,11 +7164,11 @@ var AgentExecutor = class {
6414
7164
  };
6415
7165
  function resolveChain(name) {
6416
7166
  if (!name) return null;
6417
- if (Object.values(Chain9).includes(name)) {
7167
+ if (Object.values(Chain10).includes(name)) {
6418
7168
  return name;
6419
7169
  }
6420
7170
  const lower = name.toLowerCase();
6421
- for (const [, value] of Object.entries(Chain9)) {
7171
+ for (const [, value] of Object.entries(Chain10)) {
6422
7172
  if (typeof value === "string" && value.toLowerCase() === lower) {
6423
7173
  return value;
6424
7174
  }
@@ -6444,7 +7194,7 @@ function resolveChain(name) {
6444
7194
  xrp: "Ripple"
6445
7195
  };
6446
7196
  const aliased = aliases[lower];
6447
- if (aliased && Object.values(Chain9).includes(aliased)) {
7197
+ if (aliased && Object.values(Chain10).includes(aliased)) {
6448
7198
  return aliased;
6449
7199
  }
6450
7200
  return null;
@@ -6480,20 +7230,89 @@ function resolveChainFromTxReady(txReadyData) {
6480
7230
  function extractNestedTx(txReadyData) {
6481
7231
  return txReadyData?.swap_tx || txReadyData?.send_tx || txReadyData?.tx || txReadyData?.txArgs?.tx;
6482
7232
  }
7233
+ var MAX_AMOUNT_DIGITS = 26;
7234
+ function convertBaseUnitsToDecimal(chain, amountRaw, context) {
7235
+ if (amountRaw.length > MAX_AMOUNT_DIGITS) {
7236
+ throw new VaultError3(
7237
+ VaultErrorCode3.InvalidAmount,
7238
+ `${context}: amount '${amountRaw}' for ${chain} exceeds ${MAX_AMOUNT_DIGITS}-digit safety bound. Likely a quote-side bug. Refusing to sign.`
7239
+ );
7240
+ }
7241
+ const decimals = chainFeeCoin[chain]?.decimals;
7242
+ if (decimals === void 0) {
7243
+ throw new VaultError3(VaultErrorCode3.UnsupportedChain, `${context}: no native decimals registered for ${chain}`);
7244
+ }
7245
+ try {
7246
+ return formatUnits(BigInt(amountRaw), decimals);
7247
+ } catch (err) {
7248
+ throw new VaultError3(
7249
+ VaultErrorCode3.InvalidAmount,
7250
+ `${context}: failed to convert amount '${amountRaw}' for ${chain}: ${err?.message ?? err}`
7251
+ );
7252
+ }
7253
+ }
7254
+ function parseNonEvmEnvelope(serverTxData, chain) {
7255
+ const txArgs = serverTxData?.txArgs ?? serverTxData;
7256
+ if (!txArgs || typeof txArgs !== "object") {
7257
+ throw new VaultError3(VaultErrorCode3.InvalidConfig, "parseNonEvmEnvelope: envelope missing txArgs");
7258
+ }
7259
+ const to = typeof txArgs.to === "string" ? txArgs.to : void 0;
7260
+ if (!to) {
7261
+ throw new VaultError3(VaultErrorCode3.InvalidConfig, `parseNonEvmEnvelope: missing 'to' field for ${chain}`);
7262
+ }
7263
+ const amountRaw = typeof txArgs.amount === "string" ? txArgs.amount : void 0;
7264
+ if (!amountRaw) {
7265
+ throw new VaultError3(VaultErrorCode3.InvalidConfig, `parseNonEvmEnvelope: missing 'amount' field for ${chain}`);
7266
+ }
7267
+ const amountDecimal = convertBaseUnitsToDecimal(chain, amountRaw, "parseNonEvmEnvelope");
7268
+ let symbol;
7269
+ const tokenResolved = serverTxData?.resolved?.labels?.token_resolved;
7270
+ const nativeTicker = chainFeeCoin[chain]?.ticker;
7271
+ if (typeof tokenResolved === "string" && tokenResolved !== nativeTicker) {
7272
+ symbol = tokenResolved;
7273
+ }
7274
+ const memo = typeof txArgs.memo === "string" && txArgs.memo.length > 0 ? txArgs.memo : void 0;
7275
+ return { chain, to, amount: amountDecimal, symbol, memo };
7276
+ }
7277
+ function parseThorSwapMemo(memo) {
7278
+ if (!memo.startsWith("=:")) {
7279
+ throw new VaultError3(
7280
+ VaultErrorCode3.NotImplemented,
7281
+ `parseThorSwapMemo: only swap memos (=:CHAIN.ASSET:DEST...) supported on this path; got memo='${memo}'. LP / non-swap MsgDeposit flows route through different SDK helpers (Phase E follow-up).`
7282
+ );
7283
+ }
7284
+ const memoBody = memo.slice(2);
7285
+ const parts = memoBody.split(":");
7286
+ let chainAsset = parts[0];
7287
+ if (chainAsset && !chainAsset.includes(".")) {
7288
+ const expanded = THOR_MEMO_ASSET_SHORTCUTS[chainAsset.toLowerCase()];
7289
+ if (expanded) chainAsset = expanded;
7290
+ }
7291
+ if (!chainAsset || !chainAsset.includes(".")) {
7292
+ throw new VaultError3(
7293
+ VaultErrorCode3.InvalidConfig,
7294
+ `parseThorSwapMemo: malformed swap memo '${memo}': missing CHAIN.ASSET in first segment.`
7295
+ );
7296
+ }
7297
+ const [destChainCode, destAssetRaw] = chainAsset.split(".");
7298
+ const destAsset = destAssetRaw?.split("-")[0] ?? "";
7299
+ const destAddress = typeof parts[1] === "string" ? parts[1] : "";
7300
+ return { destChainCode, destAsset, destAddress };
7301
+ }
6483
7302
  function resolveChainId(chainId) {
6484
7303
  const id = typeof chainId === "string" ? parseInt(chainId, 10) : chainId;
6485
7304
  if (isNaN(id)) return null;
6486
7305
  const chainIdMap = {
6487
- 1: Chain9.Ethereum,
6488
- 56: Chain9.BSC,
6489
- 137: Chain9.Polygon,
6490
- 43114: Chain9.Avalanche,
6491
- 42161: Chain9.Arbitrum,
6492
- 10: Chain9.Optimism,
6493
- 8453: Chain9.Base,
6494
- 81457: Chain9.Blast,
6495
- 324: Chain9.Zksync,
6496
- 25: Chain9.CronosChain
7306
+ 1: Chain10.Ethereum,
7307
+ 56: Chain10.BSC,
7308
+ 137: Chain10.Polygon,
7309
+ 43114: Chain10.Avalanche,
7310
+ 42161: Chain10.Arbitrum,
7311
+ 10: Chain10.Optimism,
7312
+ 8453: Chain10.Base,
7313
+ 81457: Chain10.Blast,
7314
+ 324: Chain10.Zksync,
7315
+ 25: Chain10.CronosChain
6497
7316
  };
6498
7317
  return chainIdMap[id] || null;
6499
7318
  }
@@ -7858,7 +8677,7 @@ var cachedVersion = null;
7858
8677
  function getVersion() {
7859
8678
  if (cachedVersion) return cachedVersion;
7860
8679
  if (true) {
7861
- cachedVersion = "0.22.5";
8680
+ cachedVersion = "0.22.7";
7862
8681
  return cachedVersion;
7863
8682
  }
7864
8683
  try {
@@ -8141,7 +8960,7 @@ function readArgValue(args, optionName) {
8141
8960
  }
8142
8961
 
8143
8962
  // src/interactive/completer.ts
8144
- import { Chain as Chain10 } from "@vultisig/sdk";
8963
+ import { Chain as Chain11 } from "@vultisig/sdk";
8145
8964
  import fs3 from "fs";
8146
8965
  import path3 from "path";
8147
8966
  var COMMANDS = [
@@ -8285,7 +9104,7 @@ function completeVaultName(ctx2, partial) {
8285
9104
  return [show, partial];
8286
9105
  }
8287
9106
  function completeChainName(partial) {
8288
- const allChains = Object.values(Chain10);
9107
+ const allChains = Object.values(Chain11);
8289
9108
  const partialLower = partial.toLowerCase();
8290
9109
  const matches = allChains.filter((chain) => chain.toLowerCase().startsWith(partialLower));
8291
9110
  matches.sort();
@@ -8293,7 +9112,7 @@ function completeChainName(partial) {
8293
9112
  return [show, partial];
8294
9113
  }
8295
9114
  function findChainByName(name) {
8296
- const allChains = Object.values(Chain10);
9115
+ const allChains = Object.values(Chain11);
8297
9116
  const nameLower = name.toLowerCase();
8298
9117
  const found = allChains.find((chain) => chain.toLowerCase() === nameLower);
8299
9118
  return found ? found : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/cli",
3
- "version": "0.22.5",
3
+ "version": "0.22.7",
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.0.1",
76
76
  "@vultisig/client-shared": "^0.2.6",
77
- "@vultisig/core-chain": "^1.6.1",
77
+ "@vultisig/core-chain": "^1.7.1",
78
78
  "@vultisig/rujira": "^17.0.1",
79
- "@vultisig/sdk": "^0.22.5",
79
+ "@vultisig/sdk": "^0.22.7",
80
80
  "chalk": "^5.6.2",
81
81
  "cli-table3": "^0.6.5",
82
82
  "commander": "^14.0.3",