@vultisig/cli 4.0.1 → 4.0.3

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 +33 -0
  2. package/dist/index.js +160 -99
  3. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @vultisig/cli
2
2
 
3
+ ## 4.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1588](https://github.com/vultisig/vultisig-sdk/pull/1588) [`74cc529`](https://github.com/vultisig/vultisig-sdk/commit/74cc52912f007c6e2afe3c5b9471b6610d39f3fc) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Export the canonical gas comparison helpers from `@vultisig/sdk/react-native`.
8
+
9
+ - [#1717](https://github.com/vultisig/vultisig-sdk/pull/1717) [`c109ff4`](https://github.com/vultisig/vultisig-sdk/commit/c109ff4f6504b9458454bad9b392f2682a51992a) Thanks [@neavra](https://github.com/neavra)! - Create keyshare temp files exclusively and keep credential and CLI config directories owner-only.
10
+
11
+ - [#1718](https://github.com/vultisig/vultisig-sdk/pull/1718) [`fb601d5`](https://github.com/vultisig/vultisig-sdk/commit/fb601d5ad6f6e6a7089ca449ee24bc5c1d7b82f9) Thanks [@neavra](https://github.com/neavra)! - Make transaction help accurately distinguish interactive previews from non-interactive confirmation requirements, describe the addresses command without advertising an unsupported argument, and remove duplicated wording from amount-too-small swap errors.
12
+
13
+ - Updated dependencies [[`a6ba6b4`](https://github.com/vultisig/vultisig-sdk/commit/a6ba6b4688027d6abf4ce0eb3385d6e141f5ef57), [`67667fe`](https://github.com/vultisig/vultisig-sdk/commit/67667fe61a8dd85d40c1b91978da5414987cab6c), [`fbc5b44`](https://github.com/vultisig/vultisig-sdk/commit/fbc5b4445e102534eb434d7cabcd6fe8d633b391), [`74cc529`](https://github.com/vultisig/vultisig-sdk/commit/74cc52912f007c6e2afe3c5b9471b6610d39f3fc), [`c49a3f2`](https://github.com/vultisig/vultisig-sdk/commit/c49a3f2bdff6d220960c3609d08b6c848961ed9f), [`c109ff4`](https://github.com/vultisig/vultisig-sdk/commit/c109ff4f6504b9458454bad9b392f2682a51992a), [`fb601d5`](https://github.com/vultisig/vultisig-sdk/commit/fb601d5ad6f6e6a7089ca449ee24bc5c1d7b82f9), [`82ea0b7`](https://github.com/vultisig/vultisig-sdk/commit/82ea0b7526ef7033605aeed461bb156416e4c012)]:
14
+ - @vultisig/sdk@4.0.3
15
+ - @vultisig/core-chain@2.31.2
16
+ - @vultisig/client-shared@0.3.3
17
+
18
+ ## 4.0.2
19
+
20
+ ### Patch Changes
21
+
22
+ - [#1580](https://github.com/vultisig/vultisig-sdk/pull/1580) [`1a87e08`](https://github.com/vultisig/vultisig-sdk/commit/1a87e080449b37475434f38c99212cc877fd5a4e) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Publish `@vultisig/sdk/tools/bridge` as a real package subpath with dedicated JS and declaration bundles.
23
+
24
+ - [#1641](https://github.com/vultisig/vultisig-sdk/pull/1641) [`199507d`](https://github.com/vultisig/vultisig-sdk/commit/199507da2be585e8b8414d7d12077174c80afb7b) Thanks [@neavra](https://github.com/neavra)! - Replace unavailable Ethereum and Polygon gas-refresh RPC endpoints, warn when pre-sign gas or nonce refreshes fail, and preserve nonce-gap safeguards when a pending-nonce lookup fails. Ethereum and Polygon pending-nonce checks now share the vault address and request timing with PublicNode.
25
+
26
+ - [#1578](https://github.com/vultisig/vultisig-sdk/pull/1578) [`9ff1eb2`](https://github.com/vultisig/vultisig-sdk/commit/9ff1eb22030cf2551269b4195155e395d624223b) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Export the full River helper family from `@vultisig/sdk/react-native`, including market/hint helpers and trove-status canonicals.
27
+
28
+ - [#1576](https://github.com/vultisig/vultisig-sdk/pull/1576) [`7ca8c40`](https://github.com/vultisig/vultisig-sdk/commit/7ca8c406a718624a701b8616a3cee1bbab6c5554) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Fix the Astroport swap builder to use a React Native / Hermes-safe fetch timeout instead of `AbortSignal.timeout()`.
29
+
30
+ - [#1720](https://github.com/vultisig/vultisig-sdk/pull/1720) [`413423b`](https://github.com/vultisig/vultisig-sdk/commit/413423b70655e6e4d7faf9cb9f10b63f601e42dc) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Carry caller-supplied THORChain and MayaChain swap destinations through agent MsgDeposit execution, preserve the existing self-swap default, and reject quote memos that substitute another destination.
31
+
32
+ - Updated dependencies [[`1a87e08`](https://github.com/vultisig/vultisig-sdk/commit/1a87e080449b37475434f38c99212cc877fd5a4e), [`9ff1eb2`](https://github.com/vultisig/vultisig-sdk/commit/9ff1eb22030cf2551269b4195155e395d624223b), [`7ca8c40`](https://github.com/vultisig/vultisig-sdk/commit/7ca8c406a718624a701b8616a3cee1bbab6c5554), [`9dfd76c`](https://github.com/vultisig/vultisig-sdk/commit/9dfd76c617812418521c820e65a07a02003d5e5e), [`413423b`](https://github.com/vultisig/vultisig-sdk/commit/413423b70655e6e4d7faf9cb9f10b63f601e42dc)]:
33
+ - @vultisig/sdk@4.0.2
34
+ - @vultisig/core-chain@2.31.1
35
+
3
36
  ## 4.0.1
4
37
 
5
38
  ### Patch Changes
package/dist/index.js CHANGED
@@ -24,11 +24,11 @@ var __export = (target, all) => {
24
24
  for (var name in all)
25
25
  __defProp(target, name, { get: all[name], enumerable: true });
26
26
  };
27
- var __copyProps = (to, from, except, desc) => {
28
- if (from && typeof from === "object" || typeof from === "function") {
29
- for (let key of __getOwnPropNames(from))
27
+ var __copyProps = (to, from2, except, desc) => {
28
+ if (from2 && typeof from2 === "object" || typeof from2 === "function") {
29
+ for (let key of __getOwnPropNames(from2))
30
30
  if (!__hasOwnProp.call(to, key) && key !== except)
31
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
31
+ __defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable });
32
32
  }
33
33
  return to;
34
34
  };
@@ -1140,7 +1140,7 @@ var init_size = __esm({
1140
1140
  var version;
1141
1141
  var init_version = __esm({
1142
1142
  "../../node_modules/viem/_esm/errors/version.js"() {
1143
- version = "2.53.1";
1143
+ version = "2.55.10";
1144
1144
  }
1145
1145
  });
1146
1146
 
@@ -2122,10 +2122,7 @@ function encodeAbiParameters(params, values) {
2122
2122
  params,
2123
2123
  values
2124
2124
  });
2125
- const data = encodeParams(preparedParams);
2126
- if (data.length === 0)
2127
- return "0x";
2128
- return data;
2125
+ return encodeParams(preparedParams);
2129
2126
  }
2130
2127
  function prepareParams({ params, values }) {
2131
2128
  const preparedParams = [];
@@ -2191,7 +2188,7 @@ function encodeParams(preparedParams) {
2191
2188
  staticParams.push(encoded);
2192
2189
  }
2193
2190
  }
2194
- return concat([...staticParams, ...dynamicParams]);
2191
+ return concatHex([...staticParams, ...dynamicParams]);
2195
2192
  }
2196
2193
  function encodeAddress(value) {
2197
2194
  if (!isAddress(value))
@@ -2208,7 +2205,7 @@ function encodeArray(value, { length, param }) {
2208
2205
  givenLength: value.length,
2209
2206
  type: `${param.type}[${length}]`
2210
2207
  });
2211
- let dynamicChild = false;
2208
+ let dynamicChild = value.length === 0 && isDynamicType(param);
2212
2209
  const preparedParams = [];
2213
2210
  for (let i = 0; i < value.length; i++) {
2214
2211
  const preparedParam = prepareParam({ param, value: value[i] });
@@ -2222,7 +2219,7 @@ function encodeArray(value, { length, param }) {
2222
2219
  const length2 = numberToHex(preparedParams.length, { size: 32 });
2223
2220
  return {
2224
2221
  dynamic: true,
2225
- encoded: preparedParams.length > 0 ? concat([length2, data]) : length2
2222
+ encoded: concatHex([length2, data])
2226
2223
  };
2227
2224
  }
2228
2225
  if (dynamicChild)
@@ -2230,7 +2227,7 @@ function encodeArray(value, { length, param }) {
2230
2227
  }
2231
2228
  return {
2232
2229
  dynamic: false,
2233
- encoded: concat(preparedParams.map(({ encoded }) => encoded))
2230
+ encoded: concatHex(preparedParams.map(({ encoded }) => encoded))
2234
2231
  };
2235
2232
  }
2236
2233
  function encodeBytes(value, { param }) {
@@ -2245,7 +2242,10 @@ function encodeBytes(value, { param }) {
2245
2242
  });
2246
2243
  return {
2247
2244
  dynamic: true,
2248
- encoded: concat([padHex(numberToHex(bytesSize, { size: 32 })), value_])
2245
+ encoded: concatHex([
2246
+ padHex(numberToHex(bytesSize, { size: 32 })),
2247
+ value_
2248
+ ])
2249
2249
  };
2250
2250
  }
2251
2251
  if (bytesSize !== Number.parseInt(paramSize, 10))
@@ -2292,7 +2292,7 @@ function encodeString(value) {
2292
2292
  }
2293
2293
  return {
2294
2294
  dynamic: true,
2295
- encoded: concat([
2295
+ encoded: concatHex([
2296
2296
  padHex(numberToHex(size(hexValue), { size: 32 })),
2297
2297
  ...parts
2298
2298
  ])
@@ -2314,7 +2314,7 @@ function encodeTuple(value, { param }) {
2314
2314
  }
2315
2315
  return {
2316
2316
  dynamic,
2317
- encoded: dynamic ? encodeParams(preparedParams) : concat(preparedParams.map(({ encoded }) => encoded))
2317
+ encoded: dynamic ? encodeParams(preparedParams) : concatHex(preparedParams.map(({ encoded }) => encoded))
2318
2318
  };
2319
2319
  }
2320
2320
  function getArrayComponents(type) {
@@ -2324,6 +2324,21 @@ function getArrayComponents(type) {
2324
2324
  [matches[2] ? Number(matches[2]) : null, matches[1]]
2325
2325
  ) : void 0;
2326
2326
  }
2327
+ function isDynamicType(param) {
2328
+ const { type } = param;
2329
+ if (type === "string")
2330
+ return true;
2331
+ if (type === "bytes")
2332
+ return true;
2333
+ if (type.endsWith("[]"))
2334
+ return true;
2335
+ if (type === "tuple")
2336
+ return param.components.some(isDynamicType);
2337
+ const arrayComponents = getArrayComponents(type);
2338
+ if (arrayComponents)
2339
+ return isDynamicType({ ...param, type: arrayComponents[1] });
2340
+ return false;
2341
+ }
2327
2342
  var init_encodeAbiParameters = __esm({
2328
2343
  "../../node_modules/viem/_esm/utils/abi/encodeAbiParameters.js"() {
2329
2344
  init_abi();
@@ -2351,8 +2366,10 @@ var init_stringify = __esm({
2351
2366
  }
2352
2367
  });
2353
2368
 
2354
- // ../../node_modules/viem/_esm/utils/unit/formatUnits.js
2355
- function formatUnits(value, decimals) {
2369
+ // ../../node_modules/viem/_esm/utils/unit/Value.js
2370
+ function format(value, decimals = 0) {
2371
+ if (!Number.isInteger(decimals) || decimals < 0)
2372
+ throw new InvalidDecimalsError({ decimals });
2356
2373
  let display = value.toString();
2357
2374
  const negative = display.startsWith("-");
2358
2375
  if (negative)
@@ -2365,8 +2382,80 @@ function formatUnits(value, decimals) {
2365
2382
  fraction = fraction.replace(/(0+)$/, "");
2366
2383
  return `${negative ? "-" : ""}${integer || "0"}${fraction ? `.${fraction}` : ""}`;
2367
2384
  }
2368
- var init_formatUnits = __esm({
2369
- "../../node_modules/viem/_esm/utils/unit/formatUnits.js"() {
2385
+ function from(value, decimals = 0) {
2386
+ if (!Number.isInteger(decimals) || decimals < 0)
2387
+ throw new InvalidDecimalsError({ decimals });
2388
+ if (!/^-?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)$/.test(value))
2389
+ throw new InvalidDecimalNumberError({ value });
2390
+ let [integer = "", fraction = "0"] = value.split(".");
2391
+ const negative = integer.startsWith("-");
2392
+ if (negative)
2393
+ integer = integer.slice(1);
2394
+ if (integer === "")
2395
+ integer = "0";
2396
+ fraction = fraction.replace(/(0+)$/, "");
2397
+ if (decimals === 0) {
2398
+ if (fraction.length > 0 && Number.parseInt(fraction[0], 10) >= 5)
2399
+ integer = `${BigInt(integer) + 1n}`;
2400
+ fraction = "";
2401
+ } else if (fraction.length > decimals) {
2402
+ const left = fraction.slice(0, decimals);
2403
+ const roundDigit = Number.parseInt(fraction.slice(decimals, decimals + 1), 10);
2404
+ if (roundDigit >= 5) {
2405
+ const carried = carry(left);
2406
+ if (carried.length > decimals) {
2407
+ fraction = carried.slice(1);
2408
+ integer = `${BigInt(integer) + 1n}`;
2409
+ } else {
2410
+ fraction = carried;
2411
+ }
2412
+ } else {
2413
+ fraction = left;
2414
+ }
2415
+ } else {
2416
+ fraction = fraction.padEnd(decimals, "0");
2417
+ }
2418
+ return BigInt(`${negative ? "-" : ""}${integer}${fraction}`);
2419
+ }
2420
+ function carry(digits) {
2421
+ const out = digits.split("");
2422
+ let i = out.length - 1;
2423
+ while (i >= 0) {
2424
+ const d = Number.parseInt(out[i], 10) + 1;
2425
+ if (d < 10) {
2426
+ out[i] = String(d);
2427
+ return out.join("");
2428
+ }
2429
+ out[i] = "0";
2430
+ i--;
2431
+ }
2432
+ return `1${out.join("")}`;
2433
+ }
2434
+ var InvalidDecimalNumberError, InvalidDecimalsError;
2435
+ var init_Value = __esm({
2436
+ "../../node_modules/viem/_esm/utils/unit/Value.js"() {
2437
+ InvalidDecimalNumberError = class extends Error {
2438
+ constructor({ value }) {
2439
+ super(`Value \`${value}\` is not a valid decimal number.`);
2440
+ Object.defineProperty(this, "name", {
2441
+ enumerable: true,
2442
+ configurable: true,
2443
+ writable: true,
2444
+ value: "Value.InvalidDecimalNumberError"
2445
+ });
2446
+ }
2447
+ };
2448
+ InvalidDecimalsError = class extends Error {
2449
+ constructor({ decimals }) {
2450
+ super(`\`decimals\` must be a non-negative integer. Got \`${decimals}\`.`);
2451
+ Object.defineProperty(this, "name", {
2452
+ enumerable: true,
2453
+ configurable: true,
2454
+ writable: true,
2455
+ value: "Value.InvalidDecimalsError"
2456
+ });
2457
+ }
2458
+ };
2370
2459
  }
2371
2460
  });
2372
2461
 
@@ -3982,7 +4071,7 @@ function weierstrass(curveDef) {
3982
4071
  function normalizeS(s) {
3983
4072
  return isBiggerThanHalfOrder(s) ? modN2(-s) : s;
3984
4073
  }
3985
- const slcNum = (b, from, to) => bytesToNumberBE(b.slice(from, to));
4074
+ const slcNum = (b, from2, to) => bytesToNumberBE(b.slice(from2, to));
3986
4075
  class Signature {
3987
4076
  constructor(r, s, recovery) {
3988
4077
  aInRange("r", r, _1n5, CURVE_ORDER);
@@ -4185,14 +4274,14 @@ function weierstrass(curveDef) {
4185
4274
  const sg = signature;
4186
4275
  msgHash = ensureBytes("msgHash", msgHash);
4187
4276
  publicKey = ensureBytes("publicKey", publicKey);
4188
- const { lowS, prehash, format } = opts;
4277
+ const { lowS, prehash, format: format2 } = opts;
4189
4278
  validateSigVerOpts(opts);
4190
4279
  if ("strict" in opts)
4191
4280
  throw new Error("options.strict was renamed to lowS");
4192
- if (format !== void 0 && format !== "compact" && format !== "der")
4281
+ if (format2 !== void 0 && format2 !== "compact" && format2 !== "der")
4193
4282
  throw new Error("format must be compact or der");
4194
4283
  const isHex2 = typeof sg === "string" || isBytes2(sg);
4195
- const isObj = !isHex2 && !format && typeof sg === "object" && sg !== null && typeof sg.r === "bigint" && typeof sg.s === "bigint";
4284
+ const isObj = !isHex2 && !format2 && typeof sg === "object" && sg !== null && typeof sg.r === "bigint" && typeof sg.s === "bigint";
4196
4285
  if (!isHex2 && !isObj)
4197
4286
  throw new Error("invalid signature, expected Uint8Array, hex string or Signature instance");
4198
4287
  let _sig = void 0;
@@ -4202,13 +4291,13 @@ function weierstrass(curveDef) {
4202
4291
  _sig = new Signature(sg.r, sg.s);
4203
4292
  if (isHex2) {
4204
4293
  try {
4205
- if (format !== "compact")
4294
+ if (format2 !== "compact")
4206
4295
  _sig = Signature.fromDER(sg);
4207
4296
  } catch (derError) {
4208
4297
  if (!(derError instanceof DER.Err))
4209
4298
  throw derError;
4210
4299
  }
4211
- if (!_sig && format !== "der")
4300
+ if (!_sig && format2 !== "der")
4212
4301
  _sig = Signature.fromCompact(sg);
4213
4302
  }
4214
4303
  P = Point2.fromHex(publicKey);
@@ -9282,54 +9371,18 @@ function encodeField({ types, name, type, value }) {
9282
9371
  return [{ type }, value];
9283
9372
  }
9284
9373
 
9285
- // ../../node_modules/viem/_esm/errors/unit.js
9286
- init_base();
9287
- var InvalidDecimalNumberError = class extends BaseError {
9288
- constructor({ value }) {
9289
- super(`Number \`${value}\` is not a valid decimal number.`, {
9290
- name: "InvalidDecimalNumberError"
9291
- });
9292
- }
9293
- };
9374
+ // ../../node_modules/viem/_esm/utils/unit/formatUnits.js
9375
+ init_Value();
9376
+ function formatUnits(value, decimals) {
9377
+ return format(value, decimals);
9378
+ }
9294
9379
 
9295
9380
  // ../../node_modules/viem/_esm/utils/unit/parseUnits.js
9381
+ init_Value();
9296
9382
  function parseUnits(value, decimals) {
9297
- if (!/^(-?)([0-9]*)\.?([0-9]*)$/.test(value))
9298
- throw new InvalidDecimalNumberError({ value });
9299
- let [integer, fraction = "0"] = value.split(".");
9300
- const negative = integer.startsWith("-");
9301
- if (negative)
9302
- integer = integer.slice(1);
9303
- fraction = fraction.replace(/(0+)$/, "");
9304
- if (decimals === 0) {
9305
- if (Math.round(Number(`.${fraction}`)) === 1)
9306
- integer = `${BigInt(integer) + 1n}`;
9307
- fraction = "";
9308
- } else if (fraction.length > decimals) {
9309
- const [left, unit, right] = [
9310
- fraction.slice(0, decimals - 1),
9311
- fraction.slice(decimals - 1, decimals),
9312
- fraction.slice(decimals)
9313
- ];
9314
- const rounded = Math.round(Number(`${unit}.${right}`));
9315
- if (rounded > 9)
9316
- fraction = `${BigInt(left) + BigInt(1)}0`.padStart(left.length + 1, "0");
9317
- else
9318
- fraction = `${left}${rounded}`;
9319
- if (fraction.length > decimals) {
9320
- fraction = fraction.slice(1);
9321
- integer = `${BigInt(integer) + 1n}`;
9322
- }
9323
- fraction = fraction.slice(0, decimals);
9324
- } else {
9325
- fraction = fraction.padEnd(decimals, "0");
9326
- }
9327
- return BigInt(`${negative ? "-" : ""}${integer}${fraction}`);
9383
+ return from(value, decimals);
9328
9384
  }
9329
9385
 
9330
- // ../../node_modules/viem/_esm/index.js
9331
- init_formatUnits();
9332
-
9333
9386
  // ../../packages/core/chain/dist/amount/toChainAmount.js
9334
9387
  var ChainAmountParseError = class extends Error {
9335
9388
  name = "ChainAmountParseError";
@@ -10818,9 +10871,9 @@ var EVM_CHAINS = /* @__PURE__ */ new Set([
10818
10871
  "Sei"
10819
10872
  ]);
10820
10873
  var EVM_GAS_RPC = {
10821
- Ethereum: "https://eth.llamarpc.com",
10874
+ Ethereum: "https://ethereum-rpc.publicnode.com",
10822
10875
  BSC: "https://bsc-dataseed.binance.org",
10823
- Polygon: "https://polygon-rpc.com",
10876
+ Polygon: "https://polygon-bor-rpc.publicnode.com",
10824
10877
  Avalanche: "https://api.avax.network/ext/bc/C/rpc",
10825
10878
  Arbitrum: "https://arb1.arbitrum.io/rpc",
10826
10879
  Optimism: "https://mainnet.optimism.io",
@@ -11448,29 +11501,23 @@ var AgentExecutor = class {
11448
11501
  * destination chain + asset, look up the corresponding `Chain` enum,
11449
11502
  * then call `vault.swap` which builds the MsgDeposit internally.
11450
11503
  *
11451
- * IMPORTANT destination address handling: `vault.swap` re-derives the
11452
- * destination address from `vault.address(toChain)` when fetching the
11453
- * native swap quote (see `findSwapQuote` `getNativeSwapQuote` —
11454
- * `destination: to.address`). It does NOT honor the destination address
11455
- * encoded in the envelope's memo. As a fund-safety guard we therefore
11456
- * require the memo's destination address to match the vault's own
11457
- * destination address (self-swap) and throw otherwise — see Phase D
11458
- * review F1. Cross-account routing must wait on a Phase E SDK extension
11459
- * that lets `vault.swap` accept a user-supplied destination.
11504
+ * The destination encoded in the server-issued memo is forwarded through
11505
+ * `vault.swap({ recipient })`. The SDK uses the same recipient both for the
11506
+ * destination coin and the THORChain/MayaChain quote request, so an explicit
11507
+ * cross-account route cannot be silently replaced with the vault's address.
11508
+ * An omitted destination keeps the existing self-swap default.
11460
11509
  */
11461
11510
  async signThorMsgDepositSwap(serverTxData, chain) {
11462
11511
  const txArgs = serverTxData?.txArgs ?? {};
11463
11512
  const memo = typeof txArgs.memo === "string" ? txArgs.memo : "";
11464
11513
  const parsed = parseThorSwapMemo(memo);
11465
- const toChain = parsed.toChain;
11466
- const vaultDestAddress = await this.vault.address(toChain);
11467
- const normalizeForCompare = (addr) => EVM_CHAINS.has(toChain) ? addr.toLowerCase() : addr;
11468
- if (parsed.destAddress && normalizeForCompare(parsed.destAddress) !== normalizeForCompare(vaultDestAddress)) {
11514
+ if (/\s/.test(parsed.destAddress)) {
11469
11515
  throw new VaultError3(
11470
- VaultErrorCode3.NotImplemented,
11471
- `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.`
11516
+ VaultErrorCode3.InvalidConfig,
11517
+ `signThorMsgDepositSwap: destination address in memo '${memo}' must not contain whitespace.`
11472
11518
  );
11473
11519
  }
11520
+ const toChain = parsed.toChain;
11474
11521
  const fromSymbol = chain === Chain11.THORChain ? "RUNE" : "CACAO";
11475
11522
  const amountRaw = typeof txArgs.amount === "string" ? txArgs.amount : void 0;
11476
11523
  if (!amountRaw) {
@@ -11490,7 +11537,8 @@ var AgentExecutor = class {
11490
11537
  fromSymbol,
11491
11538
  toChain,
11492
11539
  toSymbol: parsed.destAsset,
11493
- amount: amountDecimal
11540
+ amount: amountDecimal,
11541
+ ...parsed.destAddress && { recipient: parsed.destAddress }
11494
11542
  });
11495
11543
  if (result.dryRun) {
11496
11544
  throw new VaultError3(
@@ -11909,15 +11957,20 @@ var AgentExecutor = class {
11909
11957
  }
11910
11958
  const nonceGap = nextNonce - rpcNonce;
11911
11959
  if (pendingNonce === null && nonceGap > 3n) {
11912
- if (this.verbose)
11913
- process.stderr.write(
11914
- `[nonce] Large nonce gap for ${chain} (${nonceGap}) and couldn't verify pending txs \u2014 using on-chain nonce ${rpcNonce}
11960
+ process.stderr.write(
11961
+ `[nonce] Warning: pending nonce was not verified for ${chain}; signing will continue with on-chain nonce ${rpcNonce} because the local gap is ${nonceGap}
11915
11962
  `
11916
- );
11963
+ );
11917
11964
  this.stateStore.clearEvmState(chain);
11918
11965
  return;
11919
11966
  }
11920
11967
  bs.value.nonce = nextNonce;
11968
+ if (pendingNonce === null) {
11969
+ process.stderr.write(
11970
+ `[nonce] Warning: pending nonce was not verified for ${chain}; signing will continue with local nonce ${nextNonce}
11971
+ `
11972
+ );
11973
+ }
11921
11974
  if (this.verbose) process.stderr.write(`[nonce] Patched ${chain} nonce: ${rpcNonce} \u2192 ${nextNonce}
11922
11975
  `);
11923
11976
  }
@@ -11946,7 +11999,10 @@ var AgentExecutor = class {
11946
11999
  signal: AbortSignal.timeout(5e3)
11947
12000
  });
11948
12001
  const data = await res.json();
11949
- const baseFee = BigInt(data.result?.baseFeePerGas || "0");
12002
+ if (!res.ok || data?.error || data?.result?.baseFeePerGas === void 0 || data?.result?.baseFeePerGas === null) {
12003
+ throw new Error(`Failed to fetch current base fee for ${chain}`);
12004
+ }
12005
+ const baseFee = BigInt(data.result.baseFeePerGas);
11950
12006
  if (baseFee === 0n) return;
11951
12007
  const currentPriorityFee = BigInt(bs.value.priorityFee || "0");
11952
12008
  const currentMaxFee = BigInt(bs.value.maxFeePerGasWei || "0");
@@ -11960,8 +12016,10 @@ var AgentExecutor = class {
11960
12016
  );
11961
12017
  }
11962
12018
  } catch {
11963
- if (this.verbose) process.stderr.write(`[gas] Failed to refresh base fee for ${chain}, keeping original
11964
- `);
12019
+ process.stderr.write(
12020
+ `[gas] Warning: gas estimate was not refreshed for ${chain}; signing will continue with the original estimate
12021
+ `
12022
+ );
11965
12023
  }
11966
12024
  }
11967
12025
  /**
@@ -11985,7 +12043,10 @@ var AgentExecutor = class {
11985
12043
  signal: AbortSignal.timeout(5e3)
11986
12044
  });
11987
12045
  const data = await res.json();
11988
- return BigInt(data.result || "0");
12046
+ if (!res.ok || data?.error || data?.result === void 0 || data?.result === null) {
12047
+ return null;
12048
+ }
12049
+ return BigInt(data.result);
11989
12050
  } catch {
11990
12051
  return null;
11991
12052
  }
@@ -15590,7 +15651,7 @@ var cachedVersion = null;
15590
15651
  function getVersion() {
15591
15652
  if (cachedVersion) return cachedVersion;
15592
15653
  if (true) {
15593
- cachedVersion = "4.0.1";
15654
+ cachedVersion = "4.0.3";
15594
15655
  return cachedVersion;
15595
15656
  }
15596
15657
  try {
@@ -17727,7 +17788,7 @@ Examples:
17727
17788
  });
17728
17789
  })
17729
17790
  );
17730
- program2.command("send <chain> <to> [amount]").description(descriptions.send.description).option("--max", "Send maximum amount (balance minus fees)").option("--token <tokenId>", "Token to send (default: native)").option("--memo <memo>", "Transaction memo").option("--destination-tag <tag>", "XRP DestinationTag (0 to 4294967295)").option("--dry-run", "Preview transaction without signing or broadcasting").option("--confirm", "Confirm and broadcast (without this flag, runs as a preview)").option("-y, --yes", "Alias for --confirm").option("--force", "Bypass the duplicate-broadcast guard (re-send an identical, recently-broadcast tx)").option("--password <password>", "Vault password for signing").addHelpText(
17791
+ program2.command("send <chain> <to> [amount]").description(descriptions.send.cliDescription).option("--max", "Send maximum amount (balance minus fees)").option("--token <tokenId>", "Token to send (default: native)").option("--memo <memo>", "Transaction memo").option("--destination-tag <tag>", "XRP DestinationTag (0 to 4294967295)").option("--dry-run", "Preview transaction without signing or broadcasting").option("--confirm", "Confirm and broadcast (required to execute non-interactively; use --dry-run to preview)").option("-y, --yes", "Alias for --confirm").option("--force", "Bypass the duplicate-broadcast guard (re-send an identical, recently-broadcast tx)").option("--password <password>", "Vault password for signing").addHelpText(
17731
17792
  "after",
17732
17793
  `
17733
17794
  Examples:
@@ -17888,7 +17949,7 @@ Examples:
17888
17949
  });
17889
17950
  })
17890
17951
  );
17891
- program2.command("addresses").description(descriptions.address.description).addHelpText(
17952
+ program2.command("addresses").description(descriptions.address.cliDescription).addHelpText(
17892
17953
  "after",
17893
17954
  `
17894
17955
  Examples:
@@ -18026,7 +18087,7 @@ Examples:
18026
18087
  }
18027
18088
  )
18028
18089
  );
18029
- program2.command("swap <fromChain> <toChain> [amount]").description(descriptions.swap.description).option("--max", "Swap maximum amount (full balance minus fees for native)").option("--from-token <address>", "Token address to swap from (default: native)").option("--to-token <address>", "Token address to swap to (default: native)").option("--slippage <percent>", "Slippage tolerance in percent", "1").option("--dry-run", "Preview swap without signing or broadcasting").option("--confirm", "Confirm and broadcast (without this flag, runs as a preview)").option("-y, --yes", "Alias for --confirm").option("--force", "Bypass the duplicate-broadcast guard (re-send an identical, recently-broadcast swap)").option("--password <password>", "Vault password for signing").addHelpText(
18090
+ program2.command("swap <fromChain> <toChain> [amount]").description(descriptions.swap.cliDescription).option("--max", "Swap maximum amount (full balance minus fees for native)").option("--from-token <address>", "Token address to swap from (default: native)").option("--to-token <address>", "Token address to swap to (default: native)").option("--slippage <percent>", "Slippage tolerance in percent", "1").option("--dry-run", "Preview swap without signing or broadcasting").option("--confirm", "Confirm and broadcast (required to execute non-interactively; use --dry-run to preview)").option("-y, --yes", "Alias for --confirm").option("--force", "Bypass the duplicate-broadcast guard (re-send an identical, recently-broadcast swap)").option("--password <password>", "Vault password for signing").addHelpText(
18030
18091
  "after",
18031
18092
  `
18032
18093
  Examples:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/cli",
3
- "version": "4.0.1",
3
+ "version": "4.0.3",
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": {
@@ -73,10 +73,10 @@
73
73
  "@cosmjs/stargate": "^0.39.0",
74
74
  "@napi-rs/keyring": "^1.3.0",
75
75
  "@noble/hashes": "^2.2.0",
76
- "@vultisig/client-shared": "^0.3.2",
77
- "@vultisig/core-chain": "^2.31.0",
76
+ "@vultisig/client-shared": "^0.3.3",
77
+ "@vultisig/core-chain": "^2.31.2",
78
78
  "@vultisig/rujira": "^59.0.0",
79
- "@vultisig/sdk": "^4.0.1",
79
+ "@vultisig/sdk": "^4.0.3",
80
80
  "chalk": "^5.6.2",
81
81
  "cli-table3": "^0.6.5",
82
82
  "commander": "^15.0.0",
@@ -86,7 +86,7 @@
86
86
  "qrcode-terminal": "^0.12.0",
87
87
  "ripple-address-codec": "^5.0.1",
88
88
  "tabtab": "^3.0.2",
89
- "viem": "^2.53.1",
89
+ "viem": "^2.55.10",
90
90
  "ws": "^8.21.1"
91
91
  },
92
92
  "devDependencies": {
@@ -94,7 +94,7 @@
94
94
  "@types/node": "^26.1.1",
95
95
  "@types/tabtab": "^3.0.4",
96
96
  "@types/ws": "^8.18.1",
97
- "@vultisig/core-mpc": "^1.16.0",
97
+ "@vultisig/core-mpc": "^1.16.2",
98
98
  "esbuild": "^0.28.1",
99
99
  "ethers": "^6.17.0",
100
100
  "node-pty": "^1.1.0",