@enclave-hq/wallet-sdk 1.2.3 → 1.2.5

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/index.mjs CHANGED
@@ -1,9 +1,597 @@
1
- import EventEmitter from 'eventemitter3';
2
1
  import { ChainType as ChainType$1 } from '@enclave-hq/chain-utils';
3
- import { isAddress, getAddress, createWalletClient, custom, createPublicClient, http, verifyMessage } from 'viem';
2
+ import EventEmitter from 'eventemitter3';
3
+ import { encodeFunctionData, createWalletClient, custom, createPublicClient, http, isAddress, getAddress, verifyMessage } from 'viem';
4
4
  import { privateKeyToAccount } from 'viem/accounts';
5
+ import EthereumProvider from '@walletconnect/ethereum-provider';
6
+ import { WalletConnectChainID, WalletConnectWallet } from '@tronweb3/walletconnect-tron';
7
+ import QRCode from 'qrcode';
8
+
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __getOwnPropNames = Object.getOwnPropertyNames;
12
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
13
+ var __esm = (fn, res) => function __init() {
14
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ };
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var ChainType, WalletType, WalletState;
30
+ var init_types = __esm({
31
+ "src/core/types.ts"() {
32
+ ChainType = ChainType$1;
33
+ WalletType = /* @__PURE__ */ ((WalletType3) => {
34
+ WalletType3["METAMASK"] = "metamask";
35
+ WalletType3["WALLETCONNECT"] = "walletconnect";
36
+ WalletType3["COINBASE_WALLET"] = "coinbase-wallet";
37
+ WalletType3["TRONLINK"] = "tronlink";
38
+ WalletType3["WALLETCONNECT_TRON"] = "walletconnect-tron";
39
+ WalletType3["PRIVATE_KEY"] = "private-key";
40
+ WalletType3["DEEP_LINK_EVM"] = "deep-link-evm";
41
+ WalletType3["DEEP_LINK_TRON"] = "deep-link-tron";
42
+ return WalletType3;
43
+ })(WalletType || {});
44
+ WalletState = /* @__PURE__ */ ((WalletState2) => {
45
+ WalletState2["DISCONNECTED"] = "disconnected";
46
+ WalletState2["CONNECTING"] = "connecting";
47
+ WalletState2["CONNECTED"] = "connected";
48
+ WalletState2["ERROR"] = "error";
49
+ return WalletState2;
50
+ })(WalletState || {});
51
+ }
52
+ });
53
+
54
+ // src/adapters/deep-link/providers/tokenpocket.ts
55
+ var tokenpocket_exports = {};
56
+ __export(tokenpocket_exports, {
57
+ TokenPocketDeepLinkProvider: () => TokenPocketDeepLinkProvider
58
+ });
59
+ var TokenPocketDeepLinkProvider;
60
+ var init_tokenpocket = __esm({
61
+ "src/adapters/deep-link/providers/tokenpocket.ts"() {
62
+ init_types();
63
+ TokenPocketDeepLinkProvider = class {
64
+ constructor(options) {
65
+ this.name = "TokenPocket";
66
+ this.icon = "https://tokenpocket.pro/icon.png";
67
+ this.supportedChainTypes = [ChainType.EVM, ChainType.TRON];
68
+ this.callbackUrl = options?.callbackUrl;
69
+ this.callbackSchema = options?.callbackSchema;
70
+ }
71
+ async isAvailable() {
72
+ if (typeof window === "undefined") {
73
+ return false;
74
+ }
75
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
76
+ if (isTelegramMiniApp) {
77
+ return true;
78
+ }
79
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
80
+ navigator.userAgent
81
+ );
82
+ return isMobile;
83
+ }
84
+ /**
85
+ * Generate unique actionId
86
+ */
87
+ generateActionId() {
88
+ return `web-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
89
+ }
90
+ /**
91
+ * Get callback configuration
92
+ */
93
+ getCallbackConfig() {
94
+ if (this.callbackSchema) {
95
+ return { callbackSchema: this.callbackSchema };
96
+ }
97
+ if (this.callbackUrl) {
98
+ return { callbackUrl: this.callbackUrl };
99
+ }
100
+ if (typeof window !== "undefined" && window.location) {
101
+ return {
102
+ callbackSchema: `${window.location.protocol}//${window.location.host}${window.location.pathname}`
103
+ };
104
+ }
105
+ return {};
106
+ }
107
+ /**
108
+ * Get blockchain configuration based on chain type
109
+ */
110
+ getBlockchainConfig(chainId, chainType) {
111
+ if (chainType === ChainType.TRON) {
112
+ return {
113
+ chainId: String(chainId),
114
+ network: "tron"
115
+ };
116
+ } else if (chainType === ChainType.EVM) {
117
+ return {
118
+ chainId: String(chainId),
119
+ network: "ethereum"
120
+ };
121
+ }
122
+ throw new Error(`Unsupported chain type: ${chainType}`);
123
+ }
124
+ buildSignMessageLink(params) {
125
+ const actionId = this.generateActionId();
126
+ const callback = this.getCallbackConfig();
127
+ const blockchain = this.getBlockchainConfig(params.chainId, params.chainType);
128
+ const param = {
129
+ action: "sign",
130
+ actionId,
131
+ message: params.message,
132
+ hash: false,
133
+ signType: params.chainType === ChainType.TRON ? "ethPersonalSign" : "ethPersonalSign",
134
+ memo: `${params.chainType} message signature`,
135
+ blockchains: [blockchain],
136
+ dappName: "Enclave Wallet SDK",
137
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
138
+ protocol: "TokenPocket",
139
+ version: "1.1.8",
140
+ expired: 0,
141
+ ...callback
142
+ };
143
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
144
+ const url = `tpoutside://pull.activity?param=${encodedParam}`;
145
+ return {
146
+ url,
147
+ actionId,
148
+ ...callback
149
+ };
150
+ }
151
+ buildSignTransactionLink(params) {
152
+ const actionId = this.generateActionId();
153
+ const callback = this.getCallbackConfig();
154
+ const blockchain = this.getBlockchainConfig(params.chainId, params.chainType);
155
+ let transactionData;
156
+ if (typeof params.transaction === "string") {
157
+ transactionData = params.transaction;
158
+ } else {
159
+ transactionData = JSON.stringify(params.transaction);
160
+ }
161
+ const param = {
162
+ action: "pushTransaction",
163
+ actionId,
164
+ txData: transactionData,
165
+ blockchains: [blockchain],
166
+ dappName: "Enclave Wallet SDK",
167
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
168
+ protocol: "TokenPocket",
169
+ version: "1.1.8",
170
+ expired: 0,
171
+ ...callback
172
+ };
173
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
174
+ const url = `tpoutside://pull.activity?param=${encodedParam}`;
175
+ return {
176
+ url,
177
+ actionId,
178
+ ...callback
179
+ };
180
+ }
181
+ buildConnectLink(params) {
182
+ const actionId = this.generateActionId();
183
+ const blockchain = this.getBlockchainConfig(params.chainId, params.chainType);
184
+ const param = {
185
+ action: "login",
186
+ actionId,
187
+ blockchains: [blockchain],
188
+ dappName: "Enclave Wallet SDK",
189
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
190
+ protocol: "TokenPocket",
191
+ version: "1.0",
192
+ expired: 1602
193
+ // 30 minutes
194
+ };
195
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
196
+ const url = `tpoutside://pull.activity?param=${encodedParam}`;
197
+ return {
198
+ url,
199
+ actionId
200
+ };
201
+ }
202
+ parseCallbackResult(urlParams) {
203
+ const actionId = urlParams.get("actionId");
204
+ const resultParam = urlParams.get("result");
205
+ const error = urlParams.get("error");
206
+ let result = null;
207
+ if (resultParam) {
208
+ try {
209
+ result = JSON.parse(decodeURIComponent(resultParam));
210
+ } catch (e) {
211
+ result = resultParam;
212
+ }
213
+ }
214
+ return {
215
+ actionId,
216
+ result,
217
+ error
218
+ };
219
+ }
220
+ getDefaultCallbackSchema() {
221
+ if (typeof window !== "undefined" && window.location) {
222
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
223
+ }
224
+ return "";
225
+ }
226
+ };
227
+ }
228
+ });
229
+
230
+ // src/adapters/deep-link/providers/tronlink.ts
231
+ var tronlink_exports = {};
232
+ __export(tronlink_exports, {
233
+ TronLinkDeepLinkProvider: () => TronLinkDeepLinkProvider
234
+ });
235
+ var TronLinkDeepLinkProvider;
236
+ var init_tronlink = __esm({
237
+ "src/adapters/deep-link/providers/tronlink.ts"() {
238
+ init_types();
239
+ TronLinkDeepLinkProvider = class {
240
+ constructor() {
241
+ this.name = "TronLink";
242
+ this.icon = "https://www.tronlink.org/static/logoIcon.svg";
243
+ this.supportedChainTypes = [ChainType.TRON];
244
+ }
245
+ async isAvailable() {
246
+ if (typeof window === "undefined") {
247
+ return false;
248
+ }
249
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
250
+ if (isTelegramMiniApp) {
251
+ return true;
252
+ }
253
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
254
+ navigator.userAgent
255
+ );
256
+ return isMobile;
257
+ }
258
+ buildSignMessageLink(params) {
259
+ if (params.chainType !== ChainType.TRON) {
260
+ throw new Error("TronLink only supports TRON chain");
261
+ }
262
+ const encodedMessage = encodeURIComponent(params.message);
263
+ const url = `tronlink://signMessage?message=${encodedMessage}`;
264
+ const actionId = `tronlink-${Date.now()}`;
265
+ return {
266
+ url,
267
+ actionId
268
+ };
269
+ }
270
+ buildSignTransactionLink(params) {
271
+ if (params.chainType !== ChainType.TRON) {
272
+ throw new Error("TronLink only supports TRON chain");
273
+ }
274
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
275
+ const encodedData = encodeURIComponent(transactionData);
276
+ const url = `tronlink://signTransaction?transaction=${encodedData}`;
277
+ const actionId = `tronlink-${Date.now()}`;
278
+ return {
279
+ url,
280
+ actionId
281
+ };
282
+ }
283
+ buildConnectLink(params) {
284
+ if (params.chainType !== ChainType.TRON) {
285
+ throw new Error("TronLink only supports TRON chain");
286
+ }
287
+ const url = `tronlink://open?action=connect&network=tron`;
288
+ return {
289
+ url
290
+ };
291
+ }
292
+ parseCallbackResult(_urlParams) {
293
+ return {
294
+ actionId: null,
295
+ result: null,
296
+ error: null
297
+ };
298
+ }
299
+ };
300
+ }
301
+ });
302
+
303
+ // src/adapters/deep-link/providers/imtoken.ts
304
+ var imtoken_exports = {};
305
+ __export(imtoken_exports, {
306
+ ImTokenDeepLinkProvider: () => ImTokenDeepLinkProvider
307
+ });
308
+ var ImTokenDeepLinkProvider;
309
+ var init_imtoken = __esm({
310
+ "src/adapters/deep-link/providers/imtoken.ts"() {
311
+ init_types();
312
+ ImTokenDeepLinkProvider = class {
313
+ constructor(options) {
314
+ this.name = "ImToken";
315
+ this.icon = "https://token.im/static/img/logo.png";
316
+ this.supportedChainTypes = [ChainType.EVM, ChainType.TRON];
317
+ this.callbackUrl = options?.callbackUrl;
318
+ this.callbackSchema = options?.callbackSchema;
319
+ }
320
+ async isAvailable() {
321
+ if (typeof window === "undefined") {
322
+ return false;
323
+ }
324
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
325
+ if (isTelegramMiniApp) {
326
+ return true;
327
+ }
328
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
329
+ navigator.userAgent
330
+ );
331
+ return isMobile;
332
+ }
333
+ /**
334
+ * Generate unique actionId
335
+ */
336
+ generateActionId() {
337
+ return `imtoken-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
338
+ }
339
+ /**
340
+ * Get callback configuration
341
+ */
342
+ getCallbackConfig() {
343
+ if (this.callbackSchema) {
344
+ return { callbackSchema: this.callbackSchema };
345
+ }
346
+ if (this.callbackUrl) {
347
+ return { callbackUrl: this.callbackUrl };
348
+ }
349
+ if (typeof window !== "undefined" && window.location) {
350
+ return {
351
+ callbackSchema: `${window.location.protocol}//${window.location.host}${window.location.pathname}`
352
+ };
353
+ }
354
+ return {};
355
+ }
356
+ buildSignMessageLink(params) {
357
+ const actionId = this.generateActionId();
358
+ const callback = this.getCallbackConfig();
359
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signMessage&message=${encodeURIComponent(params.message)}&chainId=${params.chainId}`;
360
+ const encodedDappUrl = encodeURIComponent(dappUrl);
361
+ const url = `imtokenv2://navigate/DappView?url=${encodedDappUrl}`;
362
+ return {
363
+ url,
364
+ actionId,
365
+ ...callback
366
+ };
367
+ }
368
+ buildSignTransactionLink(params) {
369
+ const actionId = this.generateActionId();
370
+ const callback = this.getCallbackConfig();
371
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
372
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signTransaction&transaction=${encodeURIComponent(transactionData)}&chainId=${params.chainId}`;
373
+ const encodedDappUrl = encodeURIComponent(dappUrl);
374
+ const url = `imtokenv2://navigate/DappView?url=${encodedDappUrl}`;
375
+ return {
376
+ url,
377
+ actionId,
378
+ ...callback
379
+ };
380
+ }
381
+ buildConnectLink(params) {
382
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=connect&chainId=${params.chainId}`;
383
+ const encodedDappUrl = encodeURIComponent(dappUrl);
384
+ const url = `imtokenv2://navigate/DappView?url=${encodedDappUrl}`;
385
+ return {
386
+ url
387
+ };
388
+ }
389
+ parseCallbackResult(urlParams) {
390
+ const actionId = urlParams.get("actionId");
391
+ const resultParam = urlParams.get("result");
392
+ const error = urlParams.get("error");
393
+ let result = null;
394
+ if (resultParam) {
395
+ try {
396
+ result = JSON.parse(decodeURIComponent(resultParam));
397
+ } catch (e) {
398
+ result = resultParam;
399
+ }
400
+ }
401
+ return {
402
+ actionId,
403
+ result,
404
+ error
405
+ };
406
+ }
407
+ getDefaultCallbackSchema() {
408
+ if (typeof window !== "undefined" && window.location) {
409
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
410
+ }
411
+ return "";
412
+ }
413
+ };
414
+ }
415
+ });
416
+
417
+ // src/adapters/deep-link/providers/metamask.ts
418
+ var metamask_exports = {};
419
+ __export(metamask_exports, {
420
+ MetaMaskDeepLinkProvider: () => MetaMaskDeepLinkProvider
421
+ });
422
+ var MetaMaskDeepLinkProvider;
423
+ var init_metamask = __esm({
424
+ "src/adapters/deep-link/providers/metamask.ts"() {
425
+ init_types();
426
+ MetaMaskDeepLinkProvider = class {
427
+ constructor() {
428
+ this.name = "MetaMask";
429
+ this.icon = "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg";
430
+ this.supportedChainTypes = [ChainType.EVM];
431
+ }
432
+ async isAvailable() {
433
+ if (typeof window === "undefined") {
434
+ return false;
435
+ }
436
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
437
+ if (isTelegramMiniApp) {
438
+ return true;
439
+ }
440
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
441
+ navigator.userAgent
442
+ );
443
+ return isMobile;
444
+ }
445
+ buildSignMessageLink(params) {
446
+ if (params.chainType !== ChainType.EVM) {
447
+ throw new Error("MetaMask only supports EVM chains");
448
+ }
449
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signMessage&message=${encodeURIComponent(params.message)}&chainId=${params.chainId}`;
450
+ const encodedDappUrl = encodeURIComponent(dappUrl);
451
+ const url = `https://link.metamask.io/dapp/${encodedDappUrl}`;
452
+ const actionId = `metamask-${Date.now()}`;
453
+ return {
454
+ url,
455
+ actionId
456
+ };
457
+ }
458
+ buildSignTransactionLink(params) {
459
+ if (params.chainType !== ChainType.EVM) {
460
+ throw new Error("MetaMask only supports EVM chains");
461
+ }
462
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
463
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signTransaction&transaction=${encodeURIComponent(transactionData)}&chainId=${params.chainId}`;
464
+ const encodedDappUrl = encodeURIComponent(dappUrl);
465
+ const url = `https://link.metamask.io/dapp/${encodedDappUrl}`;
466
+ const actionId = `metamask-${Date.now()}`;
467
+ return {
468
+ url,
469
+ actionId
470
+ };
471
+ }
472
+ buildConnectLink(params) {
473
+ if (params.chainType !== ChainType.EVM) {
474
+ throw new Error("MetaMask only supports EVM chains");
475
+ }
476
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=connect&chainId=${params.chainId}`;
477
+ const encodedDappUrl = encodeURIComponent(dappUrl);
478
+ const url = `https://link.metamask.io/dapp/${encodedDappUrl}`;
479
+ return {
480
+ url
481
+ };
482
+ }
483
+ parseCallbackResult(urlParams) {
484
+ const actionId = urlParams.get("actionId");
485
+ const resultParam = urlParams.get("result");
486
+ const error = urlParams.get("error");
487
+ let result = null;
488
+ if (resultParam) {
489
+ try {
490
+ result = JSON.parse(decodeURIComponent(resultParam));
491
+ } catch (e) {
492
+ result = resultParam;
493
+ }
494
+ }
495
+ return {
496
+ actionId,
497
+ result,
498
+ error
499
+ };
500
+ }
501
+ getDefaultCallbackSchema() {
502
+ if (typeof window !== "undefined" && window.location) {
503
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
504
+ }
505
+ return "";
506
+ }
507
+ };
508
+ }
509
+ });
5
510
 
6
- // src/core/events.ts
511
+ // src/adapters/deep-link/providers/okx.ts
512
+ var okx_exports = {};
513
+ __export(okx_exports, {
514
+ OKXDeepLinkProvider: () => OKXDeepLinkProvider
515
+ });
516
+ var OKXDeepLinkProvider;
517
+ var init_okx = __esm({
518
+ "src/adapters/deep-link/providers/okx.ts"() {
519
+ init_types();
520
+ OKXDeepLinkProvider = class {
521
+ constructor() {
522
+ this.name = "OKX";
523
+ this.icon = "https://www.okx.com/favicon.ico";
524
+ this.supportedChainTypes = [ChainType.EVM, ChainType.TRON];
525
+ }
526
+ async isAvailable() {
527
+ if (typeof window === "undefined") {
528
+ return false;
529
+ }
530
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
531
+ if (isTelegramMiniApp) {
532
+ return true;
533
+ }
534
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
535
+ navigator.userAgent
536
+ );
537
+ return isMobile;
538
+ }
539
+ buildSignMessageLink(params) {
540
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signMessage&message=${encodeURIComponent(params.message)}&chainId=${params.chainId}`;
541
+ const encodedDappUrl = encodeURIComponent(dappUrl);
542
+ const url = `okx://wallet/dapp/url?dappUrl=${encodedDappUrl}`;
543
+ const actionId = `okx-${Date.now()}`;
544
+ return {
545
+ url,
546
+ actionId
547
+ };
548
+ }
549
+ buildSignTransactionLink(params) {
550
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
551
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signTransaction&transaction=${encodeURIComponent(transactionData)}&chainId=${params.chainId}`;
552
+ const encodedDappUrl = encodeURIComponent(dappUrl);
553
+ const url = `okx://wallet/dapp/url?dappUrl=${encodedDappUrl}`;
554
+ const actionId = `okx-${Date.now()}`;
555
+ return {
556
+ url,
557
+ actionId
558
+ };
559
+ }
560
+ buildConnectLink(params) {
561
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=connect&chainId=${params.chainId}`;
562
+ const encodedDappUrl = encodeURIComponent(dappUrl);
563
+ const url = `okx://wallet/dapp/url?dappUrl=${encodedDappUrl}`;
564
+ return {
565
+ url
566
+ };
567
+ }
568
+ parseCallbackResult(urlParams) {
569
+ const actionId = urlParams.get("actionId");
570
+ const resultParam = urlParams.get("result");
571
+ const error = urlParams.get("error");
572
+ let result = null;
573
+ if (resultParam) {
574
+ try {
575
+ result = JSON.parse(decodeURIComponent(resultParam));
576
+ } catch (e) {
577
+ result = resultParam;
578
+ }
579
+ }
580
+ return {
581
+ actionId,
582
+ result,
583
+ error
584
+ };
585
+ }
586
+ getDefaultCallbackSchema() {
587
+ if (typeof window !== "undefined" && window.location) {
588
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
589
+ }
590
+ return "";
591
+ }
592
+ };
593
+ }
594
+ });
7
595
  var TypedEventEmitter = class {
8
596
  constructor() {
9
597
  this.emitter = new EventEmitter();
@@ -32,23 +620,12 @@ var TypedEventEmitter = class {
32
620
  return this;
33
621
  }
34
622
  };
35
- var ChainType = ChainType$1;
36
- var WalletType = /* @__PURE__ */ ((WalletType3) => {
37
- WalletType3["METAMASK"] = "metamask";
38
- WalletType3["WALLETCONNECT"] = "walletconnect";
39
- WalletType3["COINBASE_WALLET"] = "coinbase-wallet";
40
- WalletType3["TRONLINK"] = "tronlink";
41
- WalletType3["WALLETCONNECT_TRON"] = "walletconnect-tron";
42
- WalletType3["PRIVATE_KEY"] = "private-key";
43
- return WalletType3;
44
- })(WalletType || {});
45
- var WalletState = /* @__PURE__ */ ((WalletState2) => {
46
- WalletState2["DISCONNECTED"] = "disconnected";
47
- WalletState2["CONNECTING"] = "connecting";
48
- WalletState2["CONNECTED"] = "connected";
49
- WalletState2["ERROR"] = "error";
50
- return WalletState2;
51
- })(WalletState || {});
623
+
624
+ // src/core/adapter-registry.ts
625
+ init_types();
626
+
627
+ // src/adapters/base/wallet-adapter.ts
628
+ init_types();
52
629
 
53
630
  // src/core/errors.ts
54
631
  var WalletSDKError = class _WalletSDKError extends Error {
@@ -150,6 +727,13 @@ var WalletAdapter = class extends EventEmitter {
150
727
  this.state = "disconnected" /* DISCONNECTED */;
151
728
  this.currentAccount = null;
152
729
  }
730
+ /**
731
+ * Check if the wallet is currently connected
732
+ * @returns true if the wallet is connected (state is CONNECTED and has an account)
733
+ */
734
+ isConnected() {
735
+ return this.state === "connected" /* CONNECTED */ && this.currentAccount !== null;
736
+ }
153
737
  /**
154
738
  * Get the signer's address (implements ISigner interface)
155
739
  * Returns the native address of the current account
@@ -219,6 +803,7 @@ var WalletAdapter = class extends EventEmitter {
219
803
  };
220
804
 
221
805
  // src/adapters/base/browser-wallet-adapter.ts
806
+ init_types();
222
807
  var BrowserWalletAdapter = class extends WalletAdapter {
223
808
  /**
224
809
  * 检查钱包是否可用
@@ -252,6 +837,9 @@ var BrowserWalletAdapter = class extends WalletAdapter {
252
837
  }
253
838
  };
254
839
 
840
+ // src/adapters/evm/metamask.ts
841
+ init_types();
842
+
255
843
  // src/utils/address/universal-address.ts
256
844
  function createUniversalAddress(chainId, address) {
257
845
  return `${chainId}:${address}`;
@@ -321,7 +909,12 @@ var CHAIN_INFO = {
321
909
  symbol: "ETH",
322
910
  decimals: 18
323
911
  },
324
- rpcUrls: ["https://eth.llamarpc.com"],
912
+ // 使用支持浏览器 CORS 的公共 RPC,避免 dapp 域名被跨域拦截(如 eth.llamarpc.com 无 CORS 头)
913
+ rpcUrls: [
914
+ "https://cloudflare-eth.com",
915
+ "https://rpc.ankr.com/eth",
916
+ "https://eth.llamarpc.com"
917
+ ],
325
918
  blockExplorerUrls: ["https://etherscan.io"]
326
919
  },
327
920
  // EVM Testnets
@@ -550,6 +1143,7 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
550
1143
  */
551
1144
  async connect(chainId) {
552
1145
  await this.ensureAvailable();
1146
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId;
553
1147
  try {
554
1148
  this.setState("connecting" /* CONNECTING */);
555
1149
  const provider = this.getBrowserProvider();
@@ -563,10 +1157,10 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
563
1157
  method: "eth_chainId"
564
1158
  });
565
1159
  const parsedChainId = parseInt(currentChainId, 16);
566
- if (chainId && chainId !== parsedChainId) {
567
- await this.switchChain(chainId);
1160
+ if (targetChainId && targetChainId !== parsedChainId) {
1161
+ await this.switchChain(targetChainId);
568
1162
  }
569
- const finalChainId = chainId || parsedChainId;
1163
+ const finalChainId = targetChainId || parsedChainId;
570
1164
  const viemChain = this.getViemChain(finalChainId);
571
1165
  this.walletClient = createWalletClient({
572
1166
  account: accounts[0],
@@ -728,6 +1322,56 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
728
1322
  }]
729
1323
  });
730
1324
  }
