@enclave-hq/wallet-sdk 1.2.3 → 1.2.4

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}`;
@@ -466,6 +1066,7 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
466
1066
  */
467
1067
  async connect(chainId) {
468
1068
  await this.ensureAvailable();
1069
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId;
469
1070
  try {
470
1071
  this.setState("connecting" /* CONNECTING */);
471
1072
  const provider = this.getBrowserProvider();
@@ -479,10 +1080,10 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
479
1080
  method: "eth_chainId"
480
1081
  });
481
1082
  const parsedChainId = parseInt(currentChainId, 16);
482
- if (chainId && chainId !== parsedChainId) {
483
- await this.switchChain(chainId);
1083
+ if (targetChainId && targetChainId !== parsedChainId) {
1084
+ await this.switchChain(targetChainId);
484
1085
  }
485
- const finalChainId = chainId || parsedChainId;
1086
+ const finalChainId = targetChainId || parsedChainId;
486
1087
  const viemChain = this.getViemChain(finalChainId);
487
1088
  this.walletClient = viem.createWalletClient({
488
1089
  account: accounts[0],
@@ -868,6 +1469,7 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
868
1469
  };
869
1470
 
870
1471
  // src/adapters/tron/tronlink.ts
1472
+ init_types();
871
1473
  var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
872
1474
  constructor() {
873
1475
  super(...arguments);
@@ -915,6 +1517,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
915
1517
  */
916
1518
  async connect(chainId) {
917
1519
  await this.ensureAvailable();
1520
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId;
918
1521
  try {
919
1522
  this.setState("connecting" /* CONNECTING */);
920
1523
  const w = window;
@@ -969,7 +1572,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
969
1572
  if (!address) {
970
1573
  throw new Error("Failed to get Tron address. Please make sure your wallet is unlocked and try again.");
971
1574
  }
972
- const tronChainId = chainId || _TronLinkAdapter.TRON_MAINNET_CHAIN_ID;
1575
+ const tronChainId = targetChainId || _TronLinkAdapter.TRON_MAINNET_CHAIN_ID;
973
1576
  const account = {
974
1577
  universalAddress: createUniversalAddress(tronChainId, address),
975
1578
  nativeAddress: address,
@@ -1299,6 +1902,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1299
1902
  // Tron 主网链 ID
1300
1903
  _TronLinkAdapter.TRON_MAINNET_CHAIN_ID = 195;
1301
1904
  var TronLinkAdapter = _TronLinkAdapter;
1905
+ init_types();
1302
1906
  var EVMPrivateKeyAdapter = class extends WalletAdapter {
1303
1907
  constructor() {
1304
1908
  super(...arguments);
@@ -1312,27 +1916,28 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1312
1916
  /**
1313
1917
  * 连接(导入私钥)
1314
1918
  */
1315
- async connect(chainId = 1) {
1919
+ async connect(chainId) {
1316
1920
  if (!this.privateKey) {
1317
1921
  throw new Error("Private key not set. Call setPrivateKey() first.");
1318
1922
  }
1319
1923
  try {
1320
1924
  this.setState("connecting" /* CONNECTING */);
1321
1925
  const account = accounts.privateKeyToAccount(this.privateKey);
1926
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId || 1;
1322
1927
  this.walletClient = viem.createWalletClient({
1323
1928
  account,
1324
- chain: this.getViemChain(chainId),
1929
+ chain: this.getViemChain(targetChainId),
1325
1930
  transport: viem.http()
1326
1931
  });
1327
1932
  this.publicClient = viem.createPublicClient({
1328
- chain: this.getViemChain(chainId),
1933
+ chain: this.getViemChain(targetChainId),
1329
1934
  transport: viem.http()
1330
1935
  });
1331
1936
  const address = formatEVMAddress(account.address);
1332
1937
  const accountInfo = {
1333
- universalAddress: createUniversalAddress(chainId, address),
1938
+ universalAddress: createUniversalAddress(targetChainId, address),
1334
1939
  nativeAddress: address,
1335
- chainId,
1940
+ chainId: targetChainId,
1336
1941
  chainType: ChainType.EVM,
1337
1942
  isActive: true
1338
1943
  };
@@ -1544,61 +2149,2290 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1544
2149
  };
1545
2150
  }
1546
2151
  };
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());
2152
+ init_types();
2153
+ var _WalletConnectAdapter = class _WalletConnectAdapter extends WalletAdapter {
2154
+ constructor(projectId) {
2155
+ super();
2156
+ this.type = "walletconnect" /* WALLETCONNECT */;
2157
+ this.chainType = ChainType.EVM;
2158
+ this.name = "WalletConnect";
2159
+ this.icon = "https://avatars.githubusercontent.com/u/37784886";
2160
+ this.provider = null;
2161
+ this.walletClient = null;
2162
+ this.publicClient = null;
2163
+ this.supportedChains = [];
2164
+ /**
2165
+ * Handle accounts changed
2166
+ */
2167
+ this.handleAccountsChanged = (accounts) => {
2168
+ if (accounts.length === 0) {
2169
+ this.setState("disconnected" /* DISCONNECTED */);
2170
+ this.setAccount(null);
2171
+ this.emitAccountChanged(null);
2172
+ } else {
2173
+ const address = formatEVMAddress(accounts[0]);
2174
+ const account = {
2175
+ universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
2176
+ nativeAddress: address,
2177
+ chainId: this.currentAccount.chainId,
2178
+ chainType: ChainType.EVM,
2179
+ isActive: true
2180
+ };
2181
+ this.setAccount(account);
2182
+ this.emitAccountChanged(account);
2183
+ }
2184
+ };
2185
+ /**
2186
+ * Handle chain changed
2187
+ */
2188
+ this.handleChainChanged = (chainIdHex) => {
2189
+ const chainId = parseInt(chainIdHex, 16);
2190
+ if (this.currentAccount) {
2191
+ const account = {
2192
+ ...this.currentAccount,
2193
+ chainId,
2194
+ universalAddress: createUniversalAddress(chainId, this.currentAccount.nativeAddress)
2195
+ };
2196
+ this.setAccount(account);
2197
+ this.emitChainChanged(chainId);
2198
+ const viemChain = this.getViemChain(chainId);
2199
+ const chainInfo = getChainInfo(chainId);
2200
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2201
+ if (this.provider) {
2202
+ this.walletClient = viem.createWalletClient({
2203
+ account: this.currentAccount.nativeAddress,
2204
+ chain: viemChain,
2205
+ transport: viem.custom(this.provider)
2206
+ });
2207
+ this.publicClient = viem.createPublicClient({
2208
+ chain: viemChain,
2209
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(this.provider)
2210
+ });
2211
+ }
2212
+ }
2213
+ };
2214
+ /**
2215
+ * Handle disconnect
2216
+ */
2217
+ this.handleDisconnect = () => {
2218
+ this.setState("disconnected" /* DISCONNECTED */);
2219
+ this.setAccount(null);
2220
+ if (_WalletConnectAdapter.providerInstance === this.provider) {
2221
+ _WalletConnectAdapter.providerInstance = null;
2222
+ _WalletConnectAdapter.providerProjectId = null;
2223
+ }
2224
+ this.provider = null;
2225
+ this.walletClient = null;
2226
+ this.publicClient = null;
2227
+ this.emitDisconnected();
2228
+ };
2229
+ if (!projectId) {
2230
+ throw new ConfigurationError("WalletConnect projectId is required");
2231
+ }
2232
+ this.projectId = projectId;
1561
2233
  }
1562
2234
  /**
1563
- * Register adapter
2235
+ * Check if WalletConnect is available
2236
+ * WalletConnect is always available (it's a web-based connection)
2237
+ * Also works in Telegram Mini Apps
1564
2238
  */
1565
- register(type, factory) {
1566
- this.adapters.set(type, factory);
2239
+ async isAvailable() {
2240
+ return typeof window !== "undefined";
1567
2241
  }
1568
2242
  /**
1569
- * Get adapter
2243
+ * Check if running in Telegram environment (Mini App or Web)
2244
+ * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
2245
+ * provide window.Telegram.WebApp API, so they are treated the same way.
2246
+ *
2247
+ * Reference: https://docs.reown.com/appkit/integrations/telegram-mini-apps
1570
2248
  */
1571
- getAdapter(type) {
1572
- const factory = this.adapters.get(type);
1573
- if (!factory) {
1574
- return null;
1575
- }
1576
- return factory();
2249
+ isTelegramMiniApp() {
2250
+ if (typeof window === "undefined") return false;
2251
+ const tg = window.Telegram?.WebApp;
2252
+ if (!tg) return false;
2253
+ const platform = tg.platform || "unknown";
2254
+ console.log("[WalletConnect] Telegram environment detected:", {
2255
+ platform,
2256
+ version: tg.version,
2257
+ isMiniApp: platform !== "web",
2258
+ // Mini App if not web platform
2259
+ isWeb: platform === "web"
2260
+ // Telegram Web if web platform
2261
+ });
2262
+ return true;
1577
2263
  }
1578
2264
  /**
1579
- * Check if adapter is registered
2265
+ * Get Telegram WebApp instance if available
1580
2266
  */
1581
- has(type) {
1582
- return this.adapters.has(type);
2267
+ getTelegramWebApp() {
2268
+ if (typeof window === "undefined") return null;
2269
+ return window.Telegram?.WebApp || null;
1583
2270
  }
1584
2271
  /**
1585
- * Get all registered adapter types
2272
+ * Close Telegram deep link popup (wc:// links)
2273
+ * In Telegram Mini Apps, WalletConnect may open a wc:// deep link popup
2274
+ * that doesn't automatically close after the operation completes.
2275
+ * This method attempts to close it by:
2276
+ * 1. Trying to close any open windows/popups
2277
+ * 2. Using Telegram WebApp API if available
2278
+ * 3. Navigating back or closing the popup
1586
2279
  */
1587
- getRegisteredTypes() {
1588
- return Array.from(this.adapters.keys());
2280
+ closeTelegramDeepLinkPopup() {
2281
+ if (!this.isTelegramMiniApp()) {
2282
+ return;
2283
+ }
2284
+ try {
2285
+ const tg = this.getTelegramWebApp();
2286
+ if (!tg) {
2287
+ return;
2288
+ }
2289
+ if (typeof window !== "undefined") {
2290
+ window.focus();
2291
+ if (tg.BackButton && tg.BackButton.isVisible) {
2292
+ console.log("[WalletConnect] Closing Telegram deep link popup via BackButton");
2293
+ }
2294
+ setTimeout(() => {
2295
+ if (document.hasFocus()) {
2296
+ console.log("[WalletConnect] Main window has focus, popup likely closed");
2297
+ } else {
2298
+ window.focus();
2299
+ console.log("[WalletConnect] Attempted to focus main window to close popup");
2300
+ }
2301
+ }, 500);
2302
+ const handleVisibilityChange = () => {
2303
+ if (document.visibilityState === "visible") {
2304
+ console.log("[WalletConnect] Page became visible, popup may have closed");
2305
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
2306
+ }
2307
+ };
2308
+ document.addEventListener("visibilitychange", handleVisibilityChange);
2309
+ setTimeout(() => {
2310
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
2311
+ }, 2e3);
2312
+ }
2313
+ } catch (error) {
2314
+ console.warn("[WalletConnect] Error closing Telegram deep link popup:", error);
2315
+ }
1589
2316
  }
1590
2317
  /**
1591
- * 根据链类型获取适配器类型列表
2318
+ * Connect wallet
2319
+ *
2320
+ * @param chainId - Single chain ID or array of chain IDs to request
2321
+ * If array is provided, wallet will be requested to connect to multiple chains
2322
+ * When multiple chains are requested, the wallet can switch between them
2323
+ * Default: 1 (Ethereum Mainnet)
2324
+ *
2325
+ * @example
2326
+ * // Single chain
2327
+ * await adapter.connect(1) // Ethereum only
2328
+ *
2329
+ * @example
2330
+ * // Multiple chains
2331
+ * await adapter.connect([1, 56, 137]) // Ethereum, BSC, Polygon
1592
2332
  */
1593
- getAdapterTypesByChainType(chainType) {
1594
- const types = [];
1595
- for (const type of this.adapters.keys()) {
1596
- const adapter = this.getAdapter(type);
1597
- if (adapter && adapter.chainType === chainType) {
1598
- types.push(type);
1599
- }
2333
+ async connect(chainId) {
2334
+ if (typeof window === "undefined") {
2335
+ throw new Error("WalletConnect requires a browser environment");
1600
2336
  }
1601
- return types;
2337
+ if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2338
+ const existingProvider = _WalletConnectAdapter.providerInstance;
2339
+ if (existingProvider.accounts && existingProvider.accounts.length > 0) {
2340
+ this.provider = existingProvider;
2341
+ let targetChains;
2342
+ if (Array.isArray(chainId)) {
2343
+ targetChains = chainId.length > 0 ? chainId : [1];
2344
+ } else if (chainId) {
2345
+ targetChains = [chainId];
2346
+ } else {
2347
+ targetChains = [1];
2348
+ }
2349
+ const existingChains = this.supportedChains || [];
2350
+ const mergedChains = [.../* @__PURE__ */ new Set([...existingChains, ...targetChains])];
2351
+ this.supportedChains = mergedChains;
2352
+ const currentChainId = existingProvider.chainId || targetChains[0];
2353
+ const address = formatEVMAddress(existingProvider.accounts[0]);
2354
+ const account = {
2355
+ universalAddress: createUniversalAddress(currentChainId, address),
2356
+ nativeAddress: address,
2357
+ chainId: currentChainId,
2358
+ chainType: ChainType.EVM,
2359
+ isActive: true
2360
+ };
2361
+ this.setState("connected" /* CONNECTED */);
2362
+ this.setAccount(account);
2363
+ if (!this.walletClient) {
2364
+ const viemChain = this.getViemChain(currentChainId);
2365
+ this.walletClient = viem.createWalletClient({
2366
+ account: existingProvider.accounts[0],
2367
+ chain: viemChain,
2368
+ transport: viem.custom(existingProvider)
2369
+ });
2370
+ const chainInfo = getChainInfo(currentChainId);
2371
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2372
+ this.publicClient = viem.createPublicClient({
2373
+ chain: viemChain,
2374
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(existingProvider)
2375
+ });
2376
+ this.setupEventListeners();
2377
+ }
2378
+ console.log("[WalletConnect] Reusing existing provider session");
2379
+ return account;
2380
+ }
2381
+ }
2382
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount && this.provider) {
2383
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2384
+ let targetChains;
2385
+ if (Array.isArray(chainId)) {
2386
+ targetChains = chainId.length > 0 ? chainId : [1];
2387
+ } else if (chainId) {
2388
+ targetChains = [chainId];
2389
+ } else {
2390
+ targetChains = [1];
2391
+ }
2392
+ const existingChains = this.supportedChains || [];
2393
+ const mergedChains = [.../* @__PURE__ */ new Set([...existingChains, ...targetChains])];
2394
+ this.supportedChains = mergedChains;
2395
+ console.log("[WalletConnect] Already connected, reusing existing connection");
2396
+ return this.currentAccount;
2397
+ } else {
2398
+ this.setState("disconnected" /* DISCONNECTED */);
2399
+ this.setAccount(null);
2400
+ this.provider = null;
2401
+ }
2402
+ }
2403
+ try {
2404
+ this.setState("connecting" /* CONNECTING */);
2405
+ let targetChains;
2406
+ if (Array.isArray(chainId)) {
2407
+ targetChains = chainId.length > 0 ? chainId : [1];
2408
+ } else if (chainId) {
2409
+ targetChains = [chainId];
2410
+ } else {
2411
+ targetChains = [1];
2412
+ }
2413
+ this.supportedChains = targetChains;
2414
+ const primaryChain = targetChains[0];
2415
+ const optionalChains = targetChains.slice(1);
2416
+ const isTelegram = this.isTelegramMiniApp();
2417
+ const telegramWebApp = this.getTelegramWebApp();
2418
+ let appUrl = "";
2419
+ if (typeof window !== "undefined") {
2420
+ try {
2421
+ if (window.location && window.location.origin) {
2422
+ appUrl = window.location.origin;
2423
+ } else if (window.location && window.location.href) {
2424
+ const url = new URL(window.location.href);
2425
+ appUrl = url.origin;
2426
+ }
2427
+ } catch (error) {
2428
+ console.warn("[WalletConnect] Failed to get origin from window.location:", error);
2429
+ }
2430
+ if (!appUrl) {
2431
+ appUrl = "https://enclave.network";
2432
+ }
2433
+ } else {
2434
+ appUrl = "https://enclave.network";
2435
+ }
2436
+ if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
2437
+ appUrl = "https://enclave.network";
2438
+ }
2439
+ const icons = [
2440
+ "https://walletconnect.com/walletconnect-logo.svg",
2441
+ "https://avatars.githubusercontent.com/u/37784886"
2442
+ // WalletConnect GitHub avatar
2443
+ ];
2444
+ const initOptions = {
2445
+ projectId: this.projectId,
2446
+ chains: [primaryChain],
2447
+ // Primary chain (required)
2448
+ showQrModal: true,
2449
+ // QR modal works in Telegram Mini Apps
2450
+ metadata: {
2451
+ name: "Enclave Wallet SDK",
2452
+ description: "Multi-chain wallet adapter for Enclave",
2453
+ url: appUrl,
2454
+ icons
2455
+ }
2456
+ };
2457
+ if (isTelegram && telegramWebApp) {
2458
+ const platform = telegramWebApp.platform || "unknown";
2459
+ const isMiniApp = platform !== "web";
2460
+ console.log("[WalletConnect] Detected Telegram environment:", {
2461
+ platform,
2462
+ isMiniApp,
2463
+ isWeb: platform === "web"
2464
+ });
2465
+ if (telegramWebApp.isExpanded === false) {
2466
+ telegramWebApp.expand();
2467
+ }
2468
+ }
2469
+ if (optionalChains.length > 0) {
2470
+ initOptions.optionalChains = optionalChains;
2471
+ } else {
2472
+ initOptions.optionalChains = [primaryChain];
2473
+ }
2474
+ const hasExistingProvider = _WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId;
2475
+ const needsReinit = hasExistingProvider && _WalletConnectAdapter.providerChains !== null && JSON.stringify(_WalletConnectAdapter.providerChains.sort()) !== JSON.stringify(targetChains.sort());
2476
+ if (needsReinit) {
2477
+ console.log("[WalletConnect] Provider initialized with different chains, reinitializing...", {
2478
+ existing: _WalletConnectAdapter.providerChains,
2479
+ requested: targetChains
2480
+ });
2481
+ const existingProvider = _WalletConnectAdapter.providerInstance;
2482
+ if (existingProvider) {
2483
+ try {
2484
+ if (existingProvider.accounts && existingProvider.accounts.length > 0) {
2485
+ await existingProvider.disconnect();
2486
+ }
2487
+ } catch (error) {
2488
+ console.warn("[WalletConnect] Error disconnecting existing provider:", error);
2489
+ }
2490
+ }
2491
+ _WalletConnectAdapter.providerInstance = null;
2492
+ _WalletConnectAdapter.providerChains = null;
2493
+ }
2494
+ if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2495
+ this.provider = _WalletConnectAdapter.providerInstance;
2496
+ console.log("[WalletConnect] Reusing existing provider instance");
2497
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2498
+ console.log("[WalletConnect] Provider already has accounts, skipping enable()");
2499
+ } else {
2500
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2501
+ console.log("[WalletConnect] Provider has no accounts, calling enable() to show QR modal");
2502
+ console.log("[WalletConnect] Provider state:", {
2503
+ accounts: this.provider.accounts,
2504
+ chainId: this.provider.chainId,
2505
+ hasSession,
2506
+ sessionTopic: this.provider.session?.topic
2507
+ });
2508
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2509
+ console.log("[WalletConnect] Found stale session, disconnecting before reconnecting...");
2510
+ try {
2511
+ await this.provider.disconnect();
2512
+ await new Promise((resolve) => setTimeout(resolve, 100));
2513
+ } catch (disconnectError) {
2514
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2515
+ }
2516
+ }
2517
+ try {
2518
+ console.log("[WalletConnect] Calling enable()...");
2519
+ const enableResult = await this.provider.enable();
2520
+ console.log("[WalletConnect] enable() completed, result:", enableResult);
2521
+ console.log("[WalletConnect] Provider state after enable():", {
2522
+ accounts: this.provider.accounts,
2523
+ chainId: this.provider.chainId,
2524
+ session: this.provider.session ? {
2525
+ topic: this.provider.session.topic,
2526
+ namespaces: this.provider.session.namespaces ? Object.keys(this.provider.session.namespaces) : "none"
2527
+ } : "none"
2528
+ });
2529
+ } catch (error) {
2530
+ console.error("[WalletConnect] enable() error:", error);
2531
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2532
+ throw new ConnectionRejectedError(this.type);
2533
+ }
2534
+ throw error;
2535
+ }
2536
+ }
2537
+ } else if (_WalletConnectAdapter.providerInstance && _WalletConnectAdapter.providerProjectId === this.projectId) {
2538
+ this.provider = _WalletConnectAdapter.providerInstance;
2539
+ console.log("[WalletConnect] Reusing existing provider instance (not connected)");
2540
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2541
+ console.log("[WalletConnect] Provider already has accounts after init, skipping enable()");
2542
+ } else {
2543
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2544
+ console.log("[WalletConnect] Provider has no accounts, calling enable() to show QR modal");
2545
+ console.log("[WalletConnect] Provider state:", {
2546
+ accounts: this.provider.accounts,
2547
+ chainId: this.provider.chainId,
2548
+ hasSession,
2549
+ sessionTopic: this.provider.session?.topic
2550
+ });
2551
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2552
+ console.log("[WalletConnect] Found stale session after init, disconnecting before reconnecting...");
2553
+ try {
2554
+ await this.provider.disconnect();
2555
+ await new Promise((resolve) => setTimeout(resolve, 100));
2556
+ } catch (disconnectError) {
2557
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2558
+ }
2559
+ }
2560
+ try {
2561
+ await this.provider.enable();
2562
+ } catch (error) {
2563
+ console.error("[WalletConnect] enable() error:", error);
2564
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2565
+ throw new ConnectionRejectedError(this.type);
2566
+ }
2567
+ throw error;
2568
+ }
2569
+ }
2570
+ } else if (_WalletConnectAdapter.isInitializing && _WalletConnectAdapter.initPromise) {
2571
+ console.log("[WalletConnect] Waiting for ongoing initialization...");
2572
+ this.provider = await _WalletConnectAdapter.initPromise;
2573
+ _WalletConnectAdapter.providerInstance = this.provider;
2574
+ _WalletConnectAdapter.providerProjectId = this.projectId;
2575
+ _WalletConnectAdapter.providerChains = targetChains;
2576
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2577
+ console.log("[WalletConnect] Provider already has accounts after init, skipping enable()");
2578
+ } else {
2579
+ try {
2580
+ await this.provider.enable();
2581
+ } catch (error) {
2582
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2583
+ throw new ConnectionRejectedError(this.type);
2584
+ }
2585
+ throw error;
2586
+ }
2587
+ }
2588
+ } else {
2589
+ console.log("[WalletConnect] Initializing new provider with chains:", {
2590
+ primary: primaryChain,
2591
+ optional: optionalChains,
2592
+ all: targetChains
2593
+ });
2594
+ _WalletConnectAdapter.isInitializing = true;
2595
+ _WalletConnectAdapter.initPromise = EthereumProvider__default.default.init(initOptions);
2596
+ try {
2597
+ this.provider = await _WalletConnectAdapter.initPromise;
2598
+ _WalletConnectAdapter.providerInstance = this.provider;
2599
+ _WalletConnectAdapter.providerProjectId = this.projectId;
2600
+ _WalletConnectAdapter.providerChains = targetChains;
2601
+ if (this.provider.accounts && this.provider.accounts.length > 0) {
2602
+ console.log("[WalletConnect] Provider has restored session, skipping enable()");
2603
+ } else {
2604
+ const hasSession = this.provider.session !== void 0 && this.provider.session !== null;
2605
+ console.log("[WalletConnect] New provider initialized, calling enable() to show QR modal");
2606
+ console.log("[WalletConnect] Provider state:", {
2607
+ accounts: this.provider.accounts,
2608
+ chainId: this.provider.chainId,
2609
+ hasSession,
2610
+ sessionTopic: this.provider.session?.topic
2611
+ });
2612
+ if (hasSession && (!this.provider.accounts || this.provider.accounts.length === 0)) {
2613
+ console.log("[WalletConnect] Found stale session after init, disconnecting before reconnecting...");
2614
+ try {
2615
+ await this.provider.disconnect();
2616
+ await new Promise((resolve) => setTimeout(resolve, 100));
2617
+ } catch (disconnectError) {
2618
+ console.warn("[WalletConnect] Error disconnecting stale session:", disconnectError);
2619
+ }
2620
+ }
2621
+ try {
2622
+ await this.provider.enable();
2623
+ } catch (error) {
2624
+ console.error("[WalletConnect] enable() error:", error);
2625
+ if (error.code === 4001 || error.message?.includes("rejected") || error.message?.includes("User rejected")) {
2626
+ throw new ConnectionRejectedError(this.type);
2627
+ }
2628
+ throw error;
2629
+ }
2630
+ }
2631
+ } finally {
2632
+ _WalletConnectAdapter.isInitializing = false;
2633
+ _WalletConnectAdapter.initPromise = null;
2634
+ }
2635
+ }
2636
+ let accounts = this.provider.accounts;
2637
+ if (!accounts || accounts.length === 0) {
2638
+ console.log("[WalletConnect] provider.accounts is empty, checking session.namespaces.eip155.accounts...");
2639
+ const session = this.provider.session;
2640
+ if (session && session.namespaces?.eip155?.accounts) {
2641
+ const sessionAccounts = session.namespaces.eip155.accounts.map((acc) => {
2642
+ const parts = acc.split(":");
2643
+ if (parts.length >= 3 && parts[0] === "eip155") {
2644
+ return parts[2];
2645
+ }
2646
+ return null;
2647
+ }).filter((addr) => addr !== null && addr.startsWith("0x"));
2648
+ if (sessionAccounts.length > 0) {
2649
+ const uniqueAccounts = [...new Set(sessionAccounts)];
2650
+ console.log("[WalletConnect] Found accounts in session.namespaces.eip155.accounts:", {
2651
+ raw: session.namespaces.eip155.accounts,
2652
+ extracted: uniqueAccounts,
2653
+ chains: session.namespaces.eip155.chains
2654
+ });
2655
+ accounts = uniqueAccounts;
2656
+ }
2657
+ }
2658
+ }
2659
+ if (!accounts || accounts.length === 0) {
2660
+ console.log("[WalletConnect] Accounts not available, waiting for provider.accounts to populate...");
2661
+ const maxWaitTime = 3e3;
2662
+ const checkInterval = 100;
2663
+ const maxChecks = maxWaitTime / checkInterval;
2664
+ for (let i = 0; i < maxChecks; i++) {
2665
+ await new Promise((resolve) => setTimeout(resolve, checkInterval));
2666
+ accounts = this.provider.accounts;
2667
+ if (accounts && accounts.length > 0) {
2668
+ console.log(`[WalletConnect] Accounts available after ${(i + 1) * checkInterval}ms`);
2669
+ break;
2670
+ }
2671
+ }
2672
+ }
2673
+ if (!accounts || accounts.length === 0) {
2674
+ const session = this.provider.session;
2675
+ const providerState = {
2676
+ providerAccounts: this.provider.accounts,
2677
+ providerChainId: this.provider.chainId,
2678
+ session: session ? {
2679
+ exists: true,
2680
+ topic: session.topic,
2681
+ namespaces: session.namespaces ? Object.keys(session.namespaces) : "none",
2682
+ eip155Namespace: session.namespaces?.eip155 ? {
2683
+ accounts: session.namespaces.eip155.accounts,
2684
+ // CAIP-10 format
2685
+ chains: session.namespaces.eip155.chains,
2686
+ // CAIP-2 format
2687
+ methods: session.namespaces.eip155.methods,
2688
+ events: session.namespaces.eip155.events
2689
+ } : "none",
2690
+ // Log full session structure for debugging
2691
+ fullSession: JSON.stringify(session, null, 2)
2692
+ } : "none",
2693
+ // Check if provider has any other properties that might contain accounts
2694
+ providerKeys: Object.keys(this.provider)
2695
+ };
2696
+ console.error("[WalletConnect] No accounts available after enable() and wait", providerState);
2697
+ console.error("[WalletConnect] Full provider object:", this.provider);
2698
+ console.error("[WalletConnect] Full session object:", session);
2699
+ console.error("[WalletConnect] Session namespaces structure:", session?.namespaces);
2700
+ throw new Error("WalletConnect connection established but no accounts available. Please check session.namespaces.eip155.accounts in the console logs above.");
2701
+ }
2702
+ const currentChainId = this.provider.chainId || targetChains[0];
2703
+ const viemChain = this.getViemChain(currentChainId);
2704
+ this.walletClient = viem.createWalletClient({
2705
+ account: accounts[0],
2706
+ chain: viemChain,
2707
+ transport: viem.custom(this.provider)
2708
+ });
2709
+ const chainInfo = getChainInfo(currentChainId);
2710
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2711
+ this.publicClient = viem.createPublicClient({
2712
+ chain: viemChain,
2713
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(this.provider)
2714
+ });
2715
+ const address = formatEVMAddress(accounts[0]);
2716
+ const account = {
2717
+ universalAddress: createUniversalAddress(currentChainId, address),
2718
+ nativeAddress: address,
2719
+ chainId: currentChainId,
2720
+ chainType: ChainType.EVM,
2721
+ isActive: true
2722
+ };
2723
+ this.setState("connected" /* CONNECTED */);
2724
+ this.setAccount(account);
2725
+ this.setupEventListeners();
2726
+ return account;
2727
+ } catch (error) {
2728
+ this.setState("error" /* ERROR */);
2729
+ this.setAccount(null);
2730
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
2731
+ const errorCode = error?.code;
2732
+ const errorMessage = error?.message || String(error);
2733
+ const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
2734
+ const session = this.provider?.session;
2735
+ const providerState = this.provider ? {
2736
+ accounts: this.provider.accounts,
2737
+ chainId: this.provider.chainId,
2738
+ session: session ? {
2739
+ exists: true,
2740
+ topic: session.topic,
2741
+ namespaces: session.namespaces ? Object.keys(session.namespaces) : "none",
2742
+ eip155Namespace: session.namespaces?.eip155 ? {
2743
+ accounts: session.namespaces.eip155.accounts,
2744
+ chains: session.namespaces.eip155.chains,
2745
+ methods: session.namespaces.eip155.methods,
2746
+ events: session.namespaces.eip155.events
2747
+ } : "none"
2748
+ } : "none",
2749
+ providerKeys: Object.keys(this.provider)
2750
+ } : "no provider";
2751
+ console.error("[WalletConnect] Connection error:", {
2752
+ error,
2753
+ code: error.code,
2754
+ message: error.message,
2755
+ stack: error.stack,
2756
+ providerState
2757
+ });
2758
+ if (this.provider) {
2759
+ console.error("[WalletConnect] Full provider object:", this.provider);
2760
+ console.error("[WalletConnect] Full session object:", session);
2761
+ }
2762
+ if (error.code === 4001 || error.message && (error.message.includes("User rejected") || error.message.includes("rejected by user") || error.message.includes("User cancelled"))) {
2763
+ throw new ConnectionRejectedError(this.type);
2764
+ }
2765
+ if (isOriginNotAllowed) {
2766
+ throw new ConfigurationError(
2767
+ `WalletConnect relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
2768
+
2769
+ Fix:
2770
+ 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
2771
+ 2) Add this site origin to the allowlist:
2772
+ - ${origin || "(unknown origin)"}
2773
+
2774
+ Common dev origins to allow:
2775
+ - http://localhost:5173
2776
+ - http://192.168.0.221:5173 (your LAN dev URL)
2777
+ - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
2778
+
2779
+ Original error: ${errorMessage}`
2780
+ );
2781
+ }
2782
+ throw error;
2783
+ }
2784
+ }
2785
+ /**
2786
+ * Disconnect wallet
2787
+ */
2788
+ async disconnect() {
2789
+ if (this.provider) {
2790
+ try {
2791
+ await this.provider.disconnect();
2792
+ } catch (error) {
2793
+ console.warn("[WalletConnect] Error during disconnect:", error);
2794
+ }
2795
+ if (_WalletConnectAdapter.providerInstance === this.provider) {
2796
+ _WalletConnectAdapter.providerInstance = null;
2797
+ _WalletConnectAdapter.providerProjectId = null;
2798
+ _WalletConnectAdapter.providerChains = null;
2799
+ }
2800
+ this.provider = null;
2801
+ }
2802
+ this.removeEventListeners();
2803
+ this.walletClient = null;
2804
+ this.publicClient = null;
2805
+ this.setState("disconnected" /* DISCONNECTED */);
2806
+ this.setAccount(null);
2807
+ this.emitDisconnected();
2808
+ }
2809
+ /**
2810
+ * Sign message
2811
+ */
2812
+ async signMessage(message) {
2813
+ this.ensureConnected();
2814
+ try {
2815
+ if (!this.provider) {
2816
+ throw new Error("Provider not initialized");
2817
+ }
2818
+ const signature = await this.provider.request({
2819
+ method: "personal_sign",
2820
+ params: [message, this.currentAccount.nativeAddress]
2821
+ });
2822
+ this.closeTelegramDeepLinkPopup();
2823
+ return signature;
2824
+ } catch (error) {
2825
+ if (error.code === 4001 || error.message?.includes("rejected")) {
2826
+ throw new SignatureRejectedError();
2827
+ }
2828
+ throw error;
2829
+ }
2830
+ }
2831
+ /**
2832
+ * Sign TypedData (EIP-712)
2833
+ */
2834
+ async signTypedData(typedData) {
2835
+ this.ensureConnected();
2836
+ try {
2837
+ if (!this.provider) {
2838
+ throw new Error("Provider not initialized");
2839
+ }
2840
+ const signature = await this.provider.request({
2841
+ method: "eth_signTypedData_v4",
2842
+ params: [this.currentAccount.nativeAddress, JSON.stringify(typedData)]
2843
+ });
2844
+ this.closeTelegramDeepLinkPopup();
2845
+ return signature;
2846
+ } catch (error) {
2847
+ if (error.code === 4001 || error.message?.includes("rejected")) {
2848
+ throw new SignatureRejectedError();
2849
+ }
2850
+ throw error;
2851
+ }
2852
+ }
2853
+ /**
2854
+ * Sign transaction
2855
+ */
2856
+ async signTransaction(transaction) {
2857
+ this.ensureConnected();
2858
+ try {
2859
+ if (!this.provider) {
2860
+ throw new Error("Provider not initialized");
2861
+ }
2862
+ const tx = {
2863
+ from: this.currentAccount.nativeAddress,
2864
+ to: transaction.to,
2865
+ value: transaction.value ? `0x${BigInt(transaction.value).toString(16)}` : void 0,
2866
+ data: transaction.data || "0x",
2867
+ gas: transaction.gas ? `0x${BigInt(transaction.gas).toString(16)}` : void 0,
2868
+ gasPrice: transaction.gasPrice && transaction.gasPrice !== "auto" ? `0x${BigInt(transaction.gasPrice).toString(16)}` : void 0,
2869
+ maxFeePerGas: transaction.maxFeePerGas ? `0x${BigInt(transaction.maxFeePerGas).toString(16)}` : void 0,
2870
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas ? `0x${BigInt(transaction.maxPriorityFeePerGas).toString(16)}` : void 0,
2871
+ nonce: transaction.nonce !== void 0 ? `0x${transaction.nonce.toString(16)}` : void 0,
2872
+ chainId: transaction.chainId || this.currentAccount.chainId
2873
+ };
2874
+ const signature = await this.provider.request({
2875
+ method: "eth_signTransaction",
2876
+ params: [tx]
2877
+ });
2878
+ this.closeTelegramDeepLinkPopup();
2879
+ return signature;
2880
+ } catch (error) {
2881
+ if (error.code === 4001 || error.message?.includes("rejected")) {
2882
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
2883
+ }
2884
+ throw error;
2885
+ }
2886
+ }
2887
+ /**
2888
+ * Get supported chains from current connection
2889
+ * Returns the chains that were requested during connection
2890
+ */
2891
+ getSupportedChains() {
2892
+ return [...this.supportedChains];
2893
+ }
2894
+ /**
2895
+ * Switch chain
2896
+ *
2897
+ * Note: WalletConnect v2 with mobile wallets may not support chain switching reliably.
2898
+ * Some wallets may ignore the switch request or fail silently.
2899
+ * It's recommended to include all needed chains in the initial connection.
2900
+ *
2901
+ * Reference: https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces
2902
+ */
2903
+ async switchChain(chainId) {
2904
+ if (!this.provider) {
2905
+ throw new Error("Provider not initialized");
2906
+ }
2907
+ const session = this.provider.session;
2908
+ const supportedChains = session?.namespaces?.eip155?.chains || [];
2909
+ const targetChainCAIP = `eip155:${chainId}`;
2910
+ const isChainApproved = supportedChains.includes(targetChainCAIP);
2911
+ if (!isChainApproved) {
2912
+ console.warn(`[WalletConnect] Chain ${chainId} (${targetChainCAIP}) not in session approved chains:`, supportedChains);
2913
+ console.warn("[WalletConnect] Chain switching may fail. Consider including all chains in initial connection.");
2914
+ }
2915
+ try {
2916
+ console.log(`[WalletConnect] Attempting to switch to chain ${chainId} (${targetChainCAIP})`);
2917
+ const result = await this.provider.request({
2918
+ method: "wallet_switchEthereumChain",
2919
+ params: [{ chainId: `0x${chainId.toString(16)}` }]
2920
+ });
2921
+ if (result !== null && result !== void 0) {
2922
+ console.warn("[WalletConnect] wallet_switchEthereumChain returned non-null result:", result);
2923
+ }
2924
+ await new Promise((resolve) => setTimeout(resolve, 500));
2925
+ const currentChainId = this.provider.chainId;
2926
+ if (currentChainId !== chainId) {
2927
+ console.warn(`[WalletConnect] Chain switch may have failed. Expected ${chainId}, got ${currentChainId}`);
2928
+ console.warn("[WalletConnect] Some mobile wallets may not support chain switching via WalletConnect.");
2929
+ console.warn("[WalletConnect] User may need to manually switch chains in the wallet app.");
2930
+ }
2931
+ if (this.currentAccount) {
2932
+ const updatedAccount = {
2933
+ ...this.currentAccount,
2934
+ chainId,
2935
+ universalAddress: createUniversalAddress(chainId, this.currentAccount.nativeAddress)
2936
+ };
2937
+ this.setAccount(updatedAccount);
2938
+ this.emitChainChanged(chainId);
2939
+ const viemChain = this.getViemChain(chainId);
2940
+ const chainInfo = getChainInfo(chainId);
2941
+ const primaryRpcUrl = chainInfo?.rpcUrls[0];
2942
+ this.walletClient = viem.createWalletClient({
2943
+ account: this.currentAccount.nativeAddress,
2944
+ chain: viemChain,
2945
+ transport: viem.custom(this.provider)
2946
+ });
2947
+ this.publicClient = viem.createPublicClient({
2948
+ chain: viemChain,
2949
+ transport: primaryRpcUrl ? viem.http(primaryRpcUrl) : viem.custom(this.provider)
2950
+ });
2951
+ }
2952
+ } catch (error) {
2953
+ console.error("[WalletConnect] Chain switch error:", {
2954
+ chainId,
2955
+ errorCode: error.code,
2956
+ errorMessage: error.message,
2957
+ supportedChains
2958
+ });
2959
+ if (error.code === 4902) {
2960
+ console.log(`[WalletConnect] Chain ${chainId} not found in wallet, attempting to add...`);
2961
+ const chainInfo = getChainInfo(chainId);
2962
+ if (chainInfo) {
2963
+ try {
2964
+ await this.addChain({
2965
+ chainId: chainInfo.id,
2966
+ chainName: chainInfo.name,
2967
+ nativeCurrency: chainInfo.nativeCurrency,
2968
+ rpcUrls: chainInfo.rpcUrls,
2969
+ blockExplorerUrls: chainInfo.blockExplorerUrls
2970
+ });
2971
+ console.log(`[WalletConnect] Chain added, attempting to switch again...`);
2972
+ await this.switchChain(chainId);
2973
+ } catch (addError) {
2974
+ console.error("[WalletConnect] Failed to add chain:", addError);
2975
+ throw new Error(`Failed to add chain ${chainId}: ${addError.message}`);
2976
+ }
2977
+ } else {
2978
+ throw new Error(`Chain ${chainId} not supported`);
2979
+ }
2980
+ } else if (error.code === 4001) {
2981
+ throw new Error("User rejected chain switch");
2982
+ } else if (error.code === 4100) {
2983
+ throw new Error("Wallet does not support wallet_switchEthereumChain. Please switch chains manually in your wallet app.");
2984
+ } else {
2985
+ console.warn("[WalletConnect] Chain switch may not be supported by this wallet. User may need to switch manually.");
2986
+ throw error;
2987
+ }
2988
+ }
2989
+ }
2990
+ /**
2991
+ * Add chain
2992
+ */
2993
+ async addChain(chainConfig) {
2994
+ if (!this.provider) {
2995
+ throw new Error("Provider not initialized");
2996
+ }
2997
+ await this.provider.request({
2998
+ method: "wallet_addEthereumChain",
2999
+ params: [{
3000
+ chainId: `0x${chainConfig.chainId.toString(16)}`,
3001
+ chainName: chainConfig.chainName,
3002
+ nativeCurrency: chainConfig.nativeCurrency,
3003
+ rpcUrls: chainConfig.rpcUrls,
3004
+ blockExplorerUrls: chainConfig.blockExplorerUrls
3005
+ }]
3006
+ });
3007
+ }
3008
+ /**
3009
+ * Read contract
3010
+ */
3011
+ async readContract(params) {
3012
+ if (!this.publicClient) {
3013
+ throw new Error("Public client not initialized");
3014
+ }
3015
+ const result = await this.publicClient.readContract({
3016
+ address: params.address,
3017
+ abi: params.abi,
3018
+ functionName: params.functionName,
3019
+ ...params.args ? { args: params.args } : {}
3020
+ });
3021
+ return result;
3022
+ }
3023
+ /**
3024
+ * Write contract
3025
+ */
3026
+ async writeContract(params) {
3027
+ this.ensureConnected();
3028
+ if (!this.walletClient) {
3029
+ throw new Error("Wallet client not initialized");
3030
+ }
3031
+ try {
3032
+ const txOptions = {
3033
+ address: params.address,
3034
+ abi: params.abi,
3035
+ functionName: params.functionName,
3036
+ ...params.args ? { args: params.args } : {},
3037
+ value: params.value ? BigInt(params.value) : void 0,
3038
+ gas: params.gas ? BigInt(params.gas) : void 0
3039
+ };
3040
+ if (params.maxFeePerGas || params.maxPriorityFeePerGas) {
3041
+ if (params.maxFeePerGas) {
3042
+ txOptions.maxFeePerGas = BigInt(params.maxFeePerGas);
3043
+ }
3044
+ if (params.maxPriorityFeePerGas) {
3045
+ txOptions.maxPriorityFeePerGas = BigInt(params.maxPriorityFeePerGas);
3046
+ }
3047
+ } else if (params.gasPrice && params.gasPrice !== "auto") {
3048
+ txOptions.gasPrice = BigInt(params.gasPrice);
3049
+ } else {
3050
+ if (this.publicClient) {
3051
+ try {
3052
+ const feesPerGas = await this.publicClient.estimateFeesPerGas().catch(() => null);
3053
+ if (feesPerGas) {
3054
+ const minPriorityFeeWei = BigInt(1e8);
3055
+ const maxPriorityFeePerGas = feesPerGas.maxPriorityFeePerGas > minPriorityFeeWei ? feesPerGas.maxPriorityFeePerGas : minPriorityFeeWei;
3056
+ const adjustedMaxFeePerGas = feesPerGas.maxFeePerGas > maxPriorityFeePerGas ? feesPerGas.maxFeePerGas : maxPriorityFeePerGas + BigInt(1e9);
3057
+ txOptions.maxFeePerGas = adjustedMaxFeePerGas;
3058
+ txOptions.maxPriorityFeePerGas = maxPriorityFeePerGas;
3059
+ } else {
3060
+ const gasPrice = await this.publicClient.getGasPrice();
3061
+ txOptions.gasPrice = gasPrice;
3062
+ }
3063
+ } catch (err) {
3064
+ }
3065
+ }
3066
+ }
3067
+ const txHash = await this.walletClient.writeContract(txOptions);
3068
+ this.closeTelegramDeepLinkPopup();
3069
+ return txHash;
3070
+ } catch (error) {
3071
+ if (error.code === 4001 || error.message?.includes("rejected")) {
3072
+ throw new SignatureRejectedError("Transaction was rejected by user");
3073
+ }
3074
+ throw error;
3075
+ }
3076
+ }
3077
+ /**
3078
+ * Estimate gas
3079
+ */
3080
+ async estimateGas(params) {
3081
+ if (!this.publicClient) {
3082
+ throw new Error("Public client not initialized");
3083
+ }
3084
+ const gas = await this.publicClient.estimateContractGas({
3085
+ address: params.address,
3086
+ abi: params.abi,
3087
+ functionName: params.functionName,
3088
+ ...params.args ? { args: params.args } : {},
3089
+ value: params.value ? BigInt(params.value) : void 0,
3090
+ account: this.currentAccount.nativeAddress
3091
+ });
3092
+ return gas;
3093
+ }
3094
+ /**
3095
+ * Wait for transaction
3096
+ */
3097
+ async waitForTransaction(txHash, confirmations = 1) {
3098
+ if (!this.publicClient) {
3099
+ throw new Error("Public client not initialized");
3100
+ }
3101
+ const receipt = await this.publicClient.waitForTransactionReceipt({
3102
+ hash: txHash,
3103
+ confirmations
3104
+ });
3105
+ if (receipt.status === "reverted") {
3106
+ throw new TransactionFailedError(txHash, "Transaction reverted");
3107
+ }
3108
+ return {
3109
+ transactionHash: receipt.transactionHash,
3110
+ blockNumber: Number(receipt.blockNumber),
3111
+ blockHash: receipt.blockHash,
3112
+ from: receipt.from,
3113
+ to: receipt.to || void 0,
3114
+ status: receipt.status === "success" ? "success" : "failed",
3115
+ gasUsed: receipt.gasUsed.toString(),
3116
+ effectiveGasPrice: receipt.effectiveGasPrice?.toString(),
3117
+ logs: receipt.logs
3118
+ };
3119
+ }
3120
+ /**
3121
+ * Get provider
3122
+ */
3123
+ getProvider() {
3124
+ return this.provider;
3125
+ }
3126
+ /**
3127
+ * Get signer
3128
+ */
3129
+ getSigner() {
3130
+ return this.walletClient;
3131
+ }
3132
+ /**
3133
+ * Setup event listeners
3134
+ */
3135
+ setupEventListeners() {
3136
+ if (!this.provider) return;
3137
+ this.provider.on("accountsChanged", this.handleAccountsChanged);
3138
+ this.provider.on("chainChanged", this.handleChainChanged);
3139
+ this.provider.on("disconnect", this.handleDisconnect);
3140
+ }
3141
+ /**
3142
+ * Remove event listeners
3143
+ */
3144
+ removeEventListeners() {
3145
+ if (!this.provider) return;
3146
+ this.provider.removeListener("accountsChanged", this.handleAccountsChanged);
3147
+ this.provider.removeListener("chainChanged", this.handleChainChanged);
3148
+ this.provider.removeListener("disconnect", this.handleDisconnect);
3149
+ }
3150
+ /**
3151
+ * Get viem chain config
3152
+ */
3153
+ getViemChain(chainId) {
3154
+ const chainInfo = getChainInfo(chainId);
3155
+ if (chainInfo) {
3156
+ return {
3157
+ id: chainId,
3158
+ name: chainInfo.name,
3159
+ network: chainInfo.name.toLowerCase().replace(/\s+/g, "-"),
3160
+ nativeCurrency: chainInfo.nativeCurrency,
3161
+ rpcUrls: {
3162
+ default: { http: chainInfo.rpcUrls },
3163
+ public: { http: chainInfo.rpcUrls }
3164
+ },
3165
+ blockExplorers: chainInfo.blockExplorerUrls ? {
3166
+ default: { name: "Explorer", url: chainInfo.blockExplorerUrls[0] }
3167
+ } : void 0
3168
+ };
3169
+ }
3170
+ return {
3171
+ id: chainId,
3172
+ name: `Chain ${chainId}`,
3173
+ network: `chain-${chainId}`,
3174
+ nativeCurrency: {
3175
+ name: "ETH",
3176
+ symbol: "ETH",
3177
+ decimals: 18
3178
+ },
3179
+ rpcUrls: {
3180
+ default: { http: [] },
3181
+ public: { http: [] }
3182
+ }
3183
+ };
3184
+ }
3185
+ };
3186
+ // Store supported chains from connection
3187
+ // Static provider instance to avoid multiple initializations
3188
+ _WalletConnectAdapter.providerInstance = null;
3189
+ _WalletConnectAdapter.providerProjectId = null;
3190
+ _WalletConnectAdapter.providerChains = null;
3191
+ // Store the chains used during initialization
3192
+ _WalletConnectAdapter.isInitializing = false;
3193
+ _WalletConnectAdapter.initPromise = null;
3194
+ var WalletConnectAdapter = _WalletConnectAdapter;
3195
+ init_types();
3196
+ var _WalletConnectTronAdapter = class _WalletConnectTronAdapter extends WalletAdapter {
3197
+ constructor(projectId) {
3198
+ super();
3199
+ this.type = "walletconnect-tron" /* WALLETCONNECT_TRON */;
3200
+ this.chainType = ChainType.TRON;
3201
+ this.name = "WalletConnect (Tron)";
3202
+ this.icon = "https://avatars.githubusercontent.com/u/37784886";
3203
+ this.wallet = null;
3204
+ this.currentAddress = null;
3205
+ if (!projectId) {
3206
+ throw new ConfigurationError("WalletConnect projectId is required");
3207
+ }
3208
+ this.projectId = projectId;
3209
+ }
3210
+ /**
3211
+ * Check if WalletConnect is available
3212
+ */
3213
+ async isAvailable() {
3214
+ return typeof window !== "undefined";
3215
+ }
3216
+ /**
3217
+ * Check if running in Telegram environment (Mini App or Web)
3218
+ * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
3219
+ * provide window.Telegram.WebApp API, so they are treated the same way.
3220
+ */
3221
+ isTelegramMiniApp() {
3222
+ if (typeof window === "undefined") return false;
3223
+ const tg = window.Telegram?.WebApp;
3224
+ if (!tg) return false;
3225
+ const platform = tg.platform || "unknown";
3226
+ console.log("[WalletConnect Tron] Telegram environment detected:", {
3227
+ platform,
3228
+ version: tg.version,
3229
+ isMiniApp: platform !== "web",
3230
+ // Mini App if not web platform
3231
+ isWeb: platform === "web"
3232
+ // Telegram Web if web platform
3233
+ });
3234
+ return true;
3235
+ }
3236
+ /**
3237
+ * Restore session from existing wallet (for storage restoration)
3238
+ */
3239
+ async restoreSession(chainId) {
3240
+ if (typeof window === "undefined") {
3241
+ return null;
3242
+ }
3243
+ try {
3244
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3245
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3246
+ this.initializeWallet(targetChainId);
3247
+ }
3248
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
3249
+ if (!this.wallet) {
3250
+ return null;
3251
+ }
3252
+ const status = await this.wallet.checkConnectStatus();
3253
+ if (status && status.address) {
3254
+ this.currentAddress = status.address;
3255
+ const account = {
3256
+ universalAddress: createUniversalAddress(targetChainId, status.address),
3257
+ nativeAddress: status.address,
3258
+ chainId: targetChainId,
3259
+ chainType: ChainType.TRON,
3260
+ isActive: true
3261
+ };
3262
+ this.setState("connected" /* CONNECTED */);
3263
+ this.setAccount(account);
3264
+ this.setupEventListeners();
3265
+ return account;
3266
+ }
3267
+ return null;
3268
+ } catch (error) {
3269
+ console.debug("[WalletConnect Tron] Restore session failed:", error);
3270
+ return null;
3271
+ }
3272
+ }
3273
+ /**
3274
+ * Initialize WalletConnect wallet instance
3275
+ * @param chainId - Optional chain ID to determine network (default: Mainnet)
3276
+ */
3277
+ initializeWallet(chainId) {
3278
+ if (_WalletConnectTronAdapter.walletInstance && _WalletConnectTronAdapter.walletProjectId === this.projectId) {
3279
+ return;
3280
+ }
3281
+ let appUrl = "";
3282
+ if (typeof window !== "undefined") {
3283
+ try {
3284
+ if (window.location && window.location.origin) {
3285
+ appUrl = window.location.origin;
3286
+ } else if (window.location && window.location.href) {
3287
+ const url = new URL(window.location.href);
3288
+ appUrl = url.origin;
3289
+ }
3290
+ } catch (error) {
3291
+ console.warn("[WalletConnect Tron] Failed to get origin from window.location:", error);
3292
+ }
3293
+ if (appUrl && (appUrl.includes("serveo.net") || appUrl.includes("loca.lt") || appUrl.includes("ngrok.io") || appUrl.includes("ngrok-free.app") || appUrl.includes("cloudflared.io"))) {
3294
+ console.log("[WalletConnect Tron] Detected tunnel service URL:", appUrl);
3295
+ console.log("[WalletConnect Tron] \u26A0\uFE0F Make sure this URL is added to WalletConnect Cloud project allowlist");
3296
+ }
3297
+ if (!appUrl) {
3298
+ const tg = window.Telegram?.WebApp;
3299
+ if (tg && tg.initDataUnsafe?.start_param) {
3300
+ appUrl = "https://enclave.network";
3301
+ } else {
3302
+ appUrl = "https://enclave.network";
3303
+ }
3304
+ }
3305
+ } else {
3306
+ appUrl = "https://enclave.network";
3307
+ }
3308
+ if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
3309
+ appUrl = "https://enclave.network";
3310
+ }
3311
+ const icons = [
3312
+ "https://walletconnect.com/walletconnect-logo.svg",
3313
+ "https://avatars.githubusercontent.com/u/37784886"
3314
+ // WalletConnect GitHub avatar
3315
+ ];
3316
+ let network = walletconnectTron.WalletConnectChainID.Mainnet;
3317
+ if (chainId !== void 0) {
3318
+ if (chainId === 195 || chainId === _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID) {
3319
+ network = walletconnectTron.WalletConnectChainID.Mainnet;
3320
+ } else if (chainId === 201910292) {
3321
+ network = walletconnectTron.WalletConnectChainID.Shasta;
3322
+ } else if (chainId === 2494104990) {
3323
+ network = walletconnectTron.WalletConnectChainID.Nile;
3324
+ }
3325
+ }
3326
+ const metadataInfo = {
3327
+ name: "Enclave Wallet SDK",
3328
+ description: "Multi-chain wallet adapter for Enclave",
3329
+ url: appUrl,
3330
+ icons,
3331
+ network,
3332
+ chainId,
3333
+ isTelegram: this.isTelegramMiniApp(),
3334
+ projectId: this.projectId,
3335
+ urlValid: appUrl && (appUrl.startsWith("http://") || appUrl.startsWith("https://")),
3336
+ iconsValid: icons && icons.length > 0 && icons.every((icon) => icon && icon.startsWith("http")),
3337
+ currentLocation: typeof window !== "undefined" ? window.location.href : "N/A",
3338
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A"
3339
+ };
3340
+ console.log("[WalletConnect Tron] Initializing with metadata:", metadataInfo);
3341
+ if (!metadataInfo.urlValid) {
3342
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid URL in metadata:", appUrl);
3343
+ }
3344
+ if (!metadataInfo.iconsValid) {
3345
+ console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid icons in metadata:", icons);
3346
+ }
3347
+ console.log("[WalletConnect Tron] Initializing wallet...", {
3348
+ network,
3349
+ chainId,
3350
+ note: "If no wallets are in WalletConnect Explorer for TRON, QR code will be displayed for scanning"
3351
+ });
3352
+ _WalletConnectTronAdapter.walletInstance = new walletconnectTron.WalletConnectWallet({
3353
+ network,
3354
+ options: {
3355
+ projectId: this.projectId,
3356
+ metadata: {
3357
+ name: "Enclave Wallet SDK",
3358
+ description: "Multi-chain wallet adapter for Enclave",
3359
+ url: appUrl,
3360
+ icons
3361
+ }
3362
+ },
3363
+ // Theme configuration
3364
+ themeMode: "light",
3365
+ themeVariables: {
3366
+ "--w3m-z-index": 1e4
3367
+ // Ensure modal appears above Telegram UI
3368
+ },
3369
+ // Web3Modal configuration for recommended wallets
3370
+ // According to official docs: https://developers.tron.network/docs/walletconnect-tron
3371
+ // Note: If no wallets are registered in WalletConnect Explorer for TRON,
3372
+ // explorerRecommendedWalletIds will have no effect, and QR code will be shown instead.
3373
+ // @ts-ignore - web3ModalConfig is supported but may not be in TypeScript types
3374
+ web3ModalConfig: {
3375
+ themeMode: "light",
3376
+ themeVariables: {
3377
+ "--w3m-z-index": 1e4
3378
+ },
3379
+ /**
3380
+ * Recommended Wallets are fetched from WalletConnect explore api:
3381
+ * https://walletconnect.com/explorer?type=wallet&version=2
3382
+ *
3383
+ * IMPORTANT: If wallets are not registered in Explorer for TRON, this list will be ignored.
3384
+ * The AppKit will show a QR code instead, which users can scan with any WalletConnect-compatible wallet.
3385
+ *
3386
+ * Wallet IDs (for reference, may not work if not in Explorer):
3387
+ * - TokenPocket: 20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66
3388
+ * - TronLink: 1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369
3389
+ */
3390
+ explorerRecommendedWalletIds: [
3391
+ // These IDs are kept for when wallets register in WalletConnect Explorer
3392
+ // Currently, if no TRON wallets are in Explorer, QR code will be shown
3393
+ "20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66",
3394
+ // TokenPocket
3395
+ "1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
3396
+ // TronLink
3397
+ "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0"
3398
+ // TokenPocket (backup)
3399
+ ]
3400
+ }
3401
+ });
3402
+ _WalletConnectTronAdapter.walletProjectId = this.projectId;
3403
+ }
3404
+ /**
3405
+ * Connect wallet
3406
+ */
3407
+ async connect(chainId) {
3408
+ if (typeof window === "undefined") {
3409
+ throw new Error("WalletConnect requires a browser environment");
3410
+ }
3411
+ const currentState = this.state;
3412
+ if (currentState === "connecting" /* CONNECTING */) {
3413
+ console.warn("[WalletConnect Tron] Connection already in progress, waiting...");
3414
+ let attempts = 0;
3415
+ while (this.state === "connecting" /* CONNECTING */ && attempts < 50) {
3416
+ await new Promise((resolve) => setTimeout(resolve, 100));
3417
+ attempts++;
3418
+ }
3419
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3420
+ return this.currentAccount;
3421
+ }
3422
+ if (this.state === "connecting" /* CONNECTING */) {
3423
+ throw new Error("Connection timeout - previous connection attempt is still pending");
3424
+ }
3425
+ }
3426
+ if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3427
+ return this.currentAccount;
3428
+ }
3429
+ try {
3430
+ this.setState("connecting" /* CONNECTING */);
3431
+ const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3432
+ if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3433
+ this.initializeWallet(targetChainId);
3434
+ }
3435
+ this.wallet = _WalletConnectTronAdapter.walletInstance;
3436
+ if (!this.wallet) {
3437
+ throw new Error("Failed to initialize WalletConnect wallet");
3438
+ }
3439
+ let network = walletconnectTron.WalletConnectChainID.Mainnet;
3440
+ if (targetChainId === 195) {
3441
+ network = walletconnectTron.WalletConnectChainID.Mainnet;
3442
+ } else if (targetChainId === 201910292) {
3443
+ network = walletconnectTron.WalletConnectChainID.Shasta;
3444
+ } else if (targetChainId === 2494104990) {
3445
+ network = walletconnectTron.WalletConnectChainID.Nile;
3446
+ }
3447
+ let address;
3448
+ try {
3449
+ console.log("[WalletConnect Tron] Attempting to connect...", {
3450
+ network,
3451
+ chainId: targetChainId,
3452
+ isTelegram: this.isTelegramMiniApp(),
3453
+ projectId: this.projectId
3454
+ });
3455
+ const result = await this.wallet.connect();
3456
+ address = result.address;
3457
+ if (!address) {
3458
+ throw new ConnectionRejectedError(this.type);
3459
+ }
3460
+ console.log("[WalletConnect Tron] Connection successful:", {
3461
+ address,
3462
+ network,
3463
+ chainId: targetChainId,
3464
+ isTelegram: this.isTelegramMiniApp()
3465
+ });
3466
+ } catch (error) {
3467
+ const errorMessage = error.message || String(error);
3468
+ const errorCode = error.code || error.error?.code;
3469
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
3470
+ let detailedError = errorMessage;
3471
+ if (error.error) {
3472
+ if (typeof error.error === "string") {
3473
+ detailedError = error.error;
3474
+ } else if (error.error.message) {
3475
+ detailedError = error.error.message;
3476
+ } else if (error.error.data) {
3477
+ detailedError = JSON.stringify(error.error.data);
3478
+ }
3479
+ }
3480
+ 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");
3481
+ const isTimeout = errorMessage.includes("timeout") || errorMessage.includes("\u8D85\u65F6") || errorCode === "TIMEOUT";
3482
+ const isRejected = errorMessage.includes("rejected") || errorMessage.includes("\u62D2\u7EDD") || errorCode === 4001;
3483
+ const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
3484
+ const currentMetadata = this.wallet ? {
3485
+ // Try to get metadata from wallet instance if available
3486
+ projectId: this.projectId,
3487
+ network
3488
+ } : null;
3489
+ const errorDetails = {
3490
+ error: errorMessage,
3491
+ detailedError,
3492
+ code: errorCode,
3493
+ isTelegram: this.isTelegramMiniApp(),
3494
+ network,
3495
+ chainId: targetChainId,
3496
+ projectId: this.projectId,
3497
+ metadata: currentMetadata,
3498
+ // Get URL from window.location if available
3499
+ currentUrl: typeof window !== "undefined" ? window.location.href : "N/A",
3500
+ telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A",
3501
+ errorType: isNoWalletFound ? "NO_WALLET_FOUND" : isTimeout ? "TIMEOUT" : isRejected ? "REJECTED" : "UNKNOWN"
3502
+ };
3503
+ console.error("[WalletConnect Tron] Connection error - Full details:", errorDetails);
3504
+ console.error("[WalletConnect Tron] Error object:", error);
3505
+ console.error("[WalletConnect Tron] Error stack:", error.stack);
3506
+ if (isNoWalletFound) {
3507
+ const noWalletErrorDetails = [
3508
+ `
3509
+ === WalletConnect Tron: No Matching Wallet Found ===`,
3510
+ `Error: ${errorMessage}`,
3511
+ `Detailed: ${detailedError}`,
3512
+ `Code: ${errorCode || "N/A"}`,
3513
+ ``,
3514
+ `Environment:`,
3515
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3516
+ ` - Platform: ${errorDetails.telegramPlatform}`,
3517
+ ` - Current URL: ${errorDetails.currentUrl}`,
3518
+ ``,
3519
+ `Configuration:`,
3520
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3521
+ ` - Network: ${network}`,
3522
+ ` - Chain ID: ${targetChainId}`,
3523
+ ` - Metadata URL: ${typeof window !== "undefined" ? window.location.origin : "N/A"}`,
3524
+ ``,
3525
+ `Possible Causes:`,
3526
+ ` 1. No WalletConnect-compatible wallet (TokenPocket, etc.) installed on device`,
3527
+ ` 2. Wallet app not opened or not responding to deep link (wc://)`,
3528
+ ` 3. Deep link handling issue in Telegram Mini App environment`,
3529
+ ` 4. WalletConnect session timeout (user took too long to approve)`,
3530
+ ` 5. Network connectivity issue preventing WalletConnect relay connection`,
3531
+ ``,
3532
+ `Solutions:`,
3533
+ ` 1. Ensure TokenPocket or other WalletConnect-compatible wallet is installed`,
3534
+ ` 2. Try opening the wallet app manually before connecting`,
3535
+ ` 3. In Telegram Mini App, ensure the deep link popup is not blocked`,
3536
+ ` 4. Try connecting again (may need to wait a few seconds)`,
3537
+ ` 5. Check network connection and WalletConnect relay server accessibility`,
3538
+ ``,
3539
+ `For more details, see the error object logged above.`,
3540
+ `===========================================
3541
+ `
3542
+ ].join("\n");
3543
+ console.error(noWalletErrorDetails);
3544
+ throw new ConnectionRejectedError(
3545
+ `WalletConnect Tron: \u6CA1\u6709\u627E\u5230\u652F\u6301\u7684\u94B1\u5305 (No matching wallet found)
3546
+
3547
+ \u53EF\u80FD\u7684\u539F\u56E0\uFF1A
3548
+ 1. \u8BBE\u5907\u4E0A\u672A\u5B89\u88C5\u652F\u6301 WalletConnect \u7684\u94B1\u5305\uFF08\u5982 TokenPocket\uFF09
3549
+ 2. \u94B1\u5305\u5E94\u7528\u672A\u6253\u5F00\u6216\u672A\u54CD\u5E94 deep link (wc://)
3550
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0Cdeep link \u5904\u7406\u53EF\u80FD\u6709\u95EE\u9898
3551
+ 4. \u8FDE\u63A5\u8D85\u65F6\uFF08\u7528\u6237\u672A\u53CA\u65F6\u6279\u51C6\uFF09
3552
+ 5. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898
3553
+
3554
+ \u89E3\u51B3\u65B9\u6848\uFF1A
3555
+ 1. \u786E\u4FDD\u5DF2\u5B89\u88C5 TokenPocket \u6216\u5176\u4ED6\u652F\u6301 WalletConnect \u7684\u94B1\u5305
3556
+ 2. \u5C1D\u8BD5\u624B\u52A8\u6253\u5F00\u94B1\u5305\u5E94\u7528\u540E\u518D\u8FDE\u63A5
3557
+ 3. \u5728 Telegram Mini App \u4E2D\uFF0C\u786E\u4FDD deep link \u5F39\u7A97\u672A\u88AB\u963B\u6B62
3558
+ 4. \u7A0D\u7B49\u51E0\u79D2\u540E\u91CD\u8BD5\u8FDE\u63A5
3559
+ 5. \u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C WalletConnect \u4E2D\u7EE7\u670D\u52A1\u5668\u53EF\u8BBF\u95EE\u6027
3560
+
3561
+ \u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7\u3002`
3562
+ );
3563
+ }
3564
+ if (errorMessage.includes("Invalid") || errorMessage.includes("Configuration") || errorMessage.includes("App Config") || errorMessage.includes("Invalid App")) {
3565
+ const configErrorDetails = [
3566
+ `
3567
+ === WalletConnect Tron Configuration Error ===`,
3568
+ `Error: ${errorMessage}`,
3569
+ `Detailed: ${detailedError}`,
3570
+ `Code: ${errorCode || "N/A"}`,
3571
+ `
3572
+ Environment:`,
3573
+ ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3574
+ ` - Platform: ${errorDetails.telegramPlatform}`,
3575
+ ` - Current URL: ${errorDetails.currentUrl}`,
3576
+ `
3577
+ Configuration:`,
3578
+ ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3579
+ ` - Network: ${network}`,
3580
+ ` - Chain ID: ${targetChainId}`,
3581
+ `
3582
+ Possible Causes:`,
3583
+ ` 1. Deep link (wc://) handling issue in Telegram Mini App`,
3584
+ ` 2. Invalid metadata configuration (URL or icons not accessible)`,
3585
+ ` 3. Network/chainId mismatch`,
3586
+ ` 4. WalletConnect project ID not configured correctly`,
3587
+ ` 5. Domain not added to WalletConnect Cloud allowlist`,
3588
+ `
3589
+ Please check:`,
3590
+ ` - WalletConnect Project ID is valid and active`,
3591
+ ` - Domain is added to WalletConnect Cloud allowlist (for serveo.net, etc.)`,
3592
+ ` - Metadata URL is accessible: Check console for metadata logs`,
3593
+ ` - Icons are accessible: Check console for icon URLs`,
3594
+ ` - Network matches chainId: Expected ${network} for chainId ${targetChainId}`,
3595
+ `
3596
+ For more details, see the error object logged above.`,
3597
+ `===========================================
3598
+ `
3599
+ ].join("\n");
3600
+ console.error(configErrorDetails);
3601
+ throw new ConfigurationError(
3602
+ `WalletConnect Tron connection failed: ${errorMessage}
3603
+
3604
+ Configuration Details:
3605
+ - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}
3606
+ - Platform: ${errorDetails.telegramPlatform}
3607
+ - Origin: ${origin || "(unknown)"}
3608
+ - Project ID: ${this.projectId ? "Set" : "Missing"}
3609
+ - Network: ${network}
3610
+ - Chain ID: ${targetChainId}
3611
+
3612
+ This "Invalid App Configuration" error may be caused by:
3613
+ 1. Deep link (wc://) handling issue in Telegram Mini App
3614
+ 2. Invalid metadata configuration (URL or icons)
3615
+ 3. Network/chainId mismatch
3616
+ 4. Domain not added to WalletConnect Cloud allowlist
3617
+
3618
+ Please check the console for detailed error information.`
3619
+ );
3620
+ }
3621
+ if (isOriginNotAllowed) {
3622
+ throw new ConfigurationError(
3623
+ `WalletConnect Tron relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
3624
+
3625
+ Fix:
3626
+ 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
3627
+ 2) Add this site origin to the allowlist:
3628
+ - ${origin || "(unknown origin)"}
3629
+
3630
+ Common dev origins to allow:
3631
+ - http://localhost:5173
3632
+ - http://192.168.0.221:5173 (your LAN dev URL)
3633
+ - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
3634
+
3635
+ Original error: ${errorMessage}`
3636
+ );
3637
+ }
3638
+ if (isTimeout) {
3639
+ throw new ConnectionRejectedError(
3640
+ `WalletConnect Tron connection timeout. Please try again and ensure your wallet app is open and ready.`
3641
+ );
3642
+ }
3643
+ if (isRejected) {
3644
+ throw new ConnectionRejectedError(this.type);
3645
+ }
3646
+ throw error;
3647
+ }
3648
+ this.currentAddress = address;
3649
+ const account = {
3650
+ universalAddress: createUniversalAddress(targetChainId, address),
3651
+ nativeAddress: address,
3652
+ chainId: targetChainId,
3653
+ chainType: ChainType.TRON,
3654
+ isActive: true
3655
+ };
3656
+ this.setState("connected" /* CONNECTED */);
3657
+ this.setAccount(account);
3658
+ this.setupEventListeners();
3659
+ return account;
3660
+ } catch (error) {
3661
+ this.setState("error" /* ERROR */);
3662
+ this.setAccount(null);
3663
+ this.currentAddress = null;
3664
+ if (error.message?.includes("rejected") || error.code === 4001) {
3665
+ throw new ConnectionRejectedError(this.type);
3666
+ }
3667
+ throw error;
3668
+ }
3669
+ }
3670
+ /**
3671
+ * Disconnect wallet
3672
+ */
3673
+ async disconnect() {
3674
+ this.removeEventListeners();
3675
+ if (this.wallet) {
3676
+ try {
3677
+ await this.wallet.disconnect();
3678
+ } catch (error) {
3679
+ console.warn("[WalletConnect Tron] Error during disconnect:", error);
3680
+ }
3681
+ }
3682
+ this.wallet = null;
3683
+ this.currentAddress = null;
3684
+ this.setState("disconnected" /* DISCONNECTED */);
3685
+ this.setAccount(null);
3686
+ this.emitDisconnected();
3687
+ }
3688
+ /**
3689
+ * Sign message
3690
+ */
3691
+ async signMessage(message) {
3692
+ this.ensureConnected();
3693
+ try {
3694
+ if (!this.wallet) {
3695
+ throw new Error("Wallet not initialized");
3696
+ }
3697
+ const signature = await this.wallet.signMessage(message);
3698
+ if (typeof signature === "string") {
3699
+ return signature;
3700
+ } else if (signature && typeof signature === "object") {
3701
+ if ("signature" in signature) {
3702
+ return signature.signature;
3703
+ } else if ("result" in signature) {
3704
+ return signature.result;
3705
+ } else {
3706
+ return JSON.stringify(signature);
3707
+ }
3708
+ }
3709
+ throw new Error("Invalid signature format returned from wallet");
3710
+ } catch (error) {
3711
+ console.error("[WalletConnect Tron] Sign message error:", error);
3712
+ let errorMessage = "Unknown error";
3713
+ if (typeof error === "string") {
3714
+ errorMessage = error;
3715
+ } else if (error?.message) {
3716
+ errorMessage = error.message;
3717
+ } else if (error?.error?.message) {
3718
+ errorMessage = error.error.message;
3719
+ } else {
3720
+ try {
3721
+ errorMessage = JSON.stringify(error);
3722
+ } catch {
3723
+ errorMessage = String(error);
3724
+ }
3725
+ }
3726
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
3727
+ throw new SignatureRejectedError();
3728
+ }
3729
+ if (errorMessage?.includes("not supported") || errorMessage?.includes("method not found") || errorMessage?.includes("Method not found") || error?.code === -32601 || error?.error?.code === -32601) {
3730
+ 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.");
3731
+ }
3732
+ throw new Error(`WalletConnect Tron sign message failed: ${errorMessage}`);
3733
+ }
3734
+ }
3735
+ /**
3736
+ * Sign transaction
3737
+ *
3738
+ * @param transaction - Tron transaction object
3739
+ * Can be created using TronWeb (if available) or any TRON transaction builder
3740
+ * Format: { raw_data: {...}, raw_data_hex: "...", txID: "..." }
3741
+ * @returns Signed transaction object or signature
3742
+ */
3743
+ async signTransaction(transaction) {
3744
+ this.ensureConnected();
3745
+ try {
3746
+ if (!this.wallet) {
3747
+ throw new Error("Wallet not initialized");
3748
+ }
3749
+ if (!transaction) {
3750
+ throw new Error("Transaction object is required");
3751
+ }
3752
+ console.log("[WalletConnect Tron] Signing transaction:", {
3753
+ hasRawData: !!transaction.raw_data,
3754
+ hasRawDataHex: !!transaction.raw_data_hex,
3755
+ hasTxID: !!transaction.txID
3756
+ });
3757
+ const result = await this.wallet.signTransaction(transaction);
3758
+ if (typeof result === "string") {
3759
+ return result;
3760
+ } else if (result && typeof result === "object") {
3761
+ if ("txID" in result && typeof result.txID === "string") {
3762
+ return result.txID;
3763
+ } else if ("txid" in result && typeof result.txid === "string") {
3764
+ return result.txid;
3765
+ } else if ("signature" in result) {
3766
+ return JSON.stringify(result);
3767
+ } else {
3768
+ return JSON.stringify(result);
3769
+ }
3770
+ }
3771
+ throw new Error("Invalid signature format returned from wallet");
3772
+ } catch (error) {
3773
+ console.error("[WalletConnect Tron] Sign transaction error:", error);
3774
+ let errorMessage = "Unknown error";
3775
+ if (typeof error === "string") {
3776
+ errorMessage = error;
3777
+ } else if (error?.message) {
3778
+ errorMessage = error.message;
3779
+ } else if (error?.error?.message) {
3780
+ errorMessage = error.error.message;
3781
+ } else if (error?.data?.message) {
3782
+ errorMessage = error.data.message;
3783
+ } else {
3784
+ try {
3785
+ errorMessage = JSON.stringify(error);
3786
+ } catch {
3787
+ errorMessage = String(error);
3788
+ }
3789
+ }
3790
+ if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
3791
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
3792
+ }
3793
+ 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) {
3794
+ 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.");
3795
+ }
3796
+ throw new Error(`WalletConnect Tron sign transaction failed: ${errorMessage}`);
3797
+ }
3798
+ }
3799
+ /**
3800
+ * Read contract (not supported by WalletConnect)
3801
+ */
3802
+ async readContract(_params) {
3803
+ this.ensureConnected();
3804
+ 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.");
3805
+ }
3806
+ /**
3807
+ * Write contract (not yet implemented)
3808
+ */
3809
+ async writeContract(_params) {
3810
+ throw new Error("Contract write not yet implemented for WalletConnect Tron");
3811
+ }
3812
+ /**
3813
+ * Estimate gas (not yet implemented)
3814
+ */
3815
+ async estimateGas(_params) {
3816
+ throw new Error("Gas estimation not yet implemented for WalletConnect Tron");
3817
+ }
3818
+ /**
3819
+ * Wait for transaction (not yet implemented)
3820
+ */
3821
+ async waitForTransaction(_txHash, _confirmations) {
3822
+ throw new Error("Transaction waiting not yet implemented for WalletConnect Tron");
3823
+ }
3824
+ /**
3825
+ * Setup event listeners
3826
+ */
3827
+ setupEventListeners() {
3828
+ if (!this.wallet) {
3829
+ return;
3830
+ }
3831
+ this.wallet.on("accountsChanged", (accounts) => {
3832
+ if (accounts && accounts.length > 0 && accounts[0] !== this.currentAddress) {
3833
+ const newAddress = accounts[0];
3834
+ this.currentAddress = newAddress;
3835
+ if (this.currentAccount) {
3836
+ const newAccount = {
3837
+ ...this.currentAccount,
3838
+ nativeAddress: newAddress,
3839
+ universalAddress: createUniversalAddress(this.currentAccount.chainId, newAddress)
3840
+ };
3841
+ this.setAccount(newAccount);
3842
+ this.emit("accountChanged", newAccount);
3843
+ }
3844
+ } else if (!accounts || accounts.length === 0) {
3845
+ this.disconnect();
3846
+ }
3847
+ });
3848
+ this.wallet.on("disconnect", () => {
3849
+ this.disconnect();
3850
+ });
3851
+ }
3852
+ /**
3853
+ * Remove event listeners
3854
+ */
3855
+ removeEventListeners() {
3856
+ if (!this.wallet) {
3857
+ return;
3858
+ }
3859
+ this.wallet.removeAllListeners("accountsChanged");
3860
+ this.wallet.removeAllListeners("disconnect");
3861
+ }
3862
+ /**
3863
+ * Get provider (returns wallet instance)
3864
+ */
3865
+ getProvider() {
3866
+ return this.wallet;
3867
+ }
3868
+ /**
3869
+ * Clear static wallet instance (for complete cleanup)
3870
+ */
3871
+ static clearWalletInstance() {
3872
+ if (_WalletConnectTronAdapter.walletInstance) {
3873
+ _WalletConnectTronAdapter.walletInstance.disconnect().catch(() => {
3874
+ });
3875
+ _WalletConnectTronAdapter.walletInstance = null;
3876
+ _WalletConnectTronAdapter.walletProjectId = null;
3877
+ }
3878
+ }
3879
+ };
3880
+ // Tron 主网链 ID
3881
+ _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID = 195;
3882
+ // Static wallet instance to avoid multiple initializations
3883
+ _WalletConnectTronAdapter.walletInstance = null;
3884
+ _WalletConnectTronAdapter.walletProjectId = null;
3885
+ var WalletConnectTronAdapter = _WalletConnectTronAdapter;
3886
+
3887
+ // src/adapters/deep-link/adapter.ts
3888
+ init_types();
3889
+ var _DeepLinkAdapter = class _DeepLinkAdapter extends WalletAdapter {
3890
+ constructor(config) {
3891
+ super();
3892
+ this.currentChainId = null;
3893
+ this.currentChainType = null;
3894
+ this.provider = this.createProvider(config);
3895
+ this.name = `${this.provider.name} (Deep Link)`;
3896
+ this.icon = this.provider.icon;
3897
+ if (this.provider.supportedChainTypes.includes(ChainType.EVM)) {
3898
+ this.chainType = ChainType.EVM;
3899
+ this.type = "deep-link-evm" /* DEEP_LINK_EVM */;
3900
+ } else if (this.provider.supportedChainTypes.includes(ChainType.TRON)) {
3901
+ this.chainType = ChainType.TRON;
3902
+ this.type = "deep-link-tron" /* DEEP_LINK_TRON */;
3903
+ } else {
3904
+ this.chainType = ChainType.EVM;
3905
+ this.type = "deep-link-evm" /* DEEP_LINK_EVM */;
3906
+ }
3907
+ if (typeof window !== "undefined") {
3908
+ this.setupCallbackHandler();
3909
+ }
3910
+ }
3911
+ /**
3912
+ * Create provider instance based on type
3913
+ */
3914
+ createProvider(config) {
3915
+ switch (config.providerType) {
3916
+ case "tokenpocket" /* TOKENPOCKET */: {
3917
+ const { TokenPocketDeepLinkProvider: TokenPocketDeepLinkProvider2 } = (init_tokenpocket(), __toCommonJS(tokenpocket_exports));
3918
+ return new TokenPocketDeepLinkProvider2({
3919
+ callbackUrl: config.callbackUrl,
3920
+ callbackSchema: config.callbackSchema
3921
+ });
3922
+ }
3923
+ case "tronlink" /* TRONLINK */: {
3924
+ const { TronLinkDeepLinkProvider: TronLinkDeepLinkProvider2 } = (init_tronlink(), __toCommonJS(tronlink_exports));
3925
+ return new TronLinkDeepLinkProvider2();
3926
+ }
3927
+ case "imtoken" /* IMTOKEN */: {
3928
+ const { ImTokenDeepLinkProvider: ImTokenDeepLinkProvider2 } = (init_imtoken(), __toCommonJS(imtoken_exports));
3929
+ return new ImTokenDeepLinkProvider2({
3930
+ callbackUrl: config.callbackUrl,
3931
+ callbackSchema: config.callbackSchema
3932
+ });
3933
+ }
3934
+ case "metamask" /* METAMASK */: {
3935
+ const { MetaMaskDeepLinkProvider: MetaMaskDeepLinkProvider2 } = (init_metamask(), __toCommonJS(metamask_exports));
3936
+ return new MetaMaskDeepLinkProvider2();
3937
+ }
3938
+ case "okx" /* OKX */: {
3939
+ const { OKXDeepLinkProvider: OKXDeepLinkProvider2 } = (init_okx(), __toCommonJS(okx_exports));
3940
+ return new OKXDeepLinkProvider2();
3941
+ }
3942
+ default:
3943
+ throw new Error(`Unsupported deep link provider type: ${config.providerType}`);
3944
+ }
3945
+ }
3946
+ /**
3947
+ * Setup callback handler for deep link results
3948
+ */
3949
+ setupCallbackHandler() {
3950
+ if (typeof window === "undefined") {
3951
+ return;
3952
+ }
3953
+ const handleUrlChange = () => {
3954
+ const urlParams = new URLSearchParams(window.location.search);
3955
+ const result = this.provider.parseCallbackResult(urlParams);
3956
+ if (result.actionId && _DeepLinkAdapter.pendingActions.has(result.actionId)) {
3957
+ const callback = _DeepLinkAdapter.pendingActions.get(result.actionId);
3958
+ if (result.error) {
3959
+ callback.reject(new Error(result.error));
3960
+ } else if (result.result) {
3961
+ callback.resolve(result.result);
3962
+ }
3963
+ _DeepLinkAdapter.pendingActions.delete(result.actionId);
3964
+ }
3965
+ };
3966
+ window.addEventListener("popstate", handleUrlChange);
3967
+ window.addEventListener("hashchange", handleUrlChange);
3968
+ handleUrlChange();
3969
+ }
3970
+ /**
3971
+ * Check if deep link is available
3972
+ */
3973
+ async isAvailable() {
3974
+ return this.provider.isAvailable();
3975
+ }
3976
+ /**
3977
+ * Connect to wallet via deep link
3978
+ *
3979
+ * Note: Deep links typically don't support persistent connections
3980
+ * This method may throw ConnectionRejectedError as deep links are
3981
+ * primarily used for signing operations, not connection
3982
+ */
3983
+ async connect(chainId) {
3984
+ const targetChainId = Array.isArray(chainId) ? chainId[0] : chainId || 1;
3985
+ let chainType;
3986
+ if (targetChainId === 195) {
3987
+ chainType = ChainType.TRON;
3988
+ } else {
3989
+ chainType = ChainType.EVM;
3990
+ }
3991
+ if (!this.provider.supportedChainTypes.includes(chainType)) {
3992
+ throw new Error(
3993
+ `Provider ${this.provider.name} does not support chain type ${chainType}`
3994
+ );
3995
+ }
3996
+ if (this.provider.buildConnectLink) {
3997
+ const linkInfo = this.provider.buildConnectLink({
3998
+ chainId: targetChainId,
3999
+ chainType
4000
+ });
4001
+ if (linkInfo.actionId) {
4002
+ return new Promise((resolve, reject) => {
4003
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, {
4004
+ resolve: (result) => {
4005
+ const address = result?.address || result?.account || result;
4006
+ if (!address || typeof address !== "string") {
4007
+ reject(new ConnectionRejectedError("Invalid connection result: no address found"));
4008
+ return;
4009
+ }
4010
+ const account = {
4011
+ universalAddress: createUniversalAddress(targetChainId, address),
4012
+ nativeAddress: address,
4013
+ chainId: targetChainId,
4014
+ chainType,
4015
+ isActive: true
4016
+ };
4017
+ this.setState("connected" /* CONNECTED */);
4018
+ this.setAccount(account);
4019
+ this.emit("connected", account);
4020
+ resolve(account);
4021
+ },
4022
+ reject: (error) => {
4023
+ this.setState("disconnected" /* DISCONNECTED */);
4024
+ reject(error);
4025
+ }
4026
+ });
4027
+ window.location.href = linkInfo.url;
4028
+ setTimeout(() => {
4029
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4030
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4031
+ this.setState("disconnected" /* DISCONNECTED */);
4032
+ reject(new ConnectionRejectedError("Deep link connection timeout"));
4033
+ }
4034
+ }, 3e4);
4035
+ });
4036
+ } else {
4037
+ window.location.href = linkInfo.url;
4038
+ throw new ConnectionRejectedError(
4039
+ "Deep link connection initiated. Please complete the connection in your wallet app."
4040
+ );
4041
+ }
4042
+ } else {
4043
+ throw new ConnectionRejectedError(
4044
+ `Deep link connection is not supported by ${this.provider.name}. Deep links are primarily used for signing operations.`
4045
+ );
4046
+ }
4047
+ }
4048
+ /**
4049
+ * Disconnect from wallet
4050
+ */
4051
+ async disconnect() {
4052
+ this.setState("disconnected" /* DISCONNECTED */);
4053
+ this.setAccount(null);
4054
+ this.currentChainId = null;
4055
+ this.currentChainType = null;
4056
+ this.emitDisconnected();
4057
+ }
4058
+ /**
4059
+ * Sign a message
4060
+ */
4061
+ async signMessage(message) {
4062
+ this.ensureConnected();
4063
+ if (!this.currentChainId || !this.currentChainType) {
4064
+ throw new WalletNotConnectedError(this.type);
4065
+ }
4066
+ const linkInfo = this.provider.buildSignMessageLink({
4067
+ message,
4068
+ chainId: this.currentChainId,
4069
+ chainType: this.currentChainType
4070
+ });
4071
+ if (linkInfo.callbackSchema || linkInfo.callbackUrl) {
4072
+ return new Promise((resolve, reject) => {
4073
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, { resolve, reject });
4074
+ window.location.href = linkInfo.url;
4075
+ setTimeout(() => {
4076
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4077
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4078
+ reject(new SignatureRejectedError("Message signature timeout"));
4079
+ }
4080
+ }, 3e4);
4081
+ });
4082
+ } else {
4083
+ window.location.href = linkInfo.url;
4084
+ throw new SignatureRejectedError(
4085
+ "Deep link signature initiated. Please complete the signature in your wallet app."
4086
+ );
4087
+ }
4088
+ }
4089
+ /**
4090
+ * Sign a transaction
4091
+ */
4092
+ async signTransaction(transaction) {
4093
+ this.ensureConnected();
4094
+ if (!this.currentChainId || !this.currentChainType) {
4095
+ throw new WalletNotConnectedError(this.type);
4096
+ }
4097
+ const linkInfo = this.provider.buildSignTransactionLink({
4098
+ transaction,
4099
+ chainId: this.currentChainId,
4100
+ chainType: this.currentChainType
4101
+ });
4102
+ if (linkInfo.callbackSchema || linkInfo.callbackUrl) {
4103
+ return new Promise((resolve, reject) => {
4104
+ _DeepLinkAdapter.pendingActions.set(linkInfo.actionId, { resolve, reject });
4105
+ window.location.href = linkInfo.url;
4106
+ setTimeout(() => {
4107
+ if (_DeepLinkAdapter.pendingActions.has(linkInfo.actionId)) {
4108
+ _DeepLinkAdapter.pendingActions.delete(linkInfo.actionId);
4109
+ reject(new SignatureRejectedError("Transaction signature timeout"));
4110
+ }
4111
+ }, 3e4);
4112
+ });
4113
+ } else {
4114
+ window.location.href = linkInfo.url;
4115
+ throw new SignatureRejectedError(
4116
+ "Deep link transaction signature initiated. Please complete the signature in your wallet app."
4117
+ );
4118
+ }
4119
+ }
4120
+ /**
4121
+ * Get provider (not applicable for deep links)
4122
+ */
4123
+ getProvider() {
4124
+ return null;
4125
+ }
4126
+ /**
4127
+ * Static method to handle callback from wallet apps
4128
+ * This can be called from anywhere in the application
4129
+ */
4130
+ static handleCallback() {
4131
+ if (typeof window === "undefined") {
4132
+ return;
4133
+ }
4134
+ const urlParams = new URLSearchParams(window.location.search);
4135
+ const actionId = urlParams.get("actionId");
4136
+ if (actionId && _DeepLinkAdapter.pendingActions.has(actionId)) {
4137
+ const callback = _DeepLinkAdapter.pendingActions.get(actionId);
4138
+ const result = urlParams.get("result");
4139
+ const error = urlParams.get("error");
4140
+ if (error) {
4141
+ callback.reject(new Error(error));
4142
+ } else if (result) {
4143
+ try {
4144
+ const parsedResult = JSON.parse(decodeURIComponent(result));
4145
+ callback.resolve(parsedResult);
4146
+ } catch (e) {
4147
+ callback.resolve(result);
4148
+ }
4149
+ }
4150
+ _DeepLinkAdapter.pendingActions.delete(actionId);
4151
+ }
4152
+ }
4153
+ /**
4154
+ * Set current account (called after successful connection)
4155
+ */
4156
+ setAccount(account) {
4157
+ this.currentAccount = account;
4158
+ if (account) {
4159
+ this.currentChainId = account.chainId;
4160
+ this.currentChainType = account.chainType;
4161
+ }
4162
+ }
4163
+ /**
4164
+ * Emit disconnected event
4165
+ */
4166
+ emitDisconnected() {
4167
+ this.emit("disconnected");
4168
+ }
4169
+ };
4170
+ // Static map to store pending actions across all instances
4171
+ // Key: actionId, Value: { resolve, reject }
4172
+ _DeepLinkAdapter.pendingActions = /* @__PURE__ */ new Map();
4173
+ var DeepLinkAdapter = _DeepLinkAdapter;
4174
+
4175
+ // src/core/adapter-registry.ts
4176
+ var AdapterRegistry = class {
4177
+ constructor(config = {}) {
4178
+ this.adapters = /* @__PURE__ */ new Map();
4179
+ this.config = config;
4180
+ this.registerDefaultAdapters();
4181
+ }
4182
+ /**
4183
+ * Register default adapters
4184
+ */
4185
+ registerDefaultAdapters() {
4186
+ this.register("metamask" /* METAMASK */, () => new MetaMaskAdapter());
4187
+ this.register("private-key" /* PRIVATE_KEY */, () => new EVMPrivateKeyAdapter());
4188
+ if (this.config.walletConnectProjectId) {
4189
+ this.register(
4190
+ "walletconnect" /* WALLETCONNECT */,
4191
+ () => new WalletConnectAdapter(this.config.walletConnectProjectId)
4192
+ );
4193
+ this.register(
4194
+ "walletconnect-tron" /* WALLETCONNECT_TRON */,
4195
+ () => new WalletConnectTronAdapter(this.config.walletConnectProjectId)
4196
+ );
4197
+ }
4198
+ this.register("tronlink" /* TRONLINK */, () => new TronLinkAdapter());
4199
+ this.register(
4200
+ "deep-link-evm" /* DEEP_LINK_EVM */,
4201
+ () => new DeepLinkAdapter({
4202
+ providerType: "tokenpocket" /* TOKENPOCKET */
4203
+ })
4204
+ );
4205
+ this.register(
4206
+ "deep-link-tron" /* DEEP_LINK_TRON */,
4207
+ () => new DeepLinkAdapter({
4208
+ providerType: "tokenpocket" /* TOKENPOCKET */
4209
+ })
4210
+ );
4211
+ }
4212
+ /**
4213
+ * Register adapter
4214
+ */
4215
+ register(type, factory) {
4216
+ this.adapters.set(type, factory);
4217
+ }
4218
+ /**
4219
+ * Get adapter
4220
+ */
4221
+ getAdapter(type) {
4222
+ const factory = this.adapters.get(type);
4223
+ if (!factory) {
4224
+ return null;
4225
+ }
4226
+ return factory();
4227
+ }
4228
+ /**
4229
+ * Check if adapter is registered
4230
+ */
4231
+ has(type) {
4232
+ return this.adapters.has(type);
4233
+ }
4234
+ /**
4235
+ * Get all registered adapter types
4236
+ */
4237
+ getRegisteredTypes() {
4238
+ return Array.from(this.adapters.keys());
4239
+ }
4240
+ /**
4241
+ * 根据链类型获取适配器类型列表
4242
+ */
4243
+ getAdapterTypesByChainType(chainType) {
4244
+ const types = [];
4245
+ for (const type of this.adapters.keys()) {
4246
+ const adapter = this.getAdapter(type);
4247
+ if (adapter && adapter.chainType === chainType) {
4248
+ types.push(type);
4249
+ }
4250
+ }
4251
+ return types;
4252
+ }
4253
+ };
4254
+
4255
+ // src/core/wallet-manager.ts
4256
+ init_types();
4257
+ var QRCodeSigner = class {
4258
+ constructor(config) {
4259
+ this.pollTimer = null;
4260
+ this.timeoutTimer = null;
4261
+ this.status = "waiting" /* WAITING */;
4262
+ this.qrCodeDataUrl = null;
4263
+ this.result = null;
4264
+ this.config = {
4265
+ requestId: config.requestId,
4266
+ requestUrl: config.requestUrl,
4267
+ pollUrl: config.pollUrl || "",
4268
+ pollInterval: config.pollInterval || 2e3,
4269
+ timeout: config.timeout || 3e5,
4270
+ // 5 minutes
4271
+ pollFn: config.pollFn
4272
+ };
4273
+ }
4274
+ /**
4275
+ * 生成二维码图片(Data URL)
4276
+ */
4277
+ async generateQRCode(options) {
4278
+ if (this.qrCodeDataUrl) {
4279
+ return this.qrCodeDataUrl;
4280
+ }
4281
+ try {
4282
+ const qrCodeOptions = {
4283
+ width: options?.width || 300,
4284
+ margin: options?.margin || 2,
4285
+ color: {
4286
+ dark: options?.color?.dark || "#000000",
4287
+ light: options?.color?.light || "#FFFFFF"
4288
+ }
4289
+ };
4290
+ this.qrCodeDataUrl = await QRCode__default.default.toDataURL(this.config.requestUrl, qrCodeOptions);
4291
+ return this.qrCodeDataUrl;
4292
+ } catch (error) {
4293
+ throw new Error(`Failed to generate QR code: ${error instanceof Error ? error.message : String(error)}`);
4294
+ }
4295
+ }
4296
+ /**
4297
+ * 开始轮询签名结果
4298
+ */
4299
+ async startPolling(onStatusChange, onResult) {
4300
+ if (this.status === "success" /* SUCCESS */ && this.result?.signature) {
4301
+ return this.result.signature;
4302
+ }
4303
+ if (this.status === "cancelled" /* CANCELLED */ || this.status === "timeout" /* TIMEOUT */) {
4304
+ throw new SignatureRejectedError("Signature request was cancelled or timed out");
4305
+ }
4306
+ this.timeoutTimer = setTimeout(() => {
4307
+ this.stopPolling();
4308
+ this.status = "timeout" /* TIMEOUT */;
4309
+ onStatusChange?.(this.status);
4310
+ throw new SignatureRejectedError("Signature request timed out");
4311
+ }, this.config.timeout);
4312
+ return new Promise((resolve, reject) => {
4313
+ const poll = async () => {
4314
+ try {
4315
+ let result = null;
4316
+ if (this.config.pollFn) {
4317
+ result = await this.config.pollFn(this.config.requestId);
4318
+ } else if (this.config.pollUrl) {
4319
+ result = await this.defaultPoll(this.config.requestId);
4320
+ } else {
4321
+ return;
4322
+ }
4323
+ if (result?.completed) {
4324
+ this.stopPolling();
4325
+ this.result = result;
4326
+ if (result.signature) {
4327
+ this.status = "success" /* SUCCESS */;
4328
+ onStatusChange?.(this.status);
4329
+ onResult?.(result);
4330
+ resolve(result.signature);
4331
+ } else if (result.error) {
4332
+ this.status = "failed" /* FAILED */;
4333
+ onStatusChange?.(this.status);
4334
+ reject(new SignatureRejectedError(result.error));
4335
+ }
4336
+ } else if (result) {
4337
+ if (this.status === "waiting" /* WAITING */) {
4338
+ this.status = "pending" /* PENDING */;
4339
+ onStatusChange?.(this.status);
4340
+ }
4341
+ this.pollTimer = setTimeout(poll, this.config.pollInterval);
4342
+ } else {
4343
+ this.pollTimer = setTimeout(poll, this.config.pollInterval);
4344
+ }
4345
+ } catch (error) {
4346
+ this.stopPolling();
4347
+ this.status = "failed" /* FAILED */;
4348
+ onStatusChange?.(this.status);
4349
+ reject(error);
4350
+ }
4351
+ };
4352
+ poll();
4353
+ });
4354
+ }
4355
+ /**
4356
+ * 默认 HTTP 轮询函数
4357
+ */
4358
+ async defaultPoll(requestId) {
4359
+ if (!this.config.pollUrl) {
4360
+ return null;
4361
+ }
4362
+ try {
4363
+ const url = `${this.config.pollUrl}?requestId=${encodeURIComponent(requestId)}`;
4364
+ const response = await fetch(url, {
4365
+ method: "GET",
4366
+ headers: {
4367
+ "Content-Type": "application/json"
4368
+ }
4369
+ });
4370
+ if (!response.ok) {
4371
+ if (response.status === 404) {
4372
+ return null;
4373
+ }
4374
+ throw new NetworkError(`Poll request failed: ${response.statusText}`);
4375
+ }
4376
+ const data = await response.json();
4377
+ return {
4378
+ completed: data.completed === true,
4379
+ signature: data.signature,
4380
+ error: data.error,
4381
+ signer: data.signer
4382
+ };
4383
+ } catch (error) {
4384
+ if (error instanceof NetworkError) {
4385
+ throw error;
4386
+ }
4387
+ return null;
4388
+ }
4389
+ }
4390
+ /**
4391
+ * 停止轮询
4392
+ */
4393
+ stopPolling() {
4394
+ if (this.pollTimer) {
4395
+ clearTimeout(this.pollTimer);
4396
+ this.pollTimer = null;
4397
+ }
4398
+ if (this.timeoutTimer) {
4399
+ clearTimeout(this.timeoutTimer);
4400
+ this.timeoutTimer = null;
4401
+ }
4402
+ }
4403
+ /**
4404
+ * 取消签名请求
4405
+ */
4406
+ cancel() {
4407
+ this.stopPolling();
4408
+ this.status = "cancelled" /* CANCELLED */;
4409
+ }
4410
+ /**
4411
+ * 获取当前状态
4412
+ */
4413
+ getStatus() {
4414
+ return this.status;
4415
+ }
4416
+ /**
4417
+ * 获取二维码 URL
4418
+ */
4419
+ getQRCodeUrl() {
4420
+ return this.config.requestUrl;
4421
+ }
4422
+ /**
4423
+ * 获取结果
4424
+ */
4425
+ getResult() {
4426
+ return this.result;
4427
+ }
4428
+ /**
4429
+ * 清理资源
4430
+ */
4431
+ cleanup() {
4432
+ this.stopPolling();
4433
+ this.qrCodeDataUrl = null;
4434
+ this.result = null;
4435
+ this.status = "waiting" /* WAITING */;
1602
4436
  }
1603
4437
  };
