@trustwallet/cli 0.24.1 → 0.24.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.
@@ -1 +1 @@
1
- {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0FpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAumB5D"}
1
+ {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0FpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+mB5D"}
package/dist/index.js CHANGED
@@ -4191,7 +4191,13 @@ var init_dist = __esm({
4191
4191
  USER_REJECTED: "USER_REJECTED",
4192
4192
  // The connected wallet answered a WalletConnect request with an error other
4193
4193
  // than a user rejection (e.g. unsupported method, invalid params).
4194
- WC_REQUEST_FAILED: "WC_REQUEST_FAILED"
4194
+ WC_REQUEST_FAILED: "WC_REQUEST_FAILED",
4195
+ // A WalletConnect pairing expired before the user approved it in their
4196
+ // wallet. Actionable: start a new pairing if the user still wants to.
4197
+ WC_PAIRING_EXPIRED: "WC_PAIRING_EXPIRED",
4198
+ // A WalletConnect pairing could not be started or ended with an error other
4199
+ // than a user rejection or an expiry (relay failure, wallet error).
4200
+ WC_PAIRING_FAILED: "WC_PAIRING_FAILED"
4195
4201
  };
4196
4202
  WalletError = class extends CommandError {
4197
4203
  constructor(code2, message) {
@@ -6433,6 +6439,7 @@ var dist_exports = {};
6433
6439
  __export(dist_exports, {
6434
6440
  AgentWalletProvider: () => AgentWalletProvider,
6435
6441
  ChainClient: () => ChainClient,
6442
+ PAIRING_FAILURE_CODES: () => PAIRING_FAILURE_CODES,
6436
6443
  TeeWalletProvider: () => TeeWalletProvider,
6437
6444
  VerifyCredentialsError: () => VerifyCredentialsError,
6438
6445
  WalletContext: () => WalletContext,
@@ -7281,7 +7288,7 @@ function registerShutdownHandlers(providers, onBeforeExit) {
7281
7288
  process.removeListener("SIGTERM", handler);
7282
7289
  };
7283
7290
  }
7284
- var fs2, path3, import_trust_sdk, import_trust_sdk2, import_trust_sdk3, import_trust_sdk4, import_trust_sdk5, import_crypto2, __require, polyfillsApplied, _credentials, _naasSessionId, nodeStubsPatched, sponsorNonceByAddress, NAAS_SESSION_RE, naasSessionPatched, coinTypeByValue, walletCore, initialized, BSC_COIN_ID, DEFAULT_BSC_SPONSORED_RPC, SPONSOR_PRECHECK_TIMEOUT_MS, SPONSOR_USER_AGENT, RPC_TIMEOUT_MS, RECEIPT_POLL_INTERVAL_MS, RECEIPT_DEFAULT_TIMEOUT_MS, ChainClient, SigningChainClient, WalletCoreSigner, domainsByCoinId, GATEWAY_URL, DEVICE_INFO_BODY, VerifyCredentialsError, WALLET_ID_SUFFIX, WALLET_ID_LENGTH, EVM_COIN_IDS, MAINTAINED_COIN_IDS, WalletProvider, AgentWalletProvider, ETHEREUM, TeeWalletProvider, WalletContext, SHUTDOWN_TIMEOUT_MS;
7291
+ var fs2, path3, import_trust_sdk, import_trust_sdk2, import_trust_sdk3, import_trust_sdk4, import_trust_sdk5, import_crypto2, __require, polyfillsApplied, _credentials, _naasSessionId, nodeStubsPatched, sponsorNonceByAddress, NAAS_SESSION_RE, naasSessionPatched, coinTypeByValue, walletCore, initialized, BSC_COIN_ID, DEFAULT_BSC_SPONSORED_RPC, SPONSOR_PRECHECK_TIMEOUT_MS, SPONSOR_USER_AGENT, RPC_TIMEOUT_MS, RECEIPT_POLL_INTERVAL_MS, RECEIPT_DEFAULT_TIMEOUT_MS, ChainClient, SigningChainClient, WalletCoreSigner, domainsByCoinId, GATEWAY_URL, DEVICE_INFO_BODY, VerifyCredentialsError, WALLET_ID_SUFFIX, WALLET_ID_LENGTH, EVM_COIN_IDS, MAINTAINED_COIN_IDS, WalletProvider, AgentWalletProvider, ETHEREUM, TeeWalletProvider, PAIRING_FAILURE_CODES, WalletContext, SHUTDOWN_TIMEOUT_MS;
7285
7292
  var init_dist3 = __esm({
7286
7293
  "../wallet-core/dist/index.mjs"() {
7287
7294
  "use strict";
@@ -8428,6 +8435,11 @@ var init_dist3 = __esm({
8428
8435
  return this.address !== null;
8429
8436
  }
8430
8437
  };
8438
+ PAIRING_FAILURE_CODES = {
8439
+ rejected: "USER_REJECTED",
8440
+ expired: "WC_PAIRING_EXPIRED",
8441
+ failed: "WC_PAIRING_FAILED"
8442
+ };
8431
8443
  WalletContext = class {
8432
8444
  _state = "unbound";
8433
8445
  _wallet;
@@ -8481,6 +8493,24 @@ var init_dist3 = __esm({
8481
8493
  this._state = "wc-connected";
8482
8494
  this._pairing = void 0;
8483
8495
  }
8496
+ /** End the pending pairing: back to `unbound`, with the reason in
8497
+ * `lastError`. Only reacts while pairing; the provider already ignores a
8498
+ * pairing that a newer one or a mode switch superseded. */
8499
+ handlePairingFailed(failure) {
8500
+ if (this._state !== "wc-pairing") return;
8501
+ this._pairing = void 0;
8502
+ this._state = "unbound";
8503
+ this._lastError = { code: PAIRING_FAILURE_CODES[failure.reason], message: failure.message };
8504
+ }
8505
+ /** Whether a pairing is pending. A method, so callers re-read the state
8506
+ * after an await during which a provider callback may have changed it. */
8507
+ isPairing() {
8508
+ return this._state === "wc-pairing";
8509
+ }
8510
+ /** Why the pairing ended, when it failed during an await (see isPairing). */
8511
+ pairingFailedMeanwhile() {
8512
+ return this._state === "unbound" ? this._lastError : void 0;
8513
+ }
8484
8514
  /** The process's single WC provider, created on first use. */
8485
8515
  walletConnect() {
8486
8516
  if (this._wc) return this._wc;
@@ -8493,6 +8523,7 @@ var init_dist3 = __esm({
8493
8523
  const wc3 = this._walletConnectFactory();
8494
8524
  wc3.onSessionEstablished((session) => this.handleSessionEstablished(session));
8495
8525
  wc3.onSessionEnded((reason) => this.handleSessionEnded(reason));
8526
+ wc3.onPairingFailed((failure) => this.handlePairingFailed(failure));
8496
8527
  this._wc = wc3;
8497
8528
  return wc3;
8498
8529
  }
@@ -8593,8 +8624,14 @@ var init_dist3 = __esm({
8593
8624
  const wc3 = this.walletConnect();
8594
8625
  this._generation++;
8595
8626
  await this.disconnectWcIfAny();
8627
+ this._wallet = void 0;
8628
+ this._pairing = void 0;
8629
+ this._peerName = void 0;
8630
+ this._state = "wc-pairing";
8631
+ this._lastError = void 0;
8632
+ let pairing;
8596
8633
  try {
8597
- this._pairing = await wc3.connect(chainKeys);
8634
+ pairing = await wc3.connect(chainKeys);
8598
8635
  } catch (err) {
8599
8636
  this._wallet = void 0;
8600
8637
  this._pairing = void 0;
@@ -8606,11 +8643,15 @@ var init_dist3 = __esm({
8606
8643
  };
8607
8644
  throw err;
8608
8645
  }
8609
- this._wallet = void 0;
8610
- this._state = "wc-pairing";
8611
- this._lastError = void 0;
8612
- this._peerName = void 0;
8613
- return this.snapshot().pairing;
8646
+ const ended = this.pairingFailedMeanwhile();
8647
+ if (ended) throw new WalletError(ended.code, ended.message);
8648
+ if (this.isPairing()) this._pairing = pairing;
8649
+ return {
8650
+ uri: pairing.uri,
8651
+ deepLink: pairing.deepLinks.universal,
8652
+ qrCodeImageUrl: pairing.qrCode.imageUrl,
8653
+ expiresAt: pairing.expiresAt
8654
+ };
8614
8655
  }
8615
8656
  /**
8616
8657
  * Bind the WC session persisted by a previous process, if any. Returns
@@ -41651,6 +41692,24 @@ function isUserRejection(code2, message) {
41651
41692
  if (USER_REJECTION_CODES.has(code2)) return true;
41652
41693
  return code2 === GENERIC_SERVER_ERROR_CODE && USER_REJECTION_MESSAGE_RE.test(message);
41653
41694
  }
41695
+ var PAIRING_TTL_MS = 5 * 60 * 1e3;
41696
+ function classifyPairingFailure(err, expiresAt) {
41697
+ if (Date.now() >= expiresAt) {
41698
+ return {
41699
+ reason: "expired",
41700
+ message: "The WalletConnect pairing expired before it was approved in the wallet."
41701
+ };
41702
+ }
41703
+ const { code: code2, message } = err && typeof err === "object" ? err : {};
41704
+ const text = typeof message === "string" ? message : errorMessage(err);
41705
+ if (typeof code2 === "number" && isUserRejection(code2, text)) {
41706
+ return { reason: "rejected", message: `The pairing was rejected in the wallet: ${text}` };
41707
+ }
41708
+ return {
41709
+ reason: "failed",
41710
+ message: `WalletConnect pairing failed: ${text}${typeof code2 === "number" ? ` (code ${code2})` : ""}`
41711
+ };
41712
+ }
41654
41713
  function toRequestError(err) {
41655
41714
  if (err instanceof Error || !err || typeof err !== "object") return err;
41656
41715
  const { code: code2, message } = err;
@@ -41685,6 +41744,9 @@ var WalletConnectProvider = class extends WalletProvider {
41685
41744
  pairingGeneration = 0;
41686
41745
  sessionCallback = null;
41687
41746
  sessionEndedCallback = null;
41747
+ pairingFailedCallback = null;
41748
+ /** How the current pairing ended without a session, if it did. */
41749
+ pairingFailure = null;
41688
41750
  pairingEventCallback = null;
41689
41751
  constructor(config) {
41690
41752
  super();
@@ -41757,6 +41819,14 @@ var WalletConnectProvider = class extends WalletProvider {
41757
41819
  onSessionEnded(callback) {
41758
41820
  this.sessionEndedCallback = callback;
41759
41821
  }
41822
+ /**
41823
+ * Register a callback for when the current pairing ends without a session:
41824
+ * rejected in the wallet, expired, or failed. Not called for a pairing that
41825
+ * a newer pairing or a disconnect superseded.
41826
+ */
41827
+ onPairingFailed(callback) {
41828
+ this.pairingFailedCallback = callback;
41829
+ }
41760
41830
  /**
41761
41831
  * Returns the WC account to use as the `from` field for a signing request
41762
41832
  * on CAIP-2 chain `caip2`. EVM-only: throws `CHAIN_UNSUPPORTED` if it isn't
@@ -41928,6 +41998,7 @@ var WalletConnectProvider = class extends WalletProvider {
41928
41998
  const chains = chainKeys.map(caip2Of);
41929
41999
  const client = await this.ensureClient();
41930
42000
  const generation = ++this.pairingGeneration;
42001
+ this.pairingFailure = null;
41931
42002
  for (const session of client.session.getAll()) {
41932
42003
  await this.revokeSession(client, session.topic);
41933
42004
  }
@@ -41946,6 +42017,7 @@ var WalletConnectProvider = class extends WalletProvider {
41946
42017
  events: getNamespaceEvents(ns2)
41947
42018
  };
41948
42019
  }
42020
+ const expiresAt = Date.now() + PAIRING_TTL_MS;
41949
42021
  const { uri, approval } = await client.connect({ optionalNamespaces });
41950
42022
  if (!uri) {
41951
42023
  throw new WalletError(
@@ -41953,7 +42025,7 @@ var WalletConnectProvider = class extends WalletProvider {
41953
42025
  "WalletConnect relay handshake failed: no pairing URI returned. Check network and project ID, then retry."
41954
42026
  );
41955
42027
  }
41956
- this.handleApproval(approval(), generation);
42028
+ this.handleApproval(approval(), generation, expiresAt);
41957
42029
  const encodedUri = encodeURIComponent(uri);
41958
42030
  const terminal = renderTerminalQR(uri);
41959
42031
  const imageUrl = await renderPngDataUrl(uri);
@@ -41967,12 +42039,20 @@ var WalletConnectProvider = class extends WalletProvider {
41967
42039
  terminal,
41968
42040
  imageUrl
41969
42041
  },
41970
- expiresAt: Date.now() + 5 * 60 * 1e3
42042
+ expiresAt
41971
42043
  };
41972
42044
  }
41973
- async handleApproval(approval, generation) {
42045
+ async handleApproval(approval, generation, expiresAt) {
42046
+ let session;
42047
+ try {
42048
+ session = await approval;
42049
+ } catch (err) {
42050
+ if (generation !== this.pairingGeneration) return;
42051
+ this.pairingFailure = classifyPairingFailure(err, expiresAt);
42052
+ this.pairingFailedCallback?.(this.pairingFailure);
42053
+ return;
42054
+ }
41974
42055
  try {
41975
- const session = await approval;
41976
42056
  if (generation !== this.pairingGeneration) {
41977
42057
  if (this.client) await this.revokeSession(this.client, session.topic);
41978
42058
  return;
@@ -41985,23 +42065,36 @@ var WalletConnectProvider = class extends WalletProvider {
41985
42065
  }
41986
42066
  }
41987
42067
  /**
41988
- * Block until a WC session is established, or throw on timeout.
42068
+ * Block until a WC session is established. Throws as soon as the pending
42069
+ * pairing ends without one (USER_REJECTED, WC_PAIRING_EXPIRED,
42070
+ * WC_PAIRING_FAILED), or WC_NOT_CONNECTED on timeout.
41989
42071
  *
41990
42072
  * Used by the CLI's `twak wallet connect` command (a terminal-blocking flow).
41991
42073
  * Not used by the MCP action path, which follows a "next action errors with
41992
42074
  * WC_NOT_CONNECTED" pattern to avoid blocking tool calls.
41993
42075
  */
41994
42076
  async waitForSession(timeoutMs = 3e5) {
41995
- const start = Date.now();
41996
- while (Date.now() - start < timeoutMs) {
42077
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
42078
+ throw new WalletError("VALIDATION_ERROR", `Invalid timeout: ${timeoutMs} ms.`);
42079
+ }
42080
+ const deadline = Date.now() + timeoutMs;
42081
+ for (; ; ) {
41997
42082
  const session = this.getActiveSession();
41998
42083
  if (session) return session;
42084
+ if (this.pairingFailure) {
42085
+ throw new WalletError(
42086
+ PAIRING_FAILURE_CODES[this.pairingFailure.reason],
42087
+ this.pairingFailure.message
42088
+ );
42089
+ }
42090
+ if (Date.now() >= deadline) {
42091
+ throw new WalletError(
42092
+ "WC_NOT_CONNECTED",
42093
+ `Timed out after ${Math.round(timeoutMs / 1e3)}s waiting for WalletConnect pairing approval.`
42094
+ );
42095
+ }
41999
42096
  await new Promise((r3) => setTimeout(r3, 500));
42000
42097
  }
42001
- throw new WalletError(
42002
- "WC_NOT_CONNECTED",
42003
- `Timed out after ${Math.round(timeoutMs / 1e3)}s waiting for WalletConnect pairing approval.`
42004
- );
42005
42098
  }
42006
42099
  /**
42007
42100
  * Revokes every stored session. Waits for an in-flight client init (e.g. a
@@ -42010,6 +42103,7 @@ var WalletConnectProvider = class extends WalletProvider {
42010
42103
  */
42011
42104
  async disconnect() {
42012
42105
  this.pairingGeneration++;
42106
+ this.pairingFailure = null;
42013
42107
  let client = this.client;
42014
42108
  if (!client && this.initPromise) {
42015
42109
  try {
@@ -44130,9 +44224,16 @@ ${qr3}`;
44130
44224
  "Comma-separated chains: keys, aliases or CAIP-2 IDs (default: all supported EVM chains)"
44131
44225
  ).option("--timeout <seconds>", "Connection timeout in seconds", "300").option("--json", "JSON output").action(async (opts) => {
44132
44226
  try {
44227
+ const timeoutSec = Number(opts.timeout);
44228
+ if (!Number.isInteger(timeoutSec) || timeoutSec <= 0) {
44229
+ throw new WalletError(
44230
+ "VALIDATION_ERROR",
44231
+ `--timeout must be a positive whole number of seconds (got "${opts.timeout}").`
44232
+ );
44233
+ }
44234
+ const chainKeys = opts.chains ? parseChainList(opts.chains) : void 0;
44133
44235
  const projectId = await resolveWcProjectId(opts.projectId);
44134
44236
  const provider = createWalletConnectProvider(projectId, new ChainClient());
44135
- const chainKeys = opts.chains ? parseChainList(opts.chains) : void 0;
44136
44237
  info("Connecting via WalletConnect...");
44137
44238
  const result = await provider.connect(chainKeys);
44138
44239
  const qr3 = getQRString(result.uri);
@@ -44142,8 +44243,7 @@ ${qr3}`;
44142
44243
  info(`Trust Wallet: ${result.deepLinks.native}`);
44143
44244
  info(`Universal: ${result.deepLinks.universal}`);
44144
44245
  info("\nWaiting for wallet approval...");
44145
- const timeoutMs = parseInt(opts.timeout, 10) * 1e3;
44146
- const session = await provider.waitForSession(timeoutMs);
44246
+ const session = await provider.waitForSession(timeoutSec * 1e3);
44147
44247
  if (opts.json) {
44148
44248
  output(
44149
44249
  {
@@ -49467,18 +49567,19 @@ var WalletModeActionProvider = class extends ActionProvider {
49467
49567
  return [this.switchWalletMode(), this.getWalletStatus()];
49468
49568
  }
49469
49569
  /**
49470
- * Builds the MCP response for a snapshot. When state is `wc-pairing` and
49471
- * a QR code is available, emits a text block + an image block so MCP
49472
- * clients (Claude Desktop etc.) render the QR inline. For other states,
49473
- * emits a single text block with the JSON snapshot.
49570
+ * Builds the MCP response for a snapshot: a text block with the JSON
49571
+ * snapshot, plus, when `includeQr` is set and a pairing is pending, an
49572
+ * image block so MCP clients (Claude Desktop etc.) render the QR inline.
49573
+ * The image is opt-in because agents poll the status while pairing: a QR
49574
+ * on every poll would fill their context with copies of the same image.
49474
49575
  */
49475
- snapshotResponse(snapshot) {
49576
+ snapshotResponse(snapshot, { includeQr }) {
49476
49577
  const textPayload = {
49477
49578
  ...snapshot.pairing ? { ...snapshot, pairing: { ...snapshot.pairing, qrCodeImageUrl: void 0 } } : snapshot,
49478
49579
  twakHome: twakHome()
49479
49580
  };
49480
49581
  const content = [{ type: "text", text: JSON.stringify(textPayload, null, 2) }];
49481
- if (snapshot.pairing?.qrCodeImageUrl) {
49582
+ if (includeQr && snapshot.pairing?.qrCodeImageUrl) {
49482
49583
  const match = snapshot.pairing.qrCodeImageUrl.match(/^data:(image\/[^;]+);base64,(.+)$/);
49483
49584
  if (match) {
49484
49585
  const [, mimeType, base642] = match;
@@ -49490,7 +49591,7 @@ var WalletModeActionProvider = class extends ActionProvider {
49490
49591
  switchWalletMode() {
49491
49592
  return {
49492
49593
  name: "switch_wallet_mode",
49493
- description: 'Switch the active wallet mode for this MCP server session. IMPORTANT: the LOCAL agent wallet is auto-bound at server startup when one is configured, so most users do NOT need to call this \u2014 signing actions just work. Call this ONLY when the user explicitly asks to switch. Two flows: (a) user wants to sign on their phone via Trust Wallet (or any WC-compatible wallet) \u2192 mode="walletconnect"; (b) user wants to switch back from WalletConnect to the local wallet \u2192 mode="local". \n\nDISCOVERABILITY: most users do not know WalletConnect is an option. When the user first asks about wallet operations or signing in a fresh conversation, briefly mention that they can optionally switch to signing via Trust Wallet on their phone (more secure: keys never leave their device) by saying so \u2014 then call switch_wallet_mode if they opt in. Do not push it on every signing call; just surface it once early on or when the user expresses security concerns.\n\nFor mode="walletconnect": returns a pairing payload (URI, mobile deep link, inline QR image). Surface the QR to the user, then poll get_wallet_status until state="wc-connected" before retrying any signing action. Do NOT call switch_wallet_mode while a signing action is in flight: switching disconnects the prior WC relay session, which can break the in-flight signature; wait for the current action to settle before changing modes.',
49594
+ description: 'Switch the active wallet mode for this MCP server session. IMPORTANT: the LOCAL agent wallet is auto-bound at server startup when one is configured, so most users do NOT need to call this \u2014 signing actions just work. Call this ONLY when the user explicitly asks to switch. Two flows: (a) user wants to sign on their phone via Trust Wallet (or any WC-compatible wallet) \u2192 mode="walletconnect"; (b) user wants to switch back from WalletConnect to the local wallet \u2192 mode="local". \n\nDISCOVERABILITY: most users do not know WalletConnect is an option. When the user first asks about wallet operations or signing in a fresh conversation, briefly mention that they can optionally switch to signing via Trust Wallet on their phone (more secure: keys never leave their device) by saying so \u2014 then call switch_wallet_mode if they opt in. Do not push it on every signing call; just surface it once early on or when the user expresses security concerns.\n\nFor mode="walletconnect": returns a pairing payload (URI, mobile deep link, inline QR image). Surface the QR to the user, then poll get_wallet_status every few seconds until state leaves "wc-pairing": "wc-connected" means the user approved; "unbound" means the pairing ended, and lastError says why (USER_REJECTED, WC_PAIRING_EXPIRED after about 5 minutes, or WC_PAIRING_FAILED). Do not retry a signing action before "wc-connected". Do NOT call switch_wallet_mode while a signing action is in flight: switching disconnects the prior WC relay session, which can break the in-flight signature; wait for the current action to settle before changing modes.',
49494
49595
  schema: import_zod15.z.object({
49495
49596
  mode: import_zod15.z.enum(["local", "walletconnect"]).describe(
49496
49597
  '"local" for the on-disk agent wallet, "walletconnect" to pair a remote wallet'
@@ -49500,7 +49601,7 @@ var WalletModeActionProvider = class extends ActionProvider {
49500
49601
  if (input2.mode === "local") {
49501
49602
  const agentWallet = await this.agentWallet();
49502
49603
  await this.walletContext.bindLocal(agentWallet);
49503
- return this.snapshotResponse(this.walletContext.snapshot());
49604
+ return this.snapshotResponse(this.walletContext.snapshot(), { includeQr: true });
49504
49605
  }
49505
49606
  if (!this.walletContext.walletConnectAvailable) {
49506
49607
  throw new WalletError(
@@ -49509,16 +49610,20 @@ var WalletModeActionProvider = class extends ActionProvider {
49509
49610
  );
49510
49611
  }
49511
49612
  await this.walletContext.beginWalletConnect();
49512
- return this.snapshotResponse(this.walletContext.snapshot());
49613
+ return this.snapshotResponse(this.walletContext.snapshot(), { includeQr: true });
49513
49614
  }
49514
49615
  };
49515
49616
  }
49516
49617
  getWalletStatus() {
49517
49618
  return {
49518
49619
  name: "get_wallet_status",
49519
- description: 'Returns the current wallet binding for this MCP server session: state ("unbound" | "local" | "wc-pairing" | "wc-connected"), wallet type (when bound), peer name (when wc-connected), pairing data (URI / deep link / QR code, when state="wc-pairing"), and `twakHome`: the folder this server keeps its files in (wallet, WalletConnect session, credentials), set from TWAK_HOME when the server started (default ~/.twak). When state="wc-pairing", the response includes an inline QR-code image (MCP image content), a mobile deep link (`pairing.deepLink`) for users on their phone, and the raw `pairing.uri` as a copyable string for advanced users. Poll this after switch_wallet_mode({mode: "walletconnect"}) until state transitions to "wc-connected"; that\'s when signing actions become usable. If the user asks to see the QR code again (e.g. "show me the QR", "I can\'t see it"), call this action again \u2014 every call while state="wc-pairing" re-emits the inline QR image. Do NOT try to render the QR yourself from the URI or the response JSON.',
49520
- schema: import_zod15.z.object({}),
49521
- invoke: async () => this.snapshotResponse(this.walletContext.snapshot())
49620
+ description: 'Returns the current wallet binding for this MCP server session: state ("unbound" | "local" | "wc-pairing" | "wc-connected"), wallet type (when bound), peer name (when wc-connected), pairing data (URI / deep link / expiry, when state="wc-pairing"), `lastError` (why the wallet went away or a pairing ended), and `twakHome`: the folder this server keeps its files in (wallet, WalletConnect session, credentials), set from TWAK_HOME when the server started (default ~/.twak). After switch_wallet_mode({mode: "walletconnect"}), poll this every few seconds until state leaves "wc-pairing": "wc-connected" means the user approved and signing actions are usable; "unbound" means the pairing ended without a session, and lastError.code says why: USER_REJECTED (declined in the wallet), WC_PAIRING_EXPIRED (not approved within about 5 minutes) or WC_PAIRING_FAILED. Ask the user before starting a new pairing. While pairing, the response carries `pairing.deepLink` (tap on a phone) and the raw `pairing.uri`. The QR image is returned only with showQr=true: pass it when the user asks to see the QR again (e.g. "show me the QR", "I can\'t see it"), not when polling. Do NOT try to render the QR yourself from the URI or the response JSON.',
49621
+ schema: import_zod15.z.object({
49622
+ showQr: import_zod15.z.boolean().optional().describe(
49623
+ 'Include the pairing QR image (only while state="wc-pairing"). Only when the user asks to see it again.'
49624
+ )
49625
+ }),
49626
+ invoke: async (_ctx, input2) => this.snapshotResponse(this.walletContext.snapshot(), { includeQr: input2.showQr === true })
49522
49627
  };
49523
49628
  }
49524
49629
  };
@@ -56214,7 +56319,7 @@ init_dist();
56214
56319
  // package.json
56215
56320
  var package_default = {
56216
56321
  name: "@trustwallet/cli",
56217
- version: "0.24.1",
56322
+ version: "0.24.3",
56218
56323
  description: "TWAK CLI \u2014 command-line interface for Trust Wallet Agent Kit",
56219
56324
  main: "dist/index.js",
56220
56325
  types: "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustwallet/cli",
3
- "version": "0.24.1",
3
+ "version": "0.24.3",
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",
@@ -33,19 +33,19 @@
33
33
  "tsup": "8.5.1",
34
34
  "typescript": "5.7.3",
35
35
  "vitest": "4.1.2",
36
- "@twak/actions": "0.24.1",
37
- "@twak/mcp": "0.24.1",
38
- "@twak/operations": "0.24.1",
39
- "@twak/security": "0.24.1",
40
- "@twak/storage": "0.24.1",
41
- "@twak/swap": "0.24.1",
42
- "@twak/transactions": "0.24.1",
43
- "@twak/wallet": "0.24.1",
44
- "@twak/core": "0.24.1",
45
- "@twak/contracts": "0.24.1",
46
- "@twak/walletconnect": "0.24.1",
47
- "@twak/x402": "0.24.1",
48
- "@twak/wallet-core": "0.24.1"
36
+ "@twak/actions": "0.24.3",
37
+ "@twak/core": "0.24.3",
38
+ "@twak/mcp": "0.24.3",
39
+ "@twak/operations": "0.24.3",
40
+ "@twak/security": "0.24.3",
41
+ "@twak/storage": "0.24.3",
42
+ "@twak/transactions": "0.24.3",
43
+ "@twak/swap": "0.24.3",
44
+ "@twak/wallet": "0.24.3",
45
+ "@twak/wallet-core": "0.24.3",
46
+ "@twak/x402": "0.24.3",
47
+ "@twak/walletconnect": "0.24.3",
48
+ "@twak/contracts": "0.24.3"
49
49
  },
50
50
  "publishConfig": {
51
51
  "access": "public"