@enclave-hq/wallet-sdk 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,7 +36,11 @@ interface Account {
36
36
  balance?: string;
37
37
  name?: string;
38
38
  }
39
- interface IWalletAdapter {
39
+ interface ISigner {
40
+ signMessage(message: string): Promise<string>;
41
+ getAddress(): Promise<string>;
42
+ }
43
+ interface IWalletAdapter extends ISigner {
40
44
  readonly type: WalletType;
41
45
  readonly chainType: ChainType;
42
46
  readonly name: string;
@@ -178,7 +182,7 @@ declare class WalletManager extends TypedEventEmitter<WalletManagerEvents> {
178
182
  private setupAdapterListeners;
179
183
  private removeAdapterListeners;
180
184
  private saveToStorage;
181
- private restoreFromStorage;
185
+ restoreFromStorage(): Promise<Account | null>;
182
186
  private clearStorage;
183
187
  private getHistoryRecords;
184
188
  }
@@ -188,6 +192,7 @@ interface WalletContextValue {
188
192
  account: Account | null;
189
193
  isConnected: boolean;
190
194
  connectedWallets: ConnectedWallet[];
195
+ isRestoring: boolean;
191
196
  connect: (type: WalletType, chainId?: number) => Promise<Account>;
192
197
  connectAdditional: (type: WalletType, chainId?: number) => Promise<Account>;
193
198
  disconnect: () => Promise<void>;
@@ -36,7 +36,11 @@ interface Account {
36
36
  balance?: string;
37
37
  name?: string;
38
38
  }
39
- interface IWalletAdapter {
39
+ interface ISigner {
40
+ signMessage(message: string): Promise<string>;
41
+ getAddress(): Promise<string>;
42
+ }
43
+ interface IWalletAdapter extends ISigner {
40
44
  readonly type: WalletType;
41
45
  readonly chainType: ChainType;
42
46
  readonly name: string;
@@ -178,7 +182,7 @@ declare class WalletManager extends TypedEventEmitter<WalletManagerEvents> {
178
182
  private setupAdapterListeners;
179
183
  private removeAdapterListeners;
180
184
  private saveToStorage;
181
- private restoreFromStorage;
185
+ restoreFromStorage(): Promise<Account | null>;
182
186
  private clearStorage;
183
187
  private getHistoryRecords;
184
188
  }
@@ -188,6 +192,7 @@ interface WalletContextValue {
188
192
  account: Account | null;
189
193
  isConnected: boolean;
190
194
  connectedWallets: ConnectedWallet[];
195
+ isRestoring: boolean;
191
196
  connect: (type: WalletType, chainId?: number) => Promise<Account>;
192
197
  connectAdditional: (type: WalletType, chainId?: number) => Promise<Account>;
193
198
  disconnect: () => Promise<void>;
@@ -120,6 +120,17 @@ var WalletAdapter = class extends EventEmitter__default.default {
120
120
  this.state = "disconnected" /* DISCONNECTED */;
121
121
  this.currentAccount = null;
122
122
  }
123
+ /**
124
+ * Get the signer's address (implements ISigner interface)
125
+ * Returns the native address of the current account
126
+ */
127
+ async getAddress() {
128
+ this.ensureConnected();
129
+ if (!this.currentAccount) {
130
+ throw new WalletNotConnectedError(this.type);
131
+ }
132
+ return this.currentAccount.nativeAddress;
133
+ }
123
134
  signTransaction(_transaction) {
124
135
  throw new MethodNotSupportedError("signTransaction", this.type);
125
136
  }
@@ -1480,9 +1491,6 @@ var WalletManager = class extends TypedEventEmitter {
1480
1491
  walletConnectProjectId: config.walletConnectProjectId ?? ""
1481
1492
  };
1482
1493
  this.registry = new AdapterRegistry();
1483
- if (this.config.enableStorage) {
1484
- this.restoreFromStorage();
1485
- }
1486
1494
  }
1487
1495
  // ===== Connection Management =====
1488
1496
  /**
@@ -1593,13 +1601,13 @@ var WalletManager = class extends TypedEventEmitter {
1593
1601
  return adapter.currentAccount;
1594
1602
  }
1595
1603
  /**
1596
- * 获取主钱包账户
1604
+ * Get primary wallet account
1597
1605
  */
1598
1606
  getPrimaryAccount() {
1599
1607
  return this.primaryWallet?.currentAccount || null;
1600
1608
  }
1601
1609
  /**
1602
- * 获取所有已连接的钱包
1610
+ * Get all connected wallets
1603
1611
  */
1604
1612
  getConnectedWallets() {
1605
1613
  return Array.from(this.connectedWallets.values()).map((adapter) => ({
@@ -1612,14 +1620,14 @@ var WalletManager = class extends TypedEventEmitter {
1612
1620
  }));
1613
1621
  }
1614
1622
  /**
1615
- * 根据链类型获取钱包
1623
+ * Get wallet by chain type
1616
1624
  */
1617
1625
  getWalletByChainType(chainType) {
1618
1626
  return this.connectedWallets.get(chainType) || null;
1619
1627
  }
1620
- // ===== 签名 =====
1628
+ // ===== Signing =====
1621
1629
  /**
1622
- * 使用主钱包签名
1630
+ * Sign message with primary wallet
1623
1631
  */
1624
1632
  async signMessage(message) {
1625
1633
  if (!this.primaryWallet) {
@@ -1628,7 +1636,7 @@ var WalletManager = class extends TypedEventEmitter {
1628
1636
  return this.primaryWallet.signMessage(message);
1629
1637
  }
1630
1638
  /**
1631
- * 使用指定链类型的钱包签名
1639
+ * Sign message with wallet of specified chain type
1632
1640
  */
1633
1641
  async signMessageWithChainType(message, chainType) {
1634
1642
  if (!chainType) {
@@ -1641,7 +1649,7 @@ var WalletManager = class extends TypedEventEmitter {
1641
1649
  return adapter.signMessage(message);
1642
1650
  }
1643
1651
  /**
1644
- * 签名 TypedData(仅 EVM
1652
+ * Sign TypedData (EVM only)
1645
1653
  */
1646
1654
  async signTypedData(typedData, chainType) {
1647
1655
  const adapter = chainType ? this.connectedWallets.get(chainType) : this.primaryWallet;
@@ -1654,7 +1662,7 @@ var WalletManager = class extends TypedEventEmitter {
1654
1662
  return adapter.signTypedData(typedData);
1655
1663
  }
1656
1664
  /**
1657
- * 签名交易(使用主钱包)
1665
+ * Sign transaction (with primary wallet)
1658
1666
  */
1659
1667
  async signTransaction(transaction) {
1660
1668
  if (!this.primaryWallet) {
@@ -1666,7 +1674,7 @@ var WalletManager = class extends TypedEventEmitter {
1666
1674
  return this.primaryWallet.signTransaction(transaction);
1667
1675
  }
1668
1676
  /**
1669
- * 使用指定链类型的钱包签名交易
1677
+ * Sign transaction with wallet of specified chain type
1670
1678
  */
1671
1679
  async signTransactionWithChainType(transaction, chainType) {
1672
1680
  if (!chainType) {
@@ -1681,9 +1689,9 @@ var WalletManager = class extends TypedEventEmitter {
1681
1689
  }
1682
1690
  return adapter.signTransaction(transaction);
1683
1691
  }
1684
- // ===== 链切换 =====
1692
+ // ===== Chain Switching =====
1685
1693
  /**
1686
- * 请求切换链(仅 EVM
1694
+ * Request chain switch (EVM only)
1687
1695
  */
1688
1696
  async requestSwitchChain(chainId, options) {
1689
1697
  if (!this.primaryWallet) {
@@ -1704,9 +1712,9 @@ var WalletManager = class extends TypedEventEmitter {
1704
1712
  throw error;
1705
1713
  }
1706
1714
  }
1707
- // ===== 合约调用 =====
1715
+ // ===== Contract Calls =====
1708
1716
  /**
1709
- * 读取合约
1717
+ * Read contract
1710
1718
  */
1711
1719
  async readContract(address, abi, functionName, args, chainType) {
1712
1720
  const adapter = chainType ? this.connectedWallets.get(chainType) : this.primaryWallet;
@@ -1719,7 +1727,7 @@ var WalletManager = class extends TypedEventEmitter {
1719
1727
  return adapter.readContract({ address, abi, functionName, args });
1720
1728
  }
1721
1729
  /**
1722
- * 写入合约
1730
+ * Write contract
1723
1731
  */
1724
1732
  async writeContract(address, abi, functionName, args, options, chainType) {
1725
1733
  const adapter = chainType ? this.connectedWallets.get(chainType) : this.primaryWallet;
@@ -1738,7 +1746,7 @@ var WalletManager = class extends TypedEventEmitter {
1738
1746
  });
1739
1747
  }
1740
1748
  /**
1741
- * 估算 Gas
1749
+ * Estimate gas
1742
1750
  */
1743
1751
  async estimateGas(address, abi, functionName, args, chainType) {
1744
1752
  const adapter = chainType ? this.connectedWallets.get(chainType) : this.primaryWallet;
@@ -1751,7 +1759,7 @@ var WalletManager = class extends TypedEventEmitter {
1751
1759
  return adapter.estimateGas({ address, abi, functionName, args });
1752
1760
  }
1753
1761
  /**
1754
- * 等待交易确认
1762
+ * Wait for transaction confirmation
1755
1763
  */
1756
1764
  async waitForTransaction(txHash, confirmations, chainType) {
1757
1765
  const adapter = chainType ? this.connectedWallets.get(chainType) : this.primaryWallet;
@@ -1763,9 +1771,9 @@ var WalletManager = class extends TypedEventEmitter {
1763
1771
  }
1764
1772
  return adapter.waitForTransaction(txHash, confirmations);
1765
1773
  }
1766
- // ===== Provider 访问 =====
1774
+ // ===== Provider Access =====
1767
1775
  /**
1768
- * 获取主钱包 Provider
1776
+ * Get primary wallet Provider
1769
1777
  */
1770
1778
  getProvider() {
1771
1779
  if (!this.primaryWallet) {
@@ -1774,7 +1782,7 @@ var WalletManager = class extends TypedEventEmitter {
1774
1782
  return this.primaryWallet.getProvider();
1775
1783
  }
1776
1784
  /**
1777
- * 获取指定链类型的 Provider
1785
+ * Get Provider by chain type
1778
1786
  */
1779
1787
  getProviderByChainType(chainType) {
1780
1788
  const adapter = this.connectedWallets.get(chainType);
@@ -1783,21 +1791,21 @@ var WalletManager = class extends TypedEventEmitter {
1783
1791
  }
1784
1792
  return adapter.getProvider();
1785
1793
  }
1786
- // ===== 私有方法 =====
1794
+ // ===== Private Methods =====
1787
1795
  /**
1788
- * 设置主钱包
1796
+ * Set primary wallet
1789
1797
  */
1790
1798
  setPrimaryWallet(adapter) {
1791
1799
  this.primaryWallet = adapter;
1792
1800
  }
1793
1801
  /**
1794
- * 判断钱包是否支持链切换
1802
+ * Check if wallet supports chain switching
1795
1803
  */
1796
1804
  canSwitchChain(adapter) {
1797
1805
  return !!adapter.switchChain;
1798
1806
  }
1799
1807
  /**
1800
- * 设置适配器事件监听
1808
+ * Setup adapter event listeners
1801
1809
  */
1802
1810
  setupAdapterListeners(adapter, isPrimary) {
1803
1811
  adapter.on("accountChanged", (account) => {
@@ -1838,15 +1846,15 @@ var WalletManager = class extends TypedEventEmitter {
1838
1846
  });
1839
1847
  }
1840
1848
  /**
1841
- * 移除适配器事件监听
1849
+ * Remove adapter event listeners
1842
1850
  */
1843
1851
  removeAdapterListeners(adapter) {
1844
1852
  if (!adapter) return;
1845
1853
  adapter.removeAllListeners();
1846
1854
  }
1847
- // ===== 存储 =====
1855
+ // ===== Storage =====
1848
1856
  /**
1849
- * 保存到存储
1857
+ * Save to storage
1850
1858
  */
1851
1859
  saveToStorage() {
1852
1860
  if (typeof window === "undefined" || !this.config.enableStorage) {
@@ -1854,6 +1862,8 @@ var WalletManager = class extends TypedEventEmitter {
1854
1862
  }
1855
1863
  const data = {
1856
1864
  current: this.primaryWallet?.currentAccount?.universalAddress || null,
1865
+ primaryWalletType: this.primaryWallet?.type,
1866
+ primaryChainId: this.primaryWallet?.currentAccount?.chainId,
1857
1867
  history: this.getHistoryRecords()
1858
1868
  };
1859
1869
  try {
@@ -1866,12 +1876,101 @@ var WalletManager = class extends TypedEventEmitter {
1866
1876
  }
1867
1877
  }
1868
1878
  /**
1869
- * 从存储恢复
1879
+ * Restore from storage
1880
+ * Returns a Promise that can be used for auto-reconnection
1870
1881
  */
1871
- restoreFromStorage() {
1882
+ async restoreFromStorage() {
1883
+ if (typeof window === "undefined" || !this.config.enableStorage) {
1884
+ return null;
1885
+ }
1886
+ try {
1887
+ const stored = localStorage.getItem(`${this.config.storagePrefix}data`);
1888
+ if (!stored) {
1889
+ console.debug("[WalletManager] No stored wallet data found");
1890
+ return null;
1891
+ }
1892
+ const data = JSON.parse(stored);
1893
+ console.debug("[WalletManager] Restoring from storage:", data);
1894
+ if (!data.primaryWalletType || !data.current) {
1895
+ console.debug("[WalletManager] Missing primary wallet info in storage");
1896
+ return null;
1897
+ }
1898
+ const adapter = this.registry.getAdapter(data.primaryWalletType);
1899
+ if (!adapter) {
1900
+ console.debug("[WalletManager] Adapter not found for type:", data.primaryWalletType);
1901
+ return null;
1902
+ }
1903
+ const isAvailable = await adapter.isAvailable();
1904
+ if (!isAvailable) {
1905
+ console.debug("[WalletManager] Wallet not available:", data.primaryWalletType);
1906
+ return null;
1907
+ }
1908
+ console.debug("[WalletManager] Wallet is available, attempting restoration");
1909
+ if (adapter.chainType === ChainType.EVM && data.primaryWalletType === "metamask" /* METAMASK */) {
1910
+ try {
1911
+ const provider = typeof window !== "undefined" ? window.ethereum : null;
1912
+ if (provider) {
1913
+ const accounts = await provider.request({
1914
+ method: "eth_accounts"
1915
+ });
1916
+ console.debug("[WalletManager] Checking authorized accounts:", accounts);
1917
+ if (accounts && accounts.length > 0) {
1918
+ const savedAddress = data.current.split(":")[1];
1919
+ const currentAddress = accounts[0].toLowerCase();
1920
+ console.debug("[WalletManager] Comparing addresses - saved:", savedAddress, "current:", currentAddress);
1921
+ if (currentAddress === savedAddress.toLowerCase()) {
1922
+ console.debug("[WalletManager] Address matches, attempting connect (should be silent if already authorized)");
1923
+ try {
1924
+ const account2 = await adapter.connect(data.primaryChainId);
1925
+ this.setPrimaryWallet(adapter);
1926
+ this.connectedWallets.set(adapter.chainType, adapter);
1927
+ this.setupAdapterListeners(adapter, true);
1928
+ this.emit("accountChanged", account2);
1929
+ console.debug("[WalletManager] Connect successful");
1930
+ return account2;
1931
+ } catch (connectError) {
1932
+ console.debug("[WalletManager] Connect failed (might be user rejection):", connectError?.message);
1933
+ return null;
1934
+ }
1935
+ } else {
1936
+ console.debug("[WalletManager] Address mismatch, will try normal connect");
1937
+ }
1938
+ } else {
1939
+ console.debug("[WalletManager] No authorized accounts found");
1940
+ }
1941
+ }
1942
+ } catch (silentError) {
1943
+ console.debug("Silent connection failed, trying normal connection:", silentError);
1944
+ }
1945
+ }
1946
+ if (adapter.chainType === ChainType.TRON && data.primaryWalletType === "tronlink" /* TRONLINK */) {
1947
+ try {
1948
+ const tronWeb = adapter.getTronWeb?.();
1949
+ if (tronWeb && tronWeb.defaultAddress?.base58) {
1950
+ const account2 = await adapter.connect(data.primaryChainId);
1951
+ this.setPrimaryWallet(adapter);
1952
+ this.connectedWallets.set(adapter.chainType, adapter);
1953
+ this.setupAdapterListeners(adapter, true);
1954
+ this.emit("accountChanged", account2);
1955
+ return account2;
1956
+ }
1957
+ } catch (silentError) {
1958
+ console.debug("Silent TronLink connection failed:", silentError);
1959
+ }
1960
+ }
1961
+ const account = await adapter.connect(data.primaryChainId);
1962
+ this.setPrimaryWallet(adapter);
1963
+ this.connectedWallets.set(adapter.chainType, adapter);
1964
+ this.setupAdapterListeners(adapter, true);
1965
+ this.emit("accountChanged", account);
1966
+ return account;
1967
+ } catch (error) {
1968
+ console.debug("Failed to restore wallet from storage:", error);
1969
+ return null;
1970
+ }
1872
1971
  }
1873
1972
  /**
1874
- * 清除存储
1973
+ * Clear storage
1875
1974
  */
1876
1975
  clearStorage() {
1877
1976
  if (typeof window === "undefined") {
@@ -1884,7 +1983,7 @@ var WalletManager = class extends TypedEventEmitter {
1884
1983
  }
1885
1984
  }
1886
1985
  /**
1887
- * 获取历史记录
1986
+ * Get history records
1888
1987
  */
1889
1988
  getHistoryRecords() {
1890
1989
  const records = [];
@@ -1911,6 +2010,7 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
1911
2010
  const [walletManager] = React.useState(() => externalWalletManager || new WalletManager());
1912
2011
  const [account, setAccount] = React.useState(null);
1913
2012
  const [connectedWallets, setConnectedWallets] = React.useState([]);
2013
+ const [isRestoring, setIsRestoring] = React.useState(true);
1914
2014
  const updateConnectedWallets = React.useCallback(() => {
1915
2015
  setConnectedWallets(walletManager.getConnectedWallets());
1916
2016
  }, [walletManager]);
@@ -1942,6 +2042,22 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
1942
2042
  const signTransaction = React.useCallback(async (transaction) => {
1943
2043
  return walletManager.signTransaction(transaction);
1944
2044
  }, [walletManager]);
2045
+ React.useEffect(() => {
2046
+ const restoreConnection = async () => {
2047
+ try {
2048
+ const restoredAccount = await walletManager.restoreFromStorage();
2049
+ if (restoredAccount) {
2050
+ setAccount(restoredAccount);
2051
+ updateConnectedWallets();
2052
+ }
2053
+ } catch (error) {
2054
+ console.debug("Failed to restore wallet connection:", error);
2055
+ } finally {
2056
+ setIsRestoring(false);
2057
+ }
2058
+ };
2059
+ restoreConnection();
2060
+ }, [walletManager, updateConnectedWallets]);
1945
2061
  React.useEffect(() => {
1946
2062
  const handleAccountChanged = (newAccount) => {
1947
2063
  setAccount(newAccount);
@@ -1963,20 +2079,26 @@ function WalletProvider({ children, walletManager: externalWalletManager }) {
1963
2079
  walletManager.on("chainChanged", handleChainChanged);
1964
2080
  walletManager.on("disconnected", handleDisconnected);
1965
2081
  walletManager.on("primaryWalletSwitched", handlePrimaryWalletSwitched);
1966
- setAccount(walletManager.getPrimaryAccount());
1967
- updateConnectedWallets();
2082
+ if (!isRestoring) {
2083
+ const primaryAccount = walletManager.getPrimaryAccount();
2084
+ if (primaryAccount) {
2085
+ setAccount(primaryAccount);
2086
+ updateConnectedWallets();
2087
+ }
2088
+ }
1968
2089
  return () => {
1969
2090
  walletManager.off("accountChanged", handleAccountChanged);
1970
2091
  walletManager.off("chainChanged", handleChainChanged);
1971
2092
  walletManager.off("disconnected", handleDisconnected);
1972
2093
  walletManager.off("primaryWalletSwitched", handlePrimaryWalletSwitched);
1973
2094
  };
1974
- }, [walletManager, updateConnectedWallets]);
2095
+ }, [walletManager, updateConnectedWallets, isRestoring]);
1975
2096
  const value = {
1976
2097
  walletManager,
1977
2098
  account,
1978
2099
  isConnected: account !== null,
1979
2100
  connectedWallets,
2101
+ isRestoring,
1980
2102
  connect,
1981
2103
  connectAdditional,
1982
2104
  disconnect,