1604
4438
 
@@ -1617,9 +4451,15 @@ var WalletManager = class extends TypedEventEmitter {
1617
4451
  defaultTronChainId: config.defaultTronChainId ?? 195,
1618
4452
  walletConnectProjectId: config.walletConnectProjectId ?? ""
1619
4453
  };
1620
- this.registry = new AdapterRegistry();
4454
+ this.registry = new AdapterRegistry(this.config);
1621
4455
  }
1622
4456
  // ===== Connection Management =====
4457
+ /**
4458
+ * Check if adapter is registered for a wallet type
4459
+ */
4460
+ hasAdapter(type) {
4461
+ return this.registry.has(type);
4462
+ }
1623
4463
  /**
1624
4464
  * Connect primary wallet
1625
4465
  */
@@ -1686,7 +4526,7 @@ var WalletManager = class extends TypedEventEmitter {
1686
4526
  this.connectedWallets.delete(chainType);
1687
4527
  this.primaryWallet = null;
1688
4528
  if (this.config.enableStorage) {
1689
- this.saveToStorage();
4529
+ this.clearStorage();
1690
4530
  }
1691
4531
  this.emit("disconnected");
1692
4532
  }
@@ -1775,6 +4615,35 @@ var WalletManager = class extends TypedEventEmitter {
1775
4615
  }
