@enclave-hq/wallet-sdk 1.2.4 → 1.2.7

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/tron.mjs ADDED
@@ -0,0 +1,846 @@
1
+ import { WalletConnectChainID, WalletConnectWallet } from '@tronweb3/walletconnect-tron';
2
+ import EventEmitter from 'eventemitter3';
3
+ import { ChainType as ChainType$1 } from '@enclave-hq/chain-utils';
4
+
5
+ // src/adapters/tron/wallet-connect.ts
6
+ var ChainType = ChainType$1;
7
+
8
+ // src/core/errors.ts
9
+ var WalletSDKError = class _WalletSDKError extends Error {
10
+ constructor(message, code, details) {
11
+ super(message);
12
+ this.code = code;
13
+ this.details = details;
14
+ this.name = "WalletSDKError";
15
+ Object.setPrototypeOf(this, _WalletSDKError.prototype);
16
+ }
17
+ };
18
+ var WalletNotConnectedError = class extends WalletSDKError {
19
+ constructor(walletType) {
20
+ super(
21
+ walletType ? `Wallet ${walletType} is not connected` : "No wallet is connected",
22
+ "WALLET_NOT_CONNECTED",
23
+ { walletType }
24
+ );
25
+ this.name = "WalletNotConnectedError";
26
+ }
27
+ };
28
+ var ConnectionRejectedError = class extends WalletSDKError {
29
+ constructor(walletType) {
30
+ super(
31
+ `Connection to ${walletType} was rejected by user`,
32
+ "CONNECTION_REJECTED",
33
+ { walletType }
34
+ );
35
+ this.name = "ConnectionRejectedError";
36
+ }
37
+ };
38
+ var SignatureRejectedError = class extends WalletSDKError {
39
+ constructor(message) {
40
+ super(
41
+ message || "Signature was rejected by user",
42
+ "SIGNATURE_REJECTED"
43
+ );
44
+ this.name = "SignatureRejectedError";
45
+ }
46
+ };
47
+ var MethodNotSupportedError = class extends WalletSDKError {
48
+ constructor(method, walletType) {
49
+ super(
50
+ `Method ${method} is not supported by ${walletType}`,
51
+ "METHOD_NOT_SUPPORTED",
52
+ { method, walletType }
53
+ );
54
+ this.name = "MethodNotSupportedError";
55
+ }
56
+ };
57
+ var ConfigurationError = class extends WalletSDKError {
58
+ constructor(message, details) {
59
+ super(message, "CONFIGURATION_ERROR", details);
60
+ this.name = "ConfigurationError";
61
+ }
62
+ };
63
+
64
+ // src/adapters/base/wallet-adapter.ts
65
+ var WalletAdapter = class extends EventEmitter {
66
+ constructor() {
67
+ super(...arguments);
68
+ // 状态
69
+ this.state = "disconnected" /* DISCONNECTED */;
70
+ this.currentAccount = null;
71
+ }
72
+ /**
73
+ * Check if the wallet is currently connected
74
+ * @returns true if the wallet is connected (state is CONNECTED and has an account)
75
+ */
76
+ isConnected() {
77
+ return this.state === "connected" /* CONNECTED */ && this.currentAccount !== null;
78
+ }
79
+ /**
80
+ * Get the signer's address (implements ISigner interface)
81
+ * Returns the native address of the current account
82
+ */
83
+ async getAddress() {
84
+ this.ensureConnected();
85
+ if (!this.currentAccount) {
86
+ throw new WalletNotConnectedError(this.type);
87
+ }
88
+ return this.currentAccount.nativeAddress;
89
+ }
90
+ signTransaction(_transaction) {
91
+ throw new MethodNotSupportedError("signTransaction", this.type);
92
+ }
93
+ signTypedData(_typedData) {
94
+ throw new MethodNotSupportedError("signTypedData", this.type);
95
+ }
96
+ // 链切换(默认不支持)
97
+ switchChain(_chainId) {
98
+ throw new MethodNotSupportedError("switchChain", this.type);
99
+ }
100
+ addChain(_chainConfig) {
101
+ throw new MethodNotSupportedError("addChain", this.type);
102
+ }
103
+ // 合约调用(默认不支持)
104
+ async readContract(_params) {
105
+ throw new MethodNotSupportedError("readContract", this.type);
106
+ }
107
+ async writeContract(_params) {
108
+ throw new MethodNotSupportedError("writeContract", this.type);
109
+ }
110
+ async estimateGas(_params) {
111
+ throw new MethodNotSupportedError("estimateGas", this.type);
112
+ }
113
+ async waitForTransaction(_txHash, _confirmations) {
114
+ throw new MethodNotSupportedError("waitForTransaction", this.type);
115
+ }
116
+ getSigner() {
117
+ throw new MethodNotSupportedError("getSigner", this.type);
118
+ }
119
+ // 工具方法
120
+ ensureConnected() {
121
+ if (this.state !== "connected" /* CONNECTED */ || !this.currentAccount) {
122
+ throw new WalletNotConnectedError(this.type);
123
+ }
124
+ }
125
+ setState(state) {
126
+ this.state = state;
127
+ }
128
+ setAccount(account) {
129
+ this.currentAccount = account;
130
+ }
131
+ emitAccountChanged(account) {
132
+ this.emit("accountChanged", account);
133
+ }
134
+ emitChainChanged(chainId) {
135
+ this.emit("chainChanged", chainId);
136
+ }
137
+ emitDisconnected() {
138
+ this.emit("disconnected");
139
+ }
140
+ emitError(error) {
141
+ this.emit("error", error);
142
+ }
143
+ // EventEmitter 方法(从 EventEmitter3 继承)
144
+ // removeAllListeners 已经由 EventEmitter 提供
145
+ };
146
+
147
+ // src/utils/address/universal-address.ts
148
+ function createUniversalAddress(chainId, address) {
149
+ return `${chainId}:${address}`;
150
+ }
151
+
152
+ // src/adapters/tron/wallet-connect.ts
153
+ var _WalletConnectTronAdapter = class _WalletConnectTronAdapter extends WalletAdapter {
154
+ constructor(projectId) {
155
+ super();
156
+ this.type = "walletconnect-tron" /* WALLETCONNECT_TRON */;
157
+ this.chainType = ChainType.TRON;
158
+ this.name = "WalletConnect (Tron)";
159
+ this.icon = "https://avatars.githubusercontent.com/u/37784886";
160
+ this.wallet = null;
161
+ this.currentAddress = null;
162
+ if (!projectId) {
163
+ throw new ConfigurationError("WalletConnect projectId is required");
164
+ }
165
+ this.projectId = projectId;
166
+ }
167
+ /**
168
+ * Check if WalletConnect is available
169
+ */
170
+ async isAvailable() {
171
+ return typeof window !== "undefined";
172
+ }
173
+ /**
174
+ * Check if running in Telegram environment (Mini App or Web)
175
+ * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
176
+ * provide window.Telegram.WebApp API, so they are treated the same way.
177
+ */
178
+ isTelegramMiniApp() {
179
+ if (typeof window === "undefined") return false;
180
+ const tg = window.Telegram?.WebApp;
181
+ if (!tg) return false;
182
+ const platform = tg.platform || "unknown";
183
+ console.log("[WalletConnect Tron] Telegram environment detected:", {
184
+ platform,
185
+ version: tg.version,
186
+ isMiniApp: platform !== "web",
187
+ // Mini App if not web platform
188
+ isWeb: platform === "web"
189
+ // Telegram Web if web platform
190
+ });
191
+ return true;
192
+ }
193
+ /**
194
+ * Restore session from existing wallet (for storage restoration)
195
+ */
196
+ async restoreSession(chainId) {
197
+ if (typeof window === "undefined") {
198
+ return null;
199
+ }
200
+ try {
201
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
202
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
203
+ this.initializeWallet(targetChainId);
204
+ }
205
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
206
+ if (!this.wallet) {
207
+ return null;
208
+ }
209
+ const status = await this.wallet.checkConnectStatus();
210
+ if (status && status.address) {
211
+ this.currentAddress = status.address;
212
+ const account = {
213
+ universalAddress: createUniversalAddress(targetChainId, status.address),
214
+ nativeAddress: status.address,
215
+ chainId: targetChainId,
216
+ chainType: ChainType.TRON,
217
+ isActive: true
218
+ };
219
+ this.setState("connected" /* CONNECTED */);
220
+ this.setAccount(account);
221
+ this.setupEventListeners();
222
+ return account;
223
+ }
224
+ return null;
225
+ } catch (error) {
226
+ console.debug("[WalletConnect Tron] Restore session failed:", error);
227
+ return null;
228
+ }
229
+ }
230
+ /**
231
+ * Initialize WalletConnect wallet instance
232
+ * @param chainId - Optional chain ID to determine network (default: Mainnet)
233
+ */
234
+ initializeWallet(chainId) {
235
+ if (_WalletConnectTronAdapter.walletInstance && _WalletConnectTronAdapter.walletProjectId === this.projectId) {
236
+ return;
237
+ }
238
+ let appUrl = "";
239
+ if (typeof window !== "undefined") {
240
+ try {
241
+ if (window.location && window.location.origin) {
242
+ appUrl = window.location.origin;
243
+ } else if (window.location && window.location.href) {
244
+ const url = new URL(window.location.href);
245
+ appUrl = url.origin;
246
+ }
247
+ } catch (error) {
248
+ console.warn("[WalletConnect Tron] Failed to get origin from window.location:", error);
249
+ }
250
+ if (appUrl && (appUrl.includes("serveo.net") || appUrl.includes("loca.lt") || appUrl.includes("ngrok.io") || appUrl.includes("ngrok-free.app") || appUrl.includes("cloudflared.io"))) {
251
+ console.log("[WalletConnect Tron] Detected tunnel service URL:", appUrl);
252
+ console.log("[WalletConnect Tron] \u26A0\uFE0F Make sure this URL is added to WalletConnect Cloud project allowlist");
253
+ }
254
+ if (!appUrl) {
255
+ const tg = window.Telegram?.WebApp;
256
+ if (tg && tg.initDataUnsafe?.start_param) {
257
+ appUrl = "https://enclave.network";
258
+ } else {
259
+ appUrl = "https://enclave.network";
260
+ }
261
+ }
262
+ } else {
263
+ appUrl = "https://enclave.network";
264
+ }
265
+ if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
266
+ appUrl = "https://enclave.network";
267
+ }
268
+ const icons = [
269
+ "https://walletconnect.com/walletconnect-logo.svg",
270
+ "https://avatars.githubusercontent.com/u/37784886"
271
+ // WalletConnect GitHub avatar
272
+ ];
273
+ let network = WalletConnectChainID.Mainnet;
274
+ if (chainId !== void 0) {
275
+ if (chainId === 195 || chainId === _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID) {
276
+ network = WalletConnectChainID.Mainnet;
277
+ } else if (chainId === 201910292) {
278
+ network = WalletConnectChainID.Shasta;
279
+ } else if (chainId === 2494104990) {
280
+ network = WalletConnectChainID.Nile;
281
+ }
282
+ }
283
+ const metadataInfo = {
284
+ name: "Enclave Wallet SDK",
285
+ description: "Multi-chain wallet adapter for Enclave",
286
+ url: appUrl,
287
+ icons,
288
+ network,
289
+ chainId,
290
+ isTelegram: this.isTelegramMiniApp(),
291
+ projectId: this.projectId,
292
+ urlValid: appUrl && (appUrl.startsWith("http://") || appUrl.startsWith("https://")),
293
+ iconsValid: icons && icons.length > 0 && icons.every((icon) => icon && icon.startsWith("http")),
294
+ currentLocation: typeof window !== "undefined" ? window.location.href : "N/A",
295
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A"
296
+ };
297
+ console.log("[WalletConnect Tron] Initializing with metadata:", metadataInfo);
298
+ if (!metadataInfo.urlValid) {
299
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid URL in metadata:", appUrl);
300
+ }
301
+ if (!metadataInfo.iconsValid) {
302
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid icons in metadata:", icons);
303
+ }
304
+ console.log("[WalletConnect Tron] Initializing wallet...", {
305
+ network,
306
+ chainId,
307
+ note: "If no wallets are in WalletConnect Explorer for TRON, QR code will be displayed for scanning"
308
+ });
309
+ _WalletConnectTronAdapter.walletInstance = new WalletConnectWallet({
310
+ network,
311
+ options: {
312
+ projectId: this.projectId,
313
+ metadata: {
314
+ name: "Enclave Wallet SDK",
315
+ description: "Multi-chain wallet adapter for Enclave",
316
+ url: appUrl,
317
+ icons
318
+ }
319
+ },
320
+ // Theme configuration
321
+ themeMode: "light",
322
+ themeVariables: {
323
+ "--w3m-z-index": 1e4
324
+ // Ensure modal appears above Telegram UI
325
+ },
326
+ // Web3Modal configuration for recommended wallets
327
+ // According to official docs: https://developers.tron.network/docs/walletconnect-tron
328
+ // Note: If no wallets are registered in WalletConnect Explorer for TRON,
329
+ // explorerRecommendedWalletIds will have no effect, and QR code will be shown instead.
330
+ // @ts-ignore - web3ModalConfig is supported but may not be in TypeScript types
331
+ web3ModalConfig: {
332
+ themeMode: "light",
333
+ themeVariables: {
334
+ "--w3m-z-index": 1e4
335
+ },
336
+ /**
337
+ * Recommended Wallets are fetched from WalletConnect explore api:
338
+ * https://walletconnect.com/explorer?type=wallet&version=2
339
+ *
340
+ * IMPORTANT: If wallets are not registered in Explorer for TRON, this list will be ignored.
341
+ * The AppKit will show a QR code instead, which users can scan with any WalletConnect-compatible wallet.
342
+ *
343
+ * Wallet IDs (for reference, may not work if not in Explorer):
344
+ * - TokenPocket: 20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66
345
+ * - TronLink: 1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369
346
+ */
347
+ explorerRecommendedWalletIds: [
348
+ // These IDs are kept for when wallets register in WalletConnect Explorer
349
+ // Currently, if no TRON wallets are in Explorer, QR code will be shown
350
+ "20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66",
351
+ // TokenPocket
352
+ "1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
353
+ // TronLink
354
+ "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0"
355
+ // TokenPocket (backup)
356
+ ]
357
+ }
358
+ });
359
+ _WalletConnectTronAdapter.walletProjectId = this.projectId;
360
+ }
361
+ /**
362
+ * Connect wallet
363
+ */
364
+ async connect(chainId) {
365
+ if (typeof window === "undefined") {
366
+ throw new Error("WalletConnect requires a browser environment");
367
+ }
368
+ const currentState = this.state;
369
+ if (currentState === "connecting" /* CONNECTING */) {
370
+ console.warn("[WalletConnect Tron] Connection already in progress, waiting...");
371
+ let attempts = 0;
372
+ while (this.state === "connecting" /* CONNECTING */ && attempts < 50) {
373
+ await new Promise((resolve) => setTimeout(resolve, 100));
374
+ attempts++;
375
+ }
376
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
377
+ return this.currentAccount;
378
+ }
379
+ if (this.state === "connecting" /* CONNECTING */) {
380
+ throw new Error("Connection timeout - previous connection attempt is still pending");
381
+ }
382
+ }
383
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
384
+ return this.currentAccount;
385
+ }
386
+ try {
387
+ this.setState("connecting" /* CONNECTING */);
388
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
389
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
390
+ this.initializeWallet(targetChainId);
391
+ }
392
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
393
+ if (!this.wallet) {
394
+ throw new Error("Failed to initialize WalletConnect wallet");
395
+ }
396
+ let network = WalletConnectChainID.Mainnet;
397
+ if (targetChainId === 195) {
398
+ network = WalletConnectChainID.Mainnet;
399
+ } else if (targetChainId === 201910292) {
400
+ network = WalletConnectChainID.Shasta;
401
+ } else if (targetChainId === 2494104990) {
402
+ network = WalletConnectChainID.Nile;
403
+ }
404
+ let address;
405
+ try {
406
+ console.log("[WalletConnect Tron] Attempting to connect...", {
407
+ network,
408
+ chainId: targetChainId,
409
+ isTelegram: this.isTelegramMiniApp(),
410
+ projectId: this.projectId
411
+ });
412
+ const result = await this.wallet.connect();
413
+ address = result.address;
414
+ if (!address) {
415
+ throw new ConnectionRejectedError(this.type);
416
+ }
417
+ console.log("[WalletConnect Tron] Connection successful:", {
418
+ address,
419
+ network,
420
+ chainId: targetChainId,
421
+ isTelegram: this.isTelegramMiniApp()
422
+ });
423
+ } catch (error) {
424
+ const errorMessage = error.message || String(error);
425
+ const errorCode = error.code || error.error?.code;
426
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
427
+ let detailedError = errorMessage;
428
+ if (error.error) {
429
+ if (typeof error.error === "string") {
430
+ detailedError = error.error;
431
+ } else if (error.error.message) {
432
+ detailedError = error.error.message;
433
+ } else if (error.error.data) {
434
+ detailedError = JSON.stringify(error.error.data);
435
+ }
436
+ }
437
+ const isNoWalletFound = errorMessage.includes("\u6CA1\u6709\u627E\u5230\u652F\u6301\u7684\u94B1\u5305") || errorMessage.includes("No matching wallet") || errorMessage.includes("No wallet found") || errorMessage.includes("\u627E\u4E0D\u5230\u94B1\u5305") || errorMessage.includes("not found") || errorMessage.includes("no matching");
438
+ const isTimeout = errorMessage.includes("timeout") || errorMessage.includes("\u8D85\u65F6") || errorCode === "TIMEOUT";
439
+ const isRejected = errorMessage.includes("rejected") || errorMessage.includes("\u62D2\u7EDD") || errorCode === 4001;
440
+ const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
441
+ const currentMetadata = this.wallet ? {
442
+ // Try to get metadata from wallet instance if available
443
+ projectId: this.projectId,
444
+ network
445
+ } : null;
446
+ const errorDetails = {
447
+ error: errorMessage,
448
+ detailedError,
449
+ code: errorCode,
450
+ isTelegram: this.isTelegramMiniApp(),
451
+ network,
452
+ chainId: targetChainId,
453
+ projectId: this.projectId,
454
+ metadata: currentMetadata,
455
+ // Get URL from window.location if available
456
+ currentUrl: typeof window !== "undefined" ? window.location.href : "N/A",
457
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A",
458
+ errorType: isNoWalletFound ? "NO_WALLET_FOUND" : isTimeout ? "TIMEOUT" : isRejected ? "REJECTED" : "UNKNOWN"
459
+ };
460
+ console.error("[WalletConnect Tron] Connection error - Full details:", errorDetails);
461
+ console.error("[WalletConnect Tron] Error object:", error);
462
+ console.error("[WalletConnect Tron] Error stack:", error.stack);
463
+ if (isNoWalletFound) {
464
+ const noWalletErrorDetails = [
465
+ `
466
+ === WalletConnect Tron: No Matching Wallet Found ===`,
467
+ `Error: ${errorMessage}`,
468
+ `Detailed: ${detailedError}`,
469
+ `Code: ${errorCode || "N/A"}`,
470
+ ``,
471
+ `Environment:`,
472
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
473
+ ` - Platform: ${errorDetails.telegramPlatform}`,
474
+ ` - Current URL: ${errorDetails.currentUrl}`,
475
+ ``,
476
+ `Configuration:`,
477
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
478
+ ` - Network: ${network}`,
479
+ ` - Chain ID: ${targetChainId}`,
480
+ ` - Metadata URL: ${typeof window !== "undefined" ? window.location.origin : "N/A"}`,
481
+ ``,
482
+ `Possible Causes:`,
483
+ ` 1. No WalletConnect-compatible wallet (TokenPocket, etc.) installed on device`,
484
+ ` 2. Wallet app not opened or not responding to deep link (wc://)`,
485
+ ` 3. Deep link handling issue in Telegram Mini App environment`,
486
+ ` 4. WalletConnect session timeout (user took too long to approve)`,
487
+ ` 5. Network connectivity issue preventing WalletConnect relay connection`,
488
+ ``,
489
+ `Solutions:`,
490
+ ` 1. Ensure TokenPocket or other WalletConnect-compatible wallet is installed`,
491
+ ` 2. Try opening the wallet app manually before connecting`,
492
+ ` 3. In Telegram Mini App, ensure the deep link popup is not blocked`,
493
+ ` 4. Try connecting again (may need to wait a few seconds)`,
494
+ ` 5. Check network connection and WalletConnect relay server accessibility`,
495
+ ``,
496
+ `For more details, see the error object logged above.`,
497
+ `===========================================
498
+ `
499
+ ].join("\n");
500
+ console.error(noWalletErrorDetails);
501
+ throw new ConnectionRejectedError(
502
+ `WalletConnect Tron: \u6CA1\u6709\u627E\u5230\u652F\u6301\u7684\u94B1\u5305 (No matching wallet found)
503
+
504
+ \u53EF\u80FD\u7684\u539F\u56E0\uFF1A
505
+ 1. \u8BBE\u5907\u4E0A\u672A\u5B89\u88C5\u652F\u6301 WalletConnect \u7684\u94B1\u5305\uFF08\u5982 TokenPocket\uFF09
506
+ 2. \u94B1\u5305\u5E94\u7528\u672A\u6253\u5F00\u6216\u672A\u54CD\u5E94 deep link (wc://)
507
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0Cdeep link \u5904\u7406\u53EF\u80FD\u6709\u95EE\u9898
508
+ 4. \u8FDE\u63A5\u8D85\u65F6\uFF08\u7528\u6237\u672A\u53CA\u65F6\u6279\u51C6\uFF09
509
+ 5. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898
510
+
511
+ \u89E3\u51B3\u65B9\u6848\uFF1A
512
+ 1. \u786E\u4FDD\u5DF2\u5B89\u88C5 TokenPocket \u6216\u5176\u4ED6\u652F\u6301 WalletConnect \u7684\u94B1\u5305
513
+ 2. \u5C1D\u8BD5\u624B\u52A8\u6253\u5F00\u94B1\u5305\u5E94\u7528\u540E\u518D\u8FDE\u63A5
514
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0C\u786E\u4FDD deep link \u5F39\u7A97\u672A\u88AB\u963B\u6B62
515
+ 4. \u7A0D\u7B49\u51E0\u79D2\u540E\u91CD\u8BD5\u8FDE\u63A5
516
+ 5. \u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C WalletConnect \u4E2D\u7EE7\u670D\u52A1\u5668\u53EF\u8BBF\u95EE\u6027
517
+
518
+ \u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7\u3002`
519
+ );
520
+ }
521
+ if (errorMessage.includes("Invalid") || errorMessage.includes("Configuration") || errorMessage.includes("App Config") || errorMessage.includes("Invalid App")) {
522
+ const configErrorDetails = [
523
+ `
524
+ === WalletConnect Tron Configuration Error ===`,
525
+ `Error: ${errorMessage}`,
526
+ `Detailed: ${detailedError}`,
527
+ `Code: ${errorCode || "N/A"}`,
528
+ `
529
+ Environment:`,
530
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
531
+ ` - Platform: ${errorDetails.telegramPlatform}`,
532
+ ` - Current URL: ${errorDetails.currentUrl}`,
533
+ `
534
+ Configuration:`,
535
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
536
+ ` - Network: ${network}`,
537
+ ` - Chain ID: ${targetChainId}`,
538
+ `
539
+ Possible Causes:`,
540
+ ` 1. Deep link (wc://) handling issue in Telegram Mini App`,
541
+ ` 2. Invalid metadata configuration (URL or icons not accessible)`,
542
+ ` 3. Network/chainId mismatch`,
543
+ ` 4. WalletConnect project ID not configured correctly`,
544
+ ` 5. Domain not added to WalletConnect Cloud allowlist`,
545
+ `
546
+ Please check:`,
547
+ ` - WalletConnect Project ID is valid and active`,
548
+ ` - Domain is added to WalletConnect Cloud allowlist (for serveo.net, etc.)`,
549
+ ` - Metadata URL is accessible: Check console for metadata logs`,
550
+ ` - Icons are accessible: Check console for icon URLs`,
551
+ ` - Network matches chainId: Expected ${network} for chainId ${targetChainId}`,
552
+ `
553
+ For more details, see the error object logged above.`,
554
+ `===========================================
555
+ `
556
+ ].join("\n");
557
+ console.error(configErrorDetails);
558
+ throw new ConfigurationError(
559
+ `WalletConnect Tron connection failed: ${errorMessage}
560
+
561
+ Configuration Details:
562
+ - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}
563
+ - Platform: ${errorDetails.telegramPlatform}
564
+ - Origin: ${origin || "(unknown)"}
565
+ - Project ID: ${this.projectId ? "Set" : "Missing"}
566
+ - Network: ${network}
567
+ - Chain ID: ${targetChainId}
568
+
569
+ This "Invalid App Configuration" error may be caused by:
570
+ 1. Deep link (wc://) handling issue in Telegram Mini App
571
+ 2. Invalid metadata configuration (URL or icons)
572
+ 3. Network/chainId mismatch
573
+ 4. Domain not added to WalletConnect Cloud allowlist
574
+
575
+ Please check the console for detailed error information.`
576
+ );
577
+ }
578
+ if (isOriginNotAllowed) {
579
+ throw new ConfigurationError(
580
+ `WalletConnect Tron relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
581
+
582
+ Fix:
583
+ 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
584
+ 2) Add this site origin to the allowlist:
585
+ - ${origin || "(unknown origin)"}
586
+
587
+ Common dev origins to allow:
588
+ - http://localhost:5173
589
+ - http://192.168.0.221:5173 (your LAN dev URL)
590
+ - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
591
+
592
+ Original error: ${errorMessage}`
593
+ );
594
+ }
595
+ if (isTimeout) {
596
+ throw new ConnectionRejectedError(
597
+ `WalletConnect Tron connection timeout. Please try again and ensure your wallet app is open and ready.`
598
+ );
599
+ }
600
+ if (isRejected) {
601
+ throw new ConnectionRejectedError(this.type);
602
+ }
603
+ throw error;
604
+ }
605
+ this.currentAddress = address;
606
+ const account = {
607
+ universalAddress: createUniversalAddress(targetChainId, address),
608
+ nativeAddress: address,
609
+ chainId: targetChainId,
610
+ chainType: ChainType.TRON,
611
+ isActive: true
612
+ };
613
+ this.setState("connected" /* CONNECTED */);
614
+ this.setAccount(account);
615
+ this.setupEventListeners();
616
+ return account;
617
+ } catch (error) {
618
+ this.setState("error" /* ERROR */);
619
+ this.setAccount(null);
620
+ this.currentAddress = null;
621
+ if (error.message?.includes("rejected") || error.code === 4001) {
622
+ throw new ConnectionRejectedError(this.type);
623
+ }
624
+ throw error;
625
+ }
626
+ }
627
+ /**
628
+ * Disconnect wallet
629
+ */
630
+ async disconnect() {
631
+ this.removeEventListeners();
632
+ if (this.wallet) {
633
+ try {
634
+ await this.wallet.disconnect();
635
+ } catch (error) {
636
+ console.warn("[WalletConnect Tron] Error during disconnect:", error);
637
+ }
638
+ }
639
+ this.wallet = null;
640
+ this.currentAddress = null;
641
+ this.setState("disconnected" /* DISCONNECTED */);
642
+ this.setAccount(null);
643
+ this.emitDisconnected();
644
+ }
645
+ /**
646
+ * Sign message
647
+ */
648
+ async signMessage(message) {
649
+ this.ensureConnected();
650
+ try {
651
+ if (!this.wallet) {
652
+ throw new Error("Wallet not initialized");
653
+ }
654
+ const signature = await this.wallet.signMessage(message);
655
+ if (typeof signature === "string") {
656
+ return signature;
657
+ } else if (signature && typeof signature === "object") {
658
+ if ("signature" in signature) {
659
+ return signature.signature;
660
+ } else if ("result" in signature) {
661
+ return signature.result;
662
+ } else {
663
+ return JSON.stringify(signature);
664
+ }
665
+ }
666
+ throw new Error("Invalid signature format returned from wallet");
667
+ } catch (error) {
668
+ console.error("[WalletConnect Tron] Sign message error:", error);
669
+ let errorMessage = "Unknown error";
670
+ if (typeof error === "string") {
671
+ errorMessage = error;
672
+ } else if (error?.message) {
673
+ errorMessage = error.message;
674
+ } else if (error?.error?.message) {
675
+ errorMessage = error.error.message;
676
+ } else {
677
+ try {
678
+ errorMessage = JSON.stringify(error);
679
+ } catch {
680
+ errorMessage = String(error);
681
+ }
682
+ }
683
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
684
+ throw new SignatureRejectedError();
685
+ }
686
+ if (errorMessage?.includes("not supported") || errorMessage?.includes("method not found") || errorMessage?.includes("Method not found") || error?.code === -32601 || error?.error?.code === -32601) {
687
+ throw new Error("tron_signMessage is not supported by the connected wallet. Please use a wallet that supports WalletConnect Tron signing, or use TronLink extension for browser-based signing.");
688
+ }
689
+ throw new Error(`WalletConnect Tron sign message failed: ${errorMessage}`);
690
+ }
691
+ }
692
+ /**
693
+ * Sign transaction
694
+ *
695
+ * @param transaction - Tron transaction object
696
+ * Can be created using TronWeb (if available) or any TRON transaction builder
697
+ * Format: { raw_data: {...}, raw_data_hex: "...", txID: "..." }
698
+ * @returns Signed transaction object or signature
699
+ */
700
+ async signTransaction(transaction) {
701
+ this.ensureConnected();
702
+ try {
703
+ if (!this.wallet) {
704
+ throw new Error("Wallet not initialized");
705
+ }
706
+ if (!transaction) {
707
+ throw new Error("Transaction object is required");
708
+ }
709
+ console.log("[WalletConnect Tron] Signing transaction:", {
710
+ hasRawData: !!transaction.raw_data,
711
+ hasRawDataHex: !!transaction.raw_data_hex,
712
+ hasTxID: !!transaction.txID
713
+ });
714
+ const result = await this.wallet.signTransaction(transaction);
715
+ if (typeof result === "string") {
716
+ return result;
717
+ } else if (result && typeof result === "object") {
718
+ if ("txID" in result && typeof result.txID === "string") {
719
+ return result.txID;
720
+ } else if ("txid" in result && typeof result.txid === "string") {
721
+ return result.txid;
722
+ } else if ("signature" in result) {
723
+ return JSON.stringify(result);
724
+ } else {
725
+ return JSON.stringify(result);
726
+ }
727
+ }
728
+ throw new Error("Invalid signature format returned from wallet");
729
+ } catch (error) {
730
+ console.error("[WalletConnect Tron] Sign transaction error:", error);
731
+ let errorMessage = "Unknown error";
732
+ if (typeof error === "string") {
733
+ errorMessage = error;
734
+ } else if (error?.message) {
735
+ errorMessage = error.message;
736
+ } else if (error?.error?.message) {
737
+ errorMessage = error.error.message;
738
+ } else if (error?.data?.message) {
739
+ errorMessage = error.data.message;
740
+ } else {
741
+ try {
742
+ errorMessage = JSON.stringify(error);
743
+ } catch {
744
+ errorMessage = String(error);
745
+ }
746
+ }
747
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
748
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
749
+ }
750
+ if (errorMessage?.includes("not supported") || errorMessage?.includes("method not found") || errorMessage?.includes("Method not found") || errorMessage?.includes("Not support") || error?.code === -32601 || error?.error?.code === -32601) {
751
+ throw new Error("tron_signTransaction is not supported by the connected wallet. Please use a wallet that supports WalletConnect Tron signing, or use TronLink extension for browser-based signing.");
752
+ }
753
+ throw new Error(`WalletConnect Tron sign transaction failed: ${errorMessage}`);
754
+ }
755
+ }
756
+ /**
757
+ * Read contract (not supported by WalletConnect)
758
+ */
759
+ async readContract(_params) {
760
+ this.ensureConnected();
761
+ throw new Error("WalletConnect Tron does not support direct contract reading. Please use direct Tron RPC calls or a wallet extension (like TronLink) for read operations.");
762
+ }
763
+ /**
764
+ * Write contract (not yet implemented)
765
+ */
766
+ async writeContract(_params) {
767
+ throw new Error("Contract write not yet implemented for WalletConnect Tron");
768
+ }
769
+ /**
770
+ * Estimate gas (not yet implemented)
771
+ */
772
+ async estimateGas(_params) {
773
+ throw new Error("Gas estimation not yet implemented for WalletConnect Tron");
774
+ }
775
+ /**
776
+ * Wait for transaction (not yet implemented)
777
+ */
778
+ async waitForTransaction(_txHash, _confirmations) {
779
+ throw new Error("Transaction waiting not yet implemented for WalletConnect Tron");
780
+ }
781
+ /**
782
+ * Setup event listeners
783
+ */
784
+ setupEventListeners() {
785
+ if (!this.wallet) {
786
+ return;
787
+ }
788
+ this.wallet.on("accountsChanged", (accounts) => {
789
+ if (accounts && accounts.length > 0 && accounts[0] !== this.currentAddress) {
790
+ const newAddress = accounts[0];
791
+ this.currentAddress = newAddress;
792
+ if (this.currentAccount) {
793
+ const newAccount = {
794
+ ...this.currentAccount,
795
+ nativeAddress: newAddress,
796
+ universalAddress: createUniversalAddress(this.currentAccount.chainId, newAddress)
797
+ };
798
+ this.setAccount(newAccount);
799
+ this.emit("accountChanged", newAccount);
800
+ }
801
+ } else if (!accounts || accounts.length === 0) {
802
+ this.disconnect();
803
+ }
804
+ });
805
+ this.wallet.on("disconnect", () => {
806
+ this.disconnect();
807
+ });
808
+ }
809
+ /**
810
+ * Remove event listeners
811
+ */
812
+ removeEventListeners() {
813
+ if (!this.wallet) {
814
+ return;
815
+ }
816
+ this.wallet.removeAllListeners("accountsChanged");
817
+ this.wallet.removeAllListeners("disconnect");
818
+ }
819
+ /**
820
+ * Get provider (returns wallet instance)
821
+ */
822
+ getProvider() {
823
+ return this.wallet;
824
+ }
825
+ /**
826
+ * Clear static wallet instance (for complete cleanup)
827
+ */
828
+ static clearWalletInstance() {
829
+ if (_WalletConnectTronAdapter.walletInstance) {
830
+ _WalletConnectTronAdapter.walletInstance.disconnect().catch(() => {
831
+ });
832
+ _WalletConnectTronAdapter.walletInstance = null;
833
+ _WalletConnectTronAdapter.walletProjectId = null;
834
+ }
835
+ }
836
+ };
837
+ // Tron 主网链 ID
838
+ _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID = 195;
839
+ // Static wallet instance to avoid multiple initializations
840
+ _WalletConnectTronAdapter.walletInstance = null;
841
+ _WalletConnectTronAdapter.walletProjectId = null;
842
+ var WalletConnectTronAdapter = _WalletConnectTronAdapter;
843
+
844
+ export { WalletConnectTronAdapter };
845
+ //# sourceMappingURL=tron.mjs.map
846
+ //# sourceMappingURL=tron.mjs.map