@meshconnect/uwc-bridge-child 0.0.3 → 0.1.0
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/BridgeChild.d.ts +5 -11
- package/dist/BridgeChild.d.ts.map +1 -1
- package/dist/BridgeChild.js +31 -13
- package/dist/BridgeChild.js.map +1 -1
- package/dist/BridgeChild.test.d.ts +2 -0
- package/dist/BridgeChild.test.d.ts.map +1 -0
- package/dist/BridgeChild.test.js +281 -0
- package/dist/BridgeChild.test.js.map +1 -0
- package/package.json +2 -3
- package/src/BridgeChild.test.ts +352 -0
- package/src/BridgeChild.ts +44 -15
package/dist/BridgeChild.d.ts
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import * as Comlink from 'comlink';
|
|
2
|
-
interface ParentAPI {
|
|
3
|
-
eip6963Wallets: unknown[];
|
|
4
|
-
eip6963WalletsReady: boolean;
|
|
5
|
-
walletStandardWallets: unknown[];
|
|
6
|
-
walletStandardWalletsReady: boolean;
|
|
7
|
-
}
|
|
8
1
|
export declare class BridgeChild {
|
|
9
2
|
private parentAPI?;
|
|
10
|
-
|
|
3
|
+
private tronInjectedIds;
|
|
4
|
+
private tronDiscoveryTriggered;
|
|
5
|
+
constructor(options?: {
|
|
6
|
+
tronInjectedIds?: string[];
|
|
7
|
+
});
|
|
11
8
|
private initializeConnection;
|
|
12
9
|
private pollForWallets;
|
|
13
10
|
private checkWallets;
|
|
14
|
-
getParentAPI(): Comlink.Remote<ParentAPI> | undefined;
|
|
15
|
-
isConnected(): boolean;
|
|
16
11
|
}
|
|
17
|
-
export {};
|
|
18
12
|
//# sourceMappingURL=BridgeChild.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BridgeChild.d.ts","sourceRoot":"","sources":["../src/BridgeChild.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BridgeChild.d.ts","sourceRoot":"","sources":["../src/BridgeChild.ts"],"names":[],"mappings":"AAgBA,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAC,CAA2B;IAC7C,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,sBAAsB,CAAQ;gBAE1B,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;YAKtC,oBAAoB;YAiBpB,cAAc;YAkDd,YAAY;CAmF3B"}
|
package/dist/BridgeChild.js
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
import * as Comlink from 'comlink';
|
|
4
4
|
export class BridgeChild {
|
|
5
5
|
parentAPI;
|
|
6
|
-
|
|
6
|
+
tronInjectedIds;
|
|
7
|
+
tronDiscoveryTriggered = false;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.tronInjectedIds = options?.tronInjectedIds ?? [];
|
|
7
10
|
this.initializeConnection();
|
|
8
11
|
}
|
|
9
12
|
async initializeConnection() {
|
|
@@ -11,7 +14,7 @@ export class BridgeChild {
|
|
|
11
14
|
return;
|
|
12
15
|
}
|
|
13
16
|
window.UWCBridgeChildInitialized = true;
|
|
14
|
-
this.parentAPI = Comlink.wrap(Comlink.windowEndpoint(window.parent, self,
|
|
17
|
+
this.parentAPI = Comlink.wrap(Comlink.windowEndpoint(window.parent, self, new URL(document.referrer).origin));
|
|
15
18
|
this.pollForWallets();
|
|
16
19
|
}
|
|
17
20
|
async pollForWallets() {
|
|
@@ -26,7 +29,8 @@ export class BridgeChild {
|
|
|
26
29
|
// Check if global variables are already set
|
|
27
30
|
if ((window.eip6963Wallets && window.eip6963Wallets.length > 0) ||
|
|
28
31
|
(window.walletStandardWallets &&
|
|
29
|
-
window.walletStandardWallets.length > 0)
|
|
32
|
+
window.walletStandardWallets.length > 0) ||
|
|
33
|
+
(window.tronWallets && window.tronWallets.length > 0)) {
|
|
30
34
|
return;
|
|
31
35
|
}
|
|
32
36
|
if (!this.parentAPI) {
|
|
@@ -35,7 +39,7 @@ export class BridgeChild {
|
|
|
35
39
|
}
|
|
36
40
|
// Create a timeout promise to prevent hanging
|
|
37
41
|
const timeoutPromise = new Promise((_, reject) => {
|
|
38
|
-
setTimeout(() => reject(new Error('Timeout accessing parent API')),
|
|
42
|
+
setTimeout(() => reject(new Error('Timeout accessing parent API')), 100);
|
|
39
43
|
});
|
|
40
44
|
// Try to check wallets with a timeout
|
|
41
45
|
Promise.race([this.checkWallets(), timeoutPromise])
|
|
@@ -56,10 +60,13 @@ export class BridgeChild {
|
|
|
56
60
|
}
|
|
57
61
|
async checkWallets() {
|
|
58
62
|
try {
|
|
59
|
-
//
|
|
63
|
+
//start tron walletdiscovery with provided IDs
|
|
64
|
+
await this.parentAPI?.discoverTronWallets(this.tronInjectedIds);
|
|
65
|
+
// Check if EIP6963, Tron and Wallet Standard wallets are ready
|
|
60
66
|
const eip6963Ready = await this.parentAPI?.eip6963WalletsReady;
|
|
61
67
|
const walletStandardReady = await this.parentAPI?.walletStandardWalletsReady;
|
|
62
|
-
|
|
68
|
+
const tronDiscoveryReady = await this.parentAPI?.tronWalletsReady;
|
|
69
|
+
if (!eip6963Ready || !walletStandardReady || !tronDiscoveryReady) {
|
|
63
70
|
return 'continue';
|
|
64
71
|
}
|
|
65
72
|
// Get EIP6963 wallets
|
|
@@ -92,20 +99,31 @@ export class BridgeChild {
|
|
|
92
99
|
walletStandardWallets.push(wallet);
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
|
-
//
|
|
102
|
+
// Get Tron wallets - create local wrapper objects because Comlink proxies
|
|
103
|
+
// don't support typeof checks, optional chaining, or sync property access
|
|
104
|
+
const availableTronWallets = await this.parentAPI.tronWallets.length;
|
|
105
|
+
const tronWallets = [];
|
|
106
|
+
if (availableTronWallets > 0) {
|
|
107
|
+
for (let index = 0; index < availableTronWallets; index++) {
|
|
108
|
+
// const providerProxy = this.parentAPI.tronWallets[index].provider
|
|
109
|
+
const wallet = {
|
|
110
|
+
uuid: await this.parentAPI.tronWallets[index].uuid,
|
|
111
|
+
name: await this.parentAPI.tronWallets[index].name,
|
|
112
|
+
injectedId: await this.parentAPI.tronWallets[index].injectedId,
|
|
113
|
+
provider: this.parentAPI.tronWallets[index].provider
|
|
114
|
+
};
|
|
115
|
+
tronWallets.push(wallet);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Set all wallet types on window
|
|
96
119
|
window.eip6963Wallets = eip6963Wallets;
|
|
97
120
|
window.walletStandardWallets = walletStandardWallets;
|
|
121
|
+
window.tronWallets = tronWallets;
|
|
98
122
|
return 'stop';
|
|
99
123
|
}
|
|
100
124
|
catch {
|
|
101
125
|
return 'continue';
|
|
102
126
|
}
|
|
103
127
|
}
|
|
104
|
-
getParentAPI() {
|
|
105
|
-
return this.parentAPI;
|
|
106
|
-
}
|
|
107
|
-
isConnected() {
|
|
108
|
-
return this.parentAPI !== undefined;
|
|
109
|
-
}
|
|
110
128
|
}
|
|
111
129
|
//# sourceMappingURL=BridgeChild.js.map
|
package/dist/BridgeChild.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BridgeChild.js","sourceRoot":"","sources":["../src/BridgeChild.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,cAAc;AAEd,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"BridgeChild.js","sourceRoot":"","sources":["../src/BridgeChild.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BridgeChild.test.d.ts","sourceRoot":"","sources":["../src/BridgeChild.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
// Create a mock parentAPI that simulates what Comlink.wrap returns
|
|
3
|
+
const createMockParentAPI = (opts = {}) => ({
|
|
4
|
+
eip6963WalletsReady: opts.eip6963Ready ?? true,
|
|
5
|
+
walletStandardWalletsReady: opts.walletStandardReady ?? true,
|
|
6
|
+
tronWalletsReady: opts.tronReady ?? true,
|
|
7
|
+
eip6963Wallets: opts.eip6963Wallets ?? [],
|
|
8
|
+
walletStandardWallets: opts.walletStandardWallets ?? [],
|
|
9
|
+
tronWallets: opts.tronWallets ?? [],
|
|
10
|
+
discoverTronWallets: vi.fn()
|
|
11
|
+
});
|
|
12
|
+
let mockWrappedAPI = null;
|
|
13
|
+
// Mock Comlink
|
|
14
|
+
vi.mock('comlink', () => ({
|
|
15
|
+
wrap: vi.fn(() => mockWrappedAPI),
|
|
16
|
+
windowEndpoint: vi.fn().mockReturnValue({})
|
|
17
|
+
}));
|
|
18
|
+
// Store original window properties
|
|
19
|
+
const originalParent = window.parent;
|
|
20
|
+
const originalReferrer = Object.getOwnPropertyDescriptor(document, 'referrer');
|
|
21
|
+
describe('BridgeChild', () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
vi.clearAllMocks();
|
|
24
|
+
vi.useFakeTimers();
|
|
25
|
+
vi.resetModules();
|
|
26
|
+
// Reset window globals
|
|
27
|
+
delete window.UWCBridgeChildInitialized;
|
|
28
|
+
delete window.eip6963Wallets;
|
|
29
|
+
delete window.walletStandardWallets;
|
|
30
|
+
delete window.tronWallets;
|
|
31
|
+
mockWrappedAPI = createMockParentAPI();
|
|
32
|
+
// Mock document.referrer
|
|
33
|
+
Object.defineProperty(document, 'referrer', {
|
|
34
|
+
value: 'https://parent.example.com/page',
|
|
35
|
+
writable: true,
|
|
36
|
+
configurable: true
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
vi.useRealTimers();
|
|
41
|
+
vi.restoreAllMocks();
|
|
42
|
+
// Cleanup window globals
|
|
43
|
+
delete window.UWCBridgeChildInitialized;
|
|
44
|
+
delete window.eip6963Wallets;
|
|
45
|
+
delete window.walletStandardWallets;
|
|
46
|
+
delete window.tronWallets;
|
|
47
|
+
// Restore document.referrer
|
|
48
|
+
if (originalReferrer) {
|
|
49
|
+
Object.defineProperty(document, 'referrer', originalReferrer);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
// Helper to create a BridgeChild by simulating iframe context
|
|
53
|
+
const createBridgeChildInIframe = async (options) => {
|
|
54
|
+
// Mock window.parent to be different from window (iframe context)
|
|
55
|
+
Object.defineProperty(window, 'parent', {
|
|
56
|
+
value: { postMessage: vi.fn() },
|
|
57
|
+
writable: true,
|
|
58
|
+
configurable: true
|
|
59
|
+
});
|
|
60
|
+
const { BridgeChild } = await import('./BridgeChild');
|
|
61
|
+
const child = new BridgeChild(options);
|
|
62
|
+
// Restore parent after construction
|
|
63
|
+
Object.defineProperty(window, 'parent', {
|
|
64
|
+
value: originalParent,
|
|
65
|
+
writable: true,
|
|
66
|
+
configurable: true
|
|
67
|
+
});
|
|
68
|
+
return child;
|
|
69
|
+
};
|
|
70
|
+
describe('constructor', () => {
|
|
71
|
+
it('should accept empty options', async () => {
|
|
72
|
+
const child = await createBridgeChildInIframe();
|
|
73
|
+
expect(child).toBeDefined();
|
|
74
|
+
});
|
|
75
|
+
it('should accept tronInjectedIds option', async () => {
|
|
76
|
+
const child = await createBridgeChildInIframe({
|
|
77
|
+
tronInjectedIds: ['tronLink']
|
|
78
|
+
});
|
|
79
|
+
expect(child).toBeDefined();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('initializeConnection', () => {
|
|
83
|
+
it('should not initialize when window.parent equals window (not in iframe)', async () => {
|
|
84
|
+
const Comlink = await import('comlink');
|
|
85
|
+
// window.parent === window means we're NOT in an iframe
|
|
86
|
+
Object.defineProperty(window, 'parent', {
|
|
87
|
+
value: window,
|
|
88
|
+
writable: true,
|
|
89
|
+
configurable: true
|
|
90
|
+
});
|
|
91
|
+
const { BridgeChild } = await import('./BridgeChild');
|
|
92
|
+
new BridgeChild();
|
|
93
|
+
await vi.advanceTimersByTimeAsync(200);
|
|
94
|
+
expect(Comlink.wrap).not.toHaveBeenCalled();
|
|
95
|
+
expect(window.UWCBridgeChildInitialized).toBeUndefined();
|
|
96
|
+
Object.defineProperty(window, 'parent', {
|
|
97
|
+
value: originalParent,
|
|
98
|
+
writable: true,
|
|
99
|
+
configurable: true
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it('should set UWCBridgeChildInitialized when in iframe', async () => {
|
|
103
|
+
await createBridgeChildInIframe();
|
|
104
|
+
expect(window.UWCBridgeChildInitialized).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
it('should call Comlink.wrap and windowEndpoint', async () => {
|
|
107
|
+
const Comlink = await import('comlink');
|
|
108
|
+
await createBridgeChildInIframe();
|
|
109
|
+
expect(Comlink.windowEndpoint).toHaveBeenCalled();
|
|
110
|
+
expect(Comlink.wrap).toHaveBeenCalled();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe('wallet polling', () => {
|
|
114
|
+
it('should set EIP6963 wallets on window when parent is ready', async () => {
|
|
115
|
+
const mockEip6963 = [
|
|
116
|
+
{
|
|
117
|
+
uuid: 'wallet-1',
|
|
118
|
+
name: 'MetaMask',
|
|
119
|
+
icon: 'mm-icon',
|
|
120
|
+
rdns: 'io.metamask',
|
|
121
|
+
provider: { request: vi.fn() }
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
mockWrappedAPI = createMockParentAPI({
|
|
125
|
+
eip6963Wallets: mockEip6963
|
|
126
|
+
});
|
|
127
|
+
await createBridgeChildInIframe();
|
|
128
|
+
// Allow poll cycle to complete
|
|
129
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
130
|
+
expect(window.eip6963Wallets).toBeDefined();
|
|
131
|
+
expect(window.eip6963Wallets).toHaveLength(1);
|
|
132
|
+
expect(window.eip6963Wallets[0].uuid).toBe('wallet-1');
|
|
133
|
+
});
|
|
134
|
+
it('should set Wallet Standard wallets on window', async () => {
|
|
135
|
+
const mockSolana = [
|
|
136
|
+
{
|
|
137
|
+
uuid: 'phantom-solana',
|
|
138
|
+
name: 'Phantom',
|
|
139
|
+
chains: ['solana:mainnet'],
|
|
140
|
+
features: ['standard:connect'],
|
|
141
|
+
adapter: {}
|
|
142
|
+
}
|
|
143
|
+
];
|
|
144
|
+
mockWrappedAPI = createMockParentAPI({
|
|
145
|
+
walletStandardWallets: mockSolana
|
|
146
|
+
});
|
|
147
|
+
await createBridgeChildInIframe();
|
|
148
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
149
|
+
expect(window.walletStandardWallets).toBeDefined();
|
|
150
|
+
expect(window.walletStandardWallets).toHaveLength(1);
|
|
151
|
+
expect(window.walletStandardWallets[0].name).toBe('Phantom');
|
|
152
|
+
});
|
|
153
|
+
it('should set Tron wallets on window', async () => {
|
|
154
|
+
const mockTron = [
|
|
155
|
+
{
|
|
156
|
+
uuid: 'tron-tronlink',
|
|
157
|
+
name: 'tronLink',
|
|
158
|
+
injectedId: 'tronLink',
|
|
159
|
+
provider: { tronWeb: {} }
|
|
160
|
+
}
|
|
161
|
+
];
|
|
162
|
+
mockWrappedAPI = createMockParentAPI({
|
|
163
|
+
tronWallets: mockTron
|
|
164
|
+
});
|
|
165
|
+
await createBridgeChildInIframe({ tronInjectedIds: ['tronLink'] });
|
|
166
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
167
|
+
expect(window.tronWallets).toBeDefined();
|
|
168
|
+
expect(window.tronWallets).toHaveLength(1);
|
|
169
|
+
expect(window.tronWallets[0].uuid).toBe('tron-tronlink');
|
|
170
|
+
});
|
|
171
|
+
it('should call discoverTronWallets with provided injectedIds', async () => {
|
|
172
|
+
mockWrappedAPI = createMockParentAPI();
|
|
173
|
+
await createBridgeChildInIframe({
|
|
174
|
+
tronInjectedIds: ['tronLink', 'tokenpocket.tron']
|
|
175
|
+
});
|
|
176
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
177
|
+
expect(mockWrappedAPI.discoverTronWallets).toHaveBeenCalledWith([
|
|
178
|
+
'tronLink',
|
|
179
|
+
'tokenpocket.tron'
|
|
180
|
+
]);
|
|
181
|
+
});
|
|
182
|
+
it('should continue polling when wallets are not ready', async () => {
|
|
183
|
+
mockWrappedAPI = createMockParentAPI({
|
|
184
|
+
eip6963Ready: false,
|
|
185
|
+
walletStandardReady: false,
|
|
186
|
+
tronReady: false
|
|
187
|
+
});
|
|
188
|
+
await createBridgeChildInIframe();
|
|
189
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
190
|
+
// Window globals should NOT be set when not ready
|
|
191
|
+
expect(window.eip6963Wallets).toBeUndefined();
|
|
192
|
+
});
|
|
193
|
+
it('should stop polling when wallets are already set on window', async () => {
|
|
194
|
+
// Pre-set wallets on window
|
|
195
|
+
;
|
|
196
|
+
window.eip6963Wallets = [{ uuid: 'existing' }];
|
|
197
|
+
mockWrappedAPI = createMockParentAPI();
|
|
198
|
+
await createBridgeChildInIframe();
|
|
199
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
200
|
+
// discoverTronWallets should not be called since polling stopped early
|
|
201
|
+
expect(mockWrappedAPI.discoverTronWallets).not.toHaveBeenCalled();
|
|
202
|
+
});
|
|
203
|
+
it('should handle errors gracefully and continue polling', async () => {
|
|
204
|
+
// First call throws, subsequent calls succeed
|
|
205
|
+
let callCount = 0;
|
|
206
|
+
const failingAPI = {
|
|
207
|
+
get eip6963WalletsReady() {
|
|
208
|
+
callCount++;
|
|
209
|
+
if (callCount <= 1) {
|
|
210
|
+
throw new Error('API not ready');
|
|
211
|
+
}
|
|
212
|
+
return true;
|
|
213
|
+
},
|
|
214
|
+
walletStandardWalletsReady: true,
|
|
215
|
+
tronWalletsReady: true,
|
|
216
|
+
eip6963Wallets: [],
|
|
217
|
+
walletStandardWallets: [],
|
|
218
|
+
tronWallets: [],
|
|
219
|
+
discoverTronWallets: vi.fn()
|
|
220
|
+
};
|
|
221
|
+
mockWrappedAPI = failingAPI;
|
|
222
|
+
await createBridgeChildInIframe();
|
|
223
|
+
await vi.advanceTimersByTimeAsync(1000);
|
|
224
|
+
// Should eventually succeed and set wallets
|
|
225
|
+
expect(window.eip6963Wallets).toBeDefined();
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
describe('checkWallets with all wallet types', () => {
|
|
229
|
+
it('should fetch all wallet types and set on window', async () => {
|
|
230
|
+
const eip6963Wallets = [
|
|
231
|
+
{
|
|
232
|
+
uuid: 'mm-1',
|
|
233
|
+
name: 'MetaMask',
|
|
234
|
+
icon: 'mm-icon',
|
|
235
|
+
rdns: 'io.metamask',
|
|
236
|
+
provider: { request: vi.fn() }
|
|
237
|
+
}
|
|
238
|
+
];
|
|
239
|
+
const walletStandardWallets = [
|
|
240
|
+
{
|
|
241
|
+
uuid: 'phantom-1',
|
|
242
|
+
name: 'Phantom',
|
|
243
|
+
chains: ['solana:mainnet'],
|
|
244
|
+
features: ['standard:connect'],
|
|
245
|
+
adapter: { connect: vi.fn() }
|
|
246
|
+
}
|
|
247
|
+
];
|
|
248
|
+
const tronWallets = [
|
|
249
|
+
{
|
|
250
|
+
uuid: 'tron-tronlink',
|
|
251
|
+
name: 'tronLink',
|
|
252
|
+
injectedId: 'tronLink',
|
|
253
|
+
provider: { tronWeb: {} }
|
|
254
|
+
}
|
|
255
|
+
];
|
|
256
|
+
mockWrappedAPI = createMockParentAPI({
|
|
257
|
+
eip6963Wallets,
|
|
258
|
+
walletStandardWallets,
|
|
259
|
+
tronWallets
|
|
260
|
+
});
|
|
261
|
+
await createBridgeChildInIframe({ tronInjectedIds: ['tronLink'] });
|
|
262
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
263
|
+
expect(window.eip6963Wallets).toHaveLength(1);
|
|
264
|
+
expect(window.walletStandardWallets).toHaveLength(1);
|
|
265
|
+
expect(window.tronWallets).toHaveLength(1);
|
|
266
|
+
});
|
|
267
|
+
it('should handle empty wallet arrays', async () => {
|
|
268
|
+
mockWrappedAPI = createMockParentAPI({
|
|
269
|
+
eip6963Wallets: [],
|
|
270
|
+
walletStandardWallets: [],
|
|
271
|
+
tronWallets: []
|
|
272
|
+
});
|
|
273
|
+
await createBridgeChildInIframe();
|
|
274
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
275
|
+
expect(window.eip6963Wallets).toEqual([]);
|
|
276
|
+
expect(window.walletStandardWallets).toEqual([]);
|
|
277
|
+
expect(window.tronWallets).toEqual([]);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
//# sourceMappingURL=BridgeChild.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BridgeChild.test.js","sourceRoot":"","sources":["../src/BridgeChild.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshconnect/uwc-bridge-child",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Child iframe bridge for Universal Wallet Connector",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,9 +14,8 @@
|
|
|
14
14
|
"comlink": "^4.4.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"typescript": "^5.9.
|
|
17
|
+
"typescript": "^5.9.3"
|
|
18
18
|
},
|
|
19
|
-
"peerDependencies": {},
|
|
20
19
|
"files": [
|
|
21
20
|
"dist",
|
|
22
21
|
"src"
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
|
|
2
|
+
|
|
3
|
+
// Create a mock parentAPI that simulates what Comlink.wrap returns
|
|
4
|
+
const createMockParentAPI = (
|
|
5
|
+
opts: {
|
|
6
|
+
eip6963Ready?: boolean
|
|
7
|
+
walletStandardReady?: boolean
|
|
8
|
+
tronReady?: boolean
|
|
9
|
+
eip6963Wallets?: any[]
|
|
10
|
+
walletStandardWallets?: any[]
|
|
11
|
+
tronWallets?: any[]
|
|
12
|
+
} = {}
|
|
13
|
+
) => ({
|
|
14
|
+
eip6963WalletsReady: opts.eip6963Ready ?? true,
|
|
15
|
+
walletStandardWalletsReady: opts.walletStandardReady ?? true,
|
|
16
|
+
tronWalletsReady: opts.tronReady ?? true,
|
|
17
|
+
eip6963Wallets: opts.eip6963Wallets ?? [],
|
|
18
|
+
walletStandardWallets: opts.walletStandardWallets ?? [],
|
|
19
|
+
tronWallets: opts.tronWallets ?? [],
|
|
20
|
+
discoverTronWallets: vi.fn()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
let mockWrappedAPI: ReturnType<typeof createMockParentAPI> | null = null
|
|
24
|
+
|
|
25
|
+
// Mock Comlink
|
|
26
|
+
vi.mock('comlink', () => ({
|
|
27
|
+
wrap: vi.fn(() => mockWrappedAPI),
|
|
28
|
+
windowEndpoint: vi.fn().mockReturnValue({})
|
|
29
|
+
}))
|
|
30
|
+
|
|
31
|
+
// Store original window properties
|
|
32
|
+
const originalParent = window.parent
|
|
33
|
+
const originalReferrer = Object.getOwnPropertyDescriptor(document, 'referrer')
|
|
34
|
+
|
|
35
|
+
describe('BridgeChild', () => {
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
vi.clearAllMocks()
|
|
38
|
+
vi.useFakeTimers()
|
|
39
|
+
vi.resetModules()
|
|
40
|
+
|
|
41
|
+
// Reset window globals
|
|
42
|
+
delete (window as any).UWCBridgeChildInitialized
|
|
43
|
+
delete (window as any).eip6963Wallets
|
|
44
|
+
delete (window as any).walletStandardWallets
|
|
45
|
+
delete (window as any).tronWallets
|
|
46
|
+
|
|
47
|
+
mockWrappedAPI = createMockParentAPI()
|
|
48
|
+
|
|
49
|
+
// Mock document.referrer
|
|
50
|
+
Object.defineProperty(document, 'referrer', {
|
|
51
|
+
value: 'https://parent.example.com/page',
|
|
52
|
+
writable: true,
|
|
53
|
+
configurable: true
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
afterEach(() => {
|
|
58
|
+
vi.useRealTimers()
|
|
59
|
+
vi.restoreAllMocks()
|
|
60
|
+
|
|
61
|
+
// Cleanup window globals
|
|
62
|
+
delete (window as any).UWCBridgeChildInitialized
|
|
63
|
+
delete (window as any).eip6963Wallets
|
|
64
|
+
delete (window as any).walletStandardWallets
|
|
65
|
+
delete (window as any).tronWallets
|
|
66
|
+
|
|
67
|
+
// Restore document.referrer
|
|
68
|
+
if (originalReferrer) {
|
|
69
|
+
Object.defineProperty(document, 'referrer', originalReferrer)
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// Helper to create a BridgeChild by simulating iframe context
|
|
74
|
+
const createBridgeChildInIframe = async (options?: {
|
|
75
|
+
tronInjectedIds?: string[]
|
|
76
|
+
}) => {
|
|
77
|
+
// Mock window.parent to be different from window (iframe context)
|
|
78
|
+
Object.defineProperty(window, 'parent', {
|
|
79
|
+
value: { postMessage: vi.fn() },
|
|
80
|
+
writable: true,
|
|
81
|
+
configurable: true
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const { BridgeChild } = await import('./BridgeChild')
|
|
85
|
+
const child = new BridgeChild(options)
|
|
86
|
+
|
|
87
|
+
// Restore parent after construction
|
|
88
|
+
Object.defineProperty(window, 'parent', {
|
|
89
|
+
value: originalParent,
|
|
90
|
+
writable: true,
|
|
91
|
+
configurable: true
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
return child
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
describe('constructor', () => {
|
|
98
|
+
it('should accept empty options', async () => {
|
|
99
|
+
const child = await createBridgeChildInIframe()
|
|
100
|
+
expect(child).toBeDefined()
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('should accept tronInjectedIds option', async () => {
|
|
104
|
+
const child = await createBridgeChildInIframe({
|
|
105
|
+
tronInjectedIds: ['tronLink']
|
|
106
|
+
})
|
|
107
|
+
expect(child).toBeDefined()
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
describe('initializeConnection', () => {
|
|
112
|
+
it('should not initialize when window.parent equals window (not in iframe)', async () => {
|
|
113
|
+
const Comlink = await import('comlink')
|
|
114
|
+
|
|
115
|
+
// window.parent === window means we're NOT in an iframe
|
|
116
|
+
Object.defineProperty(window, 'parent', {
|
|
117
|
+
value: window,
|
|
118
|
+
writable: true,
|
|
119
|
+
configurable: true
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
const { BridgeChild } = await import('./BridgeChild')
|
|
123
|
+
new BridgeChild()
|
|
124
|
+
|
|
125
|
+
await vi.advanceTimersByTimeAsync(200)
|
|
126
|
+
|
|
127
|
+
expect(Comlink.wrap).not.toHaveBeenCalled()
|
|
128
|
+
expect((window as any).UWCBridgeChildInitialized).toBeUndefined()
|
|
129
|
+
|
|
130
|
+
Object.defineProperty(window, 'parent', {
|
|
131
|
+
value: originalParent,
|
|
132
|
+
writable: true,
|
|
133
|
+
configurable: true
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('should set UWCBridgeChildInitialized when in iframe', async () => {
|
|
138
|
+
await createBridgeChildInIframe()
|
|
139
|
+
|
|
140
|
+
expect((window as any).UWCBridgeChildInitialized).toBe(true)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('should call Comlink.wrap and windowEndpoint', async () => {
|
|
144
|
+
const Comlink = await import('comlink')
|
|
145
|
+
|
|
146
|
+
await createBridgeChildInIframe()
|
|
147
|
+
|
|
148
|
+
expect(Comlink.windowEndpoint).toHaveBeenCalled()
|
|
149
|
+
expect(Comlink.wrap).toHaveBeenCalled()
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
describe('wallet polling', () => {
|
|
154
|
+
it('should set EIP6963 wallets on window when parent is ready', async () => {
|
|
155
|
+
const mockEip6963 = [
|
|
156
|
+
{
|
|
157
|
+
uuid: 'wallet-1',
|
|
158
|
+
name: 'MetaMask',
|
|
159
|
+
icon: 'mm-icon',
|
|
160
|
+
rdns: 'io.metamask',
|
|
161
|
+
provider: { request: vi.fn() }
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
mockWrappedAPI = createMockParentAPI({
|
|
166
|
+
eip6963Wallets: mockEip6963
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
await createBridgeChildInIframe()
|
|
170
|
+
|
|
171
|
+
// Allow poll cycle to complete
|
|
172
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
173
|
+
|
|
174
|
+
expect((window as any).eip6963Wallets).toBeDefined()
|
|
175
|
+
expect((window as any).eip6963Wallets).toHaveLength(1)
|
|
176
|
+
expect((window as any).eip6963Wallets[0].uuid).toBe('wallet-1')
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it('should set Wallet Standard wallets on window', async () => {
|
|
180
|
+
const mockSolana = [
|
|
181
|
+
{
|
|
182
|
+
uuid: 'phantom-solana',
|
|
183
|
+
name: 'Phantom',
|
|
184
|
+
chains: ['solana:mainnet'],
|
|
185
|
+
features: ['standard:connect'],
|
|
186
|
+
adapter: {}
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
mockWrappedAPI = createMockParentAPI({
|
|
191
|
+
walletStandardWallets: mockSolana
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
await createBridgeChildInIframe()
|
|
195
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
196
|
+
|
|
197
|
+
expect((window as any).walletStandardWallets).toBeDefined()
|
|
198
|
+
expect((window as any).walletStandardWallets).toHaveLength(1)
|
|
199
|
+
expect((window as any).walletStandardWallets[0].name).toBe('Phantom')
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('should set Tron wallets on window', async () => {
|
|
203
|
+
const mockTron = [
|
|
204
|
+
{
|
|
205
|
+
uuid: 'tron-tronlink',
|
|
206
|
+
name: 'tronLink',
|
|
207
|
+
injectedId: 'tronLink',
|
|
208
|
+
provider: { tronWeb: {} }
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
|
|
212
|
+
mockWrappedAPI = createMockParentAPI({
|
|
213
|
+
tronWallets: mockTron
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
await createBridgeChildInIframe({ tronInjectedIds: ['tronLink'] })
|
|
217
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
218
|
+
|
|
219
|
+
expect((window as any).tronWallets).toBeDefined()
|
|
220
|
+
expect((window as any).tronWallets).toHaveLength(1)
|
|
221
|
+
expect((window as any).tronWallets[0].uuid).toBe('tron-tronlink')
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
it('should call discoverTronWallets with provided injectedIds', async () => {
|
|
225
|
+
mockWrappedAPI = createMockParentAPI()
|
|
226
|
+
|
|
227
|
+
await createBridgeChildInIframe({
|
|
228
|
+
tronInjectedIds: ['tronLink', 'tokenpocket.tron']
|
|
229
|
+
})
|
|
230
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
231
|
+
|
|
232
|
+
expect(mockWrappedAPI!.discoverTronWallets).toHaveBeenCalledWith([
|
|
233
|
+
'tronLink',
|
|
234
|
+
'tokenpocket.tron'
|
|
235
|
+
])
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
it('should continue polling when wallets are not ready', async () => {
|
|
239
|
+
mockWrappedAPI = createMockParentAPI({
|
|
240
|
+
eip6963Ready: false,
|
|
241
|
+
walletStandardReady: false,
|
|
242
|
+
tronReady: false
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
await createBridgeChildInIframe()
|
|
246
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
247
|
+
|
|
248
|
+
// Window globals should NOT be set when not ready
|
|
249
|
+
expect((window as any).eip6963Wallets).toBeUndefined()
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('should stop polling when wallets are already set on window', async () => {
|
|
253
|
+
// Pre-set wallets on window
|
|
254
|
+
;(window as any).eip6963Wallets = [{ uuid: 'existing' }]
|
|
255
|
+
|
|
256
|
+
mockWrappedAPI = createMockParentAPI()
|
|
257
|
+
|
|
258
|
+
await createBridgeChildInIframe()
|
|
259
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
260
|
+
|
|
261
|
+
// discoverTronWallets should not be called since polling stopped early
|
|
262
|
+
expect(mockWrappedAPI!.discoverTronWallets).not.toHaveBeenCalled()
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
it('should handle errors gracefully and continue polling', async () => {
|
|
266
|
+
// First call throws, subsequent calls succeed
|
|
267
|
+
let callCount = 0
|
|
268
|
+
const failingAPI = {
|
|
269
|
+
get eip6963WalletsReady() {
|
|
270
|
+
callCount++
|
|
271
|
+
if (callCount <= 1) {
|
|
272
|
+
throw new Error('API not ready')
|
|
273
|
+
}
|
|
274
|
+
return true
|
|
275
|
+
},
|
|
276
|
+
walletStandardWalletsReady: true,
|
|
277
|
+
tronWalletsReady: true,
|
|
278
|
+
eip6963Wallets: [],
|
|
279
|
+
walletStandardWallets: [],
|
|
280
|
+
tronWallets: [],
|
|
281
|
+
discoverTronWallets: vi.fn()
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
mockWrappedAPI = failingAPI as any
|
|
285
|
+
|
|
286
|
+
await createBridgeChildInIframe()
|
|
287
|
+
await vi.advanceTimersByTimeAsync(1000)
|
|
288
|
+
|
|
289
|
+
// Should eventually succeed and set wallets
|
|
290
|
+
expect((window as any).eip6963Wallets).toBeDefined()
|
|
291
|
+
})
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
describe('checkWallets with all wallet types', () => {
|
|
295
|
+
it('should fetch all wallet types and set on window', async () => {
|
|
296
|
+
const eip6963Wallets = [
|
|
297
|
+
{
|
|
298
|
+
uuid: 'mm-1',
|
|
299
|
+
name: 'MetaMask',
|
|
300
|
+
icon: 'mm-icon',
|
|
301
|
+
rdns: 'io.metamask',
|
|
302
|
+
provider: { request: vi.fn() }
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
const walletStandardWallets = [
|
|
306
|
+
{
|
|
307
|
+
uuid: 'phantom-1',
|
|
308
|
+
name: 'Phantom',
|
|
309
|
+
chains: ['solana:mainnet'],
|
|
310
|
+
features: ['standard:connect'],
|
|
311
|
+
adapter: { connect: vi.fn() }
|
|
312
|
+
}
|
|
313
|
+
]
|
|
314
|
+
const tronWallets = [
|
|
315
|
+
{
|
|
316
|
+
uuid: 'tron-tronlink',
|
|
317
|
+
name: 'tronLink',
|
|
318
|
+
injectedId: 'tronLink',
|
|
319
|
+
provider: { tronWeb: {} }
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
|
|
323
|
+
mockWrappedAPI = createMockParentAPI({
|
|
324
|
+
eip6963Wallets,
|
|
325
|
+
walletStandardWallets,
|
|
326
|
+
tronWallets
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
await createBridgeChildInIframe({ tronInjectedIds: ['tronLink'] })
|
|
330
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
331
|
+
|
|
332
|
+
expect((window as any).eip6963Wallets).toHaveLength(1)
|
|
333
|
+
expect((window as any).walletStandardWallets).toHaveLength(1)
|
|
334
|
+
expect((window as any).tronWallets).toHaveLength(1)
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
it('should handle empty wallet arrays', async () => {
|
|
338
|
+
mockWrappedAPI = createMockParentAPI({
|
|
339
|
+
eip6963Wallets: [],
|
|
340
|
+
walletStandardWallets: [],
|
|
341
|
+
tronWallets: []
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
await createBridgeChildInIframe()
|
|
345
|
+
await vi.advanceTimersByTimeAsync(500)
|
|
346
|
+
|
|
347
|
+
expect((window as any).eip6963Wallets).toEqual([])
|
|
348
|
+
expect((window as any).walletStandardWallets).toEqual([])
|
|
349
|
+
expect((window as any).tronWallets).toEqual([])
|
|
350
|
+
})
|
|
351
|
+
})
|
|
352
|
+
})
|
package/src/BridgeChild.ts
CHANGED
|
@@ -9,12 +9,18 @@ interface ParentAPI {
|
|
|
9
9
|
eip6963WalletsReady: boolean
|
|
10
10
|
walletStandardWallets: unknown[]
|
|
11
11
|
walletStandardWalletsReady: boolean
|
|
12
|
+
tronWallets: unknown[]
|
|
13
|
+
tronWalletsReady: boolean
|
|
14
|
+
discoverTronWallets: (injectedIds: string[]) => void
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
export class BridgeChild {
|
|
15
18
|
private parentAPI?: Comlink.Remote<ParentAPI>
|
|
19
|
+
private tronInjectedIds: string[]
|
|
20
|
+
private tronDiscoveryTriggered = false
|
|
16
21
|
|
|
17
|
-
constructor() {
|
|
22
|
+
constructor(options?: { tronInjectedIds?: string[] }) {
|
|
23
|
+
this.tronInjectedIds = options?.tronInjectedIds ?? []
|
|
18
24
|
this.initializeConnection()
|
|
19
25
|
}
|
|
20
26
|
|
|
@@ -25,7 +31,11 @@ export class BridgeChild {
|
|
|
25
31
|
window.UWCBridgeChildInitialized = true
|
|
26
32
|
|
|
27
33
|
this.parentAPI = Comlink.wrap<ParentAPI>(
|
|
28
|
-
Comlink.windowEndpoint(
|
|
34
|
+
Comlink.windowEndpoint(
|
|
35
|
+
window.parent,
|
|
36
|
+
self,
|
|
37
|
+
new URL(document.referrer).origin
|
|
38
|
+
)
|
|
29
39
|
)
|
|
30
40
|
|
|
31
41
|
this.pollForWallets()
|
|
@@ -46,7 +56,8 @@ export class BridgeChild {
|
|
|
46
56
|
if (
|
|
47
57
|
(window.eip6963Wallets && window.eip6963Wallets.length > 0) ||
|
|
48
58
|
(window.walletStandardWallets &&
|
|
49
|
-
window.walletStandardWallets.length > 0)
|
|
59
|
+
window.walletStandardWallets.length > 0) ||
|
|
60
|
+
(window.tronWallets && window.tronWallets.length > 0)
|
|
50
61
|
) {
|
|
51
62
|
return
|
|
52
63
|
}
|
|
@@ -58,7 +69,7 @@ export class BridgeChild {
|
|
|
58
69
|
|
|
59
70
|
// Create a timeout promise to prevent hanging
|
|
60
71
|
const timeoutPromise = new Promise((_, reject) => {
|
|
61
|
-
setTimeout(() => reject(new Error('Timeout accessing parent API')),
|
|
72
|
+
setTimeout(() => reject(new Error('Timeout accessing parent API')), 100)
|
|
62
73
|
})
|
|
63
74
|
|
|
64
75
|
// Try to check wallets with a timeout
|
|
@@ -82,12 +93,16 @@ export class BridgeChild {
|
|
|
82
93
|
|
|
83
94
|
private async checkWallets(): Promise<string> {
|
|
84
95
|
try {
|
|
85
|
-
//
|
|
96
|
+
//start tron walletdiscovery with provided IDs
|
|
97
|
+
await this.parentAPI?.discoverTronWallets(this.tronInjectedIds)
|
|
98
|
+
|
|
99
|
+
// Check if EIP6963, Tron and Wallet Standard wallets are ready
|
|
86
100
|
const eip6963Ready = await this.parentAPI?.eip6963WalletsReady
|
|
87
101
|
const walletStandardReady =
|
|
88
102
|
await this.parentAPI?.walletStandardWalletsReady
|
|
103
|
+
const tronDiscoveryReady = await this.parentAPI?.tronWalletsReady
|
|
89
104
|
|
|
90
|
-
if (!eip6963Ready || !walletStandardReady) {
|
|
105
|
+
if (!eip6963Ready || !walletStandardReady || !tronDiscoveryReady) {
|
|
91
106
|
return 'continue'
|
|
92
107
|
}
|
|
93
108
|
|
|
@@ -128,21 +143,35 @@ export class BridgeChild {
|
|
|
128
143
|
}
|
|
129
144
|
}
|
|
130
145
|
|
|
131
|
-
//
|
|
146
|
+
// Get Tron wallets - create local wrapper objects because Comlink proxies
|
|
147
|
+
// don't support typeof checks, optional chaining, or sync property access
|
|
148
|
+
const availableTronWallets = await this.parentAPI.tronWallets.length
|
|
149
|
+
|
|
150
|
+
const tronWallets = []
|
|
151
|
+
|
|
152
|
+
if (availableTronWallets > 0) {
|
|
153
|
+
for (let index = 0; index < availableTronWallets; index++) {
|
|
154
|
+
// const providerProxy = this.parentAPI.tronWallets[index].provider
|
|
155
|
+
|
|
156
|
+
const wallet = {
|
|
157
|
+
uuid: await this.parentAPI.tronWallets[index].uuid,
|
|
158
|
+
name: await this.parentAPI.tronWallets[index].name,
|
|
159
|
+
injectedId: await this.parentAPI.tronWallets[index].injectedId,
|
|
160
|
+
provider: this.parentAPI.tronWallets[index].provider
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
tronWallets.push(wallet)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Set all wallet types on window
|
|
132
168
|
window.eip6963Wallets = eip6963Wallets
|
|
133
169
|
window.walletStandardWallets = walletStandardWallets
|
|
170
|
+
window.tronWallets = tronWallets
|
|
134
171
|
|
|
135
172
|
return 'stop'
|
|
136
173
|
} catch {
|
|
137
174
|
return 'continue'
|
|
138
175
|
}
|
|
139
176
|
}
|
|
140
|
-
|
|
141
|
-
getParentAPI(): Comlink.Remote<ParentAPI> | undefined {
|
|
142
|
-
return this.parentAPI
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
isConnected(): boolean {
|
|
146
|
-
return this.parentAPI !== undefined
|
|
147
|
-
}
|
|
148
177
|
}
|