@enclave-hq/wallet-sdk 1.2.4 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7,9 +7,12 @@ var EventEmitter = require('eventemitter3');
7
7
  var viem = require('viem');
8
8
  var accounts = require('viem/accounts');
9
9
  var EthereumProvider = require('@walletconnect/ethereum-provider');
10
- var walletconnectTron = require('@tronweb3/walletconnect-tron');
10
+ var module$1 = require('module');
11
+ var path = require('path');
12
+ var url = require('url');
11
13
  var QRCode = require('qrcode');
12
14
 
15
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
13
16
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
17
 
15
18
  var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
@@ -919,7 +922,12 @@ var CHAIN_INFO = {
919
922
  symbol: "ETH",
920
923
  decimals: 18
921
924
  },
922
- rpcUrls: ["https://eth.llamarpc.com"],
925
+ // 使用支持浏览器 CORS 的公共 RPC,避免 dapp 域名被跨域拦截(如 eth.llamarpc.com 无 CORS 头)
926
+ rpcUrls: [
927
+ "https://cloudflare-eth.com",
928
+ "https://rpc.ankr.com/eth",
929
+ "https://eth.llamarpc.com"
930
+ ],
923
931
  blockExplorerUrls: ["https://etherscan.io"]
924
932
  },
925
933
  // EVM Testnets
@@ -1327,6 +1335,56 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
1327
1335
  }]
1328
1336
  });
1329
1337
  }
1338
+ /**
1339
+ * 请求切换账户
1340
+ * 弹出 MetaMask 账户选择界面,让用户选择或切换到目标地址
1341
+ * @param targetAddress 目标地址(可选),如果提供,会在切换后验证是否匹配
1342
+ * @returns 切换后的账户信息
1343
+ */
1344
+ async requestSwitchAccount(targetAddress) {
1345
+ const provider = this.getBrowserProvider();
1346
+ if (!provider) {
1347
+ throw new Error("MetaMask provider not available");
1348
+ }
1349
+ try {
1350
+ await provider.request({
1351
+ method: "wallet_requestPermissions",
1352
+ params: [{ eth_accounts: {} }]
1353
+ });
1354
+ const accounts = await provider.request({
1355
+ method: "eth_accounts"
1356
+ });
1357
+ if (!accounts || accounts.length === 0) {
1358
+ throw new ConnectionRejectedError(this.type);
1359
+ }
1360
+ const address = formatEVMAddress(accounts[0]);
1361
+ if (targetAddress && address.toLowerCase() !== targetAddress.toLowerCase()) {
1362
+ throw new Error(`\u8BF7\u5728 MetaMask \u4E2D\u9009\u62E9\u5730\u5740 ${targetAddress.slice(0, 6)}...${targetAddress.slice(-4)}\uFF0C\u5F53\u524D\u9009\u62E9\u7684\u662F ${address.slice(0, 6)}...${address.slice(-4)}`);
1363
+ }
1364
+ const chainId = this.currentAccount?.chainId || 1;
1365
+ const account = {
1366
+ universalAddress: createUniversalAddress(chainId, address),
1367
+ nativeAddress: address,
1368
+ chainId,
1369
+ chainType: exports.ChainType.EVM,
1370
+ isActive: true
1371
+ };
1372
+ this.setAccount(account);
1373
+ this.emitAccountChanged(account);
1374
+ const viemChain = this.getViemChain(chainId);
1375
+ this.walletClient = viem.createWalletClient({
1376
+ account: address,
1377
+ chain: viemChain,
1378
+ transport: viem.custom(provider)
1379
+ });
1380
+ return account;
1381
+ } catch (error) {
1382
+ if (error.code === 4001) {
1383
+ throw new ConnectionRejectedError(this.type);
1384
+ }
1385
+ throw error;
1386
+ }
1387
+ }
1330
1388
  /**
1331
1389
  * 读取合约
1332
1390
  */
@@ -1552,6 +1610,46 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
1552
1610
 
1553
1611
  // src/adapters/tron/tronlink.ts
1554
1612
  init_types();
1613
+ var TronApiRateLimiter = class {
1614
+ constructor(minIntervalMs = 600) {
1615
+ this.lastCallTime = 0;
1616
+ this.minInterval = minIntervalMs;
1617
+ }
1618
+ /**
1619
+ * 等待直到可以进行下一次 API 调用
1620
+ */
1621
+ async waitForNextCall() {
1622
+ const now = Date.now();
1623
+ const timeSinceLastCall = now - this.lastCallTime;
1624
+ if (timeSinceLastCall < this.minInterval) {
1625
+ const waitTime = this.minInterval - timeSinceLastCall;
1626
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
1627
+ }
1628
+ this.lastCallTime = Date.now();
1629
+ }
1630
+ };
1631
+ var tronApiRateLimiter = new TronApiRateLimiter(600);
1632
+ async function retryWithBackoff(fn, maxRetries = 3, initialDelay = 500) {
1633
+ let lastError;
1634
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
1635
+ try {
1636
+ return await fn();
1637
+ } catch (error) {
1638
+ lastError = error;
1639
+ const errorMsg = error?.message || String(error);
1640
+ const errorLower = errorMsg.toLowerCase();
1641
+ const isRateLimitError = error?.response?.status === 429 || error?.status === 429 || errorLower.includes("429") || errorLower.includes("rate limit") || errorLower.includes("too many requests") || error?.code === "ERR_BAD_REQUEST" && error?.response?.status === 429;
1642
+ if (isRateLimitError && attempt < maxRetries - 1) {
1643
+ const delay = initialDelay * Math.pow(2, attempt);
1644
+ console.warn(`[TronLink] \u9047\u5230\u901F\u7387\u9650\u5236 (429)\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5 (${attempt + 1}/${maxRetries})...`);
1645
+ await new Promise((resolve) => setTimeout(resolve, delay));
1646
+ continue;
1647
+ }
1648
+ throw error;
1649
+ }
1650
+ }
1651
+ throw lastError;
1652
+ }
1555
1653
  var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1556