1325
+ /**
1326
+ * 请求切换账户
1327
+ * 弹出 MetaMask 账户选择界面,让用户选择或切换到目标地址
1328
+ * @param targetAddress 目标地址(可选),如果提供,会在切换后验证是否匹配
1329
+ * @returns 切换后的账户信息
1330
+ */
1331
+ async requestSwitchAccount(targetAddress) {
1332
+ const provider = this.getBrowserProvider();
1333
+ if (!provider) {
1334
+ throw new Error("MetaMask provider not available");
1335
+ }
1336
+ try {
1337
+ await provider.request({
1338
+ method: "wallet_requestPermissions",
1339
+ params: [{ eth_accounts: {} }]
1340
+ });
1341
+ const accounts = await provider.request({
1342
+ method: "eth_accounts"
1343
+ });
1344
+ if (!accounts || accounts.length === 0) {
1345
+ throw new ConnectionRejectedError(this.type);
1346
+ }
1347
+ const address = formatEVMAddress(accounts[0]);
1348
+ if (targetAddress && address.toLowerCase() !== targetAddress.toLowerCase()) {
1349
+ throw new Error(`\u8BF7\u5728 MetaMask \u4E2D\u9009\u62E9\u5730\u5740 ${targetAddress.slice(0, 6)}...${targetAddress.slice(-4)}\uFF0C\u5F53\u524D\u9009\u62E9\u7684\u662F ${address.slice(0, 6)}...${address.slice(-4)}`);
1350
+ }
1351
+ const chainId = this.currentAccount?.chainId || 1;
1352
+ const account = {
1353
+ universalAddress: createUniversalAddress(chainId, address),
1354
+ nativeAddress: address,
1355
+ chainId,
1356
+ chainType: ChainType.EVM,
1357
+ isActive: true
1358
+ };
1359
+ this.setAccount(account);
1360
+ this.emitAccountChanged(account);
1361
+ const viemChain = this.getViemChain(chainId);
1362
+ this.walletClient = createWalletClient({
1363
+ account: address,
1364
+ chain: viemChain,
1365
+ transport: custom(provider)
1366
+ });
1367
+ return account;
1368
+ } catch (error) {
1369
+ if (error.code === 4001) {
1370
+ throw new ConnectionRejectedError(this.type);
1371
+ }
1372
+ throw error;
1373
+ }
1374
+ }
731
1375
  /**
732
1376
  * 读取合约
733
1377
  */
@@ -952,6 +1596,47 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
952
1596
  };
953
1597
 
954
1598
  // src/adapters/tron/tronlink.ts
1599
+ init_types();
1600
+ var TronApiRateLimiter = class {
1601
+ constructor(minIntervalMs = 600) {
1602
+ this.lastCallTime = 0;
1603
+ this.minInterval = minIntervalMs;
1604
+ }
1605
+ /**
1606
+ * 等待直到可以进行下一次 API 调用
1607
+ */
1608
+ async waitForNextCall() {
1609
+ const now = Date.now();
1610
+ const timeSinceLastCall = now - this.lastCallTime;
1611
+ if (timeSinceLastCall < this.minInterval) {
1612
+ const waitTime = this.minInterval - timeSinceLastCall;
1613
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
1614
+ }
1615
+ this.lastCallTime = Date.now();
1616
+ }
1617
+ };
1618
+ var tronApiRateLimiter = new TronApiRateLimiter(600);
1619
+ async function retryWithBackoff(fn, maxRetries = 3, initialDelay = 500) {
1620
+ let lastError;
1621
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
1622
+ try {
1623
+ return await fn();
1624
+ } catch (error) {
1625
+ lastError = error;
1626
+ const errorMsg = error?.message || String(error);
1627
+ const errorLower = errorMsg.toLowerCase();
1628
+ const isRateLimitError = error?.response?.status === 429 || error?.status === 429 || errorLower.includes("429") || errorLower.includes("rate limit") || errorLower.includes("too many requests") || error?.code === "ERR_BAD_REQUEST" && error?.response?.status === 429;
1629
+ if (isRateLimitError && attempt < maxRetries - 1) {
1630
+ const delay = initialDelay * Math.pow(2, attempt);
1631
+ console.warn(`[TronLink] \u9047\u5230\u901F\u7387\u9650\u5236 (429)\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5 (${attempt + 1}/${maxRetries})...`);
1632
+ await new Promise((resolve) => setTimeout(resolve, delay));
1633
+ continue;
1634
+ }
1635
+ throw error;
1636
+ }
1637
+ }
1638
+ throw lastError;
1639
+ }
955
1640
  var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
