@tomo-inc/wallet-adaptor-base 0.0.17 → 0.0.18

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
@@ -1,3 +1,4 @@
1
+ import { mainnet } from 'viem/chains';
1
2
  import { getWallets } from '@wallet-standard/core';
2
3
  import { WalletConnectClient } from '@tomo-inc/wallet-connect-protocol';
3
4
  import { toHex, isHex, fromHex } from 'viem';
@@ -70,6 +71,50 @@ function uint8arrayToHex(uint8array) {
70
71
  return Array.from(uint8array, (byte) => byte.toString(16).padStart(2, "0")).join("");
71
72
  }
72
73
 
74
+ // src/utils/wallet-config.ts
75
+ function hasWalletConfigProperties(config) {
76
+ if (!config || typeof config !== "object") {
77
+ return false;
78
+ }
79
+ return typeof config.id === "string" && typeof config.name === "string" && typeof config.icon === "string" && typeof config.iconBackground === "string";
80
+ }
81
+ function hasWagmiConnectorProperties(config) {
82
+ if (!config || typeof config !== "object") {
83
+ return false;
84
+ }
85
+ if (typeof config.createConnector === "function") {
86
+ return true;
87
+ }
88
+ const hasConnectorMethods = typeof config.connect === "function" || typeof config.disconnect === "function" || typeof config.getAccounts === "function" || typeof config.getChainId === "function";
89
+ const hasConnectorId = typeof config.id === "string" || typeof config.name === "string";
90
+ return hasConnectorMethods && hasConnectorId;
91
+ }
92
+ function isWagmiConnector(config) {
93
+ if (typeof config === "function") {
94
+ return true;
95
+ }
96
+ if (config && typeof config === "object") {
97
+ const hasWalletConfigProps = hasWalletConfigProperties(config);
98
+ if (!hasWalletConfigProps) {
99
+ return hasWagmiConnectorProperties(config);
100
+ }
101
+ }
102
+ return false;
103
+ }
104
+
105
+ // src/wallets/index.ts
106
+ var walletBaseUrl = "https://web3-assets.tomo.inc";
107
+ var allWallets = [];
108
+ var getAllWallets = async (baseUrl) => {
109
+ if (allWallets.length > 0) {
110
+ return allWallets;
111
+ }
112
+ const walletListResponse = await fetch((baseUrl || walletBaseUrl) + "/api/wallets");
113
+ const walletListData = await walletListResponse.json();
114
+ const walletList = allWallets = walletListData == null ? void 0 : walletListData.data;
115
+ return walletList;
116
+ };
117
+
73
118
  // src/type.ts
