@trustwallet/cli 0.8.0 → 0.9.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.
@@ -1 +1 @@
1
- {"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../src/commands/alert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmEpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqO3D"}
1
+ {"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../src/commands/alert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmEpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwO3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiwB3D"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmwB3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/commands/swap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+V1D"}
1
+ {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/commands/swap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgW1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoCpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA45B5D"}
1
+ {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoCpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAi+B5D"}
package/dist/index.js CHANGED
@@ -22438,10 +22438,11 @@ function dim(message) {
22438
22438
  }
22439
22439
  function safeExit() {
22440
22440
  const code2 = process.exitCode ?? 0;
22441
- const streams = [process.stdout, process.stderr].filter((s2) => s2.writableNeedDrain);
22441
+ const streams = [process.stdout, process.stderr].filter(
22442
+ (s2) => s2.writableNeedDrain || s2.writableLength > 0
22443
+ );
22442
22444
  if (streams.length === 0) {
22443
22445
  process.exit(code2);
22444
- return;
22445
22446
  }
22446
22447
  let pending = streams.length;
22447
22448
  const onDrain = () => {
@@ -38807,8 +38808,24 @@ function getQRString(address) {
38807
38808
  }
38808
38809
  function registerWalletCommand(program3) {
38809
38810
  const wallet = program3.command("wallet").description("Manage agent wallet");
38810
- wallet.command("create").description("Create a new agent wallet").requiredOption("--password <password>", "Password to encrypt the wallet").option("--no-keychain", "Do not save password to OS keychain").option("--json", "JSON output").action(async (opts) => {
38811
+ wallet.command("create").description("Create a new agent wallet").requiredOption("--password <password>", "Password to encrypt the wallet").option("--no-keychain", "Do not save password to OS keychain").option("--skip-password-check", "Skip password strength validation").option("--json", "JSON output").action(async (opts) => {
38811
38812
  try {
38813
+ if (!opts.skipPasswordCheck) {
38814
+ const pw = opts.password;
38815
+ const issues = [];
38816
+ if (pw.length < 8) issues.push("be at least 8 characters long");
38817
+ if (!/[a-z]/.test(pw)) issues.push("include a lowercase letter");
38818
+ if (!/[A-Z]/.test(pw)) issues.push("include an uppercase letter");
38819
+ if (!/[0-9]/.test(pw)) issues.push("include a number");
38820
+ if (issues.length > 0) {
38821
+ const msg = `Password too weak: must ${issues.join(", ")}.`;
38822
+ error(msg);
38823
+ if (opts.json) output({ error: msg }, true);
38824
+ process.exitCode = 1;
38825
+ process.exit();
38826
+ return;
38827
+ }
38828
+ }
38812
38829
  await ensureTrustSDK();
38813
38830
  const store = new WalletConfigStore();
38814
38831
  if (await store.exists()) {
@@ -38816,7 +38833,7 @@ function registerWalletCommand(program3) {
38816
38833
  error(msg);
38817
38834
  if (opts.json) output({ error: msg }, true);
38818
38835
  process.exitCode = 1;
38819
- process.exit();
38836
+ safeExit();
38820
38837
  return;
38821
38838
  }
38822
38839
  const provider = await AgentWalletProvider.create(opts.password);
@@ -38847,7 +38864,7 @@ function registerWalletCommand(program3) {
38847
38864
  if (opts.json) output({ error: msg }, true);
38848
38865
  process.exitCode = 1;
38849
38866
  }
38850
- process.exit();
38867
+ safeExit();
38851
38868
  });
38852
38869
  wallet.command("address").description("Get wallet address for a chain").requiredOption("--chain <key>", "Chain key (e.g., ethereum, solana)").option(
38853
38870
  "--password <password>",
@@ -38874,7 +38891,7 @@ ${qr3}`;
38874
38891
  if (opts.json) output({ error: msg }, true);
38875
38892
  process.exitCode = 1;
38876
38893
  }
38877
- process.exit();
38894
+ safeExit();
38878
38895
  });
38879
38896
  wallet.command("addresses").description("List all wallet addresses").option(
38880
38897
  "--password <password>",
@@ -38925,7 +38942,7 @@ ${qr3}`;
38925
38942
  if (opts.json) output({ error: msg }, true);
38926
38943
  process.exitCode = 1;
38927
38944
  }
38928
- process.exit();
38945
+ safeExit();
38929
38946
  });
38930
38947
  wallet.command("balance").description("Get wallet balance on a chain (native + token holdings)").option("--chain <key>", "Chain key").option("--all", "Show balances across all chains with funds").option(
38931
38948
  "--password <password>",
@@ -38937,7 +38954,7 @@ ${qr3}`;
38937
38954
  error(msg);
38938
38955
  if (opts.json) output({ error: msg }, true);
38939
38956
  process.exitCode = 1;
38940
- process.exit();
38957
+ safeExit();
38941
38958
  return;
38942
38959
  }
38943
38960
  if (!opts.all && !opts.chain) {
@@ -38945,7 +38962,7 @@ ${qr3}`;
38945
38962
  error(msg);
38946
38963
  if (opts.json) output({ error: msg }, true);
38947
38964
  process.exitCode = 1;
38948
- process.exit();
38965
+ safeExit();
38949
38966
  return;
38950
38967
  }
38951
38968
  const creds = await ensureTrustSDK();
@@ -39130,7 +39147,7 @@ ${qr3}`;
39130
39147
  error(msg);
39131
39148
  if (opts.json) output({ error: msg }, true);
39132
39149
  process.exitCode = 1;
39133
- process.exit();
39150
+ safeExit();
39134
39151
  return;
39135
39152
  }
39136
39153
  const result = await fetchChainBalance(opts.chain, chain2, address, opts.tokens === false);
@@ -39157,7 +39174,7 @@ ${qr3}`;
39157
39174
  if (opts.json) output({ error: msg }, true);
39158
39175
  process.exitCode = 1;
39159
39176
  }
39160
- process.exit();
39177
+ safeExit();
39161
39178
  });
39162
39179
  const keychain = wallet.command("keychain").description("Manage wallet password in OS keychain");
39163
39180
  keychain.command("save").description("Save wallet password to OS keychain").requiredOption("--password <password>", "Wallet password to store").action(async (opts) => {
@@ -39169,7 +39186,7 @@ ${qr3}`;
39169
39186
  error(err instanceof Error ? err.message : String(err));
39170
39187
  process.exitCode = 1;
39171
39188
  }
39172
- process.exit();
39189
+ safeExit();
39173
39190
  });
39174
39191
  keychain.command("delete").description("Remove wallet password from OS keychain").action(async () => {
39175
39192
  try {
@@ -39180,13 +39197,14 @@ ${qr3}`;
39180
39197
  error(err instanceof Error ? err.message : String(err));
39181
39198
  process.exitCode = 1;
39182
39199
  }
39183
- process.exit();
39200
+ safeExit();
39184
39201
  });
39185
39202
  keychain.command("check").description("Check if wallet password is stored in OS keychain").action(async () => {
39186
39203
  const kc2 = new KeychainManager();
39187
39204
  if (!kc2.isAvailable()) {
39188
39205
  warn("keytar not available on this system");
39189
- process.exit(0);
39206
+ safeExit();
39207
+ return;
39190
39208
  }
39191
39209
  const pw = await kc2.getWalletPassword();
39192
39210
  if (pw) {
@@ -39194,7 +39212,7 @@ ${qr3}`;
39194
39212
  } else {
39195
39213
  info("No wallet password found in OS keychain");
39196
39214
  }
39197
- process.exit();
39215
+ safeExit();
39198
39216
  });
39199
39217
  wallet.command("connect").description("Connect external wallet via WalletConnect").option("--project-id <id>", "WalletConnect project ID (or set WALLETCONNECT_PROJECT_ID)").option(
39200
39218
  "--chains <list>",
@@ -39206,7 +39224,9 @@ ${qr3}`;
39206
39224
  error(
39207
39225
  "WalletConnect project ID required. Use --project-id or set WALLETCONNECT_PROJECT_ID"
39208
39226
  );
39209
- process.exit(1);
39227
+ process.exitCode = 1;
39228
+ safeExit();
39229
+ return;
39210
39230
  }
39211
39231
  const provider = new WalletConnectProvider({ projectId });
39212
39232
  const chains = opts.chains.split(",").map((s2) => s2.trim()).filter(Boolean);
@@ -39236,7 +39256,7 @@ ${qr3}`;
39236
39256
  info(` Address: ${session.address}`);
39237
39257
  info(` Chain: ${session.chainId}`);
39238
39258
  }
39239
- process.exit();
39259
+ safeExit();
39240
39260
  });
39241
39261
  wallet.command("status").description("Check wallet configuration status").option("--json", "JSON output").action(async (opts) => {
39242
39262
  const store = new WalletConfigStore();
@@ -39301,8 +39321,8 @@ ${qr3}`;
39301
39321
  const suppress = (fn2) => fn2();
39302
39322
  const withTimeout = (promise, ms3) => {
39303
39323
  let timerId;
39304
- const timeout = new Promise((resolve2) => {
39305
- timerId = setTimeout(() => resolve2(null), ms3);
39324
+ const timeout = new Promise((_2, reject) => {
39325
+ timerId = setTimeout(() => reject(new Error(`timed out after ${ms3 / 1e3}s`)), ms3);
39306
39326
  });
39307
39327
  return Promise.race([promise, timeout]).finally(() => {
39308
39328
  if (timerId !== void 0) clearTimeout(timerId);
@@ -39349,9 +39369,29 @@ ${qr3}`;
39349
39369
  suppress(() => blockchainClient.getBalance(`c${chain2.coinId}`, address)),
39350
39370
  15e3
39351
39371
  );
39352
- return { chainKey, chain: chain2, address, balance };
39353
- } catch {
39354
- return { chainKey, chain: chain2, address, balance: null };
39372
+ if (!balance) {
39373
+ return {
39374
+ chainKey,
39375
+ chain: chain2,
39376
+ address,
39377
+ balance: null,
39378
+ error: "empty response from SDK"
39379
+ };
39380
+ }
39381
+ return { chainKey, chain: chain2, address, balance, error: void 0 };
39382
+ } catch (e2) {
39383
+ const code2 = e2 != null ? e2.code : void 0;
39384
+ let msg;
39385
+ if (code2 === 429) {
39386
+ msg = "rate limited (429)";
39387
+ } else if (e2 instanceof Error && e2.message && e2.message !== "null") {
39388
+ msg = e2.message;
39389
+ } else if (code2) {
39390
+ msg = `HTTP ${code2}`;
39391
+ } else {
39392
+ msg = "unsupported or unavailable";
39393
+ }
39394
+ return { chainKey, chain: chain2, address, balance: null, error: msg };
39355
39395
  }
39356
39396
  },
39357
39397
  5
@@ -39371,7 +39411,9 @@ ${qr3}`;
39371
39411
  if (holdingsMap.size === 0) {
39372
39412
  try {
39373
39413
  await registerWalletWithBackend(creds, provider);
39374
- const retryHoldings = await new SecurityService2(httpClient).getTokenHoldings(holdingsAssets);
39414
+ const retryHoldings = await new SecurityService2(httpClient).getTokenHoldings(
39415
+ holdingsAssets
39416
+ );
39375
39417
  for (const h4 of retryHoldings) {
39376
39418
  if (h4.tokens?.length) holdingsMap.set(h4.coin, h4.tokens);
39377
39419
  }
@@ -39413,7 +39455,7 @@ ${qr3}`;
39413
39455
  suppress(() => blockchainClient.getBalance(assetId, job.address)),
39414
39456
  15e3
39415
39457
  );
39416
- return { ...job, rawBalance: bal?.total ?? bal?.available ?? fallback };
39458
+ return { ...job, rawBalance: bal.total ?? bal.available ?? fallback };
39417
39459
  } catch {
39418
39460
  return { ...job, rawBalance: fallback };
39419
39461
  }
@@ -39442,8 +39484,21 @@ ${qr3}`;
39442
39484
  } catch {
39443
39485
  }
39444
39486
  const rows = [];
39445
- for (const { chainKey, chain: chain2, address, balance } of nativeResults) {
39487
+ const failedChains = [];
39488
+ for (const { chainKey, chain: chain2, address, balance, error: fetchError } of nativeResults) {
39446
39489
  const c3 = chain2;
39490
+ if (fetchError) {
39491
+ failedChains.push(`${chainKey} (${fetchError})`);
39492
+ rows.push({
39493
+ chain: chainKey,
39494
+ type: "native",
39495
+ symbol: c3.symbol,
39496
+ address,
39497
+ balance: "--",
39498
+ usdValue: null
39499
+ });
39500
+ continue;
39501
+ }
39447
39502
  const price = priceMap.get(`c${c3.coinId}`) ?? null;
39448
39503
  const rawTotal = balance?.total ?? balance?.available ?? "0";
39449
39504
  const humanAmount = toHuman(rawTotal, c3.decimals);
@@ -39475,6 +39530,9 @@ ${qr3}`;
39475
39530
  });
39476
39531
  }
39477
39532
  if (opts.json) {
39533
+ if (failedChains.length > 0) {
39534
+ warn(`Balance unavailable for: ${failedChains.join(", ")}`);
39535
+ }
39478
39536
  output(rows, true);
39479
39537
  } else {
39480
39538
  const totalUsd = rows.reduce(
@@ -39484,13 +39542,16 @@ ${qr3}`;
39484
39542
  console.log("Chain Type Symbol Balance USD");
39485
39543
  console.log("\u2500".repeat(72));
39486
39544
  for (const r3 of rows) {
39487
- const usd = r3.usdValue !== null ? `$${r3.usdValue.toFixed(2)}` : "";
39545
+ const usd = r3.balance === "--" ? "" : r3.usdValue !== null ? `$${r3.usdValue.toFixed(2)}` : "";
39488
39546
  console.log(
39489
39547
  `${String(r3.chain).padEnd(12)} ${String(r3.type).padEnd(7)} ${String(r3.symbol).padEnd(17)} ${String(r3.balance).padEnd(20)} ${usd}`
39490
39548
  );
39491
39549
  }
39492
39550
  console.log("\u2500".repeat(72));
39493
39551
  console.log(`Total USD: $${totalUsd.toFixed(2)}`);
39552
+ if (failedChains.length > 0) {
39553
+ warn(`Balance unavailable for: ${failedChains.join(", ")}`);
39554
+ }
39494
39555
  }
39495
39556
  } catch (err) {
39496
39557
  const msg = err instanceof Error ? err.message : String(err);
@@ -39498,7 +39559,7 @@ ${qr3}`;
39498
39559
  if (opts.json) output({ error: msg }, true);
39499
39560
  process.exitCode = 1;
39500
39561
  }
39501
- process.exit();
39562
+ safeExit();
39502
39563
  });
39503
39564
  wallet.command("sign-message").description("Sign a message with the agent wallet").requiredOption("--chain <key>", "Chain key (e.g., ethereum, solana)").requiredOption("--message <text>", "Message to sign").option(
39504
39565
  "--password <password>",
@@ -39517,7 +39578,7 @@ ${qr3}`;
39517
39578
  if (opts.json) output({ error: msg }, true);
39518
39579
  process.exitCode = 1;
39519
39580
  }
39520
- process.exit();
39581
+ safeExit();
39521
39582
  });
39522
39583
  wallet.command("register").description("Register wallet addresses with Trust Wallet backend (enables token holdings)").option("--password <password>", "Wallet password").option("--json", "JSON output").action(async (opts) => {
39523
39584
  try {
@@ -39534,7 +39595,7 @@ ${qr3}`;
39534
39595
  if (opts.json) output({ error: msg }, true);
39535
39596
  process.exitCode = 1;
39536
39597
  }
39537
- process.exit();
39598
+ safeExit();
39538
39599
  });
39539
39600
  }
39540
39601
 
@@ -39546,6 +39607,7 @@ init_dist5();
39546
39607
  // ../swap/dist/index.mjs
39547
39608
  init_dist2();
39548
39609
  init_dist2();
39610
+ init_dist2();
39549
39611
  var SwapClient = class {
39550
39612
  constructor(httpClient) {
39551
39613
  this.httpClient = httpClient;
@@ -39692,6 +39754,26 @@ var SwapClient = class {
39692
39754
  }
39693
39755
  }
39694
39756
  };
39757
+ var MAX_RETRIES = 3;
39758
+ var BASE_DELAY_MS = 3e3;
39759
+ function isRateLimited(err) {
39760
+ return err instanceof TwakApiError && err.statusCode === 429;
39761
+ }
39762
+ function sleep(ms3) {
39763
+ return new Promise((r3) => setTimeout(r3, ms3));
39764
+ }
39765
+ async function withRetry(fn2, onRetry) {
39766
+ for (let attempt = 0; ; attempt++) {
39767
+ try {
39768
+ return await fn2();
39769
+ } catch (err) {
39770
+ if (!isRateLimited(err) || attempt >= MAX_RETRIES) throw err;
39771
+ const delay = BASE_DELAY_MS * Math.pow(2, attempt);
39772
+ onRetry?.(attempt + 1, delay);
39773
+ await sleep(delay);
39774
+ }
39775
+ }
39776
+ }
39695
39777
  var SwapExecutor = class {
39696
39778
  constructor(swapClient, walletProvider, options = {}) {
39697
39779
  this.swapClient = swapClient;
@@ -39704,7 +39786,8 @@ var SwapExecutor = class {
39704
39786
  async execute(params) {
39705
39787
  const address = await this.walletProvider.getAddress(params.fromChain);
39706
39788
  const fromTokenInfo = resolveToken(params.fromToken, params.fromChain);
39707
- if (!fromTokenInfo) throw new Error(`Unknown token: ${params.fromToken} on ${params.fromChain}`);
39789
+ if (!fromTokenInfo)
39790
+ throw new Error(`Unknown token: ${params.fromToken} on ${params.fromChain}`);
39708
39791
  const toTokenInfo = resolveToken(params.toToken, params.toChain);
39709
39792
  if (!toTokenInfo) throw new Error(`Unknown token: ${params.toToken} on ${params.toChain}`);
39710
39793
  const parsedAmount = parseAmount(params.amount, fromTokenInfo.decimals);
@@ -39715,18 +39798,20 @@ var SwapExecutor = class {
39715
39798
  if (params.toChain !== params.fromChain) {
39716
39799
  destinationAddress = await this.walletProvider.getAddress(params.toChain);
39717
39800
  }
39718
- const quote = await this.swapClient.getQuote({
39719
- fromChain: params.fromChain,
39720
- fromToken: fromTokenInfo.address,
39721
- toChain: params.toChain,
39722
- toToken: toTokenInfo.address,
39723
- amount: parsedAmount,
39724
- walletAddress: address,
39725
- destinationAddress,
39726
- slippage: params.slippage,
39727
- fromDomainId: fromCoinId ? domains.get(fromCoinId) : void 0,
39728
- toDomainId: toCoinId ? domains.get(toCoinId) : void 0
39729
- });
39801
+ const quote = await withRetry(
39802
+ () => this.swapClient.getQuote({
39803
+ fromChain: params.fromChain,
39804
+ fromToken: fromTokenInfo.address,
39805
+ toChain: params.toChain,
39806
+ toToken: toTokenInfo.address,
39807
+ amount: parsedAmount,
39808
+ walletAddress: address,
39809
+ destinationAddress,
39810
+ slippage: params.slippage,
39811
+ fromDomainId: fromCoinId ? domains.get(fromCoinId) : void 0,
39812
+ toDomainId: toCoinId ? domains.get(toCoinId) : void 0
39813
+ })
39814
+ );
39730
39815
  if (quote.routes.length === 0) {
39731
39816
  return {
39732
39817
  success: false,
@@ -39749,7 +39834,8 @@ var SwapExecutor = class {
39749
39834
  `Swapping ${inputAmt} ${firstStep.from.asset.metadata.symbol} -> ${outputAmt} ${lastStep.to.asset.metadata.symbol} via ${route.steps.map((s2) => s2.provider.name).join(" -> ")}`
39750
39835
  );
39751
39836
  const chainConfig = getChainById(params.fromChain);
39752
- const transactions = await this.swapClient.getSwapTransactions(route);
39837
+ const transactions = await withRetry(() => this.swapClient.getSwapTransactions(route));
39838
+ let approvalTxHash;
39753
39839
  try {
39754
39840
  let txHash = "";
39755
39841
  for (const txData of transactions) {
@@ -39761,6 +39847,7 @@ var SwapExecutor = class {
39761
39847
  );
39762
39848
  }
39763
39849
  txHash = await this.sendTransaction(txData, chainConfig, params.fromChain);
39850
+ if (isApproval) approvalTxHash = txHash;
39764
39851
  this.log(
39765
39852
  `${isApproval ? "Approval" : "Swap"} tx: ${getExplorerTxUrl(params.fromChain, txHash)}`
39766
39853
  );
@@ -39778,7 +39865,10 @@ var SwapExecutor = class {
39778
39865
  explorerUrl: getExplorerTxUrl(params.fromChain, txHash)
39779
39866
  };
39780
39867
  } catch (err) {
39781
- const msg = err instanceof Error ? err.message : "Unknown error";
39868
+ let msg = err instanceof Error ? err.message : "Unknown error";
39869
+ if (approvalTxHash) {
39870
+ msg += `. Approval was sent (tx: ${approvalTxHash}). Check allowance before retrying.`;
39871
+ }
39782
39872
  return { success: false, route, error: msg };
39783
39873
  }
39784
39874
  }
@@ -39851,7 +39941,7 @@ function registerTransferCommand(program3) {
39851
39941
  error(msg);
39852
39942
  if (opts.json) output({ error: msg }, true);
39853
39943
  process.exitCode = 1;
39854
- process.exit(0);
39944
+ safeExit();
39855
39945
  return;
39856
39946
  }
39857
39947
  const resolvedTo = await resolveAddressOrName(opts.to);
@@ -39862,7 +39952,7 @@ function registerTransferCommand(program3) {
39862
39952
  error(msg);
39863
39953
  if (opts.json) output({ error: msg }, true);
39864
39954
  process.exitCode = 1;
39865
- process.exit();
39955
+ safeExit();
39866
39956
  return;
39867
39957
  }
39868
39958
  }
@@ -39880,7 +39970,7 @@ function registerTransferCommand(program3) {
39880
39970
  error(msg);
39881
39971
  if (opts.json) output({ error: msg }, true);
39882
39972
  process.exitCode = 1;
39883
- process.exit();
39973
+ safeExit();
39884
39974
  return;
39885
39975
  }
39886
39976
  const parsedAmount = parseFloat(opts.amount);
@@ -39889,7 +39979,7 @@ function registerTransferCommand(program3) {
39889
39979
  error(msg);
39890
39980
  if (opts.json) output({ error: msg }, true);
39891
39981
  process.exitCode = 1;
39892
- process.exit();
39982
+ safeExit();
39893
39983
  return;
39894
39984
  }
39895
39985
  try {
@@ -39908,7 +39998,7 @@ function registerTransferCommand(program3) {
39908
39998
  error(msg);
39909
39999
  if (opts.json) output({ error: msg }, true);
39910
40000
  process.exitCode = 1;
39911
- process.exit();
40001
+ safeExit();
39912
40002
  return;
39913
40003
  }
39914
40004
  if (usdValue > 1e3) {
@@ -39947,7 +40037,7 @@ function registerTransferCommand(program3) {
39947
40037
  if (opts.json) output({ error: msg }, true);
39948
40038
  process.exitCode = 1;
39949
40039
  }
39950
- process.exit();
40040
+ safeExit();
39951
40041
  });
39952
40042
  }
39953
40043
 
@@ -40244,9 +40334,10 @@ function registerSwapCommand(program3) {
40244
40334
  const msg = err instanceof Error ? err.message : String(err);
40245
40335
  error(`Swap failed: ${msg}`);
40246
40336
  if (opts.json) output({ error: msg }, true);
40337
+ process.exitCode = 1;
40247
40338
  }
40248
40339
  if (!opts.quoteOnly) {
40249
- setTimeout(() => process.exit(0), 100);
40340
+ safeExit();
40250
40341
  }
40251
40342
  }
40252
40343
  );
@@ -40268,7 +40359,7 @@ function registerErc20Command(program3) {
40268
40359
  error(msg);
40269
40360
  if (opts.json) output({ error: msg }, true);
40270
40361
  process.exitCode = 1;
40271
- process.exit();
40362
+ safeExit();
40272
40363
  return;
40273
40364
  }
40274
40365
  const chainKey = coinTypeToChainKey(coinId);
@@ -40277,7 +40368,7 @@ function registerErc20Command(program3) {
40277
40368
  error(msg);
40278
40369
  if (opts.json) output({ error: msg }, true);
40279
40370
  process.exitCode = 1;
40280
- process.exit();
40371
+ safeExit();
40281
40372
  return;
40282
40373
  }
40283
40374
  const address = await provider.getAddress(chainKey);
@@ -40288,7 +40379,7 @@ function registerErc20Command(program3) {
40288
40379
  error(msg);
40289
40380
  if (opts.json) output({ error: msg }, true);
40290
40381
  process.exitCode = 1;
40291
- process.exit();
40382
+ safeExit();
40292
40383
  return;
40293
40384
  }
40294
40385
  warn("WARNING: Unlimited approval grants the spender access to ALL tokens of this type.");
@@ -40319,7 +40410,7 @@ function registerErc20Command(program3) {
40319
40410
  if (opts.json) output({ error: msg }, true);
40320
40411
  process.exitCode = 1;
40321
40412
  }
40322
- process.exit();
40413
+ safeExit();
40323
40414
  });
40324
40415
  erc20.command("revoke").description("Revoke token approval (set allowance to 0)").requiredOption("--token <assetId>", "Token asset ID (e.g., c60_t0xA0b8...)").requiredOption("--spender <address>", "Spender address to revoke").option("--password <password>", "Wallet password (falls back to keychain / TWAK_WALLET_PASSWORD)").option("--json", "JSON output").action(async (opts) => {
40325
40416
  try {
@@ -40332,7 +40423,7 @@ function registerErc20Command(program3) {
40332
40423
  error(msg);
40333
40424
  if (opts.json) output({ error: msg }, true);
40334
40425
  process.exitCode = 1;
40335
- process.exit();
40426
+ safeExit();
40336
40427
  return;
40337
40428
  }
40338
40429
  const chainKey = coinTypeToChainKey(coinId);
@@ -40341,7 +40432,7 @@ function registerErc20Command(program3) {
40341
40432
  error(msg);
40342
40433
  if (opts.json) output({ error: msg }, true);
40343
40434
  process.exitCode = 1;
40344
- process.exit();
40435
+ safeExit();
40345
40436
  return;
40346
40437
  }
40347
40438
  const address = await provider.getAddress(chainKey);
@@ -40370,7 +40461,7 @@ function registerErc20Command(program3) {
40370
40461
  if (opts.json) output({ error: msg }, true);
40371
40462
  process.exitCode = 1;
40372
40463
  }
40373
- process.exit();
40464
+ safeExit();
40374
40465
  });
40375
40466
  erc20.command("allowance").description("Check token allowance").requiredOption("--token <assetId>", "Token asset ID (e.g., c60_t0xA0b8...)").requiredOption("--owner <address>", "Owner address").requiredOption("--spender <address>", "Spender address").option("--json", "JSON output").action(async (opts) => {
40376
40467
  try {
@@ -40393,7 +40484,7 @@ function registerErc20Command(program3) {
40393
40484
  if (opts.json) output({ error: msg }, true);
40394
40485
  process.exitCode = 1;
40395
40486
  }
40396
- process.exit();
40487
+ safeExit();
40397
40488
  });
40398
40489
  }
40399
40490
 
@@ -40516,7 +40607,9 @@ function registerAlertCommand(program3) {
40516
40607
  }
40517
40608
  const resolved = resolveToken(sym, resolvedChain);
40518
40609
  if (!resolved) {
40519
- error(`Unknown token: ${sym} on ${resolvedChain}. Use a contract address or asset ID (e.g. c60_t0xABC...).`);
40610
+ error(
40611
+ `Unknown token: ${sym} on ${resolvedChain}. Use a contract address or asset ID (e.g. c60_t0xABC...).`
40612
+ );
40520
40613
  if (opts.json) output({ error: `Unknown token: ${sym}` }, true);
40521
40614
  process.exitCode = 1;
40522
40615
  return;
@@ -40602,6 +40695,7 @@ function registerAlertCommand(program3) {
40602
40695
  const msg = err instanceof Error ? err.message : String(err);
40603
40696
  error(msg);
40604
40697
  if (opts.json) output({ error: msg }, true);
40698
+ process.exitCode = 1;
40605
40699
  }
40606
40700
  });
40607
40701
  alert.command("delete <id>").description("Delete an alert").option("--json", "JSON output").action(async (id, opts) => {
@@ -40951,6 +41045,7 @@ function registerQueryCommand(program3) {
40951
41045
  } catch (err) {
40952
41046
  handleError(err, opts.json);
40953
41047
  }
41048
+ safeExit();
40954
41049
  });
40955
41050
  program3.command("tx <hash>").description("Get transaction details by hash (on-chain RPC lookup)").requiredOption("--chain <name>", "Chain name").option("--address <address>", "Wallet address (auto-detected from wallet if omitted)").option("--password <pw>", "Wallet password (for auto-detecting address)").option("--json", "JSON output").action(async (hash, opts) => {
40956
41051
  try {
@@ -41165,6 +41260,7 @@ function registerQueryCommand(program3) {
41165
41260
  } catch (err) {
41166
41261
  handleError(err, opts.json);
41167
41262
  }
41263
+ safeExit();
41168
41264
  });
41169
41265
  program3.command("trending").description("Get trending tokens by market activity or category").option(
41170
41266
  "--category <id>",
@@ -55702,7 +55798,7 @@ var crypto6 = __toESM(require("crypto"));
55702
55798
  // package.json
55703
55799
  var package_default = {
55704
55800
  name: "@trustwallet/cli",
55705
- version: "0.8.0",
55801
+ version: "0.9.0",
55706
55802
  description: "TWAK CLI \u2014 command-line interface for Trust Wallet Agent Kit",
55707
55803
  main: "dist/index.js",
55708
55804
  types: "dist/index.d.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAMzD;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAU/B"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAMzD;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAa/B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustwallet/cli",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "TWAK CLI — command-line interface for Trust Wallet Agent Kit",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -28,17 +28,17 @@
28
28
  "tsup": "8.5.1",
29
29
  "typescript": "5.7.3",
30
30
  "vitest": "4.1.2",
31
- "@twak/actions": "0.8.0",
32
- "@twak/blockchain": "0.8.0",
33
- "@twak/core": "0.8.0",
34
- "@twak/mcp": "0.8.0",
35
- "@twak/security": "0.8.0",
36
- "@twak/storage": "0.8.0",
37
- "@twak/swap": "0.8.0",
38
- "@twak/transactions": "0.8.0",
39
- "@twak/wallet": "0.8.0",
40
- "@twak/wallet-core": "0.8.0",
41
- "@twak/walletconnect": "0.8.0"
31
+ "@twak/actions": "0.9.0",
32
+ "@twak/blockchain": "0.9.0",
33
+ "@twak/core": "0.9.0",
34
+ "@twak/mcp": "0.9.0",
35
+ "@twak/security": "0.9.0",
36
+ "@twak/storage": "0.9.0",
37
+ "@twak/swap": "0.9.0",
38
+ "@twak/transactions": "0.9.0",
39
+ "@twak/wallet": "0.9.0",
40
+ "@twak/wallet-core": "0.9.0",
41
+ "@twak/walletconnect": "0.9.0"
42
42
  },
43
43
  "publishConfig": {
44
44
  "access": "public"