@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.
@@ -1,17 +1,589 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
4
- var EventEmitter = require('eventemitter3');
5
3
  var chainUtils = require('@enclave-hq/chain-utils');
4
+ var React2 = require('react');
5
+ var EventEmitter = require('eventemitter3');
6
6
  var viem = require('viem');
7
7
  var accounts = require('viem/accounts');
8
+ var EthereumProvider = require('@walletconnect/ethereum-provider');
9
+ var walletconnectTron = require('@tronweb3/walletconnect-tron');
10
+ var QRCode = require('qrcode');
8
11
 
9
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
13
 
11
- var React__default = /*#__PURE__*/_interopDefault(React);
14
+ var React2__default = /*#__PURE__*/_interopDefault(React2);
12
15
  var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
16
+ var EthereumProvider__default = /*#__PURE__*/_interopDefault(EthereumProvider);
17
+ var QRCode__default = /*#__PURE__*/_interopDefault(QRCode);
13
18
 
14
- // src/react/WalletContext.tsx
19
+ var __defProp = Object.defineProperty;
20
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
21
+ var __getOwnPropNames = Object.getOwnPropertyNames;
22
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
23
+ var __esm = (fn, res) => function __init() {
24
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
25
+ };
26
+ var __export = (target, all) => {
27
+ for (var name in all)
28
+ __defProp(target, name, { get: all[name], enumerable: true });
29
+ };
30
+ var __copyProps = (to, from, except, desc) => {
31
+ if (from && typeof from === "object" || typeof from === "function") {
32
+ for (let key of __getOwnPropNames(from))
33
+ if (!__hasOwnProp.call(to, key) && key !== except)
34
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
35
+ }
36
+ return to;
37
+ };
38
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
39
+ var ChainType;
40
+ var init_types = __esm({
41
+ "src/core/types.ts"() {
42
+ ChainType = chainUtils.ChainType;
43
+ }
44
+ });
45
+
46
+ // src/adapters/deep-link/providers/tokenpocket.ts
47
+ var tokenpocket_exports = {};
48
+ __export(tokenpocket_exports, {
49
+ TokenPocketDeepLinkProvider: () => TokenPocketDeepLinkProvider
50
+ });
51
+ var TokenPocketDeepLinkProvider;
52
+ var init_tokenpocket = __esm({
53
+ "src/adapters/deep-link/providers/tokenpocket.ts"() {
54
+ init_types();
55
+ TokenPocketDeepLinkProvider = class {
56
+ constructor(options) {
57
+ this.name = "TokenPocket";
58
+ this.icon = "https://tokenpocket.pro/icon.png";
59
+ this.supportedChainTypes = [ChainType.EVM, ChainType.TRON];
60
+ this.callbackUrl = options?.callbackUrl;
61
+ this.callbackSchema = options?.callbackSchema;
62
+ }
63
+ async isAvailable() {
64
+ if (typeof window === "undefined") {
65
+ return false;
66
+ }
67
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
68
+ if (isTelegramMiniApp) {
69
+ return true;
70
+ }
71
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
72
+ navigator.userAgent
73
+ );
74
+ return isMobile;
75
+ }
76
+ /**
77
+ * Generate unique actionId
78
+ */
79
+ generateActionId() {
80
+ return `web-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
81
+ }
82
+ /**
83
+ * Get callback configuration
84
+ */
85
+ getCallbackConfig() {
86
+ if (this.callbackSchema) {
87
+ return { callbackSchema: this.callbackSchema };
88
+ }
89
+ if (this.callbackUrl) {
90
+ return { callbackUrl: this.callbackUrl };
91
+ }
92
+ if (typeof window !== "undefined" && window.location) {
93
+ return {
94
+ callbackSchema: `${window.location.protocol}//${window.location.host}${window.location.pathname}`
95
+ };
96
+ }
97
+ return {};
98
+ }
99
+ /**
100
+ * Get blockchain configuration based on chain type
101
+ */
102
+ getBlockchainConfig(chainId, chainType) {
103
+ if (chainType === ChainType.TRON) {
104
+ return {
105
+ chainId: String(chainId),
106
+ network: "tron"
107
+ };
108
+ } else if (chainType === ChainType.EVM) {
109
+ return {
110
+ chainId: String(chainId),
111
+ network: "ethereum"
112
+ };
113
+ }
114
+ throw new Error(`Unsupported chain type: ${chainType}`);
115
+ }
116
+ buildSignMessageLink(params) {
117
+ const actionId = this.generateActionId();
118
+ const callback = this.getCallbackConfig();
119
+ const blockchain = this.getBlockchainConfig(params.chainId, params.chainType);
120
+ const param = {
121
+ action: "sign",
122
+ actionId,
123
+ message: params.message,
124
+ hash: false,
125
+ signType: params.chainType === ChainType.TRON ? "ethPersonalSign" : "ethPersonalSign",
126
+ memo: `${params.chainType} message signature`,
127
+ blockchains: [blockchain],
128
+ dappName: "Enclave Wallet SDK",
129
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
130
+ protocol: "TokenPocket",
131
+ version: "1.1.8",
132
+ expired: 0,
133
+ ...callback
134
+ };
135
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
136
+ const url = `tpoutside://pull.activity?param=${encodedParam}`;
137
+ return {
138
+ url,
139
+ actionId,
140
+ ...callback
141
+ };
142
+ }
143
+ buildSignTransactionLink(params) {
144
+ const actionId = this.generateActionId();
145
+ const callback = this.getCallbackConfig();
146
+ const blockchain = this.getBlockchainConfig(params.chainId, params.chainType);
147
+ let transactionData;
148
+ if (typeof params.transaction === "string") {
149
+ transactionData = params.transaction;
150
+ } else {
151
+ transactionData = JSON.stringify(params.transaction);
152
+ }
153
+ const param = {
154
+ action: "pushTransaction",
155
+ actionId,
156
+ txData: transactionData,
157
+ blockchains: [blockchain],
158
+ dappName: "Enclave Wallet SDK",
159
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
160
+ protocol: "TokenPocket",
161
+ version: "1.1.8",
162
+ expired: 0,
163
+ ...callback
164
+ };
165
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
166
+ const url = `tpoutside://pull.activity?param=${encodedParam}`;
167
+ return {
168
+ url,
169
+ actionId,
170
+ ...callback
171
+ };
172
+ }
173
+ buildConnectLink(params) {
174
+ const actionId = this.generateActionId();
175
+ const blockchain = this.getBlockchainConfig(params.chainId, params.chainType);
176
+ const param = {
177
+ action: "login",
178
+ actionId,
179
+ blockchains: [blockchain],
180
+ dappName: "Enclave Wallet SDK",
181
+ dappIcon: "https://walletconnect.com/walletconnect-logo.svg",
182
+ protocol: "TokenPocket",
183
+ version: "1.0",
184
+ expired: 1602
185
+ // 30 minutes
186
+ };
187
+ const encodedParam = encodeURIComponent(JSON.stringify(param));
188
+ const url = `tpoutside://pull.activity?param=${encodedParam}`;
189
+ return {
190
+ url,
191
+ actionId
192
+ };
193
+ }
194
+ parseCallbackResult(urlParams) {
195
+ const actionId = urlParams.get("actionId");
196
+ const resultParam = urlParams.get("result");
197
+ const error = urlParams.get("error");
198
+ let result = null;
199
+ if (resultParam) {
200
+ try {
201
+ result = JSON.parse(decodeURIComponent(resultParam));
202
+ } catch (e) {
203
+ result = resultParam;
204
+ }
205
+ }
206
+ return {
207
+ actionId,
208
+ result,
209
+ error
210
+ };
211
+ }
212
+ getDefaultCallbackSchema() {
213
+ if (typeof window !== "undefined" && window.location) {
214
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
215
+ }
216
+ return "";
217
+ }
218
+ };
219
+ }
220
+ });
221
+
222
+ // src/adapters/deep-link/providers/tronlink.ts
223
+ var tronlink_exports = {};
224
+ __export(tronlink_exports, {
225
+ TronLinkDeepLinkProvider: () => TronLinkDeepLinkProvider
226
+ });
227
+ var TronLinkDeepLinkProvider;
228
+ var init_tronlink = __esm({
229
+ "src/adapters/deep-link/providers/tronlink.ts"() {
230
+ init_types();
231
+ TronLinkDeepLinkProvider = class {
232
+ constructor() {
233
+ this.name = "TronLink";
234
+ this.icon = "https://www.tronlink.org/static/logoIcon.svg";
235
+ this.supportedChainTypes = [ChainType.TRON];
236
+ }
237
+ async isAvailable() {
238
+ if (typeof window === "undefined") {
239
+ return false;
240
+ }
241
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
242
+ if (isTelegramMiniApp) {
243
+ return true;
244
+ }
245
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
246
+ navigator.userAgent
247
+ );
248
+ return isMobile;
249
+ }
250
+ buildSignMessageLink(params) {
251
+ if (params.chainType !== ChainType.TRON) {
252
+ throw new Error("TronLink only supports TRON chain");
253
+ }
254
+ const encodedMessage = encodeURIComponent(params.message);
255
+ const url = `tronlink://signMessage?message=${encodedMessage}`;
256
+ const actionId = `tronlink-${Date.now()}`;
257
+ return {
258
+ url,
259
+ actionId
260
+ };
261
+ }
262
+ buildSignTransactionLink(params) {
263
+ if (params.chainType !== ChainType.TRON) {
264
+ throw new Error("TronLink only supports TRON chain");
265
+ }
266
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
267
+ const encodedData = encodeURIComponent(transactionData);
268
+ const url = `tronlink://signTransaction?transaction=${encodedData}`;
269
+ const actionId = `tronlink-${Date.now()}`;
270
+ return {
271
+ url,
272
+ actionId
273
+ };
274
+ }
275
+ buildConnectLink(params) {
276
+ if (params.chainType !== ChainType.TRON) {
277
+ throw new Error("TronLink only supports TRON chain");
278
+ }
279
+ const url = `tronlink://open?action=connect&network=tron`;
280
+ return {
281
+ url
282
+ };
283
+ }
284
+ parseCallbackResult(_urlParams) {
285
+ return {
286
+ actionId: null,
287
+ result: null,
288
+ error: null
289
+ };
290
+ }
291
+ };
292
+ }
293
+ });
294
+
295
+ // src/adapters/deep-link/providers/imtoken.ts
296
+ var imtoken_exports = {};
297
+ __export(imtoken_exports, {
298
+ ImTokenDeepLinkProvider: () => ImTokenDeepLinkProvider
299
+ });
300
+ var ImTokenDeepLinkProvider;
301
+ var init_imtoken = __esm({
302
+ "src/adapters/deep-link/providers/imtoken.ts"() {
303
+ init_types();
304
+ ImTokenDeepLinkProvider = class {
305
+ constructor(options) {
306
+ this.name = "ImToken";
307
+ this.icon = "https://token.im/static/img/logo.png";
308
+ this.supportedChainTypes = [ChainType.EVM, ChainType.TRON];
309
+ this.callbackUrl = options?.callbackUrl;
310
+ this.callbackSchema = options?.callbackSchema;
311
+ }
312
+ async isAvailable() {
313
+ if (typeof window === "undefined") {
314
+ return false;
315
+ }
316
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
317
+ if (isTelegramMiniApp) {
318
+ return true;
319
+ }
320
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
321
+ navigator.userAgent
322
+ );
323
+ return isMobile;
324
+ }
325
+ /**
326
+ * Generate unique actionId
327
+ */
328
+ generateActionId() {
329
+ return `imtoken-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
330
+ }
331
+ /**
332
+ * Get callback configuration
333
+ */
334
+ getCallbackConfig() {
335
+ if (this.callbackSchema) {
336
+ return { callbackSchema: this.callbackSchema };
337
+ }
338
+ if (this.callbackUrl) {
339
+ return { callbackUrl: this.callbackUrl };
340
+ }
341
+ if (typeof window !== "undefined" && window.location) {
342
+ return {
343
+ callbackSchema: `${window.location.protocol}//${window.location.host}${window.location.pathname}`
344
+ };
345
+ }
346
+ return {};
347
+ }
348
+ buildSignMessageLink(params) {
349
+ const actionId = this.generateActionId();
350
+ const callback = this.getCallbackConfig();
351
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signMessage&message=${encodeURIComponent(params.message)}&chainId=${params.chainId}`;
352
+ const encodedDappUrl = encodeURIComponent(dappUrl);
353
+ const url = `imtokenv2://navigate/DappView?url=${encodedDappUrl}`;
354
+ return {
355
+ url,
356
+ actionId,
357
+ ...callback
358
+ };
359
+ }
360
+ buildSignTransactionLink(params) {
361
+ const actionId = this.generateActionId();
362
+ const callback = this.getCallbackConfig();
363
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
364
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signTransaction&transaction=${encodeURIComponent(transactionData)}&chainId=${params.chainId}`;
365
+ const encodedDappUrl = encodeURIComponent(dappUrl);
366
+ const url = `imtokenv2://navigate/DappView?url=${encodedDappUrl}`;
367
+ return {
368
+ url,
369
+ actionId,
370
+ ...callback
371
+ };
372
+ }
373
+ buildConnectLink(params) {
374
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=connect&chainId=${params.chainId}`;
375
+ const encodedDappUrl = encodeURIComponent(dappUrl);
376
+ const url = `imtokenv2://navigate/DappView?url=${encodedDappUrl}`;
377
+ return {
378
+ url
379
+ };
380
+ }
381
+ parseCallbackResult(urlParams) {
382
+ const actionId = urlParams.get("actionId");
383
+ const resultParam = urlParams.get("result");
384
+ const error = urlParams.get("error");
385
+ let result = null;
386
+ if (resultParam) {
387
+ try {
388
+ result = JSON.parse(decodeURIComponent(resultParam));
389
+ } catch (e) {
390
+ result = resultParam;
391
+ }
392
+ }
393
+ return {
394
+ actionId,
395
+ result,
396
+ error
397
+ };
398
+ }
399
+ getDefaultCallbackSchema() {
400
+ if (typeof window !== "undefined" && window.location) {
401
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
402
+ }
403
+ return "";
404
+ }
405
+ };
406
+ }
407
+ });
408
+
409
+ // src/adapters/deep-link/providers/metamask.ts
410
+ var metamask_exports = {};
411
+ __export(metamask_exports, {
412
+ MetaMaskDeepLinkProvider: () => MetaMaskDeepLinkProvider
413
+ });
414
+ var MetaMaskDeepLinkProvider;
415
+ var init_metamask = __esm({
416
+ "src/adapters/deep-link/providers/metamask.ts"() {
417
+ init_types();
418
+ MetaMaskDeepLinkProvider = class {
419
+ constructor() {
420
+ this.name = "MetaMask";
421
+ this.icon = "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg";
422
+ this.supportedChainTypes = [ChainType.EVM];
423
+ }
424
+ async isAvailable() {
425
+ if (typeof window === "undefined") {
426
+ return false;
427
+ }
428
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
429
+ if (isTelegramMiniApp) {
430
+ return true;
431
+ }
432
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
433
+ navigator.userAgent
434
+ );
435
+ return isMobile;
436
+ }
437
+ buildSignMessageLink(params) {
438
+ if (params.chainType !== ChainType.EVM) {
439
+ throw new Error("MetaMask only supports EVM chains");
440
+ }
441
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signMessage&message=${encodeURIComponent(params.message)}&chainId=${params.chainId}`;
442
+ const encodedDappUrl = encodeURIComponent(dappUrl);
443
+ const url = `https://link.metamask.io/dapp/${encodedDappUrl}`;
444
+ const actionId = `metamask-${Date.now()}`;
445
+ return {
446
+ url,
447
+ actionId
448
+ };
449
+ }
450
+ buildSignTransactionLink(params) {
451
+ if (params.chainType !== ChainType.EVM) {
452
+ throw new Error("MetaMask only supports EVM chains");
453
+ }
454
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
455
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signTransaction&transaction=${encodeURIComponent(transactionData)}&chainId=${params.chainId}`;
456
+ const encodedDappUrl = encodeURIComponent(dappUrl);
457
+ const url = `https://link.metamask.io/dapp/${encodedDappUrl}`;
458
+ const actionId = `metamask-${Date.now()}`;
459
+ return {
460
+ url,
461
+ actionId
462
+ };
463
+ }
464
+ buildConnectLink(params) {
465
+ if (params.chainType !== ChainType.EVM) {
466
+ throw new Error("MetaMask only supports EVM chains");
467
+ }
468
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=connect&chainId=${params.chainId}`;
469
+ const encodedDappUrl = encodeURIComponent(dappUrl);
470
+ const url = `https://link.metamask.io/dapp/${encodedDappUrl}`;
471
+ return {
472
+ url
473
+ };
474
+ }
475
+ parseCallbackResult(urlParams) {
476
+ const actionId = urlParams.get("actionId");
477
+ const resultParam = urlParams.get("result");
478
+ const error = urlParams.get("error");
479
+ let result = null;
480
+ if (resultParam) {
481
+ try {
482
+ result = JSON.parse(decodeURIComponent(resultParam));
483
+ } catch (e) {
484
+ result = resultParam;
485
+ }
486
+ }
487
+ return {
488
+ actionId,
489
+ result,
490
+ error
491
+ };
492
+ }
493
+ getDefaultCallbackSchema() {
494
+ if (typeof window !== "undefined" && window.location) {
495
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
496
+ }
497
+ return "";
498
+ }
499
+ };
500
+ }
501
+ });
502
+
503
+ // src/adapters/deep-link/providers/okx.ts
504
+ var okx_exports = {};
505
+ __export(okx_exports, {
506
+ OKXDeepLinkProvider: () => OKXDeepLinkProvider
507
+ });
508
+ var OKXDeepLinkProvider;
509
+ var init_okx = __esm({
510
+ "src/adapters/deep-link/providers/okx.ts"() {
511
+ init_types();
512
+ OKXDeepLinkProvider = class {
513
+ constructor() {
514
+ this.name = "OKX";
515
+ this.icon = "https://www.okx.com/favicon.ico";
516
+ this.supportedChainTypes = [ChainType.EVM, ChainType.TRON];
517
+ }
518
+ async isAvailable() {
519
+ if (typeof window === "undefined") {
520
+ return false;
521
+ }
522
+ const isTelegramMiniApp = !!(window.Telegram && window.Telegram.WebApp);
523
+ if (isTelegramMiniApp) {
524
+ return true;
525
+ }
526
+ const isMobile = /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
527
+ navigator.userAgent
528
+ );
529
+ return isMobile;
530
+ }
531
+ buildSignMessageLink(params) {
532
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signMessage&message=${encodeURIComponent(params.message)}&chainId=${params.chainId}`;
533
+ const encodedDappUrl = encodeURIComponent(dappUrl);
534
+ const url = `okx://wallet/dapp/url?dappUrl=${encodedDappUrl}`;
535
+ const actionId = `okx-${Date.now()}`;
536
+ return {
537
+ url,
538
+ actionId
539
+ };
540
+ }
541
+ buildSignTransactionLink(params) {
542
+ const transactionData = typeof params.transaction === "string" ? params.transaction : JSON.stringify(params.transaction);
543
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=signTransaction&transaction=${encodeURIComponent(transactionData)}&chainId=${params.chainId}`;
544
+ const encodedDappUrl = encodeURIComponent(dappUrl);
545
+ const url = `okx://wallet/dapp/url?dappUrl=${encodedDappUrl}`;
546
+ const actionId = `okx-${Date.now()}`;
547
+ return {
548
+ url,
549
+ actionId
550
+ };
551
+ }
552
+ buildConnectLink(params) {
553
+ const dappUrl = `${window.location.origin}${window.location.pathname}?action=connect&chainId=${params.chainId}`;
554
+ const encodedDappUrl = encodeURIComponent(dappUrl);
555
+ const url = `okx://wallet/dapp/url?dappUrl=${encodedDappUrl}`;
556
+ return {
557
+ url
558
+ };
559
+ }
560
+ parseCallbackResult(urlParams) {
561
+ const actionId = urlParams.get("actionId");
562
+ const resultParam = urlParams.get("result");
563
+ const error = urlParams.get("error");
564
+ let result = null;
565
+ if (resultParam) {
566
+ try {
567
+ result = JSON.parse(decodeURIComponent(resultParam));
568
+ } catch (e) {
569
+ result = resultParam;
570
+ }
571
+ }
572
+ return {
573
+ actionId,
574
+ result,
575
+ error
576
+ };
577
+ }
578
+ getDefaultCallbackSchema() {
579
+ if (typeof window !== "undefined" && window.location) {
580
+ return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
581
+ }
582
+ return "";
583
+ }
584
+ };
585
+ }
586
+ });
15
587
  var TypedEventEmitter = class {
16
588
  constructor() {
17
589
  this.emitter = new EventEmitter__default.default();
@@ -40,7 +612,12 @@ var TypedEventEmitter = class {
40
612
  return this;
41
613
  }
42
614
  };
43
- var ChainType = chainUtils.ChainType;
615
+
616
+ // src/core/adapter-registry.ts
617
+ init_types();
618
+
619
+ // src/adapters/base/wallet-adapter.ts
620
+ init_types();
44
621
 
45
622
  // src/core/errors.ts
46
623
  var WalletSDKError = class _WalletSDKError extends Error {
@@ -111,6 +688,18 @@ var MethodNotSupportedError = class extends WalletSDKError {
111
688
  this.name = "MethodNotSupportedError";
112
689
  }
113
690
  };
691
+ var ConfigurationError = class extends WalletSDKError {
692
+ constructor(message, details) {
693
+ super(message, "CONFIGURATION_ERROR", details);
694
+ this.name = "ConfigurationError";
695
+ }
696
+ };
697
+ var NetworkError = class extends WalletSDKError {
698
+ constructor(message, details) {
699
+ super(message, "NETWORK_ERROR", details);
700
+ this.name = "NetworkError";
701
+ }
702
+ };
114
703
 
115
704
  // src/adapters/base/wallet-adapter.ts
116
705
  var WalletAdapter = class extends EventEmitter__default.default {
@@ -120,6 +709,13 @@ var WalletAdapter = class extends EventEmitter__default.default {
120
709
  this.state = "disconnected" /* DISCONNECTED */;
121
710
  this.currentAccount = null;
122
711
  }
712
+ /**
713
+ * Check if the wallet is currently connected
714
+ * @returns true if the wallet is connected (state is CONNECTED and has an account)
715
+ */
716
+ isConnected() {
717
+ return this.state === "connected" /* CONNECTED */ && this.currentAccount !== null;
718
+ }
123
719
  /**
124
720
  * Get the signer's address (implements ISigner interface)
125
721
  * Returns the native address of the current account
@@ -189,6 +785,7 @@ var WalletAdapter = class extends EventEmitter__default.default {
189
785
  };
190
786
 
191
787
  // src/adapters/base/browser-wallet-adapter.ts
788
+ init_types();
192
789
  var BrowserWalletAdapter = class extends WalletAdapter {
193
790
  /**
194
791
  * 检查钱包是否可用
@@ -222,6 +819,9 @@ var BrowserWalletAdapter = class extends WalletAdapter {
222
819
  }
223
820
  };
224
821
 
822
+ // src/adapters/evm/metamask.ts
823
+ init_types();
824
+
225
825
  // src/utils/address/universal-address.ts
226
826
  function createUniversalAddress(chainId, address) {
227
827
  return `${chainId}:${address}`;
@@ -246,7 +846,12 @@ var CHAIN_INFO = {
246
846
  symbol: "ETH",
247
847
  decimals: 18
248
848
  },
249
- rpcUrls: ["https://eth.llamarpc.com"],
849
+ // 使用支持浏览器 CORS 的公共 RPC,避免 dapp 域名被跨域拦截(如 eth.llamarpc.com 无 CORS 头)
850
+ rpcUrls: [
851
+ "https://cloudflare-eth.com",
852
+ "https://rpc.ankr.com/eth",
853
+ "https://eth.llamarpc.com"
854
+ ],
250
855
  blockExplorerUrls: ["https://etherscan.io"]
251
856
  },
252
857
  // EVM Testnets
@@ -466,6 +1071,7 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
466
1071
  */
467
1072
  async connect(chainId) {
468
1073
  await this.ensureAvailable();
1074
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId;
469
1075
  try {
470
1076
  this.setState("connecting" /* CONNECTING */);
471
1077
  const provider = this.getBrowserProvider();
@@ -479,10 +1085,10 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
479
1085
  method: "eth_chainId"
480
1086
  });
481
1087
  const parsedChainId = parseInt(currentChainId, 16);
482
- if (chainId && chainId !== parsedChainId) {
483
- await this.switchChain(chainId);
1088
+ if (targetChainId && targetChainId !== parsedChainId) {
1089
+ await this.switchChain(targetChainId);
484
1090
  }
485
- const finalChainId = chainId || parsedChainId;
1091
+ const finalChainId = targetChainId || parsedChainId;
486
1092
  const viemChain = this.getViemChain(finalChainId);
487
1093
  this.walletClient = viem.createWalletClient({
488
1094
  account: accounts[0],
@@ -644,6 +1250,56 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
644
1250
  }]
645
1251
  });
646
1252
  }
