@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 +9 -0
- package/dist/index.js +219 -90
- package/package.json +5 -5
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://
|
|
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://
|
|
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
|
-
"
|
|
6535
|
-
"
|
|
6536
|
-
"
|
|
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
|
-
|
|
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)
|
|
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 "
|
|
6695
|
-
return this.
|
|
6696
|
-
case "
|
|
6697
|
-
return this.
|
|
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 "
|
|
6714
|
-
return this.
|
|
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
|
-
|
|
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
|
|
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
|
|
6796
|
-
const
|
|
6797
|
-
if (
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
7820
|
-
|
|
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
|
|
7823
|
-
|
|
7824
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
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.
|
|
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
|
|
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
|
+
"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.
|
|
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.
|
|
78
|
-
"@vultisig/rujira": "^17.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": "^
|
|
97
|
+
"typescript": "^6.0.3",
|
|
98
98
|
"vitest": "^4.1.5"
|
|
99
99
|
},
|
|
100
100
|
"engines": {
|