Skip to content

Commit 52984e6

Browse files
Add tests
1 parent c0ae284 commit 52984e6

File tree

3 files changed

+237
-12
lines changed

3 files changed

+237
-12
lines changed

packages/snaps-rpc-methods/jest.config.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ module.exports = deepmerge(baseConfig, {
1010
],
1111
coverageThreshold: {
1212
global: {
13-
branches: 94.96,
14-
functions: 98.64,
15-
lines: 98.78,
16-
statements: 98.45,
13+
branches: 95.04,
14+
functions: 98.66,
15+
lines: 98.79,
16+
statements: 98.47,
1717
},
1818
},
1919
});
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
import { JsonRpcEngine } from '@metamask/json-rpc-engine';
2+
3+
import { createPreinstalledSnapsMiddleware } from './middleware';
4+
import { SnapEndowments } from '../endowments';
5+
6+
describe('createPreinstalledSnapsMiddleware', () => {
7+
it('grants permissions for accounts not already permitted', async () => {
8+
const hooks = {
9+
getPermittedEvmAccounts: jest.fn().mockReturnValue([]),
10+
getAllEvmAccounts: jest
11+
.fn()
12+
.mockReturnValue(['0x1234567890123456789012345678901234567890']),
13+
getPermissions: jest
14+
.fn()
15+
.mockReturnValue({ [SnapEndowments.EthereumProvider]: {} }),
16+
grantPermissions: jest.fn(),
17+
};
18+
19+
const middleware = createPreinstalledSnapsMiddleware(hooks);
20+
21+
const engine = new JsonRpcEngine();
22+
23+
engine.push(middleware);
24+
25+
const request = {
26+
jsonrpc: '2.0' as const,
27+
id: 1,
28+
method: 'eth_signTypedData_v4',
29+
params: {},
30+
};
31+
32+
// Since we only have one middleware, this will return an error on a successful test.
33+
expect(await engine.handle(request)).toStrictEqual({
34+
id: 1,
35+
jsonrpc: '2.0',
36+
error: {
37+
code: -32603,
38+
data: {
39+
cause: null,
40+
request: {
41+
id: 1,
42+
jsonrpc: '2.0',
43+
method: 'eth_signTypedData_v4',
44+
params: {},
45+
},
46+
},
47+
message: expect.stringContaining(
48+
'JsonRpcEngine: Response has no error or result for request',
49+
),
50+
stack: expect.stringContaining(
51+
'JsonRpcEngine: Response has no error or result for request',
52+
),
53+
},
54+
});
55+
56+
expect(hooks.grantPermissions).toHaveBeenCalledWith({
57+
'endowment:caip25': {
58+
caveats: [
59+
{
60+
type: 'authorizedScopes',
61+
value: {
62+
isMultichainOrigin: false,
63+
optionalScopes: {
64+
'wallet:eip155': {
65+
accounts: [
66+
'wallet:eip155:0x1234567890123456789012345678901234567890',
67+
],
68+
},
69+
},
70+
requiredScopes: {},
71+
sessionProperties: {},
72+
},
73+
},
74+
],
75+
},
76+
});
77+
});
78+
79+
it('skips the middleware if the accounts are already permitted', async () => {
80+
const hooks = {
81+
getPermittedEvmAccounts: jest
82+
.fn()
83+
.mockReturnValue(['0x1234567890123456789012345678901234567890']),
84+
getAllEvmAccounts: jest
85+
.fn()
86+
.mockReturnValue(['0x1234567890123456789012345678901234567890']),
87+
getPermissions: jest
88+
.fn()
89+
.mockReturnValue({ [SnapEndowments.EthereumProvider]: {} }),
90+
grantPermissions: jest.fn(),
91+
};
92+
93+
const middleware = createPreinstalledSnapsMiddleware(hooks);
94+
95+
const engine = new JsonRpcEngine();
96+
97+
engine.push(middleware);
98+
99+
const request = {
100+
jsonrpc: '2.0' as const,
101+
id: 1,
102+
method: 'eth_signTypedData_v4',
103+
params: {},
104+
};
105+
106+
// Since we only have one middleware, this will return an error on a successful test.
107+
expect(await engine.handle(request)).toStrictEqual({
108+
id: 1,
109+
jsonrpc: '2.0',
110+
error: {
111+
code: -32603,
112+
data: {
113+
cause: null,
114+
request: {
115+
id: 1,
116+
jsonrpc: '2.0',
117+
method: 'eth_signTypedData_v4',
118+
params: {},
119+
},
120+
},
121+
message: expect.stringContaining(
122+
'JsonRpcEngine: Response has no error or result for request',
123+
),
124+
stack: expect.stringContaining(
125+
'JsonRpcEngine: Response has no error or result for request',
126+
),
127+
},
128+
});
129+
130+
expect(hooks.grantPermissions).not.toHaveBeenCalled();
131+
});
132+
133+
it('ignores snap methods', async () => {
134+
const hooks = {
135+
getPermittedEvmAccounts: jest.fn(),
136+
getAllEvmAccounts: jest.fn(),
137+
getPermissions: jest.fn(),
138+
grantPermissions: jest.fn(),
139+
};
140+
141+
const middleware = createPreinstalledSnapsMiddleware(hooks);
142+
143+
const engine = new JsonRpcEngine();
144+
145+
engine.push(middleware);
146+
147+
const request = {
148+
jsonrpc: '2.0' as const,
149+
id: 1,
150+
method: 'snap_dialog',
151+
params: {},
152+
};
153+
154+
// Since we only have one middleware, this will return an error on a successful test.
155+
expect(await engine.handle(request)).toStrictEqual({
156+
id: 1,
157+
jsonrpc: '2.0',
158+
error: {
159+
code: -32603,
160+
data: {
161+
cause: null,
162+
request: {
163+
id: 1,
164+
jsonrpc: '2.0',
165+
method: 'snap_dialog',
166+
params: {},
167+
},
168+
},
169+
message: expect.stringContaining(
170+
'JsonRpcEngine: Response has no error or result for request',
171+
),
172+
stack: expect.stringContaining(
173+
'JsonRpcEngine: Response has no error or result for request',
174+
),
175+
},
176+
});
177+
178+
expect(hooks.grantPermissions).not.toHaveBeenCalled();
179+
});
180+
181+
it('skips the middleware if the Snap doesnt have endowment:ethereum-provider', async () => {
182+
const hooks = {
183+
getPermittedEvmAccounts: jest.fn(),
184+
getAllEvmAccounts: jest.fn(),
185+
getPermissions: jest.fn(),
186+
grantPermissions: jest.fn(),
187+
};
188+
189+
const middleware = createPreinstalledSnapsMiddleware(hooks);
190+
191+
const engine = new JsonRpcEngine();
192+
193+
engine.push(middleware);
194+
195+
const request = {
196+
jsonrpc: '2.0' as const,
197+
id: 1,
198+
method: 'eth_signTypedData_v4',
199+
params: {},
200+
};
201+
202+
// Since we only have one middleware, this will return an error on a successful test.
203+
expect(await engine.handle(request)).toStrictEqual({
204+
id: 1,
205+
jsonrpc: '2.0',
206+
error: {
207+
code: -32603,
208+
data: {
209+
cause: null,
210+
request: {
211+
id: 1,
212+
jsonrpc: '2.0',
213+
method: 'eth_signTypedData_v4',
214+
params: {},
215+
},
216+
},
217+
message: expect.stringContaining(
218+
'JsonRpcEngine: Response has no error or result for request',
219+
),
220+
stack: expect.stringContaining(
221+
'JsonRpcEngine: Response has no error or result for request',
222+
),
223+
},
224+
});
225+
226+
expect(hooks.grantPermissions).not.toHaveBeenCalled();
227+
});
228+
});

