Skip to content

Commit 05d47db

Browse files
committed
Add wallet_switchEthereumChain support to snaps-jest
1 parent 8281953 commit 05d47db

File tree

7 files changed

+119
-18
lines changed

7 files changed

+119
-18
lines changed

packages/examples/packages/ethereum-provider/snap.manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://github.com/MetaMask/snaps.git"
88
},
99
"source": {
10-
"shasum": "2R9rtwpmidSKcYsKHxk/o9JPKqB6RMNHbWHJEpEjN9U=",
10+
"shasum": "FvNPBDpxgcjSkTlVJ73Xi15wnD1MvkaJyIJqFK6eW3I=",
1111
"location": {
1212
"npm": {
1313
"filePath": "dist/bundle.js",

packages/examples/packages/ethereum-provider/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ async function signTypedData(message: string, from: string) {
223223
* @see https://docs.metamask.io/snaps/reference/rpc-api/#wallet_invokesnap
224224
*/
225225
export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
226-
const { chainId = '0x1' } = request.params as BaseParams;
226+
const { chainId = '0x1' } = (request.params as BaseParams) ?? {};
227227
await switchChain(chainId);
228228

229229
switch (request.method) {
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"branches": 93.28,
2+
"branches": 93.29,
33
"functions": 96.8,
4-
"lines": 98.15,
5-
"statements": 97.88
4+
"lines": 98.16,
5+
"statements": 97.89
66
}

packages/snaps-controllers/src/snaps/SnapController.test.tsx

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5330,7 +5330,7 @@ describe('SnapController', () => {
53305330
snapController.destroy();
53315331
});
53325332

5333-
it('grants the `endowment:permitted-chains` permission to a Snap with `endowment:ethereum-provider`', async () => {
5333+
it('grants the `endowment:caip25` permission to a Snap with `endowment:ethereum-provider`', async () => {
53345334
const rootMessenger = getControllerMessenger();
53355335
const messenger = getSnapControllerMessenger(rootMessenger);
53365336

@@ -5375,21 +5375,42 @@ describe('SnapController', () => {
53755375
});
53765376

53775377
const approvedPermissions = {
5378-
'endowment:ethereum-provider': {
5379-
caveats: [],
5378+
'endowment:page-home': {
5379+
caveats: null,
5380+
},
5381+
'endowment:ethereum-provider': {},
5382+
'endowment:caip25': {
5383+
caveats: [
5384+
{
5385+
type: 'authorizedScopes',
5386+
value: {
5387+
requiredScopes: {},
5388+
optionalScopes: {
5389+
'eip155:1': {
5390+
accounts: [],
5391+
},
5392+
},
5393+
sessionProperties: {},
5394+
isMultichainOrigin: false,
5395+
},
5396+
},
5397+
],
53805398
},
5381-
permittedChains: {},
53825399
};
53835400

53845401
expect(messenger.call).toHaveBeenCalledWith(
53855402
'PermissionController:grantPermissions',
5386-
{ approvedPermissions, subject: { origin: MOCK_SNAP_ID } },
5403+
{
5404+
approvedPermissions,
5405+
subject: { origin: MOCK_SNAP_ID },
5406+
requestData: expect.any(Object),
5407+
},
53875408
);
53885409

53895410
snapController.destroy();
53905411
});
53915412

5392-
it('overrides the `endowment:permitted-chains` permission if the Snap specifies it in its manifest', async () => {
5413+
it('overrides the `endowment:caip25` permission if the Snap specifies it in its manifest', async () => {
53935414
const rootMessenger = getControllerMessenger();
53945415
const messenger = getSnapControllerMessenger(rootMessenger);
53955416

@@ -5418,11 +5439,20 @@ describe('SnapController', () => {
54185439
initialPermissions: {
54195440
'endowment:page-home': {},
54205441
'endowment:ethereum-provider': {},
5421-
[PERMITTED_CHAINS_ENDOWMENT]: {
5442+
'endowment:caip25': {
54225443
caveats: [
54235444
{
5424-
type: 'restrictNetworkSwitching',
5425-
value: ['0x5'],
5445+
type: 'authorizedScopes',
5446+
value: {
5447+
requiredScopes: {},
5448+
optionalScopes: {
5449+
'eip155:2': {
5450+
accounts: [],
5451+
},
5452+
},
5453+
sessionProperties: {},
5454+
isMultichainOrigin: false,
5455+
},
54265456
},
54275457
],
54285458
},
@@ -5446,11 +5476,20 @@ describe('SnapController', () => {
54465476
caveats: null,
54475477
},
54485478
'endowment:ethereum-provider': {},
5449-
[PERMITTED_CHAINS_ENDOWMENT]: {
5479+
'endowment:caip25': {
54505480
caveats: [
54515481
{
5452-
type: 'restrictNetworkSwitching',
5453-
value: ['0x1'],
5482+
type: 'authorizedScopes',
5483+
value: {
5484+
requiredScopes: {},
5485+
optionalScopes: {
5486+
'eip155:1': {
5487+
accounts: [],
5488+
},
5489+
},
5490+
sessionProperties: {},
5491+
isMultichainOrigin: false,
5492+
},
54545493
},
54555494
],
54565495
},
@@ -5468,7 +5507,7 @@ describe('SnapController', () => {
54685507
snapController.destroy();
54695508
});
54705509

5471-
it('does not grant the `endowment:permitted-chains` permission if the Snap does not have the `endowment:ethereum-provider` permission', async () => {
5510+
it('does not grant the `endowment:caip25` permission if the Snap does not have the `endowment:ethereum-provider` permission', async () => {
54725511
const rootMessenger = getControllerMessenger();
54735512
const messenger = getSnapControllerMessenger(rootMessenger);
54745513

packages/snaps-simulation/src/middleware/internal-methods/middleware.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { getAccountsHandler } from './accounts';
66
import { getChainIdHandler } from './chain-id';
77
import { getNetworkVersionHandler } from './net-version';
88
import { getProviderStateHandler } from './provider-state';
9+
import { getSwitchEthereumChainHandler } from './switch-ethereum-chain';
910

1011
export type InternalMethodsMiddlewareHooks = {
1112
/**
@@ -23,6 +24,7 @@ const methodHandlers = {
2324
eth_accounts: getAccountsHandler,
2425
eth_chainId: getChainIdHandler,
2526
net_version: getNetworkVersionHandler,
27+
wallet_switchEthereumChain: getSwitchEthereumChainHandler,
2628
/* eslint-enable @typescript-eslint/naming-convention */
2729
};
2830

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { Json, PendingJsonRpcResponse } from '@metamask/utils';
2+
3+
import { getSwitchEthereumChainHandler } from './switch-ethereum-chain';
4+
5+
describe('getSwitchEthereumChainHandler', () => {
6+
it('returns `null`', async () => {
7+
const end = jest.fn();
8+
const result: PendingJsonRpcResponse<Json> = {
9+
jsonrpc: '2.0' as const,
10+
id: 1,
11+
};
12+
13+
await getSwitchEthereumChainHandler(
14+
{
15+
jsonrpc: '2.0',
16+
id: 1,
17+
method: 'wallet_switchEthereumChain',
18+
params: [],
19+
},
20+
result,
21+
jest.fn(),
22+
end,
23+
);
24+
25+
expect(end).toHaveBeenCalled();
26+
expect(result.result).toBeNull();
27+
});
28+
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type {
2+
JsonRpcEngineEndCallback,
3+
JsonRpcEngineNextCallback,
4+
} from '@metamask/json-rpc-engine';
5+
import type {
6+
Json,
7+
JsonRpcRequest,
8+
PendingJsonRpcResponse,
9+
} from '@metamask/utils';
10+
11+
/**
12+
* A mock handler for the `wallet_switchEthereumChain` method that always
13+
* returns `null`.
14+
*
15+
* @param _request - Incoming JSON-RPC request. This is ignored for this
16+
* specific handler.
17+
* @param response - The outgoing JSON-RPC response, modified to return the
18+
* result.
19+
* @param _next - The `json-rpc-engine` middleware next handler.
20+
* @param end - The `json-rpc-engine` middleware end handler.
21+
* @returns The response.
22+
*/
23+
export async function getSwitchEthereumChainHandler(
24+
_request: JsonRpcRequest,
25+
response: PendingJsonRpcResponse<Json>,
26+
_next: JsonRpcEngineNextCallback,
27+
end: JsonRpcEngineEndCallback,
28+
// hooks: GetAccountsHandlerHooks,
29+
) {
30+
response.result = null;
31+
return end();
32+
}

0 commit comments

Comments
 (0)