@tomo-inc/wallet-adaptor-base 0.0.19 → 0.0.21
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.cjs +18 -22
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +18 -22
- package/package.json +7 -2
- package/project.json +1 -1
- package/src/__tests__/WalletConnectProvider.test.ts +535 -0
- package/src/__tests__/WalletConnectSolanaProvider.test.ts +537 -0
- package/src/__tests__/browsers.test.ts +263 -0
- package/src/__tests__/chainId.test.ts +66 -0
- package/src/__tests__/chains-utils.test.ts +49 -0
- package/src/__tests__/defaultConnectors.test.ts +8 -5
- package/src/__tests__/detector.test.ts +402 -0
- package/src/__tests__/index.test.ts +275 -0
- package/src/__tests__/isMobile.test.ts +187 -0
- package/src/__tests__/log.test.ts +40 -0
- package/src/__tests__/utils.test.ts +66 -0
- package/src/__tests__/wallet-api.test.ts +1755 -0
- package/src/__tests__/wallet-config.test.ts +75 -0
- package/src/__tests__/wallet-eip6963.test.ts +377 -0
- package/src/__tests__/wallet-standard.test.ts +41 -3
- package/src/__tests__/wallet-walletconnect.test.ts +370 -0
- package/src/__tests__/wallets/index.test.ts +42 -0
- package/src/type.ts +4 -0
- package/src/utils/chainId.ts +6 -5
- package/src/utils/wallet-config.ts +2 -9
- package/src/wallet-api/connect.ts +4 -2
- package/src/wallets/detector.ts +3 -4
- package/src/wallets/providers/WalletConnectProvider.ts +5 -4
- package/src/wallets/providers/WalletConnectSolanaProvider.ts +1 -1
- package/src/wallets/wallet-eip6963.ts +1 -1
- package/vitest.config.ts +20 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { isWagmiConnector } from "../utils/wallet-config";
|
|
3
|
+
|
|
4
|
+
describe("wallet-config", () => {
|
|
5
|
+
describe("isWagmiConnector", () => {
|
|
6
|
+
it("should return true for function (CreateConnectorFn)", () => {
|
|
7
|
+
const createConnectorFn = () => ({ id: "test", name: "Test", connect: () => {} });
|
|
8
|
+
expect(isWagmiConnector(createConnectorFn as any)).toBe(true);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("should return true for object with createConnector method", () => {
|
|
12
|
+
expect(
|
|
13
|
+
isWagmiConnector({
|
|
14
|
+
createConnector: () => ({}),
|
|
15
|
+
} as any),
|
|
16
|
+
).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("should return true for object with connector methods and id/name but no WalletConfig props", () => {
|
|
20
|
+
expect(
|
|
21
|
+
isWagmiConnector({
|
|
22
|
+
id: "wagmi-1",
|
|
23
|
+
connect: () => {},
|
|
24
|
+
disconnect: () => {},
|
|
25
|
+
} as any),
|
|
26
|
+
).toBe(true);
|
|
27
|
+
expect(
|
|
28
|
+
isWagmiConnector({
|
|
29
|
+
name: "Wagmi Wallet",
|
|
30
|
+
getAccounts: () => {},
|
|
31
|
+
getChainId: () => {},
|
|
32
|
+
} as any),
|
|
33
|
+
).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should return false for full WalletConfig object", () => {
|
|
37
|
+
expect(
|
|
38
|
+
isWagmiConnector({
|
|
39
|
+
id: "w1",
|
|
40
|
+
name: "Wallet",
|
|
41
|
+
icon: "icon.png",
|
|
42
|
+
iconBackground: "#000",
|
|
43
|
+
} as any),
|
|
44
|
+
).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should return false for null or undefined", () => {
|
|
48
|
+
expect(isWagmiConnector(null as any)).toBe(false);
|
|
49
|
+
expect(isWagmiConnector(undefined as any)).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("should return false for non-object", () => {
|
|
53
|
+
expect(isWagmiConnector("string" as any)).toBe(false);
|
|
54
|
+
expect(isWagmiConnector(123 as any)).toBe(false);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("should return false when object has connector methods but missing both id and name", () => {
|
|
58
|
+
expect(
|
|
59
|
+
isWagmiConnector({
|
|
60
|
+
connect: () => {},
|
|
61
|
+
disconnect: () => {},
|
|
62
|
+
} as any),
|
|
63
|
+
).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("should return false when object has id/name but no connector methods", () => {
|
|
67
|
+
expect(
|
|
68
|
+
isWagmiConnector({
|
|
69
|
+
id: "x",
|
|
70
|
+
name: "y",
|
|
71
|
+
} as any),
|
|
72
|
+
).toBe(false);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { eip6963Wallets } from "../wallets/wallet-eip6963";
|
|
3
|
+
import { ProviderProtocol } from "@tomo-inc/wallet-utils";
|
|
4
|
+
|
|
5
|
+
describe("wallet-eip6963", () => {
|
|
6
|
+
let originalWindow: typeof window;
|
|
7
|
+
let originalAddEventListener: typeof window.addEventListener;
|
|
8
|
+
let originalRemoveEventListener: typeof window.removeEventListener;
|
|
9
|
+
let originalDispatchEvent: typeof window.dispatchEvent;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
originalWindow = global.window;
|
|
13
|
+
originalAddEventListener = window.addEventListener;
|
|
14
|
+
originalRemoveEventListener = window.removeEventListener;
|
|
15
|
+
originalDispatchEvent = window.dispatchEvent;
|
|
16
|
+
|
|
17
|
+
// Mock window methods
|
|
18
|
+
global.window = {
|
|
19
|
+
...window,
|
|
20
|
+
addEventListener: vi.fn(),
|
|
21
|
+
removeEventListener: vi.fn(),
|
|
22
|
+
dispatchEvent: vi.fn(),
|
|
23
|
+
} as any;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
global.window = originalWindow;
|
|
28
|
+
vi.restoreAllMocks();
|
|
29
|
+
vi.useRealTimers();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("eip6963Wallets", () => {
|
|
33
|
+
it("should return empty array when no providers announce", async () => {
|
|
34
|
+
vi.useFakeTimers();
|
|
35
|
+
|
|
36
|
+
const promise = eip6963Wallets();
|
|
37
|
+
vi.advanceTimersByTime(1000);
|
|
38
|
+
const result = await promise;
|
|
39
|
+
|
|
40
|
+
expect(result).toEqual([]);
|
|
41
|
+
expect(window.addEventListener).toHaveBeenCalled();
|
|
42
|
+
expect(window.dispatchEvent).toHaveBeenCalled();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should detect and return EIP6963 wallets", async () => {
|
|
46
|
+
vi.useFakeTimers();
|
|
47
|
+
|
|
48
|
+
const mockProvider = {
|
|
49
|
+
request: vi.fn(),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const mockWalletInfo = {
|
|
53
|
+
uuid: "test-uuid",
|
|
54
|
+
name: "Test Wallet",
|
|
55
|
+
icon: "test-icon.png",
|
|
56
|
+
rdns: "com.test.wallet",
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
60
|
+
|
|
61
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
62
|
+
if (event === "eip6963:announceProvider") {
|
|
63
|
+
eventHandler = handler;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const promise = eip6963Wallets();
|
|
68
|
+
|
|
69
|
+
// Simulate provider announcement
|
|
70
|
+
if (eventHandler) {
|
|
71
|
+
eventHandler({
|
|
72
|
+
detail: {
|
|
73
|
+
info: mockWalletInfo,
|
|
74
|
+
provider: mockProvider,
|
|
75
|
+
},
|
|
76
|
+
} as any);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
vi.advanceTimersByTime(1000);
|
|
80
|
+
const result = await promise;
|
|
81
|
+
|
|
82
|
+
expect(result).toHaveLength(1);
|
|
83
|
+
expect(result[0].info.name).toBe("Test Wallet");
|
|
84
|
+
expect(result[0].info.uuid).toBe("com.test.wallet");
|
|
85
|
+
expect(result[0].connectors.evm?.protocol).toBe(ProviderProtocol.INJECT);
|
|
86
|
+
expect(result[0].connectors.evm?.provider).toBe(mockProvider);
|
|
87
|
+
expect(result[0].isInstalled).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should filter out invalid wallet info", async () => {
|
|
91
|
+
vi.useFakeTimers();
|
|
92
|
+
|
|
93
|
+
const mockProvider = {
|
|
94
|
+
request: vi.fn(),
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
98
|
+
|
|
99
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
100
|
+
if (event === "eip6963:announceProvider") {
|
|
101
|
+
eventHandler = handler;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const promise = eip6963Wallets();
|
|
106
|
+
|
|
107
|
+
// Simulate invalid provider announcement (missing uuid)
|
|
108
|
+
if (eventHandler) {
|
|
109
|
+
eventHandler({
|
|
110
|
+
detail: {
|
|
111
|
+
info: {
|
|
112
|
+
name: "Test Wallet",
|
|
113
|
+
icon: "test-icon.png",
|
|
114
|
+
rdns: "com.test.wallet",
|
|
115
|
+
// Missing uuid
|
|
116
|
+
},
|
|
117
|
+
provider: mockProvider,
|
|
118
|
+
},
|
|
119
|
+
} as any);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
vi.advanceTimersByTime(1000);
|
|
123
|
+
const result = await promise;
|
|
124
|
+
|
|
125
|
+
expect(result).toHaveLength(0);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should filter out wallets without request method", async () => {
|
|
129
|
+
vi.useFakeTimers();
|
|
130
|
+
|
|
131
|
+
const mockWalletInfo = {
|
|
132
|
+
uuid: "test-uuid",
|
|
133
|
+
name: "Test Wallet",
|
|
134
|
+
icon: "test-icon.png",
|
|
135
|
+
rdns: "com.test.wallet",
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
139
|
+
|
|
140
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
141
|
+
if (event === "eip6963:announceProvider") {
|
|
142
|
+
eventHandler = handler;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const promise = eip6963Wallets();
|
|
147
|
+
|
|
148
|
+
// Simulate provider announcement without request method
|
|
149
|
+
if (eventHandler) {
|
|
150
|
+
eventHandler({
|
|
151
|
+
detail: {
|
|
152
|
+
info: mockWalletInfo,
|
|
153
|
+
provider: {}, // No request method
|
|
154
|
+
},
|
|
155
|
+
} as any);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
vi.advanceTimersByTime(1000);
|
|
159
|
+
const result = await promise;
|
|
160
|
+
|
|
161
|
+
expect(result).toHaveLength(0);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("should deduplicate wallets by uuid", async () => {
|
|
165
|
+
vi.useFakeTimers();
|
|
166
|
+
|
|
167
|
+
const mockProvider1 = { request: vi.fn() };
|
|
168
|
+
const mockProvider2 = { request: vi.fn() };
|
|
169
|
+
|
|
170
|
+
const mockWalletInfo = {
|
|
171
|
+
uuid: "test-uuid",
|
|
172
|
+
name: "Test Wallet",
|
|
173
|
+
icon: "test-icon.png",
|
|
174
|
+
rdns: "com.test.wallet",
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
178
|
+
|
|
179
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
180
|
+
if (event === "eip6963:announceProvider") {
|
|
181
|
+
eventHandler = handler;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const promise = eip6963Wallets();
|
|
186
|
+
|
|
187
|
+
// Simulate same wallet announcing twice
|
|
188
|
+
if (eventHandler) {
|
|
189
|
+
eventHandler({
|
|
190
|
+
detail: {
|
|
191
|
+
info: mockWalletInfo,
|
|
192
|
+
provider: mockProvider1,
|
|
193
|
+
},
|
|
194
|
+
} as any);
|
|
195
|
+
|
|
196
|
+
eventHandler({
|
|
197
|
+
detail: {
|
|
198
|
+
info: mockWalletInfo,
|
|
199
|
+
provider: mockProvider2,
|
|
200
|
+
},
|
|
201
|
+
} as any);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
vi.advanceTimersByTime(1000);
|
|
205
|
+
const result = await promise;
|
|
206
|
+
|
|
207
|
+
expect(result).toHaveLength(1);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("should handle errors in handleProviderAnnouncement", async () => {
|
|
211
|
+
vi.useFakeTimers();
|
|
212
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
213
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
214
|
+
if (event === "eip6963:announceProvider") eventHandler = handler;
|
|
215
|
+
});
|
|
216
|
+
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
217
|
+
const promise = eip6963Wallets();
|
|
218
|
+
if (eventHandler) {
|
|
219
|
+
const badEvent = {
|
|
220
|
+
detail: {
|
|
221
|
+
get info() {
|
|
222
|
+
throw new Error("Invalid info");
|
|
223
|
+
},
|
|
224
|
+
provider: { request: vi.fn() },
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
eventHandler(badEvent as any);
|
|
228
|
+
}
|
|
229
|
+
vi.advanceTimersByTime(1000);
|
|
230
|
+
const result = await promise;
|
|
231
|
+
expect(result).toEqual([]);
|
|
232
|
+
expect(consoleWarnSpy).toHaveBeenCalled();
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it("should handle dispatchEvent errors gracefully", async () => {
|
|
236
|
+
vi.useFakeTimers();
|
|
237
|
+
|
|
238
|
+
(window.dispatchEvent as any).mockImplementation(() => {
|
|
239
|
+
throw new Error("Dispatch error");
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
243
|
+
|
|
244
|
+
const promise = eip6963Wallets();
|
|
245
|
+
vi.advanceTimersByTime(1000);
|
|
246
|
+
const result = await promise;
|
|
247
|
+
|
|
248
|
+
expect(result).toEqual([]);
|
|
249
|
+
expect(consoleWarnSpy).toHaveBeenCalled();
|
|
250
|
+
expect(window.removeEventListener).toHaveBeenCalled();
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("should use rdns as uuid when available", async () => {
|
|
254
|
+
vi.useFakeTimers();
|
|
255
|
+
|
|
256
|
+
const mockProvider = {
|
|
257
|
+
request: vi.fn(),
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const mockWalletInfo = {
|
|
261
|
+
uuid: "test-uuid",
|
|
262
|
+
name: "Test Wallet",
|
|
263
|
+
icon: "test-icon.png",
|
|
264
|
+
rdns: "com.test.wallet",
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
268
|
+
|
|
269
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
270
|
+
if (event === "eip6963:announceProvider") {
|
|
271
|
+
eventHandler = handler;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const promise = eip6963Wallets();
|
|
276
|
+
|
|
277
|
+
if (eventHandler) {
|
|
278
|
+
eventHandler({
|
|
279
|
+
detail: {
|
|
280
|
+
info: mockWalletInfo,
|
|
281
|
+
provider: mockProvider,
|
|
282
|
+
},
|
|
283
|
+
} as any);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
vi.advanceTimersByTime(1000);
|
|
287
|
+
const result = await promise;
|
|
288
|
+
|
|
289
|
+
expect(result[0].info.uuid).toBe("com.test.wallet");
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it("should use encoded name as uuid when rdns is missing", async () => {
|
|
293
|
+
vi.useFakeTimers();
|
|
294
|
+
|
|
295
|
+
const mockProvider = {
|
|
296
|
+
request: vi.fn(),
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const mockWalletInfo = {
|
|
300
|
+
uuid: "test-uuid",
|
|
301
|
+
name: "Test Wallet",
|
|
302
|
+
icon: "test-icon.png",
|
|
303
|
+
// No rdns property
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
307
|
+
|
|
308
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
309
|
+
if (event === "eip6963:announceProvider") {
|
|
310
|
+
eventHandler = handler;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
const promise = eip6963Wallets();
|
|
315
|
+
|
|
316
|
+
// Trigger the event handler after a short delay to ensure listener is set up
|
|
317
|
+
vi.advanceTimersByTime(10);
|
|
318
|
+
|
|
319
|
+
// Trigger the event handler directly
|
|
320
|
+
if (eventHandler) {
|
|
321
|
+
eventHandler({
|
|
322
|
+
detail: {
|
|
323
|
+
info: mockWalletInfo,
|
|
324
|
+
provider: mockProvider,
|
|
325
|
+
},
|
|
326
|
+
} as any);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Advance timers to trigger the timeout
|
|
330
|
+
vi.advanceTimersByTime(1000);
|
|
331
|
+
const result = await promise;
|
|
332
|
+
|
|
333
|
+
expect(result.length).toBeGreaterThan(0);
|
|
334
|
+
expect(result[0].info.uuid).toBe(encodeURIComponent("Test Wallet"));
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it("should handle announcement handler errors gracefully", async () => {
|
|
338
|
+
vi.useFakeTimers();
|
|
339
|
+
|
|
340
|
+
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
341
|
+
|
|
342
|
+
let eventHandler: ((event: CustomEvent) => void) | null = null;
|
|
343
|
+
|
|
344
|
+
(window.addEventListener as any).mockImplementation((event: string, handler: any) => {
|
|
345
|
+
if (event === "eip6963:announceProvider") {
|
|
346
|
+
eventHandler = handler;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
const promise = eip6963Wallets();
|
|
351
|
+
|
|
352
|
+
// Trigger the event with invalid data that will cause an error in the handler
|
|
353
|
+
setTimeout(() => {
|
|
354
|
+
if (eventHandler) {
|
|
355
|
+
// Pass invalid data that will cause the handler to throw
|
|
356
|
+
// The handler checks for wallet?.uuid, wallet?.name, etc.
|
|
357
|
+
// Passing null will cause errors when accessing properties
|
|
358
|
+
eventHandler({
|
|
359
|
+
detail: {
|
|
360
|
+
info: null, // Invalid info - missing required fields
|
|
361
|
+
provider: null,
|
|
362
|
+
},
|
|
363
|
+
} as any);
|
|
364
|
+
}
|
|
365
|
+
}, 10);
|
|
366
|
+
|
|
367
|
+
vi.advanceTimersByTime(1000);
|
|
368
|
+
const result = await promise;
|
|
369
|
+
|
|
370
|
+
expect(result).toEqual([]);
|
|
371
|
+
// The error should be caught and logged by the handler's try-catch
|
|
372
|
+
// Note: The handler catches errors and logs them, so console.warn should be called
|
|
373
|
+
// But if the error happens before the try-catch, it might not be logged
|
|
374
|
+
// So we just verify the result is empty (error was handled)
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProviderStandard } from "@tomo-inc/wallet-utils";
|
|
1
|
+
import { ProviderProtocol, ProviderStandard } from "@tomo-inc/wallet-utils";
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import { walletStandardWallets } from "../wallets/wallet-standard";
|
|
4
4
|
|
|
@@ -63,7 +63,7 @@ describe("wallet-standard", () => {
|
|
|
63
63
|
|
|
64
64
|
expect(result.solanaWallets).toHaveLength(1);
|
|
65
65
|
expect(result.solanaWallets[0].info.name).toBe("Solana Wallet");
|
|
66
|
-
expect(result.solanaWallets[0].connectors.solana?.protocol).toBe(
|
|
66
|
+
expect(result.solanaWallets[0].connectors.solana?.protocol).toBe(ProviderProtocol.INJECT);
|
|
67
67
|
expect(result.solanaWallets[0].isInstalled).toBe(true);
|
|
68
68
|
});
|
|
69
69
|
|
|
@@ -86,7 +86,7 @@ describe("wallet-standard", () => {
|
|
|
86
86
|
|
|
87
87
|
expect(result.aptosWallets).toHaveLength(1);
|
|
88
88
|
expect(result.aptosWallets[0].info.name).toBe("Aptos Wallet");
|
|
89
|
-
expect(result.aptosWallets[0].connectors.aptos?.protocol).toBe(
|
|
89
|
+
expect(result.aptosWallets[0].connectors.aptos?.protocol).toBe(ProviderProtocol.INJECT);
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
it("should detect Sui wallets", async () => {
|
|
@@ -210,6 +210,44 @@ describe("wallet-standard", () => {
|
|
|
210
210
|
expect(result.solanaWallets).toHaveLength(1);
|
|
211
211
|
});
|
|
212
212
|
|
|
213
|
+
it("should process delayed wallets when getWallets returns more after delay", async () => {
|
|
214
|
+
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
215
|
+
const firstBatch = [
|
|
216
|
+
{
|
|
217
|
+
name: "First Solana",
|
|
218
|
+
icon: "icon.png",
|
|
219
|
+
chains: ["solana:mainnet"],
|
|
220
|
+
features: {
|
|
221
|
+
"solana:signTransaction": {},
|
|
222
|
+
"solana:signMessage": {},
|
|
223
|
+
"standard:connect": { connect: vi.fn() },
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
const secondBatch = [
|
|
228
|
+
...firstBatch,
|
|
229
|
+
{
|
|
230
|
+
name: "Delayed Wallet",
|
|
231
|
+
icon: "delayed.png",
|
|
232
|
+
chains: [],
|
|
233
|
+
features: {},
|
|
234
|
+
},
|
|
235
|
+
];
|
|
236
|
+
let getCallCount = 0;
|
|
237
|
+
const originalGet = mockWalletsAPI.get;
|
|
238
|
+
mockWalletsAPI.get = vi.fn().mockImplementation(() => {
|
|
239
|
+
getCallCount++;
|
|
240
|
+
return getCallCount === 1 ? firstBatch : secondBatch;
|
|
241
|
+
});
|
|
242
|
+
const promise = walletStandardWallets();
|
|
243
|
+
vi.advanceTimersByTime(500);
|
|
244
|
+
const result = await promise;
|
|
245
|
+
mockWalletsAPI.get = originalGet;
|
|
246
|
+
expect(result.solanaWallets).toHaveLength(1);
|
|
247
|
+
expect(result.solanaWallets[0].info.name).toBe("First Solana");
|
|
248
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith("[wallet-standard] Processing delayed wallet:", "Delayed Wallet");
|
|
249
|
+
});
|
|
250
|
+
|
|
213
251
|
it("should handle errors gracefully", async () => {
|
|
214
252
|
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
215
253
|
|