@metamask/snaps-controllers 9.19.1 → 10.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -1
- package/dist/cronjob/CronjobController.cjs +15 -1
- package/dist/cronjob/CronjobController.cjs.map +1 -1
- package/dist/cronjob/CronjobController.d.cts.map +1 -1
- package/dist/cronjob/CronjobController.d.mts.map +1 -1
- package/dist/cronjob/CronjobController.mjs +15 -1
- package/dist/cronjob/CronjobController.mjs.map +1 -1
- package/dist/interface/SnapInterfaceController.cjs.map +1 -1
- package/dist/interface/SnapInterfaceController.d.cts.map +1 -1
- package/dist/interface/SnapInterfaceController.d.mts.map +1 -1
- package/dist/interface/SnapInterfaceController.mjs.map +1 -1
- package/dist/multichain/MultichainRouter.cjs +9 -1
- package/dist/multichain/MultichainRouter.cjs.map +1 -1
- package/dist/multichain/MultichainRouter.d.cts +1 -1
- package/dist/multichain/MultichainRouter.d.cts.map +1 -1
- package/dist/multichain/MultichainRouter.d.mts +1 -1
- package/dist/multichain/MultichainRouter.d.mts.map +1 -1
- package/dist/multichain/MultichainRouter.mjs +9 -1
- package/dist/multichain/MultichainRouter.mjs.map +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.mjs +1 -1
- package/dist/node.mjs.map +1 -1
- package/dist/react-native.cjs +1 -1
- package/dist/react-native.cjs.map +1 -1
- package/dist/react-native.mjs +1 -1
- package/dist/react-native.mjs.map +1 -1
- package/dist/services/AbstractExecutionService.cjs +7 -2
- package/dist/services/AbstractExecutionService.cjs.map +1 -1
- package/dist/services/AbstractExecutionService.d.cts +1 -1
- package/dist/services/AbstractExecutionService.d.cts.map +1 -1
- package/dist/services/AbstractExecutionService.d.mts +1 -1
- package/dist/services/AbstractExecutionService.d.mts.map +1 -1
- package/dist/services/AbstractExecutionService.mjs +7 -2
- package/dist/services/AbstractExecutionService.mjs.map +1 -1
- package/dist/services/ExecutionService.cjs +0 -1
- package/dist/services/ExecutionService.cjs.map +1 -1
- package/dist/services/ExecutionService.d.cts +7 -7
- package/dist/services/ExecutionService.d.cts.map +1 -1
- package/dist/services/ExecutionService.d.mts +7 -7
- package/dist/services/ExecutionService.d.mts.map +1 -1
- package/dist/services/ExecutionService.mjs +0 -1
- package/dist/services/ExecutionService.mjs.map +1 -1
- package/dist/services/browser.cjs +0 -1
- package/dist/services/browser.cjs.map +1 -1
- package/dist/services/browser.d.cts +1 -1
- package/dist/services/browser.d.cts.map +1 -1
- package/dist/services/browser.d.mts +1 -1
- package/dist/services/browser.d.mts.map +1 -1
- package/dist/services/browser.mjs +0 -1
- package/dist/services/browser.mjs.map +1 -1
- package/dist/services/iframe/IframeExecutionService.cjs +2 -1
- package/dist/services/iframe/IframeExecutionService.cjs.map +1 -1
- package/dist/services/iframe/IframeExecutionService.d.cts +1 -1
- package/dist/services/iframe/IframeExecutionService.d.cts.map +1 -1
- package/dist/services/iframe/IframeExecutionService.d.mts +1 -1
- package/dist/services/iframe/IframeExecutionService.d.mts.map +1 -1
- package/dist/services/iframe/IframeExecutionService.mjs +2 -1
- package/dist/services/iframe/IframeExecutionService.mjs.map +1 -1
- package/dist/services/index.cjs +0 -1
- package/dist/services/index.cjs.map +1 -1
- package/dist/services/index.d.cts +1 -1
- package/dist/services/index.d.cts.map +1 -1
- package/dist/services/index.d.mts +1 -1
- package/dist/services/index.d.mts.map +1 -1
- package/dist/services/index.mjs +0 -1
- package/dist/services/index.mjs.map +1 -1
- package/dist/services/node-js/NodeThreadExecutionService.cjs +3 -1
- package/dist/services/node-js/NodeThreadExecutionService.cjs.map +1 -1
- package/dist/services/node-js/NodeThreadExecutionService.d.cts.map +1 -1
- package/dist/services/node-js/NodeThreadExecutionService.d.mts.map +1 -1
- package/dist/services/node-js/NodeThreadExecutionService.mjs +3 -1
- package/dist/services/node-js/NodeThreadExecutionService.mjs.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.cjs +2 -1
- package/dist/services/offscreen/OffscreenExecutionService.cjs.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.d.cts +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.d.cts.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.d.mts +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.d.mts.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.mjs +2 -1
- package/dist/services/offscreen/OffscreenExecutionService.mjs.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.cjs +5 -1
- package/dist/services/proxy/ProxyExecutionService.cjs.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.d.cts +1 -1
- package/dist/services/proxy/ProxyExecutionService.d.cts.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.d.mts +1 -1
- package/dist/services/proxy/ProxyExecutionService.d.mts.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.mjs +5 -1
- package/dist/services/proxy/ProxyExecutionService.mjs.map +1 -1
- package/dist/services/webview/WebViewExecutionService.cjs +20 -22
- package/dist/services/webview/WebViewExecutionService.cjs.map +1 -1
- package/dist/services/webview/WebViewExecutionService.d.cts +10 -7
- package/dist/services/webview/WebViewExecutionService.d.cts.map +1 -1
- package/dist/services/webview/WebViewExecutionService.d.mts +10 -7
- package/dist/services/webview/WebViewExecutionService.d.mts.map +1 -1
- package/dist/services/webview/WebViewExecutionService.mjs +20 -22
- package/dist/services/webview/WebViewExecutionService.mjs.map +1 -1
- package/dist/services/webview/WebViewMessageStream.cjs +14 -22
- package/dist/services/webview/WebViewMessageStream.cjs.map +1 -1
- package/dist/services/webview/WebViewMessageStream.d.cts +3 -3
- package/dist/services/webview/WebViewMessageStream.d.cts.map +1 -1
- package/dist/services/webview/WebViewMessageStream.d.mts +3 -3
- package/dist/services/webview/WebViewMessageStream.d.mts.map +1 -1
- package/dist/services/webview/WebViewMessageStream.mjs +15 -23
- package/dist/services/webview/WebViewMessageStream.mjs.map +1 -1
- package/dist/services/webworker/WebWorkerExecutionService.cjs +8 -1
- package/dist/services/webworker/WebWorkerExecutionService.cjs.map +1 -1
- package/dist/services/webworker/WebWorkerExecutionService.d.cts +1 -1
- package/dist/services/webworker/WebWorkerExecutionService.d.cts.map +1 -1
- package/dist/services/webworker/WebWorkerExecutionService.d.mts +1 -1
- package/dist/services/webworker/WebWorkerExecutionService.d.mts.map +1 -1
- package/dist/services/webworker/WebWorkerExecutionService.mjs +8 -1
- package/dist/services/webworker/WebWorkerExecutionService.mjs.map +1 -1
- package/dist/snaps/RequestQueue.cjs.map +1 -1
- package/dist/snaps/RequestQueue.d.cts.map +1 -1
- package/dist/snaps/RequestQueue.d.mts.map +1 -1
- package/dist/snaps/RequestQueue.mjs.map +1 -1
- package/dist/snaps/SnapController.cjs +15 -14
- package/dist/snaps/SnapController.cjs.map +1 -1
- package/dist/snaps/SnapController.d.cts +10 -10
- package/dist/snaps/SnapController.d.cts.map +1 -1
- package/dist/snaps/SnapController.d.mts +10 -10
- package/dist/snaps/SnapController.d.mts.map +1 -1
- package/dist/snaps/SnapController.mjs +15 -18
- package/dist/snaps/SnapController.mjs.map +1 -1
- package/dist/snaps/Timer.cjs +3 -0
- package/dist/snaps/Timer.cjs.map +1 -1
- package/dist/snaps/Timer.d.cts.map +1 -1
- package/dist/snaps/Timer.d.mts.map +1 -1
- package/dist/snaps/Timer.mjs +3 -0
- package/dist/snaps/Timer.mjs.map +1 -1
- package/dist/snaps/location/http.cjs +6 -0
- package/dist/snaps/location/http.cjs.map +1 -1
- package/dist/snaps/location/http.d.cts +2 -2
- package/dist/snaps/location/http.d.cts.map +1 -1
- package/dist/snaps/location/http.d.mts +2 -2
- package/dist/snaps/location/http.d.mts.map +1 -1
- package/dist/snaps/location/http.mjs +6 -0
- package/dist/snaps/location/http.mjs.map +1 -1
- package/dist/snaps/location/location.cjs.map +1 -1
- package/dist/snaps/location/location.d.cts +2 -2
- package/dist/snaps/location/location.d.cts.map +1 -1
- package/dist/snaps/location/location.d.mts +2 -2
- package/dist/snaps/location/location.d.mts.map +1 -1
- package/dist/snaps/location/location.mjs.map +1 -1
- package/dist/snaps/location/npm.cjs +1 -0
- package/dist/snaps/location/npm.cjs.map +1 -1
- package/dist/snaps/location/npm.d.cts +5 -5
- package/dist/snaps/location/npm.d.cts.map +1 -1
- package/dist/snaps/location/npm.d.mts +5 -5
- package/dist/snaps/location/npm.d.mts.map +1 -1
- package/dist/snaps/location/npm.mjs +1 -0
- package/dist/snaps/location/npm.mjs.map +1 -1
- package/dist/snaps/registry/json.cjs.map +1 -1
- package/dist/snaps/registry/json.mjs.map +1 -1
- package/dist/snaps/registry/registry.cjs.map +1 -1
- package/dist/snaps/registry/registry.d.cts +0 -1
- package/dist/snaps/registry/registry.d.cts.map +1 -1
- package/dist/snaps/registry/registry.d.mts +0 -1
- package/dist/snaps/registry/registry.d.mts.map +1 -1
- package/dist/snaps/registry/registry.mjs.map +1 -1
- package/dist/types/controllers.cjs +0 -1
- package/dist/types/controllers.cjs.map +1 -1
- package/dist/types/controllers.d.cts +1 -3
- package/dist/types/controllers.d.cts.map +1 -1
- package/dist/types/controllers.d.mts +1 -3
- package/dist/types/controllers.d.mts.map +1 -1
- package/dist/types/controllers.mjs +0 -1
- package/dist/types/controllers.mjs.map +1 -1
- package/dist/types/index.cjs +0 -16
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +2 -2
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs +1 -2
- package/dist/types/index.mjs.map +1 -1
- package/package.json +17 -31
- package/react-native.d.ts +0 -2
- package/react-native.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapInterfaceController.d.mts","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EACnB,sCAAsC;AACvC,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EACX,sCAAsC;AACvC,OAAO,KAAK,EACV,cAAc,EACd,MAAM,EACN,kBAAkB,EAClB,gBAAgB,EACjB,4BAA4B;AAC7B,OAAO,EAAE,WAAW,EAAE,4BAA4B;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAE1D,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"SnapInterfaceController.d.mts","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapInterfaceController.mjs","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AcceptRequest,\n HasApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n MaybeUpdateState,\n TestOrigin,\n} from '@metamask/phishing-controller';\nimport type {\n InterfaceState,\n SnapId,\n ComponentOrElement,\n InterfaceContext,\n} from '@metamask/snaps-sdk';\nimport { ContentType } from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\nimport { getJsonSizeUnsafe, validateJsxLinks } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { assert, hasProperty } from '@metamask/utils';\nimport { castDraft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport type { GetSnap } from '../snaps';\nimport {\n constructState,\n getJsxInterface,\n validateInterfaceContext,\n} from './utils';\n\nconst MAX_UI_CONTENT_SIZE = 10_000_000; // 10 mb\n\nconst controllerName = 'SnapInterfaceController';\n\nexport type CreateInterface = {\n type: `${typeof controllerName}:createInterface`;\n handler: SnapInterfaceController['createInterface'];\n};\n\nexport type GetInterface = {\n type: `${typeof controllerName}:getInterface`;\n handler: SnapInterfaceController['getInterface'];\n};\n\nexport type UpdateInterface = {\n type: `${typeof controllerName}:updateInterface`;\n handler: SnapInterfaceController['updateInterface'];\n};\n\nexport type DeleteInterface = {\n type: `${typeof controllerName}:deleteInterface`;\n handler: SnapInterfaceController['deleteInterface'];\n};\n\nexport type UpdateInterfaceState = {\n type: `${typeof controllerName}:updateInterfaceState`;\n handler: SnapInterfaceController['updateInterfaceState'];\n};\n\nexport type ResolveInterface = {\n type: `${typeof controllerName}:resolveInterface`;\n handler: SnapInterfaceController['resolveInterface'];\n};\n\nexport type SnapInterfaceControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SnapInterfaceControllerState\n>;\n\nexport type SnapInterfaceControllerAllowedActions =\n | TestOrigin\n | MaybeUpdateState\n | HasApprovalRequest\n | AcceptRequest\n | GetSnap;\n\nexport type SnapInterfaceControllerActions =\n | CreateInterface\n | GetInterface\n | UpdateInterface\n | DeleteInterface\n | UpdateInterfaceState\n | ResolveInterface\n | SnapInterfaceControllerGetStateAction;\n\nexport type SnapInterfaceControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SnapInterfaceControllerState\n >;\n\ntype OtherNotification = { type: string; [key: string]: unknown };\n\nexport type ExpandedView = {\n title: string;\n interfaceId: string;\n footerLink?: { href: string; text: string };\n};\n\ntype NormalSnapNotificationData = { message: string; origin: string };\n\ntype ExpandedSnapNotificationData = {\n message: string;\n origin: string;\n detailedView: ExpandedView;\n};\n\ntype SnapNotification = {\n type: 'snap';\n data: NormalSnapNotificationData | ExpandedSnapNotificationData;\n readDate: string | null;\n};\n\ntype Notification = OtherNotification | SnapNotification;\n\ntype NotificationListUpdatedEvent = {\n type: 'NotificationServicesController:notificationsListUpdated';\n payload: [Notification[]];\n};\n\nexport type SnapInterfaceControllerEvents =\n | SnapInterfaceControllerStateChangeEvent\n | NotificationListUpdatedEvent;\n\nexport type SnapInterfaceControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SnapInterfaceControllerActions | SnapInterfaceControllerAllowedActions,\n SnapInterfaceControllerEvents,\n SnapInterfaceControllerAllowedActions['type'],\n SnapInterfaceControllerEvents['type']\n>;\n\nexport type StoredInterface = {\n snapId: SnapId;\n content: JSXElement;\n state: InterfaceState;\n context: InterfaceContext | null;\n contentType: ContentType | null;\n};\n\nexport type SnapInterfaceControllerState = {\n interfaces: Record<string, StoredInterface>;\n};\n\nexport type SnapInterfaceControllerArgs = {\n messenger: SnapInterfaceControllerMessenger;\n state?: SnapInterfaceControllerState;\n};\n\n/**\n * Use this controller to manage snaps UI interfaces using RPC method hooks.\n */\nexport class SnapInterfaceController extends BaseController<\n typeof controllerName,\n SnapInterfaceControllerState,\n SnapInterfaceControllerMessenger\n> {\n constructor({ messenger, state }: SnapInterfaceControllerArgs) {\n super({\n messenger,\n metadata: {\n interfaces: {\n persist: (interfaces: Record<string, StoredInterface>) => {\n return Object.entries(interfaces).reduce<\n Record<string, StoredInterface>\n >((persistedInterfaces, [id, snapInterface]) => {\n switch (snapInterface.contentType) {\n case ContentType.Notification:\n persistedInterfaces[id] = snapInterface;\n return persistedInterfaces;\n default:\n return persistedInterfaces;\n }\n }, {});\n },\n anonymous: false,\n },\n },\n name: controllerName,\n state: { interfaces: {}, ...state },\n });\n\n this.messagingSystem.subscribe(\n 'NotificationServicesController:notificationsListUpdated',\n this.#onNotificationsListUpdated.bind(this),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system\n * actions.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:createInterface`,\n this.createInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getInterface`,\n this.getInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterface`,\n this.updateInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:deleteInterface`,\n this.deleteInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterfaceState`,\n this.updateInterfaceState.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:resolveInterface`,\n this.resolveInterface.bind(this),\n );\n }\n\n /**\n * Create an interface in the controller state with the associated data.\n *\n * @param snapId - The snap id that created the interface.\n * @param content - The interface content.\n * @param context - An optional interface context object.\n * @param contentType - The type of content.\n * @returns The newly interface id.\n */\n async createInterface(\n snapId: SnapId,\n content: ComponentOrElement,\n context?: InterfaceContext,\n contentType?: ContentType,\n ) {\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const id = nanoid();\n const componentState = constructState({}, element);\n\n this.update((draftState) => {\n // @ts-expect-error - TS2589: Type instantiation is excessively deep and\n // possibly infinite.\n draftState.interfaces[id] = {\n snapId,\n content: castDraft(element),\n state: componentState,\n context: context ?? null,\n contentType: contentType ?? null,\n };\n });\n\n return id;\n }\n\n /**\n * Get the data of a given interface id.\n *\n * @param snapId - The snap id requesting the interface data.\n * @param id - The interface id.\n * @returns The interface state.\n */\n getInterface(snapId: SnapId, id: string) {\n this.#validateArgs(snapId, id);\n\n return this.state.interfaces[id];\n }\n\n /**\n * Update the interface with the given content.\n *\n * @param snapId - The snap id requesting the update.\n * @param id - The interface id.\n * @param content - The new content.\n * @param context - An optional interface context object.\n */\n async updateInterface(\n snapId: SnapId,\n id: string,\n content: ComponentOrElement,\n context?: InterfaceContext,\n ) {\n this.#validateArgs(snapId, id);\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const oldState = this.state.interfaces[id].state;\n const newState = constructState(oldState, element);\n\n this.update((draftState) => {\n draftState.interfaces[id].state = newState;\n draftState.interfaces[id].content = castDraft(element);\n if (context) {\n draftState.interfaces[id].context = context;\n }\n });\n }\n\n /**\n * Delete an interface from state.\n *\n * @param id - The interface id.\n */\n deleteInterface(id: string) {\n this.update((draftState) => {\n delete draftState.interfaces[id];\n });\n }\n\n /**\n * Update the interface state.\n *\n * @param id - The interface id.\n * @param state - The new state.\n */\n updateInterfaceState(id: string, state: InterfaceState) {\n this.update((draftState) => {\n draftState.interfaces[id].state = state;\n });\n }\n\n /**\n * Resolve the promise of a given interface approval request.\n * The approval needs to have the same ID as the interface.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async resolveInterface(snapId: SnapId, id: string, value: Json) {\n this.#validateArgs(snapId, id);\n this.#validateApproval(id);\n\n await this.#acceptApprovalRequest(id, value);\n\n this.deleteInterface(id);\n }\n\n /**\n * Utility function to validate the args passed to the other methods.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n */\n #validateArgs(snapId: SnapId, id: string) {\n const existingInterface = this.state.interfaces[id];\n\n assert(\n existingInterface !== undefined,\n `Interface with id '${id}' not found.`,\n );\n assert(\n existingInterface.snapId === snapId,\n `Interface not created by ${snapId}.`,\n );\n }\n\n /**\n * Utility function to validate that the approval request exists.\n *\n * @param id - The interface id.\n */\n #validateApproval(id: string) {\n assert(\n this.#hasApprovalRequest(id),\n `Approval request with id '${id}' not found.`,\n );\n }\n\n /**\n * Trigger a Phishing list update if needed.\n */\n async #triggerPhishingListUpdate() {\n await this.messagingSystem.call('PhishingController:maybeUpdateState');\n }\n\n /**\n * Check an origin against the phishing list.\n *\n * @param origin - The origin to check.\n * @returns True if the origin is on the phishing list, otherwise false.\n */\n #checkPhishingList(origin: string) {\n return this.messagingSystem.call('PhishingController:testOrigin', origin)\n .result;\n }\n\n /**\n * Check if an approval request exists for a given interface by looking up\n * if the ApprovalController has a request with the given interface ID.\n *\n * @param id - The interface id.\n * @returns True if an approval request exists, otherwise false.\n */\n #hasApprovalRequest(id: string) {\n return this.messagingSystem.call('ApprovalController:hasRequest', {\n id,\n });\n }\n\n /**\n * Accept an approval request for a given interface.\n *\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async #acceptApprovalRequest(id: string, value: Json) {\n await this.messagingSystem.call(\n 'ApprovalController:acceptRequest',\n id,\n value,\n );\n }\n\n /**\n * Utility function to validate the components of an interface.\n * Throws if something is invalid.\n *\n * @param element - The JSX element to verify.\n */\n async #validateContent(element: JSXElement) {\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(element);\n assert(\n size <= MAX_UI_CONTENT_SIZE,\n `A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE / 1000000} MB.`,\n );\n\n await this.#triggerPhishingListUpdate();\n validateJsxLinks(\n element,\n this.#checkPhishingList.bind(this),\n (id: string) => this.messagingSystem.call('SnapController:get', id),\n );\n }\n\n #onNotificationsListUpdated(notificationsList: Notification[]) {\n const snapNotificationsWithInterface = notificationsList.filter(\n (notification) => {\n return (\n notification.type === 'snap' &&\n hasProperty((notification as SnapNotification).data, 'detailedView')\n );\n },\n );\n\n const interfaceIdSet = new Set(\n snapNotificationsWithInterface.map(\n (notification) =>\n (\n (notification as SnapNotification)\n .data as ExpandedSnapNotificationData\n ).detailedView.interfaceId,\n ),\n );\n\n this.update((state) => {\n Object.entries(state.interfaces).forEach(([id, snapInterface]) => {\n if (\n snapInterface.contentType === ContentType.Notification &&\n !interfaceIdSet.has(id)\n ) {\n delete state.interfaces[id];\n }\n });\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SnapInterfaceController.mjs","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AcceptRequest,\n HasApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n MaybeUpdateState,\n TestOrigin,\n} from '@metamask/phishing-controller';\nimport type {\n InterfaceState,\n SnapId,\n ComponentOrElement,\n InterfaceContext,\n} from '@metamask/snaps-sdk';\nimport { ContentType } from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\nimport { getJsonSizeUnsafe, validateJsxLinks } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { assert, hasProperty } from '@metamask/utils';\nimport { castDraft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport {\n constructState,\n getJsxInterface,\n validateInterfaceContext,\n} from './utils';\nimport type { GetSnap } from '../snaps';\n\nconst MAX_UI_CONTENT_SIZE = 10_000_000; // 10 mb\n\nconst controllerName = 'SnapInterfaceController';\n\nexport type CreateInterface = {\n type: `${typeof controllerName}:createInterface`;\n handler: SnapInterfaceController['createInterface'];\n};\n\nexport type GetInterface = {\n type: `${typeof controllerName}:getInterface`;\n handler: SnapInterfaceController['getInterface'];\n};\n\nexport type UpdateInterface = {\n type: `${typeof controllerName}:updateInterface`;\n handler: SnapInterfaceController['updateInterface'];\n};\n\nexport type DeleteInterface = {\n type: `${typeof controllerName}:deleteInterface`;\n handler: SnapInterfaceController['deleteInterface'];\n};\n\nexport type UpdateInterfaceState = {\n type: `${typeof controllerName}:updateInterfaceState`;\n handler: SnapInterfaceController['updateInterfaceState'];\n};\n\nexport type ResolveInterface = {\n type: `${typeof controllerName}:resolveInterface`;\n handler: SnapInterfaceController['resolveInterface'];\n};\n\nexport type SnapInterfaceControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SnapInterfaceControllerState\n>;\n\nexport type SnapInterfaceControllerAllowedActions =\n | TestOrigin\n | MaybeUpdateState\n | HasApprovalRequest\n | AcceptRequest\n | GetSnap;\n\nexport type SnapInterfaceControllerActions =\n | CreateInterface\n | GetInterface\n | UpdateInterface\n | DeleteInterface\n | UpdateInterfaceState\n | ResolveInterface\n | SnapInterfaceControllerGetStateAction;\n\nexport type SnapInterfaceControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SnapInterfaceControllerState\n >;\n\ntype OtherNotification = { type: string; [key: string]: unknown };\n\nexport type ExpandedView = {\n title: string;\n interfaceId: string;\n footerLink?: { href: string; text: string };\n};\n\ntype NormalSnapNotificationData = { message: string; origin: string };\n\ntype ExpandedSnapNotificationData = {\n message: string;\n origin: string;\n detailedView: ExpandedView;\n};\n\ntype SnapNotification = {\n type: 'snap';\n data: NormalSnapNotificationData | ExpandedSnapNotificationData;\n readDate: string | null;\n};\n\ntype Notification = OtherNotification | SnapNotification;\n\ntype NotificationListUpdatedEvent = {\n type: 'NotificationServicesController:notificationsListUpdated';\n payload: [Notification[]];\n};\n\nexport type SnapInterfaceControllerEvents =\n | SnapInterfaceControllerStateChangeEvent\n | NotificationListUpdatedEvent;\n\nexport type SnapInterfaceControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SnapInterfaceControllerActions | SnapInterfaceControllerAllowedActions,\n SnapInterfaceControllerEvents,\n SnapInterfaceControllerAllowedActions['type'],\n SnapInterfaceControllerEvents['type']\n>;\n\nexport type StoredInterface = {\n snapId: SnapId;\n content: JSXElement;\n state: InterfaceState;\n context: InterfaceContext | null;\n contentType: ContentType | null;\n};\n\nexport type SnapInterfaceControllerState = {\n interfaces: Record<string, StoredInterface>;\n};\n\nexport type SnapInterfaceControllerArgs = {\n messenger: SnapInterfaceControllerMessenger;\n state?: SnapInterfaceControllerState;\n};\n\n/**\n * Use this controller to manage snaps UI interfaces using RPC method hooks.\n */\nexport class SnapInterfaceController extends BaseController<\n typeof controllerName,\n SnapInterfaceControllerState,\n SnapInterfaceControllerMessenger\n> {\n constructor({ messenger, state }: SnapInterfaceControllerArgs) {\n super({\n messenger,\n metadata: {\n interfaces: {\n persist: (interfaces: Record<string, StoredInterface>) => {\n return Object.entries(interfaces).reduce<\n Record<string, StoredInterface>\n >((persistedInterfaces, [id, snapInterface]) => {\n switch (snapInterface.contentType) {\n case ContentType.Notification:\n persistedInterfaces[id] = snapInterface;\n return persistedInterfaces;\n default:\n return persistedInterfaces;\n }\n }, {});\n },\n anonymous: false,\n },\n },\n name: controllerName,\n state: { interfaces: {}, ...state },\n });\n\n this.messagingSystem.subscribe(\n 'NotificationServicesController:notificationsListUpdated',\n this.#onNotificationsListUpdated.bind(this),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system\n * actions.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:createInterface`,\n this.createInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getInterface`,\n this.getInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterface`,\n this.updateInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:deleteInterface`,\n this.deleteInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterfaceState`,\n this.updateInterfaceState.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:resolveInterface`,\n this.resolveInterface.bind(this),\n );\n }\n\n /**\n * Create an interface in the controller state with the associated data.\n *\n * @param snapId - The snap id that created the interface.\n * @param content - The interface content.\n * @param context - An optional interface context object.\n * @param contentType - The type of content.\n * @returns The newly interface id.\n */\n async createInterface(\n snapId: SnapId,\n content: ComponentOrElement,\n context?: InterfaceContext,\n contentType?: ContentType,\n ) {\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const id = nanoid();\n const componentState = constructState({}, element);\n\n this.update((draftState) => {\n // @ts-expect-error - TS2589: Type instantiation is excessively deep and\n // possibly infinite.\n draftState.interfaces[id] = {\n snapId,\n content: castDraft(element),\n state: componentState,\n context: context ?? null,\n contentType: contentType ?? null,\n };\n });\n\n return id;\n }\n\n /**\n * Get the data of a given interface id.\n *\n * @param snapId - The snap id requesting the interface data.\n * @param id - The interface id.\n * @returns The interface state.\n */\n getInterface(snapId: SnapId, id: string) {\n this.#validateArgs(snapId, id);\n\n return this.state.interfaces[id];\n }\n\n /**\n * Update the interface with the given content.\n *\n * @param snapId - The snap id requesting the update.\n * @param id - The interface id.\n * @param content - The new content.\n * @param context - An optional interface context object.\n */\n async updateInterface(\n snapId: SnapId,\n id: string,\n content: ComponentOrElement,\n context?: InterfaceContext,\n ) {\n this.#validateArgs(snapId, id);\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const oldState = this.state.interfaces[id].state;\n const newState = constructState(oldState, element);\n\n this.update((draftState) => {\n draftState.interfaces[id].state = newState;\n draftState.interfaces[id].content = castDraft(element);\n if (context) {\n draftState.interfaces[id].context = context;\n }\n });\n }\n\n /**\n * Delete an interface from state.\n *\n * @param id - The interface id.\n */\n deleteInterface(id: string) {\n this.update((draftState) => {\n delete draftState.interfaces[id];\n });\n }\n\n /**\n * Update the interface state.\n *\n * @param id - The interface id.\n * @param state - The new state.\n */\n updateInterfaceState(id: string, state: InterfaceState) {\n this.update((draftState) => {\n draftState.interfaces[id].state = state;\n });\n }\n\n /**\n * Resolve the promise of a given interface approval request.\n * The approval needs to have the same ID as the interface.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async resolveInterface(snapId: SnapId, id: string, value: Json) {\n this.#validateArgs(snapId, id);\n this.#validateApproval(id);\n\n await this.#acceptApprovalRequest(id, value);\n\n this.deleteInterface(id);\n }\n\n /**\n * Utility function to validate the args passed to the other methods.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n */\n #validateArgs(snapId: SnapId, id: string) {\n const existingInterface = this.state.interfaces[id];\n\n assert(\n existingInterface !== undefined,\n `Interface with id '${id}' not found.`,\n );\n assert(\n existingInterface.snapId === snapId,\n `Interface not created by ${snapId}.`,\n );\n }\n\n /**\n * Utility function to validate that the approval request exists.\n *\n * @param id - The interface id.\n */\n #validateApproval(id: string) {\n assert(\n this.#hasApprovalRequest(id),\n `Approval request with id '${id}' not found.`,\n );\n }\n\n /**\n * Trigger a Phishing list update if needed.\n */\n async #triggerPhishingListUpdate() {\n await this.messagingSystem.call('PhishingController:maybeUpdateState');\n }\n\n /**\n * Check an origin against the phishing list.\n *\n * @param origin - The origin to check.\n * @returns True if the origin is on the phishing list, otherwise false.\n */\n #checkPhishingList(origin: string) {\n return this.messagingSystem.call('PhishingController:testOrigin', origin)\n .result;\n }\n\n /**\n * Check if an approval request exists for a given interface by looking up\n * if the ApprovalController has a request with the given interface ID.\n *\n * @param id - The interface id.\n * @returns True if an approval request exists, otherwise false.\n */\n #hasApprovalRequest(id: string) {\n return this.messagingSystem.call('ApprovalController:hasRequest', {\n id,\n });\n }\n\n /**\n * Accept an approval request for a given interface.\n *\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async #acceptApprovalRequest(id: string, value: Json) {\n await this.messagingSystem.call(\n 'ApprovalController:acceptRequest',\n id,\n value,\n );\n }\n\n /**\n * Utility function to validate the components of an interface.\n * Throws if something is invalid.\n *\n * @param element - The JSX element to verify.\n */\n async #validateContent(element: JSXElement) {\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(element);\n assert(\n size <= MAX_UI_CONTENT_SIZE,\n `A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE / 1000000} MB.`,\n );\n\n await this.#triggerPhishingListUpdate();\n validateJsxLinks(\n element,\n this.#checkPhishingList.bind(this),\n (id: string) => this.messagingSystem.call('SnapController:get', id),\n );\n }\n\n #onNotificationsListUpdated(notificationsList: Notification[]) {\n const snapNotificationsWithInterface = notificationsList.filter(\n (notification) => {\n return (\n notification.type === 'snap' &&\n hasProperty((notification as SnapNotification).data, 'detailedView')\n );\n },\n );\n\n const interfaceIdSet = new Set(\n snapNotificationsWithInterface.map(\n (notification) =>\n (\n (notification as SnapNotification)\n .data as ExpandedSnapNotificationData\n ).detailedView.interfaceId,\n ),\n );\n\n this.update((state) => {\n Object.entries(state.interfaces).forEach(([id, snapInterface]) => {\n if (\n snapInterface.contentType === ContentType.Notification &&\n !interfaceIdSet.has(id)\n ) {\n delete state.interfaces[id];\n }\n });\n });\n }\n}\n"]}
|
|
@@ -17,6 +17,7 @@ const rpc_errors_1 = require("@metamask/rpc-errors");
|
|
|
17
17
|
const snaps_rpc_methods_1 = require("@metamask/snaps-rpc-methods");
|
|
18
18
|
const snaps_utils_1 = require("@metamask/snaps-utils");
|
|
19
19
|
const utils_1 = require("@metamask/utils");
|
|
20
|
+
const nanoid_1 = require("nanoid");
|
|
20
21
|
const snaps_1 = require("../snaps/index.cjs");
|
|
21
22
|
const name = 'MultichainRouter';
|
|
22
23
|
class MultichainRouter {
|
|
@@ -45,10 +46,17 @@ class MultichainRouter {
|
|
|
45
46
|
* @returns The response from the chosen Snap.
|
|
46
47
|
* @throws If no handler was found.
|
|
47
48
|
*/
|
|
48
|
-
async handleRequest({ connectedAddresses, origin, scope, request, }) {
|
|
49
|
+
async handleRequest({ connectedAddresses, origin, scope, request: rawRequest, }) {
|
|
49
50
|
// Explicitly block EVM scopes, just in case.
|
|
50
51
|
(0, utils_1.assert)(!scope.startsWith(utils_1.KnownCaipNamespace.Eip155) &&
|
|
51
52
|
!scope.startsWith('wallet:eip155'));
|
|
53
|
+
// Re-create the request to simplify and remove additional properties that may be present in MM middleware.
|
|
54
|
+
const request = {
|
|
55
|
+
jsonrpc: '2.0',
|
|
56
|
+
id: rawRequest.id ?? (0, nanoid_1.nanoid)(),
|
|
57
|
+
method: rawRequest.method,
|
|
58
|
+
params: rawRequest.params,
|
|
59
|
+
};
|
|
52
60
|
const { method, params } = request;
|
|
53
61
|
// If the RPC request can be serviced by an account Snap, route it there.
|
|
54
62
|
const accountId = await __classPrivateFieldGet(this, _MultichainRouter_instances, "m", _MultichainRouter_getSnapAccountId).call(this, connectedAddresses, scope, request);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainRouter.cjs","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAEA,qDAAiD;AACjD,mEAGqC;AAErC,uDAAoD;AAMpD,2CAKyB;AAEzB,8CAA4C;AA4F5C,MAAM,IAAI,GAAG,kBAAkB,CAAC;AAEhC,MAAa,gBAAgB;IAS3B,YAAY,EAAE,SAAS,EAAE,eAAe,EAAwB;;QARhE,SAAI,GAAgB,IAAI,CAAC;QAEzB,UAAK,GAAG,IAAI,CAAC;QAEb,8CAAsC;QAEtC,oDAA0C;QAGxC,uBAAA,IAAI,+BAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,qCAAoB,eAAe,MAAA,CAAC;QAExC,uBAAA,IAAI,mCAAW,CAAC,qBAAqB,CACnC,GAAG,IAAI,gBAAgB,EACvB,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAC/C,CAAC;QAEF,uBAAA,IAAI,mCAAW,CAAC,qBAAqB,CACnC,GAAG,IAAI,sBAAsB,EAC7B,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAC/C,CAAC;QAEF,uBAAA,IAAI,mCAAW,CAAC,qBAAqB,CACnC,GAAG,IAAI,uBAAuB,EAC9B,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,CAChD,CAAC;QAEF,uBAAA,IAAI,mCAAW,CAAC,qBAAqB,CACnC,GAAG,IAAI,mBAAmB,EAC1B,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,CAC5C,CAAC;IACJ,CAAC;IAkID;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,aAAa,CAAC,EAClB,kBAAkB,EAClB,MAAM,EACN,KAAK,EACL,OAAO,GAMR;QACC,6CAA6C;QAC7C,IAAA,cAAM,EACJ,CAAC,KAAK,CAAC,UAAU,CAAC,0BAAkB,CAAC,MAAM,CAAC;YAC1C,CAAC,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CACrC,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAEnC,yEAAyE;QACzE,MAAM,SAAS,GAAG,MAAM,uBAAA,IAAI,uEAAkB,MAAtB,IAAI,EAC1B,kBAAkB,EAClB,KAAK,EACL,OAAO,CACR,CAAC;QAEF,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,uBAAA,IAAI,yCAAiB,MAArB,IAAI,EAAkB,KAAK,EAAE,OAAO,EAAE,EAAE,CAC7C,OAAO,CAAC,aAAa,CAAC;gBACpB,OAAO,EAAE,SAAS;gBAClB,KAAK;gBACL,MAAM;gBACN,MAAM,EAAE,MAAuB;aAChC,CAAC,CACH,CAAC;QACJ,CAAC;QAED,4DAA4D;QAC5D,qDAAqD;QACrD,MAAM,aAAa,GAAG,uBAAA,IAAI,uEAAkB,MAAtB,IAAI,EAAmB,KAAK,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC9B,CAAC;QAEF,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,uBAAA,IAAI,mCAAW,CAAC,IAAI,CAAC,8BAA8B,EAAE;gBAC1D,MAAM,EAAE,YAAY,CAAC,MAAM;gBAC3B,MAAM;gBACN,OAAO,EAAE;oBACP,MAAM,EAAE,EAAE;oBACV,MAAM,EAAE;wBACN,OAAO;wBACP,KAAK;qBACN;iBACF;gBACD,OAAO,EAAE,yBAAW,CAAC,iBAAiB;aACvC,CAAkB,CAAC;QACtB,CAAC;QAED,gEAAgE;QAChE,MAAM,sBAAS,CAAC,cAAc,EAAE,CAAC;IACnC,CAAC;IAcD;;;;;;OAMG;IACH,mBAAmB,CAAC,KAAkB;QACpC,MAAM,cAAc,GAAG,uBAAA,IAAI,mFAA8B,MAAlC,IAAI,EAA+B,KAAK,CAAC,CAAC,OAAO,CACtE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAC7B,CAAC;QAEF,MAAM,eAAe,GAAG,uBAAA,IAAI,uEAAkB,MAAtB,IAAI,EAAmB,KAAK,CAAC,CAAC,OAAO,CAC3D,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CACvB,CAAC;QAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,cAAc,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,KAAkB;QACrC,OAAO,uBAAA,IAAI,mFAA8B,MAAlC,IAAI,EAA+B,KAAK,CAAC,CAAC,GAAG,CAClD,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAC3C,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,KAAkB;QACjC,+GAA+G;QAC/G,OAAO,uBAAA,IAAI,mCAAW;aACnB,IAAI,CAAC,2CAA2C,EAAE,KAAK,CAAC;aACxD,IAAI,CAAC,CAAC,OAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;CACF;AApSD,4CAoSC;;AAlQC;;;;;;;;;;GAUG;AACH,KAAK,kDACH,MAAc,EACd,KAAkB,EAClB,OAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,yCAAiB,MAArB,IAAI,EAAkB,KAAK,EAAE,OAAO,EAAE,EAAE,CAC3D,OAAO,CAAC,qBAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CACtD,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,CAAC;QAChC,OAAO,OAAO,CAAC,CAAC,CAAC,IAAA,0BAAkB,EAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,sBAAS,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,6CACH,kBAAmC,EACnC,KAAkB,EAClB,OAAuB;IAEvB,MAAM,QAAQ,GAAG,uBAAA,IAAI,mCAAW;SAC7B,IAAI,CAAC,2CAA2C,EAAE,KAAK,CAAC;SACxD,MAAM,CACL,CACE,OAAwB,EAGxB,EAAE,CACF,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QACvC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAC3C,CAAC;IAEJ,uDAAuD;IACvD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IAEtD,kEAAkE;IAClE,MAAM,OAAO,GAAG,MAAM,uBAAA,IAAI,4EAAuB,MAA3B,IAAI,EACxB,gBAAgB,EAChB,KAAK,EACL,OAAO,CACR,CAAC;IAEF,MAAM,wBAAwB,GAAG,kBAAkB,CAAC,GAAG,CACrD,CAAC,gBAAgB,EAAE,EAAE,CAAC,IAAA,0BAAkB,EAAC,gBAAgB,CAAC,CAAC,OAAO,CACnE,CAAC;IAEF,gFAAgF;IAChF,uDAAuD;IACvD,wFAAwF;IACxF,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CACnC,CAAC,OAAO,EAAE,EAAE,CACV,wBAAwB,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;QAClD,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CACxE,CAAC;IAEF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,sBAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EAAE,yCAAyC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,OAAO,eAAe,CAAC,EAAE,CAAC;AAC5B,CAAC,mFAWiB,KAAkB;IAClC,MAAM,QAAQ,GAAG,uBAAA,IAAI,mCAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC/D,MAAM,aAAa,GAAG,IAAA,wBAAgB,EAAC,QAAQ,CAAC,CAAC;IAEjD,OAAO,aAAa,CAAC,MAAM,CAAiB,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE;QAChE,MAAM,WAAW,GAAG,uBAAA,IAAI,mCAAW,CAAC,IAAI,CACtC,qCAAqC,EACrC,IAAI,CAAC,EAAE,CACR,CAAC;QAEF,IAAI,WAAW,IAAI,IAAA,mBAAW,EAAC,WAAW,EAAE,kCAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrE,MAAM,UAAU,GAAG,WAAW,CAAC,kCAAc,CAAC,QAAQ,CAAC,CAAC;YACxD,MAAM,MAAM,GAAG,IAAA,2CAAuB,EAAC,UAAU,CAAC,CAAC;YACnD,IAAI,MAAM,IAAI,IAAA,mBAAW,EAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;gBACzC,WAAW,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO;iBAC/B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC,2GAmF6B,KAAkB;IAC9C,OAAO,uBAAA,IAAI,mCAAW;SACnB,IAAI,CAAC,2CAA2C,EAAE,KAAK,CAAC;SACxD,MAAM,CAAC,CAAC,OAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { GetPermissions } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport {\n getProtocolCaveatScopes,\n SnapEndowments,\n} from '@metamask/snaps-rpc-methods';\nimport type { Json, JsonRpcRequest, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type {\n CaipAccountId,\n CaipChainId,\n JsonRpcParams,\n} from '@metamask/utils';\nimport {\n assert,\n hasProperty,\n KnownCaipNamespace,\n parseCaipAccountId,\n} from '@metamask/utils';\n\nimport { getRunnableSnaps } from '../snaps';\nimport type { GetAllSnaps, HandleSnapRequest } from '../snaps';\n\nexport type MultichainRouterHandleRequestAction = {\n type: `${typeof name}:handleRequest`;\n handler: MultichainRouter['handleRequest'];\n};\n\nexport type MultichainRouterGetSupportedMethodsAction = {\n type: `${typeof name}:getSupportedMethods`;\n handler: MultichainRouter['getSupportedMethods'];\n};\n\nexport type MultichainRouterGetSupportedAccountsAction = {\n type: `${typeof name}:getSupportedAccounts`;\n handler: MultichainRouter['getSupportedAccounts'];\n};\n\nexport type MultichainRouterIsSupportedScopeAction = {\n type: `${typeof name}:isSupportedScope`;\n handler: MultichainRouter['isSupportedScope'];\n};\n\n// Since the AccountsController depends on snaps-controllers we manually type this\ntype InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n\ntype SnapKeyring = {\n submitRequest: (request: {\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: CaipChainId;\n }) => Promise<Json>;\n resolveAccountAddress: (\n snapId: SnapId,\n scope: CaipChainId,\n request: Json,\n ) => Promise<{ address: CaipAccountId } | null>;\n};\n\n// Expecting a bound function that calls KeyringController.withKeyring selecting the Snap keyring\ntype WithSnapKeyringFunction = <ReturnType>(\n operation: (keyring: SnapKeyring) => Promise<ReturnType>,\n) => Promise<ReturnType>;\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `AccountsController:listMultichainAccounts`;\n handler: (chainId?: CaipChainId) => InternalAccount[];\n};\n\nexport type MultichainRouterActions =\n | MultichainRouterHandleRequestAction\n | MultichainRouterGetSupportedMethodsAction\n | MultichainRouterGetSupportedAccountsAction\n | MultichainRouterIsSupportedScopeAction;\n\nexport type MultichainRouterAllowedActions =\n | GetAllSnaps\n | HandleSnapRequest\n | GetPermissions\n | AccountsControllerListMultichainAccountsAction;\n\nexport type MultichainRouterEvents = never;\n\nexport type MultichainRouterMessenger = RestrictedMessenger<\n typeof name,\n MultichainRouterActions | MultichainRouterAllowedActions,\n never,\n MultichainRouterAllowedActions['type'],\n MultichainRouterEvents['type']\n>;\n\nexport type MultichainRouterArgs = {\n messenger: MultichainRouterMessenger;\n withSnapKeyring: WithSnapKeyringFunction;\n};\n\ntype ProtocolSnap = {\n snapId: SnapId;\n methods: string[];\n};\n\nconst name = 'MultichainRouter';\n\nexport class MultichainRouter {\n name: typeof name = name;\n\n state = null;\n\n #messenger: MultichainRouterMessenger;\n\n #withSnapKeyring: WithSnapKeyringFunction;\n\n constructor({ messenger, withSnapKeyring }: MultichainRouterArgs) {\n this.#messenger = messenger;\n this.#withSnapKeyring = withSnapKeyring;\n\n this.#messenger.registerActionHandler(\n `${name}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedMethods`,\n (...args) => this.getSupportedMethods(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedAccounts`,\n (...args) => this.getSupportedAccounts(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:isSupportedScope`,\n (...args) => this.isSupportedScope(...args),\n );\n }\n\n /**\n * Attempts to resolve the account address to use for a given request by inspecting the request itself.\n *\n * The request is sent to to an account Snap via the SnapKeyring that will attempt this resolution.\n *\n * @param snapId - The ID of the Snap to send the request to.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns The resolved address if found, otherwise null.\n * @throws If the invocation of the SnapKeyring fails.\n */\n async #resolveRequestAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n try {\n const result = await this.#withSnapKeyring(async (keyring) =>\n keyring.resolveAccountAddress(snapId, scope, request),\n );\n const address = result?.address;\n return address ? parseCaipAccountId(address).address : null;\n } catch {\n throw rpcErrors.internal();\n }\n }\n\n /**\n * Get the account ID of the account that should service the RPC request via an account Snap.\n *\n * This function checks whether any accounts exist that can service a given request by\n * using a combination of the resolveAccountAddress functionality and the connected accounts.\n *\n * If an account is expected to service this request but none is found, the function will throw.\n *\n * @param connectedAddresses - The CAIP-10 addresses connected to the requesting origin.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns An account ID if found, otherwise null.\n * @throws If no account is found, but the accounts exist that could service the request.\n */\n async #getSnapAccountId(\n connectedAddresses: CaipAccountId[],\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter(\n (\n account: InternalAccount,\n ): account is InternalAccount & {\n metadata: Required<InternalAccount['metadata']>;\n } =>\n Boolean(account.metadata.snap?.enabled) &&\n account.methods.includes(request.method),\n );\n\n // If no accounts can service the request, return null.\n if (accounts.length === 0) {\n return null;\n }\n\n const resolutionSnapId = accounts[0].metadata.snap.id;\n\n // Attempt to resolve the address that should be used for signing.\n const address = await this.#resolveRequestAddress(\n resolutionSnapId,\n scope,\n request,\n );\n\n const parsedConnectedAddresses = connectedAddresses.map(\n (connectedAddress) => parseCaipAccountId(connectedAddress).address,\n );\n\n // If we have a resolved address, try to find the selected account based on that\n // otherwise, default to one of the connected accounts.\n // TODO: Eventually let the user choose if we have more than one option for the account.\n const selectedAccount = accounts.find(\n (account) =>\n parsedConnectedAddresses.includes(account.address) &&\n (!address || account.address.toLowerCase() === address.toLowerCase()),\n );\n\n if (!selectedAccount) {\n throw rpcErrors.invalidParams({\n message: 'No available account found for request.',\n });\n }\n\n return selectedAccount.id;\n }\n\n /**\n * Get all protocol Snaps that can service a given CAIP-2 scope.\n *\n * Protocol Snaps are deemed fit to service a scope if they are runnable\n * and have the proper permissions set for the scope.\n *\n * @param scope - A CAIP-2 scope.\n * @returns A list of all the protocol Snaps available and their RPC methods.\n */\n #getProtocolSnaps(scope: CaipChainId) {\n const allSnaps = this.#messenger.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(allSnaps);\n\n return filteredSnaps.reduce<ProtocolSnap[]>((accumulator, snap) => {\n const permissions = this.#messenger.call(\n 'PermissionController:getPermissions',\n snap.id,\n );\n\n if (permissions && hasProperty(permissions, SnapEndowments.Protocol)) {\n const permission = permissions[SnapEndowments.Protocol];\n const scopes = getProtocolCaveatScopes(permission);\n if (scopes && hasProperty(scopes, scope)) {\n accumulator.push({\n snapId: snap.id,\n methods: scopes[scope].methods,\n });\n }\n }\n\n return accumulator;\n }, []);\n }\n\n /**\n * Handle an incoming JSON-RPC request tied to a specific scope by routing\n * to either a procotol Snap or an account Snap.\n *\n * @param options - An options bag.\n * @param options.connectedAddresses - Addresses currently connected to the origin.\n * @param options.origin - The origin of the RPC request.\n * @param options.request - The JSON-RPC request.\n * @param options.scope - The CAIP-2 scope for the request.\n * @returns The response from the chosen Snap.\n * @throws If no handler was found.\n */\n async handleRequest({\n connectedAddresses,\n origin,\n scope,\n request,\n }: {\n connectedAddresses: CaipAccountId[];\n origin: string;\n scope: CaipChainId;\n request: JsonRpcRequest;\n }): Promise<Json> {\n // Explicitly block EVM scopes, just in case.\n assert(\n !scope.startsWith(KnownCaipNamespace.Eip155) &&\n !scope.startsWith('wallet:eip155'),\n );\n\n const { method, params } = request;\n\n // If the RPC request can be serviced by an account Snap, route it there.\n const accountId = await this.#getSnapAccountId(\n connectedAddresses,\n scope,\n request,\n );\n\n if (accountId) {\n return this.#withSnapKeyring(async (keyring) =>\n keyring.submitRequest({\n account: accountId,\n scope,\n method,\n params: params as JsonRpcParams,\n }),\n );\n }\n\n // If the RPC request cannot be serviced by an account Snap,\n // but has a protocol Snap available, route it there.\n const protocolSnaps = this.#getProtocolSnaps(scope);\n const protocolSnap = protocolSnaps.find((snap) =>\n snap.methods.includes(method),\n );\n\n if (protocolSnap) {\n return this.#messenger.call('SnapController:handleRequest', {\n snapId: protocolSnap.snapId,\n origin,\n request: {\n method: '',\n params: {\n request,\n scope,\n },\n },\n handler: HandlerType.OnProtocolRequest,\n }) as Promise<Json>;\n }\n\n // If no compatible account or protocol Snaps were found, throw.\n throw rpcErrors.methodNotFound();\n }\n\n /**\n * Get a list of metadata for supported accounts for a given scope from the client.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of metadata for the supported accounts.\n */\n #getSupportedAccountsMetadata(scope: CaipChainId): InternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n\n /**\n * Get a list of supported methods for a given scope.\n * This combines both protocol and account Snaps supported methods.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of supported methods.\n */\n getSupportedMethods(scope: CaipChainId): string[] {\n const accountMethods = this.#getSupportedAccountsMetadata(scope).flatMap(\n (account) => account.methods,\n );\n\n const protocolMethods = this.#getProtocolSnaps(scope).flatMap(\n (snap) => snap.methods,\n );\n\n return Array.from(new Set([...accountMethods, ...protocolMethods]));\n }\n\n /**\n * Get a list of supported accounts for a given scope.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of CAIP-10 addresses.\n */\n getSupportedAccounts(scope: CaipChainId): string[] {\n return this.#getSupportedAccountsMetadata(scope).map(\n (account) => `${scope}:${account.address}`,\n );\n }\n\n /**\n * Determine whether a given CAIP-2 scope is supported by the router.\n *\n * @param scope - The CAIP-2 scope.\n * @returns True if the router can service the scope, otherwise false.\n */\n isSupportedScope(scope: CaipChainId): boolean {\n // We currently assume here that if one Snap exists that service the scope, we can service the scope generally.\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .some((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainRouter.cjs","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { GetPermissions } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport {\n getProtocolCaveatScopes,\n SnapEndowments,\n} from '@metamask/snaps-rpc-methods';\nimport type { Json, JsonRpcRequest, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type {\n CaipAccountId,\n CaipChainId,\n JsonRpcParams,\n} from '@metamask/utils';\nimport {\n assert,\n hasProperty,\n KnownCaipNamespace,\n parseCaipAccountId,\n} from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport { getRunnableSnaps } from '../snaps';\nimport type { GetAllSnaps, HandleSnapRequest } from '../snaps';\n\nexport type MultichainRouterHandleRequestAction = {\n type: `${typeof name}:handleRequest`;\n handler: MultichainRouter['handleRequest'];\n};\n\nexport type MultichainRouterGetSupportedMethodsAction = {\n type: `${typeof name}:getSupportedMethods`;\n handler: MultichainRouter['getSupportedMethods'];\n};\n\nexport type MultichainRouterGetSupportedAccountsAction = {\n type: `${typeof name}:getSupportedAccounts`;\n handler: MultichainRouter['getSupportedAccounts'];\n};\n\nexport type MultichainRouterIsSupportedScopeAction = {\n type: `${typeof name}:isSupportedScope`;\n handler: MultichainRouter['isSupportedScope'];\n};\n\n// Since the AccountsController depends on snaps-controllers we manually type this\ntype InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n\ntype SnapKeyring = {\n submitRequest: (request: {\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: CaipChainId;\n }) => Promise<Json>;\n resolveAccountAddress: (\n snapId: SnapId,\n scope: CaipChainId,\n request: Json,\n ) => Promise<{ address: CaipAccountId } | null>;\n};\n\n// Expecting a bound function that calls KeyringController.withKeyring selecting the Snap keyring\ntype WithSnapKeyringFunction = <ReturnType>(\n operation: (keyring: SnapKeyring) => Promise<ReturnType>,\n) => Promise<ReturnType>;\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `AccountsController:listMultichainAccounts`;\n handler: (chainId?: CaipChainId) => InternalAccount[];\n};\n\nexport type MultichainRouterActions =\n | MultichainRouterHandleRequestAction\n | MultichainRouterGetSupportedMethodsAction\n | MultichainRouterGetSupportedAccountsAction\n | MultichainRouterIsSupportedScopeAction;\n\nexport type MultichainRouterAllowedActions =\n | GetAllSnaps\n | HandleSnapRequest\n | GetPermissions\n | AccountsControllerListMultichainAccountsAction;\n\nexport type MultichainRouterEvents = never;\n\nexport type MultichainRouterMessenger = RestrictedMessenger<\n typeof name,\n MultichainRouterActions | MultichainRouterAllowedActions,\n never,\n MultichainRouterAllowedActions['type'],\n MultichainRouterEvents['type']\n>;\n\nexport type MultichainRouterArgs = {\n messenger: MultichainRouterMessenger;\n withSnapKeyring: WithSnapKeyringFunction;\n};\n\ntype ProtocolSnap = {\n snapId: SnapId;\n methods: string[];\n};\n\nconst name = 'MultichainRouter';\n\nexport class MultichainRouter {\n name: typeof name = name;\n\n state = null;\n\n readonly #messenger: MultichainRouterMessenger;\n\n readonly #withSnapKeyring: WithSnapKeyringFunction;\n\n constructor({ messenger, withSnapKeyring }: MultichainRouterArgs) {\n this.#messenger = messenger;\n this.#withSnapKeyring = withSnapKeyring;\n\n this.#messenger.registerActionHandler(\n `${name}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedMethods`,\n (...args) => this.getSupportedMethods(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedAccounts`,\n (...args) => this.getSupportedAccounts(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:isSupportedScope`,\n (...args) => this.isSupportedScope(...args),\n );\n }\n\n /**\n * Attempts to resolve the account address to use for a given request by inspecting the request itself.\n *\n * The request is sent to to an account Snap via the SnapKeyring that will attempt this resolution.\n *\n * @param snapId - The ID of the Snap to send the request to.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns The resolved address if found, otherwise null.\n * @throws If the invocation of the SnapKeyring fails.\n */\n async #resolveRequestAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n try {\n const result = await this.#withSnapKeyring(async (keyring) =>\n keyring.resolveAccountAddress(snapId, scope, request),\n );\n const address = result?.address;\n return address ? parseCaipAccountId(address).address : null;\n } catch {\n throw rpcErrors.internal();\n }\n }\n\n /**\n * Get the account ID of the account that should service the RPC request via an account Snap.\n *\n * This function checks whether any accounts exist that can service a given request by\n * using a combination of the resolveAccountAddress functionality and the connected accounts.\n *\n * If an account is expected to service this request but none is found, the function will throw.\n *\n * @param connectedAddresses - The CAIP-10 addresses connected to the requesting origin.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns An account ID if found, otherwise null.\n * @throws If no account is found, but the accounts exist that could service the request.\n */\n async #getSnapAccountId(\n connectedAddresses: CaipAccountId[],\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter(\n (\n account: InternalAccount,\n ): account is InternalAccount & {\n metadata: Required<InternalAccount['metadata']>;\n } =>\n Boolean(account.metadata.snap?.enabled) &&\n account.methods.includes(request.method),\n );\n\n // If no accounts can service the request, return null.\n if (accounts.length === 0) {\n return null;\n }\n\n const resolutionSnapId = accounts[0].metadata.snap.id;\n\n // Attempt to resolve the address that should be used for signing.\n const address = await this.#resolveRequestAddress(\n resolutionSnapId,\n scope,\n request,\n );\n\n const parsedConnectedAddresses = connectedAddresses.map(\n (connectedAddress) => parseCaipAccountId(connectedAddress).address,\n );\n\n // If we have a resolved address, try to find the selected account based on that\n // otherwise, default to one of the connected accounts.\n // TODO: Eventually let the user choose if we have more than one option for the account.\n const selectedAccount = accounts.find(\n (account) =>\n parsedConnectedAddresses.includes(account.address) &&\n (!address || account.address.toLowerCase() === address.toLowerCase()),\n );\n\n if (!selectedAccount) {\n throw rpcErrors.invalidParams({\n message: 'No available account found for request.',\n });\n }\n\n return selectedAccount.id;\n }\n\n /**\n * Get all protocol Snaps that can service a given CAIP-2 scope.\n *\n * Protocol Snaps are deemed fit to service a scope if they are runnable\n * and have the proper permissions set for the scope.\n *\n * @param scope - A CAIP-2 scope.\n * @returns A list of all the protocol Snaps available and their RPC methods.\n */\n #getProtocolSnaps(scope: CaipChainId) {\n const allSnaps = this.#messenger.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(allSnaps);\n\n return filteredSnaps.reduce<ProtocolSnap[]>((accumulator, snap) => {\n const permissions = this.#messenger.call(\n 'PermissionController:getPermissions',\n snap.id,\n );\n\n if (permissions && hasProperty(permissions, SnapEndowments.Protocol)) {\n const permission = permissions[SnapEndowments.Protocol];\n const scopes = getProtocolCaveatScopes(permission);\n if (scopes && hasProperty(scopes, scope)) {\n accumulator.push({\n snapId: snap.id,\n methods: scopes[scope].methods,\n });\n }\n }\n\n return accumulator;\n }, []);\n }\n\n /**\n * Handle an incoming JSON-RPC request tied to a specific scope by routing\n * to either a procotol Snap or an account Snap.\n *\n * @param options - An options bag.\n * @param options.connectedAddresses - Addresses currently connected to the origin.\n * @param options.origin - The origin of the RPC request.\n * @param options.request - The JSON-RPC request.\n * @param options.scope - The CAIP-2 scope for the request.\n * @returns The response from the chosen Snap.\n * @throws If no handler was found.\n */\n async handleRequest({\n connectedAddresses,\n origin,\n scope,\n request: rawRequest,\n }: {\n connectedAddresses: CaipAccountId[];\n origin: string;\n scope: CaipChainId;\n request: JsonRpcRequest;\n }): Promise<Json> {\n // Explicitly block EVM scopes, just in case.\n assert(\n !scope.startsWith(KnownCaipNamespace.Eip155) &&\n !scope.startsWith('wallet:eip155'),\n );\n\n // Re-create the request to simplify and remove additional properties that may be present in MM middleware.\n const request = {\n jsonrpc: '2.0' as const,\n id: rawRequest.id ?? nanoid(),\n method: rawRequest.method,\n params: rawRequest.params,\n };\n\n const { method, params } = request;\n\n // If the RPC request can be serviced by an account Snap, route it there.\n const accountId = await this.#getSnapAccountId(\n connectedAddresses,\n scope,\n request,\n );\n\n if (accountId) {\n return this.#withSnapKeyring(async (keyring) =>\n keyring.submitRequest({\n account: accountId,\n scope,\n method,\n params: params as JsonRpcParams,\n }),\n );\n }\n\n // If the RPC request cannot be serviced by an account Snap,\n // but has a protocol Snap available, route it there.\n const protocolSnaps = this.#getProtocolSnaps(scope);\n const protocolSnap = protocolSnaps.find((snap) =>\n snap.methods.includes(method),\n );\n\n if (protocolSnap) {\n return this.#messenger.call('SnapController:handleRequest', {\n snapId: protocolSnap.snapId,\n origin,\n request: {\n method: '',\n params: {\n request,\n scope,\n },\n },\n handler: HandlerType.OnProtocolRequest,\n }) as Promise<Json>;\n }\n\n // If no compatible account or protocol Snaps were found, throw.\n throw rpcErrors.methodNotFound();\n }\n\n /**\n * Get a list of metadata for supported accounts for a given scope from the client.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of metadata for the supported accounts.\n */\n #getSupportedAccountsMetadata(scope: CaipChainId): InternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n\n /**\n * Get a list of supported methods for a given scope.\n * This combines both protocol and account Snaps supported methods.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of supported methods.\n */\n getSupportedMethods(scope: CaipChainId): string[] {\n const accountMethods = this.#getSupportedAccountsMetadata(scope).flatMap(\n (account) => account.methods,\n );\n\n const protocolMethods = this.#getProtocolSnaps(scope).flatMap(\n (snap) => snap.methods,\n );\n\n return Array.from(new Set([...accountMethods, ...protocolMethods]));\n }\n\n /**\n * Get a list of supported accounts for a given scope.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of CAIP-10 addresses.\n */\n getSupportedAccounts(scope: CaipChainId): string[] {\n return this.#getSupportedAccountsMetadata(scope).map(\n (account) => `${scope}:${account.address}`,\n );\n }\n\n /**\n * Determine whether a given CAIP-2 scope is supported by the router.\n *\n * @param scope - The CAIP-2 scope.\n * @returns True if the router can service the scope, otherwise false.\n */\n isSupportedScope(scope: CaipChainId): boolean {\n // We currently assume here that if one Snap exists that service the scope, we can service the scope generally.\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .some((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n}\n"]}
|
|
@@ -76,7 +76,7 @@ export declare class MultichainRouter {
|
|
|
76
76
|
* @returns The response from the chosen Snap.
|
|
77
77
|
* @throws If no handler was found.
|
|
78
78
|
*/
|
|
79
|
-
handleRequest({ connectedAddresses, origin, scope, request, }: {
|
|
79
|
+
handleRequest({ connectedAddresses, origin, scope, request: rawRequest, }: {
|
|
80
80
|
connectedAddresses: CaipAccountId[];
|
|
81
81
|
origin: string;
|
|
82
82
|
scope: CaipChainId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainRouter.d.cts","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,wCAAwC;AAMtE,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,4BAA4B;AAExE,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EAEZ,wBAAwB;
|
|
1
|
+
{"version":3,"file":"MultichainRouter.d.cts","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -76,7 +76,7 @@ export declare class MultichainRouter {
|
|
|
76
76
|
* @returns The response from the chosen Snap.
|
|
77
77
|
* @throws If no handler was found.
|
|
78
78
|
*/
|
|
79
|
-
handleRequest({ connectedAddresses, origin, scope, request, }: {
|
|
79
|
+
handleRequest({ connectedAddresses, origin, scope, request: rawRequest, }: {
|
|
80
80
|
connectedAddresses: CaipAccountId[];
|
|
81
81
|
origin: string;
|
|
82
82
|
scope: CaipChainId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainRouter.d.mts","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAkC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,wCAAwC;AAMtE,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,4BAA4B;AAExE,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EAEZ,wBAAwB;
|
|
1
|
+
{"version":3,"file":"MultichainRouter.d.mts","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ import { rpcErrors } from "@metamask/rpc-errors";
|
|
|
14
14
|
import { getProtocolCaveatScopes, SnapEndowments } from "@metamask/snaps-rpc-methods";
|
|
15
15
|
import { HandlerType } from "@metamask/snaps-utils";
|
|
16
16
|
import { assert, hasProperty, KnownCaipNamespace, parseCaipAccountId } from "@metamask/utils";
|
|
17
|
+
import { nanoid } from "nanoid";
|
|
17
18
|
import { getRunnableSnaps } from "../snaps/index.mjs";
|
|
18
19
|
const name = 'MultichainRouter';
|
|
19
20
|
export class MultichainRouter {
|
|
@@ -42,10 +43,17 @@ export class MultichainRouter {
|
|
|
42
43
|
* @returns The response from the chosen Snap.
|
|
43
44
|
* @throws If no handler was found.
|
|
44
45
|
*/
|
|
45
|
-
async handleRequest({ connectedAddresses, origin, scope, request, }) {
|
|
46
|
+
async handleRequest({ connectedAddresses, origin, scope, request: rawRequest, }) {
|
|
46
47
|
// Explicitly block EVM scopes, just in case.
|
|
47
48
|
assert(!scope.startsWith(KnownCaipNamespace.Eip155) &&
|
|
48
49
|
!scope.startsWith('wallet:eip155'));
|
|
50
|
+
// Re-create the request to simplify and remove additional properties that may be present in MM middleware.
|
|
51
|
+
const request = {
|
|
52
|
+
jsonrpc: '2.0',
|
|
53
|
+
id: rawRequest.id ?? nanoid(),
|
|
54
|
+
method: rawRequest.method,
|
|
55
|
+
params: rawRequest.params,
|
|
56
|
+
};
|
|
49
57
|
const { method, params } = request;
|
|
50
58
|
// If the RPC request can be serviced by an account Snap, route it there.
|
|
51
59
|
const accountId = await __classPrivateFieldGet(this, _MultichainRouter_instances, "m", _MultichainRouter_getSnapAccountId).call(this, connectedAddresses, scope, request);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainRouter.mjs","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { GetPermissions } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport {\n getProtocolCaveatScopes,\n SnapEndowments,\n} from '@metamask/snaps-rpc-methods';\nimport type { Json, JsonRpcRequest, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type {\n CaipAccountId,\n CaipChainId,\n JsonRpcParams,\n} from '@metamask/utils';\nimport {\n assert,\n hasProperty,\n KnownCaipNamespace,\n parseCaipAccountId,\n} from '@metamask/utils';\n\nimport { getRunnableSnaps } from '../snaps';\nimport type { GetAllSnaps, HandleSnapRequest } from '../snaps';\n\nexport type MultichainRouterHandleRequestAction = {\n type: `${typeof name}:handleRequest`;\n handler: MultichainRouter['handleRequest'];\n};\n\nexport type MultichainRouterGetSupportedMethodsAction = {\n type: `${typeof name}:getSupportedMethods`;\n handler: MultichainRouter['getSupportedMethods'];\n};\n\nexport type MultichainRouterGetSupportedAccountsAction = {\n type: `${typeof name}:getSupportedAccounts`;\n handler: MultichainRouter['getSupportedAccounts'];\n};\n\nexport type MultichainRouterIsSupportedScopeAction = {\n type: `${typeof name}:isSupportedScope`;\n handler: MultichainRouter['isSupportedScope'];\n};\n\n// Since the AccountsController depends on snaps-controllers we manually type this\ntype InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n\ntype SnapKeyring = {\n submitRequest: (request: {\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: CaipChainId;\n }) => Promise<Json>;\n resolveAccountAddress: (\n snapId: SnapId,\n scope: CaipChainId,\n request: Json,\n ) => Promise<{ address: CaipAccountId } | null>;\n};\n\n// Expecting a bound function that calls KeyringController.withKeyring selecting the Snap keyring\ntype WithSnapKeyringFunction = <ReturnType>(\n operation: (keyring: SnapKeyring) => Promise<ReturnType>,\n) => Promise<ReturnType>;\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `AccountsController:listMultichainAccounts`;\n handler: (chainId?: CaipChainId) => InternalAccount[];\n};\n\nexport type MultichainRouterActions =\n | MultichainRouterHandleRequestAction\n | MultichainRouterGetSupportedMethodsAction\n | MultichainRouterGetSupportedAccountsAction\n | MultichainRouterIsSupportedScopeAction;\n\nexport type MultichainRouterAllowedActions =\n | GetAllSnaps\n | HandleSnapRequest\n | GetPermissions\n | AccountsControllerListMultichainAccountsAction;\n\nexport type MultichainRouterEvents = never;\n\nexport type MultichainRouterMessenger = RestrictedMessenger<\n typeof name,\n MultichainRouterActions | MultichainRouterAllowedActions,\n never,\n MultichainRouterAllowedActions['type'],\n MultichainRouterEvents['type']\n>;\n\nexport type MultichainRouterArgs = {\n messenger: MultichainRouterMessenger;\n withSnapKeyring: WithSnapKeyringFunction;\n};\n\ntype ProtocolSnap = {\n snapId: SnapId;\n methods: string[];\n};\n\nconst name = 'MultichainRouter';\n\nexport class MultichainRouter {\n name: typeof name = name;\n\n state = null;\n\n #messenger: MultichainRouterMessenger;\n\n #withSnapKeyring: WithSnapKeyringFunction;\n\n constructor({ messenger, withSnapKeyring }: MultichainRouterArgs) {\n this.#messenger = messenger;\n this.#withSnapKeyring = withSnapKeyring;\n\n this.#messenger.registerActionHandler(\n `${name}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedMethods`,\n (...args) => this.getSupportedMethods(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedAccounts`,\n (...args) => this.getSupportedAccounts(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:isSupportedScope`,\n (...args) => this.isSupportedScope(...args),\n );\n }\n\n /**\n * Attempts to resolve the account address to use for a given request by inspecting the request itself.\n *\n * The request is sent to to an account Snap via the SnapKeyring that will attempt this resolution.\n *\n * @param snapId - The ID of the Snap to send the request to.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns The resolved address if found, otherwise null.\n * @throws If the invocation of the SnapKeyring fails.\n */\n async #resolveRequestAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n try {\n const result = await this.#withSnapKeyring(async (keyring) =>\n keyring.resolveAccountAddress(snapId, scope, request),\n );\n const address = result?.address;\n return address ? parseCaipAccountId(address).address : null;\n } catch {\n throw rpcErrors.internal();\n }\n }\n\n /**\n * Get the account ID of the account that should service the RPC request via an account Snap.\n *\n * This function checks whether any accounts exist that can service a given request by\n * using a combination of the resolveAccountAddress functionality and the connected accounts.\n *\n * If an account is expected to service this request but none is found, the function will throw.\n *\n * @param connectedAddresses - The CAIP-10 addresses connected to the requesting origin.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns An account ID if found, otherwise null.\n * @throws If no account is found, but the accounts exist that could service the request.\n */\n async #getSnapAccountId(\n connectedAddresses: CaipAccountId[],\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter(\n (\n account: InternalAccount,\n ): account is InternalAccount & {\n metadata: Required<InternalAccount['metadata']>;\n } =>\n Boolean(account.metadata.snap?.enabled) &&\n account.methods.includes(request.method),\n );\n\n // If no accounts can service the request, return null.\n if (accounts.length === 0) {\n return null;\n }\n\n const resolutionSnapId = accounts[0].metadata.snap.id;\n\n // Attempt to resolve the address that should be used for signing.\n const address = await this.#resolveRequestAddress(\n resolutionSnapId,\n scope,\n request,\n );\n\n const parsedConnectedAddresses = connectedAddresses.map(\n (connectedAddress) => parseCaipAccountId(connectedAddress).address,\n );\n\n // If we have a resolved address, try to find the selected account based on that\n // otherwise, default to one of the connected accounts.\n // TODO: Eventually let the user choose if we have more than one option for the account.\n const selectedAccount = accounts.find(\n (account) =>\n parsedConnectedAddresses.includes(account.address) &&\n (!address || account.address.toLowerCase() === address.toLowerCase()),\n );\n\n if (!selectedAccount) {\n throw rpcErrors.invalidParams({\n message: 'No available account found for request.',\n });\n }\n\n return selectedAccount.id;\n }\n\n /**\n * Get all protocol Snaps that can service a given CAIP-2 scope.\n *\n * Protocol Snaps are deemed fit to service a scope if they are runnable\n * and have the proper permissions set for the scope.\n *\n * @param scope - A CAIP-2 scope.\n * @returns A list of all the protocol Snaps available and their RPC methods.\n */\n #getProtocolSnaps(scope: CaipChainId) {\n const allSnaps = this.#messenger.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(allSnaps);\n\n return filteredSnaps.reduce<ProtocolSnap[]>((accumulator, snap) => {\n const permissions = this.#messenger.call(\n 'PermissionController:getPermissions',\n snap.id,\n );\n\n if (permissions && hasProperty(permissions, SnapEndowments.Protocol)) {\n const permission = permissions[SnapEndowments.Protocol];\n const scopes = getProtocolCaveatScopes(permission);\n if (scopes && hasProperty(scopes, scope)) {\n accumulator.push({\n snapId: snap.id,\n methods: scopes[scope].methods,\n });\n }\n }\n\n return accumulator;\n }, []);\n }\n\n /**\n * Handle an incoming JSON-RPC request tied to a specific scope by routing\n * to either a procotol Snap or an account Snap.\n *\n * @param options - An options bag.\n * @param options.connectedAddresses - Addresses currently connected to the origin.\n * @param options.origin - The origin of the RPC request.\n * @param options.request - The JSON-RPC request.\n * @param options.scope - The CAIP-2 scope for the request.\n * @returns The response from the chosen Snap.\n * @throws If no handler was found.\n */\n async handleRequest({\n connectedAddresses,\n origin,\n scope,\n request,\n }: {\n connectedAddresses: CaipAccountId[];\n origin: string;\n scope: CaipChainId;\n request: JsonRpcRequest;\n }): Promise<Json> {\n // Explicitly block EVM scopes, just in case.\n assert(\n !scope.startsWith(KnownCaipNamespace.Eip155) &&\n !scope.startsWith('wallet:eip155'),\n );\n\n const { method, params } = request;\n\n // If the RPC request can be serviced by an account Snap, route it there.\n const accountId = await this.#getSnapAccountId(\n connectedAddresses,\n scope,\n request,\n );\n\n if (accountId) {\n return this.#withSnapKeyring(async (keyring) =>\n keyring.submitRequest({\n account: accountId,\n scope,\n method,\n params: params as JsonRpcParams,\n }),\n );\n }\n\n // If the RPC request cannot be serviced by an account Snap,\n // but has a protocol Snap available, route it there.\n const protocolSnaps = this.#getProtocolSnaps(scope);\n const protocolSnap = protocolSnaps.find((snap) =>\n snap.methods.includes(method),\n );\n\n if (protocolSnap) {\n return this.#messenger.call('SnapController:handleRequest', {\n snapId: protocolSnap.snapId,\n origin,\n request: {\n method: '',\n params: {\n request,\n scope,\n },\n },\n handler: HandlerType.OnProtocolRequest,\n }) as Promise<Json>;\n }\n\n // If no compatible account or protocol Snaps were found, throw.\n throw rpcErrors.methodNotFound();\n }\n\n /**\n * Get a list of metadata for supported accounts for a given scope from the client.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of metadata for the supported accounts.\n */\n #getSupportedAccountsMetadata(scope: CaipChainId): InternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n\n /**\n * Get a list of supported methods for a given scope.\n * This combines both protocol and account Snaps supported methods.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of supported methods.\n */\n getSupportedMethods(scope: CaipChainId): string[] {\n const accountMethods = this.#getSupportedAccountsMetadata(scope).flatMap(\n (account) => account.methods,\n );\n\n const protocolMethods = this.#getProtocolSnaps(scope).flatMap(\n (snap) => snap.methods,\n );\n\n return Array.from(new Set([...accountMethods, ...protocolMethods]));\n }\n\n /**\n * Get a list of supported accounts for a given scope.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of CAIP-10 addresses.\n */\n getSupportedAccounts(scope: CaipChainId): string[] {\n return this.#getSupportedAccountsMetadata(scope).map(\n (account) => `${scope}:${account.address}`,\n );\n }\n\n /**\n * Determine whether a given CAIP-2 scope is supported by the router.\n *\n * @param scope - The CAIP-2 scope.\n * @returns True if the router can service the scope, otherwise false.\n */\n isSupportedScope(scope: CaipChainId): boolean {\n // We currently assume here that if one Snap exists that service the scope, we can service the scope generally.\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .some((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainRouter.mjs","sourceRoot":"","sources":["../../src/multichain/MultichainRouter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestrictedMessenger } from '@metamask/base-controller';\nimport type { GetPermissions } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport {\n getProtocolCaveatScopes,\n SnapEndowments,\n} from '@metamask/snaps-rpc-methods';\nimport type { Json, JsonRpcRequest, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type {\n CaipAccountId,\n CaipChainId,\n JsonRpcParams,\n} from '@metamask/utils';\nimport {\n assert,\n hasProperty,\n KnownCaipNamespace,\n parseCaipAccountId,\n} from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport { getRunnableSnaps } from '../snaps';\nimport type { GetAllSnaps, HandleSnapRequest } from '../snaps';\n\nexport type MultichainRouterHandleRequestAction = {\n type: `${typeof name}:handleRequest`;\n handler: MultichainRouter['handleRequest'];\n};\n\nexport type MultichainRouterGetSupportedMethodsAction = {\n type: `${typeof name}:getSupportedMethods`;\n handler: MultichainRouter['getSupportedMethods'];\n};\n\nexport type MultichainRouterGetSupportedAccountsAction = {\n type: `${typeof name}:getSupportedAccounts`;\n handler: MultichainRouter['getSupportedAccounts'];\n};\n\nexport type MultichainRouterIsSupportedScopeAction = {\n type: `${typeof name}:isSupportedScope`;\n handler: MultichainRouter['isSupportedScope'];\n};\n\n// Since the AccountsController depends on snaps-controllers we manually type this\ntype InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n\ntype SnapKeyring = {\n submitRequest: (request: {\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: CaipChainId;\n }) => Promise<Json>;\n resolveAccountAddress: (\n snapId: SnapId,\n scope: CaipChainId,\n request: Json,\n ) => Promise<{ address: CaipAccountId } | null>;\n};\n\n// Expecting a bound function that calls KeyringController.withKeyring selecting the Snap keyring\ntype WithSnapKeyringFunction = <ReturnType>(\n operation: (keyring: SnapKeyring) => Promise<ReturnType>,\n) => Promise<ReturnType>;\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `AccountsController:listMultichainAccounts`;\n handler: (chainId?: CaipChainId) => InternalAccount[];\n};\n\nexport type MultichainRouterActions =\n | MultichainRouterHandleRequestAction\n | MultichainRouterGetSupportedMethodsAction\n | MultichainRouterGetSupportedAccountsAction\n | MultichainRouterIsSupportedScopeAction;\n\nexport type MultichainRouterAllowedActions =\n | GetAllSnaps\n | HandleSnapRequest\n | GetPermissions\n | AccountsControllerListMultichainAccountsAction;\n\nexport type MultichainRouterEvents = never;\n\nexport type MultichainRouterMessenger = RestrictedMessenger<\n typeof name,\n MultichainRouterActions | MultichainRouterAllowedActions,\n never,\n MultichainRouterAllowedActions['type'],\n MultichainRouterEvents['type']\n>;\n\nexport type MultichainRouterArgs = {\n messenger: MultichainRouterMessenger;\n withSnapKeyring: WithSnapKeyringFunction;\n};\n\ntype ProtocolSnap = {\n snapId: SnapId;\n methods: string[];\n};\n\nconst name = 'MultichainRouter';\n\nexport class MultichainRouter {\n name: typeof name = name;\n\n state = null;\n\n readonly #messenger: MultichainRouterMessenger;\n\n readonly #withSnapKeyring: WithSnapKeyringFunction;\n\n constructor({ messenger, withSnapKeyring }: MultichainRouterArgs) {\n this.#messenger = messenger;\n this.#withSnapKeyring = withSnapKeyring;\n\n this.#messenger.registerActionHandler(\n `${name}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedMethods`,\n (...args) => this.getSupportedMethods(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:getSupportedAccounts`,\n (...args) => this.getSupportedAccounts(...args),\n );\n\n this.#messenger.registerActionHandler(\n `${name}:isSupportedScope`,\n (...args) => this.isSupportedScope(...args),\n );\n }\n\n /**\n * Attempts to resolve the account address to use for a given request by inspecting the request itself.\n *\n * The request is sent to to an account Snap via the SnapKeyring that will attempt this resolution.\n *\n * @param snapId - The ID of the Snap to send the request to.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns The resolved address if found, otherwise null.\n * @throws If the invocation of the SnapKeyring fails.\n */\n async #resolveRequestAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n try {\n const result = await this.#withSnapKeyring(async (keyring) =>\n keyring.resolveAccountAddress(snapId, scope, request),\n );\n const address = result?.address;\n return address ? parseCaipAccountId(address).address : null;\n } catch {\n throw rpcErrors.internal();\n }\n }\n\n /**\n * Get the account ID of the account that should service the RPC request via an account Snap.\n *\n * This function checks whether any accounts exist that can service a given request by\n * using a combination of the resolveAccountAddress functionality and the connected accounts.\n *\n * If an account is expected to service this request but none is found, the function will throw.\n *\n * @param connectedAddresses - The CAIP-10 addresses connected to the requesting origin.\n * @param scope - The CAIP-2 scope for the request.\n * @param request - The JSON-RPC request.\n * @returns An account ID if found, otherwise null.\n * @throws If no account is found, but the accounts exist that could service the request.\n */\n async #getSnapAccountId(\n connectedAddresses: CaipAccountId[],\n scope: CaipChainId,\n request: JsonRpcRequest,\n ) {\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter(\n (\n account: InternalAccount,\n ): account is InternalAccount & {\n metadata: Required<InternalAccount['metadata']>;\n } =>\n Boolean(account.metadata.snap?.enabled) &&\n account.methods.includes(request.method),\n );\n\n // If no accounts can service the request, return null.\n if (accounts.length === 0) {\n return null;\n }\n\n const resolutionSnapId = accounts[0].metadata.snap.id;\n\n // Attempt to resolve the address that should be used for signing.\n const address = await this.#resolveRequestAddress(\n resolutionSnapId,\n scope,\n request,\n );\n\n const parsedConnectedAddresses = connectedAddresses.map(\n (connectedAddress) => parseCaipAccountId(connectedAddress).address,\n );\n\n // If we have a resolved address, try to find the selected account based on that\n // otherwise, default to one of the connected accounts.\n // TODO: Eventually let the user choose if we have more than one option for the account.\n const selectedAccount = accounts.find(\n (account) =>\n parsedConnectedAddresses.includes(account.address) &&\n (!address || account.address.toLowerCase() === address.toLowerCase()),\n );\n\n if (!selectedAccount) {\n throw rpcErrors.invalidParams({\n message: 'No available account found for request.',\n });\n }\n\n return selectedAccount.id;\n }\n\n /**\n * Get all protocol Snaps that can service a given CAIP-2 scope.\n *\n * Protocol Snaps are deemed fit to service a scope if they are runnable\n * and have the proper permissions set for the scope.\n *\n * @param scope - A CAIP-2 scope.\n * @returns A list of all the protocol Snaps available and their RPC methods.\n */\n #getProtocolSnaps(scope: CaipChainId) {\n const allSnaps = this.#messenger.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(allSnaps);\n\n return filteredSnaps.reduce<ProtocolSnap[]>((accumulator, snap) => {\n const permissions = this.#messenger.call(\n 'PermissionController:getPermissions',\n snap.id,\n );\n\n if (permissions && hasProperty(permissions, SnapEndowments.Protocol)) {\n const permission = permissions[SnapEndowments.Protocol];\n const scopes = getProtocolCaveatScopes(permission);\n if (scopes && hasProperty(scopes, scope)) {\n accumulator.push({\n snapId: snap.id,\n methods: scopes[scope].methods,\n });\n }\n }\n\n return accumulator;\n }, []);\n }\n\n /**\n * Handle an incoming JSON-RPC request tied to a specific scope by routing\n * to either a procotol Snap or an account Snap.\n *\n * @param options - An options bag.\n * @param options.connectedAddresses - Addresses currently connected to the origin.\n * @param options.origin - The origin of the RPC request.\n * @param options.request - The JSON-RPC request.\n * @param options.scope - The CAIP-2 scope for the request.\n * @returns The response from the chosen Snap.\n * @throws If no handler was found.\n */\n async handleRequest({\n connectedAddresses,\n origin,\n scope,\n request: rawRequest,\n }: {\n connectedAddresses: CaipAccountId[];\n origin: string;\n scope: CaipChainId;\n request: JsonRpcRequest;\n }): Promise<Json> {\n // Explicitly block EVM scopes, just in case.\n assert(\n !scope.startsWith(KnownCaipNamespace.Eip155) &&\n !scope.startsWith('wallet:eip155'),\n );\n\n // Re-create the request to simplify and remove additional properties that may be present in MM middleware.\n const request = {\n jsonrpc: '2.0' as const,\n id: rawRequest.id ?? nanoid(),\n method: rawRequest.method,\n params: rawRequest.params,\n };\n\n const { method, params } = request;\n\n // If the RPC request can be serviced by an account Snap, route it there.\n const accountId = await this.#getSnapAccountId(\n connectedAddresses,\n scope,\n request,\n );\n\n if (accountId) {\n return this.#withSnapKeyring(async (keyring) =>\n keyring.submitRequest({\n account: accountId,\n scope,\n method,\n params: params as JsonRpcParams,\n }),\n );\n }\n\n // If the RPC request cannot be serviced by an account Snap,\n // but has a protocol Snap available, route it there.\n const protocolSnaps = this.#getProtocolSnaps(scope);\n const protocolSnap = protocolSnaps.find((snap) =>\n snap.methods.includes(method),\n );\n\n if (protocolSnap) {\n return this.#messenger.call('SnapController:handleRequest', {\n snapId: protocolSnap.snapId,\n origin,\n request: {\n method: '',\n params: {\n request,\n scope,\n },\n },\n handler: HandlerType.OnProtocolRequest,\n }) as Promise<Json>;\n }\n\n // If no compatible account or protocol Snaps were found, throw.\n throw rpcErrors.methodNotFound();\n }\n\n /**\n * Get a list of metadata for supported accounts for a given scope from the client.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of metadata for the supported accounts.\n */\n #getSupportedAccountsMetadata(scope: CaipChainId): InternalAccount[] {\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .filter((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n\n /**\n * Get a list of supported methods for a given scope.\n * This combines both protocol and account Snaps supported methods.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of supported methods.\n */\n getSupportedMethods(scope: CaipChainId): string[] {\n const accountMethods = this.#getSupportedAccountsMetadata(scope).flatMap(\n (account) => account.methods,\n );\n\n const protocolMethods = this.#getProtocolSnaps(scope).flatMap(\n (snap) => snap.methods,\n );\n\n return Array.from(new Set([...accountMethods, ...protocolMethods]));\n }\n\n /**\n * Get a list of supported accounts for a given scope.\n *\n * @param scope - The CAIP-2 scope.\n * @returns A list of CAIP-10 addresses.\n */\n getSupportedAccounts(scope: CaipChainId): string[] {\n return this.#getSupportedAccountsMetadata(scope).map(\n (account) => `${scope}:${account.address}`,\n );\n }\n\n /**\n * Determine whether a given CAIP-2 scope is supported by the router.\n *\n * @param scope - The CAIP-2 scope.\n * @returns True if the router can service the scope, otherwise false.\n */\n isSupportedScope(scope: CaipChainId): boolean {\n // We currently assume here that if one Snap exists that service the scope, we can service the scope generally.\n return this.#messenger\n .call('AccountsController:listMultichainAccounts', scope)\n .some((account: InternalAccount) => account.metadata.snap?.enabled);\n }\n}\n"]}
|
package/dist/node.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable import/export */
|
|
2
|
+
/* eslint-disable import-x/export */
|
|
3
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
4
|
if (k2 === undefined) k2 = k;
|
|
5
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
package/dist/node.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.cjs","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"node.cjs","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,8CAAkB;AAClB,sDAAgC","sourcesContent":["/* eslint-disable import-x/export */\n\nexport * from '.';\nexport * from './services/node';\n"]}
|
package/dist/node.mjs
CHANGED
package/dist/node.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.mjs","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"node.mjs","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,4BAAkB;AAClB,oCAAgC","sourcesContent":["/* eslint-disable import-x/export */\n\nexport * from '.';\nexport * from './services/node';\n"]}
|
package/dist/react-native.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable import/export */
|
|
2
|
+
/* eslint-disable import-x/export */
|
|
3
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
4
|
if (k2 === undefined) k2 = k;
|
|
5
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native.cjs","sourceRoot":"","sources":["../src/react-native.ts"],"names":[],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"react-native.cjs","sourceRoot":"","sources":["../src/react-native.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,8CAAkB;AAClB,8DAAwC","sourcesContent":["/* eslint-disable import-x/export */\n\nexport * from '.';\nexport * from './services/react-native';\n"]}
|
package/dist/react-native.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native.mjs","sourceRoot":"","sources":["../src/react-native.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"react-native.mjs","sourceRoot":"","sources":["../src/react-native.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,4BAAkB;AAClB,4CAAwC","sourcesContent":["/* eslint-disable import-x/export */\n\nexport * from '.';\nexport * from './services/react-native';\n"]}
|
|
@@ -57,6 +57,9 @@ class AbstractExecutionService {
|
|
|
57
57
|
* Constructor helper for registering the controller's messaging system
|
|
58
58
|
* actions.
|
|
59
59
|
*/
|
|
60
|
+
// TODO: Either fix this lint violation or explain why it's necessary to
|
|
61
|
+
// ignore.
|
|
62
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
60
63
|
registerMessageHandlers() {
|
|
61
64
|
__classPrivateFieldGet(this, _AbstractExecutionService_messenger, "f").registerActionHandler(`${controllerName}:handleRpcRequest`, async (snapId, options) => this.handleRpcRequest(snapId, options));
|
|
62
65
|
__classPrivateFieldGet(this, _AbstractExecutionService_messenger, "f").registerActionHandler(`${controllerName}:executeSnap`, async (data) => this.executeSnap(data));
|
|
@@ -218,6 +221,9 @@ class AbstractExecutionService {
|
|
|
218
221
|
* @param snapId - The id of the Snap whose message handler to get.
|
|
219
222
|
* @returns The RPC request handler for the snap.
|
|
220
223
|
*/
|
|
224
|
+
// TODO: Either fix this lint violation or explain why it's necessary to
|
|
225
|
+
// ignore.
|
|
226
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
221
227
|
getRpcRequestHandler(snapId) {
|
|
222
228
|
return __classPrivateFieldGet(this, _AbstractExecutionService_snapRpcHooks, "f").get(snapId);
|
|
223
229
|
}
|
|
@@ -270,14 +276,13 @@ class AbstractExecutionService {
|
|
|
270
276
|
return result;
|
|
271
277
|
}
|
|
272
278
|
// Cannot be hash private yet because of tests.
|
|
279
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
273
280
|
async command(jobId, message) {
|
|
274
281
|
const job = this.jobs.get(jobId);
|
|
275
282
|
if (!job) {
|
|
276
283
|
throw new Error(`Job with id "${jobId}" not found.`);
|
|
277
284
|
}
|
|
278
285
|
(0, logging_1.log)('Parent: Sending Command', message);
|
|
279
|
-
// eslint is blocking `await` usage even though `handle` overload returns a promise.
|
|
280
|
-
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
281
286
|
const response = await job.rpcEngine.handle(message);
|
|
282
287
|
if ((0, utils_1.isJsonRpcFailure)(response)) {
|
|
283
288
|
throw new rpc_errors_1.JsonRpcError(response.error.code, response.error.message, response.error.data);
|