Skip to content

Commit 3ff7401

Browse files
authored
fix: integration with default transport (#1357)
1 parent ecba1b4 commit 3ff7401

File tree

3 files changed

+46
-20
lines changed

3 files changed

+46
-20
lines changed

packages/sdk-multichain/src/multichain/transports/default/index.ts

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,63 @@ import type { CaipAccountId } from '@metamask/utils';
33
import type { ExtendedTransport, RPCAPI, Scope, SessionData } from 'src/domain';
44
import { addValidAccounts, getOptionalScopes, getValidAccounts } from 'src/multichain/utils';
55

6+
const DEFAULT_REQUEST_TIMEOUT = 60 * 1000;
7+
68
export class DefaultTransport implements ExtendedTransport {
9+
#notificationCallbacks: Set<(data: unknown) => void> = new Set();
710
#requestId = 0;
811
#transport: Transport = getDefaultTransport();
12+
#defaultRequestOptions = {
13+
timeout: DEFAULT_REQUEST_TIMEOUT,
14+
};
15+
16+
#notifyCallbacks(data: unknown) {
17+
for (const cb of this.#notificationCallbacks) {
18+
try {
19+
cb(data);
20+
} catch (err) {
21+
console.log('[WindowPostMessageTransport] notifyCallbacks error:', err);
22+
}
23+
}
24+
}
925

1026
async connect(options?: { scopes: Scope[]; caipAccountIds: CaipAccountId[] }): Promise<void> {
1127
await this.#transport.connect();
28+
1229
//Get wallet session
13-
const sessionRequest = await this.request({ method: 'wallet_getSession' });
30+
const sessionRequest = await this.request({ method: 'wallet_getSession' }, this.#defaultRequestOptions);
1431
let walletSession = sessionRequest.result as SessionData;
1532
if (walletSession && options) {
1633
const currentScopes = Object.keys(walletSession?.sessionScopes ?? {}) as Scope[];
1734
const proposedScopes = options?.scopes ?? [];
1835
const isSameScopes = currentScopes.every((scope) => proposedScopes.includes(scope)) && proposedScopes.every((scope) => currentScopes.includes(scope));
1936
if (!isSameScopes) {
20-
await this.request({ method: 'wallet_revokeSession', params: walletSession });
37+
await this.request({ method: 'wallet_revokeSession', params: walletSession }, this.#defaultRequestOptions);
2138
const optionalScopes = addValidAccounts(getOptionalScopes(options?.scopes ?? []), getValidAccounts(options?.caipAccountIds ?? []));
2239
const sessionRequest: CreateSessionParams<RPCAPI> = { optionalScopes };
23-
const response = await this.request({ method: 'wallet_createSession', params: sessionRequest });
40+
const response = await this.request({ method: 'wallet_createSession', params: sessionRequest }, this.#defaultRequestOptions);
41+
if (response.error) {
42+
throw new Error(response.error.message);
43+
}
2444
walletSession = response.result as SessionData;
2545
}
26-
} else {
46+
} else if (!walletSession) {
2747
const optionalScopes = addValidAccounts(getOptionalScopes(options?.scopes ?? []), getValidAccounts(options?.caipAccountIds ?? []));
2848
const sessionRequest: CreateSessionParams<RPCAPI> = { optionalScopes };
29-
await this.request({ method: 'wallet_createSession', params: sessionRequest });
49+
const response = await this.request({ method: 'wallet_createSession', params: sessionRequest }, this.#defaultRequestOptions);
50+
if (response.error) {
51+
throw new Error(response.error.message);
52+
}
53+
walletSession = response.result as SessionData;
3054
}
55+
this.#notifyCallbacks({
56+
method: 'wallet_sessionChanged',
57+
params: walletSession,
58+
});
3159
}
3260

3361
async disconnect(): Promise<void> {
62+
this.#notificationCallbacks.clear();
3463
return this.#transport.disconnect();
3564
}
3665

@@ -39,15 +68,14 @@ export class DefaultTransport implements ExtendedTransport {
3968
}
4069

4170
async request<TRequest extends TransportRequest, TResponse extends TransportResponse>(request: TRequest, options?: { timeout?: number }) {
42-
const requestWithId = {
43-
...request,
44-
jsonrpc: '2.0',
45-
id: `${this.#requestId++}`,
46-
};
47-
return this.#transport.request(requestWithId, options) as Promise<TResponse>;
71+
return this.#transport.request(request, options) as Promise<TResponse>;
4872
}
4973

5074
onNotification(callback: (data: unknown) => void) {
51-
return this.#transport.onNotification(callback);
75+
this.#transport.onNotification(callback);
76+
this.#notificationCallbacks.add(callback);
77+
return () => {
78+
this.#notificationCallbacks.delete(callback);
79+
};
5280
}
5381
}

packages/sdk-multichain/src/session.test.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,17 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
9898
if (platform === 'web') {
9999
t.expect(mockedData.mockDefaultTransport.request).toHaveBeenCalledWith(
100100
t.expect.objectContaining({
101-
jsonrpc: '2.0',
102101
method: 'wallet_getSession',
103102
}),
104103

105-
undefined,
104+
{ timeout: 60 * 1000 },
106105
);
107106
t.expect(mockedData.mockDefaultTransport.request).toHaveBeenCalledWith(
108107
t.expect.objectContaining({
109108
method: 'wallet_revokeSession',
110109
params: mockSessionData,
111110
}),
112-
undefined,
111+
{ timeout: 60 * 1000 },
113112
);
114113

115114
t.expect(mockedData.mockDefaultTransport.request).toHaveBeenCalledWith(
@@ -119,7 +118,7 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
119118
optionalScopes: mockedSessionUpgradeData.sessionScopes,
120119
},
121120
}),
122-
undefined,
121+
{ timeout: 60 * 1000 },
123122
);
124123
} else {
125124
t.expect(mockedData.mockDappClient.sendRequest).toHaveBeenCalledWith(
@@ -168,10 +167,9 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
168167
if (platform === 'web') {
169168
t.expect(mockedData.mockDefaultTransport.request).toHaveBeenCalledWith(
170169
t.expect.objectContaining({
171-
jsonrpc: '2.0',
172170
method: 'wallet_getSession',
173171
}),
174-
undefined,
172+
{ timeout: 60 * 1000 },
175173
);
176174
t.expect(mockedData.mockDefaultTransport.request).toHaveBeenCalledWith(
177175
t.expect.objectContaining({
@@ -180,7 +178,7 @@ function testSuite<T extends MultichainOptions>({ platform, createSDK, options:
180178
optionalScopes: mockSessionData.sessionScopes,
181179
},
182180
}),
183-
undefined,
181+
{ timeout: 60 * 1000 },
184182
);
185183
} else {
186184
t.expect(mockedData.mockDappClient.sendRequest).toHaveBeenCalledWith(

packages/sdk-multichain/src/ui/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ t.describe('ModalFactory', () => {
330330
await constructorArgs.onClose();
331331

332332
// Multichain SDK is what will close the modal instead
333-
t.expect(mockModal.unmount).not.toHaveBeenCalled();
333+
t.expect(mockModal.unmount).toHaveBeenCalled();
334334
});
335335

336336
t.it('should handle desktop onboarding correctly', async () => {

0 commit comments

Comments
 (0)