956
1641
  constructor() {
957
1642
  super(...arguments);
@@ -999,6 +1684,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
999
1684
  */
1000
1685
  async connect(chainId) {
1001
1686
  await this.ensureAvailable();
1687
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId;
1002
1688
  try {
1003
1689
  this.setState("connecting" /* CONNECTING */);
1004
1690
  const w = window;
@@ -1053,7 +1739,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1053
1739
  if (!address) {
1054
1740
  throw new Error("Failed to get Tron address. Please make sure your wallet is unlocked and try again.");
1055
1741
  }
1056
- const tronChainId = chainId || _TronLinkAdapter.TRON_MAINNET_CHAIN_ID;
1742
+ const tronChainId = targetChainId || _TronLinkAdapter.TRON_MAINNET_CHAIN_ID;
1057
1743
  const account = {
1058
1744
  universalAddress: createUniversalAddress(tronChainId, address),
1059
1745
  nativeAddress: address,
@@ -1128,10 +1814,12 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1128
1814
  /**
1129
1815
  * 读取合约
1130
1816
  * 参考 webserver 的实现,使用 TronWeb 合约实例的标准 call() 方法
1817
+ * 带 TronGrid 限流 + 429 重试
1131
1818
  */
1132
1819
  async readContract(params) {
1133
1820
  this.ensureConnected();
1134
- try {
1821
+ await tronApiRateLimiter.waitForNextCall();
1822
+ const doRead = async () => {
1135
1823
  const tronWeb = this.getTronWeb();
1136
1824
  if (!this.currentAccount) {
1137
1825
  throw new Error("No account connected");
@@ -1146,19 +1834,17 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1146
1834
  return result;
1147
1835
  } catch (method1Error) {
1148
1836
  console.warn("\u26A0\uFE0F [\u65B9\u6CD51] TronWeb\u6807\u51C6\u65B9\u6CD5\u5931\u8D25\uFF0C\u5C1D\u8BD5\u65B9\u6CD52:", method1Error.message);
1149
- try {
1150
- const contract2 = await tronWeb.contract().at(params.address);
1151
- const method2 = contract2[params.functionName];
1152
- if (!method2 || typeof method2 !== "function") {
1153
- throw new Error(`Function ${params.functionName} not found in contract`);
1154
- }
1155
- const result = await method2(...params.args || []).call();
1156
- return result;
1157
- } catch (method2Error) {
1158
- console.error("\u26A0\uFE0F [\u65B9\u6CD52] \u4E5F\u5931\u8D25:", method2Error.message);
1159
- throw method1Error;
1837
+ const contract2 = await tronWeb.contract().at(params.address);
1838
+ const method2 = contract2[params.functionName];
1839
+ if (!method2 || typeof method2 !== "function") {
1840
+ throw new Error(`Function ${params.functionName} not found in contract`);
1160
1841
  }
1842
+ const result = await method2(...params.args || []).call();
1843
+ return result;
1161
1844
  }
1845
+ };
1846
+ try {
1847
+ return await retryWithBackoff(doRead, 3, 800);
1162
1848
  } catch (error) {
1163
1849
  console.error("Read contract error:", error);
1164
1850
  throw new Error(`Failed to read contract: ${error.message || "Unknown error"}`);
@@ -1169,6 +1855,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1169
1855
  */
1170
1856
  async writeContract(params) {
1171
1857
  this.ensureConnected();
1858
+ await tronApiRateLimiter.waitForNextCall();
1172
1859
  try {
1173
1860
  const tronWeb = this.getTronWeb();
1174
1861
  console.log("[TronLink] writeContract params:", {
@@ -1194,29 +1881,171 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1194
1881
  }
1195
1882
  console.log("[TronLink] Function ABI:", functionAbi);
1196
1883
  console.log("[TronLink] Calling with args:", params.args);
1884
+ const TRON_FEE_LIMIT = 1e8;
1197
1885
  const options = {
1198
- feeLimit: params.gas || 1e8,
1199
- // 默认 100 TRX 的能量限制
1886
+ feeLimit: TRON_FEE_LIMIT,
1887
+ // 固定为 100 TRX 的能量限制
1200
1888
  callValue: params.value || 0
1201
1889
  // 发送的 TRX 数量(单位:SUN)
1202
1890
  };
1203
- const parameter = functionAbi.inputs.map((input, index) => ({
1204
- type: input.type,
1205
- value: params.args[index]
1206
- }));
1207
- console.log("[TronLink] Transaction options:", options);
1208
- console.log("[TronLink] Parameters:", parameter);
1209
- const functionSelector = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
1210
- console.log("[TronLink] Function selector:", functionSelector);
1211
- console.log("[TronLink] Transaction options:", options);
1212
- console.log("[TronLink] Parameters:", parameter);
1213
- const tx = await tronWeb.transactionBuilder.triggerSmartContract(
1214
- params.address,
1215
- functionSelector,
1216
- options,
1217
- parameter,
1218
- this.currentAccount.nativeAddress
1219
- );
1891
+ const hasTupleArray = functionAbi.inputs.some((input) => input.type === "tuple[]");
1892
+ console.log("[TronLink] \u68C0\u67E5 tuple[] \u7C7B\u578B:", {
1893
+ hasTupleArray,
1894
+ inputs: functionAbi.inputs.map((i) => ({ name: i.name, type: i.type }))
1895
+ });
1896
+ let tx;
1897
+ if (hasTupleArray) {
1898
+ console.log("[TronLink] \u68C0\u6D4B\u5230 tuple[] \u53C2\u6570\uFF0C\u4F7F\u7528\u624B\u52A8\u7F16\u7801\u65B9\u5F0F");
1899
+ const processedArgs = params.args.map((argValue, index) => {
1900
+ const input = functionAbi.inputs[index];
1901
+ if (input.type === "address" && typeof argValue === "string") {
1902
+ if (argValue.startsWith("T") && argValue.length === 34) {
1903
+ const hexAddress = tronWeb.address.toHex(argValue);
1904
+ return hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1905
+ }
1906
+ return argValue.startsWith("0x") ? argValue : `0x${argValue}`;
1907
+ }
1908
+ if (input.type === "tuple[]" && Array.isArray(argValue)) {
1909
+ return argValue.map((tupleItem) => {
1910
+ if (input.components && Array.isArray(input.components)) {
1911
+ const processedTuple = {};
1912
+ input.components.forEach((component) => {
1913
+ let value = tupleItem[component.name];
1914
+ if (component.type === "address" && typeof value === "string") {
1915
+ if (value.startsWith("T") && value.length === 34) {
1916
+ const hexAddress = tronWeb.address.toHex(value);
1917
+ value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1918
+ } else if (!value.startsWith("0x")) {
1919
+ value = `0x${value}`;
1920
+ }
1921
+ }
1922
+ processedTuple[component.name] = value;
1923
+ });
1924
+ return processedTuple;
1925
+ }
1926
+ return tupleItem;
1927
+ });
1928
+ }
1929
+ if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
1930
+ if (input.components && Array.isArray(input.components)) {
1931
+ const processedTuple = {};
1932
+ input.components.forEach((component) => {
1933
+ let value = argValue[component.name];
1934
+ if (component.type === "address" && typeof value === "string") {
1935
+ if (value.startsWith("T") && value.length === 34) {
1936
+ const hexAddress = tronWeb.address.toHex(value);
1937
+ value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1938
+ } else if (!value.startsWith("0x")) {
1939
+ value = `0x${value}`;
1940
+ }
1941
+ }
1942
+ processedTuple[component.name] = value;
1943
+ });
1944
+ return processedTuple;
1945
+ }
1946
+ }
1947
+ return argValue;
1948
+ });
1949
+ console.log("[TronLink] \u5904\u7406\u540E\u7684\u53C2\u6570\uFF08\u7528\u4E8E viem \u7F16\u7801\uFF09:", processedArgs);
1950
+ const encodedData = encodeFunctionData({
1951
+ abi: [functionAbi],
1952
+ functionName: params.functionName,
1953
+ args: processedArgs
1954
+ });
1955
+ console.log("[TronLink] \u7F16\u7801\u540E\u7684\u6570\u636E:", encodedData);
1956
+ const functionSelector = encodedData.slice(0, 10);
1957
+ const parameterData = encodedData.slice(10);
1958
+ console.log("[TronLink] \u51FD\u6570\u9009\u62E9\u5668:", functionSelector);
1959
+ console.log("[TronLink] \u53C2\u6570\u6570\u636E:", parameterData);
1960
+ const functionSignature = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
1961
+ const parameterHexClean = parameterData.startsWith("0x") ? parameterData.slice(2) : parameterData;
1962
+ console.log("[TronLink] \u4F7F\u7528 TronWeb triggerSmartContract (rawParameter)...", {
1963
+ contractAddress: params.address,
1964
+ functionSelector: functionSignature,
1965
+ encodedDataLength: parameterHexClean.length
1966
+ });
1967
+ tx = await retryWithBackoff(
1968
+ () => tronWeb.transactionBuilder.triggerSmartContract(
1969
+ params.address,
1970
+ // Base58 格式的合约地址
1971
+ functionSignature,
1972
+ // 函数签名(用于识别函数)
1973
+ {
1974
+ feeLimit: options.feeLimit,
1975
+ callValue: options.callValue,
1976
+ rawParameter: parameterHexClean
1977
+ // 使用 rawParameter 直接提供编码后的数据
1978
+ },
1979
+ [],
1980
+ // parameter 留空(因为使用 rawParameter)
1981
+ this.currentAccount.nativeAddress
1982
+ // Base58 格式的发送地址
1983
+ ),
1984
+ 3,
1985
+ // 最多重试 3 次
1986
+ 500
1987
+ // 初始延迟 500ms
1988
+ );
1989
+ console.log("[TronLink] \u4F7F\u7528 TronWeb API \u6784\u5EFA\u7684\u4EA4\u6613:", tx);
1990
+ } else {
1991
+ const parameter = functionAbi.inputs.map((input, index) => {
1992
+ const argValue = params.args[index];
1993
+ if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
1994
+ if (input.components && Array.isArray(input.components)) {
1995
+ return {
1996
+ type: input.type,
1997
+ value: input.components.map((component) => ({
1998
+ type: component.type,
1999
+ value: argValue[component.name]
2000
+ }))
2001
+ };
2002
+ }
2003
+ }
2004
+ if (input.type === "address" && typeof argValue === "string") {
2005
+ if (argValue.startsWith("T") && argValue.length === 34) {
2006
+ return {
2007
+ type: input.type,
2008
+ value: argValue
2009
+ };
2010
+ }
2011
+ try {
2012
+ const base58Address = tronWeb.address.fromHex(argValue.startsWith("0x") ? argValue : `0x${argValue}`);
2013
+ return {
2014
+ type: input.type,
2015
+ value: base58Address
2016
+ };
2017
+ } catch (e) {
2018
+ return {
2019
+ type: input.type,
2020
+ value: argValue
2021
+ };
2022
+ }
2023
+ }
2024
+ return {
2025
+ type: input.type,
2026
+ value: argValue
2027
+ };
2028
+ });
2029
+ console.log("[TronLink] Transaction options:", options);
2030
+ console.log("[TronLink] Parameters:", parameter);
2031
+ const functionSelector = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
2032
+ console.log("[TronLink] Function selector:", functionSelector);
2033
+ console.log("[TronLink] Transaction options:", options);
2034
+ console.log("[TronLink] Parameters:", parameter);
2035
+ tx = await retryWithBackoff(
2036
+ () => tronWeb.transactionBuilder.triggerSmartContract(
2037
+ params.address,
2038
+ functionSelector,
2039
+ options,
2040
+ parameter,
2041
+ this.currentAccount.nativeAddress
2042
+ ),
2043
+ 3,
2044
+ // 最多重试 3 次
2045
+ 500
2046
+ // 初始延迟 500ms
2047
+ );
2048
+ }
1220
2049
  console.log("[TronLink] Transaction built:", tx);
1221
2050
  if (!tx || !tx.transaction) {
1222
2051
  throw new Error("Failed to build transaction");
@@ -1256,6 +2085,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1256
2085
  const maxAttempts = 60;
1257
2086
  while (attempts < maxAttempts) {
1258
2087
  try {
2088
+ await tronApiRateLimiter.waitForNextCall();
1259
2089
  const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
1260
2090
  if (txInfo && txInfo.id) {
1261
2091
  const receipt = {
@@ -1383,6 +2213,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1383
2213
  // Tron 主网链 ID
1384
2214
  _TronLinkAdapter.TRON_MAINNET_CHAIN_ID = 195;
1385
2215
  var TronLinkAdapter = _TronLinkAdapter;
2216
+ init_types();
1386
2217
  var EVMPrivateKeyAdapter = class extends WalletAdapter {
1387
2218
  constructor() {
1388
2219
  super(...arguments);
@@ -1396,27 +2227,28 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1396
2227
  /**
1397
2228
  * 连接(导入私钥)
1398
2229
  */
1399
- async connect(chainId = 1) {
2230
+ async connect(chainId) {
1400
2231
  if (!this.privateKey) {
1401
2232
  throw new Error("Private key not set. Call setPrivateKey() first.");
1402
2233
  }
1403
2234
  try {
1404
2235
  this.setState("connecting" /* CONNECTING */);
1405
2236
  const account = privateKeyToAccount(this.privateKey);
2237
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId || 1;
1406
2238
  this.walletClient = createWalletClient({
1407
2239
  account,
1408
- chain: this.getViemChain(chainId),
2240
+ chain: this.getViemChain(targetChainId),
1409
2241
  transport: http()
1410
2242
  });
1411
2243
  this.publicClient = createPublicClient({
1412
- chain: this.getViemChain(chainId),
2244
+ chain: this.getViemChain(targetChainId),
1413
2245
  transport: http()
1414
2246
  });
1415
2247
  const address = formatEVMAddress(account.address);
1416
2248
  const accountInfo = {
1417
- universalAddress: createUniversalAddress(chainId, address),
2249
+ universalAddress: createUniversalAddress(targetChainId, address),
1418
2250
  nativeAddress: address,
1419
- chainId,
2251
+ chainId: targetChainId,
1420
2252
  chainType: ChainType.EVM,
1421
2253
  isActive: true
1422
2254
  };
@@ -1628,61 +2460,2318 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1628
2460
  };
1629
2461
  }
1630
2462
  };
1631
-
1632
- // src/core/adapter-registry.ts
1633
- var AdapterRegistry = class {
1634
- constructor() {
1635
- this.adapters = /* @__PURE__ */ new Map();
1636
- this.registerDefaultAdapters();
1637
- }
1638
- /**
1639
- * Register default adapters
1640
- */
1641
- registerDefaultAdapters() {
1642
- this.register("metamask" /* METAMASK */, () => new MetaMaskAdapter());
1643
- this.register("private-key" /* PRIVATE_KEY */, () => new EVMPrivateKeyAdapter());
1644
- this.register("tronlink" /* TRONLINK */, () => new TronLinkAdapter());
1645
- }
1646
- /**
1647
- * Register adapter
1648
- */
1649
- register(type, factory) {
1650
- this.adapters.set(type, factory);
1651
- }
1652
- /**
1653
- * Get adapter
1654
- */
1655
- getAdapter(type) {
1656
- const factory = this.adapters.get(type);
1657
- if (!factory) {
1658
- return null;
1659
- }
1660
- return factory();
1661
- }
1662
- /**
1663
- * Check if adapter is registered
1664
- */
1665
- has(type) {
1666
- return this.adapters.has(type);
1667
- }
2463
+ init_types();
2464
+ var _WalletConnectAdapter = class _WalletConnectAdapter extends WalletAdapter {
2465
+ constructor(projectId) {
2466
+ super();
2467
+ this.type = "walletconnect" /* WALLETCONNECT */;
2468
+ this.chainType = ChainType.EVM;
2469
+ this.name = "WalletConnect";
2470
+ this.icon = "https://avatars.githubusercontent.com/u/37784886";
2471
+ this.provider = null;
2472
+ this.walletClient = null;
2473
+ this.publicClient = null;
2474
+ this.supportedChains = [];
2475
+ /**
2476
+ * Handle accounts changed
2477
+ */
2478
+ this.handleAccountsChanged = (accounts) => {
2479
+ if (accounts.length === 0) {
2480
+ this.setState("disconnected" /* DISCONNECTED */);
2481
+ this.setAccount(null);
2482
+ this.emitAccountChanged(null);
2483
+ } else {
2484
+ const address = formatEVMAddress(accounts[0]);
2485
+ const account = {
2486
+ universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
2487
+ nativeAddress: address,
2488
+ chainId: this.currentAccount.chainId,
2489
+ chainType: ChainType.EVM,
2490
+ isActive: true
2491
+ };
2492
+ this.setAccount(account);
2493
+ this.emitAccountChanged(account);
2494
+ }
2495
+ };
2496
+ /**
2497
+ * Handle chain changed
2498
+ */
2499
+ this.handleChainChanged = (chainIdHex) => {
2500
+ const chainId = parseInt(chainIdHex, 16);
2501
+ if (this.currentAccount) {
2502
+ const account = {
2503
+ ...this.currentAccount,
2504
+ chainId,
2505
+ universalAddress: createUniversalAddress(chainId, this.currentAccount.nativeAddress)
2506
+ };
2507
+ this.setAccount(account);
2508
+ this.emitChainChanged(chainId);
2509
+ const viemChain = this.getViemChain(chainId);
2510
+ const chainInfo = getChainInfo(chainId);
2511
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2512
+ if (this.provider) {
2513
+ this.walletClient = createWalletClient({
2514
+ account: this.currentAccount.nativeAddress,
2515
+ chain: viemChain,
2516
+ transport: custom(this.provider)
2517
+ });
2518
+ this.publicClient = createPublicClient({
2519
+ chain: viemChain,
2520
+ transport: primaryRpcUrl ? http(primaryRpcUrl) : custom(this.provider)
2521
+ });
2522
+ }
2523
+ }
2524
+ };
2525
+ /**
2526
+ * Handle disconnect
2527
+ */
2528
+ this.handleDisconnect = () => {
2529
+ this.setState("disconnected" /* DISCONNECTED */);
2530
+ this.setAccount(null);
2531
+ if (_WalletConnectAdapter.providerInstance === this.provider) {
2532
+ _WalletConnectAdapter.providerInstance = null;
2533
+ _WalletConnectAdapter.providerProjectId = null;
2534
+ }
2535
+ this.provider = null;
2536
+ this.walletClient = null;
2537
+ this.publicClient = null;
2538
+ this.emitDisconnected();
2539
+ };
2540
+ if (!projectId) {
2541
+ throw new ConfigurationError("WalletConnect projectId is required");
2542
+ }
2543
+ this.projectId = projectId;
2544
+ }
2545
+ /**
2546
+ * Check if WalletConnect is available
2547
+ * WalletConnect is always available (it's a web-based connection)
2548
+ * Also works in Telegram Mini Apps
2549
+ */
2550
+ async isAvailable() {
2551
+ return typeof window !== "undefined";
2552
+ }
2553
+ /**
2554
+ * Check if running in Telegram environment (Mini App or Web)
2555
+ * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
2556
+ * provide window.Telegram.WebApp API, so they are treated the same way.
2557
+ *
2558
+ * Reference: https://docs.reown.com/appkit/integrations/telegram-mini-apps
2559
+ */
2560
+ isTelegramMiniApp() {
2561
+ if (typeof window === "undefined") return false;
2562
+ const tg = window.Telegram?.WebApp;
2563
+ if (!tg) return false;
2564
+ const platform = tg.platform || "unknown";
2565
+ console.log("[WalletConnect] Telegram environment detected:", {
2566
+ platform,
2567
+ version: tg.version,
2568
+ isMiniApp: platform !== "web",
2569
+ // Mini App if not web platform
2570
+ isWeb: platform === "web"
2571
+ // Telegram Web if web platform
2572
+ });
2573
+ return true;
2574
+ }
2575
+ /**
2576
+ * Get Telegram WebApp instance if available
2577
+ */
2578
+ getTelegramWebApp() {
2579
+ if (typeof window === "undefined") return null;
2580
+ return window.Telegram?.WebApp || null;
2581
+ }
2582
+ /**
2583
+ * Close Telegram deep link popup (wc:// links)
2584
+ * In Telegram Mini Apps, WalletConnect may open a wc:// deep link popup
2585
+ * that doesn't automatically close after the operation completes.
2586
+ * This method attempts to close it by:
2587
+ * 1. Trying to close any open windows/popups
2588
+ * 2. Using Telegram WebApp API if available
2589
+ * 3. Navigating back or closing the popup
2590
+ */
2591
+ closeTelegramDeepLinkPopup() {
2592
+ if (!this.isTelegramMiniApp()) {
2593
+ return;
2594
+ }
2595
+ try {
2596
+ const tg = this.getTelegramWebApp();
2597
+ if (!tg) {
2598
+ return;
2599
+ }
2600
+ if (typeof window !== "undefined") {
2601
+ window.focus();
2602
+ if (tg.BackButton && tg.BackButton.isVisible) {
2603
+ console.log("[WalletConnect] Closing Telegram deep link popup via BackButton");
2604
+ }
2605
+ setTimeout(() => {
2606
+ if (document.hasFocus()) {
2607
+ console.log("[WalletConnect] Main window has focus, popup likely closed");
2608
+ } else {
2609
+ window.focus();
2610
+ console.log("[WalletConnect] Attempted to focus main window to close popup");
2611
+ }
2612
+ }, 500);
2613
+ const handleVisibilityChange = () => {
2614
+ if (document.visibilityState === "visible") {
2615
+ console.log("[WalletConnect] Page became visible, popup may have closed");
2616
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
2617
+ }
2618
+ };
2619
+ document.addEventListener("visibilitychange", handleVisibilityChange);
2620
+ setTimeout(() => {
2621
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
2622
+ }, 2e3);
2623
+ }
2624
+ } catch (error) {
2625
+ console.warn("[WalletConnect] Error closing Telegram deep link popup:", error);
2626
+ }
2627
+ }
2628
+ /**
2629
+ * Connect wallet
2630
+ *
2631
+ * @param chainId - Single chain ID or array of chain IDs to request
2632
+ * If array is provided, wallet will be requested to connect to multiple chains
2633
+ * When multiple chains are requested, the wallet can switch between them
2634
+ * Default: 1 (Ethereum Mainnet)
2635
+ *
2636
+ * @example
2637
+ * // Single chain
2638
+ * await adapter.connect(1) // Ethereum only
2639
+ *
2640
+ * @example
2641
+ * // Multiple chains
2642
+ * await adapter.connect([1, 56, 137]) // Ethereum, BSC, Polygon
2643
+ */
2644
+ async connect(chainId) {
2645
+ if (typeof window === "undefined") {
2646
+ throw new Error("WalletConnect requires a browser environment");
2647
+ }
2648
+ if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2649
+ const existingProvider = _WalletConnectAdapter.providerInstance;
2650
+ if (existingProvider.accounts && existingProvider.accounts.length > 0) {
2651
+ this.provider = existingProvider;
2652
+ let targetChains;
2653
+ if (Array.isArray(chainId)) {
2654
+ targetChains = chainId.length > 0 ? chainId : [1];
2655
+ } else if (chainId) {
2656
+ targetChains = [chainId];
2657
+ } else {
2658
+ targetChains = [1];
2659
+ }
2660
+ const existingChains = this.supportedChains || [];
2661
+ const mergedChains = [.../* @__PURE__ */ new Set([...existingChains, ...targetChains])];
2662
+ this.supportedChains = mergedChains;
2663
+ const currentChainId = existingProvider.chainId || targetChains[0];
2664
+ const address = formatEVMAddress(existingProvider.accounts[0]);
2665
+ const account = {
2666
+ universalAddress: createUniversalAddress(currentChainId, address),
2667
+ nativeAddress: address,
2668
+ chainId: currentChainId,
2669
+ chainType: ChainType.EVM,
2670
+ isActive: true
2671
+ };
2672
+ this.setState("connected" /* CONNECTED */);
2673
+ this.setAccount(account);
2674
+ if (!this.walletClient) {
2675
+ const viemChain = this.getViemChain(currentChainId);
2676
+ this.walletClient = createWalletClient({
2677
+ account: existingProvider.accounts[0],
2678
+ chain: viemChain,
2679
+ transport: custom(existingProvider)
2680
+ });
2681
+ const chainInfo = getChainInfo(currentChainId);
2682
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2683
+ this.publicClient = createPublicClient({
2684
+ chain: viemChain,
2685
+ transport: primaryRpcUrl ? http(primaryRpcUrl) : custom(existingProvider)
2686
+ });
2687
+ this.setupEventListeners();
2688
+ }
2689
+ console.log("[WalletConnect] Reusing existing provider session");
2690
+ return account;
2691
+ }
2692
+ }
2693
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount && this.provider) {
2694
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2695
+ let targetChains;
2696
+ if (Array.isArray(chainId)) {
2697
+ targetChains = chainId.length > 0 ? chainId : [1];
2698
+ } else if (chainId) {
2699
+ targetChains = [chainId];
2700
+ } else {
2701
+ targetChains = [1];
2702
+ }
2703
+ const existingChains = this.supportedChains || [];
2704
+ const mergedChains = [.../* @__PURE__ */ new Set([...existingChains, ...targetChains])];
2705
+ this.supportedChains = mergedChains;
2706
+ console.log("[WalletConnect] Already connected, reusing existing connection");
2707
+ return this.currentAccount;
2708
+ } else {
2709
+ this.setState("disconnected" /* DISCONNECTED */);
2710
+ this.setAccount(null);
2711
+ this.provider = null;
2712
+ }
2713
+ }
2714
+ try {
2715
+ this.setState("connecting" /* CONNECTING */);
2716
+ let targetChains;
2717
+ if (Array.isArray(chainId)) {
2718
+ targetChains = chainId.length > 0 ? chainId : [1];
2719
+ } else if (chainId) {
2720
+ targetChains = [chainId];
2721
+ } else {
2722
+ targetChains = [1];
2723
+ }
2724
+ this.supportedChains = targetChains;
2725
+ const primaryChain = targetChains[0];
2726
+ const optionalChains = targetChains.slice(1);
2727
+ const isTelegram = this.isTelegramMiniApp();
2728
+ const telegramWebApp = this.getTelegramWebApp();
2729
+ let appUrl = "";
2730
+ if (typeof window !== "undefined") {
2731
+ try {
2732
+ if (window.location && window.location.origin) {
2733
+ appUrl = window.location.origin;
2734
+ } else if (window.location && window.location.href) {
2735
+ const url = new URL(window.location.href);
2736
+ appUrl = url.origin;
2737
+ }
2738
+ } catch (error) {
2739
+ console.warn("[WalletConnect] Failed to get origin from window.location:", error);
2740
+ }
2741
+ if (!appUrl) {
2742
+ appUrl = "https://enclave.network";
2743
+ }
2744
+ } else {
2745
+ appUrl = "https://enclave.network";
2746
+ }
2747
+ if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
2748
+ appUrl = "https://enclave.network";
2749
+ }
2750
+ const icons = [
2751
+ "https://walletconnect.com/walletconnect-logo.svg",
2752
+ "https://avatars.githubusercontent.com/u/37784886"
2753
+ // WalletConnect GitHub avatar
2754
+ ];
2755
+ const initOptions = {
2756
+ projectId: this.projectId,
2757
+ chains: [primaryChain],
2758
+ // Primary chain (required)
2759
+ showQrModal: true,
2760
+ // QR modal works in Telegram Mini Apps
2761
+ metadata: {
2762
+ name: "Enclave Wallet SDK",
2763
+ description: "Multi-chain wallet adapter for Enclave",
2764
+ url: appUrl,
2765
+ icons
2766
+ }
2767
+ };
2768
+ if (isTelegram && telegramWebApp) {
2769
+ const platform = telegramWebApp.platform || "unknown";
2770
+ const isMiniApp = platform !== "web";
2771
+ console.log("[WalletConnect] Detected Telegram environment:", {
2772
+ platform,
2773
+ isMiniApp,
2774
+ isWeb: platform === "web"
2775
+ });
2776
+ if (telegramWebApp.isExpanded === false) {
2777
+ telegramWebApp.expand();
2778
+ }
2779
+ }
2780
+ if (optionalChains.length > 0) {
2781
+ initOptions.optionalChains = optionalChains;
2782
+ } else {
2783
+ initOptions.optionalChains = [primaryChain];
2784
+ }
2785
+ const hasExistingProvider = _WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId;
2786
+ const needsReinit = hasExistingProvider && _WalletConnectAdapter.providerChains !== null && JSON.stringify(_WalletConnectAdapter.providerChains.sort()) !== JSON.stringify(targetChains.sort());
2787
+ if (needsReinit) {
2788
+ console.log("[WalletConnect] Provider initialized with different chains, reinitializing...", {
2789
+ existing: _WalletConnectAdapter.providerChains,
2790
+ requested: targetChains
2791
+ });
2792
+ const existingProvider = _WalletConnectAdapter.providerInstance;
2793
+ if (existingProvider) {
2794
+ try {
2795
+ if (existingProvider.accounts && existingProvider.accounts.length > 0) {
2796
+ await existingProvider.disconnect();
2797
+ }
2798
+ } catch (error) {
2799
+ console.warn("[WalletConnect] Error disconnecting existing provider:", error);
2800
+ }
2801
+ }
2802
+ _WalletConnectAdapter.providerInstance = null;
2803
+ _WalletConnectAdapter.providerChains = null;
2804
+ }
2805
+ if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2806
+ this.provider = _WalletConnectAdapter.providerInstance;
2807
+ console.log("[WalletConnect] Reusing existing provider instance");
2808
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2809
+ console.log("[WalletConnect] Provider already has accounts, skipping enable()");
2810
+ } else {
2811
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2812
+ console.log("[WalletConnect] Provider has no accounts, calling enable() to show QR modal");
2813
+ console.log("[WalletConnect] Provider state:", {
2814
+ accounts: this.provider.accounts,
2815
+ chainId: this.provider.chainId,
2816
+ hasSession,
2817
+ sessionTopic: this.provider.session?.topic
2818
+ });
2819
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2820
+ console.log("[WalletConnect] Found stale session, disconnecting before reconnecting...");
2821
+ try {
2822
+ await this.provider.disconnect();
2823
+ await new Promise((resolve) => setTimeout(resolve, 100));
2824
+ } catch (disconnectError) {
2825
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2826
+ }
2827
+ }
2828
+ try {
2829
+ console.log("[WalletConnect] Calling enable()...");
2830
+ const enableResult = await this.provider.enable();
2831
+ console.log("[WalletConnect] enable() completed, result:", enableResult);
2832
+ console.log("[WalletConnect] Provider state after enable():", {
2833
+ accounts: this.provider.accounts,
2834
+ chainId: this.provider.chainId,
2835
+ session: this.provider.session ? {
2836
+ topic: this.provider.session.topic,
2837
+ namespaces: this.provider.session.namespaces ? Object.keys(this.provider.session.namespaces) : "none"
2838
+ } : "none"
2839
+ });
2840
+ } catch (error) {
2841
+ console.error("[WalletConnect] enable() error:", error);
2842
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2843
+ throw new ConnectionRejectedError(this.type);
2844
+ }
2845
+ throw error;
2846
+ }
2847
+ }
2848
+ } else if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2849
+ this.provider = _WalletConnectAdapter.providerInstance;
2850
+ console.log("[WalletConnect] Reusing existing provider instance (not connected)");
2851
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2852
+ console.log("[WalletConnect] Provider already has accounts after init, skipping enable()");
2853
+ } else {
2854
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2855
+ console.log("[WalletConnect] Provider has no accounts, calling enable() to show QR modal");
2856
+ console.log("[WalletConnect] Provider state:", {
2857
+ accounts: this.provider.accounts,
2858
+ chainId: this.provider.chainId,
2859
+ hasSession,
2860
+ sessionTopic: this.provider.session?.topic
2861
+ });
2862
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2863
+ console.log("[WalletConnect] Found stale session after init, disconnecting before reconnecting...");
2864
+ try {
2865
+ await this.provider.disconnect();
2866
+ await new Promise((resolve) => setTimeout(resolve, 100));
2867
+ } catch (disconnectError) {
2868
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2869
+ }
2870
+ }
2871
+ try {
2872
+ await this.provider.enable();
2873
+ } catch (error) {
2874
+ console.error("[WalletConnect] enable() error:", error);
2875
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2876
+ throw new ConnectionRejectedError(this.type);
2877
+ }
2878
+ throw error;
2879
+ }
2880
+ }
2881
+ } else if (_WalletConnectAdapter.isInitializing && _WalletConnectAdapter.initPromise) {
2882
+ console.log("[WalletConnect] Waiting for ongoing initialization...");
2883
+ this.provider = await _WalletConnectAdapter.initPromise;
2884
+ _WalletConnectAdapter.providerInstance = this.provider;
2885
+ _WalletConnectAdapter.providerProjectId = this.projectId;
2886
+ _WalletConnectAdapter.providerChains = targetChains;
2887
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2888
+ console.log("[WalletConnect] Provider already has accounts after init, skipping enable()");
2889
+ } else {
2890
+ try {
2891
+ await this.provider.enable();
2892
+ } catch (error) {
2893
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2894
+ throw new ConnectionRejectedError(this.type);
2895
+ }
2896
+ throw error;
2897
+ }
2898
+ }
2899
+ } else {
2900
+ console.log("[WalletConnect] Initializing new provider with chains:", {
2901
+ primary: primaryChain,
2902
+ optional: optionalChains,
2903
+ all: targetChains
2904
+ });
2905
+ _WalletConnectAdapter.isInitializing = true;
2906
+ _WalletConnectAdapter.initPromise = EthereumProvider.init(initOptions);
2907
+ try {
2908
+ this.provider = await _WalletConnectAdapter.initPromise;
2909
+ _WalletConnectAdapter.providerInstance = this.provider;
2910
+ _WalletConnectAdapter.providerProjectId = this.projectId;
2911
+ _WalletConnectAdapter.providerChains = targetChains;
2912
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2913
+ console.log("[WalletConnect] Provider has restored session, skipping enable()");
2914
+ } else {
2915
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2916
+ console.log("[WalletConnect] New provider initialized, calling enable() to show QR modal");
2917
+ console.log("[WalletConnect] Provider state:", {
2918
+ accounts: this.provider.accounts,
2919
+ chainId: this.provider.chainId,
2920
+ hasSession,
2921
+ sessionTopic: this.provider.session?.topic
2922
+ });
2923
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2924
+ console.log("[WalletConnect] Found stale session after init, disconnecting before reconnecting...");
2925
+ try {
2926
+ await this.provider.disconnect();
2927
+ await new Promise((resolve) => setTimeout(resolve, 100));
2928
+ } catch (disconnectError) {
2929
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2930
+ }
2931
+ }
2932
+ try {
2933
+ await this.provider.enable();
2934
+ } catch (error) {
2935
+ console.error("[WalletConnect] enable() error:", error);
2936
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2937
+ throw new ConnectionRejectedError(this.type);
2938
+ }
2939
+ throw error;
2940
+ }
2941
+ }
2942
+ } finally {
2943
+ _WalletConnectAdapter.isInitializing = false;
2944
+ _WalletConnectAdapter.initPromise = null;
2945
+ }
2946
+ }
2947
+ let accounts = this.provider.accounts;
2948
+ if (!accounts || accounts.length === 0) {
2949
+ console.log("[WalletConnect] provider.accounts is empty, checking session.namespaces.eip155.accounts...");
2950
+ const session = this.provider.session;
2951
+ if (session && session.namespaces?.eip155?.accounts) {
2952
+ const sessionAccounts = session.namespaces.eip155.accounts.map((acc) => {
2953
+ const parts = acc.split(":");
2954
+ if (parts.length >= 3 && parts[0] === "eip155") {
2955
+ return parts[2];
2956
+ }
2957
+ return null;
2958
+ }).filter((addr) => addr !== null && addr.startsWith("0x"));
2959
+ if (sessionAccounts.length > 0) {
2960
+ const uniqueAccounts = [...new Set(sessionAccounts)];
2961
+ console.log("[WalletConnect] Found accounts in session.namespaces.eip155.accounts:", {
2962
+ raw: session.namespaces.eip155.accounts,
2963
+ extracted: uniqueAccounts,
2964
+ chains: session.namespaces.eip155.chains
2965
+ });
2966
+ accounts = uniqueAccounts;
2967
+ }
2968
+ }
2969
+ }
2970
+ if (!accounts || accounts.length === 0) {
2971
+ console.log("[WalletConnect] Accounts not available, waiting for provider.accounts to populate...");
2972
+ const maxWaitTime = 3e3;
2973
+ const checkInterval = 100;
2974
+ const maxChecks = maxWaitTime / checkInterval;
2975
+ for (let i = 0; i < maxChecks; i++) {
2976
+ await new Promise((resolve) => setTimeout(resolve, checkInterval));
2977
+ accounts = this.provider.accounts;
2978
+ if (accounts && accounts.length > 0) {
2979
+ console.log(`[WalletConnect] Accounts available after ${(i + 1) * checkInterval}ms`);
2980
+ break;
2981
+ }
2982
+ }
2983
+ }
2984
+ if (!accounts || accounts.length === 0) {
2985
+ const session = this.provider.session;
2986
+ const providerState = {
2987
+ providerAccounts: this.provider.accounts,
2988
+ providerChainId: this.provider.chainId,
2989
+ session: session ? {
2990
+ exists: true,
2991
+ topic: session.topic,
2992
+ namespaces: session.namespaces ? Object.keys(session.namespaces) : "none",
2993
+ eip155Namespace: session.namespaces?.eip155 ? {
2994
+ accounts: session.namespaces.eip155.accounts,
2995
+ // CAIP-10 format
2996
+ chains: session.namespaces.eip155.chains,
2997
+ // CAIP-2 format
2998
+ methods: session.namespaces.eip155.methods,
2999
+ events: session.namespaces.eip155.events
3000
+ } : "none",
3001
+ // Log full session structure for debugging
3002
+ fullSession: JSON.stringify(session, null, 2)
3003
+ } : "none",
3004
+ // Check if provider has any other properties that might contain accounts
3005
+ providerKeys: Object.keys(this.provider)
3006
+ };
3007
+ console.error("[WalletConnect] No accounts available after enable() and wait", providerState);
3008
+ console.error("[WalletConnect] Full provider object:", this.provider);
3009
+ console.error("[WalletConnect] Full session object:", session);
3010
+ console.error("[WalletConnect] Session namespaces structure:", session?.namespaces);
3011
+ throw new Error("WalletConnect connection established but no accounts available. Please check session.namespaces.eip155.accounts in the console logs above.");
3012
+ }
3013
+ const currentChainId = this.provider.chainId || targetChains[0];
3014
+ const viemChain = this.getViemChain(currentChainId);
3015
+ this.walletClient = createWalletClient({
3016
+ account: accounts[0],
3017
+ chain: viemChain,
3018
+ transport: custom(this.provider)
3019
+ });
3020
+ const chainInfo = getChainInfo(currentChainId);
3021
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
3022
+ this.publicClient = createPublicClient({
3023
+ chain: viemChain,
3024
+ transport: primaryRpcUrl ? http(primaryRpcUrl) : custom(this.provider)
3025
+ });
3026
+ const address = formatEVMAddress(accounts[0]);
3027
+ const account = {
3028
+ universalAddress: createUniversalAddress(currentChainId, address),
3029
+ nativeAddress: address,
3030
+ chainId: currentChainId,
3031
+ chainType: ChainType.EVM,
3032
+ isActive: true
3033
+ };
3034
+ this.setState("connected" /* CONNECTED */);
3035
+ this.setAccount(account);
3036
+ this.setupEventListeners();
3037
+ return account;
3038
+ } catch (error) {
3039
+ this.setState("error" /* ERROR */);
3040
+ this.setAccount(null);
3041
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
3042
+ const errorCode = error?.code;
3043
+ const errorMessage = error?.message || String(error);
3044
+ const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
3045
+ const session = this.provider?.session;
3046
+ const providerState = this.provider ? {
3047
+ accounts: this.provider.accounts,
3048
+ chainId: this.provider.chainId,
3049
+ session: session ? {
3050
+ exists: true,
3051
+ topic: session.topic,
3052
+ namespaces: session.namespaces ? Object.keys(session.namespaces) : "none",
3053
+ eip155Namespace: session.namespaces?.eip155 ? {
3054
+ accounts: session.namespaces.eip155.accounts,
3055
+ chains: session.namespaces.eip155.chains,
3056
+ methods: session.namespaces.eip155.methods,
3057
+ events: session.namespaces.eip155.events
3058
+ } : "none"
3059
+ } : "none",
3060
+ providerKeys: Object.keys(this.provider)
3061
+ } : "no provider";
3062
+ console.error("[WalletConnect] Connection error:", {
3063
+ error,
3064
+ code: error.code,
3065
+ message: error.message,
3066
+ stack: error.stack,
3067
+ providerState
3068
+ });
3069
+ if (this.provider) {
3070
+ console.error("[WalletConnect] Full provider object:", this.provider);
3071
+ console.error("[WalletConnect] Full session object:", session);
3072
+ }
3073
+ if (error.code === 4001 || error.message && (error.message.includes("User rejected") || error.message.includes("rejected by user") || error.message.includes("User cancelled"))) {
3074
+ throw new ConnectionRejectedError(this.type);
3075
+ }
3076
+ if (isOriginNotAllowed) {
3077
+ throw new ConfigurationError(
3078
+ `WalletConnect relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
3079
+
3080
+ Fix:
3081
+ 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
3082
+ 2) Add this site origin to the allowlist:
3083
+ - ${origin || "(unknown origin)"}
3084
+
3085
+ Common dev origins to allow:
3086
+ - http://localhost:5173
3087
+ - http://192.168.0.221:5173 (your LAN dev URL)
3088
+ - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
3089
+
3090
+ Original error: ${errorMessage}`
3091
+ );
3092
+ }
3093
+ throw error;
3094
+ }
3095
+ }
3096
+ /**
3097
+ * Disconnect wallet
3098
+ */
3099
+ async disconnect() {
3100
+ if (this.provider) {
3101
+ try {
3102
+ await this.provider.disconnect();
3103
+ } catch (error) {
3104
+ console.warn("[WalletConnect] Error during disconnect:", error);
3105
+ }
3106
+ if (_WalletConnectAdapter.providerInstance === this.provider) {
3107
+ _WalletConnectAdapter.providerInstance = null;
3108
+ _WalletConnectAdapter.providerProjectId = null;
3109
+ _WalletConnectAdapter.providerChains = null;
3110
+ }
3111
+ this.provider = null;
3112
+ }
3113
+ this.removeEventListeners();
3114
+ this.walletClient = null;
3115
+ this.publicClient = null;
3116
+ this.setState("disconnected" /* DISCONNECTED */);
3117
+ this.setAccount(null);
3118
+ this.emitDisconnected();
3119
+ }
3120
+ /**
3121
+ * Sign message
3122
+ */
3123
+ async signMessage(message) {
3124
+ this.ensureConnected();
3125
+ try {
3126
+ if (!this.provider) {
3127
+ throw new Error("Provider not initialized");
3128
+ }
3129
+ const signature = await this.provider.request({
3130
+ method: "personal_sign",
3131
+ params: [message, this.currentAccount.nativeAddress]
3132
+ });
3133
+ this.closeTelegramDeepLinkPopup();
3134
+ return signature;
3135
+ } catch (error) {
3136
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3137
+ throw new SignatureRejectedError();
3138
+ }
3139
+ throw error;
3140
+ }
3141
+ }
3142
+ /**
3143
+ * Sign TypedData (EIP-712)
3144
+ */
3145
+ async signTypedData(typedData) {
3146
+ this.ensureConnected();
3147
+ try {
3148
+ if (!this.provider) {
3149
+ throw new Error("Provider not initialized");
3150
+ }
3151
+ const signature = await this.provider.request({
3152
+ method: "eth_signTypedData_v4",
3153
+ params: [this.currentAccount.nativeAddress, JSON.stringify(typedData)]
3154
+ });
3155
+ this.closeTelegramDeepLinkPopup();
3156
+ return signature;
3157
+ } catch (error) {
3158
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3159
+ throw new SignatureRejectedError();
3160
+ }
3161
+ throw error;
3162
+ }
3163
+ }
3164
+ /**
3165
+ * Sign transaction
3166
+ */
3167
+ async signTransaction(transaction) {
3168
+ this.ensureConnected();
3169
+ try {
3170
+ if (!this.provider) {
3171
+ throw new Error("Provider not initialized");
3172
+ }
3173
+ const tx = {
3174
+ from: this.currentAccount.nativeAddress,
3175
+ to: transaction.to,
3176
+ value: transaction.value ? `0x${BigInt(transaction.value).toString(16)}` : void 0,
3177
+ data: transaction.data || "0x",
3178
+ gas: transaction.gas ? `0x${BigInt(transaction.gas).toString(16)}` : void 0,
3179
+ gasPrice: transaction.gasPrice && transaction.gasPrice !== "auto" ? `0x${BigInt(transaction.gasPrice).toString(16)}` : void 0,
3180
+ maxFeePerGas: transaction.maxFeePerGas ? `0x${BigInt(transaction.maxFeePerGas).toString(16)}` : void 0,
3181
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas ? `0x${BigInt(transaction.maxPriorityFeePerGas).toString(16)}` : void 0,
3182
+ nonce: transaction.nonce !== void 0 ? `0x${transaction.nonce.toString(16)}` : void 0,
3183
+ chainId: transaction.chainId || this.currentAccount.chainId
3184
+ };
3185
+ const signature = await this.provider.request({
3186
+ method: "eth_signTransaction",
3187
+ params: [tx]
3188
+ });
3189
+ this.closeTelegramDeepLinkPopup();
3190
+ return signature;
3191
+ } catch (error) {
3192
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3193
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
3194
+ }
3195
+ throw error;
3196
+ }
3197
+ }
3198
+ /**
3199
+ * Get supported chains from current connection
3200
+ * Returns the chains that were requested during connection
3201
+ */
3202
+ getSupportedChains() {
3203
+ return [...this.supportedChains];
3204
+ }
3205
+ /**
3206
+ * Switch chain
3207
+ *
3208
+ * Note: WalletConnect v2 with mobile wallets may not support chain switching reliably.
3209
+ * Some wallets may ignore the switch request or fail silently.
3210
+ * It's recommended to include all needed chains in the initial connection.
3211
+ *
3212
+ * Reference: https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces
3213
+ */
3214
+ async switchChain(chainId) {
3215
+ if (!this.provider) {
3216
+ throw new Error("Provider not initialized");
3217
+ }
3218
+ const session = this.provider.session;
3219
+ const supportedChains = session?.namespaces?.eip155?.chains || [];
3220
+ const targetChainCAIP = `eip155:${chainId}`;
3221
+ const isChainApproved = supportedChains.includes(targetChainCAIP);
3222
+ if (!isChainApproved) {
3223
+ console.warn(`[WalletConnect] Chain ${chainId} (${targetChainCAIP}) not in session approved chains:`, supportedChains);
3224
+ console.warn("[WalletConnect] Chain switching may fail. Consider including all chains in initial connection.");
3225
+ }
3226
+ try {
3227
+ console.log(`[WalletConnect] Attempting to switch to chain ${chainId} (${targetChainCAIP})`);
3228
+ const result = await this.provider.request({
3229
+ method: "wallet_switchEthereumChain",
3230
+ params: [{ chainId: `0x${chainId.toString(16)}` }]
3231
+ });
3232
+ if (result !== null && result !== void 0) {
3233
+ console.warn("[WalletConnect] wallet_switchEthereumChain returned non-null result:", result);
3234
+ }
3235
+ await new Promise((resolve) => setTimeout(resolve, 500));
3236
+ const currentChainId = this.provider.chainId;
3237
+ if (currentChainId !== chainId) {
3238
+ console.warn(`[WalletConnect] Chain switch may have failed. Expected ${chainId}, got ${currentChainId}`);
3239
+ console.warn("[WalletConnect] Some mobile wallets may not support chain switching via WalletConnect.");
3240
+ console.warn("[WalletConnect] User may need to manually switch chains in the wallet app.");
3241
+ }
3242
+ if (this.currentAccount) {
3243
+ const updatedAccount = {
3244
+ ...this.currentAccount,
3245
+ chainId,
3246
+ universalAddress: createUniversalAddress(chainId, this.currentAccount.nativeAddress)
3247
+ };
3248
+ this.setAccount(updatedAccount);
3249
+ this.emitChainChanged(chainId);
3250
+ const viemChain = this.getViemChain(chainId);
3251
+ const chainInfo = getChainInfo(chainId);
3252
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
3253
+ this.walletClient = createWalletClient({
3254
+ account: this.currentAccount.nativeAddress,
3255
+ chain: viemChain,
3256
+ transport: custom(this.provider)
3257
+ });
3258
+ this.publicClient = createPublicClient({
3259
+ chain: viemChain,
3260
+ transport: primaryRpcUrl ? http(primaryRpcUrl) : custom(this.provider)
3261
+ });
3262
+ }
3263
+ } catch (error) {
3264
+ console.error("[WalletConnect] Chain switch error:", {
3265
+ chainId,
3266
+ errorCode: error.code,
3267
+ errorMessage: error.message,
3268
+ supportedChains
3269
+ });
3270
+ if (error.code === 4902) {
3271
+ console.log(`[WalletConnect] Chain ${chainId} not found in wallet, attempting to add...`);
3272
+ const chainInfo = getChainInfo(chainId);
3273
+ if (chainInfo) {
3274
+ try {
3275
+ await this.addChain({
3276
+ chainId: chainInfo.id,
3277
+ chainName: chainInfo.name,
3278
+ nativeCurrency: chainInfo.nativeCurrency,
3279
+ rpcUrls: chainInfo.rpcUrls,
3280
+ blockExplorerUrls: chainInfo.blockExplorerUrls
3281
+ });
3282
+ console.log(`[WalletConnect] Chain added, attempting to switch again...`);
3283
+ await this.switchChain(chainId);
3284
+ } catch (addError) {
3285
+ console.error("[WalletConnect] Failed to add chain:", addError);
3286
+ throw new Error(`Failed to add chain ${chainId}: ${addError.message}`);
3287
+ }
3288
+ } else {
3289
+ throw new Error(`Chain ${chainId} not supported`);
3290
+ }
3291
+ } else if (error.code === 4001) {
3292
+ throw new Error("User rejected chain switch");
3293
+ } else if (error.code === 4100) {
3294
+ throw new Error("Wallet does not support wallet_switchEthereumChain. Please switch chains manually in your wallet app.");
3295
+ } else {
3296
+ console.warn("[WalletConnect] Chain switch may not be supported by this wallet. User may need to switch manually.");
3297
+ throw error;
3298
+ }
3299
+ }
3300
+ }
3301
+ /**
3302
+ * Add chain
3303
+ */
3304
+ async addChain(chainConfig) {
3305
+ if (!this.provider) {
3306
+ throw new Error("Provider not initialized");
3307
+ }
3308
+ await this.provider.request({
3309
+ method: "wallet_addEthereumChain",
3310
+ params: [{
3311
+ chainId: `0x${chainConfig.chainId.toString(16)}`,
3312
+ chainName: chainConfig.chainName,
3313
+ nativeCurrency: chainConfig.nativeCurrency,
3314
+ rpcUrls: chainConfig.rpcUrls,
3315
+ blockExplorerUrls: chainConfig.blockExplorerUrls
3316
+ }]
3317
+ });
3318
+ }
3319
+ /**
3320
+ * Read contract
3321
+ */
3322
+ async readContract(params) {
3323
+ if (!this.publicClient) {
3324
+ throw new Error("Public client not initialized");
3325
+ }
3326
+ const result = await this.publicClient.readContract({
3327
+ address: params.address,
3328
+ abi: params.abi,
3329
+ functionName: params.functionName,
3330
+ ...params.args ? { args: params.args } : {}
3331
+ });
3332
+ return result;
3333
+ }
3334
+ /**
3335
+ * Write contract
3336
+ */
3337
+ async writeContract(params) {
3338
+ this.ensureConnected();
3339
+ if (!this.walletClient) {
3340
+ throw new Error("Wallet client not initialized");
3341
+ }
3342
+ try {
3343
+ const txOptions = {
3344
+ address: params.address,
3345
+ abi: params.abi,
3346
+ functionName: params.functionName,
3347
+ ...params.args ? { args: params.args } : {},
3348
+ value: params.value ? BigInt(params.value) : void 0,
3349
+ gas: params.gas ? BigInt(params.gas) : void 0
3350
+ };
3351
+ if (params.maxFeePerGas || params.maxPriorityFeePerGas) {
3352
+ if (params.maxFeePerGas) {
3353
+ txOptions.maxFeePerGas = BigInt(params.maxFeePerGas);
3354
+ }
3355
+ if (params.maxPriorityFeePerGas) {
3356
+ txOptions.maxPriorityFeePerGas = BigInt(params.maxPriorityFeePerGas);
3357
+ }
3358
+ } else if (params.gasPrice && params.gasPrice !== "auto") {
3359
+ txOptions.gasPrice = BigInt(params.gasPrice);
3360
+ } else {
3361
+ if (this.publicClient) {
3362
+ try {
3363
+ const feesPerGas = await this.publicClient.estimateFeesPerGas().catch(() => null);
3364
+ if (feesPerGas) {
3365
+ const minPriorityFeeWei = BigInt(1e8);
3366
+ const maxPriorityFeePerGas = feesPerGas.maxPriorityFeePerGas > minPriorityFeeWei ? feesPerGas.maxPriorityFeePerGas : minPriorityFeeWei;
3367
+ const adjustedMaxFeePerGas = feesPerGas.maxFeePerGas > maxPriorityFeePerGas ? feesPerGas.maxFeePerGas : maxPriorityFeePerGas + BigInt(1e9);
3368
+ txOptions.maxFeePerGas = adjustedMaxFeePerGas;
3369
+ txOptions.maxPriorityFeePerGas = maxPriorityFeePerGas;
3370
+ } else {
3371
+ const gasPrice = await this.publicClient.getGasPrice();
3372
+ txOptions.gasPrice = gasPrice;
3373
+ }
3374
+ } catch (err) {
3375
+ }
3376
+ }
3377
+ }
3378
+ const txHash = await this.walletClient.writeContract(txOptions);
3379
+ this.closeTelegramDeepLinkPopup();
3380
+ return txHash;
3381
+ } catch (error) {
3382
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3383
+ throw new SignatureRejectedError("Transaction was rejected by user");
3384
+ }
3385
+ throw error;
3386
+ }
3387
+ }
3388
+ /**
3389
+ * Estimate gas
3390
+ */
3391
+ async estimateGas(params) {
3392
+ if (!this.publicClient) {
3393
+ throw new Error("Public client not initialized");
3394
+ }
3395
+ const gas = await this.publicClient.estimateContractGas({
3396
+ address: params.address,
3397
+ abi: params.abi,
3398
+ functionName: params.functionName,
3399
+ ...params.args ? { args: params.args } : {},
3400
+ value: params.value ? BigInt(params.value) : void 0,
3401
+ account: this.currentAccount.nativeAddress
3402
+ });
3403
+ return gas;
3404
+ }
3405
+ /**
3406
+ * Wait for transaction
3407
+ */
3408
+ async waitForTransaction(txHash, confirmations = 1) {
3409
+ if (!this.publicClient) {
3410
+ throw new Error("Public client not initialized");
3411
+ }
3412
+ const receipt = await this.publicClient.waitForTransactionReceipt({
3413
+ hash: txHash,
3414
+ confirmations
3415
+ });
3416
+ if (receipt.status === "reverted") {
3417
+ throw new TransactionFailedError(txHash, "Transaction reverted");
3418
+ }
3419
+ return {
3420
+ transactionHash: receipt.transactionHash,
3421
+ blockNumber: Number(receipt.blockNumber),
3422
+ blockHash: receipt.blockHash,
3423
+ from: receipt.from,
3424
+ to: receipt.to || void 0,
3425
+ status: receipt.status === "success" ? "success" : "failed",
3426
+ gasUsed: receipt.gasUsed.toString(),
3427
+ effectiveGasPrice: receipt.effectiveGasPrice?.toString(),
3428
+ logs: receipt.logs
3429
+ };
3430
+ }
3431
+ /**
3432
+ * Get provider
3433
+ */
3434
+ getProvider() {
3435
+ return this.provider;
3436
+ }
3437
+ /**
3438
+ * Get signer
3439
+ */
3440
+ getSigner() {
3441
+ return this.walletClient;
3442
+ }
3443
+ /**
3444
+ * Setup event listeners
3445
+ */
3446
+ setupEventListeners() {
3447
+ if (!this.provider) return;
3448
+ this.provider.on("accountsChanged", this.handleAccountsChanged);
3449
+ this.provider.on("chainChanged", this.handleChainChanged);
3450
+ this.provider.on("disconnect", this.handleDisconnect);
3451
+ }
3452
+ /**
3453
+ * Remove event listeners
3454
+ */
3455
+ removeEventListeners() {
3456
+ if (!this.provider) return;
3457
+ this.provider.removeListener("accountsChanged", this.handleAccountsChanged);
3458
+ this.provider.removeListener("chainChanged", this.handleChainChanged);
3459
+ this.provider.removeListener("disconnect", this.handleDisconnect);
3460
+ }
3461
+ /**
3462
+ * Get viem chain config
3463
+ */
3464
+ getViemChain(chainId) {
3465
+ const chainInfo = getChainInfo(chainId);
3466
+ if (chainInfo) {
3467
+ return {
3468
+ id: chainId,
3469
+ name: chainInfo.name,
3470
+ network: chainInfo.name.toLowerCase().replace(/\s+/g, "-"),
3471
+ nativeCurrency: chainInfo.nativeCurrency,
3472
+ rpcUrls: {
3473
+ default: { http: chainInfo.rpcUrls },
3474
+ public: { http: chainInfo.rpcUrls }
3475
+ },
3476
+ blockExplorers: chainInfo.blockExplorerUrls ? {
3477
+ default: { name: "Explorer", url: chainInfo.blockExplorerUrls[0] }
3478
+ } : void 0
3479
+ };
3480
+ }
3481
+ return {
3482
+ id: chainId,
3483
+ name: `Chain ${chainId}`,
3484
+ network: `chain-${chainId}`,
3485
+ nativeCurrency: {
3486
+ name: "ETH",
3487
+ symbol: "ETH",
3488
+ decimals: 18
3489
+ },
3490
+ rpcUrls: {
3491
+ default: { http: [] },
3492
+ public: { http: [] }
3493
+ }
3494
+ };
3495
+ }
3496
+ };
3497
+ // Store supported chains from connection
3498
+ // Static provider instance to avoid multiple initializations
3499
+ _WalletConnectAdapter.providerInstance = null;
3500
+ _WalletConnectAdapter.providerProjectId = null;
3501
+ _WalletConnectAdapter.providerChains = null;
3502
+ // Store the chains used during initialization
3503
+ _WalletConnectAdapter.isInitializing = false;
3504
+ _WalletConnectAdapter.initPromise = null;
3505
+ var WalletConnectAdapter = _WalletConnectAdapter;
3506
+
3507
+ // src/adapters/tron/wallet-connect.ts
3508
+ var wallet_connect_exports = {};
3509
+ __export(wallet_connect_exports, {
3510
+ WalletConnectTronAdapter: () => WalletConnectTronAdapter
3511
+ });
3512
+ init_types();
3513
+ var _WalletConnectTronAdapter = class _WalletConnectTronAdapter extends WalletAdapter {
3514
+ constructor(projectId) {
3515
+ super();
3516
+ this.type = "walletconnect-tron" /* WALLETCONNECT_TRON */;
3517
+ this.chainType = ChainType.TRON;
3518
+ this.name = "WalletConnect (Tron)";
3519
+ this.icon = "https://avatars.githubusercontent.com/u/37784886";
3520
+ this.wallet = null;
3521
+ this.currentAddress = null;
3522
+ if (!projectId) {
3523
+ throw new ConfigurationError("WalletConnect projectId is required");
3524
+ }
3525
+ this.projectId = projectId;
3526
+ }
3527
+ /**
3528
+ * Check if WalletConnect is available
3529
+ */
3530
+ async isAvailable() {
3531
+ return typeof window !== "undefined";
3532
+ }
3533
+ /**
3534
+ * Check if running in Telegram environment (Mini App or Web)
3535
+ * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
3536
+ * provide window.Telegram.WebApp API, so they are treated the same way.
3537
+ */
3538
+ isTelegramMiniApp() {
3539
+ if (typeof window === "undefined") return false;
3540
+ const tg = window.Telegram?.WebApp;
3541
+ if (!tg) return false;
3542
+ const platform = tg.platform || "unknown";
3543
+ console.log("[WalletConnect Tron] Telegram environment detected:", {
3544
+ platform,
3545
+ version: tg.version,
3546
+ isMiniApp: platform !== "web",
3547
+ // Mini App if not web platform
3548
+ isWeb: platform === "web"
3549
+ // Telegram Web if web platform
3550
+ });
3551
+ return true;
3552
+ }
3553
+ /**
3554
+ * Restore session from existing wallet (for storage restoration)
3555
+ */
3556
+ async restoreSession(chainId) {
3557
+ if (typeof window === "undefined") {
3558
+ return null;
3559
+ }
3560
+ try {
3561
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3562
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3563
+ this.initializeWallet(targetChainId);
3564
+ }
3565
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
3566
+ if (!this.wallet) {
3567
+ return null;
3568
+ }
3569
+ const status = await this.wallet.checkConnectStatus();
3570
+ if (status && status.address) {
3571
+ this.currentAddress = status.address;
3572
+ const account = {
3573
+ universalAddress: createUniversalAddress(targetChainId, status.address),
3574
+ nativeAddress: status.address,
3575
+ chainId: targetChainId,
3576
+ chainType: ChainType.TRON,
3577
+ isActive: true
3578
+ };
3579
+ this.setState("connected" /* CONNECTED */);
3580
+ this.setAccount(account);
3581
+ this.setupEventListeners();
3582
+ return account;
3583
+ }
3584
+ return null;
3585
+ } catch (error) {
3586
+ console.debug("[WalletConnect Tron] Restore session failed:", error);
3587
+ return null;
3588
+ }
3589
+ }
3590
+ /**
3591
+ * Initialize WalletConnect wallet instance
3592
+ * @param chainId - Optional chain ID to determine network (default: Mainnet)
3593
+ */
3594
+ initializeWallet(chainId) {
3595
+ if (_WalletConnectTronAdapter.walletInstance && _WalletConnectTronAdapter.walletProjectId === this.projectId) {
3596
+ return;
3597
+ }
3598
+ let appUrl = "";
3599
+ if (typeof window !== "undefined") {
3600
+ try {
3601
+ if (window.location && window.location.origin) {
3602
+ appUrl = window.location.origin;
3603
+ } else if (window.location && window.location.href) {
3604
+ const url = new URL(window.location.href);
3605
+ appUrl = url.origin;
3606
+ }
3607
+ } catch (error) {
3608
+ console.warn("[WalletConnect Tron] Failed to get origin from window.location:", error);
3609
+ }
3610
+ if (appUrl && (appUrl.includes("serveo.net") || appUrl.includes("loca.lt") || appUrl.includes("ngrok.io") || appUrl.includes("ngrok-free.app") || appUrl.includes("cloudflared.io"))) {
3611
+ console.log("[WalletConnect Tron] Detected tunnel service URL:", appUrl);
3612
+ console.log("[WalletConnect Tron] \u26A0\uFE0F Make sure this URL is added to WalletConnect Cloud project allowlist");
3613
+ }
3614
+ if (!appUrl) {
3615
+ const tg = window.Telegram?.WebApp;
3616
+ if (tg && tg.initDataUnsafe?.start_param) {
3617
+ appUrl = "https://enclave.network";
3618
+ } else {
3619
+ appUrl = "https://enclave.network";
3620
+ }
3621
+ }
3622
+ } else {
3623
+ appUrl = "https://enclave.network";
3624
+ }
3625
+ if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
3626
+ appUrl = "https://enclave.network";
3627
+ }
3628
+ const icons = [
3629
+ "https://walletconnect.com/walletconnect-logo.svg",
3630
+ "https://avatars.githubusercontent.com/u/37784886"
3631
+ // WalletConnect GitHub avatar
3632
+ ];
3633
+ let network = WalletConnectChainID.Mainnet;
3634
+ if (chainId !== void 0) {
3635
+ if (chainId === 195 || chainId === _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID) {
3636
+ network = WalletConnectChainID.Mainnet;
3637
+ } else if (chainId === 201910292) {
3638
+ network = WalletConnectChainID.Shasta;
3639
+ } else if (chainId === 2494104990) {
3640
+ network = WalletConnectChainID.Nile;
3641
+ }
3642
+ }
3643
+ const metadataInfo = {
3644
+ name: "Enclave Wallet SDK",
3645
+ description: "Multi-chain wallet adapter for Enclave",
3646
+ url: appUrl,
3647
+ icons,
3648
+ network,
3649
+ chainId,
3650
+ isTelegram: this.isTelegramMiniApp(),
3651
+ projectId: this.projectId,
3652
+ urlValid: appUrl && (appUrl.startsWith("http://") || appUrl.startsWith("https://")),
3653
+ iconsValid: icons && icons.length > 0 && icons.every((icon) => icon && icon.startsWith("http")),
3654
+ currentLocation: typeof window !== "undefined" ? window.location.href : "N/A",
3655
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A"
3656
+ };
3657
+ console.log("[WalletConnect Tron] Initializing with metadata:", metadataInfo);
3658
+ if (!metadataInfo.urlValid) {
3659
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid URL in metadata:", appUrl);
3660
+ }
3661
+ if (!metadataInfo.iconsValid) {
3662
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid icons in metadata:", icons);
3663
+ }
3664
+ console.log("[WalletConnect Tron] Initializing wallet...", {
3665
+ network,
3666
+ chainId,
3667
+ note: "If no wallets are in WalletConnect Explorer for TRON, QR code will be displayed for scanning"
3668
+ });
3669
+ _WalletConnectTronAdapter.walletInstance = new WalletConnectWallet({
3670
+ network,
3671
+ options: {
3672
+ projectId: this.projectId,
3673
+ metadata: {
3674
+ name: "Enclave Wallet SDK",
3675
+ description: "Multi-chain wallet adapter for Enclave",
3676
+ url: appUrl,
3677
+ icons
3678
+ }
3679
+ },
3680
+ // Theme configuration
3681
+ themeMode: "light",
3682
+ themeVariables: {
3683
+ "--w3m-z-index": 1e4
3684
+ // Ensure modal appears above Telegram UI
3685
+ },
3686
+ // Web3Modal configuration for recommended wallets
3687
+ // According to official docs: https://developers.tron.network/docs/walletconnect-tron
3688
+ // Note: If no wallets are registered in WalletConnect Explorer for TRON,
3689
+ // explorerRecommendedWalletIds will have no effect, and QR code will be shown instead.
3690
+ // @ts-ignore - web3ModalConfig is supported but may not be in TypeScript types
3691
+ web3ModalConfig: {
3692
+ themeMode: "light",
3693
+ themeVariables: {
3694
+ "--w3m-z-index": 1e4
3695
+ },
3696
+ /**
3697
+ * Recommended Wallets are fetched from WalletConnect explore api:
3698
+ * https://walletconnect.com/explorer?type=wallet&version=2
3699
+ *
3700
+ * IMPORTANT: If wallets are not registered in Explorer for TRON, this list will be ignored.
3701
+ * The AppKit will show a QR code instead, which users can scan with any WalletConnect-compatible wallet.
3702
+ *
3703
+ * Wallet IDs (for reference, may not work if not in Explorer):
3704
+ * - TokenPocket: 20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66
3705
+ * - TronLink: 1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369
3706
+ */
3707
+ explorerRecommendedWalletIds: [
3708
+ // These IDs are kept for when wallets register in WalletConnect Explorer
3709
+ // Currently, if no TRON wallets are in Explorer, QR code will be shown
3710
+ "20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66",
3711
+ // TokenPocket
3712
+ "1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
3713
+ // TronLink
3714
+ "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0"
3715
+ // TokenPocket (backup)
3716
+ ]
3717
+ }
3718
+ });
3719
+ _WalletConnectTronAdapter.walletProjectId = this.projectId;
3720
+ }
3721
+ /**
3722
+ * Connect wallet
3723
+ */
3724
+ async connect(chainId) {
3725
+ if (typeof window === "undefined") {
3726
+ throw new Error("WalletConnect requires a browser environment");
3727
+ }
3728
+ const currentState = this.state;
3729
+ if (currentState === "connecting" /* CONNECTING */) {
3730
+ console.warn("[WalletConnect Tron] Connection already in progress, waiting...");
3731
+ let attempts = 0;
3732
+ while (this.state === "connecting" /* CONNECTING */ && attempts < 50) {
3733
+ await new Promise((resolve) => setTimeout(resolve, 100));
3734
+ attempts++;
3735
+ }
3736
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3737
+ return this.currentAccount;
3738
+ }
3739
+ if (this.state === "connecting" /* CONNECTING */) {
3740
+ throw new Error("Connection timeout - previous connection attempt is still pending");
3741
+ }
3742
+ }
3743
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3744
+ return this.currentAccount;
3745
+ }
3746
+ try {
3747
+ this.setState("connecting" /* CONNECTING */);
3748
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3749
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3750
+ this.initializeWallet(targetChainId);
3751
+ }
3752
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
3753
+ if (!this.wallet) {
3754
+ throw new Error("Failed to initialize WalletConnect wallet");
3755
+ }
3756
+ let network = WalletConnectChainID.Mainnet;
3757
+ if (targetChainId === 195) {
3758
+ network = WalletConnectChainID.Mainnet;
3759
+ } else if (targetChainId === 201910292) {
3760
+ network = WalletConnectChainID.Shasta;
3761
+ } else if (targetChainId === 2494104990) {
3762
+ network = WalletConnectChainID.Nile;
3763
+ }
3764
+ let address;
3765
+ try {
3766
+ console.log("[WalletConnect Tron] Attempting to connect...", {
3767
+ network,
3768
+ chainId: targetChainId,
3769
+ isTelegram: this.isTelegramMiniApp(),
3770
+ projectId: this.projectId
3771
+ });
3772
+ const result = await this.wallet.connect();
3773
+ address = result.address;
3774
+ if (!address) {
3775
+ throw new ConnectionRejectedError(this.type);
3776
+ }
3777
+ console.log("[WalletConnect Tron] Connection successful:", {
3778
+ address,
3779
+ network,
3780
+ chainId: targetChainId,
3781
+ isTelegram: this.isTelegramMiniApp()
3782
+ });
3783
+ } catch (error) {
3784
+ const errorMessage = error.message || String(error);
3785
+ const errorCode = error.code || error.error?.code;
3786
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
3787
+ let detailedError = errorMessage;
3788
+ if (error.error) {
3789
+ if (typeof error.error === "string") {
3790
+ detailedError = error.error;
3791
+ } else if (error.error.message) {
3792
+ detailedError = error.error.message;
3793
+ } else if (error.error.data) {
3794
+ detailedError = JSON.stringify(error.error.data);
3795
+ }
3796
+ }
3797
+ 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");
3798
+ const isTimeout = errorMessage.includes("timeout") || errorMessage.includes("\u8D85\u65F6") || errorCode === "TIMEOUT";
3799
+ const isRejected = errorMessage.includes("rejected") || errorMessage.includes("\u62D2\u7EDD") || errorCode === 4001;
3800
+ const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
3801
+ const currentMetadata = this.wallet ? {
3802
+ // Try to get metadata from wallet instance if available
3803
+ projectId: this.projectId,
3804
+ network
3805
+ } : null;
3806
+ const errorDetails = {
3807
+ error: errorMessage,
3808
+ detailedError,
3809
+ code: errorCode,
3810
+ isTelegram: this.isTelegramMiniApp(),
3811
+ network,
3812
+ chainId: targetChainId,
3813
+ projectId: this.projectId,
3814
+ metadata: currentMetadata,
3815
+ // Get URL from window.location if available
3816
+ currentUrl: typeof window !== "undefined" ? window.location.href : "N/A",
3817
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A",
3818
+ errorType: isNoWalletFound ? "NO_WALLET_FOUND" : isTimeout ? "TIMEOUT" : isRejected ? "REJECTED" : "UNKNOWN"
3819
+ };
3820
+ console.error("[WalletConnect Tron] Connection error - Full details:", errorDetails);
3821
+ console.error("[WalletConnect Tron] Error object:", error);
3822
+ console.error("[WalletConnect Tron] Error stack:", error.stack);
3823
+ if (isNoWalletFound) {
3824
+ const noWalletErrorDetails = [
3825
+ `
3826
+ === WalletConnect Tron: No Matching Wallet Found ===`,
3827
+ `Error: ${errorMessage}`,
3828
+ `Detailed: ${detailedError}`,
3829
+ `Code: ${errorCode || "N/A"}`,
3830
+ ``,
3831
+ `Environment:`,
3832
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3833
+ ` - Platform: ${errorDetails.telegramPlatform}`,
3834
+ ` - Current URL: ${errorDetails.currentUrl}`,
3835
+ ``,
3836
+ `Configuration:`,
3837
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3838
+ ` - Network: ${network}`,
3839
+ ` - Chain ID: ${targetChainId}`,
3840
+ ` - Metadata URL: ${typeof window !== "undefined" ? window.location.origin : "N/A"}`,
3841
+ ``,
3842
+ `Possible Causes:`,
3843
+ ` 1. No WalletConnect-compatible wallet (TokenPocket, etc.) installed on device`,
3844
+ ` 2. Wallet app not opened or not responding to deep link (wc://)`,
3845
+ ` 3. Deep link handling issue in Telegram Mini App environment`,
3846
+ ` 4. WalletConnect session timeout (user took too long to approve)`,
3847
+ ` 5. Network connectivity issue preventing WalletConnect relay connection`,
3848
+ ``,
3849
+ `Solutions:`,
3850
+ ` 1. Ensure TokenPocket or other WalletConnect-compatible wallet is installed`,
3851
+ ` 2. Try opening the wallet app manually before connecting`,
3852
+ ` 3. In Telegram Mini App, ensure the deep link popup is not blocked`,
3853
+ ` 4. Try connecting again (may need to wait a few seconds)`,
3854
+ ` 5. Check network connection and WalletConnect relay server accessibility`,
3855
+ ``,
3856
+ `For more details, see the error object logged above.`,
3857
+ `===========================================
3858
+ `
3859
+ ].join("\n");
3860
+ console.error(noWalletErrorDetails);
3861
+ throw new ConnectionRejectedError(
3862
+ `WalletConnect Tron: \u6CA1\u6709\u627E\u5230\u652F\u6301\u7684\u94B1\u5305 (No matching wallet found)
3863
+
3864
+ \u53EF\u80FD\u7684\u539F\u56E0\uFF1A
3865
+ 1. \u8BBE\u5907\u4E0A\u672A\u5B89\u88C5\u652F\u6301 WalletConnect \u7684\u94B1\u5305\uFF08\u5982 TokenPocket\uFF09
3866
+ 2. \u94B1\u5305\u5E94\u7528\u672A\u6253\u5F00\u6216\u672A\u54CD\u5E94 deep link (wc://)
3867
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0Cdeep link \u5904\u7406\u53EF\u80FD\u6709\u95EE\u9898
3868
+ 4. \u8FDE\u63A5\u8D85\u65F6\uFF08\u7528\u6237\u672A\u53CA\u65F6\u6279\u51C6\uFF09
3869
+ 5. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898
3870
+
3871
+ \u89E3\u51B3\u65B9\u6848\uFF1A
3872
+ 1. \u786E\u4FDD\u5DF2\u5B89\u88C5 TokenPocket \u6216\u5176\u4ED6\u652F\u6301 WalletConnect \u7684\u94B1\u5305
3873
+ 2. \u5C1D\u8BD5\u624B\u52A8\u6253\u5F00\u94B1\u5305\u5E94\u7528\u540E\u518D\u8FDE\u63A5
3874
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0C\u786E\u4FDD deep link \u5F39\u7A97\u672A\u88AB\u963B\u6B62
3875
+ 4. \u7A0D\u7B49\u51E0\u79D2\u540E\u91CD\u8BD5\u8FDE\u63A5
3876
+ 5. \u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C WalletConnect \u4E2D\u7EE7\u670D\u52A1\u5668\u53EF\u8BBF\u95EE\u6027
3877
+
3878
+ \u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7\u3002`
3879
+ );
3880
+ }
3881
+ if (errorMessage.includes("Invalid") || errorMessage.includes("Configuration") || errorMessage.includes("App Config") || errorMessage.includes("Invalid App")) {
3882
+ const configErrorDetails = [
3883
+ `
3884
+ === WalletConnect Tron Configuration Error ===`,
3885
+ `Error: ${errorMessage}`,
3886
+ `Detailed: ${detailedError}`,
3887
+ `Code: ${errorCode || "N/A"}`,
3888
+ `
3889
+ Environment:`,
3890
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3891
+ ` - Platform: ${errorDetails.telegramPlatform}`,
3892
+ ` - Current URL: ${errorDetails.currentUrl}`,
3893
+ `
3894
+ Configuration:`,
3895
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3896
+ ` - Network: ${network}`,
3897
+ ` - Chain ID: ${targetChainId}`,
3898
+ `
3899
+ Possible Causes:`,
3900
+ ` 1. Deep link (wc://) handling issue in Telegram Mini App`,
3901
+ ` 2. Invalid metadata configuration (URL or icons not accessible)`,
3902
+ ` 3. Network/chainId mismatch`,
3903
+ ` 4. WalletConnect project ID not configured correctly`,
3904
+ ` 5. Domain not added to WalletConnect Cloud allowlist`,
3905
+ `
3906
+ Please check:`,
3907
+ ` - WalletConnect Project ID is valid and active`,
3908
+ ` - Domain is added to WalletConnect Cloud allowlist (for serveo.net, etc.)`,
3909
+ ` - Metadata URL is accessible: Check console for metadata logs`,
3910
+ ` - Icons are accessible: Check console for icon URLs`,
3911
+ ` - Network matches chainId: Expected ${network} for chainId ${targetChainId}`,
3912
+ `
3913
+ For more details, see the error object logged above.`,
3914
+ `===========================================
3915
+ `
3916
+ ].join("\n");
3917
+ console.error(configErrorDetails);
3918
+ throw new ConfigurationError(
3919
+ `WalletConnect Tron connection failed: ${errorMessage}
3920
+
3921
+ Configuration Details:
3922
+ - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}
3923
+ - Platform: ${errorDetails.telegramPlatform}
3924
+ - Origin: ${origin || "(unknown)"}
3925
+ - Project ID: ${this.projectId ? "Set" : "Missing"}
3926
+ - Network: ${network}
3927
+ - Chain ID: ${targetChainId}
3928
+
3929
+ This "Invalid App Configuration" error may be caused by:
3930
+ 1. Deep link (wc://) handling issue in Telegram Mini App
3931
+ 2. Invalid metadata configuration (URL or icons)
3932
+ 3. Network/chainId mismatch
3933
+ 4. Domain not added to WalletConnect Cloud allowlist
3934
+
3935
+ Please check the console for detailed error information.`
3936
+ );
3937
+ }
3938
+ if (isOriginNotAllowed) {
3939
+ throw new ConfigurationError(
3940
+ `WalletConnect Tron relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
3941
+
3942
+ Fix:
3943
+ 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
3944
+ 2) Add this site origin to the allowlist:
3945
+ - ${origin || "(unknown origin)"}
3946
+
3947
+ Common dev origins to allow:
3948
+ - http://localhost:5173
3949
+ - http://192.168.0.221:5173 (your LAN dev URL)
3950
+ - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
3951
+
3952
+ Original error: ${errorMessage}`
3953
+ );
3954
+ }
3955
+ if (isTimeout) {
3956
+ throw new ConnectionRejectedError(
3957
+ `WalletConnect Tron connection timeout. Please try again and ensure your wallet app is open and ready.`
3958
+ );
3959
+ }
3960
+ if (isRejected) {
3961
+ throw new ConnectionRejectedError(this.type);
3962
+ }
3963
+ throw error;
3964
+ }
3965
+ this.currentAddress = address;
3966
+ const account = {
3967
+ universalAddress: createUniversalAddress(targetChainId, address),
3968
+ nativeAddress: address,
3969
+ chainId: targetChainId,
3970
+ chainType: ChainType.TRON,
3971
+ isActive: true
3972
+ };
3973
+ this.setState("connected" /* CONNECTED */);
3974
+ this.setAccount(account);
3975
+ this.setupEventListeners();
3976
+ return account;
3977
+ } catch (error) {
3978
+ this.setState("error" /* ERROR */);
3979
+ this.setAccount(null);
3980
+ this.currentAddress = null;
3981
+ if (error.message?.includes("rejected") || error.code === 4001) {
3982
+ throw new ConnectionRejectedError(this.type);
3983
+ }
3984
+ throw error;
3985
+ }
3986
+ }
3987
+ /**
3988
+ * Disconnect wallet
3989
+ */
3990
+ async disconnect() {
3991
+ this.removeEventListeners();
3992
+ if (this.wallet) {
3993
+ try {
3994
+ await this.wallet.disconnect();
3995
+ } catch (error) {
3996
+ console.warn("[WalletConnect Tron] Error during disconnect:", error);
3997
+ }
3998
+ }
3999
+ this.wallet = null;
4000
+ this.currentAddress = null;
4001
+ this.setState("disconnected" /* DISCONNECTED */);
4002
+ this.setAccount(null);
4003
+ this.emitDisconnected();
4004
+ }
4005
+ /**
4006
+ * Sign message
4007
+ */
4008
+ async signMessage(message) {
4009
+ this.ensureConnected();
4010
+ try {
4011
+ if (!this.wallet) {
4012
+ throw new Error("Wallet not initialized");
4013
+ }
4014
+ const signature = await this.wallet.signMessage(message);
4015
+ if (typeof signature === "string") {
4016
+ return signature;
4017
+ } else if (signature && typeof signature === "object") {
4018
+ if ("signature" in signature) {
4019
+ return signature.signature;
4020
+ } else if ("result" in signature) {
4021
+ return signature.result;
4022
+ } else {
4023
+ return JSON.stringify(signature);
4024
+ }
4025
+ }
4026
+ throw new Error("Invalid signature format returned from wallet");
4027
+ } catch (error) {
4028
+ console.error("[WalletConnect Tron] Sign message error:", error);
4029
+ let errorMessage = "Unknown error";
4030
+ if (typeof error === "string") {
4031
+ errorMessage = error;
4032
+ } else if (error?.message) {
4033
+ errorMessage = error.message;
4034
+ } else if (error?.error?.message) {
4035
+ errorMessage = error.error.message;
4036
+ } else {
4037
+ try {
4038
+ errorMessage = JSON.stringify(error);
4039
+ } catch {
4040
+ errorMessage = String(error);
4041
+ }
4042
+ }
4043
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
4044
+ throw new SignatureRejectedError();
4045
+ }
4046
+ if (errorMessage?.includes("not supported") || errorMessage?.includes("method not found") || errorMessage?.includes("Method not found") || error?.code === -32601 || error?.error?.code === -32601) {
4047
+ 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.");
4048
+ }
4049
+ throw new Error(`WalletConnect Tron sign message failed: ${errorMessage}`);
4050
+ }
4051
+ }
4052
+ /**
4053
+ * Sign transaction
4054
+ *
4055
+ * @param transaction - Tron transaction object
4056
+ * Can be created using TronWeb (if available) or any TRON transaction builder
4057
+ * Format: { raw_data: {...}, raw_data_hex: "...", txID: "..." }
4058
+ * @returns Signed transaction object or signature
4059
+ */
4060
+ async signTransaction(transaction) {
4061
+ this.ensureConnected();
4062
+ try {
4063
+ if (!this.wallet) {
4064
+ throw new Error("Wallet not initialized");
4065
+ }
4066
+ if (!transaction) {
4067
+ throw new Error("Transaction object is required");
4068
+ }
4069
+ console.log("[WalletConnect Tron] Signing transaction:", {
4070
+ hasRawData: !!transaction.raw_data,
4071
+ hasRawDataHex: !!transaction.raw_data_hex,
4072
+ hasTxID: !!transaction.txID
4073
+ });
4074
+ const result = await this.wallet.signTransaction(transaction);
4075
+ if (typeof result === "string") {
4076
+ return result;
4077
+ } else if (result && typeof result === "object") {
4078
+ if ("txID" in result && typeof result.txID === "string") {
4079
+ return result.txID;
4080
+ } else if ("txid" in result && typeof result.txid === "string") {
4081
+ return result.txid;
4082
+ } else if ("signature" in result) {
4083
+ return JSON.stringify(result);
4084
+ } else {
4085
+ return JSON.stringify(result);
4086
+ }
4087
+ }
4088
+ throw new Error("Invalid signature format returned from wallet");
4089
+ } catch (error) {
4090
+ console.error("[WalletConnect Tron] Sign transaction error:", error);
4091
+ let errorMessage = "Unknown error";
4092
+ if (typeof error === "string") {
4093
+ errorMessage = error;
4094
+ } else if (error?.message) {
4095
+ errorMessage = error.message;
4096
+ } else if (error?.error?.message) {
4097
+ errorMessage = error.error.message;
4098
+ } else if (error?.data?.message) {
4099
+ errorMessage = error.data.message;
4100
+ } else {
4101
+ try {
4102
+ errorMessage = JSON.stringify(error);
4103
+ } catch {
4104
+ errorMessage = String(error);
4105
+ }
4106
+ }
4107
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
4108
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
4109
+ }
4110
+ 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) {
4111
+ 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.");
4112
+ }
4113
+ throw new Error(`WalletConnect Tron sign transaction failed: ${errorMessage}`);
4114
+ }
4115
+ }
4116
+ /**
4117
+ * Read contract (not supported by WalletConnect)
4118
+ */
4119
+ async readContract(_params) {
4120
+ this.ensureConnected();
4121
+ 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.");
4122
+ }
4123
+ /**
4124
+ * Write contract (not yet implemented)
4125
+ */
4126
+ async writeContract(_params) {
4127
+ throw new Error("Contract write not yet implemented for WalletConnect Tron");
4128
+ }
4129
+ /**
4130
+ * Estimate gas (not yet implemented)
4131
+ */
4132
+ async estimateGas(_params) {
4133
+ throw new Error("Gas estimation not yet implemented for WalletConnect Tron");
4134
+ }
4135
+ /**
4136
+ * Wait for transaction (not yet implemented)
4137
+ */
4138
+ async waitForTransaction(_txHash, _confirmations) {
4139
+ throw new Error("Transaction waiting not yet implemented for WalletConnect Tron");
4140
+ }
4141
+ /**
4142
+ * Setup event listeners
4143
+ */
4144
+ setupEventListeners() {
4145
+ if (!this.wallet) {
4146
+ return;
4147
+ }
4148
+ this.wallet.on("accountsChanged", (accounts) => {
4149
+ if (accounts && accounts.length > 0 && accounts[0] !== this.currentAddress) {
4150
+ const newAddress = accounts[0];
4151
+ this.currentAddress = newAddress;
4152
+ if (this.currentAccount) {
4153
+ const newAccount = {
4154
+ ...this.currentAccount,
4155
+ nativeAddress: newAddress,
4156
+ universalAddress: createUniversalAddress(this.currentAccount.chainId, newAddress)
4157
+ };
4158
+ this.setAccount(newAccount);
4159
+ this.emit("accountChanged", newAccount);
4160
+ }
4161
+ } else if (!accounts || accounts.length === 0) {
4162
+ this.disconnect();
4163
+ }
4164
+ });
4165
+ this.wallet.on("disconnect", () => {
4166
+ this.disconnect();
4167
+ });
4168
+ }
4169
+ /**
4170
+ * Remove event listeners
4171
+ */
4172
+ removeEventListeners() {
4173
+ if (!this.wallet) {
4174
+ return;
4175
+ }
4176
+ this.wallet.removeAllListeners("accountsChanged");
4177
+ this.wallet.removeAllListeners("disconnect");
4178
+ }
4179
+ /**
4180
+ * Get provider (returns wallet instance)
4181
+ */
4182
+ getProvider() {
4183
+ return this.wallet;
4184
+ }
4185
+ /**
4186
+ * Clear static wallet instance (for complete cleanup)
4187
+ */
4188
+ static clearWalletInstance() {
4189
+ if (_WalletConnectTronAdapter.walletInstance) {
4190
+ _WalletConnectTronAdapter.walletInstance.disconnect().catch(() => {
4191
+ });
4192
+ _WalletConnectTronAdapter.walletInstance = null;
4193
+ _WalletConnectTronAdapter.walletProjectId = null;
4194
+ }
4195
+ }
4196
+ };
4197
+ // Tron 主网链 ID
4198
+ _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID = 195;
4199
+ // Static wallet instance to avoid multiple initializations
4200
+ _WalletConnectTronAdapter.walletInstance = null;
4201
+ _WalletConnectTronAdapter.walletProjectId = null;
4202
+ var WalletConnectTronAdapter = _WalletConnectTronAdapter;
4203
+
4204
+ // src/internal/walletconnect-tron-loader.esm.ts
4205
+ function loadWalletConnectTronModule() {
4206
+ return wallet_connect_exports;
4207
+ }
4208
+
4209
+ // src/adapters/deep-link/adapter.ts
4210
+ init_types();
4211
+ var DeepLinkProviderType = /* @__PURE__ */ ((DeepLinkProviderType2) => {
4212
+ DeepLinkProviderType2["TOKENPOCKET"] = "tokenpocket";
4213
+ DeepLinkProviderType2["TRONLINK"] = "tronlink";
4214
+ DeepLinkProviderType2["IMTOKEN"] = "imtoken";
4215
+ DeepLinkProviderType2["METAMASK"] = "metamask";
4216
+ DeepLinkProviderType2["OKX"] = "okx";
4217
+ return DeepLinkProviderType2;
4218
+ })(DeepLinkProviderType || {});
4219
+ var _DeepLinkAdapter = class _DeepLinkAdapter extends WalletAdapter {
4220
+ constructor(config) {
4221
+ super();
4222
+ this.currentChainId = null;
4223
+ this.currentChainType = null;
4224
+ this.provider = this.createProvider(config);
4225
+ this.name = `${this.provider.name} (Deep Link)`;
4226
+ this.icon = this.provider.icon;
4227
+ if (this.provider.supportedChainTypes.includes(ChainType.EVM)) {
4228
+ this.chainType = ChainType.EVM;
4229
+ this.type = "deep-link-evm" /* DEEP_LINK_EVM */;
4230
+ } else if (this.provider.supportedChainTypes.includes(ChainType.TRON)) {
4231
+ this.chainType = ChainType.TRON;
4232
+ this.type = "deep-link-tron" /* DEEP_LINK_TRON */;
4233
+ } else {
4234
+ this.chainType = ChainType.EVM;
4235
+ this.type = "deep-link-evm" /* DEEP_LINK_EVM */;
4236
+ }
4237
+ if (typeof window !== "undefined") {
4238
+ this.setupCallbackHandler();
4239
+ }
4240
+ }
4241
+ /**
4242
+ * Create provider instance based on type
4243
+ */
4244
+ createProvider(config) {
4245
+ switch (config.providerType) {
4246
+ case "tokenpocket" /* TOKENPOCKET */: {
4247
+ const { TokenPocketDeepLinkProvider: TokenPocketDeepLinkProvider2 } = (init_tokenpocket(), __toCommonJS(tokenpocket_exports));
4248
+ return new TokenPocketDeepLinkProvider2({
4249
+ callbackUrl: config.callbackUrl,
4250
+ callbackSchema: config.callbackSchema
4251
+ });
4252
+ }
4253
+ case "tronlink" /* TRONLINK */: {
4254
+ const { TronLinkDeepLinkProvider: TronLinkDeepLinkProvider2 } = (init_tronlink(), __toCommonJS(tronlink_exports));
4255
+ return new TronLinkDeepLinkProvider2();
4256
+ }
4257
+ case "imtoken" /* IMTOKEN */: {
4258
+ const { ImTokenDeepLinkProvider: ImTokenDeepLinkProvider2 } = (init_imtoken(), __toCommonJS(imtoken_exports));
4259
+ return new ImTokenDeepLinkProvider2({
4260
+ callbackUrl: config.callbackUrl,
4261
+ callbackSchema: config.callbackSchema
4262
+ });
4263
+ }
4264
+ case "metamask" /* METAMASK */: {
4265
+ const { MetaMaskDeepLinkProvider: MetaMaskDeepLinkProvider2 } = (init_metamask(), __toCommonJS(metamask_exports));
4266
+ return new MetaMaskDeepLinkProvider2();
4267
+ }
4268
+ case "okx" /* OKX */: {
4269
+ const { OKXDeepLinkProvider: OKXDeepLinkProvider2 } = (init_okx(), __toCommonJS(okx_exports));
4270
+ return new OKXDeepLinkProvider2();
4271
+ }
4272
+ default:
4273
+ throw new Error(`Unsupported deep link provider type: ${config.providerType}`);
4274
+ }
4275
+ }
4276
+ /**
4277
+ * Setup callback handler for deep link results
4278
+ */
4279
+ setupCallbackHandler() {
4280
+ if (typeof window === "undefined") {
4281
+ return;
4282
+ }
4283
+ const handleUrlChange = () => {
4284
+ const urlParams = new URLSearchParams(window.location.search);
4285
+ const result = this.provider.parseCallbackResult(urlParams);
4286
+ if (result.actionId && _DeepLinkAdapter.pendingActions.has(result.actionId)) {
4287
+ const callback = _DeepLinkAdapter.pendingActions.get(result.actionId);
4288
+ if (result.error) {
4289
+ callback.reject(new Error(result.error));
4290
+ } else if (result.result) {
4291
+ callback.resolve(result.result);
4292
+ }
4293
+ _DeepLinkAdapter.pendingActions.delete(result.actionId);
4294
+ }
4295
+ };
4296
+ window.addEventListener("popstate", handleUrlChange);
4297
+ window.addEventListener("hashchange", handleUrlChange);
4298
+ handleUrlChange();
4299
+ }
4300
+ /**
4301
+ * Check if deep link is available
4302
+ */
4303
+ async isAvailable() {
4304
+ return this.provider.isAvailable();
4305
+ }
4306
+ /**
4307
+ * Connect to wallet via deep link
4308
+ *
4309
+ * Note: Deep links typically don't support persistent connections
4310
+ * This method may throw ConnectionRejectedError as deep links are
4311
+ * primarily used for signing operations, not connection
4312
+ */
4313
+ async connect(chainId) {
4314
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId || 1;
4315
+ let chainType;
4316
+ if (targetChainId === 195) {
4317
+ chainType = ChainType.TRON;
4318
+ } else {
4319
+ chainType = ChainType.EVM;
4320
+ }
4321
+ if (!this.provider.supportedChainTypes.includes(chainType)) {
4322
+ throw new Error(
4323
+ `Provider ${this.provider.name} does not support chain type ${chainType}`
4324
+ );
4325
+ }
4326
+ if (this.provider.buildConnectLink) {
4327
+ const linkInfo = this.provider.buildConnectLink({
4328
+ chainId: targetChainId,
4329
+ chainType
4330
+ });
4331
+ if (linkInfo.actionId) {
4332
+ return new Promise((resolve, reject) => {
4333
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, {
4334
+ resolve: (result) => {
4335
+ const address = result?.address || result?.account || result;
4336
+ if (!address || typeof address !== "string") {
4337
+ reject(new ConnectionRejectedError("Invalid connection result: no address found"));
4338
+ return;
4339
+ }
4340
+ const account = {
4341
+ universalAddress: createUniversalAddress(targetChainId, address),
4342
+ nativeAddress: address,
4343
+ chainId: targetChainId,
4344
+ chainType,
4345
+ isActive: true
4346
+ };
4347
+ this.setState("connected" /* CONNECTED */);
4348
+ this.setAccount(account);
4349
+ this.emit("connected", account);
4350
+ resolve(account);
4351
+ },
4352
+ reject: (error) => {
4353
+ this.setState("disconnected" /* DISCONNECTED */);
4354
+ reject(error);
4355
+ }
4356
+ });
4357
+ window.location.href = linkInfo.url;
4358
+ setTimeout(() => {
4359
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4360
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4361
+ this.setState("disconnected" /* DISCONNECTED */);
4362
+ reject(new ConnectionRejectedError("Deep link connection timeout"));
4363
+ }
4364
+ }, 3e4);
4365
+ });
4366
+ } else {
4367
+ window.location.href = linkInfo.url;
4368
+ throw new ConnectionRejectedError(
4369
+ "Deep link connection initiated. Please complete the connection in your wallet app."
4370
+ );
4371
+ }
4372
+ } else {
4373
+ throw new ConnectionRejectedError(
4374
+ `Deep link connection is not supported by ${this.provider.name}. Deep links are primarily used for signing operations.`
4375
+ );
4376
+ }
4377
+ }
4378
+ /**
4379
+ * Disconnect from wallet
4380
+ */
4381
+ async disconnect() {
4382
+ this.setState("disconnected" /* DISCONNECTED */);
4383
+ this.setAccount(null);
4384
+ this.currentChainId = null;
4385
+ this.currentChainType = null;
4386
+ this.emitDisconnected();
4387
+ }
4388
+ /**
4389
+ * Sign a message
4390
+ */
4391
+ async signMessage(message) {
4392
+ this.ensureConnected();
4393
+ if (!this.currentChainId || !this.currentChainType) {
4394
+ throw new WalletNotConnectedError(this.type);
4395
+ }
4396
+ const linkInfo = this.provider.buildSignMessageLink({
4397
+ message,
4398
+ chainId: this.currentChainId,
4399
+ chainType: this.currentChainType
4400
+ });
4401
+ if (linkInfo.callbackSchema || linkInfo.callbackUrl) {
4402
+ return new Promise((resolve, reject) => {
4403
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, { resolve, reject });
4404
+ window.location.href = linkInfo.url;
4405
+ setTimeout(() => {
4406
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4407
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4408
+ reject(new SignatureRejectedError("Message signature timeout"));
4409
+ }
4410
+ }, 3e4);
4411
+ });
4412
+ } else {
4413
+ window.location.href = linkInfo.url;
4414
+ throw new SignatureRejectedError(
4415
+ "Deep link signature initiated. Please complete the signature in your wallet app."
4416
+ );
4417
+ }
4418
+ }
4419
+ /**
4420
+ * Sign a transaction
4421
+ */
4422
+ async signTransaction(transaction) {
4423
+ this.ensureConnected();
4424
+ if (!this.currentChainId || !this.currentChainType) {
4425
+ throw new WalletNotConnectedError(this.type);
4426
+ }
4427
+ const linkInfo = this.provider.buildSignTransactionLink({
4428
+ transaction,
4429
+ chainId: this.currentChainId,
4430
+ chainType: this.currentChainType
4431
+ });
4432
+ if (linkInfo.callbackSchema || linkInfo.callbackUrl) {
4433
+ return new Promise((resolve, reject) => {
4434
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, { resolve, reject });
4435
+ window.location.href = linkInfo.url;
4436
+ setTimeout(() => {
4437
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4438
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4439
+ reject(new SignatureRejectedError("Transaction signature timeout"));
4440
+ }
4441
+ }, 3e4);
4442
+ });
4443
+ } else {
4444
+ window.location.href = linkInfo.url;
4445
+ throw new SignatureRejectedError(
4446
+ "Deep link transaction signature initiated. Please complete the signature in your wallet app."
4447
+ );
4448
+ }
4449
+ }
4450
+ /**
4451
+ * Get provider (not applicable for deep links)
4452
+ */
4453
+ getProvider() {
4454
+ return null;
4455
+ }
4456
+ /**
4457
+ * Static method to handle callback from wallet apps
4458
+ * This can be called from anywhere in the application
4459
+ */
4460
+ static handleCallback() {
4461
+ if (typeof window === "undefined") {
4462
+ return;
4463
+ }
4464
+ const urlParams = new URLSearchParams(window.location.search);
4465
+ const actionId = urlParams.get("actionId");
4466
+ if (actionId && _DeepLinkAdapter.pendingActions.has(actionId)) {
4467
+ const callback = _DeepLinkAdapter.pendingActions.get(actionId);
4468
+ const result = urlParams.get("result");
4469
+ const error = urlParams.get("error");
4470
+ if (error) {
4471
+ callback.reject(new Error(error));
4472
+ } else if (result) {
4473
+ try {
4474
+ const parsedResult = JSON.parse(decodeURIComponent(result));
4475
+ callback.resolve(parsedResult);
4476
+ } catch (e) {
4477
+ callback.resolve(result);
4478
+ }
4479
+ }
4480
+ _DeepLinkAdapter.pendingActions.delete(actionId);
4481
+ }
4482
+ }
4483
+ /**
4484
+ * Set current account (called after successful connection)
4485
+ */
4486
+ setAccount(account) {
4487
+ this.currentAccount = account;
4488
+ if (account) {
4489
+ this.currentChainId = account.chainId;
4490
+ this.currentChainType = account.chainType;
4491
+ }
4492
+ }
4493
+ /**
4494
+ * Emit disconnected event
4495
+ */
4496
+ emitDisconnected() {
4497
+ this.emit("disconnected");
4498
+ }
4499
+ };
4500
+ // Static map to store pending actions across all instances
4501
+ // Key: actionId, Value: { resolve, reject }
4502
+ _DeepLinkAdapter.pendingActions = /* @__PURE__ */ new Map();
4503
+ var DeepLinkAdapter = _DeepLinkAdapter;
4504
+
4505
+ // src/core/adapter-registry.ts
4506
+ var AdapterRegistry = class {
4507
+ constructor(config = {}) {
4508
+ this.adapters = /* @__PURE__ */ new Map();
4509
+ this.config = config;
4510
+ this.registerDefaultAdapters();
4511
+ }
4512
+ /**
4513
+ * Register default adapters
4514
+ */
4515
+ registerDefaultAdapters() {
4516
+ this.register("metamask" /* METAMASK */, () => new MetaMaskAdapter());
4517
+ this.register("private-key" /* PRIVATE_KEY */, () => new EVMPrivateKeyAdapter());
4518
+ if (this.config.walletConnectProjectId) {
4519
+ this.register(
4520
+ "walletconnect" /* WALLETCONNECT */,
4521
+ () => new WalletConnectAdapter(this.config.walletConnectProjectId)
4522
+ );
4523
+ this.register("walletconnect-tron" /* WALLETCONNECT_TRON */, () => {
4524
+ const { WalletConnectTronAdapter: WalletConnectTronAdapter2 } = loadWalletConnectTronModule();
4525
+ return new WalletConnectTronAdapter2(this.config.walletConnectProjectId);
4526
+ });
4527
+ }
4528
+ this.register("tronlink" /* TRONLINK */, () => new TronLinkAdapter());
4529
+ this.register(
4530
+ "deep-link-evm" /* DEEP_LINK_EVM */,
4531
+ () => new DeepLinkAdapter({
4532
+ providerType: "tokenpocket" /* TOKENPOCKET */
4533
+ })
4534
+ );
4535
+ this.register(
4536
+ "deep-link-tron" /* DEEP_LINK_TRON */,
4537
+ () => new DeepLinkAdapter({
4538
+ providerType: "tokenpocket" /* TOKENPOCKET */
4539
+ })
4540
+ );
4541
+ }
4542
+ /**
4543
+ * Register adapter
4544
+ */
4545
+ register(type, factory) {
4546
+ this.adapters.set(type, factory);
4547
+ }
4548
+ /**
4549
+ * Get adapter
4550
+ */
4551
+ getAdapter(type) {
4552
+ const factory = this.adapters.get(type);
4553
+ if (!factory) {
4554
+ return null;
4555
+ }
4556
+ return factory();
4557
+ }
4558
+ /**
4559
+ * Check if adapter is registered
4560
+ */
4561
+ has(type) {
4562
+ return this.adapters.has(type);
4563
+ }
1668
4564
  /**
1669
4565
  * Get all registered adapter types
1670
4566
  */
1671
- getRegisteredTypes() {
1672
- return Array.from(this.adapters.keys());
4567
+ getRegisteredTypes() {
4568
+ return Array.from(this.adapters.keys());
4569
+ }
4570
+ /**
4571
+ * 根据链类型获取适配器类型列表
4572
+ */
4573
+ getAdapterTypesByChainType(chainType) {
4574
+ const types = [];
4575
+ for (const type of this.adapters.keys()) {
4576
+ const adapter = this.getAdapter(type);
4577
+ if (adapter && adapter.chainType === chainType) {
4578
+ types.push(type);
4579
+ }
4580
+ }
4581
+ return types;
4582
+ }
4583
+ };
4584
+
4585
+ // src/core/wallet-manager.ts
4586
+ init_types();
4587
+ var QRCodeSignStatus = /* @__PURE__ */ ((QRCodeSignStatus2) => {
4588
+ QRCodeSignStatus2["WAITING"] = "waiting";
4589
+ QRCodeSignStatus2["PENDING"] = "pending";
4590
+ QRCodeSignStatus2["SUCCESS"] = "success";
4591
+ QRCodeSignStatus2["FAILED"] = "failed";
4592
+ QRCodeSignStatus2["TIMEOUT"] = "timeout";
4593
+ QRCodeSignStatus2["CANCELLED"] = "cancelled";
4594
+ return QRCodeSignStatus2;
4595
+ })(QRCodeSignStatus || {});
4596
+ var QRCodeSigner = class {
4597
+ constructor(config) {
4598
+ this.pollTimer = null;
4599
+ this.timeoutTimer = null;
4600
+ this.status = "waiting" /* WAITING */;
4601
+ this.qrCodeDataUrl = null;
4602
+ this.result = null;
4603
+ this.config = {
4604
+ requestId: config.requestId,
4605
+ requestUrl: config.requestUrl,
4606
+ pollUrl: config.pollUrl || "",
4607
+ pollInterval: config.pollInterval || 2e3,
4608
+ timeout: config.timeout || 3e5,
4609
+ // 5 minutes
4610
+ pollFn: config.pollFn
4611
+ };
4612
+ }
4613
+ /**
4614
+ * 生成二维码图片(Data URL)
4615
+ */
4616
+ async generateQRCode(options) {
4617
+ if (this.qrCodeDataUrl) {
4618
+ return this.qrCodeDataUrl;
4619
+ }
4620
+ try {
4621
+ const qrCodeOptions = {
4622
+ width: options?.width || 300,
4623
+ margin: options?.margin || 2,
4624
+ color: {
4625
+ dark: options?.color?.dark || "#000000",
4626
+ light: options?.color?.light || "#FFFFFF"
4627
+ }
4628
+ };
4629
+ this.qrCodeDataUrl = await QRCode.toDataURL(this.config.requestUrl, qrCodeOptions);
4630
+ return this.qrCodeDataUrl;
4631
+ } catch (error) {
4632
+ throw new Error(`Failed to generate QR code: ${error instanceof Error ? error.message : String(error)}`);
4633
+ }
4634
+ }
4635
+ /**
4636
+ * 开始轮询签名结果
4637
+ */
4638
+ async startPolling(onStatusChange, onResult) {
4639
+ if (this.status === "success" /* SUCCESS */ && this.result?.signature) {
4640
+ return this.result.signature;
4641
+ }
4642
+ if (this.status === "cancelled" /* CANCELLED */ || this.status === "timeout" /* TIMEOUT */) {
4643
+ throw new SignatureRejectedError("Signature request was cancelled or timed out");
4644
+ }
4645
+ this.timeoutTimer = setTimeout(() => {
4646
+ this.stopPolling();
4647
+ this.status = "timeout" /* TIMEOUT */;
4648
+ onStatusChange?.(this.status);
4649
+ throw new SignatureRejectedError("Signature request timed out");
4650
+ }, this.config.timeout);
4651
+ return new Promise((resolve, reject) => {
4652
+ const poll = async () => {
4653
+ try {
4654
+ let result = null;
4655
+ if (this.config.pollFn) {
4656
+ result = await this.config.pollFn(this.config.requestId);
4657
+ } else if (this.config.pollUrl) {
4658
+ result = await this.defaultPoll(this.config.requestId);
4659
+ } else {
4660
+ return;
4661
+ }
4662
+ if (result?.completed) {
4663
+ this.stopPolling();
4664
+ this.result = result;
4665
+ if (result.signature) {
4666
+ this.status = "success" /* SUCCESS */;
4667
+ onStatusChange?.(this.status);
4668
+ onResult?.(result);
4669
+ resolve(result.signature);
4670
+ } else if (result.error) {
4671
+ this.status = "failed" /* FAILED */;
4672
+ onStatusChange?.(this.status);
4673
+ reject(new SignatureRejectedError(result.error));
4674
+ }
4675
+ } else if (result) {
4676
+ if (this.status === "waiting" /* WAITING */) {
4677
+ this.status = "pending" /* PENDING */;
4678
+ onStatusChange?.(this.status);
4679
+ }
4680
+ this.pollTimer = setTimeout(poll, this.config.pollInterval);
4681
+ } else {
4682
+ this.pollTimer = setTimeout(poll, this.config.pollInterval);
4683
+ }
4684
+ } catch (error) {
4685
+ this.stopPolling();
4686
+ this.status = "failed" /* FAILED */;
4687
+ onStatusChange?.(this.status);
4688
+ reject(error);
4689
+ }
4690
+ };
4691
+ poll();
4692
+ });
1673
4693
  }
1674
4694
  /**
1675
- * 根据链类型获取适配器类型列表
4695
+ * 默认 HTTP 轮询函数
1676
4696
  */
1677
- getAdapterTypesByChainType(chainType) {
1678
- const types = [];
1679
- for (const type of this.adapters.keys()) {
1680
- const adapter = this.getAdapter(type);
1681
- if (adapter && adapter.chainType === chainType) {
1682
- types.push(type);
4697
+ async defaultPoll(requestId) {
4698
+ if (!this.config.pollUrl) {
4699
+ return null;
4700
+ }
4701
+ try {
4702
+ const url = `${this.config.pollUrl}?requestId=${encodeURIComponent(requestId)}`;
4703
+ const response = await fetch(url, {
4704
+ method: "GET",
4705
+ headers: {
4706
+ "Content-Type": "application/json"
4707
+ }
4708
+ });
4709
+ if (!response.ok) {
4710
+ if (response.status === 404) {
4711
+ return null;
4712
+ }
4713
+ throw new NetworkError(`Poll request failed: ${response.statusText}`);
4714
+ }
4715
+ const data = await response.json();
4716
+ return {
4717
+ completed: data.completed === true,
4718
+ signature: data.signature,
4719
+ error: data.error,
4720
+ signer: data.signer
4721
+ };
4722
+ } catch (error) {
4723
+ if (error instanceof NetworkError) {
4724
+ throw error;
1683
4725
  }
4726
+ return null;
1684
4727
  }
1685
- return types;
4728
+ }
4729
+ /**
4730
+ * 停止轮询
4731
+ */
4732
+ stopPolling() {
4733
+ if (this.pollTimer) {
4734
+ clearTimeout(this.pollTimer);
4735
+ this.pollTimer = null;
4736
+ }
4737
+ if (this.timeoutTimer) {
4738
+ clearTimeout(this.timeoutTimer);
4739
+ this.timeoutTimer = null;
4740
+ }
4741
+ }
4742
+ /**
4743
+ * 取消签名请求
4744
+ */
4745
+ cancel() {
4746
+ this.stopPolling();
4747
+ this.status = "cancelled" /* CANCELLED */;
4748
+ }
4749
+ /**
4750
+ * 获取当前状态
4751
+ */
4752
+ getStatus() {
4753
+ return this.status;
4754
+ }
4755
+ /**
4756
+ * 获取二维码 URL
4757
+ */
4758
+ getQRCodeUrl() {
4759
+ return this.config.requestUrl;
4760
+ }
4761
+ /**
4762
+ * 获取结果
4763
+ */
4764
+ getResult() {
4765
+ return this.result;
4766
+ }
4767
+ /**
4768
+ * 清理资源
4769
+ */
4770
+ cleanup() {
4771
+ this.stopPolling();
4772
+ this.qrCodeDataUrl = null;
4773
+ this.result = null;
4774
+ this.status = "waiting" /* WAITING */;
1686
4775
  }
1687
4776
  };
1688
4777
 
@@ -1701,9 +4790,15 @@ var WalletManager = class extends TypedEventEmitter {
1701
4790
  defaultTronChainId: config.defaultTronChainId ?? 195,
1702
4791
  walletConnectProjectId: config.walletConnectProjectId ?? ""
1703
4792
  };
1704
- this.registry = new AdapterRegistry();
4793
+ this.registry = new AdapterRegistry(this.config);
1705
4794
  }
1706
4795
  // ===== Connection Management =====
4796
+ /**
4797
+ * Check if adapter is registered for a wallet type
4798
+ */
4799
+ hasAdapter(type) {
4800
+ return this.registry.has(type);
4801
+ }
1707
4802
  /**
1708
4803
  * Connect primary wallet
1709
4804
  */
@@ -1770,7 +4865,7 @@ var WalletManager = class extends TypedEventEmitter {
1770
4865
  this.connectedWallets.delete(chainType);
1771
4866
  this.primaryWallet = null;
1772
4867
  if (this.config.enableStorage) {
1773
- this.saveToStorage();
4868
+ this.clearStorage();
1774
4869
  }
1775
4870
  this.emit("disconnected");
1776
4871
  }
@@ -1859,6 +4954,35 @@ var WalletManager = class extends TypedEventEmitter {
1859
4954
  }
1860
4955
  return adapter.signMessage(message);
1861
4956
  }
4957
+ /**
4958
+ * Create QR code signer for message signing
4959
+ *
4960
+ * This method creates a QR code signer that can be used to display a QR code
4961
+ * for users to scan with their wallet app to sign a message.
4962
+ *
4963
+ * @param message - Message to sign
4964
+ * @param config - QR code signer configuration
4965
+ * @returns QRCodeSigner instance
4966
+ *
4967
+ * @example
4968
+ * ```typescript
4969
+ * const signer = walletManager.createQRCodeSigner('Hello World', {
4970
+ * requestId: 'sign-123',
4971
+ * requestUrl: 'https://example.com/sign?requestId=sign-123&message=Hello%20World',
4972
+ * pollUrl: 'https://api.example.com/sign/status',
4973
+ * })
4974
+ *
4975
+ * const qrCodeUrl = await signer.generateQRCode()
4976
+ * const signature = await signer.startPolling()
4977
+ * ```
4978
+ */
4979
+ createQRCodeSigner(message, config) {
4980
+ return new QRCodeSigner({
4981
+ ...config,
4982
+ // Encode message in request URL if not already encoded
4983
+ requestUrl: config.requestUrl.includes(encodeURIComponent(message)) ? config.requestUrl : `${config.requestUrl}${config.requestUrl.includes("?") ? "&" : "?"}message=${encodeURIComponent(message)}`
4984
+ });
4985
+ }
1862
4986
  /**
1863
4987
  * Sign TypedData (EVM only)
1864
4988
  */
@@ -1923,6 +5047,41 @@ var WalletManager = class extends TypedEventEmitter {
1923
5047
  throw error;
1924
5048
  }
1925
5049
  }
5050
+ /**
5051
+ * Request account switch (opens wallet account selector)
5052
+ * @param targetAddress Optional target address to verify after switching
5053
+ * @returns The new account after switching
5054
+ */
5055
+ async requestSwitchAccount(targetAddress) {
5056
+ if (!this.primaryWallet) {
5057
+ throw new WalletNotConnectedError();
5058
+ }
5059
+ if (!this.primaryWallet.requestSwitchAccount) {
5060
+ throw new Error(`Account switching not supported by ${this.primaryWallet.type}`);
5061
+ }
5062
+ const account = await this.primaryWallet.requestSwitchAccount(targetAddress);
5063
+ if (this.config.enableStorage) {
5064
+ this.saveToStorage();
5065
+ }
5066
+ return account;
5067
+ }
5068
+ /**
5069
+ * Ensure the current account matches the target address
5070
+ * If not matching, request account switch
5071
+ * @param targetAddress The address that should be active
5072
+ * @returns The account (either existing or after switch)
5073
+ */
5074
+ async ensureAccount(targetAddress) {
5075
+ const currentAccount = this.getPrimaryAccount();
5076
+ if (!currentAccount) {
5077
+ throw new WalletNotConnectedError();
5078
+ }
5079
+ if (currentAccount.nativeAddress.toLowerCase() === targetAddress.toLowerCase()) {
5080
+ return currentAccount;
5081
+ }
5082
+ console.log(`[WalletManager] Current account ${currentAccount.nativeAddress} doesn't match target ${targetAddress}, requesting switch...`);
5083
+ return this.requestSwitchAccount(targetAddress);
5084
+ }
1926
5085
  // ===== Contract Calls =====
1927
5086
  /**
1928
5087
  * Read contract
@@ -2169,6 +5328,29 @@ var WalletManager = class extends TypedEventEmitter {
2169
5328
  console.debug("Silent TronLink connection failed:", silentError);
2170
5329
  }
2171
5330
  }
5331
+ if (data.primaryWalletType === "walletconnect-tron" /* WALLETCONNECT_TRON */) {
5332
+ try {
5333
+ const wcAdapter = adapter;
5334
+ if (typeof wcAdapter.restoreSession === "function") {
5335
+ console.debug("[WalletManager] Attempting to restore WalletConnect Tron session...");
5336
+ const account2 = await wcAdapter.restoreSession(data.primaryChainId);
5337
+ if (account2) {
5338
+ console.debug("[WalletManager] WalletConnect Tron session restored successfully");
5339
+ this.setPrimaryWallet(adapter);
5340
+ this.connectedWallets.set(adapter.chainType, adapter);
5341
+ this.setupAdapterListeners(adapter, true);
5342
+ this.emit("accountChanged", account2);
5343
+ return account2;
5344
+ } else {
5345
+ console.debug("[WalletManager] No valid WalletConnect Tron session found");
5346
+ return null;
5347
+ }
5348
+ }
5349
+ } catch (restoreError) {
5350
+ console.debug("[WalletManager] WalletConnect Tron restore failed:", restoreError);
5351
+ return null;
5352
+ }
5353
+ }
2172
5354
  const account = await adapter.connect(data.primaryChainId);
