@metamask/snaps-rpc-methods
Version:
MetaMask Snaps JSON-RPC method implementations
1 lines • 7.3 kB
Source Map (JSON)
{"version":3,"file":"messengerCall.cjs","sourceRoot":"","sources":["../../src/permitted/messengerCall.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n JsonRpcEngineEndCallback,\n MethodHandler,\n} from '@metamask/json-rpc-engine';\nimport type { Messenger, NamespacedName } from '@metamask/messenger';\nimport type { PermissionControllerGetPermissionAction } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n MessengerCallParams,\n MessengerCallResult,\n} from '@metamask/snaps-sdk';\nimport type { InferMatching } from '@metamask/snaps-utils';\nimport { create, object, StructError, array } from '@metamask/superstruct';\nimport type { Json, PendingJsonRpcResponse } from '@metamask/utils';\nimport { definePattern, JsonStruct } from '@metamask/utils';\n\nimport { SnapEndowments } from '../endowments';\nimport { getMessengerCaveatActions } from '../endowments/messenger';\nimport type {\n JsonRpcRequestWithOrigin,\n SnapControllerGetSnapAction,\n} from '../types';\nimport type { MethodHooksObject } from '../utils';\n\nconst hookNames: MethodHooksObject<MessengerCallMethodHooks> = {\n getMessenger: true,\n};\n\ntype GenericMessengerAction = {\n type: NamespacedName;\n handler: (...args: Json[]) => Promise<Json>;\n};\n\nexport type MessengerCallMethodHooks = {\n getMessenger: (args: {\n actions?: string[] | null;\n events?: string[] | null;\n }) => Messenger<string, GenericMessengerAction>;\n};\n\nexport type MessengerCallMethodActions =\n | SnapControllerGetSnapAction\n | PermissionControllerGetPermissionAction;\n\nconst BLOCKED_MESSENGER_CLIENTS = [\n 'ApprovalController',\n 'KeyringController',\n 'PermissionController',\n 'SnapController',\n 'WebSocketService',\n 'CronjobController',\n 'SnapInsightsController',\n 'SnapInterfaceController',\n 'MultichainRoutingService',\n 'ExecutionService',\n 'SnapRegistryController',\n];\n\nconst MessengerCallParametersStruct = object({\n action: definePattern<`${string}:${string}`>('MessengerAction', /^.+:.+$/u),\n params: array(JsonStruct),\n});\n\nexport type MessengerCallParameters = InferMatching<\n typeof MessengerCallParametersStruct,\n MessengerCallParams\n>;\n\n/**\n * Handler for the `snap_messengerCall` method.\n *\n * @internal\n */\nexport const messengerCallHandler = {\n implementation: getMessengerCallImplementation,\n hookNames,\n actionNames: ['SnapController:getSnap', 'PermissionController:getPermission'],\n} satisfies MethodHandler<\n MessengerCallMethodHooks,\n MessengerCallMethodActions,\n MessengerCallParameters,\n MessengerCallResult,\n { origin: string }\n>;\n\n/**\n * The `snap_messengerCall` method implementation. This method is used to dispatch\n * an action via the messenger. It is only available to preinstalled Snaps.\n *\n * @param request - The JSON-RPC request object.\n * @param response - The JSON-RPC response object.\n * @param _next - The `json-rpc-engine` \"next\" callback. Not used by this\n * function.\n * @param end - The `json-rpc-engine` \"end\" callback.\n * @param hooks - The RPC method hooks.\n * @param hooks.getMessenger - The hook function to create a custom messenger for the Snap.\n * @param messenger - The messenger used to call controller actions.\n * @returns Nothing.\n */\nasync function getMessengerCallImplementation(\n request: JsonRpcRequestWithOrigin<MessengerCallParams>,\n response: PendingJsonRpcResponse,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n { getMessenger }: MessengerCallMethodHooks,\n messenger: Messenger<string, MessengerCallMethodActions>,\n): Promise<void> {\n const snap = messenger.call('SnapController:getSnap', request.origin);\n const permission = messenger.call(\n 'PermissionController:getPermission',\n request.origin,\n SnapEndowments.Messenger,\n );\n\n if (!snap?.preinstalled || !permission) {\n return end(rpcErrors.methodNotFound());\n }\n\n const actions = getMessengerCaveatActions(permission);\n\n const snapMessenger = getMessenger({ actions });\n\n const { params } = request;\n\n try {\n const { action, params: actionParams } = getValidatedParams(params);\n\n if (\n BLOCKED_MESSENGER_CLIENTS.some((namespace) =>\n action.startsWith(namespace),\n )\n ) {\n return end(\n rpcErrors.invalidParams({\n message: `Access to the following messenger clients are disallowed in Snaps: ${BLOCKED_MESSENGER_CLIENTS.join(', ')}.`,\n }),\n );\n }\n\n response.result = await snapMessenger.call(action, ...actionParams);\n } catch (error) {\n return end(error);\n }\n\n return end();\n}\n\n/**\n * Validate the parameters for the `snap_messengerCall` method.\n *\n * @param params - Parameters to validate.\n * @returns Validated parameters.\n * @throws Throws RPC error if validation fails.\n */\nfunction getValidatedParams(params: unknown): MessengerCallParameters {\n try {\n return create(params, MessengerCallParametersStruct);\n } catch (error) {\n if (error instanceof StructError) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}.`,\n });\n }\n\n /* istanbul ignore next */\n throw rpcErrors.internal();\n }\n}\n"]}