@trustwallet/cli 0.6.11 → 0.7.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.
Files changed (2) hide show
  1. package/dist/index.js +750 -21
  2. package/package.json +12 -12
package/dist/index.js CHANGED
@@ -3138,7 +3138,7 @@ function getBackend() {
3138
3138
  if (macSecurity.isAvailable()) return macSecurity;
3139
3139
  return null;
3140
3140
  }
3141
- var fs, path, os, crypto2, import_child_process, import_os, crypto22, __require, FileStore, ALGORITHM, KEY_LENGTH, IV_LENGTH, SALT_LENGTH, ITERATIONS, SERVICE, WALLET_ACCOUNT, API_SECRET_ACCOUNT, macSecurity, KeychainManager, CREDENTIALS_FILE, CredentialManager, WALLET_FILE, WalletConfigStore, ALERTS_FILE, AlertStore, SEEN_HASHES_FILE, SeenHashStore;
3141
+ var fs, path, os, crypto2, import_child_process, import_os, crypto22, crypto3, __require, FileStore, ALGORITHM, KEY_LENGTH, IV_LENGTH, SALT_LENGTH, ITERATIONS, SERVICE, WALLET_ACCOUNT, API_SECRET_ACCOUNT, macSecurity, KeychainManager, CREDENTIALS_FILE, CredentialManager, WALLET_FILE, WalletConfigStore, ALERTS_FILE, AlertStore, AUTOMATIONS_FILE, AutomationStore, SEEN_HASHES_FILE, SeenHashStore;
3142
3142
  var init_dist = __esm({
3143
3143
  "../storage/dist/index.mjs"() {
3144
3144
  "use strict";
@@ -3149,6 +3149,7 @@ var init_dist = __esm({
3149
3149
  import_child_process = require("child_process");
3150
3150
  import_os = require("os");
3151
3151
  crypto22 = __toESM(require("crypto"), 1);
3152
+ crypto3 = __toESM(require("crypto"), 1);
3152
3153
  __require = /* @__PURE__ */ ((x6) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x6, {
3153
3154
  get: (a3, b3) => (typeof require !== "undefined" ? require : a3)[b3]
3154
3155
  }) : x6)(function(x6) {
@@ -3410,6 +3411,51 @@ var init_dist = __esm({
3410
3411
  await this.store.remove(ALERTS_FILE);
3411
3412
  }
3412
3413
  };
3414
+ AUTOMATIONS_FILE = "automations.json";
3415
+ AutomationStore = class {
3416
+ store;
3417
+ constructor(config2) {
3418
+ this.store = new FileStore(config2);
3419
+ }
3420
+ async create(record2) {
3421
+ const automations = await this.list();
3422
+ const entry = {
3423
+ ...record2,
3424
+ id: crypto3.randomUUID(),
3425
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3426
+ active: true
3427
+ };
3428
+ automations.push(entry);
3429
+ await this.store.write(AUTOMATIONS_FILE, automations);
3430
+ return entry;
3431
+ }
3432
+ async list() {
3433
+ return await this.store.read(AUTOMATIONS_FILE) || [];
3434
+ }
3435
+ async getById(id) {
3436
+ const automations = await this.list();
3437
+ return automations.find((a3) => a3.id === id);
3438
+ }
3439
+ async update(id, updates) {
3440
+ const automations = await this.list();
3441
+ const index = automations.findIndex((a3) => a3.id === id);
3442
+ if (index === -1) return void 0;
3443
+ automations[index] = { ...automations[index], ...updates };
3444
+ await this.store.write(AUTOMATIONS_FILE, automations);
3445
+ return automations[index];
3446
+ }
3447
+ async delete(id) {
3448
+ const automations = await this.list();
3449
+ const filtered = automations.filter((a3) => a3.id !== id);
3450
+ if (filtered.length === automations.length) return false;
3451
+ await this.store.write(AUTOMATIONS_FILE, filtered);
3452
+ return true;
3453
+ }
3454
+ async getActive() {
3455
+ const automations = await this.list();
3456
+ return automations.filter((a3) => a3.active);
3457
+ }
3458
+ };
3413
3459
  SEEN_HASHES_FILE = "seen-hashes.json";
3414
3460
  SeenHashStore = class {
3415
3461
  store;
@@ -14582,8 +14628,8 @@ var require_dataType = __commonJS({
14582
14628
  return types;
14583
14629
  }
14584
14630
  exports2.getSchemaTypes = getSchemaTypes;
14585
- function getJSONTypes(ts3) {
14586
- const types = Array.isArray(ts3) ? ts3 : ts3 ? [ts3] : [];
14631
+ function getJSONTypes(ts4) {
14632
+ const types = Array.isArray(ts4) ? ts4 : ts4 ? [ts4] : [];
14587
14633
  if (types.every(rules_1.isJSONType))
14588
14634
  return types;
14589
14635
  throw new Error("type must be JSONType or JSONType[]: " + types.join(","));
@@ -15625,18 +15671,18 @@ var require_validate = __commonJS({
15625
15671
  });
15626
15672
  narrowSchemaTypes(it4, types);
15627
15673
  }
15628
- function checkMultipleTypes(it4, ts3) {
15629
- if (ts3.length > 1 && !(ts3.length === 2 && ts3.includes("null"))) {
15674
+ function checkMultipleTypes(it4, ts4) {
15675
+ if (ts4.length > 1 && !(ts4.length === 2 && ts4.includes("null"))) {
15630
15676
  strictTypesError(it4, "use allowUnionTypes to allow union type keyword");
15631
15677
  }
15632
15678
  }
15633
- function checkKeywordTypes(it4, ts3) {
15679
+ function checkKeywordTypes(it4, ts4) {
15634
15680
  const rules = it4.self.RULES.all;
15635
15681
  for (const keyword in rules) {
15636
15682
  const rule = rules[keyword];
15637
15683
  if (typeof rule == "object" && (0, applicability_1.shouldUseRule)(it4.schema, rule)) {
15638
15684
  const { type } = rule.definition;
15639
- if (type.length && !type.some((t) => hasApplicableType(ts3, t))) {
15685
+ if (type.length && !type.some((t) => hasApplicableType(ts4, t))) {
15640
15686
  strictTypesError(it4, `missing type "${type.join(",")}" for keyword "${keyword}"`);
15641
15687
  }
15642
15688
  }
@@ -15645,18 +15691,18 @@ var require_validate = __commonJS({
15645
15691
  function hasApplicableType(schTs, kwdT) {
15646
15692
  return schTs.includes(kwdT) || kwdT === "number" && schTs.includes("integer");
15647
15693
  }
15648
- function includesType(ts3, t) {
15649
- return ts3.includes(t) || t === "integer" && ts3.includes("number");
15694
+ function includesType(ts4, t) {
15695
+ return ts4.includes(t) || t === "integer" && ts4.includes("number");
15650
15696
  }
15651
15697
  function narrowSchemaTypes(it4, withTypes) {
15652
- const ts3 = [];
15698
+ const ts4 = [];
15653
15699
  for (const t of it4.dataTypes) {
15654
15700
  if (includesType(withTypes, t))
15655
- ts3.push(t);
15701
+ ts4.push(t);
15656
15702
  else if (withTypes.includes("integer") && t === "number")
15657
- ts3.push("integer");
15703
+ ts4.push("integer");
15658
15704
  }
15659
- it4.dataTypes = ts3;
15705
+ it4.dataTypes = ts4;
15660
15706
  }
15661
15707
  function strictTypesError(it4, msg) {
15662
15708
  const schemaPath = it4.schemaEnv.baseId + it4.errSchemaPath;
@@ -22368,6 +22414,9 @@ function warn(message) {
22368
22414
  function info(message) {
22369
22415
  console.log(import_chalk.default.cyan(message));
22370
22416
  }
22417
+ function dim(message) {
22418
+ console.log(import_chalk.default.dim(message));
22419
+ }
22371
22420
 
22372
22421
  // src/config-loader.ts
22373
22422
  var import_chalk2 = __toESM(require_source());
@@ -25268,7 +25317,7 @@ function walk(err, fn2) {
25268
25317
 
25269
25318
  // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/cryptoNode.js
25270
25319
  var nc = __toESM(require("crypto"), 1);
25271
- var crypto3 = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : nc && typeof nc === "object" && "randomBytes" in nc ? nc : void 0;
25320
+ var crypto4 = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : nc && typeof nc === "object" && "randomBytes" in nc ? nc : void 0;
25272
25321
 
25273
25322
  // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js
25274
25323
  function isBytes(a3) {
@@ -25365,11 +25414,11 @@ function createHasher(hashCons) {
25365
25414
  return hashC;
25366
25415
  }
25367
25416
  function randomBytes2(bytesLength = 32) {
25368
- if (crypto3 && typeof crypto3.getRandomValues === "function") {
25369
- return crypto3.getRandomValues(new Uint8Array(bytesLength));
25417
+ if (crypto4 && typeof crypto4.getRandomValues === "function") {
25418
+ return crypto4.getRandomValues(new Uint8Array(bytesLength));
25370
25419
  }
25371
- if (crypto3 && typeof crypto3.randomBytes === "function") {
25372
- return Uint8Array.from(crypto3.randomBytes(bytesLength));
25420
+ if (crypto4 && typeof crypto4.randomBytes === "function") {
25421
+ return Uint8Array.from(crypto4.randomBytes(bytesLength));
25373
25422
  }
25374
25423
  throw new Error("crypto.getRandomValues must be defined");
25375
25424
  }
@@ -39471,6 +39520,108 @@ var SwapClient = class {
39471
39520
  }
39472
39521
  }
39473
39522
  };
39523
+ var SwapExecutor = class {
39524
+ constructor(swapClient, walletProvider, options = {}) {
39525
+ this.swapClient = swapClient;
39526
+ this.walletProvider = walletProvider;
39527
+ this.options = options;
39528
+ }
39529
+ log(msg) {
39530
+ this.options.onStatus?.(msg);
39531
+ }
39532
+ async execute(params) {
39533
+ const address = await this.walletProvider.getAddress(params.fromChain);
39534
+ const fromTokenInfo = resolveToken(params.fromToken, params.fromChain);
39535
+ const toTokenInfo = resolveToken(params.toToken, params.toChain);
39536
+ const parsedAmount = parseAmount(params.amount, fromTokenInfo.decimals);
39537
+ const fromCoinId = getChainById(params.fromChain)?.coinId;
39538
+ const toCoinId = getChainById(params.toChain)?.coinId;
39539
+ const domains = this.options.amberDomains || /* @__PURE__ */ new Map();
39540
+ let destinationAddress;
39541
+ if (params.toChain !== params.fromChain) {
39542
+ destinationAddress = await this.walletProvider.getAddress(params.toChain);
39543
+ }
39544
+ const quote = await this.swapClient.getQuote({
39545
+ fromChain: params.fromChain,
39546
+ fromToken: fromTokenInfo.address,
39547
+ toChain: params.toChain,
39548
+ toToken: toTokenInfo.address,
39549
+ amount: parsedAmount,
39550
+ walletAddress: address,
39551
+ destinationAddress,
39552
+ slippage: params.slippage,
39553
+ fromDomainId: fromCoinId ? domains.get(fromCoinId) : void 0,
39554
+ toDomainId: toCoinId ? domains.get(toCoinId) : void 0
39555
+ });
39556
+ if (quote.routes.length === 0) {
39557
+ return { success: false, route: { id: "", steps: [], warnings: ["No routes found"], expirationDate: "", totalOutput: "0" }, error: "No swap routes found" };
39558
+ }
39559
+ const route = quote.routes[0];
39560
+ const firstStep = route.steps[0];
39561
+ const lastStep = route.steps[route.steps.length - 1];
39562
+ const inputAmt = formatAmount(firstStep.from.amount, firstStep.from.asset.metadata.decimals);
39563
+ const outputAmt = formatAmount(lastStep.to.amount, lastStep.to.asset.metadata.decimals);
39564
+ this.log(`Swapping ${inputAmt} ${firstStep.from.asset.metadata.symbol} -> ${outputAmt} ${lastStep.to.asset.metadata.symbol} via ${route.steps.map((s2) => s2.provider.name).join(" -> ")}`);
39565
+ const chainConfig = getChainById(params.fromChain);
39566
+ const transactions = await this.swapClient.getSwapTransactions(route);
39567
+ try {
39568
+ let txHash = "";
39569
+ for (const txData of transactions) {
39570
+ const txType = txData.transaction.type;
39571
+ const isApproval = txType === "approval" || txType === "revokeApproval";
39572
+ if (isApproval) {
39573
+ this.log(txType === "revokeApproval" ? "Revoking prior approval..." : "Sending token approval...");
39574
+ }
39575
+ txHash = await this.sendTransaction(txData, chainConfig, params.fromChain);
39576
+ this.log(`${isApproval ? "Approval" : "Swap"} tx: ${getExplorerTxUrl(params.fromChain, txHash)}`);
39577
+ await this.pollForConfirmation(params.fromChain, address, txHash, isApproval ? 6e4 : 12e4);
39578
+ }
39579
+ return {
39580
+ success: true,
39581
+ txHash,
39582
+ route,
39583
+ explorerUrl: getExplorerTxUrl(params.fromChain, txHash)
39584
+ };
39585
+ } catch (err) {
39586
+ const msg = err instanceof Error ? err.message : "Unknown error";
39587
+ return { success: false, route, error: msg };
39588
+ }
39589
+ }
39590
+ async sendTransaction(txData, chainConfig, fromChain) {
39591
+ if (chainConfig?.namespace === "solana" && txData.transaction.solanaTx) {
39592
+ return this.walletProvider.sendTransaction({
39593
+ chainId: `solana:${chainConfig.chainId}`,
39594
+ to: "",
39595
+ data: txData.transaction.solanaTx.serializedMessage
39596
+ });
39597
+ } else if (txData.transaction.evmTx) {
39598
+ return this.walletProvider.sendTransaction({
39599
+ chainId: `eip155:${chainConfig?.chainId || "1"}`,
39600
+ to: txData.transaction.evmTx.to,
39601
+ data: txData.transaction.evmTx.data,
39602
+ value: txData.transaction.evmTx.value || "0x0"
39603
+ });
39604
+ }
39605
+ throw new Error(`No transaction data returned for swap step on ${fromChain}`);
39606
+ }
39607
+ async pollForConfirmation(chainKey, address, hash, timeoutMs) {
39608
+ const blockchainClient = this.walletProvider.getBlockchainClient?.();
39609
+ if (!blockchainClient) return;
39610
+ const deadline = Date.now() + timeoutMs;
39611
+ while (Date.now() < deadline) {
39612
+ await new Promise((r3) => setTimeout(r3, 2e3));
39613
+ try {
39614
+ const status = await blockchainClient.findTransactionStatus(chainKey, address, hash);
39615
+ if (status.confirmed) return;
39616
+ if (status.failed) throw new Error(`Transaction failed: ${status.error || "unknown error"}`);
39617
+ } catch (e2) {
39618
+ const err = e2 instanceof Error ? e2 : new Error(String(e2));
39619
+ if (err.message.startsWith("Transaction failed")) throw err;
39620
+ }
39621
+ }
39622
+ throw new Error(`Transaction ${hash} was not confirmed within ${Math.round(timeoutMs / 1e3)}s`);
39623
+ }
39624
+ };
39474
39625
 
39475
39626
  // src/commands/transfer.ts
39476
39627
  var DEFAULT_MAX_TRANSFER_USD = 1e4;
@@ -45628,6 +45779,171 @@ var MarketActionProvider = class extends ActionProvider {
45628
45779
  };
45629
45780
  }
45630
45781
  };
45782
+ var AutomateActionProvider = class extends ActionProvider {
45783
+ constructor(automationStore, swapClient, walletProvider, blockchainClient) {
45784
+ super();
45785
+ this.automationStore = automationStore;
45786
+ this.swapClient = swapClient;
45787
+ this.walletProvider = walletProvider;
45788
+ this.blockchainClient = blockchainClient;
45789
+ }
45790
+ name = "automate";
45791
+ description = "DCA and limit-order automation for recurring and conditional swaps";
45792
+ getActions() {
45793
+ return [
45794
+ this.createAutomation(),
45795
+ this.listAutomations(),
45796
+ this.deleteAutomation(),
45797
+ this.runAutomationNow()
45798
+ ];
45799
+ }
45800
+ createAutomation() {
45801
+ return {
45802
+ name: "create_automation",
45803
+ description: "Create a DCA (recurring buy) or limit order (buy/sell when price condition is met)",
45804
+ schema: external_exports.object({
45805
+ type: external_exports.enum(["dca", "limit"]).describe("Automation type: dca (recurring) or limit (price trigger)"),
45806
+ fromToken: external_exports.string().describe("Source token symbol or address"),
45807
+ toToken: external_exports.string().describe("Destination token symbol or address"),
45808
+ chain: external_exports.string().default("ethereum").describe("Chain name"),
45809
+ amount: external_exports.string().describe("Amount of fromToken per execution"),
45810
+ intervalMs: external_exports.coerce.number().optional().describe("Interval in milliseconds for DCA (e.g., 86400000 for daily)"),
45811
+ targetPrice: external_exports.coerce.number().optional().describe("Target price in USD for limit orders"),
45812
+ condition: external_exports.enum(["above", "below"]).optional().describe("Price condition for limit orders")
45813
+ }),
45814
+ invoke: async (_ctx, input) => {
45815
+ if (input.type === "dca" && !input.intervalMs) {
45816
+ return { success: false, error: "DCA automations require intervalMs" };
45817
+ }
45818
+ if (input.type === "limit" && (input.targetPrice == null || !input.condition)) {
45819
+ return { success: false, error: "Limit orders require targetPrice and condition" };
45820
+ }
45821
+ const record2 = await this.automationStore.create({
45822
+ type: input.type,
45823
+ fromToken: input.fromToken,
45824
+ toToken: input.toToken,
45825
+ chain: input.chain,
45826
+ amount: input.amount,
45827
+ intervalMs: input.intervalMs,
45828
+ targetPrice: input.targetPrice,
45829
+ condition: input.condition
45830
+ });
45831
+ const summary = input.type === "dca" ? `DCA: ${input.amount} ${input.fromToken} \u2192 ${input.toToken} every ${Math.round((input.intervalMs || 0) / 36e5)}h` : `Limit: swap ${input.amount} ${input.fromToken} \u2192 ${input.toToken} when price ${input.condition} $${input.targetPrice}`;
45832
+ return { success: true, id: record2.id, summary, record: record2 };
45833
+ }
45834
+ };
45835
+ }
45836
+ listAutomations() {
45837
+ return {
45838
+ name: "list_automations",
45839
+ description: "List all active automation rules (DCA and limit orders)",
45840
+ schema: external_exports.object({
45841
+ activeOnly: external_exports.boolean().optional().default(true).describe("Only show active automations")
45842
+ }),
45843
+ invoke: async (_ctx, input) => {
45844
+ const all = await this.automationStore.list();
45845
+ const automations = input.activeOnly ? all.filter((a3) => a3.active) : all;
45846
+ return { success: true, count: automations.length, automations };
45847
+ }
45848
+ };
45849
+ }
45850
+ deleteAutomation() {
45851
+ return {
45852
+ name: "delete_automation",
45853
+ description: "Delete (deactivate) an automation rule",
45854
+ schema: external_exports.object({
45855
+ id: external_exports.string().describe("Automation ID to delete")
45856
+ }),
45857
+ invoke: async (_ctx, input) => {
45858
+ const deleted = await this.automationStore.delete(input.id);
45859
+ return deleted ? { success: true, message: `Automation ${input.id} deleted` } : { success: false, error: `Automation ${input.id} not found` };
45860
+ }
45861
+ };
45862
+ }
45863
+ async sendSwapTx(txData, chainConfig, signer) {
45864
+ if (chainConfig?.namespace === "solana" && txData.transaction.solanaTx) {
45865
+ return signer.sendTransaction({
45866
+ chainId: `solana:${chainConfig.chainId}`,
45867
+ to: "",
45868
+ data: txData.transaction.solanaTx.serializedMessage
45869
+ });
45870
+ } else if (txData.transaction.evmTx) {
45871
+ return signer.sendTransaction({
45872
+ chainId: `eip155:${chainConfig?.chainId || "1"}`,
45873
+ to: txData.transaction.evmTx.to,
45874
+ data: txData.transaction.evmTx.data,
45875
+ value: txData.transaction.evmTx.value || "0x0"
45876
+ });
45877
+ }
45878
+ throw new Error("No transaction data returned for this swap step");
45879
+ }
45880
+ async pollConfirmation(chainKey, address, hash, timeoutMs) {
45881
+ if (!this.blockchainClient) return;
45882
+ const deadline = Date.now() + timeoutMs;
45883
+ while (Date.now() < deadline) {
45884
+ await new Promise((r3) => setTimeout(r3, 2e3));
45885
+ try {
45886
+ const status = await this.blockchainClient.findTransactionStatus(chainKey, address, hash);
45887
+ if (status.confirmed) return;
45888
+ if (status.failed) throw new Error(`Transaction failed: ${status.error || "unknown error"}`);
45889
+ } catch (e2) {
45890
+ const err = e2 instanceof Error ? e2 : new Error(String(e2));
45891
+ if (err.message.startsWith("Transaction failed")) throw err;
45892
+ }
45893
+ }
45894
+ throw new Error(`Transaction ${hash} was not confirmed within ${Math.round(timeoutMs / 1e3)}s`);
45895
+ }
45896
+ runAutomationNow() {
45897
+ return {
45898
+ name: "run_automation_now",
45899
+ description: "Manually execute an automation immediately (runs the swap now regardless of schedule)",
45900
+ schema: external_exports.object({
45901
+ id: external_exports.string().describe("Automation ID to run")
45902
+ }),
45903
+ invoke: async (_ctx, input) => {
45904
+ if (!this.walletProvider || !this.swapClient) {
45905
+ return { success: false, error: "Agent wallet and swap client required to execute automation" };
45906
+ }
45907
+ const record2 = await this.automationStore.getById(input.id);
45908
+ if (!record2) return { success: false, error: `Automation ${input.id} not found` };
45909
+ if (!record2.active) return { success: false, error: `Automation ${input.id} is inactive` };
45910
+ const fromTokenInfo = resolveToken(record2.fromToken, record2.chain);
45911
+ const toTokenInfo = resolveToken(record2.toToken, record2.chain);
45912
+ const parsedAmount = parseAmount(record2.amount, fromTokenInfo.decimals);
45913
+ const address = await this.walletProvider.getAddress(record2.chain);
45914
+ const quote = await this.swapClient.getQuote({
45915
+ fromChain: record2.chain,
45916
+ fromToken: fromTokenInfo.address,
45917
+ toChain: record2.chain,
45918
+ toToken: toTokenInfo.address,
45919
+ amount: parsedAmount,
45920
+ walletAddress: address
45921
+ });
45922
+ if (quote.routes.length === 0) {
45923
+ return { success: false, error: "No swap routes found" };
45924
+ }
45925
+ const route = quote.routes[0];
45926
+ const chainConfig = getChainById(record2.chain);
45927
+ const transactions = await this.swapClient.getSwapTransactions(route);
45928
+ let txHash = "";
45929
+ for (const txData of transactions) {
45930
+ txHash = await this.sendSwapTx(txData, chainConfig, this.walletProvider);
45931
+ const isApproval = txData.transaction.type === "approval" || txData.transaction.type === "revokeApproval";
45932
+ await this.pollConfirmation(record2.chain, address, txHash, isApproval ? 6e4 : 12e4);
45933
+ }
45934
+ await this.automationStore.update(record2.id, { lastRunAt: (/* @__PURE__ */ new Date()).toISOString() });
45935
+ const explorerUrl = getExplorerTxUrl(record2.chain, txHash);
45936
+ return {
45937
+ success: true,
45938
+ txHash,
45939
+ automationId: record2.id,
45940
+ swapped: `${record2.amount} ${record2.fromToken} \u2192 ${record2.toToken}`,
45941
+ explorer: explorerUrl || void 0
45942
+ };
45943
+ }
45944
+ };
45945
+ }
45946
+ };
45631
45947
 
45632
45948
  // src/commands/serve.ts
45633
45949
  init_dist();
@@ -54426,6 +54742,7 @@ function registerServeCommand(program3) {
54426
54742
  const client = await getClient();
54427
54743
  const swapClient = new SwapClient(client);
54428
54744
  const alertStore = new AlertStore();
54745
+ const automationStore = new AutomationStore();
54429
54746
  const blockchainClient = new BlockchainClient();
54430
54747
  let agentWallet;
54431
54748
  try {
@@ -54465,6 +54782,7 @@ function registerServeCommand(program3) {
54465
54782
  registry2.register(new AgentWalletActionProvider(blockchainClient));
54466
54783
  registry2.register(new TokenActionProvider(blockchainClient, agentWallet));
54467
54784
  registry2.register(new MarketActionProvider());
54785
+ registry2.register(new AutomateActionProvider(automationStore, swapClient, walletProvider, blockchainClient));
54468
54786
  const context = {
54469
54787
  httpClient: client
54470
54788
  };
@@ -54496,6 +54814,221 @@ function registerServeCommand(program3) {
54496
54814
  });
54497
54815
  }
54498
54816
 
54817
+ // src/commands/automate.ts
54818
+ init_dist();
54819
+ init_dist2();
54820
+ function parseInterval(value) {
54821
+ const match = value.match(/^(\d+(?:\.\d+)?)\s*(s|m|h)?$/i);
54822
+ if (!match) return null;
54823
+ const num = parseFloat(match[1]);
54824
+ if (isNaN(num)) return null;
54825
+ const unit = (match[2] || "s").toLowerCase();
54826
+ if (unit === "s") return num * 1e3;
54827
+ if (unit === "m") return num * 6e4;
54828
+ if (unit === "h") return num * 36e5;
54829
+ return num * 1e3;
54830
+ }
54831
+ function formatInterval(ms3) {
54832
+ if (ms3 >= 36e5) return `${ms3 / 36e5}h`;
54833
+ if (ms3 >= 6e4) return `${ms3 / 6e4}m`;
54834
+ return `${ms3 / 1e3}s`;
54835
+ }
54836
+ function formatRelativeTime(diffMs) {
54837
+ const absDiff = Math.abs(diffMs);
54838
+ let value;
54839
+ if (absDiff < 6e4) {
54840
+ value = `${Math.round(absDiff / 1e3)}s`;
54841
+ } else if (absDiff < 36e5) {
54842
+ value = `${Math.round(absDiff / 6e4)}m`;
54843
+ } else {
54844
+ value = `${Math.round(absDiff / 36e5)}h`;
54845
+ }
54846
+ if (diffMs <= 0) return "overdue";
54847
+ return `in ${value}`;
54848
+ }
54849
+ function formatTimeAgo(isoDate) {
54850
+ const diffMs = Date.now() - new Date(isoDate).getTime();
54851
+ const absDiff = Math.abs(diffMs);
54852
+ if (absDiff < 6e4) return `${Math.round(absDiff / 1e3)}s ago`;
54853
+ if (absDiff < 36e5) return `${Math.round(absDiff / 6e4)}m ago`;
54854
+ return `${Math.round(absDiff / 36e5)}h ago`;
54855
+ }
54856
+ function registerAutomateCommand(program3) {
54857
+ const automate = program3.command("automate").description("Manage DCA and limit order automations");
54858
+ automate.command("add").description("Create a DCA or limit order automation").requiredOption("--from <token>", "Source token (e.g., USDC)").requiredOption("--to <token>", "Destination token (e.g., ETH)").option("--chain <chain>", "Chain", "ethereum").requiredOption("--amount <n>", "Amount of source token per run").option("--interval <duration>", "DCA interval \u2014 e.g. 30s, 5m, 1h (creates DCA automation)").option("--price <usd>", "Target price in USD (creates limit order)").option("--condition <cond>", "Price condition: above or below", "below").option("--max-runs <n>", "Stop after N executions").option("--expires <date>", "Expiry date (ISO 8601, e.g. 2026-04-01)").option("--json", "JSON output").action(async (opts) => {
54859
+ try {
54860
+ if (!opts.interval && !opts.price) {
54861
+ error("Provide --interval (DCA) or --price (limit order)");
54862
+ process.exitCode = 1;
54863
+ return;
54864
+ }
54865
+ const amount = parseFloat(opts.amount);
54866
+ if (isNaN(amount) || amount <= 0) {
54867
+ error("Amount must be a positive number");
54868
+ process.exitCode = 1;
54869
+ return;
54870
+ }
54871
+ if (!isChainSupported(opts.chain)) {
54872
+ error(`Unsupported chain: ${opts.chain}. Run 'twak chains' to list supported chains.`);
54873
+ process.exitCode = 1;
54874
+ return;
54875
+ }
54876
+ let intervalMs;
54877
+ if (opts.interval) {
54878
+ const parsed = parseInterval(opts.interval);
54879
+ if (parsed === null || parsed < 5e3) {
54880
+ error("Interval must be at least 5s (e.g. 30s, 5m, 1h)");
54881
+ process.exitCode = 1;
54882
+ return;
54883
+ }
54884
+ intervalMs = parsed;
54885
+ }
54886
+ const maxRuns = opts.maxRuns ? parseInt(opts.maxRuns) : void 0;
54887
+ if (maxRuns !== void 0 && (isNaN(maxRuns) || maxRuns < 1)) {
54888
+ error("--max-runs must be a positive integer");
54889
+ process.exitCode = 1;
54890
+ return;
54891
+ }
54892
+ let expiresAt;
54893
+ if (opts.expires) {
54894
+ const d3 = new Date(opts.expires);
54895
+ if (isNaN(d3.getTime())) {
54896
+ error("--expires must be a valid date (e.g. 2026-04-01)");
54897
+ process.exitCode = 1;
54898
+ return;
54899
+ }
54900
+ expiresAt = d3.toISOString();
54901
+ }
54902
+ const store = new AutomationStore();
54903
+ const record2 = await store.create({
54904
+ type: opts.interval ? "dca" : "limit",
54905
+ fromToken: opts.from,
54906
+ toToken: opts.to,
54907
+ chain: opts.chain,
54908
+ amount: opts.amount,
54909
+ intervalMs,
54910
+ targetPrice: opts.price ? parseFloat(opts.price) : void 0,
54911
+ condition: opts.price ? opts.condition : void 0,
54912
+ maxRuns,
54913
+ runCount: 0,
54914
+ expiresAt
54915
+ });
54916
+ success("Automation created!");
54917
+ if (opts.interval && intervalMs) {
54918
+ info(`DCA: ${opts.amount} ${opts.from} \u2192 ${opts.to} every ${formatInterval(intervalMs)} on ${opts.chain}`);
54919
+ } else {
54920
+ info(`Limit: swap ${opts.amount} ${opts.from} \u2192 ${opts.to} when price ${opts.condition} $${opts.price} on ${opts.chain}`);
54921
+ }
54922
+ output(record2, opts.json);
54923
+ } catch (err) {
54924
+ const msg = err instanceof Error ? err.message : String(err);
54925
+ error(msg);
54926
+ if (opts.json) output({ error: msg }, true);
54927
+ process.exitCode = 1;
54928
+ }
54929
+ });
54930
+ automate.command("list").description("List active automations").option("--all", "Include inactive automations").option("--json", "JSON output").action(async (opts) => {
54931
+ try {
54932
+ const store = new AutomationStore();
54933
+ const all = await store.list();
54934
+ const records = opts.all ? all : all.filter((a3) => a3.active);
54935
+ if (opts.json) {
54936
+ const enriched = records.map((r3) => {
54937
+ const nextRunAt = r3.type === "dca" && r3.intervalMs ? r3.lastRunAt ? new Date(new Date(r3.lastRunAt).getTime() + r3.intervalMs).toISOString() : (/* @__PURE__ */ new Date()).toISOString() : null;
54938
+ const nextRunIn = nextRunAt ? formatRelativeTime(new Date(nextRunAt).getTime() - Date.now()) : null;
54939
+ return { ...r3, nextRunAt, nextRunIn };
54940
+ });
54941
+ output(enriched, true);
54942
+ return;
54943
+ }
54944
+ if (records.length === 0) {
54945
+ info("No automations found.");
54946
+ return;
54947
+ }
54948
+ for (const r3 of records) {
54949
+ const tag = r3.id.slice(0, 8);
54950
+ const label = r3.type.toUpperCase();
54951
+ const pair = `${r3.amount} ${r3.fromToken}\u2192${r3.toToken} (${r3.chain})`;
54952
+ if (r3.type === "dca") {
54953
+ const interval = formatInterval(r3.intervalMs || 0);
54954
+ const lastPart = r3.lastRunAt ? `last: ${formatTimeAgo(r3.lastRunAt)}` : "never run";
54955
+ let nextPart;
54956
+ if (!r3.intervalMs) {
54957
+ nextPart = "next: unknown";
54958
+ } else if (!r3.lastRunAt) {
54959
+ nextPart = "next: now";
54960
+ } else {
54961
+ const nextAt = new Date(r3.lastRunAt).getTime() + r3.intervalMs;
54962
+ nextPart = `next: ${formatRelativeTime(nextAt - Date.now())}`;
54963
+ }
54964
+ console.log(`[${tag}] ${label} ${pair} every ${interval} \u2014 ${lastPart}, ${nextPart}`);
54965
+ } else {
54966
+ const cond = `${r3.fromToken} ${r3.condition} $${r3.targetPrice}`;
54967
+ console.log(`[${tag}] ${label} ${pair} when ${cond} \u2014 waiting`);
54968
+ }
54969
+ }
54970
+ } catch (err) {
54971
+ const msg = err instanceof Error ? err.message : String(err);
54972
+ error(msg);
54973
+ if (opts.json) output({ error: msg }, true);
54974
+ process.exitCode = 1;
54975
+ }
54976
+ });
54977
+ automate.command("delete <id>").description("Delete an automation by ID").option("--json", "JSON output").action(async (id, opts) => {
54978
+ try {
54979
+ const store = new AutomationStore();
54980
+ const deleted = await store.delete(id);
54981
+ if (deleted) {
54982
+ success(`Automation ${id} deleted`);
54983
+ } else {
54984
+ error(`Automation ${id} not found`);
54985
+ process.exitCode = 1;
54986
+ }
54987
+ } catch (err) {
54988
+ const msg = err instanceof Error ? err.message : String(err);
54989
+ error(msg);
54990
+ if (opts.json) output({ error: msg }, true);
54991
+ process.exitCode = 1;
54992
+ }
54993
+ });
54994
+ automate.command("pause <id>").description("Pause an automation").option("--json", "JSON output").action(async (id, opts) => {
54995
+ try {
54996
+ const store = new AutomationStore();
54997
+ const updated = await store.update(id, { active: false });
54998
+ if (updated) {
54999
+ success(`Automation ${id} paused`);
55000
+ output(updated, opts.json);
55001
+ } else {
55002
+ error(`Automation ${id} not found`);
55003
+ process.exitCode = 1;
55004
+ }
55005
+ } catch (err) {
55006
+ const msg = err instanceof Error ? err.message : String(err);
55007
+ error(msg);
55008
+ if (opts.json) output({ error: msg }, true);
55009
+ process.exitCode = 1;
55010
+ }
55011
+ });
55012
+ automate.command("resume <id>").description("Resume a paused automation").option("--json", "JSON output").action(async (id, opts) => {
55013
+ try {
55014
+ const store = new AutomationStore();
55015
+ const updated = await store.update(id, { active: true });
55016
+ if (updated) {
55017
+ success(`Automation ${id} resumed`);
55018
+ output(updated, opts.json);
55019
+ } else {
55020
+ error(`Automation ${id} not found`);
55021
+ process.exitCode = 1;
55022
+ }
55023
+ } catch (err) {
55024
+ const msg = err instanceof Error ? err.message : String(err);
55025
+ error(msg);
55026
+ if (opts.json) output({ error: msg }, true);
55027
+ process.exitCode = 1;
55028
+ }
55029
+ });
55030
+ }
55031
+
54499
55032
  // src/commands/skill.ts
54500
55033
  var import_fs = require("fs");
54501
55034
  var import_path = require("path");
@@ -54713,12 +55246,12 @@ Confirm? [y/N] `,
54713
55246
  var fs6 = __toESM(require("fs"));
54714
55247
  var os4 = __toESM(require("os"));
54715
55248
  var path4 = __toESM(require("path"));
54716
- var crypto5 = __toESM(require("crypto"));
55249
+ var crypto6 = __toESM(require("crypto"));
54717
55250
 
54718
55251
  // package.json
54719
55252
  var package_default = {
54720
55253
  name: "@trustwallet/cli",
54721
- version: "0.6.11",
55254
+ version: "0.7.0",
54722
55255
  description: "TWAK CLI \u2014 command-line interface for Trust Wallet Agent Kit",
54723
55256
  main: "dist/index.js",
54724
55257
  types: "dist/index.d.ts",
@@ -54818,7 +55351,7 @@ function getUserId() {
54818
55351
  if (fs6.existsSync(ID_FILE)) return fs6.readFileSync(ID_FILE, "utf-8").trim();
54819
55352
  } catch (_e6) {
54820
55353
  }
54821
- const id = crypto5.randomUUID();
55354
+ const id = crypto6.randomUUID();
54822
55355
  try {
54823
55356
  fs6.mkdirSync(CONFIG_DIR, { recursive: true });
54824
55357
  fs6.writeFileSync(ID_FILE, id);
@@ -54875,6 +55408,200 @@ function registerTelemetryCommand(program3) {
54875
55408
  });
54876
55409
  }
54877
55410
 
55411
+ // src/commands/watch.ts
55412
+ init_dist2();
55413
+ init_dist();
55414
+ init_dist4();
55415
+ function ts3() {
55416
+ return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
55417
+ }
55418
+ function parseInterval2(value) {
55419
+ const match = value.match(/^(\d+(?:\.\d+)?)\s*(s|m|h)?$/i);
55420
+ if (!match) return null;
55421
+ const num = parseFloat(match[1]);
55422
+ if (isNaN(num)) return null;
55423
+ const unit = (match[2] || "s").toLowerCase();
55424
+ if (unit === "m") return num * 60;
55425
+ if (unit === "h") return num * 3600;
55426
+ return num;
55427
+ }
55428
+ function registerWatchCommand(program3) {
55429
+ program3.command("watch").description("Background watcher \u2014 polls prices to trigger alerts and execute DCA/limit automations").option("--interval <duration>", "Poll interval \u2014 e.g. 30s, 5m, 1h, or plain number (seconds)", "60").option("--password <password>", "Wallet password for executing swaps").option("--auto-lock <minutes>", "Auto-lock wallet after N minutes of inactivity").option("--dry-run", "Check conditions without executing swaps").option("--json", "JSON output per tick").action(async (opts) => {
55430
+ const intervalSec = parseInterval2(opts.interval);
55431
+ if (intervalSec === null || intervalSec < 5) {
55432
+ error("Interval must be at least 5 seconds (e.g. 30s, 5m, 1h)");
55433
+ process.exitCode = 1;
55434
+ return;
55435
+ }
55436
+ let client;
55437
+ let swapClient;
55438
+ let provider = null;
55439
+ let executor = null;
55440
+ let amberDomains = /* @__PURE__ */ new Map();
55441
+ try {
55442
+ client = await getClient();
55443
+ swapClient = new SwapClient(client);
55444
+ if (!opts.dryRun) {
55445
+ await ensureTrustSDK();
55446
+ const password = await resolvePassword(opts);
55447
+ provider = await AgentWalletProvider.fromStorage(password);
55448
+ if (opts.autoLock) {
55449
+ const minutes = parseInt(opts.autoLock, 10);
55450
+ if (isNaN(minutes) || minutes <= 0) {
55451
+ error("--auto-lock must be a positive number of minutes");
55452
+ process.exitCode = 1;
55453
+ return;
55454
+ }
55455
+ provider.setAutoLock({
55456
+ autoLockMinutes: minutes,
55457
+ passwordResolver: () => resolvePassword(opts)
55458
+ });
55459
+ }
55460
+ amberDomains = await getAmberDomainsByCoinId();
55461
+ executor = new SwapExecutor(swapClient, provider, {
55462
+ amberDomains,
55463
+ onStatus: (msg) => {
55464
+ info(`[${ts3()}] ${msg}`);
55465
+ }
55466
+ });
55467
+ }
55468
+ } catch (err) {
55469
+ error(`Init failed: ${err instanceof Error ? err.message : String(err)}`);
55470
+ process.exitCode = 1;
55471
+ return;
55472
+ }
55473
+ const alertStore = new AlertStore();
55474
+ const automationStore = new AutomationStore();
55475
+ info(`[${ts3()}] Watcher started \u2014 polling every ${intervalSec}s${opts.dryRun ? " (dry run)" : ""}`);
55476
+ const tick = async () => {
55477
+ const tickResults = {
55478
+ alerts: { checked: 0, triggered: [] },
55479
+ automations: { executed: [], skipped: 0 }
55480
+ };
55481
+ try {
55482
+ const activeAlerts = await alertStore.getActive();
55483
+ tickResults.alerts.checked = activeAlerts.length;
55484
+ for (const alert of activeAlerts) {
55485
+ try {
55486
+ const { contractAddress } = parseTokenId(alert.tokenId);
55487
+ const price = await swapClient.getTokenPrice(alert.chainKey, contractAddress || "");
55488
+ if (price === null) continue;
55489
+ const triggered = alert.condition === "above" && price >= alert.targetPrice || alert.condition === "below" && price <= alert.targetPrice;
55490
+ if (triggered) {
55491
+ await alertStore.update(alert.id, { active: false, triggeredAt: (/* @__PURE__ */ new Date()).toISOString() });
55492
+ const detail = { id: alert.id, tokenId: alert.tokenId, condition: alert.condition, targetPrice: alert.targetPrice, currentPrice: price };
55493
+ tickResults.alerts.triggered.push(detail);
55494
+ success(`[${ts3()}] ALERT TRIGGERED: ${alert.tokenId} price $${price} is ${alert.condition} $${alert.targetPrice}`);
55495
+ }
55496
+ } catch (err) {
55497
+ warn(`[${ts3()}] Alert ${alert.id} check failed: ${err instanceof Error ? err.message : String(err)}`);
55498
+ }
55499
+ }
55500
+ const automations = await automationStore.getActive();
55501
+ const now = Date.now();
55502
+ for (const auto of automations) {
55503
+ try {
55504
+ if (auto.expiresAt && new Date(auto.expiresAt).getTime() <= now) {
55505
+ await automationStore.update(auto.id, { active: false });
55506
+ dim(`[${ts3()}] Automation ${auto.id.slice(0, 8)} expired`);
55507
+ tickResults.automations.skipped++;
55508
+ continue;
55509
+ }
55510
+ if (auto.maxRuns && (auto.runCount ?? 0) >= auto.maxRuns) {
55511
+ await automationStore.update(auto.id, { active: false });
55512
+ dim(`[${ts3()}] Automation ${auto.id.slice(0, 8)} reached max runs (${auto.maxRuns})`);
55513
+ tickResults.automations.skipped++;
55514
+ continue;
55515
+ }
55516
+ if (auto.type === "dca") {
55517
+ const lastRun = auto.lastRunAt ? new Date(auto.lastRunAt).getTime() : 0;
55518
+ const intervalMs = auto.intervalMs || 0;
55519
+ if (lastRun + intervalMs > now) {
55520
+ tickResults.automations.skipped++;
55521
+ continue;
55522
+ }
55523
+ if (opts.dryRun) {
55524
+ dim(`[${ts3()}] DRY RUN: would swap ${auto.amount} ${auto.fromToken} -> ${auto.toToken} on ${auto.chain}`);
55525
+ tickResults.automations.executed.push({ id: auto.id, type: "dca", dryRun: true });
55526
+ continue;
55527
+ }
55528
+ info(`[${ts3()}] Executing DCA: ${auto.amount} ${auto.fromToken} -> ${auto.toToken} on ${auto.chain}`);
55529
+ const result = await executor.execute({
55530
+ fromChain: auto.chain,
55531
+ fromToken: auto.fromToken,
55532
+ toChain: auto.chain,
55533
+ toToken: auto.toToken,
55534
+ amount: auto.amount
55535
+ });
55536
+ if (result.success) {
55537
+ await automationStore.update(auto.id, { lastRunAt: (/* @__PURE__ */ new Date()).toISOString(), runCount: (auto.runCount ?? 0) + 1 });
55538
+ success(`[${ts3()}] DCA executed: ${result.explorerUrl}`);
55539
+ tickResults.automations.executed.push({ id: auto.id, type: "dca", txHash: result.txHash, explorer: result.explorerUrl });
55540
+ } else {
55541
+ warn(`[${ts3()}] DCA ${auto.id} failed: ${result.error}`);
55542
+ }
55543
+ } else if (auto.type === "limit") {
55544
+ const toTokenInfo = resolveToken(auto.toToken, auto.chain);
55545
+ const price = await swapClient.getTokenPrice(auto.chain, toTokenInfo.address);
55546
+ if (price === null) continue;
55547
+ const triggered = auto.condition === "below" && price <= (auto.targetPrice || 0) || auto.condition === "above" && price >= (auto.targetPrice || 0);
55548
+ if (!triggered) {
55549
+ tickResults.automations.skipped++;
55550
+ continue;
55551
+ }
55552
+ if (opts.dryRun) {
55553
+ dim(`[${ts3()}] DRY RUN: limit order triggered \u2014 would swap ${auto.amount} ${auto.fromToken} -> ${auto.toToken} on ${auto.chain}`);
55554
+ tickResults.automations.executed.push({ id: auto.id, type: "limit", dryRun: true });
55555
+ continue;
55556
+ }
55557
+ info(`[${ts3()}] Limit order triggered: swapping ${auto.amount} ${auto.fromToken} -> ${auto.toToken} on ${auto.chain}`);
55558
+ const result = await executor.execute({
55559
+ fromChain: auto.chain,
55560
+ fromToken: auto.fromToken,
55561
+ toChain: auto.chain,
55562
+ toToken: auto.toToken,
55563
+ amount: auto.amount
55564
+ });
55565
+ if (result.success) {
55566
+ await automationStore.update(auto.id, { active: false, lastRunAt: (/* @__PURE__ */ new Date()).toISOString() });
55567
+ success(`[${ts3()}] Limit order executed: ${result.explorerUrl}`);
55568
+ tickResults.automations.executed.push({ id: auto.id, type: "limit", txHash: result.txHash, explorer: result.explorerUrl });
55569
+ } else {
55570
+ warn(`[${ts3()}] Limit order ${auto.id} failed: ${result.error}`);
55571
+ }
55572
+ }
55573
+ } catch (err) {
55574
+ warn(`[${ts3()}] Automation ${auto.id} failed: ${err instanceof Error ? err.message : String(err)}`);
55575
+ }
55576
+ }
55577
+ } catch (err) {
55578
+ error(`[${ts3()}] Tick error: ${err instanceof Error ? err.message : String(err)}`);
55579
+ }
55580
+ if (opts.json) {
55581
+ output({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...tickResults }, true);
55582
+ } else if (tickResults.alerts.triggered.length === 0 && tickResults.automations.executed.length === 0) {
55583
+ dim(`[${ts3()}] Checked ${tickResults.alerts.checked} alerts, ${tickResults.automations.skipped} automations \u2014 nothing to do`);
55584
+ }
55585
+ };
55586
+ await tick();
55587
+ const timer = setInterval(tick, intervalSec * 1e3);
55588
+ const shutdown = () => {
55589
+ clearInterval(timer);
55590
+ if (provider) {
55591
+ provider.disconnect().catch(() => {
55592
+ });
55593
+ }
55594
+ info(`
55595
+ [${ts3()}] Watcher stopped`);
55596
+ process.exit(0);
55597
+ };
55598
+ process.on("SIGINT", shutdown);
55599
+ process.on("SIGTERM", shutdown);
55600
+ await new Promise(() => {
55601
+ });
55602
+ });
55603
+ }
55604
+
54878
55605
  // src/index.ts
54879
55606
  var VERSION2 = package_default.version;
54880
55607
  var program2 = new Command();
@@ -54891,9 +55618,11 @@ registerErc20Command(program2);
54891
55618
  registerAlertCommand(program2);
54892
55619
  registerQueryCommand(program2);
54893
55620
  registerServeCommand(program2);
55621
+ registerAutomateCommand(program2);
54894
55622
  registerSkillCommand(program2);
54895
55623
  registerX402Command(program2);
54896
55624
  registerTelemetryCommand(program2);
55625
+ registerWatchCommand(program2);
54897
55626
  initAnalytics();
54898
55627
  program2.hook("preAction", (_thisCommand, actionCommand) => {
54899
55628
  trackEvent("twak_command", { command: actionCommand.name() });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustwallet/cli",
3
- "version": "0.6.11",
3
+ "version": "0.7.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",
@@ -27,17 +27,17 @@
27
27
  "ora": "5.4.1",
28
28
  "tsup": "8.5.1",
29
29
  "typescript": "5.7.3",
30
- "@twak/core": "0.6.11",
31
- "@twak/mcp": "0.6.11",
32
- "@twak/security": "0.6.11",
33
- "@twak/storage": "0.6.11",
34
- "@twak/actions": "0.6.11",
35
- "@twak/swap": "0.6.11",
36
- "@twak/transactions": "0.6.11",
37
- "@twak/wallet": "0.6.11",
38
- "@twak/wallet-core": "0.6.11",
39
- "@twak/blockchain": "0.6.11",
40
- "@twak/walletconnect": "0.6.11"
30
+ "@twak/blockchain": "0.7.0",
31
+ "@twak/core": "0.7.0",
32
+ "@twak/mcp": "0.7.0",
33
+ "@twak/security": "0.7.0",
34
+ "@twak/storage": "0.7.0",
35
+ "@twak/swap": "0.7.0",
36
+ "@twak/transactions": "0.7.0",
37
+ "@twak/wallet": "0.7.0",
38
+ "@twak/wallet-core": "0.7.0",
39
+ "@twak/actions": "0.7.0",
40
+ "@twak/walletconnect": "0.7.0"
41
41
  },
42
42
  "publishConfig": {
43
43
  "access": "public"