2173
5355
  this.setPrimaryWallet(adapter);
2174
5356
  this.connectedWallets.set(adapter.chainType, adapter);
@@ -2215,7 +5397,466 @@ var WalletManager = class extends TypedEventEmitter {
2215
5397
  }
2216
5398
  };
2217
5399
 
5400
+ // src/index.ts
5401
+ init_types();
5402
+ init_tokenpocket();
5403
+ init_tronlink();
5404
+ init_imtoken();
5405
+ init_metamask();
5406
+ init_okx();
5407
+
5408
+ // src/adapters/tron/deep-link.ts
5409
+ init_types();
5410
+ var DeepLinkWalletType = /* @__PURE__ */ ((DeepLinkWalletType2) => {
5411
+ DeepLinkWalletType2["TOKENPOCKET"] = "tokenpocket";
5412
+ DeepLinkWalletType2["TRONLINK"] = "tronlink";
5413
+ return DeepLinkWalletType2;
5414
+ })(DeepLinkWalletType || {});
5415
+ var _TronDeepLinkAdapter = class _TronDeepLinkAdapter extends WalletAdapter {
5416
+ constructor(walletType = "tokenpocket" /* TOKENPOCKET */, options) {
5417
+ super();
5418
+ this.type = "tronlink" /* TRONLINK */;
5419
+ // Reuse TRONLINK type for now
5420
+ this.chainType = ChainType.TRON;
5421
+ this.pendingActions = /* @__PURE__ */ new Map();
5422
+ this.walletType = walletType;
5423
+ this.callbackUrl = options?.callbackUrl;
5424
+ this.callbackSchema = options?.callbackSchema;
5425
+ if (walletType === "tokenpocket" /* TOKENPOCKET */) {
5426
+ this.name = "TokenPocket (Deep Link)";
5427
+ this.icon = "https://tokenpocket.pro/icon.png";
5428
+ } else if (walletType === "tronlink" /* TRONLINK */) {
5429
+ this.name = "TronLink (Deep Link)";
5430
+ this.icon = "https://www.tronlink.org/static/logoIcon.svg";
5431
+ } else {
5432
+ this.name = "TRON Deep Link";
5433
+ this.icon = "https://www.tronlink.org/static/logoIcon.svg";
5434
+ }
5435
+ if (walletType === "tokenpocket" /* TOKENPOCKET */ && typeof window !== "undefined") {
5436
+ this.setupCallbackHandler();
5437
+ }
5438
+ }
5439
+ /**
5440
+ * Setup callback handler for TokenPocket deep link results
5441
+ *
5442
+ * According to TokenPocket docs:
5443
+ * - callbackUrl: Wallet sends result to this URL (server-side callback)
5444
+ * - callbackSchema: Wallet launches H5 app through this schema (client-side callback)
5445
+ *
5446
+ * For H5 apps, we use callbackSchema to receive results in the same page
5447
+ */
5448
+ setupCallbackHandler() {
5449
+ if (typeof window === "undefined") {
5450
+ return;
5451
+ }
5452
+ document.addEventListener("visibilitychange", () => {
5453
+ if (document.visibilityState === "visible") {
5454
+ console.log("[TronDeepLink] Page became visible, user may have returned from wallet app");
5455
+ this.checkCallbackFromUrl();
5456
+ }
5457
+ });
5458
+ this.checkCallbackFromUrl();
5459
+ }
5460
+ /**
5461
+ * Check if callback result is in URL parameters
5462
+ * TokenPocket may append callback results to URL when using callbackSchema
5463
+ */
5464
+ checkCallbackFromUrl() {
5465
+ if (typeof window === "undefined") {
5466
+ return;
5467
+ }
5468
+ const urlParams = new URLSearchParams(window.location.search);
5469
+ const actionId = urlParams.get("actionId");
5470
+ const result = urlParams.get("result");
5471
+ const error = urlParams.get("error");
5472
+ if (actionId && this.pendingActions.has(actionId)) {
5473
+ const { resolve, reject } = this.pendingActions.get(actionId);
5474
+ if (error) {
5475
+ reject(new Error(error));
5476
+ } else if (result) {
5477
+ try {
5478
+ const parsedResult = JSON.parse(decodeURIComponent(result));
5479
+ resolve(parsedResult);
5480
+ } catch (e) {
5481
+ resolve(result);
5482
+ }
5483
+ }
5484
+ this.pendingActions.delete(actionId);
5485
+ const newUrl = window.location.pathname;
5486
+ window.history.replaceState({}, "", newUrl);
5487
+ }
5488
+ }
5489
+ /**
5490
+ * Check if deep link is available (mobile device or Telegram Mini App)
5491
+ *
5492
+ * Note: In Telegram Mini App, we're more lenient - even if platform detection
5493
+ * fails, deep links may still work, so the caller should handle Telegram Mini App
5494
+ * separately if needed.
5495
+ */
5496
+ async isAvailable() {
5497
+ if (typeof window === "undefined") {
5498
+ return false;
5499
+ }
5500
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
5501
+ if (isTelegramMiniApp) {
5502
+ const platform = window.Telegram.WebApp.platform || "unknown";
5503
+ const version = window.Telegram.WebApp.version || "unknown";
5504
+ console.log(`[TronDeepLink] Telegram Mini App detected, platform: ${platform}, version: ${version}`);
5505
+ if (platform === "unknown") {
5506
+ const userAgent = navigator.userAgent || "";
5507
+ if (/iPhone|iPad|iPod/i.test(userAgent)) {
5508
+ console.log(`[TronDeepLink] Detected iOS from user agent`);
5509
+ } else if (/Android/i.test(userAgent)) {
5510
+ console.log(`[TronDeepLink] Detected Android from user agent`);
5511
+ }
5512
+ }
5513
+ return true;
5514
+ }
5515
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
5516
+ navigator.userAgent
5517
+ );
5518
+ return isMobile;
5519
+ }
5520
+ /**
5521
+ * Connect wallet via deep link
5522
+ *
5523
+ * IMPORTANT: Deep links for TRON wallets are primarily for SIGNING, not connection.
5524
+ * TokenPocket and TronLink deep links support:
5525
+ * - Signing transactions: tron:signTransaction-version=1.0&protocol=TokenPocket&network=tron&chain_id=195&data={...}
5526
+ * - Signing messages: tron:signMessage-version=1.0&protocol=TokenPocket&network=tron&chain_id=195&data={...}
5527
+ *
5528
+ * For CONNECTION, you should use:
5529
+ * - WalletConnect (recommended for mobile)
5530
+ * - Browser extension (TronWeb/TronLink)
5531
+ *
5532
+ * Note: You can sign directly using signMessage() or signTransaction() without calling connect() first.
5533
+ * The wallet app will open and use the user's account automatically.
5534
+ *
5535
+ * This method attempts to open the wallet app, but cannot establish a connection
5536
+ * or retrieve the wallet address directly. The user must complete connection
5537
+ * through WalletConnect or browser extension after opening the app.
5538
+ */
5539
+ async connect(chainId) {
5540
+ if (typeof window === "undefined") {
5541
+ throw new Error("Deep link requires a browser environment");
5542
+ }
5543
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _TronDeepLinkAdapter.TRON_MAINNET_CHAIN_ID : chainId || _TronDeepLinkAdapter.TRON_MAINNET_CHAIN_ID;
5544
+ try {
5545
+ this.setState("connecting" /* CONNECTING */);
5546
+ const isAvailable = await this.isAvailable();
5547
+ if (!isAvailable) {
5548
+ const isTelegram = !!(window.Telegram && window.Telegram.WebApp);
5549
+ if (isTelegram) {
5550
+ const platform = window.Telegram?.WebApp?.platform || "unknown";
5551
+ throw new Error(
5552
+ `Deep link is not available in Telegram Mini App on ${platform} platform. Please use WalletConnect or browser extension, or test on a mobile device.`
5553
+ );
5554
+ } else {
5555
+ throw new Error("Deep link is only available on mobile devices or Telegram Mini App. Please use WalletConnect or browser extension.");
5556
+ }
5557
+ }
5558
+ let deepLinkUrl = "";
5559
+ if (this.walletType === "tokenpocket" /* TOKENPOCKET */) {
5560
+ const actionId = `web-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
5561
+ const param = {
5562
+ action: "login",
5563
+ // Login action to open wallet
5564
+ actionId,
5565
+ blockchains: [{
5566
+ chainId: String(targetChainId),
5567
+ network: "tron"
5568
+ }],
5569
+ dappName: "Enclave Wallet SDK",
5570
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
5571
+ protocol: "TokenPocket",
5572
+ version: "1.0",
5573
+ expired: 1602
5574
+ // 30 minutes
5575
+ };
5576
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
5577
+ deepLinkUrl = `tpoutside://pull.activity?param=${encodedParam}`;
5578
+ } else if (this.walletType === "tronlink" /* TRONLINK */) {
5579
+ deepLinkUrl = `tronlink://open?action=connect&network=tron`;
5580
+ }
5581
+ if (!deepLinkUrl) {
5582
+ throw new Error(`Unsupported wallet type: ${this.walletType}`);
5583
+ }
5584
+ console.log(`[TronDeepLink] ===== Connect via Deep Link =====`);
5585
+ console.log(`[TronDeepLink] Wallet Type:`, this.walletType);
5586
+ console.log(`[TronDeepLink] Chain ID:`, targetChainId);
5587
+ console.log(`[TronDeepLink] Deep Link URL:`, deepLinkUrl);
5588
+ console.log(`[TronDeepLink] Note: Deep links are for signing, not connection. After opening the app, please use WalletConnect to establish connection.`);
5589
+ console.log(`[TronDeepLink] ==================================`);
5590
+ window.location.href = deepLinkUrl;
5591
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
5592
+ throw new ConnectionRejectedError(
5593
+ `\u5DF2\u6253\u5F00 ${this.walletType === "tokenpocket" /* TOKENPOCKET */ ? "TokenPocket" : "TronLink"} \u5E94\u7528\u3002
5594
+
5595
+ \u6CE8\u610F\uFF1A\u6DF1\u5EA6\u94FE\u63A5\u4E3B\u8981\u7528\u4E8E\u7B7E\u540D\u4EA4\u6613\uFF0C\u4E0D\u80FD\u76F4\u63A5\u5EFA\u7ACB\u8FDE\u63A5\u3002
5596
+
5597
+ \u8BF7\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u5B8C\u6210\u8FDE\u63A5\uFF1A
5598
+ 1. \u5728\u94B1\u5305\u5E94\u7528\u4E2D\u4F7F\u7528 WalletConnect \u626B\u63CF\u4E8C\u7EF4\u7801
5599
+ 2. \u6216\u4F7F\u7528\u6D4F\u89C8\u5668\u6269\u5C55\uFF08\u5982 TronLink\uFF09\u8FDE\u63A5
5600
+
5601
+ Deep link opened ${this.walletType} app. Please use WalletConnect or browser extension to complete the connection.`
5602
+ );
5603
+ } catch (error) {
5604
+ this.setState("error" /* ERROR */);
5605
+ this.setAccount(null);
5606
+ if (error instanceof ConnectionRejectedError) {
5607
+ throw error;
5608
+ }
5609
+ throw new Error(`Failed to open ${this.walletType} via deep link: ${error.message}`);
5610
+ }
5611
+ }
5612
+ /**
5613
+ * Disconnect wallet
5614
+ */
5615
+ async disconnect() {
5616
+ this.setState("disconnected" /* DISCONNECTED */);
5617
+ this.setAccount(null);
5618
+ }
5619
+ /**
5620
+ * Sign message via deep link
5621
+ *
5622
+ * TokenPocket deep link format for signing:
5623
+ * tron:signMessage-version=1.0&protocol=TokenPocket&network=tron&chain_id=195&data={message}
5624
+ *
5625
+ * Reference: https://help.tokenpocket.pro/developer-cn/scan-protocol/tron
5626
+ *
5627
+ * Note: Deep links can sign directly without establishing a connection first.
5628
+ * The wallet app will open and use the user's account to sign the message.
5629
+ * The signature result will be returned via callback URL or app-to-app communication.
5630
+ */
5631
+ async signMessage(message) {
5632
+ if (typeof window === "undefined") {
5633
+ throw new Error("Deep link requires a browser environment");
5634
+ }
5635
+ const isAvailable = await this.isAvailable();
5636
+ if (!isAvailable) {
5637
+ const isTelegram = !!(window.Telegram && window.Telegram.WebApp);
5638
+ if (isTelegram) {
5639
+ const platform = window.Telegram?.WebApp?.platform || "unknown";
5640
+ throw new Error(
5641
+ `Deep link signing is not available in Telegram Mini App on ${platform} platform. Please use WalletConnect or test on a mobile device.`
5642
+ );
5643
+ } else {
5644
+ throw new Error("Deep link signing is only available on mobile devices or Telegram Mini App.");
5645
+ }
5646
+ }
5647
+ let deepLinkUrl = "";
5648
+ if (this.walletType === "tokenpocket" /* TOKENPOCKET */) {
5649
+ const actionId = `web-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
5650
+ const param = {
5651
+ action: "sign",
5652
+ actionId,
5653
+ message,
5654
+ hash: false,
5655
+ signType: "ethPersonalSign",
5656
+ // For TRON, we use ethPersonalSign as it's similar
5657
+ memo: "TRON message signature",
5658
+ blockchains: [{
5659
+ chainId: "195",
5660
+ // TRON Mainnet chain ID as string
5661
+ network: "tron"
5662
+ }],
5663
+ dappName: "Enclave Wallet SDK",
5664
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
5665
+ protocol: "TokenPocket",
5666
+ version: "1.1.8",
5667
+ expired: 0
5668
+ // No expiration
5669
+ // callbackUrl: optional, if you want to receive callback
5670
+ // callbackSchema: optional, custom schema for callback
5671
+ };
5672
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
5673
+ deepLinkUrl = `tpoutside://pull.activity?param=${encodedParam}`;
5674
+ console.log(`[TronDeepLink] Using TokenPocket tpoutside:// format for signMessage`);
5675
+ console.log(`[TronDeepLink] Param object:`, param);
5676
+ } else if (this.walletType === "tronlink" /* TRONLINK */) {
5677
+ const encodedMessage = encodeURIComponent(message);
5678
+ deepLinkUrl = `tronlink://signMessage?message=${encodedMessage}`;
5679
+ }
5680
+ if (!deepLinkUrl) {
5681
+ throw new MethodNotSupportedError("signMessage", this.type);
5682
+ }
5683
+ console.log(`[TronDeepLink] ===== Sign Message via Deep Link =====`);
5684
+ console.log(`[TronDeepLink] Wallet Type:`, this.walletType);
5685
+ console.log(`[TronDeepLink] Message:`, message);
5686
+ console.log(`[TronDeepLink] Deep Link URL:`, deepLinkUrl);
5687
+ console.log(`[TronDeepLink] Full URL length:`, deepLinkUrl.length);
5688
+ console.log(`[TronDeepLink] ========================================`);
5689
+ window.location.href = deepLinkUrl;
5690
+ throw new Error(
5691
+ `Deep link opened ${this.walletType} for signing. The signature will be handled by the wallet app. This adapter cannot retrieve the signature directly from deep links. Consider using WalletConnect or browser extension for programmatic signing.`
5692
+ );
5693
+ }
5694
+ /**
5695
+ * Sign transaction via deep link
5696
+ *
5697
+ * TokenPocket deep link format:
5698
+ * tron:signTransaction-version=1.0&protocol=TokenPocket&network=tron&chain_id=195&data={transaction}
5699
+ *
5700
+ * Reference: https://help.tokenpocket.pro/developer-cn/scan-protocol/tron
5701
+ *
5702
+ * Note: Deep links can sign directly without establishing a connection first.
5703
+ * The wallet app will open and use the user's account to sign the transaction.
5704
+ * The transaction data should be a JSON string containing the TRON transaction object.
5705
+ * The signature result will be returned via callback URL or app-to-app communication.
5706
+ */
5707
+ async signTransaction(transaction) {
5708
+ if (typeof window === "undefined") {
5709
+ throw new Error("Deep link requires a browser environment");
5710
+ }
5711
+ const isAvailable = await this.isAvailable();
5712
+ if (!isAvailable) {
5713
+ const isTelegram = !!(window.Telegram && window.Telegram.WebApp);
5714
+ if (isTelegram) {
5715
+ const platform = window.Telegram?.WebApp?.platform || "unknown";
5716
+ throw new Error(
5717
+ `Deep link signing is not available in Telegram Mini App on ${platform} platform. Please use WalletConnect or test on a mobile device.`
5718
+ );
5719
+ } else {
5720
+ throw new Error("Deep link signing is only available on mobile devices or Telegram Mini App.");
5721
+ }
5722
+ }
5723
+ let deepLinkUrl = "";
5724
+ let actionId = "";
5725
+ let param = null;
5726
+ if (this.walletType === "tokenpocket" /* TOKENPOCKET */) {
5727
+ actionId = `web-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
5728
+ let transactionData;
5729
+ if (typeof transaction === "string") {
5730
+ transactionData = transaction;
5731
+ } else if (transaction.raw_data_hex) {
5732
+ transactionData = JSON.stringify(transaction);
5733
+ } else {
5734
+ transactionData = JSON.stringify(transaction);
5735
+ }
5736
+ param = {
5737
+ action: "pushTransaction",
5738
+ actionId,
5739
+ txData: transactionData,
5740
+ // Transaction data as JSON string
5741
+ blockchains: [{
5742
+ chainId: "195",
5743
+ // TRON Mainnet chain ID as string
5744
+ network: "tron"
5745
+ }],
5746
+ dappName: "Enclave Wallet SDK",
5747
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
5748
+ protocol: "TokenPocket",
5749
+ version: "1.1.8",
5750
+ expired: 0
5751
+ // No expiration
5752
+ };
5753
+ if (this.callbackSchema) {
5754
+ param.callbackSchema = this.callbackSchema;
5755
+ } else if (this.callbackUrl) {
5756
+ param.callbackUrl = this.callbackUrl;
5757
+ } else {
5758
+ if (typeof window !== "undefined" && window.location) {
5759
+ param.callbackSchema = `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
5760
+ }
5761
+ }
5762
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
5763
+ deepLinkUrl = `tpoutside://pull.activity?param=${encodedParam}`;
5764
+ console.log(`[TronDeepLink] Using TokenPocket tpoutside:// format for signTransaction`);
5765
+ console.log(`[TronDeepLink] Param object (without txData):`, { ...param, txData: "[TRANSACTION DATA]" });
5766
+ } else if (this.walletType === "tronlink" /* TRONLINK */) {
5767
+ const transactionData = typeof transaction === "string" ? transaction : JSON.stringify(transaction);
5768
+ const encodedData = encodeURIComponent(transactionData);
5769
+ deepLinkUrl = `tronlink://signTransaction?transaction=${encodedData}`;
5770
+ }
5771
+ if (!deepLinkUrl) {
5772
+ throw new MethodNotSupportedError("signTransaction", this.type);
5773
+ }
5774
+ console.log(`[TronDeepLink] ===== Sign Transaction via Deep Link =====`);
5775
+ console.log(`[TronDeepLink] Wallet Type:`, this.walletType);
5776
+ console.log(`[TronDeepLink] Transaction:`, transaction);
5777
+ console.log(`[TronDeepLink] Transaction keys:`, transaction ? Object.keys(transaction) : "N/A");
5778
+ if (transaction && typeof transaction === "object") {
5779
+ console.log(`[TronDeepLink] Transaction has raw_data:`, !!transaction.raw_data);
5780
+ console.log(`[TronDeepLink] Transaction has raw_data_hex:`, !!transaction.raw_data_hex);
5781
+ console.log(`[TronDeepLink] Transaction has txID:`, !!transaction.txID);
5782
+ }
5783
+ if (actionId) {
5784
+ console.log(`[TronDeepLink] Action ID:`, actionId);
5785
+ }
5786
+ if (param) {
5787
+ console.log(`[TronDeepLink] Callback Schema:`, param.callbackSchema || param.callbackUrl || "None");
5788
+ }
5789
+ console.log(`[TronDeepLink] Deep Link URL:`, deepLinkUrl);
5790
+ console.log(`[TronDeepLink] Full URL length:`, deepLinkUrl.length);
5791
+ if (deepLinkUrl.length > 200) {
5792
+ console.log(`[TronDeepLink] URL (first 200 chars):`, deepLinkUrl.substring(0, 200) + "...");
5793
+ console.log(`[TronDeepLink] URL (last 100 chars):`, "..." + deepLinkUrl.substring(deepLinkUrl.length - 100));
5794
+ }
5795
+ console.log(`[TronDeepLink] ===========================================`);
5796
+ if (this.walletType === "tokenpocket" /* TOKENPOCKET */ && param && param.callbackSchema) {
5797
+ return new Promise((resolve, reject) => {
5798
+ this.pendingActions.set(actionId, { resolve, reject });
5799
+ window.location.href = deepLinkUrl;
5800
+ setTimeout(() => {
5801
+ if (this.pendingActions.has(actionId)) {
5802
+ this.pendingActions.delete(actionId);
5803
+ reject(new Error("Transaction signature timeout: No response from wallet app"));
5804
+ }
5805
+ }, 3e4);
5806
+ });
5807
+ }
5808
+ window.location.href = deepLinkUrl;
5809
+ throw new SignatureRejectedError(
5810
+ `\u5DF2\u6253\u5F00 ${this.walletType === "tokenpocket" /* TOKENPOCKET */ ? "TokenPocket" : "TronLink"} \u8FDB\u884C\u4EA4\u6613\u7B7E\u540D\u3002
5811
+
5812
+ \u6CE8\u610F\uFF1A\u6DF1\u5EA6\u94FE\u63A5\u65E0\u6CD5\u76F4\u63A5\u8FD4\u56DE\u7B7E\u540D\u7ED3\u679C\u3002
5813
+
5814
+ \u7B7E\u540D\u7ED3\u679C\u5C06\u901A\u8FC7\u4EE5\u4E0B\u65B9\u5F0F\u8FD4\u56DE\uFF1A
5815
+ 1. \u94B1\u5305\u5E94\u7528\u7684\u56DE\u8C03 URL
5816
+ 2. \u5E94\u7528\u95F4\u901A\u4FE1\uFF08App-to-App\uFF09
5817
+
5818
+ \u5982\u9700\u7A0B\u5E8F\u5316\u83B7\u53D6\u7B7E\u540D\uFF0C\u8BF7\u4F7F\u7528 WalletConnect \u6216\u6D4F\u89C8\u5668\u6269\u5C55\u3002
5819
+
5820
+ Deep link opened ${this.walletType} for transaction signing. The signature will be handled by the wallet app via callback. For programmatic signing, use WalletConnect or browser extension.`
5821
+ );
5822
+ }
5823
+ /**
5824
+ * Read contract (not supported via deep link)
5825
+ */
5826
+ async readContract(_params) {
5827
+ throw new MethodNotSupportedError("readContract", this.type);
5828
+ }
5829
+ /**
5830
+ * Write contract (not supported via deep link)
5831
+ */
5832
+ async writeContract(_params) {
5833
+ throw new MethodNotSupportedError("writeContract", this.type);
5834
+ }
5835
+ /**
5836
+ * Estimate gas (not supported)
5837
+ */
5838
+ async estimateGas(_params) {
5839
+ throw new MethodNotSupportedError("estimateGas", this.type);
5840
+ }
5841
+ /**
5842
+ * Wait for transaction (not supported)
5843
+ */
5844
+ async waitForTransaction(_txHash, _confirmations) {
5845
+ throw new MethodNotSupportedError("waitForTransaction", this.type);
5846
+ }
5847
+ /**
5848
+ * Get provider (not applicable for deep links)
5849
+ */
5850
+ getProvider() {
5851
+ return null;
5852
+ }
5853
+ };
5854
+ // TRON Mainnet chain ID
5855
+ _TronDeepLinkAdapter.TRON_MAINNET_CHAIN_ID = 195;
5856
+ var TronDeepLinkAdapter = _TronDeepLinkAdapter;
5857
+
2218
5858
  // src/auth/message-generator.ts
