Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('onRpcRequest', () => {
});

describe('getChainId', () => {
const MOCK_CHAIN_ID = '0x01'; // Ethereum Mainnet
const MOCK_CHAIN_ID = '0x1'; // Ethereum Mainnet

it('returns the current network version', async () => {
const { request } = await installSnap();
Expand Down
2 changes: 1 addition & 1 deletion packages/examples/packages/ethers-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
},
"dependencies": {
"@metamask/snaps-sdk": "workspace:^",
"ethers": "^6.3.0"
"ethers": "^6.16.0"
},
"devDependencies": {
"@jest/globals": "^29.5.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/examples/packages/ethers-js/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/snaps.git"
},
"source": {
"shasum": "JvI40BHRDgrfeB75rQhlRoaHO7csK0diC0RrBhW4jxw=",
"shasum": "z6v9zCXkSPMKSydCdc98zmr9xKkXRzMb2WARZE2DWuo=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
3 changes: 2 additions & 1 deletion packages/snaps-simulation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@metamask/eth-json-rpc-middleware": "^17.0.1",
"@metamask/json-rpc-engine": "^10.1.0",
"@metamask/json-rpc-middleware-stream": "^8.0.8",
"@metamask/key-tree": "^10.1.1",
"@metamask/messenger": "^0.3.0",
"@metamask/permission-controller": "^12.1.1",
"@metamask/phishing-controller": "^16.1.0",
"@metamask/rpc-errors": "^7.0.3",
"@metamask/snaps-controllers": "workspace:^",
"@metamask/snaps-execution-environments": "workspace:^",
"@metamask/snaps-rpc-methods": "workspace:^",
Expand All @@ -70,6 +70,7 @@
"@metamask/superstruct": "^3.2.1",
"@metamask/utils": "^11.9.0",
"@reduxjs/toolkit": "^1.9.5",
"ethers": "^6.16.0",
"fast-deep-equal": "^3.1.3",
"immer": "^9.0.21",
"mime": "^3.0.0",
Expand Down
5 changes: 0 additions & 5 deletions packages/snaps-simulation/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ export const DEFAULT_LOCALE = 'en';
*/
export const DEFAULT_CURRENCY = 'usd';

/**
* The default JSON-RPC endpoint for Ethereum requests.
*/
export const DEFAULT_JSON_RPC_ENDPOINT = 'https://cloudflare-eth.com/';

/**
* The types of inputs that can be used in the `typeInField` interface action.
*/
Expand Down
17 changes: 17 additions & 0 deletions packages/snaps-simulation/src/methods/hooks/chain.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getSetCurrentChainImplementation } from './chain';
import { createStore } from '../../store';
import { getMockOptions } from '../../test-utils';

describe('getSetCurrentChainImplementation', () => {
it('returns the implementation of the `setCurrentChain` hook', async () => {
const { store, runSaga } = createStore(getMockOptions());

expect(store.getState().chain.chainId).toBe('0x1');

const fn = getSetCurrentChainImplementation(runSaga);

expect(fn('0x2')).toBeNull();

expect(store.getState().chain.chainId).toBe('0x2');
});
});
30 changes: 30 additions & 0 deletions packages/snaps-simulation/src/methods/hooks/chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Hex } from '@metamask/utils';
import type { SagaIterator } from 'redux-saga';
import { put } from 'redux-saga/effects';

import { setChain } from '../../store';
import type { RunSagaFunction } from '../../store';

/**
* Set the current chain ID in state.
*
* @param chainId - The chain ID.
* @yields Puts the chain ID in the store.
* @returns `null`.
*/
function* setCurrentChainImplementation(chainId: Hex): SagaIterator {
yield put(setChain(chainId));
return null;
}

/**
* Get a method that can be used to set the current chain.
*
* @param runSaga - A function to run a saga outside the usual Redux flow.
* @returns A method that can be used to set the current chain.
*/
export function getSetCurrentChainImplementation(runSaga: RunSagaFunction) {
return (...args: Parameters<typeof setCurrentChainImplementation>) => {
return runSaga(setCurrentChainImplementation, ...args).result();
};
}
1 change: 1 addition & 0 deletions packages/snaps-simulation/src/methods/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './chain';
export * from './end-trace';
export * from './get-entropy-sources';
export * from './get-mnemonic';
Expand Down
13 changes: 2 additions & 11 deletions packages/snaps-simulation/src/middleware/engine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { createFetchMiddleware } from '@metamask/eth-json-rpc-middleware';
import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';
import { JsonRpcEngine } from '@metamask/json-rpc-engine';
import type { RestrictedMethodParameters } from '@metamask/permission-controller';
Expand All @@ -7,7 +6,7 @@ import type { Json } from '@metamask/utils';

import { createInternalMethodsMiddleware } from './internal-methods';
import { createMockMiddleware } from './mock';
import { DEFAULT_JSON_RPC_ENDPOINT } from '../constants';
import { createProviderMiddleware } from './provider';
import type {
PermittedMiddlewareHooks,
RestrictedMiddlewareHooks,
Expand All @@ -33,15 +32,13 @@ export type CreateJsonRpcEngineOptions = {
* @param options.restrictedHooks - Any hooks used by the middleware handlers.
* @param options.permittedHooks - Any hooks used by the middleware handlers.
* @param options.permissionMiddleware - The permission middleware to use.
* @param options.endpoint - The JSON-RPC endpoint to use for Ethereum requests.
* @returns A JSON-RPC engine.
*/
export function createJsonRpcEngine({
store,
restrictedHooks,
permittedHooks,
permissionMiddleware,
endpoint = DEFAULT_JSON_RPC_ENDPOINT,
}: CreateJsonRpcEngineOptions) {
const engine = new JsonRpcEngine();
engine.push(createMockMiddleware(store));
Expand All @@ -52,13 +49,7 @@ export function createJsonRpcEngine({
engine.push(createSnapsMethodMiddleware(true, permittedHooks));

engine.push(permissionMiddleware);
engine.push(
createFetchMiddleware({
btoa: globalThis.btoa,
fetch: globalThis.fetch,
rpcUrl: endpoint,
}),
);
engine.push(createProviderMiddleware(store));

return engine;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { PendingJsonRpcResponse } from '@metamask/utils';

import { getChainIdHandler } from './chain-id';
import { createStore } from '../../store';
import { getMockOptions } from '../../test-utils';

describe('getChainIdHandler', () => {
it('returns the chain id', async () => {
const { store } = createStore(getMockOptions());
const end = jest.fn();
const result: PendingJsonRpcResponse = {
jsonrpc: '2.0' as const,
Expand All @@ -20,9 +23,10 @@ describe('getChainIdHandler', () => {
result,
jest.fn(),
end,
{ getSimulationState: store.getState },
);

expect(end).toHaveBeenCalled();
expect(result.result).toBe('0x01');
expect(result.result).toBe('0x1');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import type {
} from '@metamask/json-rpc-engine';
import type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';

import type { InternalMethodsMiddlewareHooks } from './middleware';

/**
* A mock handler for eth_chainId that always returns a specific
* hardcoded result.
Expand All @@ -14,17 +16,17 @@ import type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';
* result.
* @param _next - The `json-rpc-engine` middleware next handler.
* @param end - The `json-rpc-engine` middleware end handler.
* @param hooks - The method hooks.
* @returns The JSON-RPC response.
*/
export async function getChainIdHandler(
_request: JsonRpcRequest,
response: PendingJsonRpcResponse,
_next: JsonRpcEngineNextCallback,
end: JsonRpcEngineEndCallback,
hooks: Pick<InternalMethodsMiddlewareHooks, 'getSimulationState'>,
) {
// For now this will return a mocked result, this should probably match
// whatever network the simulation is using.
response.result = '0x01';
response.result = hooks.getSimulationState().chain.chainId;

return end();
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';
import { logError } from '@metamask/snaps-utils';
import type { Json, JsonRpcParams } from '@metamask/utils';
import type { Hex, Json, JsonRpcParams } from '@metamask/utils';

import { getAccountsHandler } from './accounts';
import { getChainIdHandler } from './chain-id';
import { getNetworkVersionHandler } from './net-version';
import { getProviderStateHandler } from './provider-state';
import { getSwitchEthereumChainHandler } from './switch-ethereum-chain';
import type { ApplicationState } from '../../store';

export type InternalMethodsMiddlewareHooks = {
/**
Expand All @@ -15,11 +15,24 @@ export type InternalMethodsMiddlewareHooks = {
* @returns The user's secret recovery phrase.
*/
getMnemonic: () => Promise<Uint8Array>;

/**
* A hook that returns the simulation state.
*
* @returns The simulation state.
*/
getSimulationState: () => ApplicationState;

/**
* A hook that sets the current chain ID.
*
* @param chainId - The chain ID.
*/
setCurrentChain: (chainId: Hex) => null;
};

const methodHandlers = {
/* eslint-disable @typescript-eslint/naming-convention */
metamask_getProviderState: getProviderStateHandler,
eth_requestAccounts: getAccountsHandler,
eth_accounts: getAccountsHandler,
eth_chainId: getChainIdHandler,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { PendingJsonRpcResponse } from '@metamask/utils';

import { getNetworkVersionHandler } from './net-version';
import { createStore } from '../../store';
import { getMockOptions } from '../../test-utils';

describe('getNetworkVersionHandler', () => {
it('returns the network version', async () => {
const { store } = createStore(getMockOptions());
const end = jest.fn();
const result: PendingJsonRpcResponse = {
jsonrpc: '2.0' as const,
Expand All @@ -20,6 +23,7 @@ describe('getNetworkVersionHandler', () => {
result,
jest.fn(),
end,
{ getSimulationState: store.getState },
);

expect(end).toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import type {
JsonRpcEngineEndCallback,
JsonRpcEngineNextCallback,
} from '@metamask/json-rpc-engine';
import { hexToBigInt } from '@metamask/utils';
import type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';

import type { InternalMethodsMiddlewareHooks } from './middleware';

/**
* A mock handler for net_version that always returns a specific
* hardcoded result.
Expand All @@ -14,17 +17,18 @@ import type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';
* result.
* @param _next - The `json-rpc-engine` middleware next handler.
* @param end - The `json-rpc-engine` middleware end handler.
* @param hooks - The method hooks.
* @returns The JSON-RPC response.
*/
export async function getNetworkVersionHandler(
_request: JsonRpcRequest,
response: PendingJsonRpcResponse,
_next: JsonRpcEngineNextCallback,
end: JsonRpcEngineEndCallback,
hooks: Pick<InternalMethodsMiddlewareHooks, 'getSimulationState'>,
) {
// For now this will return a mocked result, this should probably match
// whatever network the simulation is using.
response.result = '1';
const hexChainId = hooks.getSimulationState().chain.chainId;
response.result = hexToBigInt(hexChainId).toString(10);

return end();
}

This file was deleted.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getProviderState is no longer called by Snaps, should be dead code.

This file was deleted.

Loading
Loading