1776
4616
  return adapter.signMessage(message);
1777
4617
  }
4618
+ /**
4619
+ * Create QR code signer for message signing
4620
+ *
4621
+ * This method creates a QR code signer that can be used to display a QR code
4622
+ * for users to scan with their wallet app to sign a message.
4623
+ *
4624
+ * @param message - Message to sign
4625
+ * @param config - QR code signer configuration
4626
+ * @returns QRCodeSigner instance
4627
+ *
4628
+ * @example
4629
+ * ```typescript
4630
+ * const signer = walletManager.createQRCodeSigner('Hello World', {
4631
+ * requestId: 'sign-123',
4632
+ * requestUrl: 'https://example.com/sign?requestId=sign-123&message=Hello%20World',
4633
+ * pollUrl: 'https://api.example.com/sign/status',
4634
+ * })
4635
+ *
4636
+ * const qrCodeUrl = await signer.generateQRCode()
4637
+ * const signature = await signer.startPolling()
4638
+ * ```
4639
+ */
4640
+ createQRCodeSigner(message, config) {
4641
+ return new QRCodeSigner({
4642
+ ...config,
4643
+ // Encode message in request URL if not already encoded
4644
+ requestUrl: config.requestUrl.includes(encodeURIComponent(message)) ? config.requestUrl : `${config.requestUrl}${config.requestUrl.includes("?") ? "&" : "?"}message=${encodeURIComponent(message)}`
4645
+ });
4646
+ }
1778
4647
  /**
1779
4648
  * Sign TypedData (EVM only)
1780
4649
  */