5859
+ init_types();
2219
5860
  var AuthMessageGenerator = class {
2220
5861
  constructor(domain) {
2221
5862
  this.domain = domain;
@@ -2290,6 +5931,9 @@ var AuthMessageGenerator = class {
2290
5931
  return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
2291
5932
  }
2292
5933
  };
5934
+
5935
+ // src/auth/signature-verifier.ts
5936
+ init_types();
2293
5937
  var SignatureVerifier = class {
2294
5938
  /**
2295
5939
  * 验证签名
@@ -2331,7 +5975,11 @@ var SignatureVerifier = class {
2331
5975
  }
2332
5976
  };
2333
5977
 
5978
+ // src/detection/detector.ts
5979
+ init_types();
5980
+
2334
5981
  // src/detection/supported-wallets.ts
5982
+ init_types();
2335
5983
  var SUPPORTED_WALLETS = {
2336
5984
  ["metamask" /* METAMASK */]: {
2337
5985
  type: "metamask" /* METAMASK */,
@@ -2378,6 +6026,20 @@ var SUPPORTED_WALLETS = {
2378
6026
  chainType: ChainType.EVM,
2379
6027
  // 可以用于任何链
2380
6028
  description: "Import wallet using private key (for development)"
6029
+ },
6030
+ ["deep-link-evm" /* DEEP_LINK_EVM */]: {
6031
+ type: "deep-link-evm" /* DEEP_LINK_EVM */,
6032
+ name: "Deep Link (EVM)",
6033
+ chainType: ChainType.EVM,
6034
+ icon: "https://tokenpocket.pro/icon.png",
6035
+ description: "Deep link connection for EVM chains (TokenPocket, ImToken, etc.)"
6036
+ },
6037
+ ["deep-link-tron" /* DEEP_LINK_TRON */]: {
6038
+ type: "deep-link-tron" /* DEEP_LINK_TRON */,
6039
+ name: "Deep Link (TRON)",
6040
+ chainType: ChainType.TRON,
6041
+ icon: "https://tokenpocket.pro/icon.png",
6042
+ description: "Deep link connection for TRON chain (TokenPocket, TronLink, etc.)"
2381
6043
  }
2382
6044
  };
2383
6045
  function getWalletMetadata(type) {
@@ -2525,6 +6187,7 @@ function shortenTronAddress(address, chars = 4) {
2525
6187
  }
2526
6188
 
2527
6189
  // src/utils/validation.ts
6190
+ init_types();
2528
6191
  function validateAddress(address, chainType) {
2529
6192
  switch (chainType) {
2530
6193
  case ChainType.EVM:
@@ -2594,6 +6257,6 @@ function removeHexPrefix(value) {
2594
6257
  // src/index.ts
2595
6258
  var index_default = WalletManager;
2596
6259
 
2597
- export { AdapterRegistry, AuthMessageGenerator, BrowserWalletAdapter, CHAIN_INFO, ChainNotSupportedError, ChainType, ConfigurationError, ConnectionRejectedError, EVMPrivateKeyAdapter, MetaMaskAdapter, MethodNotSupportedError, NetworkError, SUPPORTED_WALLETS, SignatureRejectedError, SignatureVerifier, TransactionFailedError, TronLinkAdapter, WalletAdapter, WalletDetector, WalletManager, WalletNotAvailableError, WalletNotConnectedError, WalletSDKError, WalletState, WalletType, compareEVMAddresses, compareTronAddresses, compareUniversalAddresses, createUniversalAddress, index_default as default, ensureHexPrefix, formatEVMAddress, fromHex, getAddressFromUniversalAddress, getChainIdFromUniversalAddress, getChainInfo, getChainType, getEVMWallets, getTronWallets, getWalletMetadata, hexToNumber, isEVMChain, isHex, isTronChain, isValidChainId, isValidEVMAddress, isValidSignature, isValidTransactionHash, isValidTronAddress, isValidTronHexAddress, isValidUniversalAddress, numberToHex, parseUniversalAddress, removeHexPrefix, shortenAddress, shortenTronAddress, toHex, validateAddress, validateAddressForChain };
6260
+ export { AdapterRegistry, AuthMessageGenerator, BrowserWalletAdapter, CHAIN_INFO, ChainNotSupportedError, ChainType, ConfigurationError, ConnectionRejectedError, DeepLinkAdapter, DeepLinkProviderType, DeepLinkWalletType, EVMPrivateKeyAdapter, ImTokenDeepLinkProvider, MetaMaskAdapter, MetaMaskDeepLinkProvider, MethodNotSupportedError, NetworkError, OKXDeepLinkProvider, QRCodeSignStatus, QRCodeSigner, SUPPORTED_WALLETS, SignatureRejectedError, SignatureVerifier, TokenPocketDeepLinkProvider, TransactionFailedError, TronDeepLinkAdapter, TronLinkAdapter, TronLinkDeepLinkProvider, WalletAdapter, WalletConnectAdapter, WalletDetector, WalletManager, WalletNotAvailableError, WalletNotConnectedError, WalletSDKError, WalletState, WalletType, compareEVMAddresses, compareTronAddresses, compareUniversalAddresses, createUniversalAddress, index_default as default, ensureHexPrefix, formatEVMAddress, fromHex, getAddressFromUniversalAddress, getChainIdFromUniversalAddress, getChainInfo, getChainType, getEVMWallets, getTronWallets, getWalletMetadata, hexToNumber, isEVMChain, isHex, isTronChain, isValidChainId, isValidEVMAddress, isValidSignature, isValidTransactionHash, isValidTronAddress, isValidTronHexAddress, isValidUniversalAddress, numberToHex, parseUniversalAddress, removeHexPrefix, shortenAddress, shortenTronAddress, toHex, validateAddress, validateAddressForChain };
2598
6261
  //# sourceMappingURL=index.mjs.map
2599
6262
  //# sourceMappingURL=index.mjs.map