@vultisig/cli 5.2.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/dist/index.js +195 -198
- package/package.json +7 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @vultisig/cli
|
|
2
2
|
|
|
3
|
+
## 6.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1389](https://github.com/vultisig/vultisig-sdk/pull/1389) [`e1e73cb`](https://github.com/vultisig/vultisig-sdk/commit/e1e73cb5a67de6c77731b2d58ed7b2cb547e1228) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Export the RN-safe `prepareIbcTransfer` and `prepareSuiTokenTransferFromKeys` helpers from `@vultisig/sdk/react-native`, along with their public support types/constants so React Native consumers no longer need deep imports for IBC and Sui token transfer prep.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#2225](https://github.com/vultisig/vultisig-sdk/pull/2225) [`95edf12`](https://github.com/vultisig/vultisig-sdk/commit/95edf1264827d0a63baa9d0580817caf2dffdc9e) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Add a canonical raw EVM transaction-envelope keysign helper and use it in the CLI signing path.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`8a98b44`](https://github.com/vultisig/vultisig-sdk/commit/8a98b44e1f4438212e6deb7cca8491e23940118c), [`95edf12`](https://github.com/vultisig/vultisig-sdk/commit/95edf1264827d0a63baa9d0580817caf2dffdc9e), [`e1e73cb`](https://github.com/vultisig/vultisig-sdk/commit/e1e73cb5a67de6c77731b2d58ed7b2cb547e1228), [`3fff7cf`](https://github.com/vultisig/vultisig-sdk/commit/3fff7cfdfe23d2d5622f7caa87a6f1525329f07e), [`0697060`](https://github.com/vultisig/vultisig-sdk/commit/0697060107c7fe1c8ec818d3e0eae01557d9d96f)]:
|
|
14
|
+
- @vultisig/sdk@6.2.0
|
|
15
|
+
- @vultisig/core-chain@4.1.0
|
|
16
|
+
|
|
17
|
+
## 6.0.0
|
|
18
|
+
|
|
19
|
+
### Major Changes
|
|
20
|
+
|
|
21
|
+
- [#2218](https://github.com/vultisig/vultisig-sdk/pull/2218) [`d043dc4`](https://github.com/vultisig/vultisig-sdk/commit/d043dc43d9fe33a3160c2739150fd6294f0e7eff) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Unify the workspace on the coordinated Noble/Scure v2 stack and align related workspace peer dependency ranges.
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- [#2024](https://github.com/vultisig/vultisig-sdk/pull/2024) [`821c8a7`](https://github.com/vultisig/vultisig-sdk/commit/821c8a73dd7d3aee55eaca59c22adc1ce8dae2f2) Thanks [@neavra](https://github.com/neavra)! - Label XRP spendable-vs-total balance. `getRippleNativeBalanceDetail` exposes the `{ total, spendable, reserve }` breakdown of a native XRP balance (the existing resolvers keep returning the spendable number, so no consumer changes meaning). SDK `Balance` gains optional `totalAmount`/`reserveAmount` fields, populated for native XRP. The CLI labels the spendable headline and prints the locked reserve for XRP balances; all other chains render unchanged.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- [#2176](https://github.com/vultisig/vultisig-sdk/pull/2176) [`d2edffd`](https://github.com/vultisig/vultisig-sdk/commit/d2edffd98730daa474d0c2f35a305d5277e3eb15) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Export a canonical typed parser for backend `tx_ready` and execute-prep envelopes, and migrate the CLI's non-EVM and THOR/Maya execution routing to that shared contract.
|
|
30
|
+
|
|
31
|
+
- [#1736](https://github.com/vultisig/vultisig-sdk/pull/1736) [`b58da97`](https://github.com/vultisig/vultisig-sdk/commit/b58da972a3830eb11449401d97ae6b5e62189501) Thanks [@neavra](https://github.com/neavra)! - Fix agent send consent summaries so token tickers, chains, and contract details render exactly once; strip negated routed-chain phrases without leaving a dangling "not" and strip ASCII-ellipsis truncated contract copies like the Unicode form.
|
|
32
|
+
|
|
33
|
+
- [#1760](https://github.com/vultisig/vultisig-sdk/pull/1760) [`9759c64`](https://github.com/vultisig/vultisig-sdk/commit/9759c6429225afe0ee96a8b51aff6b79026e1b8b) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Preserve optional `priceProviderId` on `discoverTokens()` results so downstream consumers can price newly discovered tokens without app-local metadata backfills.
|
|
34
|
+
|
|
35
|
+
- [#1870](https://github.com/vultisig/vultisig-sdk/pull/1870) [`3e37e69`](https://github.com/vultisig/vultisig-sdk/commit/3e37e69fdc60d63cb53a2ef7c74b01aa930b27e1) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Add a public `pollTxStatusUntilFinal` helper to `@vultisig/sdk` and reuse it across SDK/CLI transaction finality polling paths.
|
|
36
|
+
|
|
37
|
+
- [#2018](https://github.com/vultisig/vultisig-sdk/pull/2018) [`3163f30`](https://github.com/vultisig/vultisig-sdk/commit/3163f30ed91dad7c9e8f860c6d4dbb6e61899be8) Thanks [@neavra](https://github.com/neavra)! - The aggregate `balance` and `portfolio` views now say they only cover the vault's enabled chains. When the enabled set is a strict subset of the SDK-supported chains, the human output appends a hint pointing at `vultisig balance <chain>` and `vultisig chains --add <chain>`, and JSON mode carries the same text in a dedicated `scopeHint` field (omitted when every supported chain is enabled). The balances/portfolio payloads and the scoped `balance <chain>` path are unchanged.
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [[`d043dc4`](https://github.com/vultisig/vultisig-sdk/commit/d043dc43d9fe33a3160c2739150fd6294f0e7eff), [`d2edffd`](https://github.com/vultisig/vultisig-sdk/commit/d2edffd98730daa474d0c2f35a305d5277e3eb15), [`9759c64`](https://github.com/vultisig/vultisig-sdk/commit/9759c6429225afe0ee96a8b51aff6b79026e1b8b), [`eccbc25`](https://github.com/vultisig/vultisig-sdk/commit/eccbc25a1fd61fb9eb03494afb0d5ceb6977be8c), [`bd44426`](https://github.com/vultisig/vultisig-sdk/commit/bd44426fe80b160d8c9a0a866e3cbb759bf781ba), [`dd82325`](https://github.com/vultisig/vultisig-sdk/commit/dd82325ee2f5700429178cb513b338dac27aa281), [`e6375ee`](https://github.com/vultisig/vultisig-sdk/commit/e6375ee8a4d77035b4ae8dae01184b2100ac8ca7), [`e2be3d4`](https://github.com/vultisig/vultisig-sdk/commit/e2be3d41214b988c3b917538e26dbe1e123725de), [`f170bdd`](https://github.com/vultisig/vultisig-sdk/commit/f170bdddafd80d892cd35a050cf8f5393776a6a0), [`6c535ae`](https://github.com/vultisig/vultisig-sdk/commit/6c535ae3aed1c376d2e1bbbeb100e8b5c21c8929), [`5bf33f2`](https://github.com/vultisig/vultisig-sdk/commit/5bf33f264c90ec4055d2c12e90222bec9aea501b), [`3203589`](https://github.com/vultisig/vultisig-sdk/commit/3203589af5da361dfc51695aad4fef77afa2d78e), [`3e37e69`](https://github.com/vultisig/vultisig-sdk/commit/3e37e69fdc60d63cb53a2ef7c74b01aa930b27e1), [`4c30666`](https://github.com/vultisig/vultisig-sdk/commit/4c306668690f798ff4fb9094cf16dd26eaafa8e7), [`1672265`](https://github.com/vultisig/vultisig-sdk/commit/16722657dcefafff32744a7673c277e403e62a77), [`2faf1a2`](https://github.com/vultisig/vultisig-sdk/commit/2faf1a2b833b1fc0f10a02ad2c8bec50ef4b1f57), [`beaca3c`](https://github.com/vultisig/vultisig-sdk/commit/beaca3c086679a8b87592fb69ca30a0a9d1877db), [`5500717`](https://github.com/vultisig/vultisig-sdk/commit/5500717036e760ed81d4880c66bda559d37331cd), [`d04f246`](https://github.com/vultisig/vultisig-sdk/commit/d04f246a992f3256e4fe7151e5319003d8ae267a), [`da2ea4e`](https://github.com/vultisig/vultisig-sdk/commit/da2ea4e1ae00f17cfec3d27da4fff2e6cb5b1190), [`821c8a7`](https://github.com/vultisig/vultisig-sdk/commit/821c8a73dd7d3aee55eaca59c22adc1ce8dae2f2)]:
|
|
40
|
+
- @vultisig/core-chain@4.0.0
|
|
41
|
+
- @vultisig/sdk@6.0.0
|
|
42
|
+
- @vultisig/rujira@70.0.0
|
|
43
|
+
- @vultisig/client-shared@0.3.5
|
|
44
|
+
|
|
3
45
|
## 5.2.0
|
|
4
46
|
|
|
5
47
|
### Minor Changes
|
package/dist/index.js
CHANGED
|
@@ -2506,7 +2506,7 @@ var init_toBytes = __esm({
|
|
|
2506
2506
|
}
|
|
2507
2507
|
});
|
|
2508
2508
|
|
|
2509
|
-
// ../../node_modules/@noble/hashes/esm/_u64.js
|
|
2509
|
+
// ../../node_modules/viem/node_modules/@noble/hashes/esm/_u64.js
|
|
2510
2510
|
function fromBig(n, le = false) {
|
|
2511
2511
|
if (le)
|
|
2512
2512
|
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
@@ -2524,7 +2524,7 @@ function split(lst, le = false) {
|
|
|
2524
2524
|
}
|
|
2525
2525
|
var U32_MASK64, _32n, rotlSH, rotlSL, rotlBH, rotlBL;
|
|
2526
2526
|
var init_u64 = __esm({
|
|
2527
|
-
"../../node_modules/@noble/hashes/esm/_u64.js"() {
|
|
2527
|
+
"../../node_modules/viem/node_modules/@noble/hashes/esm/_u64.js"() {
|
|
2528
2528
|
U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
2529
2529
|
_32n = /* @__PURE__ */ BigInt(32);
|
|
2530
2530
|
rotlSH = (h, l, s) => h << s | l >>> 32 - s;
|
|
@@ -2534,16 +2534,16 @@ var init_u64 = __esm({
|
|
|
2534
2534
|
}
|
|
2535
2535
|
});
|
|
2536
2536
|
|
|
2537
|
-
// ../../node_modules/@noble/hashes/esm/cryptoNode.js
|
|
2537
|
+
// ../../node_modules/viem/node_modules/@noble/hashes/esm/cryptoNode.js
|
|
2538
2538
|
import * as nc from "node:crypto";
|
|
2539
2539
|
var crypto2;
|
|
2540
2540
|
var init_cryptoNode = __esm({
|
|
2541
|
-
"../../node_modules/@noble/hashes/esm/cryptoNode.js"() {
|
|
2541
|
+
"../../node_modules/viem/node_modules/@noble/hashes/esm/cryptoNode.js"() {
|
|
2542
2542
|
crypto2 = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : nc && typeof nc === "object" && "randomBytes" in nc ? nc : void 0;
|
|
2543
2543
|
}
|
|
2544
2544
|
});
|
|
2545
2545
|
|
|
2546
|
-
// ../../node_modules/@noble/hashes/esm/utils.js
|
|
2546
|
+
// ../../node_modules/viem/node_modules/@noble/hashes/esm/utils.js
|
|
2547
2547
|
function isBytes(a) {
|
|
2548
2548
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
2549
2549
|
}
|
|
@@ -2644,7 +2644,7 @@ function randomBytes2(bytesLength = 32) {
|
|
|
2644
2644
|
}
|
|
2645
2645
|
var isLE, swap32IfBE, Hash;
|
|
2646
2646
|
var init_utils2 = __esm({
|
|
2647
|
-
"../../node_modules/@noble/hashes/esm/utils.js"() {
|
|
2647
|
+
"../../node_modules/viem/node_modules/@noble/hashes/esm/utils.js"() {
|
|
2648
2648
|
init_cryptoNode();
|
|
2649
2649
|
isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
2650
2650
|
swap32IfBE = isLE ? (u) => u : byteSwap32;
|
|
@@ -2653,7 +2653,7 @@ var init_utils2 = __esm({
|
|
|
2653
2653
|
}
|
|
2654
2654
|
});
|
|
2655
2655
|
|
|
2656
|
-
// ../../node_modules/@noble/hashes/esm/sha3.js
|
|
2656
|
+
// ../../node_modules/viem/node_modules/@noble/hashes/esm/sha3.js
|
|
2657
2657
|
function keccakP(s, rounds = 24) {
|
|
2658
2658
|
const B = new Uint32Array(5 * 2);
|
|
2659
2659
|
for (let round = 24 - rounds; round < 24; round++) {
|
|
@@ -2696,7 +2696,7 @@ function keccakP(s, rounds = 24) {
|
|
|
2696
2696
|
}
|
|
2697
2697
|
var _0n, _1n, _2n, _7n, _256n, _0x71n, SHA3_PI, SHA3_ROTL, _SHA3_IOTA, IOTAS, SHA3_IOTA_H, SHA3_IOTA_L, rotlH, rotlL, Keccak, gen, keccak_256;
|
|
2698
2698
|
var init_sha3 = __esm({
|
|
2699
|
-
"../../node_modules/@noble/hashes/esm/sha3.js"() {
|
|
2699
|
+
"../../node_modules/viem/node_modules/@noble/hashes/esm/sha3.js"() {
|
|
2700
2700
|
init_u64();
|
|
2701
2701
|
init_utils2();
|
|
2702
2702
|
_0n = BigInt(0);
|
|
@@ -3895,7 +3895,7 @@ var init_Value = __esm({
|
|
|
3895
3895
|
}
|
|
3896
3896
|
});
|
|
3897
3897
|
|
|
3898
|
-
// ../../node_modules/@noble/hashes/esm/_md.js
|
|
3898
|
+
// ../../node_modules/viem/node_modules/@noble/hashes/esm/_md.js
|
|
3899
3899
|
function setBigUint64(view, byteOffset, value, isLE2) {
|
|
3900
3900
|
if (typeof view.setBigUint64 === "function")
|
|
3901
3901
|
return view.setBigUint64(byteOffset, value, isLE2);
|
|
@@ -3916,7 +3916,7 @@ function Maj(a, b, c) {
|
|
|
3916
3916
|
}
|
|
3917
3917
|
var HashMD, SHA256_IV;
|
|
3918
3918
|
var init_md = __esm({
|
|
3919
|
-
"../../node_modules/@noble/hashes/esm/_md.js"() {
|
|
3919
|
+
"../../node_modules/viem/node_modules/@noble/hashes/esm/_md.js"() {
|
|
3920
3920
|
init_utils2();
|
|
3921
3921
|
HashMD = class extends Hash {
|
|
3922
3922
|
constructor(blockLen, outputLen, padOffset, isLE2) {
|
|
@@ -4021,10 +4021,10 @@ var init_md = __esm({
|
|
|
4021
4021
|
}
|
|
4022
4022
|
});
|
|
4023
4023
|
|
|
4024
|
-
// ../../node_modules/@noble/hashes/esm/sha2.js
|
|
4024
|
+
// ../../node_modules/viem/node_modules/@noble/hashes/esm/sha2.js
|
|
4025
4025
|
var SHA256_K, SHA256_W, SHA256, sha256;
|
|
4026
4026
|
var init_sha2 = __esm({
|
|
4027
|
-
"../../node_modules/@noble/hashes/esm/sha2.js"() {
|
|
4027
|
+
"../../node_modules/viem/node_modules/@noble/hashes/esm/sha2.js"() {
|
|
4028
4028
|
init_md();
|
|
4029
4029
|
init_utils2();
|
|
4030
4030
|
SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
@@ -4168,10 +4168,10 @@ var init_sha2 = __esm({
|
|
|
4168
4168
|
}
|
|
4169
4169
|
});
|
|
4170
4170
|
|
|
4171
|
-
// ../../node_modules/@noble/hashes/esm/hmac.js
|
|
4171
|
+
// ../../node_modules/viem/node_modules/@noble/hashes/esm/hmac.js
|
|
4172
4172
|
var HMAC, hmac;
|
|
4173
4173
|
var init_hmac = __esm({
|
|
4174
|
-
"../../node_modules/@noble/hashes/esm/hmac.js"() {
|
|
4174
|
+
"../../node_modules/viem/node_modules/@noble/hashes/esm/hmac.js"() {
|
|
4175
4175
|
init_utils2();
|
|
4176
4176
|
HMAC = class extends Hash {
|
|
4177
4177
|
constructor(hash2, _key) {
|
|
@@ -9104,7 +9104,7 @@ x ${classified.message}`);
|
|
|
9104
9104
|
}
|
|
9105
9105
|
|
|
9106
9106
|
// src/commands/balance.ts
|
|
9107
|
-
import { fiatCurrencies, fiatCurrencyNameRecord as fiatCurrencyNameRecord2 } from "@vultisig/sdk";
|
|
9107
|
+
import { fiatCurrencies, fiatCurrencyNameRecord as fiatCurrencyNameRecord2, SUPPORTED_CHAINS } from "@vultisig/sdk";
|
|
9108
9108
|
|
|
9109
9109
|
// src/ui.ts
|
|
9110
9110
|
import { fiatCurrencyNameRecord, fromChainAmountExact, Vultisig } from "@vultisig/sdk";
|
|
@@ -9115,10 +9115,19 @@ var escapeTerminalControls = (value) => Array.from(value, (character) => {
|
|
|
9115
9115
|
const isTerminalControl = codePoint <= 31 || codePoint === 127 || codePoint >= 128 && codePoint <= 159;
|
|
9116
9116
|
return isTerminalControl ? `\\x${codePoint.toString(16).padStart(2, "0").toUpperCase()}` : character;
|
|
9117
9117
|
}).join("");
|
|
9118
|
+
var hasLockedReserve = (balance) => balance.reserveAmount !== void 0 && balance.reserveAmount !== "0" && balance.totalAmount !== void 0;
|
|
9119
|
+
var formatAmountCell = (balance) => hasLockedReserve(balance) ? `${balance.formattedAmount} (spendable)` : balance.formattedAmount;
|
|
9118
9120
|
function displayBalance(chain, balance, _raw = false) {
|
|
9119
9121
|
printResult(chalk2.cyan(`
|
|
9120
9122
|
${chain} Balance:`));
|
|
9121
|
-
printResult(
|
|
9123
|
+
printResult(
|
|
9124
|
+
` Amount: ${balance.formattedAmount} ${balance.symbol}${hasLockedReserve(balance) ? " (spendable)" : ""}`
|
|
9125
|
+
);
|
|
9126
|
+
if (hasLockedReserve(balance) && balance.totalAmount !== void 0) {
|
|
9127
|
+
const reserve = formatBalanceAmount(balance.reserveAmount, balance.decimals);
|
|
9128
|
+
const total = formatBalanceAmount(balance.totalAmount, balance.decimals);
|
|
9129
|
+
printResult(` Reserve: ${reserve} ${balance.symbol} locked (${total} ${balance.symbol} total on ledger)`);
|
|
9130
|
+
}
|
|
9122
9131
|
if (balance.fiatValue && balance.fiatCurrency) {
|
|
9123
9132
|
printResult(` Value: ${balance.fiatValue.toFixed(2)} ${balance.fiatCurrency}`);
|
|
9124
9133
|
}
|
|
@@ -9127,7 +9136,7 @@ function displayBalancesTable(balances, _raw = false) {
|
|
|
9127
9136
|
printResult(chalk2.cyan("\nPortfolio Balances:\n"));
|
|
9128
9137
|
const tableData = Object.entries(balances).map(([chain, balance]) => ({
|
|
9129
9138
|
Chain: chain,
|
|
9130
|
-
Amount: balance
|
|
9139
|
+
Amount: formatAmountCell(balance),
|
|
9131
9140
|
Symbol: balance.symbol,
|
|
9132
9141
|
Value: balance.fiatValue && balance.fiatCurrency ? `${balance.fiatValue.toFixed(2)} ${balance.fiatCurrency}` : "N/A"
|
|
9133
9142
|
}));
|
|
@@ -9145,7 +9154,7 @@ function displayPortfolio(portfolio, currency, _raw = false) {
|
|
|
9145
9154
|
const table = portfolio.chainBalances.flatMap(({ chain, balance, value, tokens }) => [
|
|
9146
9155
|
{
|
|
9147
9156
|
Chain: chain,
|
|
9148
|
-
Amount: balance
|
|
9157
|
+
Amount: formatAmountCell(balance),
|
|
9149
9158
|
Symbol: balance.symbol,
|
|
9150
9159
|
Value: value ? `${value.amount} ${value.currency.toUpperCase()}` : "N/A"
|
|
9151
9160
|
},
|
|
@@ -9257,7 +9266,7 @@ async function confirmTransaction() {
|
|
|
9257
9266
|
function setupVaultEvents(vault) {
|
|
9258
9267
|
vault.on("balanceUpdated", ({ chain, balance, tokenId }) => {
|
|
9259
9268
|
const asset = tokenId ? `${balance.symbol} token` : balance.symbol;
|
|
9260
|
-
info(chalk2.blue(`i Balance updated for ${chain} (${asset}): ${balance
|
|
9269
|
+
info(chalk2.blue(`i Balance updated for ${chain} (${asset}): ${formatAmountCell(balance)}`));
|
|
9261
9270
|
});
|
|
9262
9271
|
vault.on("transactionBroadcast", ({ chain, txHash }) => {
|
|
9263
9272
|
info(chalk2.green(`+ Transaction broadcast on ${chain}`));
|
|
@@ -9292,6 +9301,14 @@ function formatBigintAmount(amount, decimals) {
|
|
|
9292
9301
|
const trimmed = fraction.replace(/0+$/, "");
|
|
9293
9302
|
return trimmed ? `${whole}.${trimmed}` : whole;
|
|
9294
9303
|
}
|
|
9304
|
+
function formatBalanceAmount(amount, decimals) {
|
|
9305
|
+
if (!amount || amount === "0") return "0";
|
|
9306
|
+
try {
|
|
9307
|
+
return formatBigintAmount(BigInt(amount), decimals);
|
|
9308
|
+
} catch {
|
|
9309
|
+
return amount;
|
|
9310
|
+
}
|
|
9311
|
+
}
|
|
9295
9312
|
function displaySwapPreview(quote, fromAmount, fromSymbol, toSymbol, options) {
|
|
9296
9313
|
const estimatedOutputFormatted = formatBigintAmount(quote.estimatedOutput, options.toDecimals);
|
|
9297
9314
|
printResult(chalk2.cyan("\nSwap Preview:"));
|
|
@@ -9371,6 +9388,13 @@ async function confirmSwap() {
|
|
|
9371
9388
|
}
|
|
9372
9389
|
|
|
9373
9390
|
// src/commands/balance.ts
|
|
9391
|
+
function buildScopeHint(enabledChains) {
|
|
9392
|
+
const supportedCount = SUPPORTED_CHAINS.length;
|
|
9393
|
+
const enabledSupportedCount = new Set(enabledChains.filter((chain) => SUPPORTED_CHAINS.includes(chain))).size;
|
|
9394
|
+
if (enabledSupportedCount >= supportedCount) return void 0;
|
|
9395
|
+
const noun = enabledSupportedCount === 1 ? "chain" : "chains";
|
|
9396
|
+
return `Showing the vault's ${enabledSupportedCount} enabled ${noun} of ${supportedCount} supported. Funds on other chains won't appear here \u2014 run \`vultisig balance <chain>\` to check one, or \`vultisig chains --add <chain>\` to include it.`;
|
|
9397
|
+
}
|
|
9374
9398
|
function conciseError(err) {
|
|
9375
9399
|
const message = err instanceof Error ? err.message : String(err);
|
|
9376
9400
|
return message.split("\n")[0].trim() || "Unknown error";
|
|
@@ -9400,11 +9424,14 @@ async function executeBalance(ctx2, options = {}) {
|
|
|
9400
9424
|
} else {
|
|
9401
9425
|
const balances = await vault.balances(void 0, options.includeTokens);
|
|
9402
9426
|
spinner.succeed("Balances loaded");
|
|
9427
|
+
const scopeHint = buildScopeHint(vault.chains);
|
|
9403
9428
|
if (isJsonOutput()) {
|
|
9404
|
-
outputJson({ balances });
|
|
9429
|
+
outputJson({ balances, scopeHint });
|
|
9405
9430
|
return;
|
|
9406
9431
|
}
|
|
9407
9432
|
displayBalancesTable(balances, raw);
|
|
9433
|
+
if (scopeHint) info(`
|
|
9434
|
+
${scopeHint}`);
|
|
9408
9435
|
}
|
|
9409
9436
|
}
|
|
9410
9437
|
async function executePortfolio(ctx2, options = {}) {
|
|
@@ -9480,11 +9507,14 @@ async function executePortfolio(ctx2, options = {}) {
|
|
|
9480
9507
|
const totalValue = { amount: total.toFixed(2), currency, lastUpdated: Date.now() };
|
|
9481
9508
|
const portfolio = { totalValue, chainBalances };
|
|
9482
9509
|
spinner.succeed("Portfolio loaded");
|
|
9510
|
+
const scopeHint = buildScopeHint(chains);
|
|
9483
9511
|
if (isJsonOutput()) {
|
|
9484
|
-
outputJson({ portfolio, currency, failures });
|
|
9512
|
+
outputJson({ portfolio, currency, failures, scopeHint });
|
|
9485
9513
|
return;
|
|
9486
9514
|
}
|
|
9487
9515
|
displayPortfolio(portfolio, currency, options.raw ?? false);
|
|
9516
|
+
if (scopeHint) info(`
|
|
9517
|
+
${scopeHint}`);
|
|
9488
9518
|
if (failures.length > 0) {
|
|
9489
9519
|
warn(`
|
|
9490
9520
|
Warning: ${failures.length} chain(s) failed to load fully:`);
|
|
@@ -9495,7 +9525,7 @@ Warning: ${failures.length} chain(s) failed to load fully:`);
|
|
|
9495
9525
|
}
|
|
9496
9526
|
|
|
9497
9527
|
// src/commands/chains.ts
|
|
9498
|
-
import { SUPPORTED_CHAINS } from "@vultisig/sdk";
|
|
9528
|
+
import { SUPPORTED_CHAINS as SUPPORTED_CHAINS2 } from "@vultisig/sdk";
|
|
9499
9529
|
import chalk3 from "chalk";
|
|
9500
9530
|
|
|
9501
9531
|
// src/core/active-vault.ts
|
|
@@ -10332,19 +10362,19 @@ async function executeChains(ctx2, options = {}) {
|
|
|
10332
10362
|
const vault = await ctx2.ensureActiveVault();
|
|
10333
10363
|
if (options.addAll) {
|
|
10334
10364
|
const currentCount = vault.chains.length;
|
|
10335
|
-
const spinner = createSpinner(`Adding all ${
|
|
10336
|
-
await vault.setChains([...
|
|
10337
|
-
const addedCount =
|
|
10338
|
-
spinner.succeed(`Added ${addedCount} chains (${
|
|
10365
|
+
const spinner = createSpinner(`Adding all ${SUPPORTED_CHAINS2.length} supported chains...`);
|
|
10366
|
+
await vault.setChains([...SUPPORTED_CHAINS2]);
|
|
10367
|
+
const addedCount = SUPPORTED_CHAINS2.length - currentCount;
|
|
10368
|
+
spinner.succeed(`Added ${addedCount} chains (${SUPPORTED_CHAINS2.length} total)`);
|
|
10339
10369
|
if (isJsonOutput()) {
|
|
10340
|
-
outputJson({ chains: [...vault.chains], added: addedCount, total:
|
|
10370
|
+
outputJson({ chains: [...vault.chains], added: addedCount, total: SUPPORTED_CHAINS2.length });
|
|
10341
10371
|
return;
|
|
10342
10372
|
}
|
|
10343
10373
|
info(chalk3.gray("\nAll supported chains are now enabled."));
|
|
10344
10374
|
return;
|
|
10345
10375
|
}
|
|
10346
10376
|
if (options.add) {
|
|
10347
|
-
if (!
|
|
10377
|
+
if (!SUPPORTED_CHAINS2.includes(options.add)) {
|
|
10348
10378
|
throw new InvalidChainError(
|
|
10349
10379
|
`Unsupported chain: "${options.add}"`,
|
|
10350
10380
|
'Run "vultisig chains" to see the supported chains, or check the spelling.',
|
|
@@ -10384,7 +10414,7 @@ Chain already active: ${options.add}` : `
|
|
|
10384
10414
|
printResult(` - ${chain}`);
|
|
10385
10415
|
});
|
|
10386
10416
|
info(chalk3.gray(`
|
|
10387
|
-
${chains.length} of ${
|
|
10417
|
+
${chains.length} of ${SUPPORTED_CHAINS2.length} chains enabled`));
|
|
10388
10418
|
info(chalk3.gray("Use --add <chain>, --add-all, or --remove <chain>"));
|
|
10389
10419
|
}
|
|
10390
10420
|
}
|
|
@@ -11466,7 +11496,7 @@ async function executeBroadcast(ctx2, params) {
|
|
|
11466
11496
|
}
|
|
11467
11497
|
|
|
11468
11498
|
// src/commands/tx-status.ts
|
|
11469
|
-
import { Chain as Chain7, isValidTxHash, Vultisig as Vultisig5 } from "@vultisig/sdk";
|
|
11499
|
+
import { Chain as Chain7, isValidTxHash, pollTxStatusUntilFinal, Vultisig as Vultisig5 } from "@vultisig/sdk";
|
|
11470
11500
|
function resolveTxStatusParams(params) {
|
|
11471
11501
|
if (!Object.values(Chain7).includes(params.chain)) {
|
|
11472
11502
|
throw new InvalidInputError(`Invalid chain: ${params.chain}`);
|
|
@@ -11499,19 +11529,26 @@ async function executeTxStatus(ctx2, params, opts = {}) {
|
|
|
11499
11529
|
try {
|
|
11500
11530
|
let result = await vault.getTxStatus({ chain: params.chain, txHash: params.txHash });
|
|
11501
11531
|
if (!params.noWait && !isTerminal(result.status)) {
|
|
11502
|
-
const
|
|
11532
|
+
const timeoutMs = resolveTimeoutMs(params.timeoutSec);
|
|
11503
11533
|
let waited = 0;
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
|
|
11507
|
-
|
|
11508
|
-
|
|
11534
|
+
const outcome = await pollTxStatusUntilFinal({
|
|
11535
|
+
chain: params.chain,
|
|
11536
|
+
txHash: params.txHash,
|
|
11537
|
+
initialResult: result,
|
|
11538
|
+
timeoutMs,
|
|
11539
|
+
intervalMs: pollIntervalMs,
|
|
11540
|
+
getTxStatus: (pollParams) => vault.getTxStatus(pollParams),
|
|
11541
|
+
isTerminal: (candidate) => isTerminal(candidate.status),
|
|
11542
|
+
sleep: async (ms) => {
|
|
11543
|
+
waited += ms;
|
|
11544
|
+
spinner.text = `Transaction ${result.status}... (${Math.round(waited / 1e3)}s)`;
|
|
11545
|
+
await sleep(ms);
|
|
11509
11546
|
}
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
11514
|
-
|
|
11547
|
+
});
|
|
11548
|
+
if (outcome.result) result = outcome.result;
|
|
11549
|
+
if (outcome.timedOut) {
|
|
11550
|
+
spinner.fail(`Gave up waiting after ${Math.round(outcome.elapsedMs / 1e3)}s (status: ${result.status})`);
|
|
11551
|
+
throw giveUpError(params, result, outcome.elapsedMs);
|
|
11515
11552
|
}
|
|
11516
11553
|
}
|
|
11517
11554
|
if (result.status === "success") {
|
|
@@ -14038,14 +14075,15 @@ import { getChainKind as getChainKind5 } from "@vultisig/sdk";
|
|
|
14038
14075
|
// src/agent/executor.ts
|
|
14039
14076
|
import {
|
|
14040
14077
|
Chain as Chain11,
|
|
14041
|
-
chainFeeCoin as chainFeeCoin2,
|
|
14042
14078
|
computeEip712Hash,
|
|
14043
14079
|
getChainKind as getChainKind4,
|
|
14044
14080
|
getEvmRpcUrl,
|
|
14045
14081
|
knownTokensIndex,
|
|
14046
|
-
|
|
14082
|
+
parseTxReadyEnvelope,
|
|
14083
|
+
pollTxStatusUntilFinal as pollTxStatusUntilFinal2,
|
|
14047
14084
|
resolveChainReference,
|
|
14048
14085
|
toCanonicalEvmSignature,
|
|
14086
|
+
TxReadyParseError,
|
|
14049
14087
|
VaultError as VaultError3,
|
|
14050
14088
|
VaultErrorCode as VaultErrorCode3,
|
|
14051
14089
|
Vultisig as VultisigSdk
|
|
@@ -14463,6 +14501,18 @@ function decodeErc20Transfer(calldata) {
|
|
|
14463
14501
|
}
|
|
14464
14502
|
}
|
|
14465
14503
|
var isEvmChain = (chain) => EVM_CHAINS.has(chain);
|
|
14504
|
+
function stripEmbeddedPayloadContract(value, disclosedContract) {
|
|
14505
|
+
if (!disclosedContract) return value;
|
|
14506
|
+
const escapedContract = disclosedContract.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14507
|
+
const normalizedContract = disclosedContract.toLowerCase();
|
|
14508
|
+
return value.replace(new RegExp(escapedContract, "gi"), "").replace(/0x([0-9a-fA-F]{2,8})(?:…|\.{3})([0-9a-fA-F]{2,8})/g, (match, prefix, suffix) => {
|
|
14509
|
+
const normalizedPrefix = `0x${prefix}`.toLowerCase();
|
|
14510
|
+
return normalizedContract.startsWith(normalizedPrefix) && normalizedContract.endsWith(suffix.toLowerCase()) ? "" : match;
|
|
14511
|
+
}).replace(/\(\s*\)/g, "").replace(/\s{2,}/g, " ").trim();
|
|
14512
|
+
}
|
|
14513
|
+
function formatTokenContractDisclosure(disclosedContract) {
|
|
14514
|
+
return disclosedContract ? ` (token contract ${disclosedContract})` : "";
|
|
14515
|
+
}
|
|
14466
14516
|
var AgentExecutor = class {
|
|
14467
14517
|
vault;
|
|
14468
14518
|
/** Owning SDK (optional); used for address book backed by app storage */
|
|
@@ -14852,11 +14902,35 @@ var AgentExecutor = class {
|
|
|
14852
14902
|
if (transfer) {
|
|
14853
14903
|
return this.renderErc20TransferSummary(transfer.amount, contractTo, stored.chain, to);
|
|
14854
14904
|
}
|
|
14855
|
-
const
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14905
|
+
const disclosedContract = isContractSend && contractTo.toLowerCase() !== to.toLowerCase() ? contractTo : "";
|
|
14906
|
+
return this.renderLabelSendSummary(p, labels, stored.chain, to, disclosedContract);
|
|
14907
|
+
}
|
|
14908
|
+
/**
|
|
14909
|
+
* Render the send summary from producer labels — the fallback for native,
|
|
14910
|
+
* non-EVM, and non-transfer envelopes only (decoded ERC-20 transfers are
|
|
14911
|
+
* rendered from calldata by renderErc20TransferSummary above). De-duplicates
|
|
14912
|
+
* token/chain/contract details the label may repeat, anchored to the routed
|
|
14913
|
+
* chain and the payload-derived contract disclosure.
|
|
14914
|
+
*/
|
|
14915
|
+
renderLabelSendSummary(p, labels, chain, to, disclosedContract) {
|
|
14916
|
+
const amount = stripEmbeddedPayloadContract(labels.resolved_amount ?? p?.txArgs?.amount ?? "?", disclosedContract);
|
|
14917
|
+
const tokenLabel = stripEmbeddedPayloadContract(
|
|
14918
|
+
(labels.token_resolved || labels.token_symbol || "").trim(),
|
|
14919
|
+
disclosedContract
|
|
14920
|
+
);
|
|
14921
|
+
const symbol = tokenLabel.split(/\s+/, 1)[0];
|
|
14922
|
+
const escapedChain = String(chain).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14923
|
+
const routedChainPattern = new RegExp(`(?:^|\\s)(?:not\\s+)?on ${escapedChain}(?=\\s|$)`);
|
|
14924
|
+
const positiveRoutedChainPattern = new RegExp(`(?:^|\\s)(?<!\\bnot\\s+)on ${escapedChain}(?=\\s|$)`);
|
|
14925
|
+
const tokenContext = tokenLabel.slice(symbol.length);
|
|
14926
|
+
const labelCarriesRoutedChain = positiveRoutedChainPattern.test(tokenContext);
|
|
14927
|
+
const tokenDetail = tokenContext.replace(routedChainPattern, "").trim();
|
|
14928
|
+
const amountEmbedsTokenLabel = tokenLabel.length > 0 && amount.endsWith(` ${tokenLabel}`);
|
|
14929
|
+
const amountWithSymbol = symbol && !amount.endsWith(` ${symbol}`) && !amountEmbedsTokenLabel ? `${amount} ${symbol}` : amount;
|
|
14930
|
+
const tokenDetailSuffix = amountEmbedsTokenLabel || !tokenDetail ? "" : ` ${tokenDetail}`;
|
|
14931
|
+
const location = amountEmbedsTokenLabel && labelCarriesRoutedChain ? "" : `on ${chain}${tokenDetailSuffix}`;
|
|
14932
|
+
const contractPart = formatTokenContractDisclosure(disclosedContract);
|
|
14933
|
+
return `send ${amountWithSymbol}${location ? ` ${location}` : ""} to ${to}${contractPart}`;
|
|
14860
14934
|
}
|
|
14861
14935
|
/**
|
|
14862
14936
|
* Render the consent amount for an ERC-20 transfer from the SIGNED calldata
|
|
@@ -15150,8 +15224,8 @@ var AgentExecutor = class {
|
|
|
15150
15224
|
return this.signNonEvmServerTx(serverTxData, chain);
|
|
15151
15225
|
}
|
|
15152
15226
|
/**
|
|
15153
|
-
* Non-EVM signing path: parse the agent's tx_ready envelope
|
|
15154
|
-
*
|
|
15227
|
+
* Non-EVM signing path: parse the agent's tx_ready envelope through the
|
|
15228
|
+
* SDK's canonical discriminated contract and call through. The SDK already
|
|
15155
15229
|
* handles per-chain prepare/sign/broadcast internally via
|
|
15156
15230
|
* `VaultBase.prepareSendTx` virtuals — sdk-cli only owns envelope
|
|
15157
15231
|
* parsing here, not chain-specific signing logic.
|
|
@@ -15178,20 +15252,20 @@ var AgentExecutor = class {
|
|
|
15178
15252
|
`signNonEvmServerTx: dispatcher chain '${chain}' disagrees with envelope chain '${txArgs.chain}'`
|
|
15179
15253
|
);
|
|
15180
15254
|
}
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
|
|
15255
|
+
const parsed = parseTxReadyForCli(serverTxData, chain, this.vault.getTokens?.(chain) ?? []);
|
|
15256
|
+
if (parsed.kind === "thor-swap-deposit") {
|
|
15257
|
+
return this.signThorMsgDepositSwap(parsed);
|
|
15258
|
+
}
|
|
15259
|
+
if (parsed.kind === "thor-lp-deposit") {
|
|
15260
|
+
return this.signThorMsgDepositLp(parsed);
|
|
15261
|
+
}
|
|
15262
|
+
if (parsed.kind !== "send") {
|
|
15189
15263
|
throw new VaultError3(
|
|
15190
|
-
VaultErrorCode3.
|
|
15191
|
-
`signNonEvmServerTx:
|
|
15264
|
+
VaultErrorCode3.InvalidConfig,
|
|
15265
|
+
`signNonEvmServerTx: expected a non-EVM send/deposit envelope, got ${parsed.kind}`
|
|
15192
15266
|
);
|
|
15193
15267
|
}
|
|
15194
|
-
const args =
|
|
15268
|
+
const args = parsed;
|
|
15195
15269
|
if (this.verbose)
|
|
15196
15270
|
process.stderr.write(
|
|
15197
15271
|
`[sign_non_evm_server_tx] chain=${chain}, to=${args.to}, amount=${args.amount}${args.symbol ? ` ${args.symbol}` : ""}, memo=${args.memo ? `"${args.memo}"` : "(none)"}
|
|
@@ -15240,38 +15314,20 @@ var AgentExecutor = class {
|
|
|
15240
15314
|
* cross-account route cannot be silently replaced with the vault's address.
|
|
15241
15315
|
* An omitted destination keeps the existing self-swap default.
|
|
15242
15316
|
*/
|
|
15243
|
-
async signThorMsgDepositSwap(
|
|
15244
|
-
const
|
|
15245
|
-
const memo = typeof txArgs.memo === "string" ? txArgs.memo : "";
|
|
15246
|
-
const parsed = parseThorSwapMemo(memo);
|
|
15247
|
-
if (/\s/.test(parsed.destAddress)) {
|
|
15248
|
-
throw new VaultError3(
|
|
15249
|
-
VaultErrorCode3.InvalidConfig,
|
|
15250
|
-
`signThorMsgDepositSwap: destination address in memo '${memo}' must not contain whitespace.`
|
|
15251
|
-
);
|
|
15252
|
-
}
|
|
15253
|
-
const toChain = parsed.toChain;
|
|
15254
|
-
const fromSymbol = chain === Chain11.THORChain ? "RUNE" : "CACAO";
|
|
15255
|
-
const amountRaw = typeof txArgs.amount === "string" ? txArgs.amount : void 0;
|
|
15256
|
-
if (!amountRaw) {
|
|
15257
|
-
throw new VaultError3(
|
|
15258
|
-
VaultErrorCode3.InvalidConfig,
|
|
15259
|
-
`signThorMsgDepositSwap: missing or non-string 'amount' field on ${chain} envelope`
|
|
15260
|
-
);
|
|
15261
|
-
}
|
|
15262
|
-
const amountDecimal = convertBaseUnitsToDecimal(chain, amountRaw, "signThorMsgDepositSwap");
|
|
15317
|
+
async signThorMsgDepositSwap(parsed) {
|
|
15318
|
+
const { amount, chain, fromSymbol, memo, recipient, toChain, toSymbol } = parsed;
|
|
15263
15319
|
if (this.verbose)
|
|
15264
15320
|
process.stderr.write(
|
|
15265
|
-
`[sign_thor_msg_deposit_swap] ${fromSymbol}@${chain} \u2192 ${
|
|
15321
|
+
`[sign_thor_msg_deposit_swap] ${fromSymbol}@${chain} \u2192 ${toSymbol}@${toChain}, amount=${amount}, memo='${memo}'
|
|
15266
15322
|
`
|
|
15267
15323
|
);
|
|
15268
15324
|
const result = await this.vault.swap({
|
|
15269
15325
|
fromChain: chain,
|
|
15270
15326
|
fromSymbol,
|
|
15271
15327
|
toChain,
|
|
15272
|
-
toSymbol
|
|
15273
|
-
amount
|
|
15274
|
-
...
|
|
15328
|
+
toSymbol,
|
|
15329
|
+
amount,
|
|
15330
|
+
...recipient && { recipient }
|
|
15275
15331
|
});
|
|
15276
15332
|
if (result.dryRun) {
|
|
15277
15333
|
throw new VaultError3(
|
|
@@ -15303,28 +15359,16 @@ var AgentExecutor = class {
|
|
|
15303
15359
|
* as base units directly (no decimal conversion) since the agent
|
|
15304
15360
|
* already emits RUNE / CACAO in base units.
|
|
15305
15361
|
*/
|
|
15306
|
-
async signThorMsgDepositLp(
|
|
15307
|
-
const
|
|
15308
|
-
const memo = typeof txArgs.memo === "string" ? txArgs.memo : "";
|
|
15309
|
-
const amountRaw = typeof txArgs.amount === "string" ? txArgs.amount : void 0;
|
|
15310
|
-
if (!amountRaw) {
|
|
15311
|
-
throw new VaultError3(
|
|
15312
|
-
VaultErrorCode3.InvalidConfig,
|
|
15313
|
-
`signThorMsgDepositLp: missing or non-string 'amount' field on ${chain} envelope`
|
|
15314
|
-
);
|
|
15315
|
-
}
|
|
15316
|
-
if (amountRaw.length > MAX_AMOUNT_DIGITS) {
|
|
15317
|
-
throw new VaultError3(
|
|
15318
|
-
VaultErrorCode3.InvalidAmount,
|
|
15319
|
-
`signThorMsgDepositLp: amount '${amountRaw}' for ${chain} exceeds ${MAX_AMOUNT_DIGITS}-digit safety bound. Likely a quote-side bug. Refusing to sign.`
|
|
15320
|
-
);
|
|
15321
|
-
}
|
|
15362
|
+
async signThorMsgDepositLp(parsed) {
|
|
15363
|
+
const { amountBaseUnits, chain, memo } = parsed;
|
|
15322
15364
|
if (this.verbose)
|
|
15323
|
-
process.stderr.write(
|
|
15324
|
-
`
|
|
15365
|
+
process.stderr.write(
|
|
15366
|
+
`[sign_thor_msg_deposit_lp] chain=${chain}, memo='${memo}', amountBaseUnits=${amountBaseUnits}
|
|
15367
|
+
`
|
|
15368
|
+
);
|
|
15325
15369
|
const result = await this.vault.signMsgDeposit({
|
|
15326
15370
|
chain,
|
|
15327
|
-
amountBaseUnits
|
|
15371
|
+
amountBaseUnits,
|
|
15328
15372
|
memo
|
|
15329
15373
|
});
|
|
15330
15374
|
this.pendingPayloads.clear();
|
|
@@ -15338,9 +15382,8 @@ var AgentExecutor = class {
|
|
|
15338
15382
|
}
|
|
15339
15383
|
/**
|
|
15340
15384
|
* Sign and broadcast a server-built EVM transaction (raw EVM tx from
|
|
15341
|
-
* tx_ready SSE).
|
|
15342
|
-
*
|
|
15343
|
-
* `signMultiLeg` depends on for back-to-back approve+main broadcasts.
|
|
15385
|
+
* tx_ready SSE). The SDK raw-envelope helper owns zero-value calldata,
|
|
15386
|
+
* gas-limit, and fee mapping; the CLI reconciles its nonce with local state.
|
|
15344
15387
|
*/
|
|
15345
15388
|
async signEvmServerTx(serverTxData, defaultChain, params) {
|
|
15346
15389
|
const swapTx = extractNestedTx(serverTxData);
|
|
@@ -15357,14 +15400,6 @@ var AgentExecutor = class {
|
|
|
15357
15400
|
}
|
|
15358
15401
|
await this.acquireEvmLockIfNeeded(chain);
|
|
15359
15402
|
try {
|
|
15360
|
-
const address = await this.vault.address(chain);
|
|
15361
|
-
const balance = await this.vault.balance(chain);
|
|
15362
|
-
const coin = {
|
|
15363
|
-
chain,
|
|
15364
|
-
address,
|
|
15365
|
-
decimals: balance.decimals || 18,
|
|
15366
|
-
ticker: balance.symbol || chain.toString()
|
|
15367
|
-
};
|
|
15368
15403
|
const amount = BigInt(swapTx.value || "0");
|
|
15369
15404
|
const hasCalldata = !!(swapTx.data && swapTx.data !== "0x");
|
|
15370
15405
|
if (this.verbose)
|
|
@@ -15377,30 +15412,19 @@ var AgentExecutor = class {
|
|
|
15377
15412
|
await this.vault.unlock?.(this.password);
|
|
15378
15413
|
}
|
|
15379
15414
|
}
|
|
15380
|
-
const
|
|
15381
|
-
|
|
15382
|
-
|
|
15383
|
-
|
|
15384
|
-
|
|
15385
|
-
|
|
15415
|
+
const keysignPayload = await this.vault.prepareRawEvmTx({
|
|
15416
|
+
chain,
|
|
15417
|
+
tx: {
|
|
15418
|
+
to: swapTx.to,
|
|
15419
|
+
value: swapTx.value ?? 0n,
|
|
15420
|
+
data: swapTx.data ?? "0x",
|
|
15421
|
+
gasLimit: swapTx.gasLimit ?? swapTx.gas_limit,
|
|
15422
|
+
maxFeePerGas: swapTx.maxFeePerGas ?? swapTx.max_fee_per_gas,
|
|
15423
|
+
maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas ?? swapTx.max_priority_fee_per_gas,
|
|
15424
|
+
nonce: swapTx.nonce
|
|
15425
|
+
}
|
|
15386
15426
|
});
|
|
15387
|
-
if (amount === 0n && hasCalldata) {
|
|
15388
|
-
;
|
|
15389
|
-
keysignPayload.toAmount = "0";
|
|
15390
|
-
}
|
|
15391
15427
|
await this.patchEvmNonce(chain, keysignPayload);
|
|
15392
|
-
if (swapTx.gas_limit) {
|
|
15393
|
-
const bs = keysignPayload.blockchainSpecific;
|
|
15394
|
-
if (bs?.case === "ethereumSpecific" && bs.value?.gasLimit) {
|
|
15395
|
-
const serverGas = swapTx.gas_limit.toString();
|
|
15396
|
-
const currentGas = bs.value.gasLimit.toString();
|
|
15397
|
-
if (BigInt(serverGas) > BigInt(currentGas)) {
|
|
15398
|
-
bs.value.gasLimit = serverGas;
|
|
15399
|
-
if (this.verbose) process.stderr.write(`[gas] Using server gas_limit: ${serverGas} (was ${currentGas})
|
|
15400
|
-
`);
|
|
15401
|
-
}
|
|
15402
|
-
}
|
|
15403
|
-
}
|
|
15404
15428
|
await this.patchEvmGas(chain, keysignPayload);
|
|
15405
15429
|
const messageHashes = await this.vault.extractMessageHashes(keysignPayload);
|
|
15406
15430
|
const signature = await this.vault.sign(
|
|
@@ -15512,20 +15536,20 @@ var AgentExecutor = class {
|
|
|
15512
15536
|
* success.
|
|
15513
15537
|
*/
|
|
15514
15538
|
async waitForEvmReceipt(chain, txHash, opts) {
|
|
15515
|
-
const
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
|
|
15521
|
-
|
|
15522
|
-
|
|
15523
|
-
|
|
15524
|
-
} catch (e) {
|
|
15525
|
-
if (e instanceof VaultError3 && e.code === VaultErrorCode3.BroadcastFailed) throw e;
|
|
15526
|
-
if (e?.message?.includes("reverted")) throw e;
|
|
15539
|
+
const outcome = await pollTxStatusUntilFinal2({
|
|
15540
|
+
chain,
|
|
15541
|
+
txHash,
|
|
15542
|
+
timeoutMs: opts.timeoutSec * 1e3,
|
|
15543
|
+
intervalMs: 3e3,
|
|
15544
|
+
getTxStatus: (params) => this.vault.getTxStatus(params),
|
|
15545
|
+
shouldRetryError: (error2) => {
|
|
15546
|
+
if (error2 instanceof VaultError3 && error2.code === VaultErrorCode3.BroadcastFailed) return false;
|
|
15547
|
+
return !error2?.message?.includes("reverted");
|
|
15527
15548
|
}
|
|
15528
|
-
|
|
15549
|
+
});
|
|
15550
|
+
if (outcome.result?.status === "success") return;
|
|
15551
|
+
if (outcome.result?.status === "error") {
|
|
15552
|
+
throw new VaultError3(VaultErrorCode3.BroadcastFailed, `approve tx reverted (${txHash})`);
|
|
15529
15553
|
}
|
|
15530
15554
|
throw new VaultError3(VaultErrorCode3.Timeout, `approve tx ${txHash} not confirmed within ${opts.timeoutSec}s`);
|
|
15531
15555
|
}
|
|
@@ -16020,49 +16044,14 @@ function resolveChainFromTxReady(txReadyData) {
|
|
|
16020
16044
|
function extractNestedTx(txReadyData) {
|
|
16021
16045
|
return txReadyData?.swap_tx || txReadyData?.send_tx || txReadyData?.tx || txReadyData?.txArgs?.tx;
|
|
16022
16046
|
}
|
|
16023
|
-
|
|
16024
|
-
function convertBaseUnitsToDecimal(chain, amountRaw, context) {
|
|
16025
|
-
if (amountRaw.length > MAX_AMOUNT_DIGITS) {
|
|
16026
|
-
throw new VaultError3(
|
|
16027
|
-
VaultErrorCode3.InvalidAmount,
|
|
16028
|
-
`${context}: amount '${amountRaw}' for ${chain} exceeds ${MAX_AMOUNT_DIGITS}-digit safety bound. Likely a quote-side bug. Refusing to sign.`
|
|
16029
|
-
);
|
|
16030
|
-
}
|
|
16031
|
-
const decimals = chainFeeCoin2[chain]?.decimals;
|
|
16032
|
-
if (decimals === void 0) {
|
|
16033
|
-
throw new VaultError3(VaultErrorCode3.UnsupportedChain, `${context}: no native decimals registered for ${chain}`);
|
|
16034
|
-
}
|
|
16047
|
+
function parseTxReadyForCli(serverTxData, defaultChain, tokens = []) {
|
|
16035
16048
|
try {
|
|
16036
|
-
return
|
|
16037
|
-
} catch (
|
|
16038
|
-
throw
|
|
16039
|
-
|
|
16040
|
-
|
|
16041
|
-
);
|
|
16042
|
-
}
|
|
16043
|
-
}
|
|
16044
|
-
function parseNonEvmEnvelope(serverTxData, chain) {
|
|
16045
|
-
const txArgs = serverTxData?.txArgs ?? serverTxData;
|
|
16046
|
-
if (!txArgs || typeof txArgs !== "object") {
|
|
16047
|
-
throw new VaultError3(VaultErrorCode3.InvalidConfig, "parseNonEvmEnvelope: envelope missing txArgs");
|
|
16048
|
-
}
|
|
16049
|
-
const to = typeof txArgs.to === "string" ? txArgs.to : void 0;
|
|
16050
|
-
if (!to) {
|
|
16051
|
-
throw new VaultError3(VaultErrorCode3.InvalidConfig, `parseNonEvmEnvelope: missing 'to' field for ${chain}`);
|
|
16052
|
-
}
|
|
16053
|
-
const amountRaw = typeof txArgs.amount === "string" ? txArgs.amount : void 0;
|
|
16054
|
-
if (!amountRaw) {
|
|
16055
|
-
throw new VaultError3(VaultErrorCode3.InvalidConfig, `parseNonEvmEnvelope: missing 'amount' field for ${chain}`);
|
|
16056
|
-
}
|
|
16057
|
-
const amountDecimal = convertBaseUnitsToDecimal(chain, amountRaw, "parseNonEvmEnvelope");
|
|
16058
|
-
let symbol;
|
|
16059
|
-
const tokenResolved = serverTxData?.resolved?.labels?.token_resolved;
|
|
16060
|
-
const nativeTicker = chainFeeCoin2[chain]?.ticker;
|
|
16061
|
-
if (typeof tokenResolved === "string" && tokenResolved !== nativeTicker) {
|
|
16062
|
-
symbol = tokenResolved;
|
|
16049
|
+
return parseTxReadyEnvelope(serverTxData, { defaultChain, tokens });
|
|
16050
|
+
} catch (error2) {
|
|
16051
|
+
if (!(error2 instanceof TxReadyParseError)) throw error2;
|
|
16052
|
+
const code = error2.code === "INVALID_AMOUNT" ? VaultErrorCode3.InvalidAmount : error2.code === "UNKNOWN_CHAIN" ? VaultErrorCode3.UnsupportedChain : error2.code === "UNSUPPORTED_DEPOSIT" || error2.code === "UNSUPPORTED_ENVELOPE" ? VaultErrorCode3.NotImplemented : VaultErrorCode3.InvalidConfig;
|
|
16053
|
+
throw new VaultError3(code, error2.message);
|
|
16063
16054
|
}
|
|
16064
|
-
const memo = typeof txArgs.memo === "string" && txArgs.memo.length > 0 ? txArgs.memo : void 0;
|
|
16065
|
-
return { chain, to, amount: amountDecimal, symbol, memo };
|
|
16066
16055
|
}
|
|
16067
16056
|
function resolveChainId(chainId) {
|
|
16068
16057
|
return resolveChainReference(chainId) ?? null;
|
|
@@ -17123,7 +17112,7 @@ var AgentClient = class {
|
|
|
17123
17112
|
};
|
|
17124
17113
|
|
|
17125
17114
|
// src/agent/context.ts
|
|
17126
|
-
import { chainFeeCoin as
|
|
17115
|
+
import { chainFeeCoin as chainFeeCoin2 } from "@vultisig/sdk";
|
|
17127
17116
|
function applyChainPublicKeys(vault, context) {
|
|
17128
17117
|
const raw = vault.data.chainPublicKeys;
|
|
17129
17118
|
if (!raw) return;
|
|
@@ -17184,7 +17173,7 @@ async function buildMessageContext(vault) {
|
|
|
17184
17173
|
const coins = [];
|
|
17185
17174
|
const chains = vault.chains;
|
|
17186
17175
|
for (const chain of chains) {
|
|
17187
|
-
const nativeCoin =
|
|
17176
|
+
const nativeCoin = chainFeeCoin2[chain];
|
|
17188
17177
|
coins.push({
|
|
17189
17178
|
chain: chain.toString(),
|
|
17190
17179
|
ticker: nativeCoin?.ticker ?? chain.toString(),
|
|
@@ -19491,7 +19480,7 @@ var cachedVersion = null;
|
|
|
19491
19480
|
function getVersion() {
|
|
19492
19481
|
if (cachedVersion) return cachedVersion;
|
|
19493
19482
|
if (true) {
|
|
19494
|
-
cachedVersion = "
|
|
19483
|
+
cachedVersion = "6.2.0";
|
|
19495
19484
|
return cachedVersion;
|
|
19496
19485
|
}
|
|
19497
19486
|
try {
|
|
@@ -19756,8 +19745,16 @@ function executeSchema(prog) {
|
|
|
19756
19745
|
};
|
|
19757
19746
|
})
|
|
19758
19747
|
};
|
|
19759
|
-
|
|
19760
|
-
|
|
19748
|
+
return new Promise((resolve, reject) => {
|
|
19749
|
+
process.stdout.write(`${JSON.stringify(schema, null, 2)}
|
|
19750
|
+
`, (error2) => {
|
|
19751
|
+
if (error2) {
|
|
19752
|
+
reject(error2);
|
|
19753
|
+
return;
|
|
19754
|
+
}
|
|
19755
|
+
resolve();
|
|
19756
|
+
});
|
|
19757
|
+
});
|
|
19761
19758
|
}
|
|
19762
19759
|
|
|
19763
19760
|
// src/core/server-endpoints.ts
|
|
@@ -21060,7 +21057,7 @@ Error: ${error2.message}`));
|
|
|
21060
21057
|
|
|
21061
21058
|
// src/lib/completion.ts
|
|
21062
21059
|
import { getVultisigConfigDir as getVultisigConfigDir5 } from "@vultisig/client-shared";
|
|
21063
|
-
import { SUPPORTED_CHAINS as
|
|
21060
|
+
import { SUPPORTED_CHAINS as SUPPORTED_CHAINS3 } from "@vultisig/sdk";
|
|
21064
21061
|
import { program } from "commander";
|
|
21065
21062
|
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync5 } from "fs";
|
|
21066
21063
|
import { join as join5 } from "path";
|
|
@@ -21082,7 +21079,7 @@ function getCommands() {
|
|
|
21082
21079
|
return program.commands.map((cmd) => cmd.name()).sort();
|
|
21083
21080
|
}
|
|
21084
21081
|
function getChains() {
|
|
21085
|
-
return [...
|
|
21082
|
+
return [...SUPPORTED_CHAINS3];
|
|
21086
21083
|
}
|
|
21087
21084
|
function getVaultNames() {
|
|
21088
21085
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "The self-custody MPC wallet CLI for AI coding agents (Claude Code, Cursor, OpenCode). Natural-language agent mode, 36+ chains, DKLS23 threshold signatures. Seedless.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -67,17 +67,16 @@
|
|
|
67
67
|
},
|
|
68
68
|
"homepage": "https://vultisig.com",
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@cosmjs/cosmwasm-stargate": "^0.39.0",
|
|
71
70
|
"@cosmjs/encoding": "^0.39.0",
|
|
72
71
|
"@cosmjs/proto-signing": "^0.39.0",
|
|
73
72
|
"@cosmjs/stargate": "^0.39.0",
|
|
74
73
|
"@msgpack/msgpack": "^3.1.2",
|
|
75
74
|
"@napi-rs/keyring": "^1.3.0",
|
|
76
75
|
"@noble/hashes": "^2.2.0",
|
|
77
|
-
"@vultisig/client-shared": "^0.3.
|
|
78
|
-
"@vultisig/core-chain": "^
|
|
79
|
-
"@vultisig/rujira": "^
|
|
80
|
-
"@vultisig/sdk": "^
|
|
76
|
+
"@vultisig/client-shared": "^0.3.5",
|
|
77
|
+
"@vultisig/core-chain": "^4.1.0",
|
|
78
|
+
"@vultisig/rujira": "^70.0.0",
|
|
79
|
+
"@vultisig/sdk": "^6.2.0",
|
|
81
80
|
"chalk": "^5.6.2",
|
|
82
81
|
"cli-table3": "^0.6.5",
|
|
83
82
|
"commander": "^15.0.0",
|
|
@@ -95,7 +94,7 @@
|
|
|
95
94
|
"@types/node": "^26.1.1",
|
|
96
95
|
"@types/tabtab": "^3.0.4",
|
|
97
96
|
"@types/ws": "^8.18.1",
|
|
98
|
-
"@vultisig/core-mpc": "^1.
|
|
97
|
+
"@vultisig/core-mpc": "^2.1.0",
|
|
99
98
|
"esbuild": "^0.28.1",
|
|
100
99
|
"ethers": "^6.17.0",
|
|
101
100
|
"node-pty": "^1.1.0",
|
|
@@ -104,7 +103,7 @@
|
|
|
104
103
|
"vitest": "^4.1.8"
|
|
105
104
|
},
|
|
106
105
|
"engines": {
|
|
107
|
-
"node": ">=20.
|
|
106
|
+
"node": ">=20.19.0"
|
|
108
107
|
},
|
|
109
108
|
"publishConfig": {
|
|
110
109
|
"access": "public",
|