From 552a4b53578f30e2088eadeb78e4ae82dad0b5ca Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 10 Nov 2022 14:23:38 +0100 Subject: [PATCH] Fix a bunch of tests and simplify --- packages/execution-environments/package.json | 1 + .../src/common/BaseSnapExecutor.test.ts | 265 ++++-------------- .../src/common/BaseSnapExecutor.ts | 2 + .../src/iframe/IFrameSnapExecutor.test.ts | 34 ++- .../ChildProcessSnapExecutor.test.ts | 34 ++- .../node-thread/ThreadSnapExecutor.test.ts | 34 ++- .../services/AbstractExecutionService.test.ts | 94 ++++--- .../iframe/IframeExecutionService.test.ts | 165 ++++------- .../node/NodeProcessExecutionService.test.ts | 166 ++++------- .../node/NodeThreadExecutionService.test.ts | 167 ++++------- .../src/snaps/SnapController.test.ts | 18 +- .../src/test-utils/execution-environment.ts | 7 +- yarn.lock | 1 + 13 files changed, 386 insertions(+), 602 deletions(-) diff --git a/packages/execution-environments/package.json b/packages/execution-environments/package.json index 560141bc27..350c918363 100644 --- a/packages/execution-environments/package.json +++ b/packages/execution-environments/package.json @@ -37,6 +37,7 @@ "@metamask/snap-utils": "^0.23.0", "@metamask/utils": "^3.3.0", "eth-rpc-errors": "^4.0.3", + "json-rpc-engine": "^6.1.0", "pump": "^3.0.0", "ses": "^0.17.0", "stream-browserify": "^3.0.0", diff --git a/packages/execution-environments/src/common/BaseSnapExecutor.test.ts b/packages/execution-environments/src/common/BaseSnapExecutor.test.ts index 59541cbe23..62c1dab540 100644 --- a/packages/execution-environments/src/common/BaseSnapExecutor.test.ts +++ b/packages/execution-environments/src/common/BaseSnapExecutor.test.ts @@ -111,6 +111,37 @@ class TestSnapExecutor extends BaseSnapExecutor { }); } + // Utility function for executing snaps + public async executeSnap( + id: number, + name: string, + code: string, + endowments: string[], + ) { + await this.writeCommand({ + jsonrpc: '2.0', + id, + method: 'executeSnap', + params: [name, code, endowments], + }); + + const providerRequest = await this.readRpc(); + await this.writeRpc({ + name: 'metamask-provider', + data: { + jsonrpc: '2.0', + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + id: providerRequest.data.id!, + result: { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }, + }, + }); + } + public writeCommand(message: JsonRpcRequest): Promise { return new Promise((resolve, reject) => this.commandLeft.write(message, (error) => { @@ -200,12 +231,7 @@ describe('BaseSnapExecutor', () => { const executor = new TestSnapExecutor(); const consoleErrorSpy = jest.spyOn(console, 'error'); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -236,12 +262,7 @@ describe('BaseSnapExecutor', () => { const executor = new TestSnapExecutor(); const consoleErrorSpy = jest.spyOn(console, 'error'); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -308,19 +329,8 @@ describe('BaseSnapExecutor', () => { const executor = new TestSnapExecutor(); // Initiate the snaps - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [SNAP_NAME_1, CODE_1, TIMER_ENDOWMENTS], - }); - - await executor.writeCommand({ - jsonrpc: '2.0', - id: 2, - method: 'executeSnap', - params: [SNAP_NAME_2, CODE_2, TIMER_ENDOWMENTS], - }); + await executor.executeSnap(1, SNAP_NAME_1, CODE_1, TIMER_ENDOWMENTS); + await executor.executeSnap(2, SNAP_NAME_2, CODE_2, TIMER_ENDOWMENTS); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -407,12 +417,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -463,12 +468,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, ['ethereum']], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, ['ethereum']); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -493,27 +493,6 @@ describe('BaseSnapExecutor', () => { method: 'OutboundRequest', }); - const providerRequest = await executor.readRpc(); - expect(providerRequest).toStrictEqual({ - name: 'metamask-provider', - data: { - id: expect.any(Number), - jsonrpc: '2.0', - method: 'metamask_getProviderState', - params: undefined, - }, - }); - - await executor.writeRpc({ - name: 'metamask-provider', - data: { - jsonrpc: '2.0', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - id: providerRequest.data.id!, - result: { isUnlocked: false, accounts: [] }, - }, - }); - const blockNumRequest = await executor.readRpc(); expect(blockNumRequest).toStrictEqual({ name: 'metamask-provider', @@ -560,12 +539,7 @@ describe('BaseSnapExecutor', () => { emitter.on(type, listener as any), ); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -623,12 +597,7 @@ describe('BaseSnapExecutor', () => { emitter.on(type, listener as any), ); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -686,12 +655,7 @@ describe('BaseSnapExecutor', () => { emitter.on(type, listener as any), ); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -742,12 +706,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -794,12 +753,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -875,12 +829,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -934,12 +883,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1023,12 +967,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1060,12 +999,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1104,12 +1038,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1151,12 +1080,7 @@ describe('BaseSnapExecutor', () => { const consoleErrorSpy = jest.spyOn(console, 'error'); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1216,13 +1140,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - // --- Execute Snap - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1248,27 +1166,6 @@ describe('BaseSnapExecutor', () => { method: 'OutboundRequest', }); - const providerRequest = await executor.readRpc(); - expect(providerRequest).toStrictEqual({ - name: 'metamask-provider', - data: { - id: expect.any(Number), - jsonrpc: '2.0', - method: 'metamask_getProviderState', - params: undefined, - }, - }); - - await executor.writeRpc({ - name: 'metamask-provider', - data: { - jsonrpc: '2.0', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - id: providerRequest.data.id!, - result: { isUnlocked: false, accounts: [] }, - }, - }); - const blockNumRequest = await executor.readRpc(); expect(blockNumRequest).toStrictEqual({ name: 'metamask-provider', @@ -1349,12 +1246,7 @@ describe('BaseSnapExecutor', () => { const executor = new TestSnapExecutor(); // --- Execute Snap - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, TIMER_ENDOWMENTS); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1380,27 +1272,6 @@ describe('BaseSnapExecutor', () => { method: 'OutboundRequest', }); - const providerRequest = await executor.readRpc(); - expect(providerRequest).toStrictEqual({ - name: 'metamask-provider', - data: { - id: expect.any(Number), - jsonrpc: '2.0', - method: 'metamask_getProviderState', - params: undefined, - }, - }); - - await executor.writeRpc({ - name: 'metamask-provider', - data: { - jsonrpc: '2.0', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - id: providerRequest.data.id!, - result: { isUnlocked: false, accounts: [] }, - }, - }); - const blockNumRequest = await executor.readRpc(); expect(blockNumRequest).toStrictEqual({ name: 'metamask-provider', @@ -1464,12 +1335,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, ['ethereum']], - }); + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, ['ethereum']); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', @@ -1494,27 +1360,6 @@ describe('BaseSnapExecutor', () => { method: 'OutboundRequest', }); - const providerRequest = await executor.readRpc(); - expect(providerRequest).toStrictEqual({ - name: 'metamask-provider', - data: { - id: expect.any(Number), - jsonrpc: '2.0', - method: 'metamask_getProviderState', - params: undefined, - }, - }); - - await executor.writeRpc({ - name: 'metamask-provider', - data: { - jsonrpc: '2.0', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - id: providerRequest.data.id!, - result: { isUnlocked: false, accounts: [] }, - }, - }); - const blockNumRequest = await executor.readRpc(); expect(blockNumRequest).toStrictEqual({ name: 'metamask-provider', @@ -1557,13 +1402,7 @@ describe('BaseSnapExecutor', () => { `; const executor = new TestSnapExecutor(); - await executor.writeCommand({ - jsonrpc: '2.0', - id: 1, - method: 'executeSnap', - params: [FAKE_SNAP_NAME, CODE, []], - }); - + await executor.executeSnap(1, FAKE_SNAP_NAME, CODE, []); expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', id: 1, diff --git a/packages/execution-environments/src/common/BaseSnapExecutor.ts b/packages/execution-environments/src/common/BaseSnapExecutor.ts index c09245dd49..14a0a92b05 100644 --- a/packages/execution-environments/src/common/BaseSnapExecutor.ts +++ b/packages/execution-environments/src/common/BaseSnapExecutor.ts @@ -2,6 +2,7 @@ /// import { Duplex } from 'stream'; import { StreamProvider } from '@metamask/providers'; +import { createIdRemapMiddleware } from 'json-rpc-engine'; import { SnapExports, SnapAPI } from '@metamask/snap-types'; import { errorCodes, ethErrors, serializeError } from 'eth-rpc-errors'; import { @@ -277,6 +278,7 @@ export class BaseSnapExecutor { const provider = new StreamProvider(this.rpcStream, { jsonRpcStreamName: 'metamask-provider', + rpcMiddleware: [createIdRemapMiddleware()], }); await provider.initialize(); diff --git a/packages/execution-environments/src/iframe/IFrameSnapExecutor.test.ts b/packages/execution-environments/src/iframe/IFrameSnapExecutor.test.ts index fe14ffe50c..2fcf017092 100644 --- a/packages/execution-environments/src/iframe/IFrameSnapExecutor.test.ts +++ b/packages/execution-environments/src/iframe/IFrameSnapExecutor.test.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line import/no-unassigned-import import 'ses'; import { EventEmitter } from 'stream'; -import { Json, JsonRpcSuccess } from '@metamask/utils'; +import { Json, JsonRpcRequest, JsonRpcSuccess } from '@metamask/utils'; import { SNAP_STREAM_NAMES, HandlerType } from '@metamask/snap-utils'; import { IFrameSnapExecutor } from './IFrameSnapExecutor'; @@ -39,6 +39,20 @@ describe('IFrameSnapExecutor', () => { const emit = (data: Json) => parentEmitter.emit('message', { data: { data, target: 'child' } }); const emitChunk = (name: string, data: Json) => emit({ name, data }); + const waitForOutbound = ( + request: Partial>, + ): any => + new Promise((resolve) => { + childEmitter.on('message', ({ data: { name, data } }) => { + if ( + name === SNAP_STREAM_NAMES.JSON_RPC && + data.name === 'metamask-provider' && + data.data.method === request.method + ) { + resolve(data.data); + } + }); + }); const waitForResponse = (response: JsonRpcSuccess) => new Promise((resolve) => { childEmitter.on('message', ({ data }) => { @@ -78,6 +92,24 @@ describe('IFrameSnapExecutor', () => { params: [FAKE_SNAP_NAME, CODE, []], }); + const providerRequest = await waitForOutbound({ + method: 'metamask_getProviderState', + }); + + emitChunk(SNAP_STREAM_NAMES.JSON_RPC, { + name: 'metamask-provider', + data: { + jsonrpc: '2.0', + id: providerRequest.id, + result: { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }, + }, + }); + expect( await waitForResponse({ result: 'OK', id: 1, jsonrpc: '2.0' }), ).not.toBeNull(); diff --git a/packages/execution-environments/src/node-process/ChildProcessSnapExecutor.test.ts b/packages/execution-environments/src/node-process/ChildProcessSnapExecutor.test.ts index b1f1d10a89..95b835714c 100644 --- a/packages/execution-environments/src/node-process/ChildProcessSnapExecutor.test.ts +++ b/packages/execution-environments/src/node-process/ChildProcessSnapExecutor.test.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line import/no-unassigned-import import 'ses'; import { EventEmitter } from 'stream'; -import { Json, JsonRpcSuccess } from '@metamask/utils'; +import { Json, JsonRpcRequest, JsonRpcSuccess } from '@metamask/utils'; import { SNAP_STREAM_NAMES, HandlerType } from '@metamask/snap-utils'; import { ChildProcessSnapExecutor } from './ChildProcessSnapExecutor'; @@ -36,6 +36,20 @@ describe('ChildProcessSnapExecutor', () => { // Utility functions const emit = (data: Json) => parentEmitter.emit('message', { data }); const emitChunk = (name: string, data: Json) => emit({ name, data }); + const waitForOutbound = ( + request: Partial>, + ): any => + new Promise((resolve) => { + childEmitter.on('message', ({ data: { name, data } }) => { + if ( + name === SNAP_STREAM_NAMES.JSON_RPC && + data.name === 'metamask-provider' && + data.data.method === request.method + ) { + resolve(data.data); + } + }); + }); const waitForResponse = (response: JsonRpcSuccess) => new Promise((resolve) => { childEmitter.on('message', ({ data }) => { @@ -61,6 +75,24 @@ describe('ChildProcessSnapExecutor', () => { params: [FAKE_SNAP_NAME, CODE, []], }); + const providerRequest = await waitForOutbound({ + method: 'metamask_getProviderState', + }); + + emitChunk(SNAP_STREAM_NAMES.JSON_RPC, { + name: 'metamask-provider', + data: { + jsonrpc: '2.0', + id: providerRequest.id, + result: { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }, + }, + }); + expect( await waitForResponse({ result: 'OK', id: 1, jsonrpc: '2.0' }), ).not.toBeNull(); diff --git a/packages/execution-environments/src/node-thread/ThreadSnapExecutor.test.ts b/packages/execution-environments/src/node-thread/ThreadSnapExecutor.test.ts index 03862a5087..3a70dbf264 100644 --- a/packages/execution-environments/src/node-thread/ThreadSnapExecutor.test.ts +++ b/packages/execution-environments/src/node-thread/ThreadSnapExecutor.test.ts @@ -2,7 +2,7 @@ import 'ses'; import { EventEmitter } from 'stream'; import { parentPort } from 'worker_threads'; -import { Json, JsonRpcSuccess } from '@metamask/utils'; +import { Json, JsonRpcRequest, JsonRpcSuccess } from '@metamask/utils'; import { SNAP_STREAM_NAMES, HandlerType } from '@metamask/snap-utils'; import { ThreadSnapExecutor } from './ThreadSnapExecutor'; @@ -47,6 +47,20 @@ describe('ThreadSnapExecutor', () => { // Utility functions const emit = (data: Json) => parentEmitter.emit('message', { data }); const emitChunk = (name: string, data: Json) => emit({ name, data }); + const waitForOutbound = ( + request: Partial>, + ): any => + new Promise((resolve) => { + childEmitter.on('message', ({ data: { name, data } }) => { + if ( + name === SNAP_STREAM_NAMES.JSON_RPC && + data.name === 'metamask-provider' && + data.data.method === request.method + ) { + resolve(data.data); + } + }); + }); const waitForResponse = (response: JsonRpcSuccess) => new Promise((resolve) => { childEmitter.on('message', ({ data }) => { @@ -72,6 +86,24 @@ describe('ThreadSnapExecutor', () => { params: [FAKE_SNAP_NAME, CODE, []], }); + const providerRequest = await waitForOutbound({ + method: 'metamask_getProviderState', + }); + + emitChunk(SNAP_STREAM_NAMES.JSON_RPC, { + name: 'metamask-provider', + data: { + jsonrpc: '2.0', + id: providerRequest.id, + result: { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }, + }, + }); + expect( await waitForResponse({ result: 'OK', id: 1, jsonrpc: '2.0' }), ).not.toBeNull(); diff --git a/packages/snap-controllers/src/services/AbstractExecutionService.test.ts b/packages/snap-controllers/src/services/AbstractExecutionService.test.ts index 5f1cfb4139..9f96e4fd43 100644 --- a/packages/snap-controllers/src/services/AbstractExecutionService.test.ts +++ b/packages/snap-controllers/src/services/AbstractExecutionService.test.ts @@ -1,16 +1,20 @@ import { ControllerMessenger } from '@metamask/controllers'; import { HandlerType } from '@metamask/snap-utils'; +import { JsonRpcEngine } from 'json-rpc-engine'; +import { createEngineStream } from 'json-rpc-middleware-stream'; +import pump from 'pump'; import { - ErrorMessageEvent, - ExecutionServiceMessenger, -} from './ExecutionService'; + ExecutionServiceArgs, + setupMultiplex, +} from './AbstractExecutionService'; +import { ErrorMessageEvent } from './ExecutionService'; import { NodeThreadExecutionService } from './node'; class MockExecutionService extends NodeThreadExecutionService { - constructor(messenger: ExecutionServiceMessenger) { + constructor({ messenger, setupSnapProvider }: ExecutionServiceArgs) { super({ messenger, - setupSnapProvider: () => undefined, + setupSnapProvider, }); } @@ -19,6 +23,43 @@ class MockExecutionService extends NodeThreadExecutionService { } } +function createService() { + const controllerMessenger = new ControllerMessenger< + never, + ErrorMessageEvent + >(); + const messenger = controllerMessenger.getRestricted< + 'ExecutionService', + never, + ErrorMessageEvent['type'] + >({ + name: 'ExecutionService', + }); + const service = new MockExecutionService({ + messenger, + setupSnapProvider: (_snapId, rpcStream) => { + const mux = setupMultiplex(rpcStream, 'foo'); + const stream = mux.createStream('metamask-provider'); + const engine = new JsonRpcEngine(); + engine.push((req, res, next, end) => { + if (req.method === 'metamask_getProviderState') { + res.result = { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }; + return end(); + } + return next(); + }); + const providerStream = createEngineStream({ engine }); + pump(stream, providerStream, stream); + }, + }); + return { service, messenger, controllerMessenger }; +} + describe('AbstractExecutionService', () => { afterEach(() => { jest.restoreAllMocks(); @@ -27,19 +68,7 @@ describe('AbstractExecutionService', () => { it('logs error for unrecognized notifications', async () => { const consoleErrorSpy = jest.spyOn(console, 'error'); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new MockExecutionService( - controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - ); + const { service } = createService(); await service.executeSnap({ snapId: 'TestSnap', @@ -66,19 +95,7 @@ describe('AbstractExecutionService', () => { it('logs error for malformed UnhandledError notification', async () => { const consoleErrorSpy = jest.spyOn(console, 'error'); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new MockExecutionService( - controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - ); + const { service } = createService(); await service.executeSnap({ snapId: 'TestSnap', @@ -112,20 +129,7 @@ describe('AbstractExecutionService', () => { }); it('throws an error if RPC request handler is unavailable', async () => { - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new MockExecutionService( - controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - ); - + const { service } = createService(); const snapId = 'TestSnap'; await expect( service.handleRpcRequest(snapId, { diff --git a/packages/snap-controllers/src/services/iframe/IframeExecutionService.test.ts b/packages/snap-controllers/src/services/iframe/IframeExecutionService.test.ts index cd813931b2..4951c72867 100644 --- a/packages/snap-controllers/src/services/iframe/IframeExecutionService.test.ts +++ b/packages/snap-controllers/src/services/iframe/IframeExecutionService.test.ts @@ -18,6 +18,50 @@ import { const iframeUrl = new URL(`http://localhost:${serverPort}`); +const MOCK_BLOCK_NUM = '0xa70e75'; + +function createService() { + const controllerMessenger = new ControllerMessenger< + never, + ErrorMessageEvent + >(); + const messenger = controllerMessenger.getRestricted< + 'ExecutionService', + never, + ErrorMessageEvent['type'] + >({ + name: 'ExecutionService', + }); + const service = new IframeExecutionService({ + messenger, + setupSnapProvider: (_snapId, rpcStream) => { + const mux = setupMultiplex(rpcStream, 'foo'); + const stream = mux.createStream('metamask-provider'); + const engine = new JsonRpcEngine(); + engine.push((req, res, next, end) => { + if (req.method === 'metamask_getProviderState') { + res.result = { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }; + return end(); + } else if (req.method === 'eth_blockNumber') { + res.result = MOCK_BLOCK_NUM; + return end(); + } + return next(); + }); + const providerStream = createEngineStream({ engine }); + pump(stream, providerStream, stream); + }, + iframeUrl, + }); + const removeListener = fixJSDOMPostMessageEventSource(service); + return { service, messenger, controllerMessenger, removeListener }; +} + describe('IframeExecutionService', () => { // The tests start running before the server is ready if we don't use the done callback. // eslint-disable-next-line jest/no-done-callback @@ -31,53 +75,15 @@ describe('IframeExecutionService', () => { }); it('can boot', async () => { - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const iframeExecutionService = new IframeExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - iframeUrl, - }); - const removeListener = fixJSDOMPostMessageEventSource( - iframeExecutionService, - ); - expect(iframeExecutionService).toBeDefined(); - await iframeExecutionService.terminateAllSnaps(); + const { service, removeListener } = createService(); + expect(service).toBeDefined(); + await service.terminateAllSnaps(); removeListener(); }); it('can create a snap worker and start the snap', async () => { - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const iframeExecutionService = new IframeExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - iframeUrl, - }); - const removeListener = fixJSDOMPostMessageEventSource( - iframeExecutionService, - ); - const response = await iframeExecutionService.executeSnap({ + const { service, removeListener } = createService(); + const response = await service.executeSnap({ snapId: 'TestSnap', sourceCode: ` console.log('foo'); @@ -85,34 +91,15 @@ describe('IframeExecutionService', () => { endowments: ['console'], }); expect(response).toStrictEqual('OK'); - await iframeExecutionService.terminateAllSnaps(); + await service.terminateAllSnaps(); removeListener(); }); it('can handle a crashed snap', async () => { expect.assertions(1); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const iframeExecutionService = new IframeExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - iframeUrl, - }); - const removeListener = fixJSDOMPostMessageEventSource( - iframeExecutionService, - ); + const { service, removeListener } = createService(); const action = async () => { - await iframeExecutionService.executeSnap({ + await service.executeSnap({ snapId: 'TestSnap', sourceCode: ` throw new Error("potato"); @@ -124,61 +111,27 @@ describe('IframeExecutionService', () => { await expect(action()).rejects.toThrow( /Error while running snap 'TestSnap'/u, ); - await iframeExecutionService.terminateAllSnaps(); + await service.terminateAllSnaps(); removeListener(); }); it('can detect outbound requests', async () => { const blockNumber = '0xa70e75'; expect.assertions(4); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const messenger = controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }); + const { service, removeListener, messenger } = createService(); const publishSpy = jest.spyOn(messenger, 'publish'); - const iframeExecutionService = new IframeExecutionService({ - messenger, - setupSnapProvider: (_snapId, rpcStream) => { - const mux = setupMultiplex(rpcStream, 'foo'); - const stream = mux.createStream('metamask-provider'); - const engine = new JsonRpcEngine(); - engine.push((req, res, next, end) => { - if (req.method === 'metamask_getProviderState') { - res.result = { isUnlocked: false, accounts: [] }; - return end(); - } else if (req.method === 'eth_blockNumber') { - res.result = blockNumber; - return end(); - } - return next(); - }); - const providerStream = createEngineStream({ engine }); - pump(stream, providerStream, stream); - }, - iframeUrl, - }); const snapId = 'TestSnap'; - const removeListener = fixJSDOMPostMessageEventSource( - iframeExecutionService, - ); - const executeResult = await iframeExecutionService.executeSnap({ + const executeResult = await service.executeSnap({ snapId, sourceCode: ` - module.exports.onRpcRequest = () => wallet.request({ method: 'eth_blockNumber', params: [] }); + module.exports.onRpcRequest = () => ethereum.request({ method: 'eth_blockNumber', params: [] }); `, - endowments: [], + endowments: ['ethereum'], }); expect(executeResult).toBe('OK'); - const result = await iframeExecutionService.handleRpcRequest(snapId, { + const result = await service.handleRpcRequest(snapId, { origin: 'foo', handler: HandlerType.OnRpcRequest, request: { @@ -201,7 +154,7 @@ describe('IframeExecutionService', () => { 'TestSnap', ); - await iframeExecutionService.terminateAllSnaps(); + await service.terminateAllSnaps(); removeListener(); }); }); diff --git a/packages/snap-controllers/src/services/node/NodeProcessExecutionService.test.ts b/packages/snap-controllers/src/services/node/NodeProcessExecutionService.test.ts index 2e23eb5ed0..4e56782f3b 100644 --- a/packages/snap-controllers/src/services/node/NodeProcessExecutionService.test.ts +++ b/packages/snap-controllers/src/services/node/NodeProcessExecutionService.test.ts @@ -9,45 +9,57 @@ import { NodeProcessExecutionService } from './NodeProcessExecutionService'; const ON_RPC_REQUEST = HandlerType.OnRpcRequest; +const MOCK_BLOCK_NUM = '0xa70e75'; + +function createService() { + const controllerMessenger = new ControllerMessenger< + never, + ErrorMessageEvent + >(); + const messenger = controllerMessenger.getRestricted< + 'ExecutionService', + never, + ErrorMessageEvent['type'] + >({ + name: 'ExecutionService', + }); + const service = new NodeProcessExecutionService({ + messenger, + setupSnapProvider: (_snapId, rpcStream) => { + const mux = setupMultiplex(rpcStream, 'foo'); + const stream = mux.createStream('metamask-provider'); + const engine = new JsonRpcEngine(); + engine.push((req, res, next, end) => { + if (req.method === 'metamask_getProviderState') { + res.result = { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }; + return end(); + } else if (req.method === 'eth_blockNumber') { + res.result = MOCK_BLOCK_NUM; + return end(); + } + return next(); + }); + const providerStream = createEngineStream({ engine }); + pump(stream, providerStream, stream); + }, + }); + return { service, messenger, controllerMessenger }; +} + describe('NodeProcessExecutionService', () => { it('can boot', async () => { - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeProcessExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); expect(service).toBeDefined(); await service.terminateAllSnaps(); }); it('can create a snap worker and start the snap', async () => { - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeProcessExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); const response = await service.executeSnap({ snapId: 'TestSnap', sourceCode: ` @@ -61,22 +73,7 @@ describe('NodeProcessExecutionService', () => { it('can handle a crashed snap', async () => { expect.assertions(1); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeProcessExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); const action = async () => { await service.executeSnap({ snapId: 'TestSnap', @@ -95,22 +92,7 @@ describe('NodeProcessExecutionService', () => { it('can handle errors in request handler', async () => { expect.assertions(1); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeProcessExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); const snapId = 'TestSnap'; await service.executeSnap({ snapId, @@ -137,22 +119,7 @@ describe('NodeProcessExecutionService', () => { it('can handle errors out of band', async () => { expect.assertions(2); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeProcessExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service, controllerMessenger } = createService(); const snapId = 'TestSnap'; await service.executeSnap({ snapId, @@ -211,46 +178,15 @@ describe('NodeProcessExecutionService', () => { it('can detect outbound requests', async () => { expect.assertions(4); - const blockNumber = '0xa70e75'; - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const messenger = controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }); + const { service, messenger } = createService(); const publishSpy = jest.spyOn(messenger, 'publish'); - const service = new NodeProcessExecutionService({ - messenger, - setupSnapProvider: (_snapId, rpcStream) => { - const mux = setupMultiplex(rpcStream, 'foo'); - const stream = mux.createStream('metamask-provider'); - const engine = new JsonRpcEngine(); - engine.push((req, res, next, end) => { - if (req.method === 'metamask_getProviderState') { - res.result = { isUnlocked: false, accounts: [] }; - return end(); - } else if (req.method === 'eth_blockNumber') { - res.result = blockNumber; - return end(); - } - return next(); - }); - const providerStream = createEngineStream({ engine }); - pump(stream, providerStream, stream); - }, - }); const snapId = 'TestSnap'; const executeResult = await service.executeSnap({ snapId, sourceCode: ` - module.exports.onRpcRequest = () => wallet.request({ method: 'eth_blockNumber', params: [] }); + module.exports.onRpcRequest = () => ethereum.request({ method: 'eth_blockNumber', params: [] }); `, - endowments: [], + endowments: ['ethereum'], }); expect(executeResult).toBe('OK'); @@ -266,7 +202,7 @@ describe('NodeProcessExecutionService', () => { }, }); - expect(result).toBe(blockNumber); + expect(result).toBe(MOCK_BLOCK_NUM); expect(publishSpy).toHaveBeenCalledWith( 'ExecutionService:outboundRequest', diff --git a/packages/snap-controllers/src/services/node/NodeThreadExecutionService.test.ts b/packages/snap-controllers/src/services/node/NodeThreadExecutionService.test.ts index 40328595b7..83a2b7cfca 100644 --- a/packages/snap-controllers/src/services/node/NodeThreadExecutionService.test.ts +++ b/packages/snap-controllers/src/services/node/NodeThreadExecutionService.test.ts @@ -9,45 +9,57 @@ import { NodeThreadExecutionService } from './NodeThreadExecutionService'; const ON_RPC_REQUEST = HandlerType.OnRpcRequest; +const MOCK_BLOCK_NUM = '0xa70e75'; + +function createService() { + const controllerMessenger = new ControllerMessenger< + never, + ErrorMessageEvent + >(); + const messenger = controllerMessenger.getRestricted< + 'ExecutionService', + never, + ErrorMessageEvent['type'] + >({ + name: 'ExecutionService', + }); + const service = new NodeThreadExecutionService({ + messenger, + setupSnapProvider: (_snapId, rpcStream) => { + const mux = setupMultiplex(rpcStream, 'foo'); + const stream = mux.createStream('metamask-provider'); + const engine = new JsonRpcEngine(); + engine.push((req, res, next, end) => { + if (req.method === 'metamask_getProviderState') { + res.result = { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }; + return end(); + } else if (req.method === 'eth_blockNumber') { + res.result = MOCK_BLOCK_NUM; + return end(); + } + return next(); + }); + const providerStream = createEngineStream({ engine }); + pump(stream, providerStream, stream); + }, + }); + return { service, messenger, controllerMessenger }; +} + describe('NodeThreadExecutionService', () => { it('can boot', async () => { - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeThreadExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); expect(service).toBeDefined(); await service.terminateAllSnaps(); }); it('can create a snap worker and start the snap', async () => { - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeThreadExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); const response = await service.executeSnap({ snapId: 'TestSnap', sourceCode: ` @@ -61,22 +73,7 @@ describe('NodeThreadExecutionService', () => { it('can handle a crashed snap', async () => { expect.assertions(1); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeThreadExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); const action = async () => { await service.executeSnap({ snapId: 'TestSnap', @@ -95,22 +92,7 @@ describe('NodeThreadExecutionService', () => { it('can handle errors in request handler', async () => { expect.assertions(1); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeThreadExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service } = createService(); const snapId = 'TestSnap'; await service.executeSnap({ snapId, @@ -137,22 +119,7 @@ describe('NodeThreadExecutionService', () => { it('can handle errors out of band', async () => { expect.assertions(2); - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const service = new NodeThreadExecutionService({ - messenger: controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }), - setupSnapProvider: () => { - // do nothing - }, - }); + const { service, controllerMessenger } = createService(); const snapId = 'TestSnap'; await service.executeSnap({ snapId, @@ -211,46 +178,16 @@ describe('NodeThreadExecutionService', () => { it('can detect outbound requests', async () => { expect.assertions(4); - const blockNumber = '0xa70e75'; - const controllerMessenger = new ControllerMessenger< - never, - ErrorMessageEvent - >(); - const messenger = controllerMessenger.getRestricted< - 'ExecutionService', - never, - ErrorMessageEvent['type'] - >({ - name: 'ExecutionService', - }); + const { service, messenger } = createService(); const publishSpy = jest.spyOn(messenger, 'publish'); - const service = new NodeThreadExecutionService({ - messenger, - setupSnapProvider: (_snapId, rpcStream) => { - const mux = setupMultiplex(rpcStream, 'foo'); - const stream = mux.createStream('metamask-provider'); - const engine = new JsonRpcEngine(); - engine.push((req, res, next, end) => { - if (req.method === 'metamask_getProviderState') { - res.result = { isUnlocked: false, accounts: [] }; - return end(); - } else if (req.method === 'eth_blockNumber') { - res.result = blockNumber; - return end(); - } - return next(); - }); - const providerStream = createEngineStream({ engine }); - pump(stream, providerStream, stream); - }, - }); + const snapId = 'TestSnap'; const executeResult = await service.executeSnap({ snapId, sourceCode: ` - module.exports.onRpcRequest = () => wallet.request({ method: 'eth_blockNumber', params: [] }); + module.exports.onRpcRequest = () => ethereum.request({ method: 'eth_blockNumber', params: [] }); `, - endowments: [], + endowments: ['ethereum'], }); expect(executeResult).toBe('OK'); @@ -266,7 +203,7 @@ describe('NodeThreadExecutionService', () => { }, }); - expect(result).toBe(blockNumber); + expect(result).toBe(MOCK_BLOCK_NUM); expect(publishSpy).toHaveBeenCalledWith( 'ExecutionService:outboundRequest', diff --git a/packages/snap-controllers/src/snaps/SnapController.test.ts b/packages/snap-controllers/src/snaps/SnapController.test.ts index f0ce9fb4a5..aee10c38e0 100644 --- a/packages/snap-controllers/src/snaps/SnapController.test.ts +++ b/packages/snap-controllers/src/snaps/SnapController.test.ts @@ -924,7 +924,7 @@ describe('SnapController', () => { it('does not timeout while waiting for response from MetaMask', async () => { const sourceCode = ` - module.exports.onRpcRequest = () => wallet.request({ method: 'eth_blockNumber', params: [] }); + module.exports.onRpcRequest = () => ethereum.request({ method: 'eth_blockNumber', params: [] }); `; const [snapController, service] = getSnapControllerWithEES( @@ -957,7 +957,12 @@ describe('SnapController', () => { const engine = new JsonRpcEngine(); const middleware = createAsyncMiddleware(async (req, res, _next) => { if (req.method === 'metamask_getProviderState') { - res.result = { isUnlocked: false, accounts: [] }; + res.result = { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }; } else if (req.method === 'eth_blockNumber') { await new Promise((resolve) => setTimeout(resolve, 400)); res.result = blockNumber; @@ -994,7 +999,7 @@ describe('SnapController', () => { it('does not timeout while waiting for response from MetaMask when snap does multiple calls', async () => { const sourceCode = ` - const fetch = async () => parseInt(await wallet.request({ method: 'eth_blockNumber', params: [] }), 16); + const fetch = async () => parseInt(await ethereum.request({ method: 'eth_blockNumber', params: [] }), 16); module.exports.onRpcRequest = async () => (await fetch()) + (await fetch()); `; @@ -1026,7 +1031,12 @@ describe('SnapController', () => { const engine = new JsonRpcEngine(); const middleware = createAsyncMiddleware(async (req, res, _next) => { if (req.method === 'metamask_getProviderState') { - res.result = { isUnlocked: false, accounts: [] }; + res.result = { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }; } else if (req.method === 'eth_blockNumber') { await new Promise((resolve) => setTimeout(resolve, 400)); res.result = '0xa70e77'; diff --git a/packages/snap-controllers/src/test-utils/execution-environment.ts b/packages/snap-controllers/src/test-utils/execution-environment.ts index 980f266d9c..74d2939f37 100644 --- a/packages/snap-controllers/src/test-utils/execution-environment.ts +++ b/packages/snap-controllers/src/test-utils/execution-environment.ts @@ -44,7 +44,12 @@ export const getNodeEES = (messenger: ReturnType) => const engine = new JsonRpcEngine(); engine.push((req, res, next, end) => { if (req.method === 'metamask_getProviderState') { - res.result = { isUnlocked: false, accounts: [] }; + res.result = { + isUnlocked: false, + accounts: [], + chainId: '0x1', + networkVersion: '1', + }; return end(); } else if (req.method === 'eth_blockNumber') { res.result = MOCK_BLOCK_NUMBER; diff --git a/yarn.lock b/yarn.lock index f3d60a2c9a..65ed506700 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2783,6 +2783,7 @@ __metadata: jest-fetch-mock: ^3.0.3 jest-it-up: ^2.0.0 jsdom: ^19.0.0 + json-rpc-engine: ^6.1.0 mock-socket: ^9.1.5 node-polyfill-webpack-plugin: ^1.1.4 prettier: ^2.3.2