import { permissionRpcMethods } from '@metamask/snap-controllers'; import { selectHooks } from '@metamask/rpc-methods'; import { ethErrors } from 'eth-rpc-errors'; import { UNSUPPORTED_RPC_METHODS } from '../../../../shared/constants/network'; import localHandlers from './handlers'; const allHandlers = [...localHandlers, ...permissionRpcMethods.handlers]; const handlerMap = allHandlers.reduce((map, handler) => { for (const methodName of handler.methodNames) { map.set(methodName, handler); } return map; }, new Map()); /** * Creates a json-rpc-engine middleware of RPC method implementations. * * Handlers consume functions that hook into the background, and only depend * on their signatures, not e.g. controller internals. * * @param {Record} hooks - Required "hooks" into our * controllers. * @returns {(req: Object, res: Object, next: Function, end: Function) => void} */ export default function createMethodMiddleware(hooks) { return async function methodMiddleware(req, res, next, end) { // Reject unsupported methods. if (UNSUPPORTED_RPC_METHODS.has(req.method)) { return end(ethErrors.rpc.methodNotSupported()); } const handler = handlerMap.get(req.method); if (handler) { const { implementation, hookNames } = handler; try { // Implementations may or may not be async, so we must await them. return await implementation( req, res, next, end, selectHooks(hooks, hookNames), ); } catch (error) { return end(error); } } return next(); }; }