1253
+ /**
1254
+ * 请求切换账户
1255
+ * 弹出 MetaMask 账户选择界面,让用户选择或切换到目标地址
1256
+ * @param targetAddress 目标地址(可选),如果提供,会在切换后验证是否匹配
1257
+ * @returns 切换后的账户信息
1258
+ */
1259
+ async requestSwitchAccount(targetAddress) {
1260
+ const provider = this.getBrowserProvider();
1261
+ if (!provider) {
1262
+ throw new Error("MetaMask provider not available");
1263
+ }
1264
+ try {
1265
+ await provider.request({
1266
+ method: "wallet_requestPermissions",
1267
+ params: [{ eth_accounts: {} }]
1268
+ });
1269
+ const accounts = await provider.request({
1270
+ method: "eth_accounts"
1271
+ });
1272
+ if (!accounts || accounts.length === 0) {
1273
+ throw new ConnectionRejectedError(this.type);
1274
+ }
1275
+ const address = formatEVMAddress(accounts[0]);
1276
+ if (targetAddress && address.toLowerCase() !== targetAddress.toLowerCase()) {
1277
+ 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)}`);
1278
+ }
1279
+ const chainId = this.currentAccount?.chainId || 1;
1280
+ const account = {
1281
+ universalAddress: createUniversalAddress(chainId, address),
1282
+ nativeAddress: address,
1283
+ chainId,
1284
+ chainType: ChainType.EVM,
1285
+ isActive: true
1286
+ };
1287
+ this.setAccount(account);
1288
+ this.emitAccountChanged(account);
1289
+ const viemChain = this.getViemChain(chainId);
1290
+ this.walletClient = viem.createWalletClient({
1291
+ account: address,
1292
+ chain: viemChain,
1293
+ transport: viem.custom(provider)
1294
+ });
1295
+ return account;
1296
+ } catch (error) {
1297
+ if (error.code === 4001) {
1298
+ throw new ConnectionRejectedError(this.type);
1299
+ }
1300
+ throw error;
1301
+ }
1302
+ }
647
1303
  /**
648
1304
  * 读取合约
649
1305
  */
@@ -868,6 +1524,47 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
868
1524
  };
869
1525
 
870
1526
  // src/adapters/tron/tronlink.ts
1527
+ init_types();
1528
+ var TronApiRateLimiter = class {
1529
+ constructor(minIntervalMs = 600) {
1530
+ this.lastCallTime = 0;
1531
+ this.minInterval = minIntervalMs;
1532
+ }
1533
+ /**
1534
+ * 等待直到可以进行下一次 API 调用
1535
+ */
1536
+ async waitForNextCall() {
1537
+ const now = Date.now();
1538
+ const timeSinceLastCall = now - this.lastCallTime;
1539
+ if (timeSinceLastCall < this.minInterval) {
1540
+ const waitTime = this.minInterval - timeSinceLastCall;
1541
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
1542
+ }
1543
+ this.lastCallTime = Date.now();
1544
+ }
1545
+ };
1546
+ var tronApiRateLimiter = new TronApiRateLimiter(600);
1547
+ async function retryWithBackoff(fn, maxRetries = 3, initialDelay = 500) {
1548
+ let lastError;
1549
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
1550
+ try {
1551
+ return await fn();
1552
+ } catch (error) {
1553
+ lastError = error;
1554
+ const errorMsg = error?.message || String(error);
1555
+ const errorLower = errorMsg.toLowerCase();
1556
+ 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;
1557
+ if (isRateLimitError && attempt < maxRetries - 1) {
1558
+ const delay = initialDelay * Math.pow(2, attempt);
1559
+ console.warn(`[TronLink] \u9047\u5230\u901F\u7387\u9650\u5236 (429)\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5 (${attempt + 1}/${maxRetries})...`);
1560
+ await new Promise((resolve) => setTimeout(resolve, delay));
1561
+ continue;
1562
+ }
1563
+ throw error;
1564
+ }
1565
+ }
1566
+ throw lastError;
1567
+ }
871
1568
  var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
872
1569
  constructor() {
873
1570
  super(...arguments);
@@ -915,6 +1612,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
915
1612
  */
916
1613
  async connect(chainId) {
917
1614
  await this.ensureAvailable();
1615
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId;
918
1616
  try {
919
1617
  this.setState("connecting" /* CONNECTING */);
920
1618
  const w = window;
@@ -969,7 +1667,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
969
1667
  if (!address) {
970
1668
  throw new Error("Failed to get Tron address. Please make sure your wallet is unlocked and try again.");
971
1669
  }
972
- const tronChainId = chainId || _TronLinkAdapter.TRON_MAINNET_CHAIN_ID;
1670
+ const tronChainId = targetChainId || _TronLinkAdapter.TRON_MAINNET_CHAIN_ID;
973
1671
  const account = {
974
1672
  universalAddress: createUniversalAddress(tronChainId, address),
975
1673
  nativeAddress: address,
@@ -1044,10 +1742,12 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1044
1742
  /**
1045
1743
  * 读取合约
1046
1744
  * 参考 webserver 的实现,使用 TronWeb 合约实例的标准 call() 方法
1745
+ * 带 TronGrid 限流 + 429 重试
1047
1746
  */
1048
1747
  async readContract(params) {
1049
1748
  this.ensureConnected();
1050
- try {
1749
+ await tronApiRateLimiter.waitForNextCall();
1750
+ const doRead = async () => {
1051
1751
  const tronWeb = this.getTronWeb();
1052
1752
  if (!this.currentAccount) {
1053
1753
  throw new Error("No account connected");
@@ -1062,19 +1762,17 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1062
1762
  return result;
1063
1763
  } catch (method1Error) {
1064
1764
  console.warn("\u26A0\uFE0F [\u65B9\u6CD51] TronWeb\u6807\u51C6\u65B9\u6CD5\u5931\u8D25\uFF0C\u5C1D\u8BD5\u65B9\u6CD52:", method1Error.message);
1065
- try {
1066
- const contract2 = await tronWeb.contract().at(params.address);
1067
- const method2 = contract2[params.functionName];
1068
- if (!method2 || typeof method2 !== "function") {
1069
- throw new Error(`Function ${params.functionName} not found in contract`);
1070
- }
1071
- const result = await method2(...params.args || []).call();
1072
- return result;
1073
- } catch (method2Error) {
1074
- console.error("\u26A0\uFE0F [\u65B9\u6CD52] \u4E5F\u5931\u8D25:", method2Error.message);
1075
- throw method1Error;
1765
+ const contract2 = await tronWeb.contract().at(params.address);
1766
+ const method2 = contract2[params.functionName];
1767
+ if (!method2 || typeof method2 !== "function") {
1768
+ throw new Error(`Function ${params.functionName} not found in contract`);
1076
1769
  }
1770
+ const result = await method2(...params.args || []).call();
1771
+ return result;
1077
1772
  }
1773
+ };
1774
+ try {
1775
+ return await retryWithBackoff(doRead, 3, 800);
1078
1776
  } catch (error) {
1079
1777
  console.error("Read contract error:", error);
1080
1778
  throw new Error(`Failed to read contract: ${error.message || "Unknown error"}`);
@@ -1085,6 +1783,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1085
1783
  */
1086
1784
  async writeContract(params) {
1087
1785
  this.ensureConnected();
1786
+ await tronApiRateLimiter.waitForNextCall();
1088
1787
  try {
1089
1788
  const tronWeb = this.getTronWeb();
1090
1789
  console.log("[TronLink] writeContract params:", {
@@ -1110,29 +1809,171 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1110
1809
  }
1111
1810
  console.log("[TronLink] Function ABI:", functionAbi);
1112
1811
  console.log("[TronLink] Calling with args:", params.args);
1812
+ const TRON_FEE_LIMIT = 1e8;
1113
1813
  const options = {
1114
- feeLimit: params.gas || 1e8,
1115
- // 默认 100 TRX 的能量限制
1814
+ feeLimit: TRON_FEE_LIMIT,
1815
+ // 固定为 100 TRX 的能量限制
1116
1816
  callValue: params.value || 0
1117
1817
  // 发送的 TRX 数量(单位:SUN)
1118
1818
  };
1119
- const parameter = functionAbi.inputs.map((input, index) => ({
1120
- type: input.type,
1121
- value: params.args[index]
1122
- }));
1123
- console.log("[TronLink] Transaction options:", options);
1124
- console.log("[TronLink] Parameters:", parameter);
1125
- const functionSelector = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
1126
- console.log("[TronLink] Function selector:", functionSelector);
1127
- console.log("[TronLink] Transaction options:", options);
1128
- console.log("[TronLink] Parameters:", parameter);
1129
- const tx = await tronWeb.transactionBuilder.triggerSmartContract(
1130
- params.address,
1131
- functionSelector,
1132
- options,
1133
- parameter,
1134
- this.currentAccount.nativeAddress
1135
- );
1819
+ const hasTupleArray = functionAbi.inputs.some((input) => input.type === "tuple[]");
1820
+ console.log("[TronLink] \u68C0\u67E5 tuple[] \u7C7B\u578B:", {
1821
+ hasTupleArray,
1822
+ inputs: functionAbi.inputs.map((i) => ({ name: i.name, type: i.type }))
1823
+ });
1824
+ let tx;
1825
+ if (hasTupleArray) {
1826
+ console.log("[TronLink] \u68C0\u6D4B\u5230 tuple[] \u53C2\u6570\uFF0C\u4F7F\u7528\u624B\u52A8\u7F16\u7801\u65B9\u5F0F");
1827
+ const processedArgs = params.args.map((argValue, index) => {
1828
+ const input = functionAbi.inputs[index];
1829
+ if (input.type === "address" && typeof argValue === "string") {
1830
+ if (argValue.startsWith("T") && argValue.length === 34) {
1831
+ const hexAddress = tronWeb.address.toHex(argValue);
1832
+ return hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1833
+ }
1834
+ return argValue.startsWith("0x") ? argValue : `0x${argValue}`;
1835
+ }
1836
+ if (input.type === "tuple[]" && Array.isArray(argValue)) {
1837
+ return argValue.map((tupleItem) => {
1838
+ if (input.components && Array.isArray(input.components)) {
1839
+ const processedTuple = {};
1840
+ input.components.forEach((component) => {
1841
+ let value = tupleItem[component.name];
1842
+ if (component.type === "address" && typeof value === "string") {
1843
+ if (value.startsWith("T") && value.length === 34) {
1844
+ const hexAddress = tronWeb.address.toHex(value);
1845
+ value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1846
+ } else if (!value.startsWith("0x")) {
1847
+ value = `0x${value}`;
1848
+ }
1849
+ }
1850
+ processedTuple[component.name] = value;
1851
+ });
1852
+ return processedTuple;
1853
+ }
1854
+ return tupleItem;
1855
+ });
1856
+ }
1857
+ if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
1858
+ if (input.components && Array.isArray(input.components)) {
1859
+ const processedTuple = {};
1860
+ input.components.forEach((component) => {
1861
+ let value = argValue[component.name];
1862
+ if (component.type === "address" && typeof value === "string") {
1863
+ if (value.startsWith("T") && value.length === 34) {
1864
+ const hexAddress = tronWeb.address.toHex(value);
1865
+ value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1866
+ } else if (!value.startsWith("0x")) {
1867
+ value = `0x${value}`;
1868
+ }
1869
+ }
1870
+ processedTuple[component.name] = value;
1871
+ });
1872
+ return processedTuple;
1873
+ }
1874
+ }
1875
+ return argValue;
1876
+ });
1877
+ console.log("[TronLink] \u5904\u7406\u540E\u7684\u53C2\u6570\uFF08\u7528\u4E8E viem \u7F16\u7801\uFF09:", processedArgs);
1878
+ const encodedData = viem.encodeFunctionData({
1879
+ abi: [functionAbi],
1880
+ functionName: params.functionName,
1881
+ args: processedArgs
1882
+ });
1883
+ console.log("[TronLink] \u7F16\u7801\u540E\u7684\u6570\u636E:", encodedData);
1884
+ const functionSelector = encodedData.slice(0, 10);
1885
+ const parameterData = encodedData.slice(10);
1886
+ console.log("[TronLink] \u51FD\u6570\u9009\u62E9\u5668:", functionSelector);
1887
+ console.log("[TronLink] \u53C2\u6570\u6570\u636E:", parameterData);
1888
+ const functionSignature = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
1889
+ const parameterHexClean = parameterData.startsWith("0x") ? parameterData.slice(2) : parameterData;
1890
+ console.log("[TronLink] \u4F7F\u7528 TronWeb triggerSmartContract (rawParameter)...", {
1891
+ contractAddress: params.address,
1892
+ functionSelector: functionSignature,
1893
+ encodedDataLength: parameterHexClean.length
1894
+ });
1895
+ tx = await retryWithBackoff(
1896
+ () => tronWeb.transactionBuilder.triggerSmartContract(
1897
+ params.address,
1898
+ // Base58 格式的合约地址
1899
+ functionSignature,
1900
+ // 函数签名(用于识别函数)
1901
+ {
1902
+ feeLimit: options.feeLimit,
1903
+ callValue: options.callValue,
1904
+ rawParameter: parameterHexClean
1905
+ // 使用 rawParameter 直接提供编码后的数据
1906
+ },
1907
+ [],
1908
+ // parameter 留空(因为使用 rawParameter)
1909
+ this.currentAccount.nativeAddress
1910
+ // Base58 格式的发送地址
1911
+ ),
1912
+ 3,
1913
+ // 最多重试 3 次
1914
+ 500
1915
+ // 初始延迟 500ms
1916
+ );
1917
+ console.log("[TronLink] \u4F7F\u7528 TronWeb API \u6784\u5EFA\u7684\u4EA4\u6613:", tx);
1918
+ } else {
1919
+ const parameter = functionAbi.inputs.map((input, index) => {
1920
+ const argValue = params.args[index];
1921
+ if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
1922
+ if (input.components && Array.isArray(input.components)) {
1923
+ return {
1924
+ type: input.type,
1925
+ value: input.components.map((component) => ({
1926
+ type: component.type,
1927
+ value: argValue[component.name]
1928
+ }))
1929
+ };
1930
+ }
1931
+ }
1932
+ if (input.type === "address" && typeof argValue === "string") {
1933
+ if (argValue.startsWith("T") && argValue.length === 34) {
1934
+ return {
1935
+ type: input.type,
1936
+ value: argValue
1937
+ };
1938
+ }
1939
+ try {
1940
+ const base58Address = tronWeb.address.fromHex(argValue.startsWith("0x") ? argValue : `0x${argValue}`);
1941
+ return {
1942
+ type: input.type,
1943
+ value: base58Address
1944
+ };
1945
+ } catch (e) {
1946
+ return {
1947
+ type: input.type,
1948
+ value: argValue
1949
+ };
1950
+ }
1951
+ }
1952
+ return {
1953
+ type: input.type,
1954
+ value: argValue
1955
+ };
1956
+ });
1957
+ console.log("[TronLink] Transaction options:", options);
1958
+ console.log("[TronLink] Parameters:", parameter);
1959
+ const functionSelector = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
1960
+ console.log("[TronLink] Function selector:", functionSelector);
1961
+ console.log("[TronLink] Transaction options:", options);
1962
+ console.log("[TronLink] Parameters:", parameter);
1963
+ tx = await retryWithBackoff(
1964
+ () => tronWeb.transactionBuilder.triggerSmartContract(
1965
+ params.address,
1966
+ functionSelector,
1967
+ options,
1968
+ parameter,
1969
+ this.currentAccount.nativeAddress
1970
+ ),
1971
+ 3,
1972
+ // 最多重试 3 次
1973
+ 500
1974
+ // 初始延迟 500ms
1975
+ );
1976
+ }
1136
1977
  console.log("[TronLink] Transaction built:", tx);
1137
1978
  if (!tx || !tx.transaction) {
1138
1979
  throw new Error("Failed to build transaction");
@@ -1172,6 +2013,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1172
2013
  const maxAttempts = 60;
1173
2014
  while (attempts < maxAttempts) {
1174
2015
  try {
2016
+ await tronApiRateLimiter.waitForNextCall();
1175
2017
  const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
1176
2018
  if (txInfo && txInfo.id) {
1177
2019
  const receipt = {
@@ -1299,6 +2141,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1299
2141
  // Tron 主网链 ID
1300
2142
  _TronLinkAdapter.TRON_MAINNET_CHAIN_ID = 195;
1301
2143
  var TronLinkAdapter = _TronLinkAdapter;
2144
+ init_types();
1302
2145
  var EVMPrivateKeyAdapter = class extends WalletAdapter {
1303
2146
  constructor() {
1304
2147
  super(...arguments);
@@ -1312,27 +2155,28 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1312
2155
  /**
1313
2156
  * 连接(导入私钥)
1314
2157
  */
1315
- async connect(chainId = 1) {
2158
+ async connect(chainId) {
1316
2159
  if (!this.privateKey) {
1317
2160
  throw new Error("Private key not set. Call setPrivateKey() first.");
1318
2161
  }
1319
2162
  try {
1320
2163
  this.setState("connecting" /* CONNECTING */);
1321
2164
  const account = accounts.privateKeyToAccount(this.privateKey);
2165
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId || 1;
1322
2166
  this.walletClient = viem.createWalletClient({
1323
2167
  account,
1324
- chain: this.getViemChain(chainId),
2168
+ chain: this.getViemChain(targetChainId),
1325
2169
  transport: viem.http()
1326
2170
  });
1327
2171
  this.publicClient = viem.createPublicClient({
1328
- chain: this.getViemChain(chainId),
2172
+ chain: this.getViemChain(targetChainId),
1329
2173
  transport: viem.http()
1330
2174
  });
1331
2175
  const address = formatEVMAddress(account.address);
1332
2176
  const accountInfo = {
1333
- universalAddress: createUniversalAddress(chainId, address),
2177
+ universalAddress: createUniversalAddress(targetChainId, address),
1334
2178
  nativeAddress: address,
1335
- chainId,
2179
+ chainId: targetChainId,
1336
2180
  chainType: ChainType.EVM,
1337
2181
  isActive: true
1338
2182
  };
@@ -1544,38 +2388,2094 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1544
2388
  };
1545
2389
  }
1546
2390
  };
1547
-
1548
- // src/core/adapter-registry.ts
1549
- var AdapterRegistry = class {
1550
- constructor() {
1551
- this.adapters = /* @__PURE__ */ new Map();
1552
- this.registerDefaultAdapters();
1553
- }
1554
- /**
1555
- * Register default adapters
1556
- */
1557
- registerDefaultAdapters() {
1558
- this.register("metamask" /* METAMASK */, () => new MetaMaskAdapter());
1559
- this.register("private-key" /* PRIVATE_KEY */, () => new EVMPrivateKeyAdapter());
1560
- this.register("tronlink" /* TRONLINK */, () => new TronLinkAdapter());
1561
- }
1562
- /**
1563
- * Register adapter
1564
- */
1565
- register(type, factory) {
1566
- this.adapters.set(type, factory);
1567
- }
1568
- /**
1569
- * Get adapter
1570
- */
1571
- getAdapter(type) {
1572
- const factory = this.adapters.get(type);
1573
- if (!factory) {
1574
- return null;
1575
- }
1576
- return factory();
1577
- }
1578
- /**
2391
+ init_types();
2392
+ var _WalletConnectAdapter = class _WalletConnectAdapter extends WalletAdapter {
2393
+ constructor(projectId) {
2394
+ super();
2395
+ this.type = "walletconnect" /* WALLETCONNECT */;
2396
+ this.chainType = ChainType.EVM;
2397
+ this.name = "WalletConnect";
2398
+ this.icon = "https://avatars.githubusercontent.com/u/37784886";
2399
+ this.provider = null;
2400
+ this.walletClient = null;
2401
+ this.publicClient = null;
2402
+ this.supportedChains = [];
2403
+ /**
2404
+ * Handle accounts changed
2405
+ */
2406
+ this.handleAccountsChanged = (accounts) => {
2407
+ if (accounts.length === 0) {
2408
+ this.setState("disconnected" /* DISCONNECTED */);
2409
+ this.setAccount(null);
2410
+ this.emitAccountChanged(null);
2411
+ } else {
2412
+ const address = formatEVMAddress(accounts[0]);
2413
+ const account = {
2414
+ universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
2415
+ nativeAddress: address,
2416
+ chainId: this.currentAccount.chainId,
2417
+ chainType: ChainType.EVM,
2418
+ isActive: true
2419
+ };
2420
+ this.setAccount(account);
2421
+ this.emitAccountChanged(account);
2422
+ }
2423
+ };
2424
+ /**
2425
+ * Handle chain changed
2426
+ */
2427
+ this.handleChainChanged = (chainIdHex) => {
2428
+ const chainId = parseInt(chainIdHex, 16);
2429
+ if (this.currentAccount) {
2430
+ const account = {
2431
+ ...this.currentAccount,
2432
+ chainId,
2433
+ universalAddress: createUniversalAddress(chainId, this.currentAccount.nativeAddress)
2434
+ };
2435
+ this.setAccount(account);
2436
+ this.emitChainChanged(chainId);
2437
+ const viemChain = this.getViemChain(chainId);
2438
+ const chainInfo = getChainInfo(chainId);
2439
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2440
+ if (this.provider) {
2441
+ this.walletClient = viem.createWalletClient({
2442
+ account: this.currentAccount.nativeAddress,
2443
+ chain: viemChain,
2444
+ transport: viem.custom(this.provider)
2445
+ });
2446
+ this.publicClient = viem.createPublicClient({
2447
+ chain: viemChain,
2448
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(this.provider)
2449
+ });
2450
+ }
2451
+ }
2452
+ };
2453
+ /**
2454
+ * Handle disconnect
2455
+ */
2456
+ this.handleDisconnect = () => {
2457
+ this.setState("disconnected" /* DISCONNECTED */);
2458
+ this.setAccount(null);
2459
+ if (_WalletConnectAdapter.providerInstance === this.provider) {
2460
+ _WalletConnectAdapter.providerInstance = null;
2461
+ _WalletConnectAdapter.providerProjectId = null;
2462
+ }
2463
+ this.provider = null;
2464
+ this.walletClient = null;
2465
+ this.publicClient = null;
2466
+ this.emitDisconnected();
2467
+ };
2468
+ if (!projectId) {
2469
+ throw new ConfigurationError("WalletConnect projectId is required");
2470
+ }
2471
+ this.projectId = projectId;
2472
+ }
2473
+ /**
2474
+ * Check if WalletConnect is available
2475
+ * WalletConnect is always available (it's a web-based connection)
2476
+ * Also works in Telegram Mini Apps
2477
+ */
2478
+ async isAvailable() {
2479
+ return typeof window !== "undefined";
2480
+ }
2481
+ /**
2482
+ * Check if running in Telegram environment (Mini App or Web)
2483
+ * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
2484
+ * provide window.Telegram.WebApp API, so they are treated the same way.
2485
+ *
2486
+ * Reference: https://docs.reown.com/appkit/integrations/telegram-mini-apps
2487
+ */
2488
+ isTelegramMiniApp() {
2489
+ if (typeof window === "undefined") return false;
2490
+ const tg = window.Telegram?.WebApp;
2491
+ if (!tg) return false;
2492
+ const platform = tg.platform || "unknown";
2493
+ console.log("[WalletConnect] Telegram environment detected:", {
2494
+ platform,
2495
+ version: tg.version,
2496
+ isMiniApp: platform !== "web",
2497
+ // Mini App if not web platform
2498
+ isWeb: platform === "web"
2499
+ // Telegram Web if web platform
2500
+ });
2501
+ return true;
2502
+ }
2503
+ /**
2504
+ * Get Telegram WebApp instance if available
2505
+ */
2506
+ getTelegramWebApp() {
2507
+ if (typeof window === "undefined") return null;
2508
+ return window.Telegram?.WebApp || null;
2509
+ }
2510
+ /**
2511
+ * Close Telegram deep link popup (wc:// links)
2512
+ * In Telegram Mini Apps, WalletConnect may open a wc:// deep link popup
2513
+ * that doesn't automatically close after the operation completes.
2514
+ * This method attempts to close it by:
2515
+ * 1. Trying to close any open windows/popups
2516
+ * 2. Using Telegram WebApp API if available
2517
+ * 3. Navigating back or closing the popup
2518
+ */
2519
+ closeTelegramDeepLinkPopup() {
2520
+ if (!this.isTelegramMiniApp()) {
2521
+ return;
2522
+ }
2523
+ try {
2524
+ const tg = this.getTelegramWebApp();
2525
+ if (!tg) {
2526
+ return;
2527
+ }
2528
+ if (typeof window !== "undefined") {
2529
+ window.focus();
2530
+ if (tg.BackButton && tg.BackButton.isVisible) {
2531
+ console.log("[WalletConnect] Closing Telegram deep link popup via BackButton");
2532
+ }
2533
+ setTimeout(() => {
2534
+ if (document.hasFocus()) {
2535
+ console.log("[WalletConnect] Main window has focus, popup likely closed");
2536
+ } else {
2537
+ window.focus();
2538
+ console.log("[WalletConnect] Attempted to focus main window to close popup");
2539
+ }
2540
+ }, 500);
2541
+ const handleVisibilityChange = () => {
2542
+ if (document.visibilityState === "visible") {
2543
+ console.log("[WalletConnect] Page became visible, popup may have closed");
2544
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
2545
+ }
2546
+ };
2547
+ document.addEventListener("visibilitychange", handleVisibilityChange);
2548
+ setTimeout(() => {
2549
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
2550
+ }, 2e3);
2551
+ }
2552
+ } catch (error) {
2553
+ console.warn("[WalletConnect] Error closing Telegram deep link popup:", error);
2554
+ }
2555
+ }
2556
+ /**
2557
+ * Connect wallet
2558
+ *
2559
+ * @param chainId - Single chain ID or array of chain IDs to request
2560
+ * If array is provided, wallet will be requested to connect to multiple chains
2561
+ * When multiple chains are requested, the wallet can switch between them
2562
+ * Default: 1 (Ethereum Mainnet)
2563
+ *
2564
+ * @example
2565
+ * // Single chain
2566
+ * await adapter.connect(1) // Ethereum only
2567
+ *
2568
+ * @example
2569
+ * // Multiple chains
2570
+ * await adapter.connect([1, 56, 137]) // Ethereum, BSC, Polygon
2571
+ */
2572
+ async connect(chainId) {
2573
+ if (typeof window === "undefined") {
2574
+ throw new Error("WalletConnect requires a browser environment");
2575
+ }
2576
+ if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2577
+ const existingProvider = _WalletConnectAdapter.providerInstance;
2578
+ if (existingProvider.accounts && existingProvider.accounts.length > 0) {
2579
+ this.provider = existingProvider;
2580
+ let targetChains;
2581
+ if (Array.isArray(chainId)) {
2582
+ targetChains = chainId.length > 0 ? chainId : [1];
2583
+ } else if (chainId) {
2584
+ targetChains = [chainId];
2585
+ } else {
2586
+ targetChains = [1];
2587
+ }
2588
+ const existingChains = this.supportedChains || [];
2589
+ const mergedChains = [.../* @__PURE__ */ new Set([...existingChains, ...targetChains])];
2590
+ this.supportedChains = mergedChains;
2591
+ const currentChainId = existingProvider.chainId || targetChains[0];
2592
+ const address = formatEVMAddress(existingProvider.accounts[0]);
2593
+ const account = {
2594
+ universalAddress: createUniversalAddress(currentChainId, address),
2595
+ nativeAddress: address,
2596
+ chainId: currentChainId,
2597
+ chainType: ChainType.EVM,
2598
+ isActive: true
2599
+ };
2600
+ this.setState("connected" /* CONNECTED */);
2601
+ this.setAccount(account);
2602
+ if (!this.walletClient) {
2603
+ const viemChain = this.getViemChain(currentChainId);
2604
+ this.walletClient = viem.createWalletClient({
2605
+ account: existingProvider.accounts[0],
2606
+ chain: viemChain,
2607
+ transport: viem.custom(existingProvider)
2608
+ });
2609
+ const chainInfo = getChainInfo(currentChainId);
2610
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2611
+ this.publicClient = viem.createPublicClient({
2612
+ chain: viemChain,
2613
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(existingProvider)
2614
+ });
2615
+ this.setupEventListeners();
2616
+ }
2617
+ console.log("[WalletConnect] Reusing existing provider session");
2618
+ return account;
2619
+ }
2620
+ }
2621
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount && this.provider) {
2622
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2623
+ let targetChains;
2624
+ if (Array.isArray(chainId)) {
2625
+ targetChains = chainId.length > 0 ? chainId : [1];
2626
+ } else if (chainId) {
2627
+ targetChains = [chainId];
2628
+ } else {
2629
+ targetChains = [1];
2630
+ }
2631
+ const existingChains = this.supportedChains || [];
2632
+ const mergedChains = [.../* @__PURE__ */ new Set([...existingChains, ...targetChains])];
2633
+ this.supportedChains = mergedChains;
2634
+ console.log("[WalletConnect] Already connected, reusing existing connection");
2635
+ return this.currentAccount;
2636
+ } else {
2637
+ this.setState("disconnected" /* DISCONNECTED */);
2638
+ this.setAccount(null);
2639
+ this.provider = null;
2640
+ }
2641
+ }
2642
+ try {
2643
+ this.setState("connecting" /* CONNECTING */);
2644
+ let targetChains;
2645
+ if (Array.isArray(chainId)) {
2646
+ targetChains = chainId.length > 0 ? chainId : [1];
2647
+ } else if (chainId) {
2648
+ targetChains = [chainId];
2649
+ } else {
2650
+ targetChains = [1];
2651
+ }
2652
+ this.supportedChains = targetChains;
2653
+ const primaryChain = targetChains[0];
2654
+ const optionalChains = targetChains.slice(1);
2655
+ const isTelegram = this.isTelegramMiniApp();
2656
+ const telegramWebApp = this.getTelegramWebApp();
2657
+ let appUrl = "";
2658
+ if (typeof window !== "undefined") {
2659
+ try {
2660
+ if (window.location && window.location.origin) {
2661
+ appUrl = window.location.origin;
2662
+ } else if (window.location && window.location.href) {
2663
+ const url = new URL(window.location.href);
2664
+ appUrl = url.origin;
2665
+ }
2666
+ } catch (error) {
2667
+ console.warn("[WalletConnect] Failed to get origin from window.location:", error);
2668
+ }
2669
+ if (!appUrl) {
2670
+ appUrl = "https://enclave.network";
2671
+ }
2672
+ } else {
2673
+ appUrl = "https://enclave.network";
2674
+ }
2675
+ if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
2676
+ appUrl = "https://enclave.network";
2677
+ }
2678
+ const icons = [
2679
+ "https://walletconnect.com/walletconnect-logo.svg",
2680
+ "https://avatars.githubusercontent.com/u/37784886"
2681
+ // WalletConnect GitHub avatar
2682
+ ];
2683
+ const initOptions = {
2684
+ projectId: this.projectId,
2685
+ chains: [primaryChain],
2686
+ // Primary chain (required)
2687
+ showQrModal: true,
2688
+ // QR modal works in Telegram Mini Apps
2689
+ metadata: {
2690
+ name: "Enclave Wallet SDK",
2691
+ description: "Multi-chain wallet adapter for Enclave",
2692
+ url: appUrl,
2693
+ icons
2694
+ }
2695
+ };
2696
+ if (isTelegram && telegramWebApp) {
2697
+ const platform = telegramWebApp.platform || "unknown";
2698
+ const isMiniApp = platform !== "web";
2699
+ console.log("[WalletConnect] Detected Telegram environment:", {
2700
+ platform,
2701
+ isMiniApp,
2702
+ isWeb: platform === "web"
2703
+ });
2704
+ if (telegramWebApp.isExpanded === false) {
2705
+ telegramWebApp.expand();
2706
+ }
2707
+ }
2708
+ if (optionalChains.length > 0) {
2709
+ initOptions.optionalChains = optionalChains;
2710
+ } else {
2711
+ initOptions.optionalChains = [primaryChain];
2712
+ }
2713
+ const hasExistingProvider = _WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId;
2714
+ const needsReinit = hasExistingProvider && _WalletConnectAdapter.providerChains !== null && JSON.stringify(_WalletConnectAdapter.providerChains.sort()) !== JSON.stringify(targetChains.sort());
2715
+ if (needsReinit) {
2716
+ console.log("[WalletConnect] Provider initialized with different chains, reinitializing...", {
2717
+ existing: _WalletConnectAdapter.providerChains,
2718
+ requested: targetChains
2719
+ });
2720
+ const existingProvider = _WalletConnectAdapter.providerInstance;
2721
+ if (existingProvider) {
2722
+ try {
2723
+ if (existingProvider.accounts && existingProvider.accounts.length > 0) {
2724
+ await existingProvider.disconnect();
2725
+ }
2726
+ } catch (error) {
2727
+ console.warn("[WalletConnect] Error disconnecting existing provider:", error);
2728
+ }
2729
+ }
2730
+ _WalletConnectAdapter.providerInstance = null;
2731
+ _WalletConnectAdapter.providerChains = null;
2732
+ }
2733
+ if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2734
+ this.provider = _WalletConnectAdapter.providerInstance;
2735
+ console.log("[WalletConnect] Reusing existing provider instance");
2736
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2737
+ console.log("[WalletConnect] Provider already has accounts, skipping enable()");
2738
+ } else {
2739
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2740
+ console.log("[WalletConnect] Provider has no accounts, calling enable() to show QR modal");
2741
+ console.log("[WalletConnect] Provider state:", {
2742
+ accounts: this.provider.accounts,
2743
+ chainId: this.provider.chainId,
2744
+ hasSession,
2745
+ sessionTopic: this.provider.session?.topic
2746
+ });
2747
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2748
+ console.log("[WalletConnect] Found stale session, disconnecting before reconnecting...");
2749
+ try {
2750
+ await this.provider.disconnect();
2751
+ await new Promise((resolve) => setTimeout(resolve, 100));
2752
+ } catch (disconnectError) {
2753
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2754
+ }
2755
+ }
2756
+ try {
2757
+ console.log("[WalletConnect] Calling enable()...");
2758
+ const enableResult = await this.provider.enable();
2759
+ console.log("[WalletConnect] enable() completed, result:", enableResult);
2760
+ console.log("[WalletConnect] Provider state after enable():", {
2761
+ accounts: this.provider.accounts,
2762
+ chainId: this.provider.chainId,
2763
+ session: this.provider.session ? {
2764
+ topic: this.provider.session.topic,
2765
+ namespaces: this.provider.session.namespaces ? Object.keys(this.provider.session.namespaces) : "none"
2766
+ } : "none"
2767
+ });
2768
+ } catch (error) {
2769
+ console.error("[WalletConnect] enable() error:", error);
2770
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2771
+ throw new ConnectionRejectedError(this.type);
2772
+ }
2773
+ throw error;
2774
+ }
2775
+ }
2776
+ } else if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2777
+ this.provider = _WalletConnectAdapter.providerInstance;
2778
+ console.log("[WalletConnect] Reusing existing provider instance (not connected)");
2779
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2780
+ console.log("[WalletConnect] Provider already has accounts after init, skipping enable()");
2781
+ } else {
2782
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2783
+ console.log("[WalletConnect] Provider has no accounts, calling enable() to show QR modal");
2784
+ console.log("[WalletConnect] Provider state:", {
2785
+ accounts: this.provider.accounts,
2786
+ chainId: this.provider.chainId,
2787
+ hasSession,
2788
+ sessionTopic: this.provider.session?.topic
2789
+ });
2790
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2791
+ console.log("[WalletConnect] Found stale session after init, disconnecting before reconnecting...");
2792
+ try {
2793
+ await this.provider.disconnect();
2794
+ await new Promise((resolve) => setTimeout(resolve, 100));
2795
+ } catch (disconnectError) {
2796
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2797
+ }
2798
+ }
2799
+ try {
2800
+ await this.provider.enable();
2801
+ } catch (error) {
2802
+ console.error("[WalletConnect] enable() error:", error);
2803
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2804
+ throw new ConnectionRejectedError(this.type);
2805
+ }
2806
+ throw error;
2807
+ }
2808
+ }
2809
+ } else if (_WalletConnectAdapter.isInitializing && _WalletConnectAdapter.initPromise) {
2810
+ console.log("[WalletConnect] Waiting for ongoing initialization...");
2811
+ this.provider = await _WalletConnectAdapter.initPromise;
2812
+ _WalletConnectAdapter.providerInstance = this.provider;
2813
+ _WalletConnectAdapter.providerProjectId = this.projectId;
2814
+ _WalletConnectAdapter.providerChains = targetChains;
2815
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2816
+ console.log("[WalletConnect] Provider already has accounts after init, skipping enable()");
2817
+ } else {
2818
+ try {
2819
+ await this.provider.enable();
2820
+ } catch (error) {
2821
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2822
+ throw new ConnectionRejectedError(this.type);
2823
+ }
2824
+ throw error;
2825
+ }
2826
+ }
2827
+ } else {
2828
+ console.log("[WalletConnect] Initializing new provider with chains:", {
2829
+ primary: primaryChain,
2830
+ optional: optionalChains,
2831
+ all: targetChains
2832
+ });
2833
+ _WalletConnectAdapter.isInitializing = true;
2834
+ _WalletConnectAdapter.initPromise = EthereumProvider__default.default.init(initOptions);
2835
+ try {
2836
+ this.provider = await _WalletConnectAdapter.initPromise;
2837
+ _WalletConnectAdapter.providerInstance = this.provider;
2838
+ _WalletConnectAdapter.providerProjectId = this.projectId;
2839
+ _WalletConnectAdapter.providerChains = targetChains;
2840
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2841
+ console.log("[WalletConnect] Provider has restored session, skipping enable()");
2842
+ } else {
2843
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2844
+ console.log("[WalletConnect] New provider initialized, calling enable() to show QR modal");
2845
+ console.log("[WalletConnect] Provider state:", {
2846
+ accounts: this.provider.accounts,
2847
+ chainId: this.provider.chainId,
2848
+ hasSession,
2849
+ sessionTopic: this.provider.session?.topic
2850
+ });
2851
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2852
+ console.log("[WalletConnect] Found stale session after init, disconnecting before reconnecting...");
2853
+ try {
2854
+ await this.provider.disconnect();
2855
+ await new Promise((resolve) => setTimeout(resolve, 100));
2856
+ } catch (disconnectError) {
2857
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2858
+ }
2859
+ }
2860
+ try {
2861
+ await this.provider.enable();
2862
+ } catch (error) {
2863
+ console.error("[WalletConnect] enable() error:", error);
2864
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2865
+ throw new ConnectionRejectedError(this.type);
2866
+ }
2867
+ throw error;
2868
+ }
2869
+ }
2870
+ } finally {
2871
+ _WalletConnectAdapter.isInitializing = false;
2872
+ _WalletConnectAdapter.initPromise = null;
2873
+ }
2874
+ }
2875
+ let accounts = this.provider.accounts;
2876
+ if (!accounts || accounts.length === 0) {
2877
+ console.log("[WalletConnect] provider.accounts is empty, checking session.namespaces.eip155.accounts...");
2878
+ const session = this.provider.session;
2879
+ if (session && session.namespaces?.eip155?.accounts) {
2880
+ const sessionAccounts = session.namespaces.eip155.accounts.map((acc) => {
2881
+ const parts = acc.split(":");
2882
+ if (parts.length >= 3 && parts[0] === "eip155") {
2883
+ return parts[2];
2884
+ }
2885
+ return null;
2886
+ }).filter((addr) => addr !== null && addr.startsWith("0x"));
2887
+ if (sessionAccounts.length > 0) {
2888
+ const uniqueAccounts = [...new Set(sessionAccounts)];
2889
+ console.log("[WalletConnect] Found accounts in session.namespaces.eip155.accounts:", {
2890
+ raw: session.namespaces.eip155.accounts,
2891
+ extracted: uniqueAccounts,
2892
+ chains: session.namespaces.eip155.chains
2893
+ });
2894
+ accounts = uniqueAccounts;
2895
+ }
2896
+ }
2897
+ }
2898
+ if (!accounts || accounts.length === 0) {
2899
+ console.log("[WalletConnect] Accounts not available, waiting for provider.accounts to populate...");
2900
+ const maxWaitTime = 3e3;
2901
+ const checkInterval = 100;
2902
+ const maxChecks = maxWaitTime / checkInterval;
2903
+ for (let i = 0; i < maxChecks; i++) {
2904
+ await new Promise((resolve) => setTimeout(resolve, checkInterval));
2905
+ accounts = this.provider.accounts;
2906
+ if (accounts && accounts.length > 0) {
2907
+ console.log(`[WalletConnect] Accounts available after ${(i + 1) * checkInterval}ms`);
2908
+ break;
2909
+ }
2910
+ }
2911
+ }
2912
+ if (!accounts || accounts.length === 0) {
2913
+ const session = this.provider.session;
2914
+ const providerState = {
2915
+ providerAccounts: this.provider.accounts,
2916
+ providerChainId: this.provider.chainId,
2917
+ session: session ? {
2918
+ exists: true,
2919
+ topic: session.topic,
2920
+ namespaces: session.namespaces ? Object.keys(session.namespaces) : "none",
2921
+ eip155Namespace: session.namespaces?.eip155 ? {
2922
+ accounts: session.namespaces.eip155.accounts,
2923
+ // CAIP-10 format
2924
+ chains: session.namespaces.eip155.chains,
2925
+ // CAIP-2 format
2926
+ methods: session.namespaces.eip155.methods,
2927
+ events: session.namespaces.eip155.events
2928
+ } : "none",
2929
+ // Log full session structure for debugging
2930
+ fullSession: JSON.stringify(session, null, 2)
2931
+ } : "none",
2932
+ // Check if provider has any other properties that might contain accounts
2933
+ providerKeys: Object.keys(this.provider)
2934
+ };
2935
+ console.error("[WalletConnect] No accounts available after enable() and wait", providerState);
2936
+ console.error("[WalletConnect] Full provider object:", this.provider);
2937
+ console.error("[WalletConnect] Full session object:", session);
2938
+ console.error("[WalletConnect] Session namespaces structure:", session?.namespaces);
2939
+ throw new Error("WalletConnect connection established but no accounts available. Please check session.namespaces.eip155.accounts in the console logs above.");
2940
+ }
2941
+ const currentChainId = this.provider.chainId || targetChains[0];
2942
+ const viemChain = this.getViemChain(currentChainId);
2943
+ this.walletClient = viem.createWalletClient({
2944
+ account: accounts[0],
2945
+ chain: viemChain,
2946
+ transport: viem.custom(this.provider)
2947
+ });
2948
+ const chainInfo = getChainInfo(currentChainId);
2949
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2950
+ this.publicClient = viem.createPublicClient({
2951
+ chain: viemChain,
2952
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(this.provider)
2953
+ });
2954
+ const address = formatEVMAddress(accounts[0]);
2955
+ const account = {
2956
+ universalAddress: createUniversalAddress(currentChainId, address),
2957
+ nativeAddress: address,
2958
+ chainId: currentChainId,
2959
+ chainType: ChainType.EVM,
2960
+ isActive: true
2961
+ };
2962
+ this.setState("connected" /* CONNECTED */);
2963
+ this.setAccount(account);
2964
+ this.setupEventListeners();
2965
+ return account;
2966
+ } catch (error) {
2967
+ this.setState("error" /* ERROR */);
2968
+ this.setAccount(null);
2969
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
2970
+ const errorCode = error?.code;
2971
+ const errorMessage = error?.message || String(error);
2972
+ const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
2973
+ const session = this.provider?.session;
2974
+ const providerState = this.provider ? {
2975
+ accounts: this.provider.accounts,
2976
+ chainId: this.provider.chainId,
2977
+ session: session ? {
2978
+ exists: true,
2979
+ topic: session.topic,
2980
+ namespaces: session.namespaces ? Object.keys(session.namespaces) : "none",
2981
+ eip155Namespace: session.namespaces?.eip155 ? {
2982
+ accounts: session.namespaces.eip155.accounts,
2983
+ chains: session.namespaces.eip155.chains,
2984
+ methods: session.namespaces.eip155.methods,
2985
+ events: session.namespaces.eip155.events
2986
+ } : "none"
2987
+ } : "none",
2988
+ providerKeys: Object.keys(this.provider)
2989
+ } : "no provider";
2990
+ console.error("[WalletConnect] Connection error:", {
2991
+ error,
2992
+ code: error.code,
2993
+ message: error.message,
2994
+ stack: error.stack,
2995
+ providerState
2996
+ });
2997
+ if (this.provider) {
2998
+ console.error("[WalletConnect] Full provider object:", this.provider);
2999
+ console.error("[WalletConnect] Full session object:", session);
3000
+ }
3001
+ if (error.code === 4001 || error.message && (error.message.includes("User rejected") || error.message.includes("rejected by user") || error.message.includes("User cancelled"))) {
3002
+ throw new ConnectionRejectedError(this.type);
3003
+ }
3004
+ if (isOriginNotAllowed) {
3005
+ throw new ConfigurationError(
3006
+ `WalletConnect relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
3007
+
3008
+ Fix:
3009
+ 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
3010
+ 2) Add this site origin to the allowlist:
3011
+ - ${origin || "(unknown origin)"}
3012
+
3013
+ Common dev origins to allow:
3014
+ - http://localhost:5173
3015
+ - http://192.168.0.221:5173 (your LAN dev URL)
3016
+ - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
3017
+
3018
+ Original error: ${errorMessage}`
3019
+ );
3020
+ }
3021
+ throw error;
3022
+ }
3023
+ }
3024
+ /**
3025
+ * Disconnect wallet
3026
+ */
3027
+ async disconnect() {
3028
+ if (this.provider) {
3029
+ try {
3030
+ await this.provider.disconnect();
3031
+ } catch (error) {
3032
+ console.warn("[WalletConnect] Error during disconnect:", error);
3033
+ }
3034
+ if (_WalletConnectAdapter.providerInstance === this.provider) {
3035
+ _WalletConnectAdapter.providerInstance = null;
3036
+ _WalletConnectAdapter.providerProjectId = null;
3037
+ _WalletConnectAdapter.providerChains = null;
3038
+ }
3039
+ this.provider = null;
3040
+ }
3041
+ this.removeEventListeners();
3042
+ this.walletClient = null;
3043
+ this.publicClient = null;
3044
+ this.setState("disconnected" /* DISCONNECTED */);
3045
+ this.setAccount(null);
3046
+ this.emitDisconnected();
3047
+ }
3048
+ /**
3049
+ * Sign message
3050
+ */
3051
+ async signMessage(message) {
3052
+ this.ensureConnected();
3053
+ try {
3054
+ if (!this.provider) {
3055
+ throw new Error("Provider not initialized");
3056
+ }
3057
+ const signature = await this.provider.request({
3058
+ method: "personal_sign",
3059
+ params: [message, this.currentAccount.nativeAddress]
3060
+ });
3061
+ this.closeTelegramDeepLinkPopup();
3062
+ return signature;
3063
+ } catch (error) {
3064
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3065
+ throw new SignatureRejectedError();
3066
+ }
3067
+ throw error;
3068
+ }
3069
+ }
3070
+ /**
3071
+ * Sign TypedData (EIP-712)
3072
+ */
3073
+ async signTypedData(typedData) {
3074
+ this.ensureConnected();
3075
+ try {
3076
+ if (!this.provider) {
3077
+ throw new Error("Provider not initialized");
3078
+ }
3079
+ const signature = await this.provider.request({
3080
+ method: "eth_signTypedData_v4",
3081
+ params: [this.currentAccount.nativeAddress, JSON.stringify(typedData)]
3082
+ });
3083
+ this.closeTelegramDeepLinkPopup();
3084
+ return signature;
3085
+ } catch (error) {
3086
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3087
+ throw new SignatureRejectedError();
3088
+ }
3089
+ throw error;
3090
+ }
3091
+ }
3092
+ /**
3093
+ * Sign transaction
3094
+ */
3095
+ async signTransaction(transaction) {
3096
+ this.ensureConnected();
3097
+ try {
3098
+ if (!this.provider) {
3099
+ throw new Error("Provider not initialized");
3100
+ }
3101
+ const tx = {
3102
+ from: this.currentAccount.nativeAddress,
3103
+ to: transaction.to,
3104
+ value: transaction.value ? `0x${BigInt(transaction.value).toString(16)}` : void 0,
3105
+ data: transaction.data || "0x",
3106
+ gas: transaction.gas ? `0x${BigInt(transaction.gas).toString(16)}` : void 0,
3107
+ gasPrice: transaction.gasPrice && transaction.gasPrice !== "auto" ? `0x${BigInt(transaction.gasPrice).toString(16)}` : void 0,
3108
+ maxFeePerGas: transaction.maxFeePerGas ? `0x${BigInt(transaction.maxFeePerGas).toString(16)}` : void 0,
3109
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas ? `0x${BigInt(transaction.maxPriorityFeePerGas).toString(16)}` : void 0,
3110
+ nonce: transaction.nonce !== void 0 ? `0x${transaction.nonce.toString(16)}` : void 0,
3111
+ chainId: transaction.chainId || this.currentAccount.chainId
3112
+ };
3113
+ const signature = await this.provider.request({
3114
+ method: "eth_signTransaction",
3115
+ params: [tx]
3116
+ });
3117
+ this.closeTelegramDeepLinkPopup();
3118
+ return signature;
3119
+ } catch (error) {
3120
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3121
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
3122
+ }
3123
+ throw error;
3124
+ }
3125
+ }
3126
+ /**
3127
+ * Get supported chains from current connection
3128
+ * Returns the chains that were requested during connection
3129
+ */
3130
+ getSupportedChains() {
3131
+ return [...this.supportedChains];
3132
+ }
3133
+ /**
3134
+ * Switch chain
3135
+ *
3136
+ * Note: WalletConnect v2 with mobile wallets may not support chain switching reliably.
3137
+ * Some wallets may ignore the switch request or fail silently.
3138
+ * It's recommended to include all needed chains in the initial connection.
3139
+ *
3140
+ * Reference: https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces
3141
+ */
3142
+ async switchChain(chainId) {
3143
+ if (!this.provider) {
3144
+ throw new Error("Provider not initialized");
3145
+ }
3146
+ const session = this.provider.session;
3147
+ const supportedChains = session?.namespaces?.eip155?.chains || [];
3148
+ const targetChainCAIP = `eip155:${chainId}`;
3149
+ const isChainApproved = supportedChains.includes(targetChainCAIP);
3150
+ if (!isChainApproved) {
3151
+ console.warn(`[WalletConnect] Chain ${chainId} (${targetChainCAIP}) not in session approved chains:`, supportedChains);
3152
+ console.warn("[WalletConnect] Chain switching may fail. Consider including all chains in initial connection.");
3153
+ }
3154
+ try {
3155
+ console.log(`[WalletConnect] Attempting to switch to chain ${chainId} (${targetChainCAIP})`);
3156
+ const result = await this.provider.request({
3157
+ method: "wallet_switchEthereumChain",
3158
+ params: [{ chainId: `0x${chainId.toString(16)}` }]
3159
+ });
3160
+ if (result !== null && result !== void 0) {
3161
+ console.warn("[WalletConnect] wallet_switchEthereumChain returned non-null result:", result);
3162
+ }
3163
+ await new Promise((resolve) => setTimeout(resolve, 500));
3164
+ const currentChainId = this.provider.chainId;
3165
+ if (currentChainId !== chainId) {
3166
+ console.warn(`[WalletConnect] Chain switch may have failed. Expected ${chainId}, got ${currentChainId}`);
3167
+ console.warn("[WalletConnect] Some mobile wallets may not support chain switching via WalletConnect.");
3168
+ console.warn("[WalletConnect] User may need to manually switch chains in the wallet app.");
3169
+ }
3170
+ if (this.currentAccount) {
3171
+ const updatedAccount = {
3172
+ ...this.currentAccount,
3173
+ chainId,
3174
+ universalAddress: createUniversalAddress(chainId, this.currentAccount.nativeAddress)
3175
+ };
3176
+ this.setAccount(updatedAccount);
3177
+ this.emitChainChanged(chainId);
3178
+ const viemChain = this.getViemChain(chainId);
3179
+ const chainInfo = getChainInfo(chainId);
3180
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
3181
+ this.walletClient = viem.createWalletClient({
3182
+ account: this.currentAccount.nativeAddress,
3183
+ chain: viemChain,
3184
+ transport: viem.custom(this.provider)
3185
+ });
3186
+ this.publicClient = viem.createPublicClient({
3187
+ chain: viemChain,
3188
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(this.provider)
3189
+ });
3190
+ }
3191
+ } catch (error) {
3192
+ console.error("[WalletConnect] Chain switch error:", {
3193
+ chainId,
3194
+ errorCode: error.code,
3195
+ errorMessage: error.message,
3196
+ supportedChains
3197
+ });
3198
+ if (error.code === 4902) {
3199
+ console.log(`[WalletConnect] Chain ${chainId} not found in wallet, attempting to add...`);
3200
+ const chainInfo = getChainInfo(chainId);
3201
+ if (chainInfo) {
3202
+ try {
3203
+ await this.addChain({
3204
+ chainId: chainInfo.id,
3205
+ chainName: chainInfo.name,
3206
+ nativeCurrency: chainInfo.nativeCurrency,
3207
+ rpcUrls: chainInfo.rpcUrls,
3208
+ blockExplorerUrls: chainInfo.blockExplorerUrls
3209
+ });
3210
+ console.log(`[WalletConnect] Chain added, attempting to switch again...`);
3211
+ await this.switchChain(chainId);
3212
+ } catch (addError) {
3213
+ console.error("[WalletConnect] Failed to add chain:", addError);
3214
+ throw new Error(`Failed to add chain ${chainId}: ${addError.message}`);
3215
+ }
3216
+ } else {
3217
+ throw new Error(`Chain ${chainId} not supported`);
3218
+ }
3219
+ } else if (error.code === 4001) {
3220
+ throw new Error("User rejected chain switch");
3221
+ } else if (error.code === 4100) {
3222
+ throw new Error("Wallet does not support wallet_switchEthereumChain. Please switch chains manually in your wallet app.");
3223
+ } else {
3224
+ console.warn("[WalletConnect] Chain switch may not be supported by this wallet. User may need to switch manually.");
3225
+ throw error;
3226
+ }
3227
+ }
3228
+ }
3229
+ /**
3230
+ * Add chain
3231
+ */
3232
+ async addChain(chainConfig) {
3233
+ if (!this.provider) {
3234
+ throw new Error("Provider not initialized");
3235
+ }
3236
+ await this.provider.request({
3237
+ method: "wallet_addEthereumChain",
3238
+ params: [{
3239
+ chainId: `0x${chainConfig.chainId.toString(16)}`,
3240
+ chainName: chainConfig.chainName,
3241
+ nativeCurrency: chainConfig.nativeCurrency,
3242
+ rpcUrls: chainConfig.rpcUrls,
3243
+ blockExplorerUrls: chainConfig.blockExplorerUrls
3244
+ }]
3245
+ });
3246
+ }
3247
+ /**
3248
+ * Read contract
3249
+ */
3250
+ async readContract(params) {
3251
+ if (!this.publicClient) {
3252
+ throw new Error("Public client not initialized");
3253
+ }
3254
+ const result = await this.publicClient.readContract({
3255
+ address: params.address,
3256
+ abi: params.abi,
3257
+ functionName: params.functionName,
3258
+ ...params.args ? { args: params.args } : {}
3259
+ });
3260
+ return result;
3261
+ }
3262
+ /**
3263
+ * Write contract
3264
+ */
3265
+ async writeContract(params) {
3266
+ this.ensureConnected();
3267
+ if (!this.walletClient) {
3268
+ throw new Error("Wallet client not initialized");
3269
+ }
3270
+ try {
3271
+ const txOptions = {
3272
+ address: params.address,
3273
+ abi: params.abi,
3274
+ functionName: params.functionName,
3275
+ ...params.args ? { args: params.args } : {},
3276
+ value: params.value ? BigInt(params.value) : void 0,
3277
+ gas: params.gas ? BigInt(params.gas) : void 0
3278
+ };
3279
+ if (params.maxFeePerGas || params.maxPriorityFeePerGas) {
3280
+ if (params.maxFeePerGas) {
3281
+ txOptions.maxFeePerGas = BigInt(params.maxFeePerGas);
3282
+ }
3283
+ if (params.maxPriorityFeePerGas) {
3284
+ txOptions.maxPriorityFeePerGas = BigInt(params.maxPriorityFeePerGas);
3285
+ }
3286
+ } else if (params.gasPrice && params.gasPrice !== "auto") {
3287
+ txOptions.gasPrice = BigInt(params.gasPrice);
3288
+ } else {
3289
+ if (this.publicClient) {
3290
+ try {
3291
+ const feesPerGas = await this.publicClient.estimateFeesPerGas().catch(() => null);
3292
+ if (feesPerGas) {
3293
+ const minPriorityFeeWei = BigInt(1e8);
3294
+ const maxPriorityFeePerGas = feesPerGas.maxPriorityFeePerGas > minPriorityFeeWei ? feesPerGas.maxPriorityFeePerGas : minPriorityFeeWei;
3295
+ const adjustedMaxFeePerGas = feesPerGas.maxFeePerGas > maxPriorityFeePerGas ? feesPerGas.maxFeePerGas : maxPriorityFeePerGas + BigInt(1e9);
3296
+ txOptions.maxFeePerGas = adjustedMaxFeePerGas;
3297
+ txOptions.maxPriorityFeePerGas = maxPriorityFeePerGas;
3298
+ } else {
3299
+ const gasPrice = await this.publicClient.getGasPrice();
3300
+ txOptions.gasPrice = gasPrice;
3301
+ }
3302
+ } catch (err) {
3303
+ }
3304
+ }
3305
+ }
3306
+ const txHash = await this.walletClient.writeContract(txOptions);
3307
+ this.closeTelegramDeepLinkPopup();
3308
+ return txHash;
3309
+ } catch (error) {
3310
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3311
+ throw new SignatureRejectedError("Transaction was rejected by user");
3312
+ }
3313
+ throw error;
3314
+ }
3315
+ }
3316
+ /**
3317
+ * Estimate gas
3318
+ */
3319
+ async estimateGas(params) {
3320
+ if (!this.publicClient) {
3321
+ throw new Error("Public client not initialized");
3322
+ }
3323
+ const gas = await this.publicClient.estimateContractGas({
3324
+ address: params.address,
3325
+ abi: params.abi,
3326
+ functionName: params.functionName,
3327
+ ...params.args ? { args: params.args } : {},
3328
+ value: params.value ? BigInt(params.value) : void 0,
3329
+ account: this.currentAccount.nativeAddress
3330
+ });
3331
+ return gas;
3332
+ }
3333
+ /**
3334
+ * Wait for transaction
3335
+ */
3336
+ async waitForTransaction(txHash, confirmations = 1) {
3337
+ if (!this.publicClient) {
3338
+ throw new Error("Public client not initialized");
3339
+ }
3340
+ const receipt = await this.publicClient.waitForTransactionReceipt({
3341
+ hash: txHash,
3342
+ confirmations
3343
+ });
3344
+ if (receipt.status === "reverted") {
3345
+ throw new TransactionFailedError(txHash, "Transaction reverted");
3346
+ }
3347
+ return {
3348
+ transactionHash: receipt.transactionHash,
3349
+ blockNumber: Number(receipt.blockNumber),
3350
+ blockHash: receipt.blockHash,
3351
+ from: receipt.from,
3352
+ to: receipt.to || void 0,
3353
+ status: receipt.status === "success" ? "success" : "failed",
3354
+ gasUsed: receipt.gasUsed.toString(),
3355
+ effectiveGasPrice: receipt.effectiveGasPrice?.toString(),
3356
+ logs: receipt.logs
3357
+ };
3358
+ }
3359
+ /**
3360
+ * Get provider
3361
+ */
3362
+ getProvider() {
3363
+ return this.provider;
3364
+ }
3365
+ /**
3366
+ * Get signer
3367
+ */
3368
+ getSigner() {
3369
+ return this.walletClient;
3370
+ }
3371
+ /**
3372
+ * Setup event listeners
3373
+ */
3374
+ setupEventListeners() {
3375
+ if (!this.provider) return;
3376
+ this.provider.on("accountsChanged", this.handleAccountsChanged);
3377
+ this.provider.on("chainChanged", this.handleChainChanged);
3378
+ this.provider.on("disconnect", this.handleDisconnect);
3379
+ }
3380
+ /**
3381
+ * Remove event listeners
3382
+ */
3383
+ removeEventListeners() {
3384
+ if (!this.provider) return;
3385
+ this.provider.removeListener("accountsChanged", this.handleAccountsChanged);
3386
+ this.provider.removeListener("chainChanged", this.handleChainChanged);
3387
+ this.provider.removeListener("disconnect", this.handleDisconnect);
3388
+ }
3389
+ /**
3390
+ * Get viem chain config
3391
+ */
3392
+ getViemChain(chainId) {
3393
+ const chainInfo = getChainInfo(chainId);
3394
+ if (chainInfo) {
3395
+ return {
3396
+ id: chainId,
3397
+ name: chainInfo.name,
3398
+ network: chainInfo.name.toLowerCase().replace(/\s+/g, "-"),
3399
+ nativeCurrency: chainInfo.nativeCurrency,
3400
+ rpcUrls: {
3401
+ default: { http: chainInfo.rpcUrls },
3402
+ public: { http: chainInfo.rpcUrls }
3403
+ },
3404
+ blockExplorers: chainInfo.blockExplorerUrls ? {
3405
+ default: { name: "Explorer", url: chainInfo.blockExplorerUrls[0] }
3406
+ } : void 0
3407
+ };
3408
+ }
3409
+ return {
3410
+ id: chainId,
3411
+ name: `Chain ${chainId}`,
3412
+ network: `chain-${chainId}`,
3413
+ nativeCurrency: {
3414
+ name: "ETH",
3415
+ symbol: "ETH",
3416
+ decimals: 18
3417
+ },
3418
+ rpcUrls: {
3419
+ default: { http: [] },
3420
+ public: { http: [] }
3421
+ }
3422
+ };
3423
+ }
3424
+ };
3425
+ // Store supported chains from connection
3426
+ // Static provider instance to avoid multiple initializations
3427
+ _WalletConnectAdapter.providerInstance = null;
3428
+ _WalletConnectAdapter.providerProjectId = null;
3429
+ _WalletConnectAdapter.providerChains = null;
3430
+ // Store the chains used during initialization
3431
+ _WalletConnectAdapter.isInitializing = false;
3432
+ _WalletConnectAdapter.initPromise = null;
3433
+ var WalletConnectAdapter = _WalletConnectAdapter;
3434
+
3435
+ // src/adapters/tron/wallet-connect.ts
3436
+ var wallet_connect_exports = {};
3437
+ __export(wallet_connect_exports, {
3438
+ WalletConnectTronAdapter: () => WalletConnectTronAdapter
3439
+ });
3440
+ init_types();
3441
+ var _WalletConnectTronAdapter = class _WalletConnectTronAdapter extends WalletAdapter {
3442
+ constructor(projectId) {
3443
+ super();
3444
+ this.type = "walletconnect-tron" /* WALLETCONNECT_TRON */;
3445
+ this.chainType = ChainType.TRON;
3446
+ this.name = "WalletConnect (Tron)";
3447
+ this.icon = "https://avatars.githubusercontent.com/u/37784886";
3448
+ this.wallet = null;
3449
+ this.currentAddress = null;
3450
+ if (!projectId) {
3451
+ throw new ConfigurationError("WalletConnect projectId is required");
3452
+ }
3453
+ this.projectId = projectId;
3454
+ }
3455
+ /**
3456
+ * Check if WalletConnect is available
3457
+ */
3458
+ async isAvailable() {
3459
+ return typeof window !== "undefined";
3460
+ }
3461
+ /**
3462
+ * Check if running in Telegram environment (Mini App or Web)
3463
+ * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
3464
+ * provide window.Telegram.WebApp API, so they are treated the same way.
3465
+ */
3466
+ isTelegramMiniApp() {
3467
+ if (typeof window === "undefined") return false;
3468
+ const tg = window.Telegram?.WebApp;
3469
+ if (!tg) return false;
3470
+ const platform = tg.platform || "unknown";
3471
+ console.log("[WalletConnect Tron] Telegram environment detected:", {
3472
+ platform,
3473
+ version: tg.version,
3474
+ isMiniApp: platform !== "web",
3475
+ // Mini App if not web platform
3476
+ isWeb: platform === "web"
3477
+ // Telegram Web if web platform
3478
+ });
3479
+ return true;
3480
+ }
3481
+ /**
3482
+ * Restore session from existing wallet (for storage restoration)
3483
+ */
3484
+ async restoreSession(chainId) {
3485
+ if (typeof window === "undefined") {
3486
+ return null;
3487
+ }
3488
+ try {
3489
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3490
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3491
+ this.initializeWallet(targetChainId);
3492
+ }
3493
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
3494
+ if (!this.wallet) {
3495
+ return null;
3496
+ }
3497
+ const status = await this.wallet.checkConnectStatus();
3498
+ if (status && status.address) {
3499
+ this.currentAddress = status.address;
3500
+ const account = {
3501
+ universalAddress: createUniversalAddress(targetChainId, status.address),
3502
+ nativeAddress: status.address,
3503
+ chainId: targetChainId,
3504
+ chainType: ChainType.TRON,
3505
+ isActive: true
3506
+ };
3507
+ this.setState("connected" /* CONNECTED */);
3508
+ this.setAccount(account);
3509
+ this.setupEventListeners();
3510
+ return account;
3511
+ }
3512
+ return null;
3513
+ } catch (error) {
3514
+ console.debug("[WalletConnect Tron] Restore session failed:", error);
3515
+ return null;
3516
+ }
3517
+ }
3518
+ /**
3519
+ * Initialize WalletConnect wallet instance
3520
+ * @param chainId - Optional chain ID to determine network (default: Mainnet)
3521
+ */
3522
+ initializeWallet(chainId) {
3523
+ if (_WalletConnectTronAdapter.walletInstance && _WalletConnectTronAdapter.walletProjectId === this.projectId) {
3524
+ return;
3525
+ }
3526
+ let appUrl = "";
3527
+ if (typeof window !== "undefined") {
3528
+ try {
3529
+ if (window.location && window.location.origin) {
3530
+ appUrl = window.location.origin;
3531
+ } else if (window.location && window.location.href) {
3532
+ const url = new URL(window.location.href);
3533
+ appUrl = url.origin;
3534
+ }
3535
+ } catch (error) {
3536
+ console.warn("[WalletConnect Tron] Failed to get origin from window.location:", error);
3537
+ }
3538
+ if (appUrl && (appUrl.includes("serveo.net") || appUrl.includes("loca.lt") || appUrl.includes("ngrok.io") || appUrl.includes("ngrok-free.app") || appUrl.includes("cloudflared.io"))) {
3539
+ console.log("[WalletConnect Tron] Detected tunnel service URL:", appUrl);
3540
+ console.log("[WalletConnect Tron] \u26A0\uFE0F Make sure this URL is added to WalletConnect Cloud project allowlist");
3541
+ }
3542
+ if (!appUrl) {
3543
+ const tg = window.Telegram?.WebApp;
3544
+ if (tg && tg.initDataUnsafe?.start_param) {
3545
+ appUrl = "https://enclave.network";
3546
+ } else {
3547
+ appUrl = "https://enclave.network";
3548
+ }
3549
+ }
3550
+ } else {
3551
+ appUrl = "https://enclave.network";
3552
+ }
3553
+ if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
3554
+ appUrl = "https://enclave.network";
3555
+ }
3556
+ const icons = [
3557
+ "https://walletconnect.com/walletconnect-logo.svg",
3558
+ "https://avatars.githubusercontent.com/u/37784886"
3559
+ // WalletConnect GitHub avatar
3560
+ ];
3561
+ let network = walletconnectTron.WalletConnectChainID.Mainnet;
3562
+ if (chainId !== void 0) {
3563
+ if (chainId === 195 || chainId === _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID) {
3564
+ network = walletconnectTron.WalletConnectChainID.Mainnet;
3565
+ } else if (chainId === 201910292) {
3566
+ network = walletconnectTron.WalletConnectChainID.Shasta;
3567
+ } else if (chainId === 2494104990) {
3568
+ network = walletconnectTron.WalletConnectChainID.Nile;
3569
+ }
3570
+ }
3571
+ const metadataInfo = {
3572
+ name: "Enclave Wallet SDK",
3573
+ description: "Multi-chain wallet adapter for Enclave",
3574
+ url: appUrl,
3575
+ icons,
3576
+ network,
3577
+ chainId,
3578
+ isTelegram: this.isTelegramMiniApp(),
3579
+ projectId: this.projectId,
3580
+ urlValid: appUrl && (appUrl.startsWith("http://") || appUrl.startsWith("https://")),
3581
+ iconsValid: icons && icons.length > 0 && icons.every((icon) => icon && icon.startsWith("http")),
3582
+ currentLocation: typeof window !== "undefined" ? window.location.href : "N/A",
3583
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A"
3584
+ };
3585
+ console.log("[WalletConnect Tron] Initializing with metadata:", metadataInfo);
3586
+ if (!metadataInfo.urlValid) {
3587
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid URL in metadata:", appUrl);
3588
+ }
3589
+ if (!metadataInfo.iconsValid) {
3590
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid icons in metadata:", icons);
3591
+ }
3592
+ console.log("[WalletConnect Tron] Initializing wallet...", {
3593
+ network,
3594
+ chainId,
3595
+ note: "If no wallets are in WalletConnect Explorer for TRON, QR code will be displayed for scanning"
3596
+ });
3597
+ _WalletConnectTronAdapter.walletInstance = new walletconnectTron.WalletConnectWallet({
3598
+ network,
3599
+ options: {
3600
+ projectId: this.projectId,
3601
+ metadata: {
3602
+ name: "Enclave Wallet SDK",
3603
+ description: "Multi-chain wallet adapter for Enclave",
3604
+ url: appUrl,
3605
+ icons
3606
+ }
3607
+ },
3608
+ // Theme configuration
3609
+ themeMode: "light",
3610
+ themeVariables: {
3611
+ "--w3m-z-index": 1e4
3612
+ // Ensure modal appears above Telegram UI
3613
+ },
3614
+ // Web3Modal configuration for recommended wallets
3615
+ // According to official docs: https://developers.tron.network/docs/walletconnect-tron
3616
+ // Note: If no wallets are registered in WalletConnect Explorer for TRON,
3617
+ // explorerRecommendedWalletIds will have no effect, and QR code will be shown instead.
3618
+ // @ts-ignore - web3ModalConfig is supported but may not be in TypeScript types
3619
+ web3ModalConfig: {
3620
+ themeMode: "light",
3621
+ themeVariables: {
3622
+ "--w3m-z-index": 1e4
3623
+ },
3624
+ /**
3625
+ * Recommended Wallets are fetched from WalletConnect explore api:
3626
+ * https://walletconnect.com/explorer?type=wallet&version=2
3627
+ *
3628
+ * IMPORTANT: If wallets are not registered in Explorer for TRON, this list will be ignored.
3629
+ * The AppKit will show a QR code instead, which users can scan with any WalletConnect-compatible wallet.
3630
+ *
3631
+ * Wallet IDs (for reference, may not work if not in Explorer):
3632
+ * - TokenPocket: 20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66
3633
+ * - TronLink: 1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369
3634
+ */
3635
+ explorerRecommendedWalletIds: [
3636
+ // These IDs are kept for when wallets register in WalletConnect Explorer
3637
+ // Currently, if no TRON wallets are in Explorer, QR code will be shown
3638
+ "20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66",
3639
+ // TokenPocket
3640
+ "1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
3641
+ // TronLink
3642
+ "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0"
3643
+ // TokenPocket (backup)
3644
+ ]
3645
+ }
3646
+ });
3647
+ _WalletConnectTronAdapter.walletProjectId = this.projectId;
3648
+ }
3649
+ /**
3650
+ * Connect wallet
3651
+ */
3652
+ async connect(chainId) {
3653
+ if (typeof window === "undefined") {
3654
+ throw new Error("WalletConnect requires a browser environment");
3655
+ }
3656
+ const currentState = this.state;
3657
+ if (currentState === "connecting" /* CONNECTING */) {
3658
+ console.warn("[WalletConnect Tron] Connection already in progress, waiting...");
3659
+ let attempts = 0;
3660
+ while (this.state === "connecting" /* CONNECTING */ && attempts < 50) {
3661
+ await new Promise((resolve) => setTimeout(resolve, 100));
3662
+ attempts++;
3663
+ }
3664
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3665
+ return this.currentAccount;
3666
+ }
3667
+ if (this.state === "connecting" /* CONNECTING */) {
3668
+ throw new Error("Connection timeout - previous connection attempt is still pending");
3669
+ }
3670
+ }
3671
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3672
+ return this.currentAccount;
3673
+ }
3674
+ try {
3675
+ this.setState("connecting" /* CONNECTING */);
3676
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3677
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3678
+ this.initializeWallet(targetChainId);
3679
+ }
3680
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
3681
+ if (!this.wallet) {
3682
+ throw new Error("Failed to initialize WalletConnect wallet");
3683
+ }
3684
+ let network = walletconnectTron.WalletConnectChainID.Mainnet;
3685
+ if (targetChainId === 195) {
3686
+ network = walletconnectTron.WalletConnectChainID.Mainnet;
3687
+ } else if (targetChainId === 201910292) {
3688
+ network = walletconnectTron.WalletConnectChainID.Shasta;
3689
+ } else if (targetChainId === 2494104990) {
3690
+ network = walletconnectTron.WalletConnectChainID.Nile;
3691
+ }
3692
+ let address;
3693
+ try {
3694
+ console.log("[WalletConnect Tron] Attempting to connect...", {
3695
+ network,
3696
+ chainId: targetChainId,
3697
+ isTelegram: this.isTelegramMiniApp(),
3698
+ projectId: this.projectId
3699
+ });
3700
+ const result = await this.wallet.connect();
3701
+ address = result.address;
3702
+ if (!address) {
3703
+ throw new ConnectionRejectedError(this.type);
3704
+ }
3705
+ console.log("[WalletConnect Tron] Connection successful:", {
3706
+ address,
3707
+ network,
3708
+ chainId: targetChainId,
3709
+ isTelegram: this.isTelegramMiniApp()
3710
+ });
3711
+ } catch (error) {
3712
+ const errorMessage = error.message || String(error);
3713
+ const errorCode = error.code || error.error?.code;
3714
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
3715
+ let detailedError = errorMessage;
3716
+ if (error.error) {
3717
+ if (typeof error.error === "string") {
3718
+ detailedError = error.error;
3719
+ } else if (error.error.message) {
3720
+ detailedError = error.error.message;
3721
+ } else if (error.error.data) {
3722
+ detailedError = JSON.stringify(error.error.data);
3723
+ }
3724
+ }
3725
+ 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");
3726
+ const isTimeout = errorMessage.includes("timeout") || errorMessage.includes("\u8D85\u65F6") || errorCode === "TIMEOUT";
3727
+ const isRejected = errorMessage.includes("rejected") || errorMessage.includes("\u62D2\u7EDD") || errorCode === 4001;
3728
+ const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
3729
+ const currentMetadata = this.wallet ? {
3730
+ // Try to get metadata from wallet instance if available
3731
+ projectId: this.projectId,
3732
+ network
3733
+ } : null;
3734
+ const errorDetails = {
3735
+ error: errorMessage,
3736
+ detailedError,
3737
+ code: errorCode,
3738
+ isTelegram: this.isTelegramMiniApp(),
3739
+ network,
3740
+ chainId: targetChainId,
3741
+ projectId: this.projectId,
3742
+ metadata: currentMetadata,
3743
+ // Get URL from window.location if available
3744
+ currentUrl: typeof window !== "undefined" ? window.location.href : "N/A",
3745
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A",
3746
+ errorType: isNoWalletFound ? "NO_WALLET_FOUND" : isTimeout ? "TIMEOUT" : isRejected ? "REJECTED" : "UNKNOWN"
3747
+ };
3748
+ console.error("[WalletConnect Tron] Connection error - Full details:", errorDetails);
3749
+ console.error("[WalletConnect Tron] Error object:", error);
3750
+ console.error("[WalletConnect Tron] Error stack:", error.stack);
3751
+ if (isNoWalletFound) {
3752
+ const noWalletErrorDetails = [
3753
+ `
3754
+ === WalletConnect Tron: No Matching Wallet Found ===`,
3755
+ `Error: ${errorMessage}`,
3756
+ `Detailed: ${detailedError}`,
3757
+ `Code: ${errorCode || "N/A"}`,
3758
+ ``,
3759
+ `Environment:`,
3760
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3761
+ ` - Platform: ${errorDetails.telegramPlatform}`,
3762
+ ` - Current URL: ${errorDetails.currentUrl}`,
3763
+ ``,
3764
+ `Configuration:`,
3765
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3766
+ ` - Network: ${network}`,
3767
+ ` - Chain ID: ${targetChainId}`,
3768
+ ` - Metadata URL: ${typeof window !== "undefined" ? window.location.origin : "N/A"}`,
3769
+ ``,
3770
+ `Possible Causes:`,
3771
+ ` 1. No WalletConnect-compatible wallet (TokenPocket, etc.) installed on device`,
3772
+ ` 2. Wallet app not opened or not responding to deep link (wc://)`,
3773
+ ` 3. Deep link handling issue in Telegram Mini App environment`,
3774
+ ` 4. WalletConnect session timeout (user took too long to approve)`,
3775
+ ` 5. Network connectivity issue preventing WalletConnect relay connection`,
3776
+ ``,
3777
+ `Solutions:`,
3778
+ ` 1. Ensure TokenPocket or other WalletConnect-compatible wallet is installed`,
3779
+ ` 2. Try opening the wallet app manually before connecting`,
3780
+ ` 3. In Telegram Mini App, ensure the deep link popup is not blocked`,
3781
+ ` 4. Try connecting again (may need to wait a few seconds)`,
3782
+ ` 5. Check network connection and WalletConnect relay server accessibility`,
3783
+ ``,
3784
+ `For more details, see the error object logged above.`,
3785
+ `===========================================
3786
+ `
3787
+ ].join("\n");
3788
+ console.error(noWalletErrorDetails);
3789
+ throw new ConnectionRejectedError(
3790
+ `WalletConnect Tron: \u6CA1\u6709\u627E\u5230\u652F\u6301\u7684\u94B1\u5305 (No matching wallet found)
3791
+
3792
+ \u53EF\u80FD\u7684\u539F\u56E0\uFF1A
3793
+ 1. \u8BBE\u5907\u4E0A\u672A\u5B89\u88C5\u652F\u6301 WalletConnect \u7684\u94B1\u5305\uFF08\u5982 TokenPocket\uFF09
3794
+ 2. \u94B1\u5305\u5E94\u7528\u672A\u6253\u5F00\u6216\u672A\u54CD\u5E94 deep link (wc://)
3795
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0Cdeep link \u5904\u7406\u53EF\u80FD\u6709\u95EE\u9898
3796
+ 4. \u8FDE\u63A5\u8D85\u65F6\uFF08\u7528\u6237\u672A\u53CA\u65F6\u6279\u51C6\uFF09
3797
+ 5. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898
3798
+
3799
+ \u89E3\u51B3\u65B9\u6848\uFF1A
3800
+ 1. \u786E\u4FDD\u5DF2\u5B89\u88C5 TokenPocket \u6216\u5176\u4ED6\u652F\u6301 WalletConnect \u7684\u94B1\u5305
3801
+ 2. \u5C1D\u8BD5\u624B\u52A8\u6253\u5F00\u94B1\u5305\u5E94\u7528\u540E\u518D\u8FDE\u63A5
3802
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0C\u786E\u4FDD deep link \u5F39\u7A97\u672A\u88AB\u963B\u6B62
3803
+ 4. \u7A0D\u7B49\u51E0\u79D2\u540E\u91CD\u8BD5\u8FDE\u63A5
3804
+ 5. \u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C WalletConnect \u4E2D\u7EE7\u670D\u52A1\u5668\u53EF\u8BBF\u95EE\u6027
3805
+
3806
+ \u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7\u3002`
3807
+ );
3808
+ }
3809
+ if (errorMessage.includes("Invalid") || errorMessage.includes("Configuration") || errorMessage.includes("App Config") || errorMessage.includes("Invalid App")) {
3810
+ const configErrorDetails = [
3811
+ `
3812
+ === WalletConnect Tron Configuration Error ===`,
3813
+ `Error: ${errorMessage}`,
3814
+ `Detailed: ${detailedError}`,
3815
+ `Code: ${errorCode || "N/A"}`,
3816
+ `
3817
+ Environment:`,
3818
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3819
+ ` - Platform: ${errorDetails.telegramPlatform}`,
3820
+ ` - Current URL: ${errorDetails.currentUrl}`,
3821
+ `
3822
+ Configuration:`,
3823
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3824
+ ` - Network: ${network}`,
3825
+ ` - Chain ID: ${targetChainId}`,
3826
+ `
3827
+ Possible Causes:`,
3828
+ ` 1. Deep link (wc://) handling issue in Telegram Mini App`,
3829
+ ` 2. Invalid metadata configuration (URL or icons not accessible)`,
3830
+ ` 3. Network/chainId mismatch`,
3831
+ ` 4. WalletConnect project ID not configured correctly`,
3832
+ ` 5. Domain not added to WalletConnect Cloud allowlist`,
3833
+ `
3834
+ Please check:`,
3835
+ ` - WalletConnect Project ID is valid and active`,
3836
+ ` - Domain is added to WalletConnect Cloud allowlist (for serveo.net, etc.)`,
3837
+ ` - Metadata URL is accessible: Check console for metadata logs`,
3838
+ ` - Icons are accessible: Check console for icon URLs`,
3839
+ ` - Network matches chainId: Expected ${network} for chainId ${targetChainId}`,
3840
+ `
3841
+ For more details, see the error object logged above.`,
3842
+ `===========================================
3843
+ `
3844
+ ].join("\n");
3845
+ console.error(configErrorDetails);
3846
+ throw new ConfigurationError(
3847
+ `WalletConnect Tron connection failed: ${errorMessage}
3848
+
3849
+ Configuration Details:
3850
+ - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}
3851
+ - Platform: ${errorDetails.telegramPlatform}
3852
+ - Origin: ${origin || "(unknown)"}
3853
+ - Project ID: ${this.projectId ? "Set" : "Missing"}
3854
+ - Network: ${network}
3855
+ - Chain ID: ${targetChainId}
3856
+
3857
+ This "Invalid App Configuration" error may be caused by:
3858
+ 1. Deep link (wc://) handling issue in Telegram Mini App
3859
+ 2. Invalid metadata configuration (URL or icons)
3860
+ 3. Network/chainId mismatch
3861
+ 4. Domain not added to WalletConnect Cloud allowlist
3862
+
3863
+ Please check the console for detailed error information.`
3864
+ );
3865
+ }
3866
+ if (isOriginNotAllowed) {
3867
+ throw new ConfigurationError(
3868
+ `WalletConnect Tron relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
3869
+
3870
+ Fix:
3871
+ 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
3872
+ 2) Add this site origin to the allowlist:
3873
+ - ${origin || "(unknown origin)"}
3874
+
3875
+ Common dev origins to allow:
3876
+ - http://localhost:5173
3877
+ - http://192.168.0.221:5173 (your LAN dev URL)
3878
+ - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
3879
+
3880
+ Original error: ${errorMessage}`
3881
+ );
3882
+ }
3883
+ if (isTimeout) {
3884
+ throw new ConnectionRejectedError(
3885
+ `WalletConnect Tron connection timeout. Please try again and ensure your wallet app is open and ready.`
3886
+ );
3887
+ }
3888
+ if (isRejected) {
3889
+ throw new ConnectionRejectedError(this.type);
3890
+ }
3891
+ throw error;
3892
+ }
3893
+ this.currentAddress = address;
3894
+ const account = {
3895
+ universalAddress: createUniversalAddress(targetChainId, address),
3896
+ nativeAddress: address,
3897
+ chainId: targetChainId,
3898
+ chainType: ChainType.TRON,
3899
+ isActive: true
3900
+ };
3901
+ this.setState("connected" /* CONNECTED */);
3902
+ this.setAccount(account);
3903
+ this.setupEventListeners();
3904
+ return account;
3905
+ } catch (error) {
3906
+ this.setState("error" /* ERROR */);
3907
+ this.setAccount(null);
3908
+ this.currentAddress = null;
3909
+ if (error.message?.includes("rejected") || error.code === 4001) {
3910
+ throw new ConnectionRejectedError(this.type);
3911
+ }
3912
+ throw error;
3913
+ }
3914
+ }
3915
+ /**
3916
+ * Disconnect wallet
3917
+ */
3918
+ async disconnect() {
3919
+ this.removeEventListeners();
3920
+ if (this.wallet) {
3921
+ try {
3922
+ await this.wallet.disconnect();
3923
+ } catch (error) {
3924
+ console.warn("[WalletConnect Tron] Error during disconnect:", error);
3925
+ }
3926
+ }
3927
+ this.wallet = null;
3928
+ this.currentAddress = null;
3929
+ this.setState("disconnected" /* DISCONNECTED */);
3930
+ this.setAccount(null);
3931
+ this.emitDisconnected();
3932
+ }
3933
+ /**
3934
+ * Sign message
3935
+ */
3936
+ async signMessage(message) {
3937
+ this.ensureConnected();
3938
+ try {
3939
+ if (!this.wallet) {
3940
+ throw new Error("Wallet not initialized");
3941
+ }
3942
+ const signature = await this.wallet.signMessage(message);
3943
+ if (typeof signature === "string") {
3944
+ return signature;
3945
+ } else if (signature && typeof signature === "object") {
3946
+ if ("signature" in signature) {
3947
+ return signature.signature;
3948
+ } else if ("result" in signature) {
3949
+ return signature.result;
3950
+ } else {
3951
+ return JSON.stringify(signature);
3952
+ }
3953
+ }
3954
+ throw new Error("Invalid signature format returned from wallet");
3955
+ } catch (error) {
3956
+ console.error("[WalletConnect Tron] Sign message error:", error);
3957
+ let errorMessage = "Unknown error";
3958
+ if (typeof error === "string") {
3959
+ errorMessage = error;
3960
+ } else if (error?.message) {
3961
+ errorMessage = error.message;
3962
+ } else if (error?.error?.message) {
3963
+ errorMessage = error.error.message;
3964
+ } else {
3965
+ try {
3966
+ errorMessage = JSON.stringify(error);
3967
+ } catch {
3968
+ errorMessage = String(error);
3969
+ }
3970
+ }
3971
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
3972
+ throw new SignatureRejectedError();
3973
+ }
3974
+ if (errorMessage?.includes("not supported") || errorMessage?.includes("method not found") || errorMessage?.includes("Method not found") || error?.code === -32601 || error?.error?.code === -32601) {
3975
+ 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.");
3976
+ }
3977
+ throw new Error(`WalletConnect Tron sign message failed: ${errorMessage}`);
3978
+ }
3979
+ }
3980
+ /**
3981
+ * Sign transaction
3982
+ *
3983
+ * @param transaction - Tron transaction object
3984
+ * Can be created using TronWeb (if available) or any TRON transaction builder
3985
+ * Format: { raw_data: {...}, raw_data_hex: "...", txID: "..." }
3986
+ * @returns Signed transaction object or signature
3987
+ */
3988
+ async signTransaction(transaction) {
3989
+ this.ensureConnected();
3990
+ try {
3991
+ if (!this.wallet) {
3992
+ throw new Error("Wallet not initialized");
3993
+ }
3994
+ if (!transaction) {
3995
+ throw new Error("Transaction object is required");
3996
+ }
3997
+ console.log("[WalletConnect Tron] Signing transaction:", {
3998
+ hasRawData: !!transaction.raw_data,
3999
+ hasRawDataHex: !!transaction.raw_data_hex,
4000
+ hasTxID: !!transaction.txID
4001
+ });
4002
+ const result = await this.wallet.signTransaction(transaction);
4003
+ if (typeof result === "string") {
4004
+ return result;
4005
+ } else if (result && typeof result === "object") {
4006
+ if ("txID" in result && typeof result.txID === "string") {
4007
+ return result.txID;
4008
+ } else if ("txid" in result && typeof result.txid === "string") {
4009
+ return result.txid;
4010
+ } else if ("signature" in result) {
4011
+ return JSON.stringify(result);
4012
+ } else {
4013
+ return JSON.stringify(result);
4014
+ }
4015
+ }
4016
+ throw new Error("Invalid signature format returned from wallet");
4017
+ } catch (error) {
4018
+ console.error("[WalletConnect Tron] Sign transaction error:", error);
4019
+ let errorMessage = "Unknown error";
4020
+ if (typeof error === "string") {
4021
+ errorMessage = error;
4022
+ } else if (error?.message) {
4023
+ errorMessage = error.message;
4024
+ } else if (error?.error?.message) {
4025
+ errorMessage = error.error.message;
4026
+ } else if (error?.data?.message) {
4027
+ errorMessage = error.data.message;
4028
+ } else {
4029
+ try {
4030
+ errorMessage = JSON.stringify(error);
4031
+ } catch {
4032
+ errorMessage = String(error);
4033
+ }
4034
+ }
4035
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
4036
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
4037
+ }
4038
+ 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) {
4039
+ 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.");
4040
+ }
4041
+ throw new Error(`WalletConnect Tron sign transaction failed: ${errorMessage}`);
4042
+ }
4043
+ }
4044
+ /**
4045
+ * Read contract (not supported by WalletConnect)
4046
+ */
4047
+ async readContract(_params) {
4048
+ this.ensureConnected();
4049
+ 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.");
4050
+ }
4051
+ /**
4052
+ * Write contract (not yet implemented)
4053
+ */
4054
+ async writeContract(_params) {
4055
+ throw new Error("Contract write not yet implemented for WalletConnect Tron");
4056
+ }
4057
+ /**
4058
+ * Estimate gas (not yet implemented)
4059
+ */
4060
+ async estimateGas(_params) {
4061
+ throw new Error("Gas estimation not yet implemented for WalletConnect Tron");
4062
+ }
4063
+ /**
4064
+ * Wait for transaction (not yet implemented)
4065
+ */
4066
+ async waitForTransaction(_txHash, _confirmations) {
4067
+ throw new Error("Transaction waiting not yet implemented for WalletConnect Tron");
4068
+ }
4069
+ /**
4070
+ * Setup event listeners
4071
+ */
4072
+ setupEventListeners() {
4073
+ if (!this.wallet) {
4074
+ return;
4075
+ }
4076
+ this.wallet.on("accountsChanged", (accounts) => {
4077
+ if (accounts && accounts.length > 0 && accounts[0] !== this.currentAddress) {
4078
+ const newAddress = accounts[0];
4079
+ this.currentAddress = newAddress;
4080
+ if (this.currentAccount) {
4081
+ const newAccount = {
4082
+ ...this.currentAccount,
4083
+ nativeAddress: newAddress,
4084
+ universalAddress: createUniversalAddress(this.currentAccount.chainId, newAddress)
4085
+ };
4086
+ this.setAccount(newAccount);
4087
+ this.emit("accountChanged", newAccount);
4088
+ }
4089
+ } else if (!accounts || accounts.length === 0) {
4090
+ this.disconnect();
4091
+ }
4092
+ });
4093
+ this.wallet.on("disconnect", () => {
4094
+ this.disconnect();
4095
+ });
4096
+ }
4097
+ /**
4098
+ * Remove event listeners
4099
+ */
4100
+ removeEventListeners() {
4101
+ if (!this.wallet) {
4102
+ return;
4103
+ }
4104
+ this.wallet.removeAllListeners("accountsChanged");
4105
+ this.wallet.removeAllListeners("disconnect");
4106
+ }
4107
+ /**
4108
+ * Get provider (returns wallet instance)
4109
+ */
4110
+ getProvider() {
4111
+ return this.wallet;
4112
+ }
4113
+ /**
4114
+ * Clear static wallet instance (for complete cleanup)
4115
+ */
4116
+ static clearWalletInstance() {
4117
+ if (_WalletConnectTronAdapter.walletInstance) {
4118
+ _WalletConnectTronAdapter.walletInstance.disconnect().catch(() => {
4119
+ });
4120
+ _WalletConnectTronAdapter.walletInstance = null;
4121
+ _WalletConnectTronAdapter.walletProjectId = null;
4122
+ }
4123
+ }
4124
+ };
4125
+ // Tron 主网链 ID
4126
+ _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID = 195;
4127
+ // Static wallet instance to avoid multiple initializations
4128
+ _WalletConnectTronAdapter.walletInstance = null;
4129
+ _WalletConnectTronAdapter.walletProjectId = null;
4130
+ var WalletConnectTronAdapter = _WalletConnectTronAdapter;
4131
+
4132
+ // src/internal/walletconnect-tron-loader.esm.ts
4133
+ function loadWalletConnectTronModule() {
4134
+ return wallet_connect_exports;
4135
+ }
4136
+
4137
+ // src/adapters/deep-link/adapter.ts
4138
+ init_types();
4139
+ var _DeepLinkAdapter = class _DeepLinkAdapter extends WalletAdapter {
4140
+ constructor(config) {
4141
+ super();
4142
+ this.currentChainId = null;
4143
+ this.currentChainType = null;
4144
+ this.provider = this.createProvider(config);
4145
+ this.name = `${this.provider.name} (Deep Link)`;
4146
+ this.icon = this.provider.icon;
4147
+ if (this.provider.supportedChainTypes.includes(ChainType.EVM)) {
4148
+ this.chainType = ChainType.EVM;
4149
+ this.type = "deep-link-evm" /* DEEP_LINK_EVM */;
4150
+ } else if (this.provider.supportedChainTypes.includes(ChainType.TRON)) {
4151
+ this.chainType = ChainType.TRON;
4152
+ this.type = "deep-link-tron" /* DEEP_LINK_TRON */;
4153
+ } else {
4154
+ this.chainType = ChainType.EVM;
4155
+ this.type = "deep-link-evm" /* DEEP_LINK_EVM */;
4156
+ }
4157
+ if (typeof window !== "undefined") {
4158
+ this.setupCallbackHandler();
4159
+ }
4160
+ }
4161
+ /**
4162
+ * Create provider instance based on type
4163
+ */
4164
+ createProvider(config) {
4165
+ switch (config.providerType) {
4166
+ case "tokenpocket" /* TOKENPOCKET */: {
4167
+ const { TokenPocketDeepLinkProvider: TokenPocketDeepLinkProvider2 } = (init_tokenpocket(), __toCommonJS(tokenpocket_exports));
4168
+ return new TokenPocketDeepLinkProvider2({
4169
+ callbackUrl: config.callbackUrl,
4170
+ callbackSchema: config.callbackSchema
4171
+ });
4172
+ }
4173
+ case "tronlink" /* TRONLINK */: {
4174
+ const { TronLinkDeepLinkProvider: TronLinkDeepLinkProvider2 } = (init_tronlink(), __toCommonJS(tronlink_exports));
4175
+ return new TronLinkDeepLinkProvider2();
4176
+ }
4177
+ case "imtoken" /* IMTOKEN */: {
4178
+ const { ImTokenDeepLinkProvider: ImTokenDeepLinkProvider2 } = (init_imtoken(), __toCommonJS(imtoken_exports));
4179
+ return new ImTokenDeepLinkProvider2({
4180
+ callbackUrl: config.callbackUrl,
4181
+ callbackSchema: config.callbackSchema
4182
+ });
4183
+ }
4184
+ case "metamask" /* METAMASK */: {
4185
+ const { MetaMaskDeepLinkProvider: MetaMaskDeepLinkProvider2 } = (init_metamask(), __toCommonJS(metamask_exports));
4186
+ return new MetaMaskDeepLinkProvider2();
4187
+ }
4188
+ case "okx" /* OKX */: {
4189
+ const { OKXDeepLinkProvider: OKXDeepLinkProvider2 } = (init_okx(), __toCommonJS(okx_exports));
4190
+ return new OKXDeepLinkProvider2();
4191
+ }
4192
+ default:
4193
+ throw new Error(`Unsupported deep link provider type: ${config.providerType}`);
4194
+ }
4195
+ }
4196
+ /**
4197
+ * Setup callback handler for deep link results
4198
+ */
4199
+ setupCallbackHandler() {
4200
+ if (typeof window === "undefined") {
4201
+ return;
4202
+ }
4203
+ const handleUrlChange = () => {
4204
+ const urlParams = new URLSearchParams(window.location.search);
4205
+ const result = this.provider.parseCallbackResult(urlParams);
4206
+ if (result.actionId && _DeepLinkAdapter.pendingActions.has(result.actionId)) {
4207
+ const callback = _DeepLinkAdapter.pendingActions.get(result.actionId);
4208
+ if (result.error) {
4209
+ callback.reject(new Error(result.error));
4210
+ } else if (result.result) {
4211
+ callback.resolve(result.result);
4212
+ }
4213
+ _DeepLinkAdapter.pendingActions.delete(result.actionId);
4214
+ }
4215
+ };
4216
+ window.addEventListener("popstate", handleUrlChange);
4217
+ window.addEventListener("hashchange", handleUrlChange);
4218
+ handleUrlChange();
4219
+ }
4220
+ /**
4221
+ * Check if deep link is available
4222
+ */
4223
+ async isAvailable() {
4224
+ return this.provider.isAvailable();
4225
+ }
4226
+ /**
4227
+ * Connect to wallet via deep link
4228
+ *
4229
+ * Note: Deep links typically don't support persistent connections
4230
+ * This method may throw ConnectionRejectedError as deep links are
4231
+ * primarily used for signing operations, not connection
4232
+ */
4233
+ async connect(chainId) {
4234
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId || 1;
4235
+ let chainType;
4236
+ if (targetChainId === 195) {
4237
+ chainType = ChainType.TRON;
4238
+ } else {
4239
+ chainType = ChainType.EVM;
4240
+ }
4241
+ if (!this.provider.supportedChainTypes.includes(chainType)) {
4242
+ throw new Error(
4243
+ `Provider ${this.provider.name} does not support chain type ${chainType}`
4244
+ );
4245
+ }
4246
+ if (this.provider.buildConnectLink) {
4247
+ const linkInfo = this.provider.buildConnectLink({
4248
+ chainId: targetChainId,
4249
+ chainType
4250
+ });
4251
+ if (linkInfo.actionId) {
4252
+ return new Promise((resolve, reject) => {
4253
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, {
4254
+ resolve: (result) => {
4255
+ const address = result?.address || result?.account || result;
4256
+ if (!address || typeof address !== "string") {
4257
+ reject(new ConnectionRejectedError("Invalid connection result: no address found"));
4258
+ return;
4259
+ }
4260
+ const account = {
4261
+ universalAddress: createUniversalAddress(targetChainId, address),
4262
+ nativeAddress: address,
4263
+ chainId: targetChainId,
4264
+ chainType,
4265
+ isActive: true
4266
+ };
4267
+ this.setState("connected" /* CONNECTED */);
4268
+ this.setAccount(account);
4269
+ this.emit("connected", account);
4270
+ resolve(account);
4271
+ },
4272
+ reject: (error) => {
4273
+ this.setState("disconnected" /* DISCONNECTED */);
4274
+ reject(error);
4275
+ }
4276
+ });
4277
+ window.location.href = linkInfo.url;
4278
+ setTimeout(() => {
4279
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4280
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4281
+ this.setState("disconnected" /* DISCONNECTED */);
4282
+ reject(new ConnectionRejectedError("Deep link connection timeout"));
4283
+ }
4284
+ }, 3e4);
4285
+ });
4286
+ } else {
4287
+ window.location.href = linkInfo.url;
4288
+ throw new ConnectionRejectedError(
4289
+ "Deep link connection initiated. Please complete the connection in your wallet app."
4290
+ );
4291
+ }
4292
+ } else {
4293
+ throw new ConnectionRejectedError(
4294
+ `Deep link connection is not supported by ${this.provider.name}. Deep links are primarily used for signing operations.`
4295
+ );
4296
+ }
4297
+ }
4298
+ /**
4299
+ * Disconnect from wallet
4300
+ */
4301
+ async disconnect() {
4302
+ this.setState("disconnected" /* DISCONNECTED */);
4303
+ this.setAccount(null);
4304
+ this.currentChainId = null;
4305
+ this.currentChainType = null;
4306
+ this.emitDisconnected();
4307
+ }
4308
+ /**
4309
+ * Sign a message
4310
+ */
4311
+ async signMessage(message) {
4312
+ this.ensureConnected();
4313
+ if (!this.currentChainId || !this.currentChainType) {
4314
+ throw new WalletNotConnectedError(this.type);
4315
+ }
4316
+ const linkInfo = this.provider.buildSignMessageLink({
4317
+ message,
4318
+ chainId: this.currentChainId,
4319
+ chainType: this.currentChainType
4320
+ });
4321
+ if (linkInfo.callbackSchema || linkInfo.callbackUrl) {
4322
+ return new Promise((resolve, reject) => {
4323
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, { resolve, reject });
4324
+ window.location.href = linkInfo.url;
4325
+ setTimeout(() => {
4326
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4327
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4328
+ reject(new SignatureRejectedError("Message signature timeout"));
4329
+ }
4330
+ }, 3e4);
4331
+ });
4332
+ } else {
4333
+ window.location.href = linkInfo.url;
4334
+ throw new SignatureRejectedError(
4335
+ "Deep link signature initiated. Please complete the signature in your wallet app."
4336
+ );
4337
+ }
4338
+ }
4339
+ /**
4340
+ * Sign a transaction
4341
+ */
4342
+ async signTransaction(transaction) {
4343
+ this.ensureConnected();
4344
+ if (!this.currentChainId || !this.currentChainType) {
4345
+ throw new WalletNotConnectedError(this.type);
4346
+ }
4347
+ const linkInfo = this.provider.buildSignTransactionLink({
4348
+ transaction,
4349
+ chainId: this.currentChainId,
4350
+ chainType: this.currentChainType
4351
+ });
4352
+ if (linkInfo.callbackSchema || linkInfo.callbackUrl) {
4353
+ return new Promise((resolve, reject) => {
4354
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, { resolve, reject });
4355
+ window.location.href = linkInfo.url;
4356
+ setTimeout(() => {
4357
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4358
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4359
+ reject(new SignatureRejectedError("Transaction signature timeout"));
4360
+ }
4361
+ }, 3e4);
4362
+ });
4363
+ } else {
4364
+ window.location.href = linkInfo.url;
4365
+ throw new SignatureRejectedError(
4366
+ "Deep link transaction signature initiated. Please complete the signature in your wallet app."
4367
+ );
4368
+ }
4369
+ }
4370
+ /**
4371
+ * Get provider (not applicable for deep links)
4372
+ */
4373
+ getProvider() {
4374
+ return null;
4375
+ }
4376
+ /**
4377
+ * Static method to handle callback from wallet apps
4378
+ * This can be called from anywhere in the application
4379
+ */
4380
+ static handleCallback() {
4381
+ if (typeof window === "undefined") {
4382
+ return;
4383
+ }
4384
+ const urlParams = new URLSearchParams(window.location.search);
4385
+ const actionId = urlParams.get("actionId");
4386
+ if (actionId && _DeepLinkAdapter.pendingActions.has(actionId)) {
4387
+ const callback = _DeepLinkAdapter.pendingActions.get(actionId);
4388
+ const result = urlParams.get("result");
4389
+ const error = urlParams.get("error");
4390
+ if (error) {
4391
+ callback.reject(new Error(error));
4392
+ } else if (result) {
4393
+ try {
4394
+ const parsedResult = JSON.parse(decodeURIComponent(result));
4395
+ callback.resolve(parsedResult);
4396
+ } catch (e) {
4397
+ callback.resolve(result);
4398
+ }
4399
+ }
4400
+ _DeepLinkAdapter.pendingActions.delete(actionId);
4401
+ }
4402
+ }
4403
+ /**
4404
+ * Set current account (called after successful connection)
4405
+ */
4406
+ setAccount(account) {
4407
+ this.currentAccount = account;
4408
+ if (account) {
4409
+ this.currentChainId = account.chainId;
4410
+ this.currentChainType = account.chainType;
4411
+ }
4412
+ }
4413
+ /**
4414
+ * Emit disconnected event
4415
+ */
4416
+ emitDisconnected() {
4417
+ this.emit("disconnected");
4418
+ }
4419
+ };
4420
+ // Static map to store pending actions across all instances
4421
+ // Key: actionId, Value: { resolve, reject }
4422
+ _DeepLinkAdapter.pendingActions = /* @__PURE__ */ new Map();
4423
+ var DeepLinkAdapter = _DeepLinkAdapter;
4424
+
4425
+ // src/core/adapter-registry.ts
4426
+ var AdapterRegistry = class {
4427
+ constructor(config = {}) {
4428
+ this.adapters = /* @__PURE__ */ new Map();
4429
+ this.config = config;
4430
+ this.registerDefaultAdapters();
4431
+ }
4432
+ /**
4433
+ * Register default adapters
4434
+ */
4435
+ registerDefaultAdapters() {
4436
+ this.register("metamask" /* METAMASK */, () => new MetaMaskAdapter());
4437
+ this.register("private-key" /* PRIVATE_KEY */, () => new EVMPrivateKeyAdapter());
4438
+ if (this.config.walletConnectProjectId) {
4439
+ this.register(
4440
+ "walletconnect" /* WALLETCONNECT */,
4441
+ () => new WalletConnectAdapter(this.config.walletConnectProjectId)
4442
+ );
4443
+ this.register("walletconnect-tron" /* WALLETCONNECT_TRON */, () => {
4444
+ const { WalletConnectTronAdapter: WalletConnectTronAdapter2 } = loadWalletConnectTronModule();
4445
+ return new WalletConnectTronAdapter2(this.config.walletConnectProjectId);
4446
+ });
4447
+ }
4448
+ this.register("tronlink" /* TRONLINK */, () => new TronLinkAdapter());
4449
+ this.register(
4450
+ "deep-link-evm" /* DEEP_LINK_EVM */,
4451
+ () => new DeepLinkAdapter({
4452
+ providerType: "tokenpocket" /* TOKENPOCKET */
4453
+ })
4454
+ );
4455
+ this.register(
4456
+ "deep-link-tron" /* DEEP_LINK_TRON */,
4457
+ () => new DeepLinkAdapter({
4458
+ providerType: "tokenpocket" /* TOKENPOCKET */
4459
+ })
4460
+ );
4461
+ }
4462
+ /**
4463
+ * Register adapter
4464
+ */
4465
+ register(type, factory) {
4466
+ this.adapters.set(type, factory);
4467
+ }
4468
+ /**
4469
+ * Get adapter
4470
+ */
4471
+ getAdapter(type) {
4472
+ const factory = this.adapters.get(type);
4473
+ if (!factory) {
4474
+ return null;
4475
+ }
4476
+ return factory();
4477
+ }
4478
+ /**
1579
4479
  * Check if adapter is registered
1580
4480
  */
1581
4481
  has(type) {
@@ -1602,6 +4502,190 @@ var AdapterRegistry = class {
1602
4502
  }
1603
4503
  };
1604
4504
 
4505
+ // src/core/wallet-manager.ts
4506
+ init_types();
4507
+ var QRCodeSigner = class {
4508
+ constructor(config) {
4509
+ this.pollTimer = null;
4510
+ this.timeoutTimer = null;
4511
+ this.status = "waiting" /* WAITING */;
4512
+ this.qrCodeDataUrl = null;
4513
+ this.result = null;
4514
+ this.config = {
4515
+ requestId: config.requestId,
4516
+ requestUrl: config.requestUrl,
4517
+ pollUrl: config.pollUrl || "",
4518
+ pollInterval: config.pollInterval || 2e3,
4519
+ timeout: config.timeout || 3e5,
4520
+ // 5 minutes
4521
+ pollFn: config.pollFn
4522
+ };
4523
+ }
4524
+ /**
4525
+ * 生成二维码图片(Data URL)
4526
+ */
4527
+ async generateQRCode(options) {
4528
+ if (this.qrCodeDataUrl) {
4529
+ return this.qrCodeDataUrl;
4530
+ }
4531
+ try {
4532
+ const qrCodeOptions = {
4533
+ width: options?.width || 300,
4534
+ margin: options?.margin || 2,
4535
+ color: {
4536
+ dark: options?.color?.dark || "#000000",
4537
+ light: options?.color?.light || "#FFFFFF"
4538
+ }
4539
+ };
4540
+ this.qrCodeDataUrl = await QRCode__default.default.toDataURL(this.config.requestUrl, qrCodeOptions);
4541
+ return this.qrCodeDataUrl;
4542
+ } catch (error) {
4543
+ throw new Error(`Failed to generate QR code: ${error instanceof Error ? error.message : String(error)}`);
4544
+ }
4545
+ }
4546
+ /**
4547
+ * 开始轮询签名结果
4548
+ */
4549
+ async startPolling(onStatusChange, onResult) {
4550
+ if (this.status === "success" /* SUCCESS */ && this.result?.signature) {
4551
+ return this.result.signature;
4552
+ }
4553
+ if (this.status === "cancelled" /* CANCELLED */ || this.status === "timeout" /* TIMEOUT */) {
4554
+ throw new SignatureRejectedError("Signature request was cancelled or timed out");
4555
+ }
4556
+ this.timeoutTimer = setTimeout(() => {
4557
+ this.stopPolling();
4558
+ this.status = "timeout" /* TIMEOUT */;
4559
+ onStatusChange?.(this.status);
4560
+ throw new SignatureRejectedError("Signature request timed out");
4561
+ }, this.config.timeout);
4562
+ return new Promise((resolve, reject) => {
4563
+ const poll = async () => {
4564
+ try {
4565
+ let result = null;
4566
+ if (this.config.pollFn) {
4567
+ result = await this.config.pollFn(this.config.requestId);
4568
+ } else if (this.config.pollUrl) {
4569
+ result = await this.defaultPoll(this.config.requestId);
4570
+ } else {
4571
+ return;
4572
+ }
4573
+ if (result?.completed) {
4574
+ this.stopPolling();
4575
+ this.result = result;
4576
+ if (result.signature) {
4577
+ this.status = "success" /* SUCCESS */;
4578
+ onStatusChange?.(this.status);
4579
+ onResult?.(result);
4580
+ resolve(result.signature);
4581
+ } else if (result.error) {
4582
+ this.status = "failed" /* FAILED */;
4583
+ onStatusChange?.(this.status);
4584
+ reject(new SignatureRejectedError(result.error));
4585
+ }
4586
+ } else if (result) {
4587
+ if (this.status === "waiting" /* WAITING */) {
4588
+ this.status = "pending" /* PENDING */;
4589
+ onStatusChange?.(this.status);
4590
+ }
4591
+ this.pollTimer = setTimeout(poll, this.config.pollInterval);
4592
+ } else {
4593
+ this.pollTimer = setTimeout(poll, this.config.pollInterval);
4594
+ }
4595
+ } catch (error) {
4596
+ this.stopPolling();
4597
+ this.status = "failed" /* FAILED */;
4598
+ onStatusChange?.(this.status);
4599
+ reject(error);
4600
+ }
4601
+ };
4602
+ poll();
4603
+ });
4604
+ }
4605
+ /**
4606
+ * 默认 HTTP 轮询函数
4607
+ */
4608
+ async defaultPoll(requestId) {
4609
+ if (!this.config.pollUrl) {
4610
+ return null;
4611
+ }
4612
+ try {
4613
+ const url = `${this.config.pollUrl}?requestId=${encodeURIComponent(requestId)}`;
4614
+ const response = await fetch(url, {
4615
+ method: "GET",
4616
+ headers: {
4617
+ "Content-Type": "application/json"
4618
+ }
4619
+ });
4620
+ if (!response.ok) {
4621
+ if (response.status === 404) {
4622
+ return null;
4623
+ }
4624
+ throw new NetworkError(`Poll request failed: ${response.statusText}`);
4625
+ }
4626
+ const data = await response.json();
4627
+ return {
4628
+ completed: data.completed === true,
4629
+ signature: data.signature,
4630
+ error: data.error,
4631
+ signer: data.signer
4632
+ };
4633
+ } catch (error) {
4634
+ if (error instanceof NetworkError) {
4635
+ throw error;
4636
+ }
4637
+ return null;
4638
+ }
4639
+ }
4640
+ /**
4641
+ * 停止轮询
4642
+ */
4643
+ stopPolling() {
4644
+ if (this.pollTimer) {
4645
+ clearTimeout(this.pollTimer);
4646
+ this.pollTimer = null;
4647
+ }
4648
+ if (this.timeoutTimer) {
4649
+ clearTimeout(this.timeoutTimer);
4650
+ this.timeoutTimer = null;
4651
+ }
4652
+ }
4653
+ /**
4654
+ * 取消签名请求
4655
+ */
4656
+ cancel() {
4657
+ this.stopPolling();
4658
+ this.status = "cancelled" /* CANCELLED */;
4659
+ }
4660
+ /**
4661
+ * 获取当前状态
4662
+ */
4663
+ getStatus() {
4664
+ return this.status;
4665
+ }
4666
+ /**
4667
+ * 获取二维码 URL
4668
+ */
4669
+ getQRCodeUrl() {
4670
+ return this.config.requestUrl;
4671
+ }
4672
+ /**
4673
+ * 获取结果
4674
+ */
4675
+ getResult() {
4676
+ return this.result;
4677
+ }
4678
+ /**
4679
+ * 清理资源
4680
+ */
4681
+ cleanup() {
4682
+ this.stopPolling();
4683
+ this.qrCodeDataUrl = null;
4684
+ this.result = null;
4685
+ this.status = "waiting" /* WAITING */;
4686
+ }
4687
+ };
4688
+
1605
4689
  // src/core/wallet-manager.ts
1606
4690
  var WalletManager = class extends TypedEventEmitter {
1607
4691
  constructor(config = {}) {
@@ -1617,9 +4701,15 @@ var WalletManager = class extends TypedEventEmitter {
1617
4701
  defaultTronChainId: config.defaultTronChainId ?? 195,
1618
4702
  walletConnectProjectId: config.walletConnectProjectId ?? ""
1619
4703
  };
1620
- this.registry = new AdapterRegistry();
4704
+ this.registry = new AdapterRegistry(this.config);
1621
4705
  }
1622
4706
  // ===== Connection Management =====
4707
+ /**
4708
+ * Check if adapter is registered for a wallet type
4709
+ */
4710
+ hasAdapter(type) {
4711
+ return this.registry.has(type);
4712
+ }
1623
4713
  /**
1624
4714
  * Connect primary wallet
1625
4715
  */
@@ -1686,7 +4776,7 @@ var WalletManager = class extends TypedEventEmitter {
1686
4776
  this.connectedWallets.delete(chainType);
1687
4777
  this.primaryWallet = null;
1688
4778
  if (this.config.enableStorage) {
1689
- this.saveToStorage();
4779
+ this.clearStorage();
1690
4780
  }
1691
4781
  this.emit("disconnected");
1692
4782
  }
@@ -1775,6 +4865,35 @@ var WalletManager = class extends TypedEventEmitter {
1775
4865
  }
1776
4866
  return adapter.signMessage(message);
1777
4867
  }
4868
+ /**
4869
+ * Create QR code signer for message signing
4870
+ *
4871
+ * This method creates a QR code signer that can be used to display a QR code
4872
+ * for users to scan with their wallet app to sign a message.
4873
+ *
4874
+ * @param message - Message to sign
4875
+ * @param config - QR code signer configuration
4876
+ * @returns QRCodeSigner instance
4877
+ *
4878
+ * @example
4879
+ * ```typescript
4880
+ * const signer = walletManager.createQRCodeSigner('Hello World', {
4881
+ * requestId: 'sign-123',
4882
+ * requestUrl: 'https://example.com/sign?requestId=sign-123&message=Hello%20World',
4883
+ * pollUrl: 'https://api.example.com/sign/status',
4884
+ * })
4885
+ *
4886
+ * const qrCodeUrl = await signer.generateQRCode()
4887
+ * const signature = await signer.startPolling()
4888
+ * ```
4889
+ */
4890
+ createQRCodeSigner(message, config) {
4891
+ return new QRCodeSigner({
4892
+ ...config,
4893
+ // Encode message in request URL if not already encoded
4894
+ requestUrl: config.requestUrl.includes(encodeURIComponent(message)) ? config.requestUrl : `${config.requestUrl}${config.requestUrl.includes("?") ? "&" : "?"}message=${encodeURIComponent(message)}`
4895
+ });
4896
+ }
1778
4897
  /**
1779
4898
  * Sign TypedData (EVM only)
1780
4899
  */
@@ -1839,6 +4958,41 @@ var WalletManager = class extends TypedEventEmitter {
1839
4958
  throw error;
1840
4959
  }
1841
4960
  }