@@ -2085,6 +4954,29 @@ var WalletManager = class extends TypedEventEmitter {
2085
4954
  console.debug("Silent TronLink connection failed:", silentError);
2086
4955
  }
2087
4956
  }
4957
+ if (data.primaryWalletType === "walletconnect-tron" /* WALLETCONNECT_TRON */) {
4958
+ try {
4959
+ const wcAdapter = adapter;
4960
+ if (typeof wcAdapter.restoreSession === "function") {
4961
+ console.debug("[WalletManager] Attempting to restore WalletConnect Tron session...");
4962
+ const account2 = await wcAdapter.restoreSession(data.primaryChainId);
4963
+ if (account2) {
4964
+ console.debug("[WalletManager] WalletConnect Tron session restored successfully");
4965
+ this.setPrimaryWallet(adapter);
4966
+ this.connectedWallets.set(adapter.chainType, adapter);
4967
+ this.setupAdapterListeners(adapter, true);
4968
+ this.emit("accountChanged", account2);
4969
+ return account2;
4970
+ } else {
4971
+ console.debug("[WalletManager] No valid WalletConnect Tron session found");
4972
+ return null;
4973
+ }
4974
+ }
4975
+ } catch (restoreError) {
4976
+ console.debug("[WalletManager] WalletConnect Tron restore failed:", restoreError);
4977
+ return null;
4978
+ }
4979
+ }
2088
4980
  const account = await adapter.connect(data.primaryChainId);
