@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.d.mts +9 -227
- package/dist/index.js +336 -745
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +339 -54
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +5 -1
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.js +347 -54
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +348 -55
- package/dist/react/index.mjs.map +1 -1
- package/dist/tron.d.mts +36 -0
- package/dist/tron.js +852 -0
- package/dist/tron.js.map +1 -0
- package/dist/tron.mjs +846 -0
- package/dist/tron.mjs.map +1 -0
- package/dist/wallet-adapter-DRd0xm3N.d.mts +197 -0
- package/package.json +8 -3
- package/dist/index.d.ts +0 -880
package/dist/react/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ChainType as ChainType$1 } from '@enclave-hq/chain-utils';
|
|
2
2
|
import React2, { createContext, useState, useCallback, useEffect, useContext, useRef } from 'react';
|
|
3
3
|
import EventEmitter from 'eventemitter3';
|
|
4
|
-
import { createWalletClient, custom, createPublicClient, http, isAddress, getAddress } from 'viem';
|
|
4
|
+
import { encodeFunctionData, createWalletClient, custom, createPublicClient, http, isAddress, getAddress } from 'viem';
|
|
5
5
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
6
6
|
import EthereumProvider from '@walletconnect/ethereum-provider';
|
|
7
7
|
import { WalletConnectChainID, WalletConnectWallet } from '@tronweb3/walletconnect-tron';
|
|
@@ -837,7 +837,12 @@ var CHAIN_INFO = {
|
|
|
837
837
|
symbol: "ETH",
|
|
838
838
|
decimals: 18
|
|
839
839
|
},
|
|
840
|
-
|
|
840
|
+
// 使用支持浏览器 CORS 的公共 RPC,避免 dapp 域名被跨域拦截(如 eth.llamarpc.com 无 CORS 头)
|
|
841
|
+
rpcUrls: [
|
|
842
|
+
"https://cloudflare-eth.com",
|
|
843
|
+
"https://rpc.ankr.com/eth",
|
|
844
|
+
"https://eth.llamarpc.com"
|
|
845
|
+
],
|
|
841
846
|
blockExplorerUrls: ["https://etherscan.io"]
|
|
842
847
|
},
|
|
843
848
|
// EVM Testnets
|
|
@@ -1236,6 +1241,56 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
|
|
|
1236
1241
|
}]
|
|
1237
1242
|
});
|
|
1238
1243
|
}
|
|
1244
|
+
/**
|
|
1245
|
+
* 请求切换账户
|
|
1246
|
+
* 弹出 MetaMask 账户选择界面,让用户选择或切换到目标地址
|
|
1247
|
+
* @param targetAddress 目标地址(可选),如果提供,会在切换后验证是否匹配
|
|
1248
|
+
* @returns 切换后的账户信息
|
|
1249
|
+
*/
|
|
1250
|
+
async requestSwitchAccount(targetAddress) {
|
|
1251
|
+
const provider = this.getBrowserProvider();
|
|
1252
|
+
if (!provider) {
|
|
1253
|
+
throw new Error("MetaMask provider not available");
|
|
1254
|
+
}
|
|
1255
|
+
try {
|
|
1256
|
+
await provider.request({
|
|
1257
|
+
method: "wallet_requestPermissions",
|
|
1258
|
+
params: [{ eth_accounts: {} }]
|
|
1259
|
+
});
|
|
1260
|
+
const accounts = await provider.request({
|
|
1261
|
+
method: "eth_accounts"
|
|
1262
|
+
});
|
|
1263
|
+
if (!accounts || accounts.length === 0) {
|
|
1264
|
+
throw new ConnectionRejectedError(this.type);
|
|
1265
|
+
}
|
|
1266
|
+
const address = formatEVMAddress(accounts[0]);
|
|
1267
|
+
if (targetAddress && address.toLowerCase() !== targetAddress.toLowerCase()) {
|
|
1268
|
+
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)}`);
|
|
1269
|
+
}
|
|
1270
|
+
const chainId = this.currentAccount?.chainId || 1;
|
|
1271
|
+
const account = {
|
|
1272
|
+
universalAddress: createUniversalAddress(chainId, address),
|
|
1273
|
+
nativeAddress: address,
|
|
1274
|
+
chainId,
|
|
1275
|
+
chainType: ChainType.EVM,
|
|
1276
|
+
isActive: true
|
|
1277
|
+
};
|
|
1278
|
+
this.setAccount(account);
|
|
1279
|
+
this.emitAccountChanged(account);
|
|
1280
|
+
const viemChain = this.getViemChain(chainId);
|
|
1281
|
+
this.walletClient = createWalletClient({
|
|
1282
|
+
account: address,
|
|
1283
|
+
chain: viemChain,
|
|
1284
|
+
transport: custom(provider)
|
|
1285
|
+
});
|
|
1286
|
+
return account;
|
|
1287
|
+
} catch (error) {
|
|
1288
|
+
if (error.code === 4001) {
|
|
1289
|
+
throw new ConnectionRejectedError(this.type);
|
|
1290
|
+
}
|
|
1291
|
+
throw error;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1239
1294
|
/**
|
|
1240
1295
|
* 读取合约
|
|
1241
1296
|
*/
|
|
@@ -1461,6 +1516,46 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
|
|
|
1461
1516
|
|
|
1462
1517
|
// src/adapters/tron/tronlink.ts
|
|
1463
1518
|
init_types();
|
|
1519
|
+
var TronApiRateLimiter = class {
|
|
1520
|
+
constructor(minIntervalMs = 600) {
|
|
1521
|
+
this.lastCallTime = 0;
|
|
1522
|
+
this.minInterval = minIntervalMs;
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* 等待直到可以进行下一次 API 调用
|
|
1526
|
+
*/
|
|
1527
|
+
async waitForNextCall() {
|
|
1528
|
+
const now = Date.now();
|
|
1529
|
+
const timeSinceLastCall = now - this.lastCallTime;
|
|
1530
|
+
if (timeSinceLastCall < this.minInterval) {
|
|
1531
|
+
const waitTime = this.minInterval - timeSinceLastCall;
|
|
1532
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
1533
|
+
}
|
|
1534
|
+
this.lastCallTime = Date.now();
|
|
1535
|
+
}
|
|
1536
|
+
};
|
|
1537
|
+
var tronApiRateLimiter = new TronApiRateLimiter(600);
|
|
1538
|
+
async function retryWithBackoff(fn, maxRetries = 3, initialDelay = 500) {
|
|
1539
|
+
let lastError;
|
|
1540
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
1541
|
+
try {
|
|
1542
|
+
return await fn();
|
|
1543
|
+
} catch (error) {
|
|
1544
|
+
lastError = error;
|
|
1545
|
+
const errorMsg = error?.message || String(error);
|
|
1546
|
+
const errorLower = errorMsg.toLowerCase();
|
|
1547
|
+
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;
|
|
1548
|
+
if (isRateLimitError && attempt < maxRetries - 1) {
|
|
1549
|
+
const delay = initialDelay * Math.pow(2, attempt);
|
|
1550
|
+
console.warn(`[TronLink] \u9047\u5230\u901F\u7387\u9650\u5236 (429)\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5 (${attempt + 1}/${maxRetries})...`);
|
|
1551
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1552
|
+
continue;
|
|
1553
|
+
}
|
|
1554
|
+
throw error;
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
throw lastError;
|
|
1558
|
+
}
|
|
1464
1559
|
var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
|
|
1465
1560
|
constructor() {
|
|
1466
1561
|
super(...arguments);
|
|
@@ -1638,10 +1733,12 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
|
|
|
1638
1733
|
/**
|
|
1639
1734
|
* 读取合约
|
|
1640
1735
|
* 参考 webserver 的实现,使用 TronWeb 合约实例的标准 call() 方法
|
|
1736
|
+
* 带 TronGrid 限流 + 429 重试
|
|
1641
1737
|
*/
|
|
1642
1738
|
async readContract(params) {
|
|
1643
1739
|
this.ensureConnected();
|
|
1644
|
-
|
|
1740
|
+
await tronApiRateLimiter.waitForNextCall();
|
|
1741
|
+
const doRead = async () => {
|
|
1645
1742
|
const tronWeb = this.getTronWeb();
|
|
1646
1743
|
if (!this.currentAccount) {
|
|
1647
1744
|
throw new Error("No account connected");
|
|
@@ -1656,19 +1753,17 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
|
|
|
1656
1753
|
return result;
|
|
1657
1754
|
} catch (method1Error) {
|
|
1658
1755
|
console.warn("\u26A0\uFE0F [\u65B9\u6CD51] TronWeb\u6807\u51C6\u65B9\u6CD5\u5931\u8D25\uFF0C\u5C1D\u8BD5\u65B9\u6CD52:", method1Error.message);
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
throw new Error(`Function ${params.functionName} not found in contract`);
|
|
1664
|
-
}
|
|
1665
|
-
const result = await method2(...params.args || []).call();
|
|
1666
|
-
return result;
|
|
1667
|
-
} catch (method2Error) {
|
|
1668
|
-
console.error("\u26A0\uFE0F [\u65B9\u6CD52] \u4E5F\u5931\u8D25:", method2Error.message);
|
|
1669
|
-
throw method1Error;
|
|
1756
|
+
const contract2 = await tronWeb.contract().at(params.address);
|
|
1757
|
+
const method2 = contract2[params.functionName];
|
|
1758
|
+
if (!method2 || typeof method2 !== "function") {
|
|
1759
|
+
throw new Error(`Function ${params.functionName} not found in contract`);
|
|
1670
1760
|
}
|
|
1761
|
+
const result = await method2(...params.args || []).call();
|
|
1762
|
+
return result;
|
|
1671
1763
|
}
|
|
1764
|
+
};
|
|
1765
|
+
try {
|
|
1766
|
+
return await retryWithBackoff(doRead, 3, 800);
|
|
1672
1767
|
} catch (error) {
|
|
1673
1768
|
console.error("Read contract error:", error);
|
|
1674
1769
|
throw new Error(`Failed to read contract: ${error.message || "Unknown error"}`);
|
|
@@ -1679,6 +1774,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
|
|
|
1679
1774
|
*/
|
|
1680
1775
|
async writeContract(params) {
|
|
1681
1776
|
this.ensureConnected();
|
|
1777
|
+
await tronApiRateLimiter.waitForNextCall();
|
|
1682
1778
|
try {
|
|
1683
1779
|
const tronWeb = this.getTronWeb();
|
|
1684
1780
|
console.log("[TronLink] writeContract params:", {
|
|
@@ -1704,29 +1800,171 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
|
|
|
1704
1800
|
}
|
|
1705
1801
|
console.log("[TronLink] Function ABI:", functionAbi);
|
|
1706
1802
|
console.log("[TronLink] Calling with args:", params.args);
|
|
1803
|
+
const TRON_FEE_LIMIT = 1e8;
|
|
1707
1804
|
const options = {
|
|
1708
|
-
feeLimit:
|
|
1709
|
-
//
|
|
1805
|
+
feeLimit: TRON_FEE_LIMIT,
|
|
1806
|
+
// 固定为 100 TRX 的能量限制
|
|
1710
1807
|
callValue: params.value || 0
|
|
1711
1808
|
// 发送的 TRX 数量(单位:SUN)
|
|
1712
1809
|
};
|
|
1713
|
-
const
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1810
|
+
const hasTupleArray = functionAbi.inputs.some((input) => input.type === "tuple[]");
|
|
1811
|
+
console.log("[TronLink] \u68C0\u67E5 tuple[] \u7C7B\u578B:", {
|
|
1812
|
+
hasTupleArray,
|
|
1813
|
+
inputs: functionAbi.inputs.map((i) => ({ name: i.name, type: i.type }))
|
|
1814
|
+
});
|
|
1815
|
+
let tx;
|
|
1816
|
+
if (hasTupleArray) {
|
|
1817
|
+
console.log("[TronLink] \u68C0\u6D4B\u5230 tuple[] \u53C2\u6570\uFF0C\u4F7F\u7528\u624B\u52A8\u7F16\u7801\u65B9\u5F0F");
|
|
1818
|
+
const processedArgs = params.args.map((argValue, index) => {
|
|
1819
|
+
const input = functionAbi.inputs[index];
|
|
1820
|
+
if (input.type === "address" && typeof argValue === "string") {
|
|
1821
|
+
if (argValue.startsWith("T") && argValue.length === 34) {
|
|
1822
|
+
const hexAddress = tronWeb.address.toHex(argValue);
|
|
1823
|
+
return hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
|
|
1824
|
+
}
|
|
1825
|
+
return argValue.startsWith("0x") ? argValue : `0x${argValue}`;
|
|
1826
|
+
}
|
|
1827
|
+
if (input.type === "tuple[]" && Array.isArray(argValue)) {
|
|
1828
|
+
return argValue.map((tupleItem) => {
|
|
1829
|
+
if (input.components && Array.isArray(input.components)) {
|
|
1830
|
+
const processedTuple = {};
|
|
1831
|
+
input.components.forEach((component) => {
|
|
1832
|
+
let value = tupleItem[component.name];
|
|
1833
|
+
if (component.type === "address" && typeof value === "string") {
|
|
1834
|
+
if (value.startsWith("T") && value.length === 34) {
|
|
1835
|
+
const hexAddress = tronWeb.address.toHex(value);
|
|
1836
|
+
value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
|
|
1837
|
+
} else if (!value.startsWith("0x")) {
|
|
1838
|
+
value = `0x${value}`;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
processedTuple[component.name] = value;
|
|
1842
|
+
});
|
|
1843
|
+
return processedTuple;
|
|
1844
|
+
}
|
|
1845
|
+
return tupleItem;
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
|
|
1849
|
+
if (input.components && Array.isArray(input.components)) {
|
|
1850
|
+
const processedTuple = {};
|
|
1851
|
+
input.components.forEach((component) => {
|
|
1852
|
+
let value = argValue[component.name];
|
|
1853
|
+
if (component.type === "address" && typeof value === "string") {
|
|
1854
|
+
if (value.startsWith("T") && value.length === 34) {
|
|
1855
|
+
const hexAddress = tronWeb.address.toHex(value);
|
|
1856
|
+
value = hexAddress.startsWith("0x") ? hexAddress : `0x${hexAddress}`;
|
|
1857
|
+
} else if (!value.startsWith("0x")) {
|
|
1858
|
+
value = `0x${value}`;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
processedTuple[component.name] = value;
|
|
1862
|
+
});
|
|
1863
|
+
return processedTuple;
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
return argValue;
|
|
1867
|
+
});
|
|
1868
|
+
console.log("[TronLink] \u5904\u7406\u540E\u7684\u53C2\u6570\uFF08\u7528\u4E8E viem \u7F16\u7801\uFF09:", processedArgs);
|
|
1869
|
+
const encodedData = encodeFunctionData({
|
|
1870
|
+
abi: [functionAbi],
|
|
1871
|
+
functionName: params.functionName,
|
|
1872
|
+
args: processedArgs
|
|
1873
|
+
});
|
|
1874
|
+
console.log("[TronLink] \u7F16\u7801\u540E\u7684\u6570\u636E:", encodedData);
|
|
1875
|
+
const functionSelector = encodedData.slice(0, 10);
|
|
1876
|
+
const parameterData = encodedData.slice(10);
|
|
1877
|
+
console.log("[TronLink] \u51FD\u6570\u9009\u62E9\u5668:", functionSelector);
|
|
1878
|
+
console.log("[TronLink] \u53C2\u6570\u6570\u636E:", parameterData);
|
|
1879
|
+
const functionSignature = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
|
|
1880
|
+
const parameterHexClean = parameterData.startsWith("0x") ? parameterData.slice(2) : parameterData;
|
|
1881
|
+
console.log("[TronLink] \u4F7F\u7528 TronWeb triggerSmartContract (rawParameter)...", {
|
|
1882
|
+
contractAddress: params.address,
|
|
1883
|
+
functionSelector: functionSignature,
|
|
1884
|
+
encodedDataLength: parameterHexClean.length
|
|
1885
|
+
});
|
|
1886
|
+
tx = await retryWithBackoff(
|
|
1887
|
+
() => tronWeb.transactionBuilder.triggerSmartContract(
|
|
1888
|
+
params.address,
|
|
1889
|
+
// Base58 格式的合约地址
|
|
1890
|
+
functionSignature,
|
|
1891
|
+
// 函数签名(用于识别函数)
|
|
1892
|
+
{
|
|
1893
|
+
feeLimit: options.feeLimit,
|
|
1894
|
+
callValue: options.callValue,
|
|
1895
|
+
rawParameter: parameterHexClean
|
|
1896
|
+
// 使用 rawParameter 直接提供编码后的数据
|
|
1897
|
+
},
|
|
1898
|
+
[],
|
|
1899
|
+
// parameter 留空(因为使用 rawParameter)
|
|
1900
|
+
this.currentAccount.nativeAddress
|
|
1901
|
+
// Base58 格式的发送地址
|
|
1902
|
+
),
|
|
1903
|
+
3,
|
|
1904
|
+
// 最多重试 3 次
|
|
1905
|
+
500
|
|
1906
|
+
// 初始延迟 500ms
|
|
1907
|
+
);
|
|
1908
|
+
console.log("[TronLink] \u4F7F\u7528 TronWeb API \u6784\u5EFA\u7684\u4EA4\u6613:", tx);
|
|
1909
|
+
} else {
|
|
1910
|
+
const parameter = functionAbi.inputs.map((input, index) => {
|
|
1911
|
+
const argValue = params.args[index];
|
|
1912
|
+
if (input.type === "tuple" && typeof argValue === "object" && !Array.isArray(argValue)) {
|
|
1913
|
+
if (input.components && Array.isArray(input.components)) {
|
|
1914
|
+
return {
|
|
1915
|
+
type: input.type,
|
|
1916
|
+
value: input.components.map((component) => ({
|
|
1917
|
+
type: component.type,
|
|
1918
|
+
value: argValue[component.name]
|
|
1919
|
+
}))
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
if (input.type === "address" && typeof argValue === "string") {
|
|
1924
|
+
if (argValue.startsWith("T") && argValue.length === 34) {
|
|
1925
|
+
return {
|
|
1926
|
+
type: input.type,
|
|
1927
|
+
value: argValue
|
|
1928
|
+
};
|
|
1929
|
+
}
|
|
1930
|
+
try {
|
|
1931
|
+
const base58Address = tronWeb.address.fromHex(argValue.startsWith("0x") ? argValue : `0x${argValue}`);
|
|
1932
|
+
return {
|
|
1933
|
+
type: input.type,
|
|
1934
|
+
value: base58Address
|
|
1935
|
+
};
|
|
1936
|
+
} catch (e) {
|
|
1937
|
+
return {
|
|
1938
|
+
type: input.type,
|
|
1939
|
+
value: argValue
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
return {
|
|
1944
|
+
type: input.type,
|
|
1945
|
+
value: argValue
|
|
1946
|
+
};
|
|
1947
|
+
});
|
|
1948
|
+
console.log("[TronLink] Transaction options:", options);
|
|
1949
|
+
console.log("[TronLink] Parameters:", parameter);
|
|
1950
|
+
const functionSelector = params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")";
|
|
1951
|
+
console.log("[TronLink] Function selector:", functionSelector);
|
|
1952
|
+
console.log("[TronLink] Transaction options:", options);
|
|
1953
|
+
console.log("[TronLink] Parameters:", parameter);
|
|
1954
|
+
tx = await retryWithBackoff(
|
|
1955
|
+
() => tronWeb.transactionBuilder.triggerSmartContract(
|
|
1956
|
+
params.address,
|
|
1957
|
+
functionSelector,
|
|
1958
|
+
options,
|
|
1959
|
+
parameter,
|
|
1960
|
+
this.currentAccount.nativeAddress
|
|
1961
|
+
),
|
|
1962
|
+
3,
|
|
1963
|
+
// 最多重试 3 次
|
|
1964
|
+
500
|
|
1965
|
+
// 初始延迟 500ms
|
|
1966
|
+
);
|
|
1967
|
+
}
|
|
1730
1968
|
console.log("[TronLink] Transaction built:", tx);
|
|
1731
1969
|
if (!tx || !tx.transaction) {
|
|
1732
1970
|
throw new Error("Failed to build transaction");
|
|
@@ -1766,6 +2004,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
|
|
|
1766
2004
|
const maxAttempts = 60;
|
|
1767
2005
|
while (attempts < maxAttempts) {
|
|
1768
2006
|
try {
|
|
2007
|
+
await tronApiRateLimiter.waitForNextCall();
|
|
1769
2008
|
const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
|
|
1770
2009
|
if (txInfo && txInfo.id) {
|
|
1771
2010
|
const receipt = {
|
|
@@ -3183,6 +3422,12 @@ _WalletConnectAdapter.providerChains = null;
|
|
|
3183
3422
|
_WalletConnectAdapter.isInitializing = false;
|
|
3184
3423
|
_WalletConnectAdapter.initPromise = null;
|
|
3185
3424
|
var WalletConnectAdapter = _WalletConnectAdapter;
|
|
3425
|
+
|
|
3426
|
+
// src/adapters/tron/wallet-connect.ts
|
|
3427
|
+
var wallet_connect_exports = {};
|
|
3428
|
+
__export(wallet_connect_exports, {
|
|
3429
|
+
WalletConnectTronAdapter: () => WalletConnectTronAdapter
|
|
3430
|
+
});
|
|
3186
3431
|
init_types();
|
|
3187
3432
|
var _WalletConnectTronAdapter = class _WalletConnectTronAdapter extends WalletAdapter {
|
|
3188
3433
|
constructor(projectId) {
|
|
@@ -3875,6 +4120,11 @@ _WalletConnectTronAdapter.walletInstance = null;
|
|
|
3875
4120
|
_WalletConnectTronAdapter.walletProjectId = null;
|
|
3876
4121
|
var WalletConnectTronAdapter = _WalletConnectTronAdapter;
|
|
3877
4122
|
|
|
4123
|
+
// src/internal/walletconnect-tron-loader.esm.ts
|
|
4124
|
+
function loadWalletConnectTronModule() {
|
|
4125
|
+
return wallet_connect_exports;
|
|
4126
|
+
}
|
|
4127
|
+
|
|
3878
4128
|
// src/adapters/deep-link/adapter.ts
|
|
3879
4129
|
init_types();
|
|
3880
4130
|
var _DeepLinkAdapter = class _DeepLinkAdapter extends WalletAdapter {
|
|
@@ -4181,10 +4431,10 @@ var AdapterRegistry = class {
|
|
|
4181
4431
|
"walletconnect" /* WALLETCONNECT */,
|
|
4182
4432
|
() => new WalletConnectAdapter(this.config.walletConnectProjectId)
|
|
4183
4433
|
);
|
|
4184
|
-
this.register(
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
);
|
|
4434
|
+
this.register("walletconnect-tron" /* WALLETCONNECT_TRON */, () => {
|
|
4435
|
+
const { WalletConnectTronAdapter: WalletConnectTronAdapter2 } = loadWalletConnectTronModule();
|
|
4436
|
+
return new WalletConnectTronAdapter2(this.config.walletConnectProjectId);
|
|
4437
|
+
});
|
|
4188
4438
|
}
|
|
4189
4439
|
this.register("tronlink" /* TRONLINK */, () => new TronLinkAdapter());
|
|
4190
4440
|
this.register(
|
|
@@ -4699,6 +4949,41 @@ var WalletManager = class extends TypedEventEmitter {
|
|
|
4699
4949
|
throw error;
|
|
4700
4950
|
}
|
|
4701
4951
|
}
|
|
4952
|
+
/**
|
|
4953
|
+
* Request account switch (opens wallet account selector)
|
|
4954
|
+
* @param targetAddress Optional target address to verify after switching
|
|
4955
|
+
* @returns The new account after switching
|
|
4956
|
+
*/
|
|
4957
|
+
async requestSwitchAccount(targetAddress) {
|
|
4958
|
+
if (!this.primaryWallet) {
|
|
4959
|
+
throw new WalletNotConnectedError();
|
|
4960
|
+
}
|
|
4961
|
+
if (!this.primaryWallet.requestSwitchAccount) {
|
|
4962
|
+
throw new Error(`Account switching not supported by ${this.primaryWallet.type}`);
|
|
4963
|
+
}
|
|
4964
|
+
const account = await this.primaryWallet.requestSwitchAccount(targetAddress);
|
|
4965
|
+
if (this.config.enableStorage) {
|
|
4966
|
+
this.saveToStorage();
|
|
4967
|
+
}
|
|
4968
|
+
return account;
|
|
4969
|
+
}
|
|
4970
|
+
/**
|
|
4971
|
+
* Ensure the current account matches the target address
|
|
4972
|
+
* If not matching, request account switch
|
|
4973
|
+
* @param targetAddress The address that should be active
|
|
4974
|
+
* @returns The account (either existing or after switch)
|
|
4975
|
+
*/
|
|
4976
|
+
async ensureAccount(targetAddress) {
|
|
4977
|
+
const currentAccount = this.getPrimaryAccount();
|
|
4978
|
+
if (!currentAccount) {
|
|
4979
|
+
throw new WalletNotConnectedError();
|
|
4980
|
+
}
|
|
4981
|
+
if (currentAccount.nativeAddress.toLowerCase() === targetAddress.toLowerCase()) {
|
|
4982
|
+
return currentAccount;
|
|
4983
|
+
}
|
|
4984
|
+
console.log(`[WalletManager] Current account ${currentAccount.nativeAddress} doesn't match target ${targetAddress}, requesting switch...`);
|
|
4985
|
+
return this.requestSwitchAccount(targetAddress);
|
|
4986
|
+
}
|
|
4702
4987
|
// ===== Contract Calls =====
|
|
4703
4988
|
/**
|
|
4704
4989
|
* Read contract
|
|
@@ -4908,13 +5193,13 @@ var WalletManager = class extends TypedEventEmitter {
|
|
|
4908
5193
|
if (currentAddress === savedAddress.toLowerCase()) {
|
|
4909
5194
|
console.debug("[WalletManager] Address matches, attempting connect (should be silent if already authorized)");
|
|
4910
5195
|
try {
|
|
4911
|
-
const
|
|
5196
|
+
const account = await adapter.connect(data.primaryChainId);
|
|
4912
5197
|
this.setPrimaryWallet(adapter);
|
|
4913
5198
|
this.connectedWallets.set(adapter.chainType, adapter);
|
|
4914
5199
|
this.setupAdapterListeners(adapter, true);
|
|
4915
|
-
this.emit("accountChanged",
|
|
5200
|
+
this.emit("accountChanged", account);
|
|
4916
5201
|
console.debug("[WalletManager] Connect successful");
|
|
4917
|
-
return
|
|
5202
|
+
return account;
|
|
4918
5203
|
} catch (connectError) {
|
|
4919
5204
|
console.debug("[WalletManager] Connect failed (might be user rejection):", connectError?.message);
|
|
4920
5205
|
return null;
|
|
@@ -4934,12 +5219,12 @@ var WalletManager = class extends TypedEventEmitter {
|
|
|
4934
5219
|
try {
|
|
4935
5220
|
const tronWeb = adapter.getTronWeb?.();
|
|
4936
5221
|
if (tronWeb && tronWeb.defaultAddress?.base58) {
|
|
4937
|
-
const
|
|
5222
|
+
const account = await adapter.connect(data.primaryChainId);
|
|
4938
5223
|
this.setPrimaryWallet(adapter);
|
|
4939
5224
|
this.connectedWallets.set(adapter.chainType, adapter);
|
|
4940
5225
|
this.setupAdapterListeners(adapter, true);
|
|
4941
|
-
this.emit("accountChanged",
|
|
4942
|
-
return
|
|
5226
|
+
this.emit("accountChanged", account);
|
|
5227
|
+
return account;
|
|
4943
5228
|
}
|
|
4944
5229
|
} catch (silentError) {
|
|
4945
5230
|
console.debug("Silent TronLink connection failed:", silentError);
|
|
@@ -4950,14 +5235,14 @@ var WalletManager = class extends TypedEventEmitter {
|
|
|
4950
5235
|
const wcAdapter = adapter;
|
|
4951
5236
|
if (typeof wcAdapter.restoreSession === "function") {
|
|
4952
5237
|
console.debug("[WalletManager] Attempting to restore WalletConnect Tron session...");
|
|
4953
|
-
const
|
|
4954
|
-
if (
|
|
5238
|
+
const account = await wcAdapter.restoreSession(data.primaryChainId);
|
|
5239
|
+
if (account) {
|
|
4955
5240
|
console.debug("[WalletManager] WalletConnect Tron session restored successfully");
|
|
4956
5241
|
this.setPrimaryWallet(adapter);
|
|
4957
5242
|
this.connectedWallets.set(adapter.chainType, adapter);
|
|
4958
5243
|
this.setupAdapterListeners(adapter, true);
|
|
4959
|
-
this.emit("accountChanged",
|
|
4960
|
-
return
|
|
5244
|
+
this.emit("accountChanged", account);
|
|
5245
|
+
return account;
|
|
4961
5246
|
} else {
|
|
4962
5247
|
console.debug("[WalletManager] No valid WalletConnect Tron session found");
|
|
4963
5248
|
return null;
|
|
@@ -4968,12 +5253,12 @@ var WalletManager = class extends TypedEventEmitter {
|
|
|
4968
5253
|
return null;
|
|
4969
5254
|
}
|
|
4970
5255
|
}
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
return
|
|
5256
|
+
console.debug(
|
|
5257
|
+
"[WalletManager] restoreFromStorage: no silent session; skipping interactive connect (type:",
|
|
5258
|
+
data.primaryWalletType,
|
|
5259
|
+
")"
|
|
5260
|
+
);
|
|
5261
|
+
return null;
|
|
4977
5262
|
} catch (error) {
|
|
4978
5263
|
console.debug("Failed to restore wallet from storage:", error);
|
|
4979
5264
|
return null;
|
|
@@ -5016,7 +5301,11 @@ var WalletManager = class extends TypedEventEmitter {
|
|
|
5016
5301
|
|
|
5017
5302
|
// src/react/WalletContext.tsx
|
|
5018
5303
|
var WalletContext = createContext(null);
|
|
5019
|
-
function WalletProvider({
|
|
5304
|
+
function WalletProvider({
|
|
5305
|
+
children,
|
|
5306
|
+
walletManager: externalWalletManager,
|
|
5307
|
+
autoRestoreFromStorage = true
|
|
5308
|
+
}) {
|
|
5020
5309
|
const [walletManager] = useState(() => externalWalletManager || new WalletManager());
|
|
5021
5310
|
const [account, setAccount] = useState(null);
|
|
5022
5311
|
const [connectedWallets, setConnectedWallets] = useState([]);
|
|
@@ -5053,6 +5342,10 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
|
|
|
5053
5342
|
return walletManager.signTransaction(transaction);
|
|
5054
5343
|
}, [walletManager]);
|
|
5055
5344
|
useEffect(() => {
|
|
5345
|
+
if (!autoRestoreFromStorage) {
|
|
5346
|
+
setIsRestoring(false);
|
|
5347
|
+
return;
|
|
5348
|
+
}
|
|
5056
5349
|
const restoreConnection = async () => {
|
|
5057
5350
|
try {
|
|
5058
5351
|
const restoredAccount = await walletManager.restoreFromStorage();
|
|
@@ -5067,7 +5360,7 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
|
|
|
5067
5360
|
}
|
|
5068
5361
|
};
|
|
5069
5362
|
restoreConnection();
|
|
5070
|
-
}, [walletManager, updateConnectedWallets]);
|
|
5363
|
+
}, [walletManager, updateConnectedWallets, autoRestoreFromStorage]);
|
|
5071
5364
|
useEffect(() => {
|
|
5072
5365
|
const handleAccountChanged = (newAccount) => {
|
|
5073
5366
|
setAccount(newAccount);
|