4961
+ /**
4962
+ * Request account switch (opens wallet account selector)
4963
+ * @param targetAddress Optional target address to verify after switching
4964
+ * @returns The new account after switching
4965
+ */
4966
+ async requestSwitchAccount(targetAddress) {
4967
+ if (!this.primaryWallet) {
4968
+ throw new WalletNotConnectedError();
4969
+ }
4970
+ if (!this.primaryWallet.requestSwitchAccount) {
4971
+ throw new Error(`Account switching not supported by ${this.primaryWallet.type}`);
4972
+ }
4973
+ const account = await this.primaryWallet.requestSwitchAccount(targetAddress);
4974
+ if (this.config.enableStorage) {
4975
+ this.saveToStorage();
4976
+ }
4977
+ return account;
4978
+ }
4979
+ /**
4980
+ * Ensure the current account matches the target address
4981
+ * If not matching, request account switch
4982
+ * @param targetAddress The address that should be active
4983
+ * @returns The account (either existing or after switch)
4984
+ */
4985
+ async ensureAccount(targetAddress) {
4986
+ const currentAccount = this.getPrimaryAccount();
4987
+ if (!currentAccount) {
4988
+ throw new WalletNotConnectedError();
4989
+ }
4990
+ if (currentAccount.nativeAddress.toLowerCase() === targetAddress.toLowerCase()) {
4991
+ return currentAccount;
4992
+ }
4993
+ console.log(`[WalletManager] Current account ${currentAccount.nativeAddress} doesn't match target ${targetAddress}, requesting switch...`);
4994
+ return this.requestSwitchAccount(targetAddress);
4995
+ }
1842
4996
  // ===== Contract Calls =====