packages/snaps-rpc-methods/src/preinstalled/middleware.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ export type PreinstalledSnapsMiddlewareHooks = {
2020
* that want to use the Ethereum provider endowment.
2121
*
2222
* @param hooks - The hooks used by the middleware.
23-
* @param hooks.getPermittedEvmAccounts
24-
* @param hooks.getAllEvmAccounts
25-
* @param hooks.getPermissions
26-
* @param hooks.grantPermissions
23+
* @param hooks.getPermittedEvmAccounts - Hook for retrieving the currently permitted EVM addresses.
24+
* @param hooks.getAllEvmAccounts - Hook for retriveing all available EVM addresses.
25+
* @param hooks.getPermissions - Hook for retrieving the permissions of the requesting origin.
26+
* @param hooks.grantPermissions - Hook for granting permissions to the requesting origin.
2727
* @returns The middleware.
2828
*/
2929
export function createPreinstalledSnapsMiddleware({
@@ -33,10 +33,7 @@ export function createPreinstalledSnapsMiddleware({
3333
grantPermissions,
3434
}: PreinstalledSnapsMiddlewareHooks): JsonRpcMiddleware<JsonRpcParams, Json> {
3535
return function methodMiddleware(request, _response, next, _end) {
36-
if (
37-
!request.method.startsWith('wallet') &&
38-
!request.method.startsWith('eth')
39-
) {
36+
if (request.method.startsWith('snap')) {
4037
return next();
4138
}
4239

0 commit comments

Comments
 (0)