2089
4981
  this.setPrimaryWallet(adapter);
2090
4982
  this.connectedWallets.set(adapter.chainType, adapter);
@@ -2132,44 +5024,44 @@ var WalletManager = class extends TypedEventEmitter {
2132
5024
  };
2133
5025
 
2134
5026
  // src/react/WalletContext.tsx
2135
- var WalletContext = React.createContext(null);
5027
+ var WalletContext = React2.createContext(null);
2136
5028
  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(() => {
5029
+ const [walletManager] = React2.useState(() => externalWalletManager || new WalletManager());
5030
+ const [account, setAccount] = React2.useState(null);
5031
+ const [connectedWallets, setConnectedWallets] = React2.useState([]);
5032
+ const [isRestoring, setIsRestoring] = React2.useState(true);
5033
+ const updateConnectedWallets = React2.useCallback(() => {
2142
5034
  setConnectedWallets(walletManager.getConnectedWallets());
2143
5035
  }, [walletManager]);
2144
- const connect = React.useCallback(async (type, chainId) => {
5036
+ const connect = React2.useCallback(async (type, chainId) => {
2145
5037
  const account2 = await walletManager.connect(type, chainId);
2146
5038
  setAccount(account2);
2147
5039
  updateConnectedWallets();
2148
5040
  return account2;
2149
5041
  }, [walletManager, updateConnectedWallets]);
2150
- const connectAdditional = React.useCallback(async (type, chainId) => {
5042
+ const connectAdditional = React2.useCallback(async (type, chainId) => {
2151
5043
  const account2 = await walletManager.connectAdditional(type, chainId);
2152
5044
  updateConnectedWallets();
2153
5045
  return account2;
2154
5046
  }, [walletManager, updateConnectedWallets]);
2155
- const disconnect = React.useCallback(async () => {
5047
+ const disconnect = React2.useCallback(async () => {
2156
5048
  await walletManager.disconnect();
2157
5049
  setAccount(null);
2158
5050
  updateConnectedWallets();
2159
5051
  }, [walletManager, updateConnectedWallets]);
2160
- const switchPrimaryWallet = React.useCallback(async (chainType) => {
5052
+ const switchPrimaryWallet = React2.useCallback(async (chainType) => {
2161
5053
  const account2 = await walletManager.switchPrimaryWallet(chainType);
2162
5054
  setAccount(account2);
2163
5055
  updateConnectedWallets();
2164
5056
  return account2;
2165
5057
  }, [walletManager, updateConnectedWallets]);
2166
- const signMessage = React.useCallback(async (message) => {
5058
+ const signMessage = React2.useCallback(async (message) => {
2167
5059
  return walletManager.signMessage(message);
2168
5060
  }, [walletManager]);
2169
- const signTransaction = React.useCallback(async (transaction) => {
5061
+ const signTransaction = React2.useCallback(async (transaction) => {
2170
5062
  return walletManager.signTransaction(transaction);
2171
5063
  }, [walletManager]);
2172
- React.useEffect(() => {
5064
+ React2.useEffect(() => {
2173
5065
  const restoreConnection = async () => {
2174
5066
  try {
2175
5067
  const restoredAccount = await walletManager.restoreFromStorage();
@@ -2185,7 +5077,7 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
2185
5077
  };
2186
5078
  restoreConnection();
2187
5079
  }, [walletManager, updateConnectedWallets]);
2188
- React.useEffect(() => {
5080
+ React2.useEffect(() => {
2189
5081
  const handleAccountChanged = (newAccount) => {
2190
5082
  setAccount(newAccount);
2191
5083
  updateConnectedWallets();
@@ -2233,10 +5125,10 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
2233
5125
  signMessage,
2234
5126
  signTransaction
2235
5127
  };
2236
- return /* @__PURE__ */ React__default.default.createElement(WalletContext.Provider, { value }, children);
5128
+ return /* @__PURE__ */ React2__default.default.createElement(WalletContext.Provider, { value }, children);
2237
5129
  }
2238
5130
  function useWallet() {
2239
- const context = React.useContext(WalletContext);
5131
+ const context = React2.useContext(WalletContext);
2240
5132
  if (!context) {
2241
5133
  throw new Error("useWallet must be used within a WalletProvider");
2242
5134
  }
@@ -2256,8 +5148,8 @@ function useAccount() {
2256
5148
  }
2257
5149
  function useConnect() {
2258
5150
  const { connect: contextConnect, connectAdditional: contextConnectAdditional } = useWallet();
2259
- const [isConnecting, setIsConnecting] = React.useState(false);
2260
- const [error, setError] = React.useState(null);
5151
+ const [isConnecting, setIsConnecting] = React2.useState(false);
5152
+ const [error, setError] = React2.useState(null);
2261
5153
  const connect = async (type, chainId) => {
2262
5154
  setIsConnecting(true);
2263
5155
  setError(null);
@@ -2295,8 +5187,8 @@ function useConnect() {
2295
5187
  }
2296
5188
  function useDisconnect() {
2297
5189
  const { disconnect: contextDisconnect } = useWallet();
2298
- const [isDisconnecting, setIsDisconnecting] = React.useState(false);
2299
- const [error, setError] = React.useState(null);
5190
+ const [isDisconnecting, setIsDisconnecting] = React2.useState(false);
5191
+ const [error, setError] = React2.useState(null);
2300
5192
  const disconnect = async () => {
2301
5193
  setIsDisconnecting(true);
2302
5194
  setError(null);
@@ -2318,8 +5210,8 @@ function useDisconnect() {
2318
5210
  }
2319
5211
  function useSignMessage() {
2320
5212
  const { signMessage: contextSignMessage } = useWallet();
2321
- const [isSigning, setIsSigning] = React.useState(false);
2322
- const [error, setError] = React.useState(null);
5213
+ const [isSigning, setIsSigning] = React2.useState(false);
5214
+ const [error, setError] = React2.useState(null);
2323
5215
  const signMessage = async (message) => {
2324
5216
  setIsSigning(true);
2325
5217
  setError(null);
@@ -2342,8 +5234,8 @@ function useSignMessage() {
2342
5234
  }
2343
5235
  function useSignTransaction() {
2344
5236
  const { signTransaction: contextSignTransaction } = useWallet();
2345
- const [isSigning, setIsSigning] = React.useState(false);
2346
- const [error, setError] = React.useState(null);
5237
+ const [isSigning, setIsSigning] = React2.useState(false);
5238
+ const [error, setError] = React2.useState(null);
2347
5239
  const signTransaction = async (transaction) => {
2348
5240
  setIsSigning(true);
2349
5241
  setError(null);
@@ -2364,11 +5256,381 @@ function useSignTransaction() {
2364
5256
  error
2365
5257
  };
2366
5258
  }
5259
+ function useQRCodeSigner(config) {
5260
+ const [qrCodeDataUrl, setQrCodeDataUrl] = React2.useState(null);
5261
+ const [status, setStatus] = React2.useState("waiting" /* WAITING */);
5262
+ const [result, setResult] = React2.useState(null);
5263
+ const [isPolling, setIsPolling] = React2.useState(false);
5264
+ const [error, setError] = React2.useState(null);
5265
+ const signerRef = React2.useRef(null);
5266
+ React2.useEffect(() => {
5267
+ signerRef.current = new QRCodeSigner(config);
5268
+ return () => {
5269
+ signerRef.current?.cleanup();
5270
+ };
5271
+ }, [config.requestId, config.requestUrl, config.pollUrl]);
5272
+ const generateQRCode = React2.useCallback(async () => {
5273
+ if (!signerRef.current) return;
5274
+ try {
5275
+ const dataUrl = await signerRef.current.generateQRCode();
5276
+ setQrCodeDataUrl(dataUrl);
5277
+ } catch (err) {
5278
+ const error2 = err instanceof Error ? err : new Error(String(err));
5279
+ setError(error2);
5280
+ }
5281
+ }, []);
5282
+ const startSign = React2.useCallback(async () => {
5283
+ if (!signerRef.current) {
5284
+ throw new Error("QRCodeSigner not initialized");
5285
+ }
5286
+ setError(null);
5287
+ setStatus("waiting" /* WAITING */);
5288
+ setIsPolling(true);
5289
+ try {
5290
+ await generateQRCode();
5291
+ const signature = await signerRef.current.startPolling(
5292
+ (newStatus) => {
5293
+ setStatus(newStatus);
5294
+ },
5295
+ (signResult) => {
5296
+ setResult(signResult);
5297
+ }
5298
+ );
5299
+ setIsPolling(false);
5300
+ return signature;
5301
+ } catch (err) {
5302
+ setIsPolling(false);
5303
+ const error2 = err instanceof Error ? err : new SignatureRejectedError(err instanceof Error ? err.message : String(err));
5304
+ setError(error2);
5305
+ throw error2;
5306
+ }
5307
+ }, [generateQRCode]);
5308
+ const stopPolling = React2.useCallback(() => {
5309
+ signerRef.current?.stopPolling();
5310
+ setIsPolling(false);
5311
+ }, []);
5312
+ const cancel = React2.useCallback(() => {
5313
+ signerRef.current?.cancel();
5314
+ setStatus("cancelled" /* CANCELLED */);
5315
+ setIsPolling(false);
5316
+ }, []);
5317
+ return {
5318
+ qrCodeDataUrl,
5319
+ status,
5320
+ result,
5321
+ isPolling,
5322
+ startSign,
5323
+ stopPolling,
5324
+ cancel,
5325
+ error
5326
+ };
5327
+ }
5328
+ function QRCodeModal({
5329
+ isOpen,
5330
+ onClose,
5331
+ qrCodeDataUrl,
5332
+ status,
5333
+ error,
5334
+ title = "\u626B\u7801\u7B7E\u540D",
5335
+ description
5336
+ }) {
5337
+ React2.useEffect(() => {
5338
+ if (isOpen) {
5339
+ document.body.style.overflow = "hidden";
5340
+ } else {
5341
+ document.body.style.overflow = "";
5342
+ }
5343
+ return () => {
5344
+ document.body.style.overflow = "";
5345
+ };
5346
+ }, [isOpen]);
5347
+ if (!isOpen) {
5348
+ return null;
5349
+ }
5350
+ const getStatusText = () => {
5351
+ switch (status) {
5352
+ case "waiting" /* WAITING */:
5353
+ return "\u8BF7\u4F7F\u7528\u94B1\u5305\u626B\u63CF\u4E8C\u7EF4\u7801";
5354
+ case "pending" /* PENDING */:
5355
+ return "\u5DF2\u626B\u63CF\uFF0C\u8BF7\u5728\u94B1\u5305\u4E2D\u786E\u8BA4\u7B7E\u540D";
5356
+ case "success" /* SUCCESS */:
5357
+ return "\u7B7E\u540D\u6210\u529F";
5358
+ case "failed" /* FAILED */:
5359
+ return "\u7B7E\u540D\u5931\u8D25";
5360
+ case "timeout" /* TIMEOUT */:
5361
+ return "\u7B7E\u540D\u8D85\u65F6";
5362
+ case "cancelled" /* CANCELLED */:
5363
+ return "\u5DF2\u53D6\u6D88";
5364
+ default:
5365
+ return "\u7B49\u5F85\u626B\u63CF";
5366
+ }
5367
+ };
5368
+ const getStatusColor = () => {
5369
+ switch (status) {
5370
+ case "waiting" /* WAITING */:
5371
+ case "pending" /* PENDING */:
5372
+ return "#3b82f6";
5373
+ // blue
5374
+ case "success" /* SUCCESS */:
5375
+ return "#10b981";
5376
+ // green
5377
+ case "failed" /* FAILED */:
5378
+ case "timeout" /* TIMEOUT */:
5379
+ case "cancelled" /* CANCELLED */:
5380
+ return "#ef4444";
5381
+ // red
5382
+ default:
5383
+ return "#6b7280";
5384
+ }
5385
+ };
5386
+ return /* @__PURE__ */ React2__default.default.createElement(
5387
+ "div",
5388
+ {
5389
+ style: {
5390
+ position: "fixed",
5391
+ top: 0,
5392
+ left: 0,
5393
+ right: 0,
5394
+ bottom: 0,
5395
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
5396
+ display: "flex",
5397
+ alignItems: "center",
5398
+ justifyContent: "center",
5399
+ zIndex: 1e4,
5400
+ padding: "20px"
5401
+ },
5402
+ onClick: (e) => {
5403
+ if (e.target === e.currentTarget) {
5404
+ onClose();
5405
+ }
5406
+ }
5407
+ },
5408
+ /* @__PURE__ */ React2__default.default.createElement(
5409
+ "div",
5410
+ {
5411
+ style: {
5412
+ backgroundColor: "#ffffff",
5413
+ borderRadius: "12px",
5414
+ padding: "24px",
5415
+ maxWidth: "400px",
5416
+ width: "100%",
5417
+ boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"
5418
+ }
5419
+ },
5420
+ /* @__PURE__ */ React2__default.default.createElement(
5421
+ "div",
5422
+ {
5423
+ style: {
5424
+ display: "flex",
5425
+ justifyContent: "space-between",
5426
+ alignItems: "center",
5427
+ marginBottom: "20px"
5428
+ }
5429
+ },
5430
+ /* @__PURE__ */ React2__default.default.createElement(
5431
+ "h2",
5432
+ {
5433
+ style: {
5434
+ margin: 0,
5435
+ fontSize: "20px",
5436
+ fontWeight: 600,
5437
+ color: "#111827"
5438
+ }
5439
+ },
5440
+ title
5441
+ ),
5442
+ /* @__PURE__ */ React2__default.default.createElement(
5443
+ "button",
5444
+ {
5445
+ onClick: onClose,
5446
+ style: {
5447
+ background: "none",
5448
+ border: "none",
5449
+ fontSize: "24px",
5450
+ cursor: "pointer",
5451
+ color: "#6b7280",
5452
+ padding: 0,
5453
+ width: "24px",
5454
+ height: "24px",
5455
+ display: "flex",
5456
+ alignItems: "center",
5457
+ justifyContent: "center"
5458
+ }
5459
+ },
5460
+ "\xD7"
5461
+ )
5462
+ ),
5463
+ description && /* @__PURE__ */ React2__default.default.createElement(
5464
+ "p",
5465
+ {
5466
+ style: {
5467
+ margin: "0 0 20px 0",
5468
+ fontSize: "14px",
5469
+ color: "#6b7280"
5470
+ }
5471
+ },
5472
+ description
5473
+ ),
5474
+ /* @__PURE__ */ React2__default.default.createElement(
5475
+ "div",
5476
+ {
5477
+ style: {
5478
+ display: "flex",
5479
+ justifyContent: "center",
5480
+ marginBottom: "20px"
5481
+ }
5482
+ },
5483
+ qrCodeDataUrl ? /* @__PURE__ */ React2__default.default.createElement(
5484
+ "img",
5485
+ {
5486
+ src: qrCodeDataUrl,
5487
+ alt: "QR Code",
5488
+ style: {
5489
+ width: "100%",
5490
+ maxWidth: "300px",
5491
+ height: "auto",
5492
+ border: "1px solid #e5e7eb",
5493
+ borderRadius: "8px"
5494
+ }
5495
+ }
5496
+ ) : /* @__PURE__ */ React2__default.default.createElement(
5497
+ "div",
5498
+ {
5499
+ style: {
5500
+ width: "300px",
5501
+ height: "300px",
5502
+ backgroundColor: "#f3f4f6",
5503
+ display: "flex",
5504
+ alignItems: "center",
5505
+ justifyContent: "center",
5506
+ borderRadius: "8px",
5507
+ color: "#6b7280"
5508
+ }
5509
+ },
5510
+ "\u751F\u6210\u4E8C\u7EF4\u7801\u4E2D..."
5511
+ )
5512
+ ),
5513
+ /* @__PURE__ */ React2__default.default.createElement(
5514
+ "div",
5515
+ {
5516
+ style: {
5517
+ textAlign: "center",
5518
+ marginBottom: "20px"
5519
+ }
5520
+ },
5521
+ /* @__PURE__ */ React2__default.default.createElement(
5522
+ "div",
5523
+ {
5524
+ style: {
5525
+ display: "inline-flex",
5526
+ alignItems: "center",
5527
+ gap: "8px",
5528
+ padding: "8px 16px",
5529
+ borderRadius: "6px",
5530
+ backgroundColor: `${getStatusColor()}15`,
5531
+ color: getStatusColor(),
5532
+ fontSize: "14px",
5533
+ fontWeight: 500
5534
+ }
5535
+ },
5536
+ status === "waiting" /* WAITING */ && /* @__PURE__ */ React2__default.default.createElement(
5537
+ "div",
5538
+ {
5539
+ style: {
5540
+ width: "8px",
5541
+ height: "8px",
5542
+ borderRadius: "50%",
5543
+ backgroundColor: getStatusColor(),
5544
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
5545
+ }
5546
+ }
5547
+ ),
5548
+ status === "pending" /* PENDING */ && /* @__PURE__ */ React2__default.default.createElement(
5549
+ "div",
5550
+ {
5551
+ style: {
5552
+ width: "8px",
5553
+ height: "8px",
5554
+ borderRadius: "50%",
5555
+ backgroundColor: getStatusColor()
5556
+ }
5557
+ }
5558
+ ),
5559
+ status === "success" /* SUCCESS */ && "\u2713",
5560
+ status === "failed" /* FAILED */ && "\u2715",
5561
+ getStatusText()
5562
+ )
5563
+ ),
5564
+ error && /* @__PURE__ */ React2__default.default.createElement(
5565
+ "div",
5566
+ {
5567
+ style: {
5568
+ padding: "12px",
5569
+ backgroundColor: "#fef2f2",
5570
+ border: "1px solid #fecaca",
5571
+ borderRadius: "6px",
5572
+ marginBottom: "20px"
5573
+ }
5574
+ },
5575
+ /* @__PURE__ */ React2__default.default.createElement(
5576
+ "p",
5577
+ {
5578
+ style: {
5579
+ margin: 0,
5580
+ fontSize: "14px",
5581
+ color: "#dc2626"
5582
+ }
5583
+ },
5584
+ error.message
5585
+ )
5586
+ ),
5587
+ /* @__PURE__ */ React2__default.default.createElement(
5588
+ "div",
5589
+ {
5590
+ style: {
5591
+ display: "flex",
5592
+ gap: "12px"
5593
+ }
5594
+ },
5595
+ /* @__PURE__ */ React2__default.default.createElement(
5596
+ "button",
5597
+ {
5598
+ onClick: onClose,
5599
+ style: {
5600
+ flex: 1,
5601
+ padding: "10px 20px",
5602
+ border: "1px solid #d1d5db",
5603
+ borderRadius: "6px",
5604
+ backgroundColor: "#ffffff",
5605
+ color: "#374151",
5606
+ fontSize: "14px",
5607
+ fontWeight: 500,
5608
+ cursor: "pointer"
5609
+ }
5610
+ },
5611
+ status === "success" /* SUCCESS */ ? "\u5173\u95ED" : "\u53D6\u6D88"
5612
+ )
5613
+ )
5614
+ ),
5615
+ /* @__PURE__ */ React2__default.default.createElement("style", null, `
5616
+ @keyframes pulse {
5617
+ 0%, 100% {
5618
+ opacity: 1;
5619
+ }
5620
+ 50% {
5621
+ opacity: 0.5;
5622
+ }
5623
+ }
5624
+ `)
5625
+ );
5626
+ }
2367
5627
 
5628
+ exports.QRCodeModal = QRCodeModal;
2368
5629
  exports.WalletProvider = WalletProvider;
2369
5630
  exports.useAccount = useAccount;
2370
5631
  exports.useConnect = useConnect;
2371
5632
  exports.useDisconnect = useDisconnect;
5633
+ exports.useQRCodeSigner = useQRCodeSigner;
2372
5634
  exports.useSignMessage = useSignMessage;
2373
5635
  exports.useSignTransaction = useSignTransaction;
2374
5636
  exports.useWallet = useWallet;