1843
4997
  /**
1844
4998
  * Read contract
@@ -2085,6 +5239,29 @@ var WalletManager = class extends TypedEventEmitter {
2085
5239
  console.debug("Silent TronLink connection failed:", silentError);
2086
5240
  }
2087
5241
  }
5242
+ if (data.primaryWalletType === "walletconnect-tron" /* WALLETCONNECT_TRON */) {
5243
+ try {
5244
+ const wcAdapter = adapter;
5245
+ if (typeof wcAdapter.restoreSession === "function") {
5246
+ console.debug("[WalletManager] Attempting to restore WalletConnect Tron session...");
5247
+ const account2 = await wcAdapter.restoreSession(data.primaryChainId);
5248
+ if (account2) {
5249
+ console.debug("[WalletManager] WalletConnect Tron session restored successfully");
5250
+ this.setPrimaryWallet(adapter);
5251
+ this.connectedWallets.set(adapter.chainType, adapter);
5252
+ this.setupAdapterListeners(adapter, true);
5253
+ this.emit("accountChanged", account2);
5254
+ return account2;
5255
+ } else {
5256
+ console.debug("[WalletManager] No valid WalletConnect Tron session found");
5257
+ return null;
5258
+ }
5259
+ }
5260
+ } catch (restoreError) {
5261
+ console.debug("[WalletManager] WalletConnect Tron restore failed:", restoreError);
5262
+ return null;
5263
+ }
5264
+ }
2088
5265
  const account = await adapter.connect(data.primaryChainId);
