@trustwallet/cli 0.24.1 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/wallet.d.ts.map +1 -1
- package/dist/index.js +139 -34
- package/package.json +14 -14
|
@@ -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,
|
|
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,CA6mB5D"}
|
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
|
-
|
|
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
|
-
|
|
8610
|
-
|
|
8611
|
-
this.
|
|
8612
|
-
|
|
8613
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
41996
|
-
|
|
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 {
|
|
@@ -44142,8 +44236,14 @@ ${qr3}`;
|
|
|
44142
44236
|
info(`Trust Wallet: ${result.deepLinks.native}`);
|
|
44143
44237
|
info(`Universal: ${result.deepLinks.universal}`);
|
|
44144
44238
|
info("\nWaiting for wallet approval...");
|
|
44145
|
-
const
|
|
44146
|
-
|
|
44239
|
+
const timeoutSec = Number(opts.timeout);
|
|
44240
|
+
if (!Number.isInteger(timeoutSec) || timeoutSec <= 0) {
|
|
44241
|
+
throw new WalletError(
|
|
44242
|
+
"VALIDATION_ERROR",
|
|
44243
|
+
`--timeout must be a positive whole number of seconds (got "${opts.timeout}").`
|
|
44244
|
+
);
|
|
44245
|
+
}
|
|
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
|
|
49471
|
-
*
|
|
49472
|
-
* clients (Claude Desktop etc.) render the QR inline.
|
|
49473
|
-
*
|
|
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
|
|
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 /
|
|
49520
|
-
schema: import_zod15.z.object({
|
|
49521
|
-
|
|
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.
|
|
56322
|
+
version: "0.24.2",
|
|
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.
|
|
3
|
+
"version": "0.24.2",
|
|
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.
|
|
37
|
-
"@twak/
|
|
38
|
-
"@twak/operations": "0.24.
|
|
39
|
-
"@twak/security": "0.24.
|
|
40
|
-
"@twak/storage": "0.24.
|
|
41
|
-
"@twak/
|
|
42
|
-
"@twak/
|
|
43
|
-
"@twak/wallet": "0.24.
|
|
44
|
-
"@twak/
|
|
45
|
-
"@twak/
|
|
46
|
-
"@twak/
|
|
47
|
-
"@twak/
|
|
48
|
-
"@twak/
|
|
36
|
+
"@twak/actions": "0.24.2",
|
|
37
|
+
"@twak/core": "0.24.2",
|
|
38
|
+
"@twak/operations": "0.24.2",
|
|
39
|
+
"@twak/security": "0.24.2",
|
|
40
|
+
"@twak/storage": "0.24.2",
|
|
41
|
+
"@twak/transactions": "0.24.2",
|
|
42
|
+
"@twak/wallet": "0.24.2",
|
|
43
|
+
"@twak/wallet-core": "0.24.2",
|
|
44
|
+
"@twak/walletconnect": "0.24.2",
|
|
45
|
+
"@twak/swap": "0.24.2",
|
|
46
|
+
"@twak/x402": "0.24.2",
|
|
47
|
+
"@twak/contracts": "0.24.2",
|
|
48
|
+
"@twak/mcp": "0.24.2"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|