74
119
  var ProviderProtocol = /* @__PURE__ */ ((ProviderProtocol2) => {
75
120
  ProviderProtocol2["EIP6963"] = "eip6963";
@@ -131,17 +176,67 @@ var supportedWalletConfigTypes = {
131
176
  tomo: true,
132
177
  wagmi: true
133
178
  };
134
- function walletConfigAdapter(walletConfig, connectorType) {
179
+ function findWalletInDefaultConnectors(id, name, defaultWallets) {
180
+ let found = defaultWallets.find(
181
+ (wallet) => {
182
+ var _a, _b;
183
+ return ((_a = wallet.id) == null ? void 0 : _a.toLowerCase()) === id.toLowerCase() || ((_b = wallet.id) == null ? void 0 : _b.toLowerCase()) === id.toLowerCase().replace(/\s+/g, "-");
184
+ }
185
+ );
186
+ if (!found) {
187
+ const normalizedName = name.toLowerCase();
188
+ found = defaultWallets.find((wallet) => {
189
+ const walletName = wallet.name.toLowerCase();
190
+ return walletName === normalizedName || walletName.includes(normalizedName) || normalizedName.includes(walletName) || // support common wallet name variations matching
191
+ normalizedName.includes("metamask") && walletName.includes("metamask") || normalizedName.includes("coinbase") && walletName.includes("coinbase") || normalizedName.includes("safe") && walletName.includes("safe") || normalizedName.includes("walletconnect") && walletName.includes("walletconnect") || normalizedName.includes("injected") && walletName.includes("injected");
192
+ });
193
+ }
194
+ return found || null;
195
+ }
196
+ function adaptWagmiConnectorToWalletConfig(wagmiConnector, allWallets2, baseUrl) {
197
+ var _a, _b, _c, _d;
198
+ const tempConfig = { chains: [mainnet] };
199
+ const connector = wagmiConnector(tempConfig);
200
+ const id = connector.id || "unknown";
201
+ const name = connector.name || "Unknown Wallet";
202
+ const defaultWallet = findWalletInDefaultConnectors(id, name, allWallets2);
203
+ const walletConfig = {
204
+ id,
205
+ name,
206
+ namespace: (defaultWallet == null ? void 0 : defaultWallet.namespace) || "eip155",
207
+ // default EVM namespace
208
+ icon: baseUrl + (defaultWallet == null ? void 0 : defaultWallet.icon) || "",
209
+ iconBackground: (defaultWallet == null ? void 0 : defaultWallet.iconBackground) || "#666666",
210
+ rdns: defaultWallet == null ? void 0 : defaultWallet.rdns,
211
+ downloadUrls: (defaultWallet == null ? void 0 : defaultWallet.downloadUrls) || {},
212
+ installed: (defaultWallet == null ? void 0 : defaultWallet.installed) || false,
213
+ flag: (defaultWallet == null ? void 0 : defaultWallet.flag) || "",
214
+ solana: {
215
+ namespace: ((_a = defaultWallet == null ? void 0 : defaultWallet.solana) == null ? void 0 : _a.namespace) || "",
216
+ flag: ((_b = defaultWallet == null ? void 0 : defaultWallet.solana) == null ? void 0 : _b.flag) || ""
217
+ },
218
+ aptos: {
219
+ namespace: ((_c = defaultWallet == null ? void 0 : defaultWallet.aptos) == null ? void 0 : _c.namespace) || "",
220
+ flag: ((_d = defaultWallet == null ? void 0 : defaultWallet.aptos) == null ? void 0 : _d.flag) || ""
221
+ },
222
+ createConnector: wagmiConnector
223
+ };
224
+ return walletConfig;
225
+ }
226
+ function walletConfigAdapter(walletConfig, connectorType, allWallets2, baseUrl) {
135
227
  switch (connectorType) {
136
228
  case "tomo":
137
229
  return walletConfig;
138
230
  case "wagmi":
139
- return null;
231
+ if (typeof walletConfig === "function") {
232
+ return adaptWagmiConnectorToWalletConfig(walletConfig, allWallets2, baseUrl);
233
+ }
234
+ return walletConfig;
140
235
  default:
141
236
  return walletConfig;
142
237
  }
143
238
  }
144
- function connectorDector(wallet) {
239
+ function tomoConnectorDector(wallet) {
145
240
  var _a, _b, _c, _d, _e, _f, _g;
146
241
  const evmNS = {
147
242
  namespace: (wallet == null ? void 0 : wallet.namespace) || "",
@@ -218,19 +313,54 @@ function connectorDector(wallet) {
218
313
  providers
219
314
  };
220
315
  }
316
+ function wagmiConnectorDector(wallet) {
317
+ var _a, _b, _c, _d;
318
+ const tempConfig = {};
319
+ const connector = wallet.createConnector(tempConfig);
320
+ const evmNS = {
321
+ namespace: (wallet == null ? void 0 : wallet.namespace) || "",
322
+ flag: (wallet == null ? void 0 : wallet.flag) || ""
323
+ };
324
+ const isEvm = hasInjectedProvider(evmNS);
325
+ isEvm || wallet.installed || false;
326
+ const providers = {
327
+ evm: {
328
+ provider: connector,
329
+ protocol: "eip6963" /* EIP6963 */
330
+ }
331
+ };
332
+ return {
333
+ info: {
334
+ uuid: wallet == null ? void 0 : wallet.id,
335
+ name: wallet == null ? void 0 : wallet.name,
336
+ icon: wallet == null ? void 0 : wallet.icon,
337
+ iconBackground: wallet == null ? void 0 : wallet.iconBackground,
338
+ rdns: wallet == null ? void 0 : wallet.rdns,
339
+ links: {
340
+ homepage: ((_a = wallet == null ? void 0 : wallet.downloadUrls) == null ? void 0 : _a.qrCode) || "",
341
+ ios_install: ((_b = wallet == null ? void 0 : wallet.downloadUrls) == null ? void 0 : _b.ios) || "",
342
+ android_install: ((_c = wallet == null ? void 0 : wallet.downloadUrls) == null ? void 0 : _c.android) || "",
343
+ chrome_install: ((_d = wallet == null ? void 0 : wallet.downloadUrls) == null ? void 0 : _d.chrome) || ""
344
+ }
345
+ },
346
+ isInstalled: true,
347
+ providers
348
+ };
349
+ }
350
+ function connectorDector(wallet, connectorType) {
351
+ if (connectorType === "wagmi") {
352
+ return wagmiConnectorDector(wallet);
353
+ }
354
+ return tomoConnectorDector(wallet);
355
+ }
221
356
 
222
357
  // src/wallets/defaultConnectors.ts
223
- var defaultWallets = [];
224
358
  var getDefaultConnectors = async (baseUrl) => {
225
- if (defaultWallets.length > 0) {
226
- return defaultWallets.map((wallet) => connectorDector(wallet));
227
- }
228
- const walletListResponse = await fetch((baseUrl || "https://web3-assets.tomo.inc") + "/api/wallets");
229
- const walletList = await walletListResponse.json();
230
- defaultWallets = walletList == null ? void 0 : walletList.data.map((wallet) => __spreadProps(__spreadValues({}, wallet), {
231
- icon: (baseUrl || "https://web3-assets.tomo.inc") + wallet.icon
359
+ const walletList = await getAllWallets(baseUrl);
360
+ const defaultWallets = walletList == null ? void 0 : walletList.map((wallet) => __spreadProps(__spreadValues({}, wallet), {
361
+ icon: (baseUrl || walletBaseUrl) + wallet.icon
232
362
  }));
233
- return defaultWallets == null ? void 0 : defaultWallets.map((wallet) => connectorDector(wallet));
363
+ return defaultWallets == null ? void 0 : defaultWallets.map((wallet) => connectorDector(wallet, "tomo"));
234
364
  };
235
365
 
236
366
  // src/wallets/wallet-eip6963.ts
@@ -1004,9 +1134,7 @@ async function walletConnectWallets(baseUrl) {
1004
1134
  if (wcWallets.length > 0) {
1005
1135
  return wcWallets.map((wallet) => convertWalletToConnector(wallet));
1006
1136
  }
1007
- const walletListResponse = await fetch(
1008
- (baseUrl || "https://web3-assets.tomo.inc") + "/api/wallets?walletId=walletConnect"
1009
- );
1137
+ const walletListResponse = await fetch((baseUrl || walletBaseUrl) + "/api/wallets?walletId=walletConnect");
1010
1138
  const walletList = await walletListResponse.json();
1011
1139
  if (((_a = walletList == null ? void 0 : walletList.data) == null ? void 0 : _a.length) === 0) {
1012
1140
  return [];
@@ -1180,9 +1308,16 @@ var connect = async (connectParams, walletOptions) => {
1180
1308
  let address = "";
1181
1309
  let network = "";
1182
1310
  if (chainType === "evm") {
1183
- const res = await provider.request({ method: "eth_requestAccounts" });
1184
- address = (res == null ? void 0 : res[0]) || "";
1185
- chainId = await provider.request({ method: "eth_chainId" });
1311
+ if (provider == null ? void 0 : provider.request) {
1312
+ const res = await provider.request({ method: "eth_requestAccounts" });
1313
+ address = (res == null ? void 0 : res[0]) || "";
1314
+ chainId = await provider.request({ method: "eth_chainId" });
1315
+ } else {
1316
+ const wagmiProvider = await provider.getProvider();
1317
+ const res = await wagmiProvider.request({ method: "eth_requestAccounts" });
1318
+ address = (res == null ? void 0 : res[0]) || "";
1319
+ chainId = await provider.request({ method: "eth_chainId" });
1320
+ }
1186
1321
  }
1187
1322
  if (chainType === "solana") {
1188
1323
  let res = null;
@@ -1692,42 +1827,40 @@ var getBalance = async (token, walletOptions) => {
1692
1827
  throw new Error(`getBalance not supported in ${chainType}`);
1693
1828
  };
1694
1829
 
1695
- // src/wallets/index.ts
1696
- var getAllWallets = async (baseUrl) => {
1697
- const walletListResponse = await fetch((baseUrl || "https://web3-assets.tomo.inc") + "/api/wallets");
1698
- const walletList = await walletListResponse.json();
1699
- return walletList;
1700
- };
1701
-
1702
1830
  // src/index.ts
1703
- var walletBaseUrl = "https://embedded-wallet.tomo.inc";
1704
1831
  async function loadConnectors({
1705
1832
  chainType = "all",
1706
- recommonedConnectors,
1833
+ recommendedConnectors,
1707
1834
  connectorTypes = [],
1708
1835
  options = {
1709
1836
  baseUrl: walletBaseUrl
1710
1837
  }
1711
1838
  }) {
1712
- const recommonedWalletConfigs = recommonedConnectors || [];
1839
+ const recommonedWalletConfigs = recommendedConnectors || [];
1713
1840
  const evmWallets = await eip6963Wallets();
1714
1841
  const { solanaWallets, aptosWallets } = await walletStandardWallets();
1715
1842
  const wcWallets2 = await walletConnectWallets(options.baseUrl);
1716
- let recommonedConnectorsDetected = [];
1843
+ const allWallets2 = await getAllWallets(options.baseUrl);
1844
+ let recommendedConnectorsDetected = [];
1717
1845
  if (recommonedWalletConfigs.length > 0) {
1718
- recommonedConnectorsDetected = recommonedWalletConfigs.map((walletConfig, index) => {
1846
+ recommendedConnectorsDetected = recommonedWalletConfigs.map((walletConfig, index) => {
1719
1847
  const connectorType = connectorTypes[index];
1720
1848
  if (!supportedWalletConfigTypes[connectorType]) {
1721
1849
  throw new Error(`Unsupported wallet config type: ${connectorType}`);
1722
1850
  }
1723
- const _walletConfig = walletConfigAdapter(walletConfig, connectorType);
1724
- return __spreadProps(__spreadValues({}, connectorDector(_walletConfig)), {
1851
+ const _walletConfig = walletConfigAdapter(
1852
+ walletConfig,
1853
+ connectorType,
1854
+ allWallets2,
1855
+ options.baseUrl || walletBaseUrl
1856
+ );
1857
+ return __spreadProps(__spreadValues({}, connectorDector(_walletConfig, connectorType)), {
1725
1858
  recommoned: true
1726
1859
  });
1727
1860
  });
1728
1861
  }
1729
1862
  const defaultConnectors = await getDefaultConnectors(options.baseUrl);
1730
- const connectorsFromConfig = uniqueConnectors([...recommonedConnectorsDetected, ...defaultConnectors]);
1863
+ const connectorsFromConfig = uniqueConnectors([...recommendedConnectorsDetected, ...defaultConnectors]);
1731
1864
  const connectorsDetecteds = [...evmWallets, ...solanaWallets, ...aptosWallets, ...wcWallets2];
1732
1865
  for (const connector of connectorsDetecteds) {
1733
1866
  const _connector = connectorsFromConfig.find((c) => c.info.name === connector.info.name);
@@ -1747,8 +1880,8 @@ async function loadConnectors({
1747
1880
  });
1748
1881
  return {
1749
1882
  all: allConnectors,
1750
- recommoned: recommonedConnectorsDetected
1883
+ recommoned: recommendedConnectorsDetected
1751
1884
  };
1752
1885
  }
1753
1886
 
1754
- export { ProviderChainType, ProviderProtocol, SupportedChainTypes, addChain, connect, connectMobile, disconnect, getAllWallets, getBalance, isMobile, loadConnectors, setWalletConnectConfig, signInWithWallet, signMessage, switchChain };
1887
+ export { ProviderChainType, ProviderProtocol, SupportedChainTypes, addChain, connect, connectMobile, disconnect, getAllWallets, getBalance, isMobile, isWagmiConnector, loadConnectors, setWalletConnectConfig, signInWithWallet, signMessage, switchChain, walletBaseUrl };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomo-inc/wallet-adaptor-base",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "author": "tomo.inc",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -22,7 +22,7 @@
22
22
  "@solana/web3.js": "^1.98.0",
23
23
  "@wallet-standard/core": "^1.1.0",
24
24
  "viem": "2.21.54",
25
- "@tomo-inc/wallet-connect-protocol": "0.0.16"
25
+ "@tomo-inc/wallet-connect-protocol": "0.0.17"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^20.0.0",
@@ -0,0 +1,110 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+
3
+ describe("defaultConnectors", () => {
4
+ let originalFetch: typeof fetch;
5
+ let mockConnectorDector: ReturnType<typeof vi.fn>;
6
+
7
+ beforeEach(async () => {
8
+ originalFetch = global.fetch;
9
+ // Reset module cache before each test
10
+ vi.resetModules();
11
+
12
+ // Re-import after reset
13
+ const detectorModule = await import("../wallets/detector");
14
+ mockConnectorDector = vi.fn((wallet: any) => ({
15
+ info: { name: wallet.name, uuid: wallet.id },
16
+ providers: {},
17
+ }));
18
+ vi.spyOn(detectorModule, "connectorDector").mockImplementation(mockConnectorDector);
19
+ });
20
+
21
+ afterEach(() => {
22
+ global.fetch = originalFetch;
23
+ vi.restoreAllMocks();
24
+ });
25
+
26
+ describe("getDefaultConnectors", () => {
27
+ it("should fetch and return default connectors", async () => {
28
+ const { getDefaultConnectors } = await import("../wallets/defaultConnectors");
29
+ const mockWallets = [
30
+ { id: "wallet1", name: "Wallet 1", icon: "/icon1.png" },
31
+ { id: "wallet2", name: "Wallet 2", icon: "/icon2.png" },
32
+ ];
33
+
34
+ global.fetch = vi.fn().mockResolvedValue({
35
+ json: vi.fn().mockResolvedValue({ data: mockWallets }),
36
+ });
37
+
38
+ const result = await getDefaultConnectors();
39
+
40
+ expect(global.fetch).toHaveBeenCalledWith("https://web3-assets.tomo.inc/api/wallets");
41
+ expect(result).toHaveLength(2);
42
+ expect(mockConnectorDector).toHaveBeenCalledTimes(2);
43
+ });
44
+
45
+ it("should use custom baseUrl", async () => {
46
+ const { getDefaultConnectors } = await import("../wallets/defaultConnectors");
47
+ const mockWallets = [{ id: "wallet1", name: "Wallet 1", icon: "/icon1.png" }];
48
+
49
+ global.fetch = vi.fn().mockResolvedValue({
50
+ json: vi.fn().mockResolvedValue({ data: mockWallets }),
51
+ });
52
+
53
+ const customBaseUrl = "https://custom-api.example.com";
54
+ await getDefaultConnectors(customBaseUrl);
55
+
56
+ expect(global.fetch).toHaveBeenCalledWith(`${customBaseUrl}/api/wallets`);
57
+ });
58
+
59
+ it("should prepend baseUrl to icon paths", async () => {
60
+ const { getDefaultConnectors } = await import("../wallets/defaultConnectors");
61
+ const mockWallets = [{ id: "wallet1", name: "Wallet 1", icon: "/icon1.png" }];
62
+
63
+ global.fetch = vi.fn().mockResolvedValue({
64
+ json: vi.fn().mockResolvedValue({ data: mockWallets }),
65
+ });
66
+
67
+ const customBaseUrl = "https://custom-api.example.com";
68
+ await getDefaultConnectors(customBaseUrl);
69
+
70
+ expect(mockConnectorDector).toHaveBeenCalledWith({
71
+ id: "wallet1",
72
+ name: "Wallet 1",
73
+ icon: "https://custom-api.example.com/icon1.png",
74
+ });
75
+ });
76
+
77
+ it("should return cached connectors on second call", async () => {
78
+ const { getDefaultConnectors } = await import("../wallets/defaultConnectors");
79
+ const mockWallets = [{ id: "wallet1", name: "Wallet 1", icon: "/icon1.png" }];
80
+
81
+ global.fetch = vi.fn().mockResolvedValue({
82
+ json: vi.fn().mockResolvedValue({ data: mockWallets }),
83
+ });
84
+
85
+ const result1 = await getDefaultConnectors();
86
+ const result2 = await getDefaultConnectors();
87
+
88
+ expect(global.fetch).toHaveBeenCalledTimes(1);
89
+ expect(result1).toEqual(result2);
90
+ });
91
+
92
+ it("should handle empty wallet list", async () => {
93
+ const { getDefaultConnectors } = await import("../wallets/defaultConnectors");
94
+ global.fetch = vi.fn().mockResolvedValue({
95
+ json: vi.fn().mockResolvedValue({ data: [] }),
96
+ });
97
+
98
+ const result = await getDefaultConnectors();
99
+
100
+ expect(result).toHaveLength(0);
101
+ });
102
+
103
+ it("should handle fetch errors gracefully", async () => {
104
+ const { getDefaultConnectors } = await import("../wallets/defaultConnectors");
105
+ global.fetch = vi.fn().mockRejectedValue(new Error("Network error"));
106
+
107
+ await expect(getDefaultConnectors()).rejects.toThrow("Network error");
108
+ });
109
+ });
110
+ });