2089
5266
  this.setPrimaryWallet(adapter);
2090
5267
  this.connectedWallets.set(adapter.chainType, adapter);
@@ -2132,44 +5309,44 @@ var WalletManager = class extends TypedEventEmitter {
2132
5309
  };
2133
5310
 
2134
5311
  // src/react/WalletContext.tsx
2135
- var WalletContext = React.createContext(null);
5312
+ var WalletContext = React2.createContext(null);
2136
5313
  function WalletProvider({ children, walletManager: externalWalletManager }) {
2137
- const [walletManager] = React.useState(() => externalWalletManager || new WalletManager());
2138
- const [account, setAccount] = React.useState(null);
2139
- const [connectedWallets, setConnectedWallets] = React.useState([]);
2140
- const [isRestoring, setIsRestoring] = React.useState(true);
2141
- const updateConnectedWallets = React.useCallback(() => {
5314
+ const [walletManager] = React2.useState(() => externalWalletManager || new WalletManager());
5315
+ const [account, setAccount] = React2.useState(null);
5316
+ const [connectedWallets, setConnectedWallets] = React2.useState([]);
5317
+ const [isRestoring, setIsRestoring] = React2.useState(true);
5318
+ const updateConnectedWallets = React2.useCallback(() => {
2142
5319
  setConnectedWallets(walletManager.getConnectedWallets());
2143
5320
  }, [walletManager]);
2144
- const connect = React.useCallback(async (type, chainId) => {
5321
+ const connect = React2.useCallback(async (type, chainId) => {
2145
5322
  const account2 = await walletManager.connect(type, chainId);
2146
5323
  setAccount(account2);
2147
5324
  updateConnectedWallets();
2148
5325
  return account2;
2149
5326
  }, [walletManager, updateConnectedWallets]);
2150
- const connectAdditional = React.useCallback(async (type, chainId) => {
5327
+ const connectAdditional = React2.useCallback(async (type, chainId) => {
2151
5328
  const account2 = await walletManager.connectAdditional(type, chainId);
2152
5329
  updateConnectedWallets();
2153
5330
  return account2;
2154
5331
  }, [walletManager, updateConnectedWallets]);
2155
- const disconnect = React.useCallback(async () => {
5332
+ const disconnect = React2.useCallback(async () => {
2156
5333
  await walletManager.disconnect();
2157
5334
  setAccount(null);
2158
5335
  updateConnectedWallets();
2159
5336
  }, [walletManager, updateConnectedWallets]);
2160
- const switchPrimaryWallet = React.useCallback(async (chainType) => {
5337
+ const switchPrimaryWallet = React2.useCallback(async (chainType) => {
2161
5338
  const account2 = await walletManager.switchPrimaryWallet(chainType);
2162
5339
  setAccount(account2);
2163
5340
  updateConnectedWallets();
2164
5341
  return account2;
2165
5342
  }, [walletManager, updateConnectedWallets]);
2166
- const signMessage = React.useCallback(async (message) => {
5343
+ const signMessage = React2.useCallback(async (message) => {
2167
5344
  return walletManager.signMessage(message);
2168
5345
  }, [walletManager]);
2169
- const signTransaction = React.useCallback(async (transaction) => {
5346
+ const signTransaction = React2.useCallback(async (transaction) => {
2170
5347
  return walletManager.signTransaction(transaction);
2171
5348
  }, [walletManager]);
2172
- React.useEffect(() => {
5349
+ React2.useEffect(() => {
2173
5350
  const restoreConnection = async () => {
2174
5351
  try {
2175
5352
  const restoredAccount = await walletManager.restoreFromStorage();
@@ -2185,7 +5362,7 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
2185
5362
  };
2186
5363
  restoreConnection();
2187
5364
  }, [walletManager, updateConnectedWallets]);
2188
- React.useEffect(() => {
5365
+ React2.useEffect(() => {
2189
5366
  const handleAccountChanged = (newAccount) => {
2190
5367
  setAccount(newAccount);
2191
5368
  updateConnectedWallets();
@@ -2233,10 +5410,10 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
2233
5410
  signMessage,
2234
5411
  signTransaction
2235
5412
  };
2236
- return /* @__PURE__ */ React__default.default.createElement(WalletContext.Provider, { value }, children);
5413
+ return /* @__PURE__ */ React2__default.default.createElement(WalletContext.Provider, { value }, children);
2237
5414
  }
2238
5415
  function useWallet() {
2239
- const context = React.useContext(WalletContext);
5416
+ const context = React2.useContext(WalletContext);
2240
5417
  if (!context) {
2241
5418
  throw new Error("useWallet must be used within a WalletProvider");
2242
5419
  }
@@ -2256,8 +5433,8 @@ function useAccount() {
2256
5433
  }
2257
5434
  function useConnect() {
2258
5435
  const { connect: contextConnect, connectAdditional: contextConnectAdditional } = useWallet();
2259
- const [isConnecting, setIsConnecting] = React.useState(false);
2260
- const [error, setError] = React.useState(null);
5436
+ const [isConnecting, setIsConnecting] = React2.useState(false);
5437
+ const [error, setError] = React2.useState(null);
2261
5438
  const connect = async (type, chainId) => {
2262
5439
  setIsConnecting(true);
2263
5440
  setError(null);
@@ -2295,8 +5472,8 @@ function useConnect() {
2295
5472
  }
2296
5473
  function useDisconnect() {
2297
5474
  const { disconnect: contextDisconnect } = useWallet();
2298
- const [isDisconnecting, setIsDisconnecting] = React.useState(false);
2299
- const [error, setError] = React.useState(null);
5475
+ const [isDisconnecting, setIsDisconnecting] = React2.useState(false);
5476
+ const [error, setError] = React2.useState(null);
2300
5477
  const disconnect = async () => {
2301
5478
  setIsDisconnecting(true);
2302
5479
  setError(null);
@@ -2318,8 +5495,8 @@ function useDisconnect() {
2318
5495
  }
2319
5496
  function useSignMessage() {
2320
5497
  const { signMessage: contextSignMessage } = useWallet();
2321
- const [isSigning, setIsSigning] = React.useState(false);
2322
- const [error, setError] = React.useState(null);
5498
+ const [isSigning, setIsSigning] = React2.useState(false);
5499
+ const [error, setError] = React2.useState(null);
2323
5500
  const signMessage = async (message) => {
2324
5501
  setIsSigning(true);
2325
5502
  setError(null);
@@ -2342,8 +5519,8 @@ function useSignMessage() {
2342
5519
  }
2343
5520
  function useSignTransaction() {
2344
5521
  const { signTransaction: contextSignTransaction } = useWallet();
2345
- const [isSigning, setIsSigning] = React.useState(false);
2346
- const [error, setError] = React.useState(null);
5522
+ const [isSigning, setIsSigning] = React2.useState(false);
5523
+ const [error, setError] = React2.useState(null);
2347
5524
  const signTransaction = async (transaction) => {
2348
5525
  setIsSigning(true);
2349
5526
  setError(null);
@@ -2364,11 +5541,381 @@ function useSignTransaction() {
2364
5541
  error
2365
5542
  };
2366
5543
  }
5544
+ function useQRCodeSigner(config) {
5545
+ const [qrCodeDataUrl, setQrCodeDataUrl] = React2.useState(null);
5546
+ const [status, setStatus] = React2.useState("waiting" /* WAITING */);
5547
+ const [result, setResult] = React2.useState(null);
5548
+ const [isPolling, setIsPolling] = React2.useState(false);
5549
+ const [error, setError] = React2.useState(null);
5550
+ const signerRef = React2.useRef(null);
5551
+ React2.useEffect(() => {
5552
+ signerRef.current = new QRCodeSigner(config);
5553
+ return () => {
5554
+ signerRef.current?.cleanup();
5555
+ };
5556
+ }, [config.requestId, config.requestUrl, config.pollUrl]);
5557
+ const generateQRCode = React2.useCallback(async () => {
5558
+ if (!signerRef.current) return;
5559
+ try {
5560
+ const dataUrl = await signerRef.current.generateQRCode();
5561
+ setQrCodeDataUrl(dataUrl);
5562
+ } catch (err) {
5563
+ const error2 = err instanceof Error ? err : new Error(String(err));
5564
+ setError(error2);
5565
+ }
5566
+ }, []);
5567
+ const startSign = React2.useCallback(async () => {
5568
+ if (!signerRef.current) {
5569
+ throw new Error("QRCodeSigner not initialized");
5570
+ }
5571
+ setError(null);
5572
+ setStatus("waiting" /* WAITING */);
5573
+ setIsPolling(true);
5574
+ try {
5575
+ await generateQRCode();
5576
+ const signature = await signerRef.current.startPolling(
5577
+ (newStatus) => {
5578
+ setStatus(newStatus);
5579
+ },
5580
+ (signResult) => {
5581
+ setResult(signResult);
5582
+ }
5583
+ );
5584
+ setIsPolling(false);
5585
+ return signature;
5586
+ } catch (err) {
5587
+ setIsPolling(false);
5588
+ const error2 = err instanceof Error ? err : new SignatureRejectedError(err instanceof Error ? err.message : String(err));
5589
+ setError(error2);
5590
+ throw error2;
5591
+ }
5592
+ }, [generateQRCode]);
5593
+ const stopPolling = React2.useCallback(() => {
5594
+ signerRef.current?.stopPolling();
5595
+ setIsPolling(false);
5596
+ }, []);
5597
+ const cancel = React2.useCallback(() => {
5598
+ signerRef.current?.cancel();
5599
+ setStatus("cancelled" /* CANCELLED */);
5600
+ setIsPolling(false);
5601
+ }, []);
5602
+ return {
5603
+ qrCodeDataUrl,
5604
+ status,
5605
+ result,
5606
+ isPolling,
5607
+ startSign,
5608
+ stopPolling,
5609
+ cancel,
5610
+ error
5611
+ };
5612
+ }
5613
+ function QRCodeModal({
5614
+ isOpen,
5615
+ onClose,
5616
+ qrCodeDataUrl,
5617
+ status,
5618
+ error,
5619
+ title = "\u626B\u7801\u7B7E\u540D",
5620
+ description
5621
+ }) {
5622
+ React2.useEffect(() => {
5623
+ if (isOpen) {
5624
+ document.body.style.overflow = "hidden";
5625
+ } else {
5626
+ document.body.style.overflow = "";
5627
+ }
5628
+ return () => {
5629
+ document.body.style.overflow = "";
5630
+ };
5631
+ }, [isOpen]);
5632
+ if (!isOpen) {
5633
+ return null;
5634
+ }
5635
+ const getStatusText = () => {
5636
+ switch (status) {
5637
+ case "waiting" /* WAITING */:
5638
+ return "\u8BF7\u4F7F\u7528\u94B1\u5305\u626B\u63CF\u4E8C\u7EF4\u7801";
5639
+ case "pending" /* PENDING */:
5640
+ return "\u5DF2\u626B\u63CF\uFF0C\u8BF7\u5728\u94B1\u5305\u4E2D\u786E\u8BA4\u7B7E\u540D";
5641
+ case "success" /* SUCCESS */:
5642
+ return "\u7B7E\u540D\u6210\u529F";
5643
+ case "failed" /* FAILED */:
5644
+ return "\u7B7E\u540D\u5931\u8D25";
5645
+ case "timeout" /* TIMEOUT */:
5646
+ return "\u7B7E\u540D\u8D85\u65F6";
5647
+ case "cancelled" /* CANCELLED */:
5648
+ return "\u5DF2\u53D6\u6D88";
5649
+ default:
5650
+ return "\u7B49\u5F85\u626B\u63CF";
5651
+ }
5652
+ };
5653
+ const getStatusColor = () => {
5654
+ switch (status) {
5655
+ case "waiting" /* WAITING */:
5656
+ case "pending" /* PENDING */:
5657
+ return "#3b82f6";
5658
+ // blue
5659
+ case "success" /* SUCCESS */:
5660
+ return "#10b981";
5661
+ // green
5662
+ case "failed" /* FAILED */:
5663
+ case "timeout" /* TIMEOUT */:
5664
+ case "cancelled" /* CANCELLED */:
5665
+ return "#ef4444";
5666
+ // red
5667
+ default:
5668
+ return "#6b7280";
5669
+ }
5670
+ };
5671
+ return /* @__PURE__ */ React2__default.default.createElement(
5672
+ "div",
5673
+ {
5674
+ style: {
5675
+ position: "fixed",
5676
+ top: 0,
5677
+ left: 0,
5678
+ right: 0,
5679
+ bottom: 0,
5680
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
5681
+ display: "flex",
5682
+ alignItems: "center",
5683
+ justifyContent: "center",
5684
+ zIndex: 1e4,
5685
+ padding: "20px"
5686
+ },
5687
+ onClick: (e) => {
5688
+ if (e.target === e.currentTarget) {
5689
+ onClose();
5690
+ }
5691
+ }
5692
+ },
5693
+ /* @__PURE__ */ React2__default.default.createElement(
5694
+ "div",
5695
+ {
5696
+ style: {
5697
+ backgroundColor: "#ffffff",
5698
+ borderRadius: "12px",
5699
+ padding: "24px",
5700
+ maxWidth: "400px",
5701
+ width: "100%",
5702
+ boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"
5703
+ }
5704
+ },
5705
+ /* @__PURE__ */ React2__default.default.createElement(
5706
+ "div",
5707
+ {
5708
+ style: {
5709
+ display: "flex",
5710
+ justifyContent: "space-between",
5711
+ alignItems: "center",
5712
+ marginBottom: "20px"
5713
+ }
5714
+ },
5715
+ /* @__PURE__ */ React2__default.default.createElement(
5716
+ "h2",
5717
+ {
5718
+ style: {
5719
+ margin: 0,
5720
+ fontSize: "20px",
5721
+ fontWeight: 600,
5722
+ color: "#111827"
5723
+ }
5724
+ },
5725
+ title
5726
+ ),
5727
+ /* @__PURE__ */ React2__default.default.createElement(
5728
+ "button",
5729
+ {
5730
+ onClick: onClose,
5731
+ style: {
5732
+ background: "none",
5733
+ border: "none",
5734
+ fontSize: "24px",
5735
+ cursor: "pointer",
5736
+ color: "#6b7280",
5737
+ padding: 0,
5738
+ width: "24px",
5739
+ height: "24px",
5740
+ display: "flex",
5741
+ alignItems: "center",
5742
+ justifyContent: "center"
5743
+ }
5744
+ },
5745
+ "\xD7"
5746
+ )
5747
+ ),
5748
+ description && /* @__PURE__ */ React2__default.default.createElement(
5749
+ "p",
5750
+ {
5751
+ style: {
5752
+ margin: "0 0 20px 0",
5753
+ fontSize: "14px",
5754
+ color: "#6b7280"
5755
+ }
5756
+ },
5757
+ description
5758
+ ),
5759
+ /* @__PURE__ */ React2__default.default.createElement(
5760
+ "div",
5761
+ {
5762
+ style: {
5763
+ display: "flex",
5764
+ justifyContent: "center",
5765
+ marginBottom: "20px"
5766
+ }
5767
+ },
5768
+ qrCodeDataUrl ? /* @__PURE__ */ React2__default.default.createElement(
5769
+ "img",
5770
+ {
5771
+ src: qrCodeDataUrl,
5772
+ alt: "QR Code",
5773
+ style: {
5774
+ width: "100%",
5775
+ maxWidth: "300px",
5776
+ height: "auto",
5777
+ border: "1px solid #e5e7eb",
5778
+ borderRadius: "8px"
5779
+ }
5780
+ }
5781
+ ) : /* @__PURE__ */ React2__default.default.createElement(
5782
+ "div",
5783
+ {
5784
+ style: {
5785
+ width: "300px",
5786
+ height: "300px",
5787
+ backgroundColor: "#f3f4f6",
5788
+ display: "flex",
5789
+ alignItems: "center",
5790
+ justifyContent: "center",
5791
+ borderRadius: "8px",
5792
+ color: "#6b7280"
5793
+ }
5794
+ },
5795
+ "\u751F\u6210\u4E8C\u7EF4\u7801\u4E2D..."
5796
+ )
5797
+ ),
5798
+ /* @__PURE__ */ React2__default.default.createElement(
5799
+ "div",
5800
+ {
5801
+ style: {
5802
+ textAlign: "center",
5803
+ marginBottom: "20px"
5804
+ }
5805
+ },
5806
+ /* @__PURE__ */ React2__default.default.createElement(
5807
+ "div",
5808
+ {
5809
+ style: {
5810
+ display: "inline-flex",
5811
+ alignItems: "center",
5812
+ gap: "8px",
5813
+ padding: "8px 16px",
5814
+ borderRadius: "6px",
5815
+ backgroundColor: `${getStatusColor()}15`,
5816
+ color: getStatusColor(),
5817
+ fontSize: "14px",
5818
+ fontWeight: 500
5819
+ }
5820
+ },
5821
+ status === "waiting" /* WAITING */ && /* @__PURE__ */ React2__default.default.createElement(
5822
+ "div",
5823
+ {
5824
+ style: {
5825
+ width: "8px",
5826
+ height: "8px",
5827
+ borderRadius: "50%",
5828
+ backgroundColor: getStatusColor(),
5829
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
5830
+ }
5831
+ }
5832
+ ),
5833
+ status === "pending" /* PENDING */ && /* @__PURE__ */ React2__default.default.createElement(
5834
+ "div",
5835
+ {
5836
+ style: {
5837
+ width: "8px",
5838
+ height: "8px",
5839
+ borderRadius: "50%",
5840
+ backgroundColor: getStatusColor()
5841
+ }
5842
+ }
5843
+ ),
5844
+ status === "success" /* SUCCESS */ && "\u2713",
5845
+ status === "failed" /* FAILED */ && "\u2715",
5846
+ getStatusText()
5847
+ )
5848
+ ),
5849
+ error && /* @__PURE__ */ React2__default.default.createElement(
5850
+ "div",
5851
+ {
5852
+ style: {
5853
+ padding: "12px",
5854
+ backgroundColor: "#fef2f2",
5855
+ border: "1px solid #fecaca",
5856
+ borderRadius: "6px",
5857
+ marginBottom: "20px"
5858
+ }
5859
+ },
5860
+ /* @__PURE__ */ React2__default.default.createElement(
5861
+ "p",
5862
+ {
5863
+ style: {
5864
+ margin: 0,
5865
+ fontSize: "14px",
5866
+ color: "#dc2626"
5867
+ }
5868
+ },
5869
+ error.message
5870
+ )
5871
+ ),
5872
+ /* @__PURE__ */ React2__default.default.createElement(
5873
+ "div",
5874
+ {
5875
+ style: {
5876
+ display: "flex",
5877
+ gap: "12px"
5878
+ }
5879
+ },
5880
+ /* @__PURE__ */ React2__default.default.createElement(
5881
+ "button",
5882
+ {
5883
+ onClick: onClose,
5884
+ style: {
5885
+ flex: 1,
5886
+ padding: "10px 20px",
5887
+ border: "1px solid #d1d5db",
5888
+ borderRadius: "6px",
5889
+ backgroundColor: "#ffffff",
5890
+ color: "#374151",
5891
+ fontSize: "14px",
5892
+ fontWeight: 500,
5893
+ cursor: "pointer"
5894
+ }
5895
+ },
5896
+ status === "success" /* SUCCESS */ ? "\u5173\u95ED" : "\u53D6\u6D88"
5897
+ )
5898
+ )
5899
+ ),
5900
+ /* @__PURE__ */ React2__default.default.createElement("style", null, `
5901
+ @keyframes pulse {
5902
+ 0%, 100% {
5903
+ opacity: 1;
5904
+ }
5905
+ 50% {
5906
+ opacity: 0.5;
5907
+ }
5908
+ }
5909
+ `)
5910
+ );
5911
+ }
2367
5912
 
5913
+ exports.QRCodeModal = QRCodeModal;
2368
5914
  exports.WalletProvider = WalletProvider;
2369
5915
  exports.useAccount = useAccount;
2370
5916
  exports.useConnect = useConnect;
2371
5917
  exports.useDisconnect = useDisconnect;
5918
+ exports.useQRCodeSigner = useQRCodeSigner;
2372
5919
  exports.useSignMessage = useSignMessage;
2373
5920
  exports.useSignTransaction = useSignTransaction;
2374
5921
  exports.useWallet = useWallet;