1654
  constructor() {
1557
1655
  super(...arguments);
@@ -1729,10 +1827,12 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1729
1827
  /**
1730
1828
  * 读取合约
1731
1829
  * 参考 webserver 的实现,使用 TronWeb 合约实例的标准 call() 方法
1830
+ * 带 TronGrid 限流 + 429 重试
1732
1831
  */
1733
1832
  async readContract(params) {
1734
1833
  this.ensureConnected();
1735
- try {
1834
+ await tronApiRateLimiter.waitForNextCall();
1835
+ const doRead = async () => {
1736
1836
  const tronWeb = this.getTronWeb();
1737
1837
  if (!this.currentAccount) {
1738
1838
  throw new Error("No account connected");
@@ -1747,19 +1847,17 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1747
1847
  return result;
1748
1848
  } catch (method1Error) {
1749
1849
  console.warn("\u26A0\uFE0F [\u65B9\u6CD51] TronWeb\u6807\u51C6\u65B9\u6CD5\u5931\u8D25\uFF0C\u5C1D\u8BD5\u65B9\u6CD52:", method1Error.message);
1750
- try {
1751
- const contract2 = await tronWeb.contract().at(params.address);
1752
- const method2 = contract2[params.functionName];
1753
- if (!method2 || typeof method2 !== "function") {
1754
- throw new Error(`Function ${params.functionName} not found in contract`);
1755
- }
1756
- const result = await method2(...params.args || []).call();
1757
- return result;
1758
- } catch (method2Error) {
1759
- console.error("\u26A0\uFE0F [\u65B9\u6CD52] \u4E5F\u5931\u8D25:", method2Error.message);
1760
- throw method1Error;
1850
+ const contract2 = await tronWeb.contract().at(params.address);
1851
+ const method2 = contract2[params.functionName];
1852
+ if (!method2 || typeof method2 !== "function") {
1853
+ throw new Error(`Function ${params.functionName} not found in contract`);
1761
1854
  }
1855
+ const result = await method2(...params.args || []).call();
1856
+ return result;
1762
1857
  }
1858
+ };
1859
+ try {
1860
+ return await retryWithBackoff(doRead, 3, 800);
1763
1861
  } catch (error) {
1764
1862
  console.error("Read contract error:", error);
1765
1863
  throw new Error(`Failed to read contract: ${error.message || "Unknown error"}`);
@@ -1770,6 +1868,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1770
1868
  */
1771
1869
  async writeContract(params) {
1772
1870
  this.ensureConnected();
1871
+ await tronApiRateLimiter.waitForNextCall();
1773
1872
  try {
1774
1873
  const tronWeb = this.getTronWeb();
1775
1874
  console.log("[TronLink] writeContract params:", {
@@ -1795,29 +1894,171 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1795
1894
  }
1796
1895
  console.log("[TronLink] Function ABI:", functionAbi);
1797
1896
  console.log("[TronLink] Calling with args:", params.args);
1897
+ const TRON_FEE_LIMIT = 1e8;
1798
1898
  const options = {
1799
- feeLimit: params.gas || 1e8,
1800
- // 默认 100 TRX 的能量限制
1899
+ feeLimit: TRON_FEE_LIMIT,
1900
+ // 固定为 100 TRX 的能量限制
1801
1901
  callValue: params.value || 0
1802
1902
  // 发送的 TRX 数量(单位:SUN)
1803
1903
  };
1804
- const parameter = functionAbi.inputs.map((input, index) => ({
1805
- type: input.type,
1806
- value: params.args[index]
1807
- }));
1808
- console.log("[TronLink] Transaction options:", options);
1809
- console.log("[TronLink] Parameters:", parameter);
1810
- const functionSelector = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
1811
- console.log("[TronLink] Function selector:", functionSelector);
1812
- console.log("[TronLink] Transaction options:", options);
1813
- console.log("[TronLink] Parameters:", parameter);
1814
- const tx = await tronWeb.transactionBuilder.triggerSmartContract(
1815
- params.address,
1816
- functionSelector,
1817
- options,
1818
- parameter,
1819
- this.currentAccount.nativeAddress
1820
- );
1904
+ const hasTupleArray = functionAbi.inputs.some((input) => input.type === "tuple[]");
1905
+ console.log("[TronLink] \u68C0\u67E5 tuple[] \u7C7B\u578B:", {
1906
+ hasTupleArray,
1907
+ inputs: functionAbi.inputs.map((i) => ({ name: i.name, type: i.type }))
1908
+ });
1909
+ let tx;
1910
+ if (hasTupleArray) {
1911
+ console.log("[TronLink] \u68C0\u6D4B\u5230 tuple[] \u53C2\u6570\uFF0C\u4F7F\u7528\u624B\u52A8\u7F16\u7801\u65B9\u5F0F");
1912
+ const processedArgs = params.args.map((argValue, index) => {
1913
+ const input = functionAbi.inputs[index];
1914
+ if (input.type === "address" && typeof argValue === "string") {
1915
+ if (argValue.startsWith("T") && argValue.length === 34) {
1916
+ const hexAddress = tronWeb.address.toHex(argValue);
1917
+ return hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1918
+ }
1919
+ return argValue.startsWith("0x") ? argValue : `0x${argValue}`;
1920
+ }
1921
+ if (input.type === "tuple[]" && Array.isArray(argValue)) {
1922
+ return argValue.map((tupleItem) => {
1923
+ if (input.components && Array.isArray(input.components)) {
1924
+ const processedTuple = {};
1925
+ input.components.forEach((component) => {
1926
+ let value = tupleItem[component.name];
1927
+ if (component.type === "address" && typeof value === "string") {
1928
+ if (value.startsWith("T") && value.length === 34) {
1929
+ const hexAddress = tronWeb.address.toHex(value);
1930
+ value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1931
+ } else if (!value.startsWith("0x")) {
1932
+ value = `0x${value}`;
1933
+ }
1934
+ }
1935
+ processedTuple[component.name] = value;
1936
+ });
1937
+ return processedTuple;
1938
+ }
1939
+ return tupleItem;
1940
+ });
1941
+ }
1942
+ if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
1943
+ if (input.components && Array.isArray(input.components)) {
1944
+ const processedTuple = {};
1945
+ input.components.forEach((component) => {
1946
+ let value = argValue[component.name];
1947
+ if (component.type === "address" && typeof value === "string") {
1948
+ if (value.startsWith("T") && value.length === 34) {
1949
+ const hexAddress = tronWeb.address.toHex(value);
1950
+ value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
1951
+ } else if (!value.startsWith("0x")) {
1952
+ value = `0x${value}`;
1953
+ }
1954
+ }
1955
+ processedTuple[component.name] = value;
1956
+ });
1957
+ return processedTuple;
1958
+ }
1959
+ }
1960
+ return argValue;
1961
+ });
1962
+ console.log("[TronLink] \u5904\u7406\u540E\u7684\u53C2\u6570\uFF08\u7528\u4E8E viem \u7F16\u7801\uFF09:", processedArgs);
1963
+ const encodedData = viem.encodeFunctionData({
1964
+ abi: [functionAbi],
1965
+ functionName: params.functionName,
1966
+ args: processedArgs
1967
+ });
1968
+ console.log("[TronLink] \u7F16\u7801\u540E\u7684\u6570\u636E:", encodedData);
1969
+ const functionSelector = encodedData.slice(0, 10);
1970
+ const parameterData = encodedData.slice(10);
1971
+ console.log("[TronLink] \u51FD\u6570\u9009\u62E9\u5668:", functionSelector);
1972
+ console.log("[TronLink] \u53C2\u6570\u6570\u636E:", parameterData);
1973
+ const functionSignature = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
1974
+ const parameterHexClean = parameterData.startsWith("0x") ? parameterData.slice(2) : parameterData;
1975
+ console.log("[TronLink] \u4F7F\u7528 TronWeb triggerSmartContract (rawParameter)...", {
1976
+ contractAddress: params.address,
1977
+ functionSelector: functionSignature,
1978
+ encodedDataLength: parameterHexClean.length
1979
+ });
1980
+ tx = await retryWithBackoff(
1981
+ () => tronWeb.transactionBuilder.triggerSmartContract(
1982
+ params.address,
1983
+ // Base58 格式的合约地址
1984
+ functionSignature,
1985
+ // 函数签名(用于识别函数)
1986
+ {
1987
+ feeLimit: options.feeLimit,
1988
+ callValue: options.callValue,
1989
+ rawParameter: parameterHexClean
1990
+ // 使用 rawParameter 直接提供编码后的数据
1991
+ },
1992
+ [],
1993
+ // parameter 留空(因为使用 rawParameter)
1994
+ this.currentAccount.nativeAddress
1995
+ // Base58 格式的发送地址
1996
+ ),
1997
+ 3,
1998
+ // 最多重试 3 次
1999
+ 500
2000
+ // 初始延迟 500ms
2001
+ );
2002
+ console.log("[TronLink] \u4F7F\u7528 TronWeb API \u6784\u5EFA\u7684\u4EA4\u6613:", tx);
2003
+ } else {
2004
+ const parameter = functionAbi.inputs.map((input, index) => {
2005
+ const argValue = params.args[index];
2006
+ if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
2007
+ if (input.components && Array.isArray(input.components)) {
2008
+ return {
2009
+ type: input.type,
2010
+ value: input.components.map((component) => ({
2011
+ type: component.type,
2012
+ value: argValue[component.name]
2013
+ }))
2014
+ };
2015
+ }
2016
+ }
2017
+ if (input.type === "address" && typeof argValue === "string") {
2018
+ if (argValue.startsWith("T") && argValue.length === 34) {
2019
+ return {
2020
+ type: input.type,
2021
+ value: argValue
2022
+ };
2023
+ }
2024
+ try {
2025
+ const base58Address = tronWeb.address.fromHex(argValue.startsWith("0x") ? argValue : `0x${argValue}`);
2026
+ return {
2027
+ type: input.type,
2028
+ value: base58Address
2029
+ };
2030
+ } catch (e) {
2031
+ return {
2032
+ type: input.type,
2033
+ value: argValue
2034
+ };
2035
+ }
2036
+ }
2037
+ return {
2038
+ type: input.type,
2039
+ value: argValue
2040
+ };
2041
+ });
2042
+ console.log("[TronLink] Transaction options:", options);
2043
+ console.log("[TronLink] Parameters:", parameter);
2044
+ const functionSelector = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
2045
+ console.log("[TronLink] Function selector:", functionSelector);
2046
+ console.log("[TronLink] Transaction options:", options);
2047
+ console.log("[TronLink] Parameters:", parameter);
2048
+ tx = await retryWithBackoff(
2049
+ () => tronWeb.transactionBuilder.triggerSmartContract(
2050
+ params.address,
2051
+ functionSelector,
2052
+ options,
2053
+ parameter,
2054
+ this.currentAccount.nativeAddress
2055
+ ),
2056
+ 3,
2057
+ // 最多重试 3 次
2058
+ 500
2059
+ // 初始延迟 500ms
2060
+ );
2061
+ }
1821
2062
  console.log("[TronLink] Transaction built:", tx);
1822
2063
  if (!tx || !tx.transaction) {
1823
2064
  throw new Error("Failed to build transaction");
@@ -1857,6 +2098,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
1857
2098
  const maxAttempts = 60;
1858
2099
  while (attempts < maxAttempts) {
1859
2100
  try {
2101
+ await tronApiRateLimiter.waitForNextCall();
1860
2102
  const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
1861
2103
  if (txInfo && txInfo.id) {
1862
2104
  const receipt = {
@@ -3274,697 +3516,12 @@ _WalletConnectAdapter.providerChains = null;
3274
3516
  _WalletConnectAdapter.isInitializing = false;
3275
3517
  _WalletConnectAdapter.initPromise = null;
3276
3518
  var WalletConnectAdapter = _WalletConnectAdapter;
3277
- init_types();
3278
- var _WalletConnectTronAdapter = class _WalletConnectTronAdapter extends WalletAdapter {
3279
- constructor(projectId) {
3280
- super();
3281
- this.type = "walletconnect-tron" /* WALLETCONNECT_TRON */;
3282
- this.chainType = exports.ChainType.TRON;
3283
- this.name = "WalletConnect (Tron)";
3284
- this.icon = "https://avatars.githubusercontent.com/u/37784886";
3285
- this.wallet = null;
3286
- this.currentAddress = null;
3287
- if (!projectId) {
3288
- throw new ConfigurationError("WalletConnect projectId is required");
3289
- }
3290
- this.projectId = projectId;
3291
- }
3292
- /**
3293
- * Check if WalletConnect is available
3294
- */
3295
- async isAvailable() {
3296
- return typeof window !== "undefined";
3297
- }
3298
- /**
3299
- * Check if running in Telegram environment (Mini App or Web)
3300
- * Both Telegram Mini App (in client) and Telegram Web (web.telegram.org)
3301
- * provide window.Telegram.WebApp API, so they are treated the same way.
3302
- */
3303
- isTelegramMiniApp() {
3304
- if (typeof window === "undefined") return false;
3305
- const tg = window.Telegram?.WebApp;
3306
- if (!tg) return false;
3307
- const platform = tg.platform || "unknown";
3308
- console.log("[WalletConnect Tron] Telegram environment detected:", {
3309
- platform,
3310
- version: tg.version,
3311
- isMiniApp: platform !== "web",
3312
- // Mini App if not web platform
3313
- isWeb: platform === "web"
3314
- // Telegram Web if web platform
3315
- });
3316
- return true;
3317
- }
3318
- /**
3319
- * Restore session from existing wallet (for storage restoration)
3320
- */
3321
- async restoreSession(chainId) {
3322
- if (typeof window === "undefined") {
3323
- return null;
3324
- }
3325
- try {
3326
- const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3327
- if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3328
- this.initializeWallet(targetChainId);
3329
- }
3330
- this.wallet = _WalletConnectTronAdapter.walletInstance;
3331
- if (!this.wallet) {
3332
- return null;
3333
- }
3334
- const status = await this.wallet.checkConnectStatus();
3335
- if (status && status.address) {
3336
- this.currentAddress = status.address;
3337
- const account = {
3338
- universalAddress: createUniversalAddress(targetChainId, status.address),
3339
- nativeAddress: status.address,
3340
- chainId: targetChainId,
3341
- chainType: exports.ChainType.TRON,
3342
- isActive: true
3343
- };
3344
- this.setState("connected" /* CONNECTED */);
3345
- this.setAccount(account);
3346
- this.setupEventListeners();
3347
- return account;
3348
- }
3349
- return null;
3350
- } catch (error) {
3351
- console.debug("[WalletConnect Tron] Restore session failed:", error);
3352
- return null;
3353
- }
3354
- }
3355
- /**
3356
- * Initialize WalletConnect wallet instance
3357
- * @param chainId - Optional chain ID to determine network (default: Mainnet)
3358
- */
3359
- initializeWallet(chainId) {
3360
- if (_WalletConnectTronAdapter.walletInstance && _WalletConnectTronAdapter.walletProjectId === this.projectId) {
3361
- return;
3362
- }
3363
- let appUrl = "";
3364
- if (typeof window !== "undefined") {
3365
- try {
3366
- if (window.location && window.location.origin) {
3367
- appUrl = window.location.origin;
3368
- } else if (window.location && window.location.href) {
3369
- const url = new URL(window.location.href);
3370
- appUrl = url.origin;
3371
- }
3372
- } catch (error) {
3373
- console.warn("[WalletConnect Tron] Failed to get origin from window.location:", error);
3374
- }
3375
- if (appUrl && (appUrl.includes("serveo.net") || appUrl.includes("loca.lt") || appUrl.includes("ngrok.io") || appUrl.includes("ngrok-free.app") || appUrl.includes("cloudflared.io"))) {
3376
- console.log("[WalletConnect Tron] Detected tunnel service URL:", appUrl);
3377
- console.log("[WalletConnect Tron] \u26A0\uFE0F Make sure this URL is added to WalletConnect Cloud project allowlist");
3378
- }
3379
- if (!appUrl) {
3380
- const tg = window.Telegram?.WebApp;
3381
- if (tg && tg.initDataUnsafe?.start_param) {
3382
- appUrl = "https://enclave.network";
3383
- } else {
3384
- appUrl = "https://enclave.network";
3385
- }
3386
- }
3387
- } else {
3388
- appUrl = "https://enclave.network";
3389
- }
3390
- if (!appUrl || !appUrl.startsWith("http://") && !appUrl.startsWith("https://")) {
3391
- appUrl = "https://enclave.network";
3392
- }
3393
- const icons = [
3394
- "https://walletconnect.com/walletconnect-logo.svg",
3395
- "https://avatars.githubusercontent.com/u/37784886"
3396
- // WalletConnect GitHub avatar
3397
- ];
3398
- let network = walletconnectTron.WalletConnectChainID.Mainnet;
3399
- if (chainId !== void 0) {
3400
- if (chainId === 195 || chainId === _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID) {
3401
- network = walletconnectTron.WalletConnectChainID.Mainnet;
3402
- } else if (chainId === 201910292) {
3403
- network = walletconnectTron.WalletConnectChainID.Shasta;
3404
- } else if (chainId === 2494104990) {
3405
- network = walletconnectTron.WalletConnectChainID.Nile;
3406
- }
3407
- }
3408
- const metadataInfo = {
3409
- name: "Enclave Wallet SDK",
3410
- description: "Multi-chain wallet adapter for Enclave",
3411
- url: appUrl,
3412
- icons,
3413
- network,
3414
- chainId,
3415
- isTelegram: this.isTelegramMiniApp(),
3416
- projectId: this.projectId,
3417
- urlValid: appUrl && (appUrl.startsWith("http://") || appUrl.startsWith("https://")),
3418
- iconsValid: icons && icons.length > 0 && icons.every((icon) => icon && icon.startsWith("http")),
3419
- currentLocation: typeof window !== "undefined" ? window.location.href : "N/A",
3420
- telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A"
3421
- };
3422
- console.log("[WalletConnect Tron] Initializing with metadata:", metadataInfo);
3423
- if (!metadataInfo.urlValid) {
3424
- console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid URL in metadata:", appUrl);
3425
- }
3426
- if (!metadataInfo.iconsValid) {
3427
- console.warn("[WalletConnect Tron] \u26A0\uFE0F Invalid icons in metadata:", icons);
3428
- }
3429
- console.log("[WalletConnect Tron] Initializing wallet...", {
3430
- network,
3431
- chainId,
3432
- note: "If no wallets are in WalletConnect Explorer for TRON, QR code will be displayed for scanning"
3433
- });
3434
- _WalletConnectTronAdapter.walletInstance = new walletconnectTron.WalletConnectWallet({
3435
- network,
3436
- options: {
3437
- projectId: this.projectId,
3438
- metadata: {
3439
- name: "Enclave Wallet SDK",
3440
- description: "Multi-chain wallet adapter for Enclave",
3441
- url: appUrl,
3442
- icons
3443
- }
3444
- },
3445
- // Theme configuration
3446
- themeMode: "light",
3447
- themeVariables: {
3448
- "--w3m-z-index": 1e4
3449
- // Ensure modal appears above Telegram UI
3450
- },
3451
- // Web3Modal configuration for recommended wallets
3452
- // According to official docs: https://developers.tron.network/docs/walletconnect-tron
3453
- // Note: If no wallets are registered in WalletConnect Explorer for TRON,
3454
- // explorerRecommendedWalletIds will have no effect, and QR code will be shown instead.
3455
- // @ts-ignore - web3ModalConfig is supported but may not be in TypeScript types
3456
- web3ModalConfig: {
3457
- themeMode: "light",
3458
- themeVariables: {
3459
- "--w3m-z-index": 1e4
3460
- },
3461
- /**
3462
- * Recommended Wallets are fetched from WalletConnect explore api:
3463
- * https://walletconnect.com/explorer?type=wallet&version=2
3464
- *
3465
- * IMPORTANT: If wallets are not registered in Explorer for TRON, this list will be ignored.
3466
- * The AppKit will show a QR code instead, which users can scan with any WalletConnect-compatible wallet.
3467
- *
3468
- * Wallet IDs (for reference, may not work if not in Explorer):
3469
- * - TokenPocket: 20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66
3470
- * - TronLink: 1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369
3471
- */
3472
- explorerRecommendedWalletIds: [
3473
- // These IDs are kept for when wallets register in WalletConnect Explorer
3474
- // Currently, if no TRON wallets are in Explorer, QR code will be shown
3475
- "20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66",
3476
- // TokenPocket
3477
- "1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
3478
- // TronLink
3479
- "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0"
3480
- // TokenPocket (backup)
3481
- ]
3482
- }
3483
- });
3484
- _WalletConnectTronAdapter.walletProjectId = this.projectId;
3485
- }
3486
- /**
3487
- * Connect wallet
3488
- */
3489
- async connect(chainId) {
3490
- if (typeof window === "undefined") {
3491
- throw new Error("WalletConnect requires a browser environment");
3492
- }
3493
- const currentState = this.state;
3494
- if (currentState === "connecting" /* CONNECTING */) {
3495
- console.warn("[WalletConnect Tron] Connection already in progress, waiting...");
3496
- let attempts = 0;
3497
- while (this.state === "connecting" /* CONNECTING */ && attempts < 50) {
3498
- await new Promise((resolve) => setTimeout(resolve, 100));
3499
- attempts++;
3500
- }
3501
- if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3502
- return this.currentAccount;
3503
- }
3504
- if (this.state === "connecting" /* CONNECTING */) {
3505
- throw new Error("Connection timeout - previous connection attempt is still pending");
3506
- }
3507
- }
3508
- if (this.state === "connected" /* CONNECTED */ && this.currentAccount) {
3509
- return this.currentAccount;
3510
- }
3511
- try {
3512
- this.setState("connecting" /* CONNECTING */);
3513
- const targetChainId = Array.isArray(chainId) ? chainId[0] || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID : chainId || _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID;
3514
- if (!_WalletConnectTronAdapter.walletInstance || _WalletConnectTronAdapter.walletProjectId !== this.projectId) {
3515
- this.initializeWallet(targetChainId);
3516
- }
3517
- this.wallet = _WalletConnectTronAdapter.walletInstance;
3518
- if (!this.wallet) {
3519
- throw new Error("Failed to initialize WalletConnect wallet");
3520
- }
3521
- let network = walletconnectTron.WalletConnectChainID.Mainnet;
3522
- if (targetChainId === 195) {
3523
- network = walletconnectTron.WalletConnectChainID.Mainnet;
3524
- } else if (targetChainId === 201910292) {
3525
- network = walletconnectTron.WalletConnectChainID.Shasta;
3526
- } else if (targetChainId === 2494104990) {
3527
- network = walletconnectTron.WalletConnectChainID.Nile;
3528
- }
3529
- let address;
3530
- try {
3531
- console.log("[WalletConnect Tron] Attempting to connect...", {
3532
- network,
3533
- chainId: targetChainId,
3534
- isTelegram: this.isTelegramMiniApp(),
3535
- projectId: this.projectId
3536
- });
3537
- const result = await this.wallet.connect();
3538
- address = result.address;
3539
- if (!address) {
3540
- throw new ConnectionRejectedError(this.type);
3541
- }
3542
- console.log("[WalletConnect Tron] Connection successful:", {
3543
- address,
3544
- network,
3545
- chainId: targetChainId,
3546
- isTelegram: this.isTelegramMiniApp()
3547
- });
3548
- } catch (error) {
3549
- const errorMessage = error.message || String(error);
3550
- const errorCode = error.code || error.error?.code;
3551
- const origin = typeof window !== "undefined" && window.location ? window.location.origin : "";
3552
- let detailedError = errorMessage;
3553
- if (error.error) {
3554
- if (typeof error.error === "string") {
3555
- detailedError = error.error;
3556
- } else if (error.error.message) {
3557
- detailedError = error.error.message;
3558
- } else if (error.error.data) {
3559
- detailedError = JSON.stringify(error.error.data);
3560
- }
3561
- }
3562
- 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");
3563
- const isTimeout = errorMessage.includes("timeout") || errorMessage.includes("\u8D85\u65F6") || errorCode === "TIMEOUT";
3564
- const isRejected = errorMessage.includes("rejected") || errorMessage.includes("\u62D2\u7EDD") || errorCode === 4001;
3565
- const isOriginNotAllowed = errorCode === 3e3 || /origin not allowed/i.test(errorMessage) || /Unauthorized:\s*origin not allowed/i.test(errorMessage);
3566
- const currentMetadata = this.wallet ? {
3567
- // Try to get metadata from wallet instance if available
3568
- projectId: this.projectId,
3569
- network
3570
- } : null;
3571
- const errorDetails = {
3572
- error: errorMessage,
3573
- detailedError,
3574
- code: errorCode,
3575
- isTelegram: this.isTelegramMiniApp(),
3576
- network,
3577
- chainId: targetChainId,
3578
- projectId: this.projectId,
3579
- metadata: currentMetadata,
3580
- // Get URL from window.location if available
3581
- currentUrl: typeof window !== "undefined" ? window.location.href : "N/A",
3582
- telegramPlatform: typeof window !== "undefined" && window.Telegram?.WebApp?.platform || "N/A",
3583
- errorType: isNoWalletFound ? "NO_WALLET_FOUND" : isTimeout ? "TIMEOUT" : isRejected ? "REJECTED" : "UNKNOWN"
3584
- };
3585
- console.error("[WalletConnect Tron] Connection error - Full details:", errorDetails);
3586
- console.error("[WalletConnect Tron] Error object:", error);
3587
- console.error("[WalletConnect Tron] Error stack:", error.stack);
3588
- if (isNoWalletFound) {
3589
- const noWalletErrorDetails = [
3590
- `
3591
- === WalletConnect Tron: No Matching Wallet Found ===`,
3592
- `Error: ${errorMessage}`,
3593
- `Detailed: ${detailedError}`,
3594
- `Code: ${errorCode || "N/A"}`,
3595
- ``,
3596
- `Environment:`,
3597
- ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3598
- ` - Platform: ${errorDetails.telegramPlatform}`,
3599
- ` - Current URL: ${errorDetails.currentUrl}`,
3600
- ``,
3601
- `Configuration:`,
3602
- ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3603
- ` - Network: ${network}`,
3604
- ` - Chain ID: ${targetChainId}`,
3605
- ` - Metadata URL: ${typeof window !== "undefined" ? window.location.origin : "N/A"}`,
3606
- ``,
3607
- `Possible Causes:`,
3608
- ` 1. No WalletConnect-compatible wallet (TokenPocket, etc.) installed on device`,
3609
- ` 2. Wallet app not opened or not responding to deep link (wc://)`,
3610
- ` 3. Deep link handling issue in Telegram Mini App environment`,
3611
- ` 4. WalletConnect session timeout (user took too long to approve)`,
3612
- ` 5. Network connectivity issue preventing WalletConnect relay connection`,
3613
- ``,
3614
- `Solutions:`,
3615
- ` 1. Ensure TokenPocket or other WalletConnect-compatible wallet is installed`,
3616
- ` 2. Try opening the wallet app manually before connecting`,
3617
- ` 3. In Telegram Mini App, ensure the deep link popup is not blocked`,
3618
- ` 4. Try connecting again (may need to wait a few seconds)`,
3619
- ` 5. Check network connection and WalletConnect relay server accessibility`,
3620
- ``,
3621
- `For more details, see the error object logged above.`,
3622
- `===========================================
3623
- `
3624
- ].join("\n");
3625
- console.error(noWalletErrorDetails);
3626
- throw new ConnectionRejectedError(
3627
- `WalletConnect Tron: \u6CA1\u6709\u627E\u5230\u652F\u6301\u7684\u94B1\u5305 (No matching wallet found)
3628
-
3629
- \u53EF\u80FD\u7684\u539F\u56E0\uFF1A
3630
- 1. \u8BBE\u5907\u4E0A\u672A\u5B89\u88C5\u652F\u6301 WalletConnect \u7684\u94B1\u5305\uFF08\u5982 TokenPocket\uFF09
3631
- 2. \u94B1\u5305\u5E94\u7528\u672A\u6253\u5F00\u6216\u672A\u54CD\u5E94 deep link (wc://)
3632
- 3. \u5728 Telegram Mini App \u4E2D\uFF0Cdeep link \u5904\u7406\u53EF\u80FD\u6709\u95EE\u9898
3633
- 4. \u8FDE\u63A5\u8D85\u65F6\uFF08\u7528\u6237\u672A\u53CA\u65F6\u6279\u51C6\uFF09
3634
- 5. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898
3635
-
3636
- \u89E3\u51B3\u65B9\u6848\uFF1A
3637
- 1. \u786E\u4FDD\u5DF2\u5B89\u88C5 TokenPocket \u6216\u5176\u4ED6\u652F\u6301 WalletConnect \u7684\u94B1\u5305
3638
- 2. \u5C1D\u8BD5\u624B\u52A8\u6253\u5F00\u94B1\u5305\u5E94\u7528\u540E\u518D\u8FDE\u63A5
3639
- 3. \u5728 Telegram Mini App \u4E2D\uFF0C\u786E\u4FDD deep link \u5F39\u7A97\u672A\u88AB\u963B\u6B62
3640
- 4. \u7A0D\u7B49\u51E0\u79D2\u540E\u91CD\u8BD5\u8FDE\u63A5
3641
- 5. \u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C WalletConnect \u4E2D\u7EE7\u670D\u52A1\u5668\u53EF\u8BBF\u95EE\u6027
3642
-
3643
- \u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7\u3002`
3644
- );
3645
- }
3646
- if (errorMessage.includes("Invalid") || errorMessage.includes("Configuration") || errorMessage.includes("App Config") || errorMessage.includes("Invalid App")) {
3647
- const configErrorDetails = [
3648
- `
3649
- === WalletConnect Tron Configuration Error ===`,
3650
- `Error: ${errorMessage}`,
3651
- `Detailed: ${detailedError}`,
3652
- `Code: ${errorCode || "N/A"}`,
3653
- `
3654
- Environment:`,
3655
- ` - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}`,
3656
- ` - Platform: ${errorDetails.telegramPlatform}`,
3657
- ` - Current URL: ${errorDetails.currentUrl}`,
3658
- `
3659
- Configuration:`,
3660
- ` - Project ID: ${this.projectId ? "Set" : "Missing"}`,
3661
- ` - Network: ${network}`,
3662
- ` - Chain ID: ${targetChainId}`,
3663
- `
3664
- Possible Causes:`,
3665
- ` 1. Deep link (wc://) handling issue in Telegram Mini App`,
3666
- ` 2. Invalid metadata configuration (URL or icons not accessible)`,
3667
- ` 3. Network/chainId mismatch`,
3668
- ` 4. WalletConnect project ID not configured correctly`,
3669
- ` 5. Domain not added to WalletConnect Cloud allowlist`,
3670
- `
3671
- Please check:`,
3672
- ` - WalletConnect Project ID is valid and active`,
3673
- ` - Domain is added to WalletConnect Cloud allowlist (for serveo.net, etc.)`,
3674
- ` - Metadata URL is accessible: Check console for metadata logs`,
3675
- ` - Icons are accessible: Check console for icon URLs`,
3676
- ` - Network matches chainId: Expected ${network} for chainId ${targetChainId}`,
3677
- `
3678
- For more details, see the error object logged above.`,
3679
- `===========================================
3680
- `
3681
- ].join("\n");
3682
- console.error(configErrorDetails);
3683
- throw new ConfigurationError(
3684
- `WalletConnect Tron connection failed: ${errorMessage}
3685
-
3686
- Configuration Details:
3687
- - Telegram Mini App: ${this.isTelegramMiniApp() ? "Yes" : "No"}
3688
- - Platform: ${errorDetails.telegramPlatform}
3689
- - Origin: ${origin || "(unknown)"}
3690
- - Project ID: ${this.projectId ? "Set" : "Missing"}
3691
- - Network: ${network}
3692
- - Chain ID: ${targetChainId}
3693
-
3694
- This "Invalid App Configuration" error may be caused by:
3695
- 1. Deep link (wc://) handling issue in Telegram Mini App
3696
- 2. Invalid metadata configuration (URL or icons)
3697
- 3. Network/chainId mismatch
3698
- 4. Domain not added to WalletConnect Cloud allowlist
3699
-
3700
- Please check the console for detailed error information.`
3701
- );
3702
- }
3703
- if (isOriginNotAllowed) {
3704
- throw new ConfigurationError(
3705
- `WalletConnect Tron relayer rejected this origin (code 3000: Unauthorized: origin not allowed).
3706
-
3707
- Fix:
3708
- 1) Open WalletConnect Cloud \u2192 your project (${this.projectId})
3709
- 2) Add this site origin to the allowlist:
3710
- - ${origin || "(unknown origin)"}
3711
-
3712
- Common dev origins to allow:
3713
- - http://localhost:5173
3714
- - http://192.168.0.221:5173 (your LAN dev URL)
3715
- - https://wallet-test.enclave-hq.com (your Cloudflare Tunnel/custom domain)
3716
-
3717
- Original error: ${errorMessage}`
3718
- );
3719
- }
3720
- if (isTimeout) {
3721
- throw new ConnectionRejectedError(
3722
- `WalletConnect Tron connection timeout. Please try again and ensure your wallet app is open and ready.`
3723
- );
3724
- }
3725
- if (isRejected) {
3726
- throw new ConnectionRejectedError(this.type);
3727
- }
3728
- throw error;
3729
- }
3730
- this.currentAddress = address;
3731
- const account = {
3732
- universalAddress: createUniversalAddress(targetChainId, address),
3733
- nativeAddress: address,
3734
- chainId: targetChainId,
3735
- chainType: exports.ChainType.TRON,
3736
- isActive: true
3737
- };
3738
- this.setState("connected" /* CONNECTED */);
3739
- this.setAccount(account);
3740
- this.setupEventListeners();
3741
- return account;
3742
- } catch (error) {
3743
- this.setState("error" /* ERROR */);
3744
- this.setAccount(null);
3745
- this.currentAddress = null;
3746
- if (error.message?.includes("rejected") || error.code === 4001) {
3747
- throw new ConnectionRejectedError(this.type);
3748
- }
3749
- throw error;
3750
- }
3751
- }
3752
- /**
3753
- * Disconnect wallet
3754
- */
3755
- async disconnect() {
3756
- this.removeEventListeners();
3757
- if (this.wallet) {
3758
- try {
3759
- await this.wallet.disconnect();
3760
- } catch (error) {
3761
- console.warn("[WalletConnect Tron] Error during disconnect:", error);
3762
- }
3763
- }
3764
- this.wallet = null;
3765
- this.currentAddress = null;
3766
- this.setState("disconnected" /* DISCONNECTED */);
3767
- this.setAccount(null);
3768
- this.emitDisconnected();
3769
- }
3770
- /**
3771
- * Sign message
3772
- */
3773
- async signMessage(message) {
3774
- this.ensureConnected();
3775
- try {
3776
- if (!this.wallet) {
3777
- throw new Error("Wallet not initialized");
3778
- }
3779
- const signature = await this.wallet.signMessage(message);
3780
- if (typeof signature === "string") {
3781
- return signature;
3782
- } else if (signature && typeof signature === "object") {
3783
- if ("signature" in signature) {
3784
- return signature.signature;
3785
- } else if ("result" in signature) {
3786
- return signature.result;
3787
- } else {
3788
- return JSON.stringify(signature);
3789
- }
3790
- }
3791
- throw new Error("Invalid signature format returned from wallet");
3792
- } catch (error) {
3793
- console.error("[WalletConnect Tron] Sign message error:", error);
3794
- let errorMessage = "Unknown error";
3795
- if (typeof error === "string") {
3796
- errorMessage = error;
3797
- } else if (error?.message) {
3798
- errorMessage = error.message;
3799
- } else if (error?.error?.message) {
3800
- errorMessage = error.error.message;
3801
- } else {
3802
- try {
3803
- errorMessage = JSON.stringify(error);
3804
- } catch {
3805
- errorMessage = String(error);
3806
- }
3807
- }
3808
- if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
3809
- throw new SignatureRejectedError();
3810
- }
3811
- if (errorMessage?.includes("not supported") || errorMessage?.includes("method not found") || errorMessage?.includes("Method not found") || error?.code === -32601 || error?.error?.code === -32601) {
3812
- 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.");
3813
- }
3814
- throw new Error(`WalletConnect Tron sign message failed: ${errorMessage}`);
3815
- }
3816
- }
3817
- /**
3818
- * Sign transaction
3819
- *
3820
- * @param transaction - Tron transaction object
3821
- * Can be created using TronWeb (if available) or any TRON transaction builder
3822
- * Format: { raw_data: {...}, raw_data_hex: "...", txID: "..." }
3823
- * @returns Signed transaction object or signature
3824
- */
3825
- async signTransaction(transaction) {
3826
- this.ensureConnected();
3827
- try {
3828
- if (!this.wallet) {
3829
- throw new Error("Wallet not initialized");
3830
- }
3831
- if (!transaction) {
3832
- throw new Error("Transaction object is required");
3833
- }
3834
- console.log("[WalletConnect Tron] Signing transaction:", {
3835
- hasRawData: !!transaction.raw_data,
3836
- hasRawDataHex: !!transaction.raw_data_hex,
3837
- hasTxID: !!transaction.txID
3838
- });
3839
- const result = await this.wallet.signTransaction(transaction);
3840
- if (typeof result === "string") {
3841
- return result;
3842
- } else if (result && typeof result === "object") {
3843
- if ("txID" in result && typeof result.txID === "string") {
3844
- return result.txID;
3845
- } else if ("txid" in result && typeof result.txid === "string") {
3846
- return result.txid;
3847
- } else if ("signature" in result) {
3848
- return JSON.stringify(result);
3849
- } else {
3850
- return JSON.stringify(result);
3851
- }
3852
- }
3853
- throw new Error("Invalid signature format returned from wallet");
3854
- } catch (error) {
3855
- console.error("[WalletConnect Tron] Sign transaction error:", error);
3856
- let errorMessage = "Unknown error";
3857
- if (typeof error === "string") {
3858
- errorMessage = error;
3859
- } else if (error?.message) {
3860
- errorMessage = error.message;
3861
- } else if (error?.error?.message) {
3862
- errorMessage = error.error.message;
3863
- } else if (error?.data?.message) {
3864
- errorMessage = error.data.message;
3865
- } else {
3866
- try {
3867
- errorMessage = JSON.stringify(error);
3868
- } catch {
3869
- errorMessage = String(error);
3870
- }
3871
- }
3872
- if (errorMessage?.includes("rejected") || errorMessage?.includes("declined") || errorMessage?.includes("User rejected") || error?.code === 4001 || error?.code === "USER_REJECTED" || error?.error?.code === 4001) {
3873
- throw new SignatureRejectedError("Transaction signature was rejected by user");
3874
- }
3875
- 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) {
3876
- 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.");
3877
- }
3878
- throw new Error(`WalletConnect Tron sign transaction failed: ${errorMessage}`);
3879
- }
3880
- }
3881
- /**
3882
- * Read contract (not supported by WalletConnect)
3883
- */
3884
- async readContract(_params) {
3885
- this.ensureConnected();
3886
- 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.");
3887
- }
3888
- /**
3889
- * Write contract (not yet implemented)
3890
- */
3891
- async writeContract(_params) {
3892
- throw new Error("Contract write not yet implemented for WalletConnect Tron");
3893
- }
3894
- /**
3895
- * Estimate gas (not yet implemented)
3896
- */
3897
- async estimateGas(_params) {
3898
- throw new Error("Gas estimation not yet implemented for WalletConnect Tron");
3899
- }
3900
- /**
3901
- * Wait for transaction (not yet implemented)
3902
- */
3903
- async waitForTransaction(_txHash, _confirmations) {
3904
- throw new Error("Transaction waiting not yet implemented for WalletConnect Tron");
3905
- }
3906
- /**
3907
- * Setup event listeners
3908
- */
3909
- setupEventListeners() {
3910
- if (!this.wallet) {
3911
- return;
3912
- }
3913
- this.wallet.on("accountsChanged", (accounts) => {
3914
- if (accounts && accounts.length > 0 && accounts[0] !== this.currentAddress) {
3915
- const newAddress = accounts[0];
3916
- this.currentAddress = newAddress;
3917
- if (this.currentAccount) {
3918
- const newAccount = {
3919
- ...this.currentAccount,
3920
- nativeAddress: newAddress,
3921
- universalAddress: createUniversalAddress(this.currentAccount.chainId, newAddress)
3922
- };
3923
- this.setAccount(newAccount);
3924
- this.emit("accountChanged", newAccount);
3925
- }
3926
- } else if (!accounts || accounts.length === 0) {
3927
- this.disconnect();
3928
- }
3929
- });
3930
- this.wallet.on("disconnect", () => {
3931
- this.disconnect();
3932
- });
3933
- }
3934
- /**
3935
- * Remove event listeners
3936
- */
3937
- removeEventListeners() {
3938
- if (!this.wallet) {
3939
- return;
3940
- }
3941
- this.wallet.removeAllListeners("accountsChanged");
3942
- this.wallet.removeAllListeners("disconnect");
3943
- }
3944
- /**
3945
- * Get provider (returns wallet instance)
3946
- */
3947
- getProvider() {
3948
- return this.wallet;
3949
- }
3950
- /**
3951
- * Clear static wallet instance (for complete cleanup)
3952
- */
3953
- static clearWalletInstance() {
3954
- if (_WalletConnectTronAdapter.walletInstance) {
3955
- _WalletConnectTronAdapter.walletInstance.disconnect().catch(() => {
3956
- });
3957
- _WalletConnectTronAdapter.walletInstance = null;
3958
- _WalletConnectTronAdapter.walletProjectId = null;
3959
- }
3960
- }
3961
- };
3962
- // Tron 主网链 ID
3963
- _WalletConnectTronAdapter.TRON_MAINNET_CHAIN_ID = 195;
3964
- // Static wallet instance to avoid multiple initializations
3965
- _WalletConnectTronAdapter.walletInstance = null;
3966
- _WalletConnectTronAdapter.walletProjectId = null;
3967
- var WalletConnectTronAdapter = _WalletConnectTronAdapter;
3519
+ function loadWalletConnectTronModule() {
3520
+ const here = typeof __filename !== "undefined" ? __filename : url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
3521
+ const req = module$1.createRequire(here);
3522
+ const tronBundle = here.endsWith(".mjs") ? "tron.mjs" : "tron.js";
3523
+ return req(path.join(path.dirname(here), tronBundle));
3524
+ }
3968
3525
 
3969
3526
  // src/adapters/deep-link/adapter.ts
3970
3527
  init_types();
@@ -4280,10 +3837,10 @@ var AdapterRegistry = class {
4280
3837
  "walletconnect" /* WALLETCONNECT */,
4281
3838
  () => new WalletConnectAdapter(this.config.walletConnectProjectId)
4282
3839
  );
4283
- this.register(
4284
- "walletconnect-tron" /* WALLETCONNECT_TRON */,
4285
- () => new WalletConnectTronAdapter(this.config.walletConnectProjectId)
4286
- );
3840
+ this.register("walletconnect-tron" /* WALLETCONNECT_TRON */, () => {
3841
+ const { WalletConnectTronAdapter } = loadWalletConnectTronModule();
3842
+ return new WalletConnectTronAdapter(this.config.walletConnectProjectId);
3843
+ });
4287
3844
  }
4288
3845
  this.register("tronlink" /* TRONLINK */, () => new TronLinkAdapter());
4289
3846
  this.register(
@@ -4807,6 +4364,41 @@ var WalletManager = class extends TypedEventEmitter {
4807
4364
  throw error;
4808
4365
  }
4809
4366
  }
4367
+ /**
4368
+ * Request account switch (opens wallet account selector)
4369
+ * @param targetAddress Optional target address to verify after switching
4370
+ * @returns The new account after switching
4371
+ */
4372
+ async requestSwitchAccount(targetAddress) {
4373
+ if (!this.primaryWallet) {
4374
+ throw new WalletNotConnectedError();
4375
+ }
4376
+ if (!this.primaryWallet.requestSwitchAccount) {
4377
+ throw new Error(`Account switching not supported by ${this.primaryWallet.type}`);
4378
+ }
4379
+ const account = await this.primaryWallet.requestSwitchAccount(targetAddress);
4380
+ if (this.config.enableStorage) {
4381
+ this.saveToStorage();
4382
+ }
4383
+ return account;
4384
+ }
4385
+ /**
4386
+ * Ensure the current account matches the target address
4387
+ * If not matching, request account switch
4388
+ * @param targetAddress The address that should be active
4389
+ * @returns The account (either existing or after switch)
4390
+ */
4391
+ async ensureAccount(targetAddress) {
4392
+ const currentAccount = this.getPrimaryAccount();
4393
+ if (!currentAccount) {
4394
+ throw new WalletNotConnectedError();
4395
+ }
4396
+ if (currentAccount.nativeAddress.toLowerCase() === targetAddress.toLowerCase()) {
4397
+ return currentAccount;
4398
+ }
4399
+ console.log(`[WalletManager] Current account ${currentAccount.nativeAddress} doesn't match target ${targetAddress}, requesting switch...`);
4400
+ return this.requestSwitchAccount(targetAddress);
4401
+ }
4810
4402
  // ===== Contract Calls =====
4811
4403
  /**
4812
4404
  * Read contract
@@ -5016,13 +4608,13 @@ var WalletManager = class extends TypedEventEmitter {
5016
4608
  if (currentAddress === savedAddress.toLowerCase()) {
5017
4609
  console.debug("[WalletManager] Address matches, attempting connect (should be silent if already authorized)");
5018
4610
  try {
5019
- const account2 = await adapter.connect(data.primaryChainId);
4611
+ const account = await adapter.connect(data.primaryChainId);
5020
4612
  this.setPrimaryWallet(adapter);
5021
4613
  this.connectedWallets.set(adapter.chainType, adapter);
5022
4614
  this.setupAdapterListeners(adapter, true);
5023
- this.emit("accountChanged", account2);
4615
+ this.emit("accountChanged", account);
5024
4616
  console.debug("[WalletManager] Connect successful");
5025
- return account2;
4617
+ return account;
5026
4618
  } catch (connectError) {
5027
4619
  console.debug("[WalletManager] Connect failed (might be user rejection):", connectError?.message);
5028
4620
  return null;
@@ -5042,12 +4634,12 @@ var WalletManager = class extends TypedEventEmitter {
5042
4634
  try {
5043
4635
  const tronWeb = adapter.getTronWeb?.();
5044
4636
  if (tronWeb && tronWeb.defaultAddress?.base58) {
5045
- const account2 = await adapter.connect(data.primaryChainId);
4637
+ const account = await adapter.connect(data.primaryChainId);
5046
4638
  this.setPrimaryWallet(adapter);
5047
4639
  this.connectedWallets.set(adapter.chainType, adapter);
5048
4640
  this.setupAdapterListeners(adapter, true);
5049
- this.emit("accountChanged", account2);
5050
- return account2;
4641
+ this.emit("accountChanged", account);
4642
+ return account;
5051
4643
  }
5052
4644
  } catch (silentError) {
5053
4645
  console.debug("Silent TronLink connection failed:", silentError);
@@ -5058,14 +4650,14 @@ var WalletManager = class extends TypedEventEmitter {
5058
4650
  const wcAdapter = adapter;
5059
4651
  if (typeof wcAdapter.restoreSession === "function") {
5060
4652
  console.debug("[WalletManager] Attempting to restore WalletConnect Tron session...");
5061
- const account2 = await wcAdapter.restoreSession(data.primaryChainId);
5062
- if (account2) {
4653
+ const account = await wcAdapter.restoreSession(data.primaryChainId);
4654
+ if (account) {
5063
4655
  console.debug("[WalletManager] WalletConnect Tron session restored successfully");
5064
4656
  this.setPrimaryWallet(adapter);
5065
4657
  this.connectedWallets.set(adapter.chainType, adapter);
5066
4658
  this.setupAdapterListeners(adapter, true);
5067
- this.emit("accountChanged", account2);
5068
- return account2;
4659
+ this.emit("accountChanged", account);
4660
+ return account;
5069
4661
  } else {
5070
4662
  console.debug("[WalletManager] No valid WalletConnect Tron session found");
5071
4663
  return null;
@@ -5076,12 +4668,12 @@ var WalletManager = class extends TypedEventEmitter {
5076
4668
  return null;
5077
4669
  }
5078
4670
  }
5079
- const account = await adapter.connect(data.primaryChainId);
5080
- this.setPrimaryWallet(adapter);
5081
- this.connectedWallets.set(adapter.chainType, adapter);
5082
- this.setupAdapterListeners(adapter, true);
5083
- this.emit("accountChanged", account);
5084
- return account;
4671
+ console.debug(
4672
+ "[WalletManager] restoreFromStorage: no silent session; skipping interactive connect (type:",
4673
+ data.primaryWalletType,
4674
+ ")"
4675
+ );
4676
+ return null;
5085
4677
  } catch (error) {
5086
4678
  console.debug("Failed to restore wallet from storage:", error);
5087
4679
  return null;
@@ -6006,7 +5598,6 @@ exports.TronDeepLinkAdapter = TronDeepLinkAdapter;
6006
5598
  exports.TronLinkAdapter = TronLinkAdapter;
6007
5599
  exports.WalletAdapter = WalletAdapter;
6008
5600
  exports.WalletConnectAdapter = WalletConnectAdapter;
6009
- exports.WalletConnectTronAdapter = WalletConnectTronAdapter;
6010
5601
  exports.WalletDetector = WalletDetector;
6011
5602
  exports.WalletManager = WalletManager;
6012
5603
  exports.WalletNotAvailableError = WalletNotAvailableError;