diff --git a/.yarn/patches/@metamask-snaps-execution-environments-npm-10.3.0-75e3841f68.patch b/.yarn/patches/@metamask-snaps-execution-environments-npm-10.3.0-75e3841f68.patch
new file mode 100644
index 000000000000..c29b61f3a121
--- /dev/null
+++ b/.yarn/patches/@metamask-snaps-execution-environments-npm-10.3.0-75e3841f68.patch
@@ -0,0 +1,340 @@
+diff --git a/dist/common/BaseSnapExecutor.cjs b/dist/common/BaseSnapExecutor.cjs
+index f828a457e0af706c9d6941a88d61e085f750a446..4af456fc49d2ac657d404949edfac1c32f1841c5 100644
+--- a/dist/common/BaseSnapExecutor.cjs
++++ b/dist/common/BaseSnapExecutor.cjs
+@@ -287,7 +287,11 @@ class BaseSnapExecutor {
+ rpcMiddleware: [(0, json_rpc_engine_1.createIdRemapMiddleware)()],
+ });
+ provider.initializeSync();
+- const snap = this.createSnapGlobal(provider);
++ const multichainProvider = new SnapProvider_1.SnapProvider(multiplex.createStream('metamask-multichain-provider'), {
++ rpcMiddleware: [(0, json_rpc_engine_1.createIdRemapMiddleware)()],
++ });
++ multichainProvider.initializeSync();
++ const snap = this.createSnapGlobal(provider, multichainProvider);
+ const ethereum = this.createEIP1193Provider(provider);
+ // We specifically use any type because the Snap can modify the object any way they want
+ const snapModule = { exports: {} };
+@@ -373,18 +377,23 @@ class BaseSnapExecutor {
+ /**
+ * Instantiates a snap API object (i.e. `globalThis.snap`).
+ *
+- * @param provider - A StreamProvider connected to MetaMask.
++ * @param provider - A StreamProvider connected to the EIP-1193 client stream.
++ * @param multichainProvider - A StreamProvider connected to the CAIP-27 client stream.
+ * @returns The snap provider object.
+ */
+ // TODO: Either fix this lint violation or explain why it's necessary to
+ // ignore.
+ // eslint-disable-next-line no-restricted-syntax
+- createSnapGlobal(provider) {
++ createSnapGlobal(provider, multichainProvider) {
+ const originalRequest = provider.request.bind(provider);
++ const originalMultichainRequest = multichainProvider.request.bind(multichainProvider);
+ const request = async (args) => {
+ // As part of the sanitization, we validate that the args are valid JSON.
+ const sanitizedArgs = (0, utils_2.sanitizeRequestArguments)(args);
+ (0, utils_2.assertSnapOutboundRequest)(sanitizedArgs);
++ if ((0, utils_2.isMultichainRequest)(sanitizedArgs)) {
++ return await (0, utils_2.withTeardown)(originalMultichainRequest(sanitizedArgs), this);
++ }
+ return await (0, utils_2.withTeardown)(originalRequest(sanitizedArgs), this);
+ };
+ const snapsProvider = { request };
+diff --git a/dist/common/BaseSnapExecutor.cjs.map b/dist/common/BaseSnapExecutor.cjs.map
+index 76d107a756a9eb132edfef8de56aabae19fe0cce..c4fd3c1a2488ebdf4967cd4406e06a65ad90d6f3 100644
+--- a/dist/common/BaseSnapExecutor.cjs.map
++++ b/dist/common/BaseSnapExecutor.cjs.map
+@@ -1 +1 @@
+-{"version":3,"file":"BaseSnapExecutor.cjs","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment\n/// \nimport { createIdRemapMiddleware } from '@metamask/json-rpc-engine';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { RequestArguments, StreamProvider } from '@metamask/providers';\nimport { errorCodes, rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';\nimport { getErrorData } from '@metamask/snaps-sdk';\nimport type {\n SnapExports,\n HandlerType,\n SnapExportsParameters,\n} from '@metamask/snaps-utils';\nimport {\n SNAP_EXPORT_NAMES,\n logError,\n SNAP_EXPORTS,\n WrappedSnapError,\n unwrapError,\n logInfo,\n} from '@metamask/snaps-utils';\nimport { validate, is } from '@metamask/superstruct';\nimport type {\n JsonRpcNotification,\n JsonRpcId,\n JsonRpcRequest,\n Json,\n} from '@metamask/utils';\nimport {\n assert,\n isJsonRpcRequest,\n hasProperty,\n getSafeJson,\n JsonRpcIdStruct,\n} from '@metamask/utils';\nimport type { Duplex } from 'readable-stream';\nimport { pipeline } from 'readable-stream';\n\nimport type { CommandMethodsMapping } from './commands';\nimport { getCommandMethodImplementations } from './commands';\nimport { createEndowments } from './endowments';\nimport { addEventListener, removeEventListener } from './globalEvents';\nimport { SnapProvider } from './SnapProvider';\nimport { sortParamKeys } from './sortParams';\nimport {\n assertEthereumOutboundRequest,\n assertSnapOutboundRequest,\n sanitizeRequestArguments,\n withTeardown,\n isValidResponse,\n} from './utils';\nimport {\n ExecuteSnapRequestArgumentsStruct,\n PingRequestArgumentsStruct,\n SnapRpcRequestArgumentsStruct,\n TerminateRequestArgumentsStruct,\n} from './validation';\nimport { log } from '../logging';\n\ntype EvaluationData = {\n stop: () => void;\n};\n\ntype SnapData = {\n exports: SnapExports;\n runningEvaluations: Set;\n idleTeardown: () => Promise;\n};\n\nconst fallbackError = {\n code: errorCodes.rpc.internal,\n message: 'Execution Environment Error',\n};\n\nconst unhandledError = rpcErrors\n .internal({\n message: 'Unhandled Snap Error',\n })\n .serialize();\n\nexport type InvokeSnapArgs = Omit;\n\nexport type InvokeSnap = (\n target: string,\n handler: HandlerType,\n args: InvokeSnapArgs | undefined,\n) => Promise;\n\n/**\n * The supported methods in the execution environment. The validator checks the\n * incoming JSON-RPC request, and the `params` property is used for sorting the\n * parameters, if they are an object.\n */\nconst EXECUTION_ENVIRONMENT_METHODS = {\n ping: {\n struct: PingRequestArgumentsStruct,\n params: [],\n },\n executeSnap: {\n struct: ExecuteSnapRequestArgumentsStruct,\n params: ['snapId', 'sourceCode', 'endowments'],\n },\n terminate: {\n struct: TerminateRequestArgumentsStruct,\n params: [],\n },\n snapRpc: {\n struct: SnapRpcRequestArgumentsStruct,\n params: ['target', 'handler', 'origin', 'request'],\n },\n};\n\ntype Methods = typeof EXECUTION_ENVIRONMENT_METHODS;\n\nexport type NotifyFunction = (\n notification: Omit,\n) => Promise;\n\nexport class BaseSnapExecutor {\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly snapData: Map;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly commandStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly rpcStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly methods: CommandMethodsMapping;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapErrorHandler?: (event: ErrorEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapPromiseErrorHandler?: (event: PromiseRejectionEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private lastTeardown = 0;\n\n protected constructor(commandStream: Duplex, rpcStream: Duplex) {\n this.snapData = new Map();\n this.commandStream = commandStream;\n this.commandStream.on('data', (data) => {\n this.onCommandRequest(data).catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n });\n this.rpcStream = rpcStream;\n\n this.methods = getCommandMethodImplementations(\n this.startSnap.bind(this),\n async (target, handlerType, args) => {\n const data = this.snapData.get(target);\n // We're capturing the handler in case someone modifies the data object\n // before the call.\n const handler = data?.exports[handlerType];\n const { required } = SNAP_EXPORTS[handlerType];\n\n assert(\n !required || handler !== undefined,\n `No ${handlerType} handler exported for snap \"${target}\".`,\n rpcErrors.methodNotSupported,\n );\n\n // Certain handlers are not required. If they are not exported, we\n // return null.\n if (!handler) {\n return null;\n }\n\n const result = await this.executeInSnapContext(target, async () =>\n // TODO: fix handler args type cast\n handler(args as any),\n );\n\n // The handler might not return anything, but undefined is not valid JSON.\n if (result === undefined || result === null) {\n return null;\n }\n\n // /!\\ Always return only sanitized JSON to prevent security flaws. /!\\\n try {\n return getSafeJson(result);\n } catch (error) {\n throw rpcErrors.internal(\n `Received non-JSON-serializable value: ${error.message.replace(\n /^Assertion failed: /u,\n '',\n )}`,\n );\n }\n },\n this.onTerminate.bind(this),\n );\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private errorHandler(error: unknown, data: Record) {\n const serializedError = serializeError(error, {\n fallbackError: unhandledError,\n shouldIncludeStack: false,\n shouldPreserveMessage: false,\n });\n\n const errorData = getErrorData(serializedError);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line promise/no-promise-in-callback\n this.#notify({\n method: 'UnhandledError',\n params: {\n error: {\n ...serializedError,\n data: {\n ...errorData,\n ...data,\n },\n },\n },\n }).catch((notifyError) => {\n logError(notifyError);\n });\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async onCommandRequest(message: JsonRpcRequest) {\n if (!isJsonRpcRequest(message)) {\n if (\n hasProperty(message, 'id') &&\n is((message as Pick).id, JsonRpcIdStruct)\n ) {\n // Instead of throwing, we directly respond with an error.\n // We can only do this if the message ID is still valid.\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC requests must be JSON serializable objects.',\n ),\n ),\n id: (message as Pick).id,\n jsonrpc: '2.0',\n });\n } else {\n logInfo(\n 'Command stream received a non-JSON-RPC request, and was unable to respond.',\n );\n }\n return;\n }\n\n const { id, method, params } = message;\n\n if (!hasProperty(EXECUTION_ENVIRONMENT_METHODS, method)) {\n await this.#respond(id, {\n error: rpcErrors\n .methodNotFound({\n data: {\n method,\n },\n })\n .serialize(),\n });\n return;\n }\n\n const methodObject = EXECUTION_ENVIRONMENT_METHODS[method as keyof Methods];\n\n // support params by-name and by-position\n const paramsAsArray = sortParamKeys(methodObject.params, params);\n\n const [error] = validate(paramsAsArray, methodObject.struct);\n if (error) {\n await this.#respond(id, {\n error: rpcErrors\n .invalidParams({\n message: `Invalid parameters for method \"${method}\": ${error.message}.`,\n data: {\n method,\n params: paramsAsArray,\n },\n })\n .serialize(),\n });\n return;\n }\n\n try {\n const result = await (this.methods as any)[method](...paramsAsArray);\n await this.#respond(id, { result });\n } catch (rpcError) {\n await this.#respond(id, {\n error: serializeError(rpcError, {\n fallbackError,\n shouldPreserveMessage: false,\n }),\n });\n }\n }\n\n // Awaitable function that writes back to the command stream\n // To prevent snap execution from blocking writing we wrap in a promise\n // and await it before continuing execution\n async #write(chunk: Json) {\n return new Promise((resolve, reject) => {\n this.commandStream.write(chunk, (error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n async #notify(notification: Omit) {\n if (!isValidResponse(notification)) {\n throw rpcErrors.internal(\n 'JSON-RPC notifications must be JSON serializable objects smaller than 64 MB.',\n );\n }\n\n await this.#write({\n ...notification,\n jsonrpc: '2.0',\n });\n }\n\n async #respond(id: JsonRpcId, response: Record) {\n if (!isValidResponse(response)) {\n // Instead of throwing, we directly respond with an error.\n // This prevents an issue where we wouldn't respond when errors were non-serializable\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC responses must be JSON serializable objects smaller than 64 MB.',\n ),\n ),\n id,\n jsonrpc: '2.0',\n });\n return;\n }\n\n await this.#write({\n ...response,\n id,\n jsonrpc: '2.0',\n });\n }\n\n /**\n * Attempts to evaluate a snap in SES. Generates APIs for the snap. May throw\n * on errors.\n *\n * @param snapId - The id of the snap.\n * @param sourceCode - The source code of the snap, in IIFE format.\n * @param _endowments - An array of the names of the endowments.\n */\n protected async startSnap(\n snapId: string,\n sourceCode: string,\n _endowments: string[],\n ): Promise {\n log(`Starting snap '${snapId}' in worker.`);\n if (this.snapPromiseErrorHandler) {\n removeEventListener('unhandledrejection', this.snapPromiseErrorHandler);\n }\n\n if (this.snapErrorHandler) {\n removeEventListener('error', this.snapErrorHandler);\n }\n\n this.snapErrorHandler = (error: ErrorEvent) => {\n this.errorHandler(error.error, { snapId });\n };\n\n this.snapPromiseErrorHandler = (error: PromiseRejectionEvent) => {\n this.errorHandler(error instanceof Error ? error : error.reason, {\n snapId,\n });\n };\n\n const multiplex = new ObjectMultiplex();\n pipeline(this.rpcStream, multiplex, this.rpcStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Provider stream failure.`, error);\n }\n });\n\n const provider = new SnapProvider(\n multiplex.createStream('metamask-provider'),\n {\n rpcMiddleware: [createIdRemapMiddleware()],\n },\n );\n\n provider.initializeSync();\n\n const snap = this.createSnapGlobal(provider);\n const ethereum = this.createEIP1193Provider(provider);\n // We specifically use any type because the Snap can modify the object any way they want\n const snapModule: any = { exports: {} };\n\n try {\n const { endowments, teardown: endowmentTeardown } = createEndowments({\n snap,\n ethereum,\n snapId,\n endowments: _endowments,\n notify: this.#notify.bind(this),\n });\n\n // !!! Ensure that this is the only place the data is being set.\n // Other methods access the object value and mutate its properties.\n this.snapData.set(snapId, {\n idleTeardown: endowmentTeardown,\n runningEvaluations: new Set(),\n exports: {},\n });\n\n addEventListener('unhandledRejection', this.snapPromiseErrorHandler);\n addEventListener('error', this.snapErrorHandler);\n\n const compartment = new Compartment({\n ...endowments,\n module: snapModule,\n exports: snapModule.exports,\n });\n\n // All of those are JavaScript runtime specific and self referential,\n // but we add them for compatibility sake with external libraries.\n //\n // We can't do that in the injected globals object above\n // because SES creates its own globalThis\n compartment.globalThis.self = compartment.globalThis;\n compartment.globalThis.global = compartment.globalThis;\n compartment.globalThis.window = compartment.globalThis;\n\n await this.executeInSnapContext(snapId, async () => {\n compartment.evaluate(sourceCode);\n await this.registerSnapExports(snapId, snapModule);\n });\n } catch (error) {\n this.removeSnap(snapId);\n\n const [cause] = unwrapError(error);\n throw rpcErrors.internal({\n message: `Error while running snap '${snapId}': ${cause.message}`,\n data: {\n cause: cause.serialize(),\n },\n });\n }\n }\n\n /**\n * Cancels all running evaluations of all snaps and clears all snap data.\n * NOTE:** Should only be called in response to the `terminate` RPC command.\n */\n protected onTerminate() {\n // `stop()` tears down snap endowments.\n // Teardown will also be run for each snap as soon as there are\n // no more running evaluations for that snap.\n this.snapData.forEach((data) =>\n data.runningEvaluations.forEach((evaluation) => evaluation.stop()),\n );\n this.snapData.clear();\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async registerSnapExports(snapId: string, snapModule: any) {\n const data = this.snapData.get(snapId);\n // Somebody deleted the snap before we could register.\n if (!data) {\n return;\n }\n\n // If the module is async, we must await the exports.\n const snapExports = await snapModule.exports;\n data.exports = SNAP_EXPORT_NAMES.reduce((acc, exportName) => {\n const snapExport = snapExports[exportName];\n const { validator } = SNAP_EXPORTS[exportName];\n if (validator(snapExport)) {\n return { ...acc, [exportName]: snapExport };\n }\n return acc;\n }, {});\n\n // If the Snap has no valid exports after this, fail.\n assert(Object.keys(data.exports).length > 0, 'Snap has no valid exports.');\n }\n\n /**\n * Instantiates a snap API object (i.e. `globalThis.snap`).\n *\n * @param provider - A StreamProvider connected to MetaMask.\n * @returns The snap provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createSnapGlobal(provider: StreamProvider): SnapsProvider {\n const originalRequest = provider.request.bind(provider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertSnapOutboundRequest(sanitizedArgs);\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const snapsProvider = { request } as SnapsProvider;\n\n return harden(snapsProvider);\n }\n\n /**\n * Instantiates an EIP-1193 Ethereum provider object (i.e. `globalThis.ethereum`).\n *\n * @param provider - A StreamProvider connected to MetaMask.\n * @returns The EIP-1193 Ethereum provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createEIP1193Provider(\n provider: StreamProvider,\n ): SnapsEthereumProvider {\n const originalRequest = provider.request.bind(provider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertEthereumOutboundRequest(sanitizedArgs);\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const ethereumProvider = { request };\n\n return harden(ethereumProvider);\n }\n\n /**\n * Removes the snap with the given name.\n *\n * @param snapId - The id of the snap to remove.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private removeSnap(snapId: string): void {\n this.snapData.delete(snapId);\n }\n\n /**\n * Calls the specified executor function in the context of the specified snap.\n * Essentially, this means that the operation performed by the executor is\n * counted as an evaluation of the specified snap. When the count of running\n * evaluations of a snap reaches zero, its endowments are torn down.\n *\n * @param snapId - The id of the snap whose context to execute in.\n * @param executor - The function that will be executed in the snap's context.\n * @returns The executor's return value.\n * @template Result - The return value of the executor.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async executeInSnapContext(\n snapId: string,\n executor: () => Promise | Result,\n ): Promise {\n const data = this.snapData.get(snapId);\n if (data === undefined) {\n throw rpcErrors.internal(\n `Tried to execute in context of unknown snap: \"${snapId}\".`,\n );\n }\n\n let stop: () => void;\n const stopPromise = new Promise(\n (_resolve, reject) =>\n (stop = () =>\n reject(\n // TODO(rekmarks): Specify / standardize error code for this case.\n rpcErrors.internal(\n `The snap \"${snapId}\" has been terminated during execution.`,\n ),\n )),\n );\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const evaluationData = { stop: stop! };\n\n try {\n data.runningEvaluations.add(evaluationData);\n // Notice that we have to await this executor.\n // If we didn't, we would decrease the amount of running evaluations\n // before the promise actually resolves\n return await Promise.race([executor(), stopPromise]);\n } catch (error) {\n throw new WrappedSnapError(error);\n } finally {\n data.runningEvaluations.delete(evaluationData);\n\n if (data.runningEvaluations.size === 0) {\n this.lastTeardown += 1;\n await data.idleTeardown();\n }\n }\n }\n}\n"]}
+\ No newline at end of file
++{"version":3,"file":"BaseSnapExecutor.cjs","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":";;;;;;AAAA,qFAAqF;AACrF,gEAAgE;AAChE,+DAAoE;AACpE,kFAAyD;AAEzD,qDAA6E;AAE7E,mDAAmD;AAMnD,uDAO+B;AAC/B,uDAAqD;AAOrD,2CAMyB;AAEzB,qDAA2C;AAG3C,6CAA6D;AAC7D,uDAAgD;AAChD,qDAAuE;AACvE,qDAA8C;AAC9C,iDAA6C;AAC7C,uCAOiB;AACjB,iDAKsB;AACtB,4CAAiC;AAYjC,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,uBAAU,CAAC,GAAG,CAAC,QAAQ;IAC7B,OAAO,EAAE,6BAA6B;CACvC,CAAC;AAEF,MAAM,cAAc,GAAG,sBAAS;KAC7B,QAAQ,CAAO;IACd,OAAO,EAAE,sBAAsB;CAChC,CAAC;KACD,SAAS,EAAE,CAAC;AAUf;;;;GAIG;AACH,MAAM,6BAA6B,GAAG;IACpC,IAAI,EAAE;QACJ,MAAM,EAAE,uCAA0B;QAClC,MAAM,EAAE,EAAE;KACX;IACD,WAAW,EAAE;QACX,MAAM,EAAE,8CAAiC;QACzC,MAAM,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC;KAC/C;IACD,SAAS,EAAE;QACT,MAAM,EAAE,4CAA+B;QACvC,MAAM,EAAE,EAAE;KACX;IACD,OAAO,EAAE;QACP,MAAM,EAAE,0CAA6B;QACrC,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;KACnD;CACF,CAAC;AAQF,MAAa,gBAAgB;IAC3B,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IAC/B,QAAQ,CAAwB;IAEjD,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IAC/B,aAAa,CAAS;IAEvC,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IAC/B,SAAS,CAAS;IAEnC,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IAC/B,OAAO,CAAwB;IAEhD,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,gBAAgB,CAA+B;IAEvD,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,uBAAuB,CAA0C;IAEzE,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,YAAY,GAAG,CAAC,CAAC;IAEzB,YAAsB,aAAqB,EAAE,SAAiB;QAC5D,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACrC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC1C,qCAAqC;gBACrC,IAAA,sBAAQ,EAAC,KAAK,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,IAAI,CAAC,OAAO,GAAG,IAAA,0CAA+B,EAC5C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EACzB,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACvC,uEAAuE;YACvE,mBAAmB;YACnB,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,0BAAY,CAAC,WAAW,CAAC,CAAC;YAE/C,IAAA,cAAM,EACJ,CAAC,QAAQ,IAAI,OAAO,KAAK,SAAS,EAClC,MAAM,WAAW,+BAA+B,MAAM,IAAI,EAC1D,sBAAS,CAAC,kBAAkB,CAC7B,CAAC;YAEF,kEAAkE;YAClE,eAAe;YACf,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;YAChE,mCAAmC;YACnC,OAAO,CAAC,IAAW,CAAC,CACrB,CAAC;YAEF,0EAA0E;YAC1E,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC5C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,uEAAuE;YACvE,IAAI,CAAC;gBACH,OAAO,IAAA,mBAAW,EAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,sBAAS,CAAC,QAAQ,CACtB,yCAAyC,KAAK,CAAC,OAAO,CAAC,OAAO,CAC5D,sBAAsB,EACtB,EAAE,CACH,EAAE,CACJ,CAAC;YACJ,CAAC;QACH,CAAC,EACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAC5B,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,YAAY,CAAC,KAAc,EAAE,IAA0B;QAC7D,MAAM,eAAe,GAAG,IAAA,2BAAc,EAAC,KAAK,EAAE;YAC5C,aAAa,EAAE,cAAc;YAC7B,kBAAkB,EAAE,KAAK;YACzB,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,IAAA,wBAAY,EAAC,eAAe,CAAC,CAAC;QAEhD,wEAAwE;QACxE,WAAW;QACX,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC;YACX,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE;gBACN,KAAK,EAAE;oBACL,GAAG,eAAe;oBAClB,IAAI,EAAE;wBACJ,GAAG,SAAS;wBACZ,GAAG,IAAI;qBACR;iBACF;aACF;SACF,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE;YACvB,IAAA,sBAAQ,EAAC,WAAW,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,KAAK,CAAC,gBAAgB,CAAC,OAAuB;QACpD,IAAI,CAAC,IAAA,wBAAgB,EAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,IACE,IAAA,mBAAW,EAAC,OAAO,EAAE,IAAI,CAAC;gBAC1B,IAAA,gBAAE,EAAE,OAAsC,CAAC,EAAE,EAAE,uBAAe,CAAC,EAC/D,CAAC;gBACD,0DAA0D;gBAC1D,wDAAwD;gBACxD,MAAM,IAAI,CAAC,MAAM,CAAC;oBAChB,KAAK,EAAE,IAAA,2BAAc,EACnB,sBAAS,CAAC,QAAQ,CAChB,sDAAsD,CACvD,CACF;oBACD,EAAE,EAAG,OAAsC,CAAC,EAAE;oBAC9C,OAAO,EAAE,KAAK;iBACf,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,IAAA,qBAAO,EACL,4EAA4E,CAC7E,CAAC;YACJ,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAEvC,IAAI,CAAC,IAAA,mBAAW,EAAC,6BAA6B,EAAE,MAAM,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBACtB,KAAK,EAAE,sBAAS;qBACb,cAAc,CAAC;oBACd,IAAI,EAAE;wBACJ,MAAM;qBACP;iBACF,CAAC;qBACD,SAAS,EAAE;aACf,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,6BAA6B,CAAC,MAAuB,CAAC,CAAC;QAE5E,yCAAyC;QACzC,MAAM,aAAa,GAAG,IAAA,0BAAa,EAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAEjE,MAAM,CAAC,KAAK,CAAC,GAAG,IAAA,sBAAQ,EAAW,aAAa,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBACtB,KAAK,EAAE,sBAAS;qBACb,aAAa,CAAC;oBACb,OAAO,EAAE,kCAAkC,MAAM,MAAM,KAAK,CAAC,OAAO,GAAG;oBACvE,IAAI,EAAE;wBACJ,MAAM;wBACN,MAAM,EAAE,aAAa;qBACtB;iBACF,CAAC;qBACD,SAAS,EAAE;aACf,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAO,IAAI,CAAC,OAAe,CAAC,MAAM,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC;YACrE,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBACtB,KAAK,EAAE,IAAA,2BAAc,EAAC,QAAQ,EAAE;oBAC9B,aAAa;oBACb,qBAAqB,EAAE,KAAK;iBAC7B,CAAC;aACH,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,uEAAuE;IACvE,2CAA2C;IAC3C,KAAK,CAAC,MAAM,CAAC,KAAW;QACtB,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;gBACxC,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,CAAC,KAAK,CAAC,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,YAAkD;QAC9D,IAAI,CAAC,IAAA,uBAAe,EAAC,YAAY,CAAC,EAAE,CAAC;YACnC,MAAM,sBAAS,CAAC,QAAQ,CACtB,8EAA8E,CAC/E,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC;YAChB,GAAG,YAAY;YACf,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,EAAa,EAAE,QAA8B;QAC1D,IAAI,CAAC,IAAA,uBAAe,EAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,0DAA0D;YAC1D,qFAAqF;YACrF,MAAM,IAAI,CAAC,MAAM,CAAC;gBAChB,KAAK,EAAE,IAAA,2BAAc,EACnB,sBAAS,CAAC,QAAQ,CAChB,0EAA0E,CAC3E,CACF;gBACD,EAAE;gBACF,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC;YAChB,GAAG,QAAQ;YACX,EAAE;YACF,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,SAAS,CACvB,MAAc,EACd,UAAkB,EAClB,WAAqB;QAErB,IAAA,aAAG,EAAC,kBAAkB,MAAM,cAAc,CAAC,CAAC;QAC5C,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACjC,IAAA,kCAAmB,EAAC,oBAAoB,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAA,kCAAmB,EAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,CAAC,KAAiB,EAAE,EAAE;YAC5C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC;QAEF,IAAI,CAAC,uBAAuB,GAAG,CAAC,KAA4B,EAAE,EAAE;YAC9D,IAAI,CAAC,YAAY,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE;gBAC/D,MAAM;aACP,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,0BAAe,EAAE,CAAC;QACxC,IAAA,0BAAQ,EAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5D,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACtD,IAAA,sBAAQ,EAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,IAAI,2BAAY,CAC/B,SAAS,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAC3C;YACE,aAAa,EAAE,CAAC,IAAA,yCAAuB,GAAE,CAAC;SAC3C,CACF,CAAC;QAEF,QAAQ,CAAC,cAAc,EAAE,CAAC;QAE1B,MAAM,kBAAkB,GAAG,IAAI,2BAAY,CACzC,SAAS,CAAC,YAAY,CAAC,8BAA8B,CAAC,EACtD;YACE,aAAa,EAAE,CAAC,IAAA,yCAAuB,GAAE,CAAC;SAC3C,CACF,CAAC;QAEF,kBAAkB,CAAC,cAAc,EAAE,CAAC;QAEpC,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QACtD,wFAAwF;QACxF,MAAM,UAAU,GAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAExC,IAAI,CAAC;YACH,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,IAAA,6BAAgB,EAAC;gBACnE,IAAI;gBACJ,QAAQ;gBACR,MAAM;gBACN,UAAU,EAAE,WAAW;gBACvB,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;aAChC,CAAC,CAAC;YAEH,gEAAgE;YAChE,mEAAmE;YACnE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE;gBACxB,YAAY,EAAE,iBAAiB;gBAC/B,kBAAkB,EAAE,IAAI,GAAG,EAAE;gBAC7B,OAAO,EAAE,EAAE;aACZ,CAAC,CAAC;YAEH,IAAA,+BAAgB,EAAC,oBAAoB,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACrE,IAAA,+BAAgB,EAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAEjD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;gBAClC,GAAG,UAAU;gBACb,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,UAAU,CAAC,OAAO;aAC5B,CAAC,CAAC;YAEH,qEAAqE;YACrE,kEAAkE;YAClE,EAAE;YACF,wDAAwD;YACxD,yCAAyC;YACzC,WAAW,CAAC,UAAU,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;YACrD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;YACvD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;YAEvD,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;gBACjD,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;gBACjC,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAExB,MAAM,CAAC,KAAK,CAAC,GAAG,IAAA,yBAAW,EAAC,KAAK,CAAC,CAAC;YACnC,MAAM,sBAAS,CAAC,QAAQ,CAAC;gBACvB,OAAO,EAAE,6BAA6B,MAAM,MAAM,KAAK,CAAC,OAAO,EAAE;gBACjE,IAAI,EAAE;oBACJ,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE;iBACzB;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;OAGG;IACO,WAAW;QACnB,uCAAuC;QACvC,+DAA+D;QAC/D,6CAA6C;QAC7C,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC7B,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CACnE,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,KAAK,CAAC,mBAAmB,CAAC,MAAc,EAAE,UAAe;QAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,sDAAsD;QACtD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,qDAAqD;QACrD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,+BAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE;YAC1D,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;YAC3C,MAAM,EAAE,SAAS,EAAE,GAAG,0BAAY,CAAC,UAAU,CAAC,CAAC;YAC/C,IAAI,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC1B,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;YAC9C,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,qDAAqD;QACrD,IAAA,cAAM,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,4BAA4B,CAAC,CAAC;IAC7E,CAAC;IAED;;;;;;OAMG;IACH,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,gBAAgB,CACtB,QAAwB,EACxB,kBAAkC;QAElC,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAEtD,MAAM,OAAO,GAAG,KAAK,EAAE,IAAsB,EAAE,EAAE;YAC/C,yEAAyE;YACzE,MAAM,aAAa,GAAG,IAAA,gCAAwB,EAAC,IAAI,CAAC,CAAC;YACrD,IAAA,iCAAyB,EAAC,aAAa,CAAC,CAAC;YAEzC,IAAI,IAAA,2BAAmB,EAAC,aAAa,CAAC,EAAE,CAAC;gBACvC,OAAO,MAAM,IAAA,oBAAY,EACvB,yBAAyB,CAAC,aAAa,CAAC,EACxC,IAAW,CACZ,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,IAAA,oBAAY,EAAC,eAAe,CAAC,aAAa,CAAC,EAAE,IAAW,CAAC,CAAC;QACzE,CAAC,CAAC;QAEF,MAAM,aAAa,GAAG,EAAE,OAAO,EAAmB,CAAC;QAEnD,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,qBAAqB,CAC3B,QAAwB;QAExB,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAExD,MAAM,OAAO,GAAG,KAAK,EAAE,IAAsB,EAAE,EAAE;YAC/C,yEAAyE;YACzE,MAAM,aAAa,GAAG,IAAA,gCAAwB,EAAC,IAAI,CAAC,CAAC;YACrD,IAAA,qCAA6B,EAAC,aAAa,CAAC,CAAC;YAC7C,OAAO,MAAM,IAAA,oBAAY,EAAC,eAAe,CAAC,aAAa,CAAC,EAAE,IAAW,CAAC,CAAC;QACzE,CAAC,CAAC;QAEF,MAAM,gBAAgB,GAAG,EAAE,OAAO,EAAE,CAAC;QAErC,OAAO,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,UAAU,CAAC,MAAc;QAC/B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;OAUG;IACH,wEAAwE;IACxE,WAAW;IACX,gDAAgD;IACxC,KAAK,CAAC,oBAAoB,CAChC,MAAc,EACd,QAAwC;QAExC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,sBAAS,CAAC,QAAQ,CACtB,iDAAiD,MAAM,IAAI,CAC5D,CAAC;QACJ,CAAC;QAED,IAAI,IAAgB,CAAC;QACrB,MAAM,WAAW,GAAG,IAAI,OAAO,CAC7B,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CACnB,CAAC,IAAI,GAAG,GAAG,EAAE,CACX,MAAM;QACJ,kEAAkE;QAClE,sBAAS,CAAC,QAAQ,CAChB,aAAa,MAAM,yCAAyC,CAC7D,CACF,CAAC,CACP,CAAC;QAEF,oEAAoE;QACpE,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,IAAK,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5C,8CAA8C;YAC9C,oEAAoE;YACpE,uCAAuC;YACvC,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,8BAAgB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAE/C,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;gBACvB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;CACF;AA3hBD,4CA2hBC","sourcesContent":["// eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment\n/// \nimport { createIdRemapMiddleware } from '@metamask/json-rpc-engine';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { RequestArguments, StreamProvider } from '@metamask/providers';\nimport { errorCodes, rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';\nimport { getErrorData } from '@metamask/snaps-sdk';\nimport type {\n SnapExports,\n HandlerType,\n SnapExportsParameters,\n} from '@metamask/snaps-utils';\nimport {\n SNAP_EXPORT_NAMES,\n logError,\n SNAP_EXPORTS,\n WrappedSnapError,\n unwrapError,\n logInfo,\n} from '@metamask/snaps-utils';\nimport { validate, is } from '@metamask/superstruct';\nimport type {\n JsonRpcNotification,\n JsonRpcId,\n JsonRpcRequest,\n Json,\n} from '@metamask/utils';\nimport {\n assert,\n isJsonRpcRequest,\n hasProperty,\n getSafeJson,\n JsonRpcIdStruct,\n} from '@metamask/utils';\nimport type { Duplex } from 'readable-stream';\nimport { pipeline } from 'readable-stream';\n\nimport type { CommandMethodsMapping } from './commands';\nimport { getCommandMethodImplementations } from './commands';\nimport { createEndowments } from './endowments';\nimport { addEventListener, removeEventListener } from './globalEvents';\nimport { SnapProvider } from './SnapProvider';\nimport { sortParamKeys } from './sortParams';\nimport {\n assertEthereumOutboundRequest,\n assertSnapOutboundRequest,\n sanitizeRequestArguments,\n withTeardown,\n isValidResponse,\n isMultichainRequest,\n} from './utils';\nimport {\n ExecuteSnapRequestArgumentsStruct,\n PingRequestArgumentsStruct,\n SnapRpcRequestArgumentsStruct,\n TerminateRequestArgumentsStruct,\n} from './validation';\nimport { log } from '../logging';\n\ntype EvaluationData = {\n stop: () => void;\n};\n\ntype SnapData = {\n exports: SnapExports;\n runningEvaluations: Set;\n idleTeardown: () => Promise;\n};\n\nconst fallbackError = {\n code: errorCodes.rpc.internal,\n message: 'Execution Environment Error',\n};\n\nconst unhandledError = rpcErrors\n .internal({\n message: 'Unhandled Snap Error',\n })\n .serialize();\n\nexport type InvokeSnapArgs = Omit;\n\nexport type InvokeSnap = (\n target: string,\n handler: HandlerType,\n args: InvokeSnapArgs | undefined,\n) => Promise;\n\n/**\n * The supported methods in the execution environment. The validator checks the\n * incoming JSON-RPC request, and the `params` property is used for sorting the\n * parameters, if they are an object.\n */\nconst EXECUTION_ENVIRONMENT_METHODS = {\n ping: {\n struct: PingRequestArgumentsStruct,\n params: [],\n },\n executeSnap: {\n struct: ExecuteSnapRequestArgumentsStruct,\n params: ['snapId', 'sourceCode', 'endowments'],\n },\n terminate: {\n struct: TerminateRequestArgumentsStruct,\n params: [],\n },\n snapRpc: {\n struct: SnapRpcRequestArgumentsStruct,\n params: ['target', 'handler', 'origin', 'request'],\n },\n};\n\ntype Methods = typeof EXECUTION_ENVIRONMENT_METHODS;\n\nexport type NotifyFunction = (\n notification: Omit,\n) => Promise;\n\nexport class BaseSnapExecutor {\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly snapData: Map;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly commandStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly rpcStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly methods: CommandMethodsMapping;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapErrorHandler?: (event: ErrorEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapPromiseErrorHandler?: (event: PromiseRejectionEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private lastTeardown = 0;\n\n protected constructor(commandStream: Duplex, rpcStream: Duplex) {\n this.snapData = new Map();\n this.commandStream = commandStream;\n this.commandStream.on('data', (data) => {\n this.onCommandRequest(data).catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n });\n this.rpcStream = rpcStream;\n\n this.methods = getCommandMethodImplementations(\n this.startSnap.bind(this),\n async (target, handlerType, args) => {\n const data = this.snapData.get(target);\n // We're capturing the handler in case someone modifies the data object\n // before the call.\n const handler = data?.exports[handlerType];\n const { required } = SNAP_EXPORTS[handlerType];\n\n assert(\n !required || handler !== undefined,\n `No ${handlerType} handler exported for snap \"${target}\".`,\n rpcErrors.methodNotSupported,\n );\n\n // Certain handlers are not required. If they are not exported, we\n // return null.\n if (!handler) {\n return null;\n }\n\n const result = await this.executeInSnapContext(target, async () =>\n // TODO: fix handler args type cast\n handler(args as any),\n );\n\n // The handler might not return anything, but undefined is not valid JSON.\n if (result === undefined || result === null) {\n return null;\n }\n\n // /!\\ Always return only sanitized JSON to prevent security flaws. /!\\\n try {\n return getSafeJson(result);\n } catch (error) {\n throw rpcErrors.internal(\n `Received non-JSON-serializable value: ${error.message.replace(\n /^Assertion failed: /u,\n '',\n )}`,\n );\n }\n },\n this.onTerminate.bind(this),\n );\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private errorHandler(error: unknown, data: Record) {\n const serializedError = serializeError(error, {\n fallbackError: unhandledError,\n shouldIncludeStack: false,\n shouldPreserveMessage: false,\n });\n\n const errorData = getErrorData(serializedError);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line promise/no-promise-in-callback\n this.#notify({\n method: 'UnhandledError',\n params: {\n error: {\n ...serializedError,\n data: {\n ...errorData,\n ...data,\n },\n },\n },\n }).catch((notifyError) => {\n logError(notifyError);\n });\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async onCommandRequest(message: JsonRpcRequest) {\n if (!isJsonRpcRequest(message)) {\n if (\n hasProperty(message, 'id') &&\n is((message as Pick).id, JsonRpcIdStruct)\n ) {\n // Instead of throwing, we directly respond with an error.\n // We can only do this if the message ID is still valid.\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC requests must be JSON serializable objects.',\n ),\n ),\n id: (message as Pick).id,\n jsonrpc: '2.0',\n });\n } else {\n logInfo(\n 'Command stream received a non-JSON-RPC request, and was unable to respond.',\n );\n }\n return;\n }\n\n const { id, method, params } = message;\n\n if (!hasProperty(EXECUTION_ENVIRONMENT_METHODS, method)) {\n await this.#respond(id, {\n error: rpcErrors\n .methodNotFound({\n data: {\n method,\n },\n })\n .serialize(),\n });\n return;\n }\n\n const methodObject = EXECUTION_ENVIRONMENT_METHODS[method as keyof Methods];\n\n // support params by-name and by-position\n const paramsAsArray = sortParamKeys(methodObject.params, params);\n\n const [error] = validate(paramsAsArray, methodObject.struct);\n if (error) {\n await this.#respond(id, {\n error: rpcErrors\n .invalidParams({\n message: `Invalid parameters for method \"${method}\": ${error.message}.`,\n data: {\n method,\n params: paramsAsArray,\n },\n })\n .serialize(),\n });\n return;\n }\n\n try {\n const result = await (this.methods as any)[method](...paramsAsArray);\n await this.#respond(id, { result });\n } catch (rpcError) {\n await this.#respond(id, {\n error: serializeError(rpcError, {\n fallbackError,\n shouldPreserveMessage: false,\n }),\n });\n }\n }\n\n // Awaitable function that writes back to the command stream\n // To prevent snap execution from blocking writing we wrap in a promise\n // and await it before continuing execution\n async #write(chunk: Json) {\n return new Promise((resolve, reject) => {\n this.commandStream.write(chunk, (error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n async #notify(notification: Omit) {\n if (!isValidResponse(notification)) {\n throw rpcErrors.internal(\n 'JSON-RPC notifications must be JSON serializable objects smaller than 64 MB.',\n );\n }\n\n await this.#write({\n ...notification,\n jsonrpc: '2.0',\n });\n }\n\n async #respond(id: JsonRpcId, response: Record) {\n if (!isValidResponse(response)) {\n // Instead of throwing, we directly respond with an error.\n // This prevents an issue where we wouldn't respond when errors were non-serializable\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC responses must be JSON serializable objects smaller than 64 MB.',\n ),\n ),\n id,\n jsonrpc: '2.0',\n });\n return;\n }\n\n await this.#write({\n ...response,\n id,\n jsonrpc: '2.0',\n });\n }\n\n /**\n * Attempts to evaluate a snap in SES. Generates APIs for the snap. May throw\n * on errors.\n *\n * @param snapId - The id of the snap.\n * @param sourceCode - The source code of the snap, in IIFE format.\n * @param _endowments - An array of the names of the endowments.\n */\n protected async startSnap(\n snapId: string,\n sourceCode: string,\n _endowments: string[],\n ): Promise {\n log(`Starting snap '${snapId}' in worker.`);\n if (this.snapPromiseErrorHandler) {\n removeEventListener('unhandledrejection', this.snapPromiseErrorHandler);\n }\n\n if (this.snapErrorHandler) {\n removeEventListener('error', this.snapErrorHandler);\n }\n\n this.snapErrorHandler = (error: ErrorEvent) => {\n this.errorHandler(error.error, { snapId });\n };\n\n this.snapPromiseErrorHandler = (error: PromiseRejectionEvent) => {\n this.errorHandler(error instanceof Error ? error : error.reason, {\n snapId,\n });\n };\n\n const multiplex = new ObjectMultiplex();\n pipeline(this.rpcStream, multiplex, this.rpcStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Provider stream failure.`, error);\n }\n });\n\n const provider = new SnapProvider(\n multiplex.createStream('metamask-provider'),\n {\n rpcMiddleware: [createIdRemapMiddleware()],\n },\n );\n\n provider.initializeSync();\n\n const multichainProvider = new SnapProvider(\n multiplex.createStream('metamask-multichain-provider'),\n {\n rpcMiddleware: [createIdRemapMiddleware()],\n },\n );\n\n multichainProvider.initializeSync();\n\n const snap = this.createSnapGlobal(provider, multichainProvider);\n const ethereum = this.createEIP1193Provider(provider);\n // We specifically use any type because the Snap can modify the object any way they want\n const snapModule: any = { exports: {} };\n\n try {\n const { endowments, teardown: endowmentTeardown } = createEndowments({\n snap,\n ethereum,\n snapId,\n endowments: _endowments,\n notify: this.#notify.bind(this),\n });\n\n // !!! Ensure that this is the only place the data is being set.\n // Other methods access the object value and mutate its properties.\n this.snapData.set(snapId, {\n idleTeardown: endowmentTeardown,\n runningEvaluations: new Set(),\n exports: {},\n });\n\n addEventListener('unhandledRejection', this.snapPromiseErrorHandler);\n addEventListener('error', this.snapErrorHandler);\n\n const compartment = new Compartment({\n ...endowments,\n module: snapModule,\n exports: snapModule.exports,\n });\n\n // All of those are JavaScript runtime specific and self referential,\n // but we add them for compatibility sake with external libraries.\n //\n // We can't do that in the injected globals object above\n // because SES creates its own globalThis\n compartment.globalThis.self = compartment.globalThis;\n compartment.globalThis.global = compartment.globalThis;\n compartment.globalThis.window = compartment.globalThis;\n\n await this.executeInSnapContext(snapId, async () => {\n compartment.evaluate(sourceCode);\n await this.registerSnapExports(snapId, snapModule);\n });\n } catch (error) {\n this.removeSnap(snapId);\n\n const [cause] = unwrapError(error);\n throw rpcErrors.internal({\n message: `Error while running snap '${snapId}': ${cause.message}`,\n data: {\n cause: cause.serialize(),\n },\n });\n }\n }\n\n /**\n * Cancels all running evaluations of all snaps and clears all snap data.\n * NOTE:** Should only be called in response to the `terminate` RPC command.\n */\n protected onTerminate() {\n // `stop()` tears down snap endowments.\n // Teardown will also be run for each snap as soon as there are\n // no more running evaluations for that snap.\n this.snapData.forEach((data) =>\n data.runningEvaluations.forEach((evaluation) => evaluation.stop()),\n );\n this.snapData.clear();\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async registerSnapExports(snapId: string, snapModule: any) {\n const data = this.snapData.get(snapId);\n // Somebody deleted the snap before we could register.\n if (!data) {\n return;\n }\n\n // If the module is async, we must await the exports.\n const snapExports = await snapModule.exports;\n data.exports = SNAP_EXPORT_NAMES.reduce((acc, exportName) => {\n const snapExport = snapExports[exportName];\n const { validator } = SNAP_EXPORTS[exportName];\n if (validator(snapExport)) {\n return { ...acc, [exportName]: snapExport };\n }\n return acc;\n }, {});\n\n // If the Snap has no valid exports after this, fail.\n assert(Object.keys(data.exports).length > 0, 'Snap has no valid exports.');\n }\n\n /**\n * Instantiates a snap API object (i.e. `globalThis.snap`).\n *\n * @param provider - A StreamProvider connected to the EIP-1193 client stream.\n * @param multichainProvider - A StreamProvider connected to the CAIP-27 client stream.\n * @returns The snap provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createSnapGlobal(\n provider: StreamProvider,\n multichainProvider: StreamProvider,\n ): SnapsProvider {\n const originalRequest = provider.request.bind(provider);\n const originalMultichainRequest =\n multichainProvider.request.bind(multichainProvider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertSnapOutboundRequest(sanitizedArgs);\n\n if (isMultichainRequest(sanitizedArgs)) {\n return await withTeardown(\n originalMultichainRequest(sanitizedArgs),\n this as any,\n );\n }\n\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const snapsProvider = { request } as SnapsProvider;\n\n return harden(snapsProvider);\n }\n\n /**\n * Instantiates an EIP-1193 Ethereum provider object (i.e. `globalThis.ethereum`).\n *\n * @param provider - A StreamProvider connected to MetaMask.\n * @returns The EIP-1193 Ethereum provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createEIP1193Provider(\n provider: StreamProvider,\n ): SnapsEthereumProvider {\n const originalRequest = provider.request.bind(provider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertEthereumOutboundRequest(sanitizedArgs);\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const ethereumProvider = { request };\n\n return harden(ethereumProvider);\n }\n\n /**\n * Removes the snap with the given name.\n *\n * @param snapId - The id of the snap to remove.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private removeSnap(snapId: string): void {\n this.snapData.delete(snapId);\n }\n\n /**\n * Calls the specified executor function in the context of the specified snap.\n * Essentially, this means that the operation performed by the executor is\n * counted as an evaluation of the specified snap. When the count of running\n * evaluations of a snap reaches zero, its endowments are torn down.\n *\n * @param snapId - The id of the snap whose context to execute in.\n * @param executor - The function that will be executed in the snap's context.\n * @returns The executor's return value.\n * @template Result - The return value of the executor.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async executeInSnapContext(\n snapId: string,\n executor: () => Promise | Result,\n ): Promise {\n const data = this.snapData.get(snapId);\n if (data === undefined) {\n throw rpcErrors.internal(\n `Tried to execute in context of unknown snap: \"${snapId}\".`,\n );\n }\n\n let stop: () => void;\n const stopPromise = new Promise(\n (_resolve, reject) =>\n (stop = () =>\n reject(\n // TODO(rekmarks): Specify / standardize error code for this case.\n rpcErrors.internal(\n `The snap \"${snapId}\" has been terminated during execution.`,\n ),\n )),\n );\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const evaluationData = { stop: stop! };\n\n try {\n data.runningEvaluations.add(evaluationData);\n // Notice that we have to await this executor.\n // If we didn't, we would decrease the amount of running evaluations\n // before the promise actually resolves\n return await Promise.race([executor(), stopPromise]);\n } catch (error) {\n throw new WrappedSnapError(error);\n } finally {\n data.runningEvaluations.delete(evaluationData);\n\n if (data.runningEvaluations.size === 0) {\n this.lastTeardown += 1;\n await data.idleTeardown();\n }\n }\n }\n}\n"]}
+\ No newline at end of file
+diff --git a/dist/common/BaseSnapExecutor.d.cts b/dist/common/BaseSnapExecutor.d.cts
+index f79e6dd7cebda999c014997403cf09c4b7dc241c..efc4c9c07b1117eac2e179491fa2bb921e9c53dd 100644
+--- a/dist/common/BaseSnapExecutor.d.cts
++++ b/dist/common/BaseSnapExecutor.d.cts
+@@ -36,7 +36,8 @@ export declare class BaseSnapExecutor {
+ /**
+ * Instantiates a snap API object (i.e. `globalThis.snap`).
+ *
+- * @param provider - A StreamProvider connected to MetaMask.
++ * @param provider - A StreamProvider connected to the EIP-1193 client stream.
++ * @param multichainProvider - A StreamProvider connected to the CAIP-27 client stream.
+ * @returns The snap provider object.
+ */
+ private createSnapGlobal;
+diff --git a/dist/common/BaseSnapExecutor.d.cts.map b/dist/common/BaseSnapExecutor.d.cts.map
+index 4b660ace462a660f93d37a23b45023aae1d9f7d0..9d4ec76680f915f4ad2055d7ab05931e74ad2e95 100644
+--- a/dist/common/BaseSnapExecutor.d.cts.map
++++ b/dist/common/BaseSnapExecutor.d.cts.map
+@@ -1 +1 @@
+-{"version":3,"file":"BaseSnapExecutor.d.cts","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":";;AAQA,OAAO,KAAK,EAEV,WAAW,EACX,qBAAqB,EACtB,8BAA8B;AAU/B,OAAO,KAAK,EACV,mBAAmB,EAGnB,IAAI,EACL,wBAAwB;AAQzB,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AA6C9C,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,UAAU,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,cAAc,GAAG,SAAS,KAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;AA4BnB,MAAM,MAAM,cAAc,GAAG,CAC3B,YAAY,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,KAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,qBAAa,gBAAgB;;IAI3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAKjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAKvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAKnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAKhD,OAAO,CAAC,gBAAgB,CAAC,CAA8B;IAKvD,OAAO,CAAC,uBAAuB,CAAC,CAAyC;IAKzE,OAAO,CAAC,YAAY,CAAK;IAEzB,SAAS,aAAa,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IA6D9D,OAAO,CAAC,YAAY;YA+BN,gBAAgB;IA6H9B;;;;;;;OAOG;cACa,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC;IA6FhB;;;OAGG;IACH,SAAS,CAAC,WAAW;YAaP,mBAAmB;IAsBjC;;;;;OAKG;IAIH,OAAO,CAAC,gBAAgB;IAexB;;;;;OAKG;IAIH,OAAO,CAAC,qBAAqB;IAiB7B;;;;OAIG;IAIH,OAAO,CAAC,UAAU;IAIlB;;;;;;;;;;OAUG;YAIW,oBAAoB;CA2CnC"}
+\ No newline at end of file
++{"version":3,"file":"BaseSnapExecutor.d.cts","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":";;AAQA,OAAO,KAAK,EAEV,WAAW,EACX,qBAAqB,EACtB,8BAA8B;AAU/B,OAAO,KAAK,EACV,mBAAmB,EAGnB,IAAI,EACL,wBAAwB;AAQzB,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AA8C9C,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,UAAU,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,cAAc,GAAG,SAAS,KAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;AA4BnB,MAAM,MAAM,cAAc,GAAG,CAC3B,YAAY,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,KAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,qBAAa,gBAAgB;;IAI3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAKjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAKvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAKnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAKhD,OAAO,CAAC,gBAAgB,CAAC,CAA8B;IAKvD,OAAO,CAAC,uBAAuB,CAAC,CAAyC;IAKzE,OAAO,CAAC,YAAY,CAAK;IAEzB,SAAS,aAAa,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IA6D9D,OAAO,CAAC,YAAY;YA+BN,gBAAgB;IA6H9B;;;;;;;OAOG;cACa,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC;IAsGhB;;;OAGG;IACH,SAAS,CAAC,WAAW;YAaP,mBAAmB;IAsBjC;;;;;;OAMG;IAIH,OAAO,CAAC,gBAAgB;IA4BxB;;;;;OAKG;IAIH,OAAO,CAAC,qBAAqB;IAiB7B;;;;OAIG;IAIH,OAAO,CAAC,UAAU;IAIlB;;;;;;;;;;OAUG;YAIW,oBAAoB;CA2CnC"}
+\ No newline at end of file
+diff --git a/dist/common/BaseSnapExecutor.d.mts b/dist/common/BaseSnapExecutor.d.mts
+index 74bef8317b4141faa44f576bdf76bdfe93b29a40..86cd53cbcc8275e20605cc82645a12102b79a0ee 100644
+--- a/dist/common/BaseSnapExecutor.d.mts
++++ b/dist/common/BaseSnapExecutor.d.mts
+@@ -36,7 +36,8 @@ export declare class BaseSnapExecutor {
+ /**
+ * Instantiates a snap API object (i.e. `globalThis.snap`).
+ *
+- * @param provider - A StreamProvider connected to MetaMask.
++ * @param provider - A StreamProvider connected to the EIP-1193 client stream.
++ * @param multichainProvider - A StreamProvider connected to the CAIP-27 client stream.
+ * @returns The snap provider object.
+ */
+ private createSnapGlobal;
+diff --git a/dist/common/BaseSnapExecutor.d.mts.map b/dist/common/BaseSnapExecutor.d.mts.map
+index 6afdace6cf9ab0973fe1e705233e05d98bae32a1..7465c7c2ccde0e158283436d762780996f37cc2c 100644
+--- a/dist/common/BaseSnapExecutor.d.mts.map
++++ b/dist/common/BaseSnapExecutor.d.mts.map
+@@ -1 +1 @@
+-{"version":3,"file":"BaseSnapExecutor.d.mts","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":";;AAQA,OAAO,KAAK,EAEV,WAAW,EACX,qBAAqB,EACtB,8BAA8B;AAU/B,OAAO,KAAK,EACV,mBAAmB,EAGnB,IAAI,EACL,wBAAwB;AAQzB,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AA6C9C,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,UAAU,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,cAAc,GAAG,SAAS,KAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;AA4BnB,MAAM,MAAM,cAAc,GAAG,CAC3B,YAAY,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,KAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,qBAAa,gBAAgB;;IAI3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAKjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAKvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAKnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAKhD,OAAO,CAAC,gBAAgB,CAAC,CAA8B;IAKvD,OAAO,CAAC,uBAAuB,CAAC,CAAyC;IAKzE,OAAO,CAAC,YAAY,CAAK;IAEzB,SAAS,aAAa,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IA6D9D,OAAO,CAAC,YAAY;YA+BN,gBAAgB;IA6H9B;;;;;;;OAOG;cACa,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC;IA6FhB;;;OAGG;IACH,SAAS,CAAC,WAAW;YAaP,mBAAmB;IAsBjC;;;;;OAKG;IAIH,OAAO,CAAC,gBAAgB;IAexB;;;;;OAKG;IAIH,OAAO,CAAC,qBAAqB;IAiB7B;;;;OAIG;IAIH,OAAO,CAAC,UAAU;IAIlB;;;;;;;;;;OAUG;YAIW,oBAAoB;CA2CnC"}
+\ No newline at end of file
++{"version":3,"file":"BaseSnapExecutor.d.mts","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":";;AAQA,OAAO,KAAK,EAEV,WAAW,EACX,qBAAqB,EACtB,8BAA8B;AAU/B,OAAO,KAAK,EACV,mBAAmB,EAGnB,IAAI,EACL,wBAAwB;AAQzB,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AA8C9C,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,UAAU,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,cAAc,GAAG,SAAS,KAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;AA4BnB,MAAM,MAAM,cAAc,GAAG,CAC3B,YAAY,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,KAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,qBAAa,gBAAgB;;IAI3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAKjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAKvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAKnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAKhD,OAAO,CAAC,gBAAgB,CAAC,CAA8B;IAKvD,OAAO,CAAC,uBAAuB,CAAC,CAAyC;IAKzE,OAAO,CAAC,YAAY,CAAK;IAEzB,SAAS,aAAa,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IA6D9D,OAAO,CAAC,YAAY;YA+BN,gBAAgB;IA6H9B;;;;;;;OAOG;cACa,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC;IAsGhB;;;OAGG;IACH,SAAS,CAAC,WAAW;YAaP,mBAAmB;IAsBjC;;;;;;OAMG;IAIH,OAAO,CAAC,gBAAgB;IA4BxB;;;;;OAKG;IAIH,OAAO,CAAC,qBAAqB;IAiB7B;;;;OAIG;IAIH,OAAO,CAAC,UAAU;IAIlB;;;;;;;;;;OAUG;YAIW,oBAAoB;CA2CnC"}
+\ No newline at end of file
+diff --git a/dist/common/BaseSnapExecutor.mjs b/dist/common/BaseSnapExecutor.mjs
+index 724b338f2cadc0f81322ffefc431fc166604a82d..dd16e58ffc2df95ae13aea103cea81b5f68b773c 100644
+--- a/dist/common/BaseSnapExecutor.mjs
++++ b/dist/common/BaseSnapExecutor.mjs
+@@ -20,7 +20,7 @@ import { createEndowments } from "./endowments/index.mjs";
+ import { addEventListener, removeEventListener } from "./globalEvents.mjs";
+ import { SnapProvider } from "./SnapProvider.mjs";
+ import { sortParamKeys } from "./sortParams.mjs";
+-import { assertEthereumOutboundRequest, assertSnapOutboundRequest, sanitizeRequestArguments, withTeardown, isValidResponse } from "./utils.mjs";
++import { assertEthereumOutboundRequest, assertSnapOutboundRequest, sanitizeRequestArguments, withTeardown, isValidResponse, isMultichainRequest } from "./utils.mjs";
+ import { ExecuteSnapRequestArgumentsStruct, PingRequestArgumentsStruct, SnapRpcRequestArgumentsStruct, TerminateRequestArgumentsStruct } from "./validation.mjs";
+ import { log } from "../logging.mjs";
+ const fallbackError = {
+@@ -288,7 +288,11 @@ export class BaseSnapExecutor {
+ rpcMiddleware: [createIdRemapMiddleware()],
+ });
+ provider.initializeSync();
+- const snap = this.createSnapGlobal(provider);
++ const multichainProvider = new SnapProvider(multiplex.createStream('metamask-multichain-provider'), {
++ rpcMiddleware: [createIdRemapMiddleware()],
++ });
++ multichainProvider.initializeSync();
++ const snap = this.createSnapGlobal(provider, multichainProvider);
+ const ethereum = this.createEIP1193Provider(provider);
+ // We specifically use any type because the Snap can modify the object any way they want
+ const snapModule = { exports: {} };
+@@ -374,18 +378,23 @@ export class BaseSnapExecutor {
+ /**
+ * Instantiates a snap API object (i.e. `globalThis.snap`).
+ *
+- * @param provider - A StreamProvider connected to MetaMask.
++ * @param provider - A StreamProvider connected to the EIP-1193 client stream.
++ * @param multichainProvider - A StreamProvider connected to the CAIP-27 client stream.
+ * @returns The snap provider object.
+ */
+ // TODO: Either fix this lint violation or explain why it's necessary to
+ // ignore.
+ // eslint-disable-next-line no-restricted-syntax
+- createSnapGlobal(provider) {
++ createSnapGlobal(provider, multichainProvider) {
+ const originalRequest = provider.request.bind(provider);
++ const originalMultichainRequest = multichainProvider.request.bind(multichainProvider);
+ const request = async (args) => {
+ // As part of the sanitization, we validate that the args are valid JSON.
+ const sanitizedArgs = sanitizeRequestArguments(args);
+ assertSnapOutboundRequest(sanitizedArgs);
++ if (isMultichainRequest(sanitizedArgs)) {
++ return await withTeardown(originalMultichainRequest(sanitizedArgs), this);
++ }
+ return await withTeardown(originalRequest(sanitizedArgs), this);
+ };
+ const snapsProvider = { request };
+diff --git a/dist/common/BaseSnapExecutor.mjs.map b/dist/common/BaseSnapExecutor.mjs.map
+index f07e1439aaf1e1d3ad9af2c0ed17bdd699fd729d..51054f3455f44b81b33cc28bde862aa0c4cabe19 100644
+--- a/dist/common/BaseSnapExecutor.mjs.map
++++ b/dist/common/BaseSnapExecutor.mjs.map
+@@ -1 +1 @@
+-{"version":3,"file":"BaseSnapExecutor.mjs","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment\n/// \nimport { createIdRemapMiddleware } from '@metamask/json-rpc-engine';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { RequestArguments, StreamProvider } from '@metamask/providers';\nimport { errorCodes, rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';\nimport { getErrorData } from '@metamask/snaps-sdk';\nimport type {\n SnapExports,\n HandlerType,\n SnapExportsParameters,\n} from '@metamask/snaps-utils';\nimport {\n SNAP_EXPORT_NAMES,\n logError,\n SNAP_EXPORTS,\n WrappedSnapError,\n unwrapError,\n logInfo,\n} from '@metamask/snaps-utils';\nimport { validate, is } from '@metamask/superstruct';\nimport type {\n JsonRpcNotification,\n JsonRpcId,\n JsonRpcRequest,\n Json,\n} from '@metamask/utils';\nimport {\n assert,\n isJsonRpcRequest,\n hasProperty,\n getSafeJson,\n JsonRpcIdStruct,\n} from '@metamask/utils';\nimport type { Duplex } from 'readable-stream';\nimport { pipeline } from 'readable-stream';\n\nimport type { CommandMethodsMapping } from './commands';\nimport { getCommandMethodImplementations } from './commands';\nimport { createEndowments } from './endowments';\nimport { addEventListener, removeEventListener } from './globalEvents';\nimport { SnapProvider } from './SnapProvider';\nimport { sortParamKeys } from './sortParams';\nimport {\n assertEthereumOutboundRequest,\n assertSnapOutboundRequest,\n sanitizeRequestArguments,\n withTeardown,\n isValidResponse,\n} from './utils';\nimport {\n ExecuteSnapRequestArgumentsStruct,\n PingRequestArgumentsStruct,\n SnapRpcRequestArgumentsStruct,\n TerminateRequestArgumentsStruct,\n} from './validation';\nimport { log } from '../logging';\n\ntype EvaluationData = {\n stop: () => void;\n};\n\ntype SnapData = {\n exports: SnapExports;\n runningEvaluations: Set;\n idleTeardown: () => Promise;\n};\n\nconst fallbackError = {\n code: errorCodes.rpc.internal,\n message: 'Execution Environment Error',\n};\n\nconst unhandledError = rpcErrors\n .internal({\n message: 'Unhandled Snap Error',\n })\n .serialize();\n\nexport type InvokeSnapArgs = Omit;\n\nexport type InvokeSnap = (\n target: string,\n handler: HandlerType,\n args: InvokeSnapArgs | undefined,\n) => Promise;\n\n/**\n * The supported methods in the execution environment. The validator checks the\n * incoming JSON-RPC request, and the `params` property is used for sorting the\n * parameters, if they are an object.\n */\nconst EXECUTION_ENVIRONMENT_METHODS = {\n ping: {\n struct: PingRequestArgumentsStruct,\n params: [],\n },\n executeSnap: {\n struct: ExecuteSnapRequestArgumentsStruct,\n params: ['snapId', 'sourceCode', 'endowments'],\n },\n terminate: {\n struct: TerminateRequestArgumentsStruct,\n params: [],\n },\n snapRpc: {\n struct: SnapRpcRequestArgumentsStruct,\n params: ['target', 'handler', 'origin', 'request'],\n },\n};\n\ntype Methods = typeof EXECUTION_ENVIRONMENT_METHODS;\n\nexport type NotifyFunction = (\n notification: Omit,\n) => Promise;\n\nexport class BaseSnapExecutor {\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly snapData: Map;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly commandStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly rpcStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly methods: CommandMethodsMapping;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapErrorHandler?: (event: ErrorEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapPromiseErrorHandler?: (event: PromiseRejectionEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private lastTeardown = 0;\n\n protected constructor(commandStream: Duplex, rpcStream: Duplex) {\n this.snapData = new Map();\n this.commandStream = commandStream;\n this.commandStream.on('data', (data) => {\n this.onCommandRequest(data).catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n });\n this.rpcStream = rpcStream;\n\n this.methods = getCommandMethodImplementations(\n this.startSnap.bind(this),\n async (target, handlerType, args) => {\n const data = this.snapData.get(target);\n // We're capturing the handler in case someone modifies the data object\n // before the call.\n const handler = data?.exports[handlerType];\n const { required } = SNAP_EXPORTS[handlerType];\n\n assert(\n !required || handler !== undefined,\n `No ${handlerType} handler exported for snap \"${target}\".`,\n rpcErrors.methodNotSupported,\n );\n\n // Certain handlers are not required. If they are not exported, we\n // return null.\n if (!handler) {\n return null;\n }\n\n const result = await this.executeInSnapContext(target, async () =>\n // TODO: fix handler args type cast\n handler(args as any),\n );\n\n // The handler might not return anything, but undefined is not valid JSON.\n if (result === undefined || result === null) {\n return null;\n }\n\n // /!\\ Always return only sanitized JSON to prevent security flaws. /!\\\n try {\n return getSafeJson(result);\n } catch (error) {\n throw rpcErrors.internal(\n `Received non-JSON-serializable value: ${error.message.replace(\n /^Assertion failed: /u,\n '',\n )}`,\n );\n }\n },\n this.onTerminate.bind(this),\n );\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private errorHandler(error: unknown, data: Record) {\n const serializedError = serializeError(error, {\n fallbackError: unhandledError,\n shouldIncludeStack: false,\n shouldPreserveMessage: false,\n });\n\n const errorData = getErrorData(serializedError);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line promise/no-promise-in-callback\n this.#notify({\n method: 'UnhandledError',\n params: {\n error: {\n ...serializedError,\n data: {\n ...errorData,\n ...data,\n },\n },\n },\n }).catch((notifyError) => {\n logError(notifyError);\n });\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async onCommandRequest(message: JsonRpcRequest) {\n if (!isJsonRpcRequest(message)) {\n if (\n hasProperty(message, 'id') &&\n is((message as Pick).id, JsonRpcIdStruct)\n ) {\n // Instead of throwing, we directly respond with an error.\n // We can only do this if the message ID is still valid.\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC requests must be JSON serializable objects.',\n ),\n ),\n id: (message as Pick).id,\n jsonrpc: '2.0',\n });\n } else {\n logInfo(\n 'Command stream received a non-JSON-RPC request, and was unable to respond.',\n );\n }\n return;\n }\n\n const { id, method, params } = message;\n\n if (!hasProperty(EXECUTION_ENVIRONMENT_METHODS, method)) {\n await this.#respond(id, {\n error: rpcErrors\n .methodNotFound({\n data: {\n method,\n },\n })\n .serialize(),\n });\n return;\n }\n\n const methodObject = EXECUTION_ENVIRONMENT_METHODS[method as keyof Methods];\n\n // support params by-name and by-position\n const paramsAsArray = sortParamKeys(methodObject.params, params);\n\n const [error] = validate(paramsAsArray, methodObject.struct);\n if (error) {\n await this.#respond(id, {\n error: rpcErrors\n .invalidParams({\n message: `Invalid parameters for method \"${method}\": ${error.message}.`,\n data: {\n method,\n params: paramsAsArray,\n },\n })\n .serialize(),\n });\n return;\n }\n\n try {\n const result = await (this.methods as any)[method](...paramsAsArray);\n await this.#respond(id, { result });\n } catch (rpcError) {\n await this.#respond(id, {\n error: serializeError(rpcError, {\n fallbackError,\n shouldPreserveMessage: false,\n }),\n });\n }\n }\n\n // Awaitable function that writes back to the command stream\n // To prevent snap execution from blocking writing we wrap in a promise\n // and await it before continuing execution\n async #write(chunk: Json) {\n return new Promise((resolve, reject) => {\n this.commandStream.write(chunk, (error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n async #notify(notification: Omit) {\n if (!isValidResponse(notification)) {\n throw rpcErrors.internal(\n 'JSON-RPC notifications must be JSON serializable objects smaller than 64 MB.',\n );\n }\n\n await this.#write({\n ...notification,\n jsonrpc: '2.0',\n });\n }\n\n async #respond(id: JsonRpcId, response: Record) {\n if (!isValidResponse(response)) {\n // Instead of throwing, we directly respond with an error.\n // This prevents an issue where we wouldn't respond when errors were non-serializable\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC responses must be JSON serializable objects smaller than 64 MB.',\n ),\n ),\n id,\n jsonrpc: '2.0',\n });\n return;\n }\n\n await this.#write({\n ...response,\n id,\n jsonrpc: '2.0',\n });\n }\n\n /**\n * Attempts to evaluate a snap in SES. Generates APIs for the snap. May throw\n * on errors.\n *\n * @param snapId - The id of the snap.\n * @param sourceCode - The source code of the snap, in IIFE format.\n * @param _endowments - An array of the names of the endowments.\n */\n protected async startSnap(\n snapId: string,\n sourceCode: string,\n _endowments: string[],\n ): Promise {\n log(`Starting snap '${snapId}' in worker.`);\n if (this.snapPromiseErrorHandler) {\n removeEventListener('unhandledrejection', this.snapPromiseErrorHandler);\n }\n\n if (this.snapErrorHandler) {\n removeEventListener('error', this.snapErrorHandler);\n }\n\n this.snapErrorHandler = (error: ErrorEvent) => {\n this.errorHandler(error.error, { snapId });\n };\n\n this.snapPromiseErrorHandler = (error: PromiseRejectionEvent) => {\n this.errorHandler(error instanceof Error ? error : error.reason, {\n snapId,\n });\n };\n\n const multiplex = new ObjectMultiplex();\n pipeline(this.rpcStream, multiplex, this.rpcStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Provider stream failure.`, error);\n }\n });\n\n const provider = new SnapProvider(\n multiplex.createStream('metamask-provider'),\n {\n rpcMiddleware: [createIdRemapMiddleware()],\n },\n );\n\n provider.initializeSync();\n\n const snap = this.createSnapGlobal(provider);\n const ethereum = this.createEIP1193Provider(provider);\n // We specifically use any type because the Snap can modify the object any way they want\n const snapModule: any = { exports: {} };\n\n try {\n const { endowments, teardown: endowmentTeardown } = createEndowments({\n snap,\n ethereum,\n snapId,\n endowments: _endowments,\n notify: this.#notify.bind(this),\n });\n\n // !!! Ensure that this is the only place the data is being set.\n // Other methods access the object value and mutate its properties.\n this.snapData.set(snapId, {\n idleTeardown: endowmentTeardown,\n runningEvaluations: new Set(),\n exports: {},\n });\n\n addEventListener('unhandledRejection', this.snapPromiseErrorHandler);\n addEventListener('error', this.snapErrorHandler);\n\n const compartment = new Compartment({\n ...endowments,\n module: snapModule,\n exports: snapModule.exports,\n });\n\n // All of those are JavaScript runtime specific and self referential,\n // but we add them for compatibility sake with external libraries.\n //\n // We can't do that in the injected globals object above\n // because SES creates its own globalThis\n compartment.globalThis.self = compartment.globalThis;\n compartment.globalThis.global = compartment.globalThis;\n compartment.globalThis.window = compartment.globalThis;\n\n await this.executeInSnapContext(snapId, async () => {\n compartment.evaluate(sourceCode);\n await this.registerSnapExports(snapId, snapModule);\n });\n } catch (error) {\n this.removeSnap(snapId);\n\n const [cause] = unwrapError(error);\n throw rpcErrors.internal({\n message: `Error while running snap '${snapId}': ${cause.message}`,\n data: {\n cause: cause.serialize(),\n },\n });\n }\n }\n\n /**\n * Cancels all running evaluations of all snaps and clears all snap data.\n * NOTE:** Should only be called in response to the `terminate` RPC command.\n */\n protected onTerminate() {\n // `stop()` tears down snap endowments.\n // Teardown will also be run for each snap as soon as there are\n // no more running evaluations for that snap.\n this.snapData.forEach((data) =>\n data.runningEvaluations.forEach((evaluation) => evaluation.stop()),\n );\n this.snapData.clear();\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async registerSnapExports(snapId: string, snapModule: any) {\n const data = this.snapData.get(snapId);\n // Somebody deleted the snap before we could register.\n if (!data) {\n return;\n }\n\n // If the module is async, we must await the exports.\n const snapExports = await snapModule.exports;\n data.exports = SNAP_EXPORT_NAMES.reduce((acc, exportName) => {\n const snapExport = snapExports[exportName];\n const { validator } = SNAP_EXPORTS[exportName];\n if (validator(snapExport)) {\n return { ...acc, [exportName]: snapExport };\n }\n return acc;\n }, {});\n\n // If the Snap has no valid exports after this, fail.\n assert(Object.keys(data.exports).length > 0, 'Snap has no valid exports.');\n }\n\n /**\n * Instantiates a snap API object (i.e. `globalThis.snap`).\n *\n * @param provider - A StreamProvider connected to MetaMask.\n * @returns The snap provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createSnapGlobal(provider: StreamProvider): SnapsProvider {\n const originalRequest = provider.request.bind(provider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertSnapOutboundRequest(sanitizedArgs);\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const snapsProvider = { request } as SnapsProvider;\n\n return harden(snapsProvider);\n }\n\n /**\n * Instantiates an EIP-1193 Ethereum provider object (i.e. `globalThis.ethereum`).\n *\n * @param provider - A StreamProvider connected to MetaMask.\n * @returns The EIP-1193 Ethereum provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createEIP1193Provider(\n provider: StreamProvider,\n ): SnapsEthereumProvider {\n const originalRequest = provider.request.bind(provider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertEthereumOutboundRequest(sanitizedArgs);\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const ethereumProvider = { request };\n\n return harden(ethereumProvider);\n }\n\n /**\n * Removes the snap with the given name.\n *\n * @param snapId - The id of the snap to remove.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private removeSnap(snapId: string): void {\n this.snapData.delete(snapId);\n }\n\n /**\n * Calls the specified executor function in the context of the specified snap.\n * Essentially, this means that the operation performed by the executor is\n * counted as an evaluation of the specified snap. When the count of running\n * evaluations of a snap reaches zero, its endowments are torn down.\n *\n * @param snapId - The id of the snap whose context to execute in.\n * @param executor - The function that will be executed in the snap's context.\n * @returns The executor's return value.\n * @template Result - The return value of the executor.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async executeInSnapContext(\n snapId: string,\n executor: () => Promise | Result,\n ): Promise {\n const data = this.snapData.get(snapId);\n if (data === undefined) {\n throw rpcErrors.internal(\n `Tried to execute in context of unknown snap: \"${snapId}\".`,\n );\n }\n\n let stop: () => void;\n const stopPromise = new Promise(\n (_resolve, reject) =>\n (stop = () =>\n reject(\n // TODO(rekmarks): Specify / standardize error code for this case.\n rpcErrors.internal(\n `The snap \"${snapId}\" has been terminated during execution.`,\n ),\n )),\n );\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const evaluationData = { stop: stop! };\n\n try {\n data.runningEvaluations.add(evaluationData);\n // Notice that we have to await this executor.\n // If we didn't, we would decrease the amount of running evaluations\n // before the promise actually resolves\n return await Promise.race([executor(), stopPromise]);\n } catch (error) {\n throw new WrappedSnapError(error);\n } finally {\n data.runningEvaluations.delete(evaluationData);\n\n if (data.runningEvaluations.size === 0) {\n this.lastTeardown += 1;\n await data.idleTeardown();\n }\n }\n }\n}\n"]}
+\ No newline at end of file
++{"version":3,"file":"BaseSnapExecutor.mjs","sourceRoot":"","sources":["../../src/common/BaseSnapExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment\n/// \nimport { createIdRemapMiddleware } from '@metamask/json-rpc-engine';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { RequestArguments, StreamProvider } from '@metamask/providers';\nimport { errorCodes, rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';\nimport { getErrorData } from '@metamask/snaps-sdk';\nimport type {\n SnapExports,\n HandlerType,\n SnapExportsParameters,\n} from '@metamask/snaps-utils';\nimport {\n SNAP_EXPORT_NAMES,\n logError,\n SNAP_EXPORTS,\n WrappedSnapError,\n unwrapError,\n logInfo,\n} from '@metamask/snaps-utils';\nimport { validate, is } from '@metamask/superstruct';\nimport type {\n JsonRpcNotification,\n JsonRpcId,\n JsonRpcRequest,\n Json,\n} from '@metamask/utils';\nimport {\n assert,\n isJsonRpcRequest,\n hasProperty,\n getSafeJson,\n JsonRpcIdStruct,\n} from '@metamask/utils';\nimport type { Duplex } from 'readable-stream';\nimport { pipeline } from 'readable-stream';\n\nimport type { CommandMethodsMapping } from './commands';\nimport { getCommandMethodImplementations } from './commands';\nimport { createEndowments } from './endowments';\nimport { addEventListener, removeEventListener } from './globalEvents';\nimport { SnapProvider } from './SnapProvider';\nimport { sortParamKeys } from './sortParams';\nimport {\n assertEthereumOutboundRequest,\n assertSnapOutboundRequest,\n sanitizeRequestArguments,\n withTeardown,\n isValidResponse,\n isMultichainRequest,\n} from './utils';\nimport {\n ExecuteSnapRequestArgumentsStruct,\n PingRequestArgumentsStruct,\n SnapRpcRequestArgumentsStruct,\n TerminateRequestArgumentsStruct,\n} from './validation';\nimport { log } from '../logging';\n\ntype EvaluationData = {\n stop: () => void;\n};\n\ntype SnapData = {\n exports: SnapExports;\n runningEvaluations: Set;\n idleTeardown: () => Promise;\n};\n\nconst fallbackError = {\n code: errorCodes.rpc.internal,\n message: 'Execution Environment Error',\n};\n\nconst unhandledError = rpcErrors\n .internal({\n message: 'Unhandled Snap Error',\n })\n .serialize();\n\nexport type InvokeSnapArgs = Omit;\n\nexport type InvokeSnap = (\n target: string,\n handler: HandlerType,\n args: InvokeSnapArgs | undefined,\n) => Promise;\n\n/**\n * The supported methods in the execution environment. The validator checks the\n * incoming JSON-RPC request, and the `params` property is used for sorting the\n * parameters, if they are an object.\n */\nconst EXECUTION_ENVIRONMENT_METHODS = {\n ping: {\n struct: PingRequestArgumentsStruct,\n params: [],\n },\n executeSnap: {\n struct: ExecuteSnapRequestArgumentsStruct,\n params: ['snapId', 'sourceCode', 'endowments'],\n },\n terminate: {\n struct: TerminateRequestArgumentsStruct,\n params: [],\n },\n snapRpc: {\n struct: SnapRpcRequestArgumentsStruct,\n params: ['target', 'handler', 'origin', 'request'],\n },\n};\n\ntype Methods = typeof EXECUTION_ENVIRONMENT_METHODS;\n\nexport type NotifyFunction = (\n notification: Omit,\n) => Promise;\n\nexport class BaseSnapExecutor {\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly snapData: Map;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly commandStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly rpcStream: Duplex;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private readonly methods: CommandMethodsMapping;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapErrorHandler?: (event: ErrorEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private snapPromiseErrorHandler?: (event: PromiseRejectionEvent) => void;\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private lastTeardown = 0;\n\n protected constructor(commandStream: Duplex, rpcStream: Duplex) {\n this.snapData = new Map();\n this.commandStream = commandStream;\n this.commandStream.on('data', (data) => {\n this.onCommandRequest(data).catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n });\n this.rpcStream = rpcStream;\n\n this.methods = getCommandMethodImplementations(\n this.startSnap.bind(this),\n async (target, handlerType, args) => {\n const data = this.snapData.get(target);\n // We're capturing the handler in case someone modifies the data object\n // before the call.\n const handler = data?.exports[handlerType];\n const { required } = SNAP_EXPORTS[handlerType];\n\n assert(\n !required || handler !== undefined,\n `No ${handlerType} handler exported for snap \"${target}\".`,\n rpcErrors.methodNotSupported,\n );\n\n // Certain handlers are not required. If they are not exported, we\n // return null.\n if (!handler) {\n return null;\n }\n\n const result = await this.executeInSnapContext(target, async () =>\n // TODO: fix handler args type cast\n handler(args as any),\n );\n\n // The handler might not return anything, but undefined is not valid JSON.\n if (result === undefined || result === null) {\n return null;\n }\n\n // /!\\ Always return only sanitized JSON to prevent security flaws. /!\\\n try {\n return getSafeJson(result);\n } catch (error) {\n throw rpcErrors.internal(\n `Received non-JSON-serializable value: ${error.message.replace(\n /^Assertion failed: /u,\n '',\n )}`,\n );\n }\n },\n this.onTerminate.bind(this),\n );\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private errorHandler(error: unknown, data: Record) {\n const serializedError = serializeError(error, {\n fallbackError: unhandledError,\n shouldIncludeStack: false,\n shouldPreserveMessage: false,\n });\n\n const errorData = getErrorData(serializedError);\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line promise/no-promise-in-callback\n this.#notify({\n method: 'UnhandledError',\n params: {\n error: {\n ...serializedError,\n data: {\n ...errorData,\n ...data,\n },\n },\n },\n }).catch((notifyError) => {\n logError(notifyError);\n });\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async onCommandRequest(message: JsonRpcRequest) {\n if (!isJsonRpcRequest(message)) {\n if (\n hasProperty(message, 'id') &&\n is((message as Pick).id, JsonRpcIdStruct)\n ) {\n // Instead of throwing, we directly respond with an error.\n // We can only do this if the message ID is still valid.\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC requests must be JSON serializable objects.',\n ),\n ),\n id: (message as Pick).id,\n jsonrpc: '2.0',\n });\n } else {\n logInfo(\n 'Command stream received a non-JSON-RPC request, and was unable to respond.',\n );\n }\n return;\n }\n\n const { id, method, params } = message;\n\n if (!hasProperty(EXECUTION_ENVIRONMENT_METHODS, method)) {\n await this.#respond(id, {\n error: rpcErrors\n .methodNotFound({\n data: {\n method,\n },\n })\n .serialize(),\n });\n return;\n }\n\n const methodObject = EXECUTION_ENVIRONMENT_METHODS[method as keyof Methods];\n\n // support params by-name and by-position\n const paramsAsArray = sortParamKeys(methodObject.params, params);\n\n const [error] = validate(paramsAsArray, methodObject.struct);\n if (error) {\n await this.#respond(id, {\n error: rpcErrors\n .invalidParams({\n message: `Invalid parameters for method \"${method}\": ${error.message}.`,\n data: {\n method,\n params: paramsAsArray,\n },\n })\n .serialize(),\n });\n return;\n }\n\n try {\n const result = await (this.methods as any)[method](...paramsAsArray);\n await this.#respond(id, { result });\n } catch (rpcError) {\n await this.#respond(id, {\n error: serializeError(rpcError, {\n fallbackError,\n shouldPreserveMessage: false,\n }),\n });\n }\n }\n\n // Awaitable function that writes back to the command stream\n // To prevent snap execution from blocking writing we wrap in a promise\n // and await it before continuing execution\n async #write(chunk: Json) {\n return new Promise((resolve, reject) => {\n this.commandStream.write(chunk, (error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n\n async #notify(notification: Omit) {\n if (!isValidResponse(notification)) {\n throw rpcErrors.internal(\n 'JSON-RPC notifications must be JSON serializable objects smaller than 64 MB.',\n );\n }\n\n await this.#write({\n ...notification,\n jsonrpc: '2.0',\n });\n }\n\n async #respond(id: JsonRpcId, response: Record) {\n if (!isValidResponse(response)) {\n // Instead of throwing, we directly respond with an error.\n // This prevents an issue where we wouldn't respond when errors were non-serializable\n await this.#write({\n error: serializeError(\n rpcErrors.internal(\n 'JSON-RPC responses must be JSON serializable objects smaller than 64 MB.',\n ),\n ),\n id,\n jsonrpc: '2.0',\n });\n return;\n }\n\n await this.#write({\n ...response,\n id,\n jsonrpc: '2.0',\n });\n }\n\n /**\n * Attempts to evaluate a snap in SES. Generates APIs for the snap. May throw\n * on errors.\n *\n * @param snapId - The id of the snap.\n * @param sourceCode - The source code of the snap, in IIFE format.\n * @param _endowments - An array of the names of the endowments.\n */\n protected async startSnap(\n snapId: string,\n sourceCode: string,\n _endowments: string[],\n ): Promise {\n log(`Starting snap '${snapId}' in worker.`);\n if (this.snapPromiseErrorHandler) {\n removeEventListener('unhandledrejection', this.snapPromiseErrorHandler);\n }\n\n if (this.snapErrorHandler) {\n removeEventListener('error', this.snapErrorHandler);\n }\n\n this.snapErrorHandler = (error: ErrorEvent) => {\n this.errorHandler(error.error, { snapId });\n };\n\n this.snapPromiseErrorHandler = (error: PromiseRejectionEvent) => {\n this.errorHandler(error instanceof Error ? error : error.reason, {\n snapId,\n });\n };\n\n const multiplex = new ObjectMultiplex();\n pipeline(this.rpcStream, multiplex, this.rpcStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Provider stream failure.`, error);\n }\n });\n\n const provider = new SnapProvider(\n multiplex.createStream('metamask-provider'),\n {\n rpcMiddleware: [createIdRemapMiddleware()],\n },\n );\n\n provider.initializeSync();\n\n const multichainProvider = new SnapProvider(\n multiplex.createStream('metamask-multichain-provider'),\n {\n rpcMiddleware: [createIdRemapMiddleware()],\n },\n );\n\n multichainProvider.initializeSync();\n\n const snap = this.createSnapGlobal(provider, multichainProvider);\n const ethereum = this.createEIP1193Provider(provider);\n // We specifically use any type because the Snap can modify the object any way they want\n const snapModule: any = { exports: {} };\n\n try {\n const { endowments, teardown: endowmentTeardown } = createEndowments({\n snap,\n ethereum,\n snapId,\n endowments: _endowments,\n notify: this.#notify.bind(this),\n });\n\n // !!! Ensure that this is the only place the data is being set.\n // Other methods access the object value and mutate its properties.\n this.snapData.set(snapId, {\n idleTeardown: endowmentTeardown,\n runningEvaluations: new Set(),\n exports: {},\n });\n\n addEventListener('unhandledRejection', this.snapPromiseErrorHandler);\n addEventListener('error', this.snapErrorHandler);\n\n const compartment = new Compartment({\n ...endowments,\n module: snapModule,\n exports: snapModule.exports,\n });\n\n // All of those are JavaScript runtime specific and self referential,\n // but we add them for compatibility sake with external libraries.\n //\n // We can't do that in the injected globals object above\n // because SES creates its own globalThis\n compartment.globalThis.self = compartment.globalThis;\n compartment.globalThis.global = compartment.globalThis;\n compartment.globalThis.window = compartment.globalThis;\n\n await this.executeInSnapContext(snapId, async () => {\n compartment.evaluate(sourceCode);\n await this.registerSnapExports(snapId, snapModule);\n });\n } catch (error) {\n this.removeSnap(snapId);\n\n const [cause] = unwrapError(error);\n throw rpcErrors.internal({\n message: `Error while running snap '${snapId}': ${cause.message}`,\n data: {\n cause: cause.serialize(),\n },\n });\n }\n }\n\n /**\n * Cancels all running evaluations of all snaps and clears all snap data.\n * NOTE:** Should only be called in response to the `terminate` RPC command.\n */\n protected onTerminate() {\n // `stop()` tears down snap endowments.\n // Teardown will also be run for each snap as soon as there are\n // no more running evaluations for that snap.\n this.snapData.forEach((data) =>\n data.runningEvaluations.forEach((evaluation) => evaluation.stop()),\n );\n this.snapData.clear();\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async registerSnapExports(snapId: string, snapModule: any) {\n const data = this.snapData.get(snapId);\n // Somebody deleted the snap before we could register.\n if (!data) {\n return;\n }\n\n // If the module is async, we must await the exports.\n const snapExports = await snapModule.exports;\n data.exports = SNAP_EXPORT_NAMES.reduce((acc, exportName) => {\n const snapExport = snapExports[exportName];\n const { validator } = SNAP_EXPORTS[exportName];\n if (validator(snapExport)) {\n return { ...acc, [exportName]: snapExport };\n }\n return acc;\n }, {});\n\n // If the Snap has no valid exports after this, fail.\n assert(Object.keys(data.exports).length > 0, 'Snap has no valid exports.');\n }\n\n /**\n * Instantiates a snap API object (i.e. `globalThis.snap`).\n *\n * @param provider - A StreamProvider connected to the EIP-1193 client stream.\n * @param multichainProvider - A StreamProvider connected to the CAIP-27 client stream.\n * @returns The snap provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createSnapGlobal(\n provider: StreamProvider,\n multichainProvider: StreamProvider,\n ): SnapsProvider {\n const originalRequest = provider.request.bind(provider);\n const originalMultichainRequest =\n multichainProvider.request.bind(multichainProvider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertSnapOutboundRequest(sanitizedArgs);\n\n if (isMultichainRequest(sanitizedArgs)) {\n return await withTeardown(\n originalMultichainRequest(sanitizedArgs),\n this as any,\n );\n }\n\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const snapsProvider = { request } as SnapsProvider;\n\n return harden(snapsProvider);\n }\n\n /**\n * Instantiates an EIP-1193 Ethereum provider object (i.e. `globalThis.ethereum`).\n *\n * @param provider - A StreamProvider connected to MetaMask.\n * @returns The EIP-1193 Ethereum provider object.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private createEIP1193Provider(\n provider: StreamProvider,\n ): SnapsEthereumProvider {\n const originalRequest = provider.request.bind(provider);\n\n const request = async (args: RequestArguments) => {\n // As part of the sanitization, we validate that the args are valid JSON.\n const sanitizedArgs = sanitizeRequestArguments(args);\n assertEthereumOutboundRequest(sanitizedArgs);\n return await withTeardown(originalRequest(sanitizedArgs), this as any);\n };\n\n const ethereumProvider = { request };\n\n return harden(ethereumProvider);\n }\n\n /**\n * Removes the snap with the given name.\n *\n * @param snapId - The id of the snap to remove.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private removeSnap(snapId: string): void {\n this.snapData.delete(snapId);\n }\n\n /**\n * Calls the specified executor function in the context of the specified snap.\n * Essentially, this means that the operation performed by the executor is\n * counted as an evaluation of the specified snap. When the count of running\n * evaluations of a snap reaches zero, its endowments are torn down.\n *\n * @param snapId - The id of the snap whose context to execute in.\n * @param executor - The function that will be executed in the snap's context.\n * @returns The executor's return value.\n * @template Result - The return value of the executor.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line no-restricted-syntax\n private async executeInSnapContext(\n snapId: string,\n executor: () => Promise | Result,\n ): Promise {\n const data = this.snapData.get(snapId);\n if (data === undefined) {\n throw rpcErrors.internal(\n `Tried to execute in context of unknown snap: \"${snapId}\".`,\n );\n }\n\n let stop: () => void;\n const stopPromise = new Promise(\n (_resolve, reject) =>\n (stop = () =>\n reject(\n // TODO(rekmarks): Specify / standardize error code for this case.\n rpcErrors.internal(\n `The snap \"${snapId}\" has been terminated during execution.`,\n ),\n )),\n );\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const evaluationData = { stop: stop! };\n\n try {\n data.runningEvaluations.add(evaluationData);\n // Notice that we have to await this executor.\n // If we didn't, we would decrease the amount of running evaluations\n // before the promise actually resolves\n return await Promise.race([executor(), stopPromise]);\n } catch (error) {\n throw new WrappedSnapError(error);\n } finally {\n data.runningEvaluations.delete(evaluationData);\n\n if (data.runningEvaluations.size === 0) {\n this.lastTeardown += 1;\n await data.idleTeardown();\n }\n }\n }\n}\n"]}
+\ No newline at end of file
+diff --git a/dist/common/utils.cjs b/dist/common/utils.cjs
+index 901cb9731c02504de9ef4a49ba802f03d2b14720..4f095457637d54725273059305e1dba11cc0f506 100644
+--- a/dist/common/utils.cjs
++++ b/dist/common/utils.cjs
+@@ -1,6 +1,6 @@
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+-exports.isValidResponse = exports.sanitizeRequestArguments = exports.assertEthereumOutboundRequest = exports.assertSnapOutboundRequest = exports.BLOCKED_RPC_METHODS = exports.withTeardown = void 0;
++exports.isValidResponse = exports.sanitizeRequestArguments = exports.assertEthereumOutboundRequest = exports.assertSnapOutboundRequest = exports.isMultichainRequest = exports.MULTICHAIN_API_METHODS = exports.BLOCKED_RPC_METHODS = exports.withTeardown = void 0;
+ const rpc_errors_1 = require("@metamask/rpc-errors");
+ const snaps_utils_1 = require("@metamask/snaps-utils");
+ const utils_1 = require("@metamask/utils");
+@@ -54,6 +54,22 @@ exports.BLOCKED_RPC_METHODS = Object.freeze([
+ 'wallet_registerOnboarding',
+ 'wallet_scanQRCode',
+ ]);
++exports.MULTICHAIN_API_METHODS = Object.freeze([
++ 'wallet_createSession',
++ 'wallet_invokeMethod',
++ 'wallet_getSession',
++ 'wallet_revokeSession',
++]);
++/**
++ * Check whether a validated request should be routed to the multichain API.
++ *
++ * @param args - The request arguments.
++ * @returns True if the request is a multichain request, otherwise false.
++ */
++function isMultichainRequest(args) {
++ return exports.MULTICHAIN_API_METHODS.includes(args.method);
++}
++exports.isMultichainRequest = isMultichainRequest;
+ /**
+ * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.
+ *
+diff --git a/dist/common/utils.cjs.map b/dist/common/utils.cjs.map
+index b0940a9b1f04f5601537c61fc959859c539f2b19..29727db3f6c942099f70a16a27ae9cd0590489a7 100644
+--- a/dist/common/utils.cjs.map
++++ b/dist/common/utils.cjs.map
+@@ -1 +1 @@
+-{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RequestArguments } from '@metamask/providers';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getJsonSizeUnsafe } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { assert, getSafeJson, isObject } from '@metamask/utils';\n\nimport { log } from '../logging';\n\n// 64 MB - we chose this number because it is the size limit for postMessage\n// between the extension and the dapp enforced by Chrome.\nconst MAX_RESPONSE_JSON_SIZE = 64_000_000;\n\n/**\n * Make proxy for Promise and handle the teardown process properly.\n * If the teardown is called in the meanwhile, Promise result will not be\n * exposed to the snap anymore and warning will be logged to the console.\n *\n * @param originalPromise - Original promise.\n * @param teardownRef - Reference containing teardown count.\n * @param teardownRef.lastTeardown - Number of the last teardown.\n * @returns New proxy promise.\n */\nexport async function withTeardown(\n originalPromise: Promise,\n teardownRef: { lastTeardown: number },\n): Promise {\n const myTeardown = teardownRef.lastTeardown;\n return new Promise((resolve, reject) => {\n originalPromise\n .then((value) => {\n if (teardownRef.lastTeardown === myTeardown) {\n resolve(value);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n })\n .catch((reason) => {\n if (teardownRef.lastTeardown === myTeardown) {\n reject(reason);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n });\n });\n}\n\n// We're blocking these RPC methods for v1, will revisit later.\nexport const BLOCKED_RPC_METHODS = Object.freeze([\n 'wallet_requestPermissions',\n 'wallet_revokePermissions',\n // We disallow all of these confirmations for now, since the screens are not ready for Snaps.\n 'eth_sendTransaction',\n 'eth_decrypt',\n 'eth_getEncryptionPublicKey',\n 'wallet_addEthereumChain',\n 'wallet_watchAsset',\n 'wallet_registerOnboarding',\n 'wallet_scanQRCode',\n]);\n\n/**\n * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertSnapOutboundRequest(args: RequestArguments) {\n // Disallow any non `wallet_` or `snap_` methods for separation of concerns.\n assert(\n String.prototype.startsWith.call(args.method, 'wallet_') ||\n String.prototype.startsWith.call(args.method, 'snap_'),\n 'The global Snap API only allows RPC methods starting with `wallet_*` and `snap_*`.',\n rpcErrors.methodNotSupported,\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Asserts the validity of request arguments for an ethereum outbound request using the `ethereum.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertEthereumOutboundRequest(args: RequestArguments) {\n // Disallow snaps methods for separation of concerns.\n assert(\n !String.prototype.startsWith.call(args.method, 'snap_'),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Gets a sanitized value to be used for passing to the underlying MetaMask provider.\n *\n * @param value - An unsanitized value from a snap.\n * @returns A sanitized value ready to be passed to a MetaMask provider.\n */\nexport function sanitizeRequestArguments(value: unknown): RequestArguments {\n // Before passing to getSafeJson we run the value through JSON serialization.\n // This lets request arguments contain undefined which is normally disallowed.\n const json = JSON.parse(JSON.stringify(value));\n return getSafeJson(json) as RequestArguments;\n}\n\n/**\n * Check if the input is a valid response.\n *\n * @param response - The response.\n * @returns True if the response is valid, otherwise false.\n */\nexport function isValidResponse(response: Record) {\n if (!isObject(response)) {\n return false;\n }\n\n // We know that the response is valid JSON already and we don't\n // need the size to be exact.\n const size = getJsonSizeUnsafe(response);\n return size < MAX_RESPONSE_JSON_SIZE;\n}\n"]}
+\ No newline at end of file
++{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RequestArguments } from '@metamask/providers';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getJsonSizeUnsafe } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { assert, getSafeJson, isObject } from '@metamask/utils';\n\nimport { log } from '../logging';\n\n// 64 MB - we chose this number because it is the size limit for postMessage\n// between the extension and the dapp enforced by Chrome.\nconst MAX_RESPONSE_JSON_SIZE = 64_000_000;\n\n/**\n * Make proxy for Promise and handle the teardown process properly.\n * If the teardown is called in the meanwhile, Promise result will not be\n * exposed to the snap anymore and warning will be logged to the console.\n *\n * @param originalPromise - Original promise.\n * @param teardownRef - Reference containing teardown count.\n * @param teardownRef.lastTeardown - Number of the last teardown.\n * @returns New proxy promise.\n */\nexport async function withTeardown(\n originalPromise: Promise,\n teardownRef: { lastTeardown: number },\n): Promise {\n const myTeardown = teardownRef.lastTeardown;\n return new Promise((resolve, reject) => {\n originalPromise\n .then((value) => {\n if (teardownRef.lastTeardown === myTeardown) {\n resolve(value);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n })\n .catch((reason) => {\n if (teardownRef.lastTeardown === myTeardown) {\n reject(reason);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n });\n });\n}\n\n// We're blocking these RPC methods for v1, will revisit later.\nexport const BLOCKED_RPC_METHODS = Object.freeze([\n 'wallet_requestPermissions',\n 'wallet_revokePermissions',\n // We disallow all of these confirmations for now, since the screens are not ready for Snaps.\n 'eth_sendTransaction',\n 'eth_decrypt',\n 'eth_getEncryptionPublicKey',\n 'wallet_addEthereumChain',\n 'wallet_watchAsset',\n 'wallet_registerOnboarding',\n 'wallet_scanQRCode',\n]);\n\nexport const MULTICHAIN_API_METHODS = Object.freeze([\n 'wallet_createSession',\n 'wallet_invokeMethod',\n 'wallet_getSession',\n 'wallet_revokeSession',\n]);\n\n/**\n * Check whether a validated request should be routed to the multichain API.\n *\n * @param args - The request arguments.\n * @returns True if the request is a multichain request, otherwise false.\n */\nexport function isMultichainRequest(args: RequestArguments) {\n return MULTICHAIN_API_METHODS.includes(args.method);\n}\n\n/**\n * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertSnapOutboundRequest(args: RequestArguments) {\n // Disallow any non `wallet_` or `snap_` methods for separation of concerns.\n assert(\n String.prototype.startsWith.call(args.method, 'wallet_') ||\n String.prototype.startsWith.call(args.method, 'snap_'),\n 'The global Snap API only allows RPC methods starting with `wallet_*` and `snap_*`.',\n rpcErrors.methodNotSupported,\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Asserts the validity of request arguments for an ethereum outbound request using the `ethereum.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertEthereumOutboundRequest(args: RequestArguments) {\n // Disallow snaps methods for separation of concerns.\n assert(\n !String.prototype.startsWith.call(args.method, 'snap_'),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Gets a sanitized value to be used for passing to the underlying MetaMask provider.\n *\n * @param value - An unsanitized value from a snap.\n * @returns A sanitized value ready to be passed to a MetaMask provider.\n */\nexport function sanitizeRequestArguments(value: unknown): RequestArguments {\n // Before passing to getSafeJson we run the value through JSON serialization.\n // This lets request arguments contain undefined which is normally disallowed.\n const json = JSON.parse(JSON.stringify(value));\n return getSafeJson(json) as RequestArguments;\n}\n\n/**\n * Check if the input is a valid response.\n *\n * @param response - The response.\n * @returns True if the response is valid, otherwise false.\n */\nexport function isValidResponse(response: Record) {\n if (!isObject(response)) {\n return false;\n }\n\n // We know that the response is valid JSON already and we don't\n // need the size to be exact.\n const size = getJsonSizeUnsafe(response);\n return size < MAX_RESPONSE_JSON_SIZE;\n}\n"]}
+\ No newline at end of file
+diff --git a/dist/common/utils.d.cts b/dist/common/utils.d.cts
+index 9e32450bc72c1efd523c9c6ed296a641abd63fa5..d64e37fe6f93c050dcddae9d1acd02ae8496cf9e 100644
+--- a/dist/common/utils.d.cts
++++ b/dist/common/utils.d.cts
+@@ -14,6 +14,14 @@ export declare function withTeardown(originalPromise: Promise, teard
+ lastTeardown: number;
+ }): Promise;
+ export declare const BLOCKED_RPC_METHODS: readonly string[];
++export declare const MULTICHAIN_API_METHODS: readonly string[];
++/**
++ * Check whether a validated request should be routed to the multichain API.
++ *
++ * @param args - The request arguments.
++ * @returns True if the request is a multichain request, otherwise false.
++ */
++export declare function isMultichainRequest(args: RequestArguments): boolean;
+ /**
+ * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.
+ *
+diff --git a/dist/common/utils.d.cts.map b/dist/common/utils.d.cts.map
+index 0af143ed42edfd12e31272c2eb958172e13edd75..b87d8fe2e17da4acb76f563a47eba97b61310e84 100644
+--- a/dist/common/utils.d.cts.map
++++ b/dist/common/utils.d.cts.map
+@@ -1 +1 @@
+-{"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B;AAG5D,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAS5C;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EACrC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,EAC9B,WAAW,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAGD,eAAO,MAAM,mBAAmB,mBAW9B,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,gBAAgB,QAgB/D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,gBAAgB,QAkBnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAKzE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,WAS7D"}
+\ No newline at end of file
++{"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B;AAG5D,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAS5C;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EACrC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,EAC9B,WAAW,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAGD,eAAO,MAAM,mBAAmB,mBAW9B,CAAC;AAEH,eAAO,MAAM,sBAAsB,mBAKjC,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,WAEzD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,gBAAgB,QAgB/D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,gBAAgB,QAkBnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAKzE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,WAS7D"}
+\ No newline at end of file
+diff --git a/dist/common/utils.d.mts b/dist/common/utils.d.mts
+index 3c6204abbb9cd7bbfed2e9e89d29c119c9b2fdf7..d60a70074f98146c5a9ab615cd0a5a46420a2f04 100644
+--- a/dist/common/utils.d.mts
++++ b/dist/common/utils.d.mts
+@@ -14,6 +14,14 @@ export declare function withTeardown(originalPromise: Promise, teard
+ lastTeardown: number;
+ }): Promise;
+ export declare const BLOCKED_RPC_METHODS: readonly string[];
++export declare const MULTICHAIN_API_METHODS: readonly string[];
++/**
++ * Check whether a validated request should be routed to the multichain API.
++ *
++ * @param args - The request arguments.
++ * @returns True if the request is a multichain request, otherwise false.
++ */
++export declare function isMultichainRequest(args: RequestArguments): boolean;
+ /**
+ * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.
+ *
+diff --git a/dist/common/utils.d.mts.map b/dist/common/utils.d.mts.map
+index affd197aa8ad0e0f6bdf0f152946d4a367b5d134..7fa671b863a7bd2379749f4131667a882137592b 100644
+--- a/dist/common/utils.d.mts.map
++++ b/dist/common/utils.d.mts.map
+@@ -1 +1 @@
+-{"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B;AAG5D,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAS5C;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EACrC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,EAC9B,WAAW,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAGD,eAAO,MAAM,mBAAmB,mBAW9B,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,gBAAgB,QAgB/D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,gBAAgB,QAkBnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAKzE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,WAS7D"}
+\ No newline at end of file
++{"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B;AAG5D,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAS5C;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EACrC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,EAC9B,WAAW,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAGD,eAAO,MAAM,mBAAmB,mBAW9B,CAAC;AAEH,eAAO,MAAM,sBAAsB,mBAKjC,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,WAEzD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,gBAAgB,QAgB/D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,gBAAgB,QAkBnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAKzE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,WAS7D"}
+\ No newline at end of file
+diff --git a/dist/common/utils.mjs b/dist/common/utils.mjs
+index 047d70d1694d369a7956b58101f2abc137596236..351fc6583c668fcec63c9e9d2aba527fba2a9662 100644
+--- a/dist/common/utils.mjs
++++ b/dist/common/utils.mjs
+@@ -50,6 +50,21 @@ export const BLOCKED_RPC_METHODS = Object.freeze([
+ 'wallet_registerOnboarding',
+ 'wallet_scanQRCode',
+ ]);
++export const MULTICHAIN_API_METHODS = Object.freeze([
++ 'wallet_createSession',
++ 'wallet_invokeMethod',
++ 'wallet_getSession',
++ 'wallet_revokeSession',
++]);
++/**
++ * Check whether a validated request should be routed to the multichain API.
++ *
++ * @param args - The request arguments.
++ * @returns True if the request is a multichain request, otherwise false.
++ */
++export function isMultichainRequest(args) {
++ return MULTICHAIN_API_METHODS.includes(args.method);
++}
+ /**
+ * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.
+ *
+diff --git a/dist/common/utils.mjs.map b/dist/common/utils.mjs.map
+index 813174ee186c2d05a9f3b6f34fe881a0f4697880..4b4292cc9358effdddb15a2eb4cb210e2e2b5a27 100644
+--- a/dist/common/utils.mjs.map
++++ b/dist/common/utils.mjs.map
+@@ -1 +1 @@
+-{"version":3,"file":"utils.mjs","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RequestArguments } from '@metamask/providers';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getJsonSizeUnsafe } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { assert, getSafeJson, isObject } from '@metamask/utils';\n\nimport { log } from '../logging';\n\n// 64 MB - we chose this number because it is the size limit for postMessage\n// between the extension and the dapp enforced by Chrome.\nconst MAX_RESPONSE_JSON_SIZE = 64_000_000;\n\n/**\n * Make proxy for Promise and handle the teardown process properly.\n * If the teardown is called in the meanwhile, Promise result will not be\n * exposed to the snap anymore and warning will be logged to the console.\n *\n * @param originalPromise - Original promise.\n * @param teardownRef - Reference containing teardown count.\n * @param teardownRef.lastTeardown - Number of the last teardown.\n * @returns New proxy promise.\n */\nexport async function withTeardown(\n originalPromise: Promise,\n teardownRef: { lastTeardown: number },\n): Promise {\n const myTeardown = teardownRef.lastTeardown;\n return new Promise((resolve, reject) => {\n originalPromise\n .then((value) => {\n if (teardownRef.lastTeardown === myTeardown) {\n resolve(value);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n })\n .catch((reason) => {\n if (teardownRef.lastTeardown === myTeardown) {\n reject(reason);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n });\n });\n}\n\n// We're blocking these RPC methods for v1, will revisit later.\nexport const BLOCKED_RPC_METHODS = Object.freeze([\n 'wallet_requestPermissions',\n 'wallet_revokePermissions',\n // We disallow all of these confirmations for now, since the screens are not ready for Snaps.\n 'eth_sendTransaction',\n 'eth_decrypt',\n 'eth_getEncryptionPublicKey',\n 'wallet_addEthereumChain',\n 'wallet_watchAsset',\n 'wallet_registerOnboarding',\n 'wallet_scanQRCode',\n]);\n\n/**\n * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertSnapOutboundRequest(args: RequestArguments) {\n // Disallow any non `wallet_` or `snap_` methods for separation of concerns.\n assert(\n String.prototype.startsWith.call(args.method, 'wallet_') ||\n String.prototype.startsWith.call(args.method, 'snap_'),\n 'The global Snap API only allows RPC methods starting with `wallet_*` and `snap_*`.',\n rpcErrors.methodNotSupported,\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Asserts the validity of request arguments for an ethereum outbound request using the `ethereum.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertEthereumOutboundRequest(args: RequestArguments) {\n // Disallow snaps methods for separation of concerns.\n assert(\n !String.prototype.startsWith.call(args.method, 'snap_'),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Gets a sanitized value to be used for passing to the underlying MetaMask provider.\n *\n * @param value - An unsanitized value from a snap.\n * @returns A sanitized value ready to be passed to a MetaMask provider.\n */\nexport function sanitizeRequestArguments(value: unknown): RequestArguments {\n // Before passing to getSafeJson we run the value through JSON serialization.\n // This lets request arguments contain undefined which is normally disallowed.\n const json = JSON.parse(JSON.stringify(value));\n return getSafeJson(json) as RequestArguments;\n}\n\n/**\n * Check if the input is a valid response.\n *\n * @param response - The response.\n * @returns True if the response is valid, otherwise false.\n */\nexport function isValidResponse(response: Record) {\n if (!isObject(response)) {\n return false;\n }\n\n // We know that the response is valid JSON already and we don't\n // need the size to be exact.\n const size = getJsonSizeUnsafe(response);\n return size < MAX_RESPONSE_JSON_SIZE;\n}\n"]}
+\ No newline at end of file
++{"version":3,"file":"utils.mjs","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RequestArguments } from '@metamask/providers';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getJsonSizeUnsafe } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { assert, getSafeJson, isObject } from '@metamask/utils';\n\nimport { log } from '../logging';\n\n// 64 MB - we chose this number because it is the size limit for postMessage\n// between the extension and the dapp enforced by Chrome.\nconst MAX_RESPONSE_JSON_SIZE = 64_000_000;\n\n/**\n * Make proxy for Promise and handle the teardown process properly.\n * If the teardown is called in the meanwhile, Promise result will not be\n * exposed to the snap anymore and warning will be logged to the console.\n *\n * @param originalPromise - Original promise.\n * @param teardownRef - Reference containing teardown count.\n * @param teardownRef.lastTeardown - Number of the last teardown.\n * @returns New proxy promise.\n */\nexport async function withTeardown(\n originalPromise: Promise,\n teardownRef: { lastTeardown: number },\n): Promise {\n const myTeardown = teardownRef.lastTeardown;\n return new Promise((resolve, reject) => {\n originalPromise\n .then((value) => {\n if (teardownRef.lastTeardown === myTeardown) {\n resolve(value);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n })\n .catch((reason) => {\n if (teardownRef.lastTeardown === myTeardown) {\n reject(reason);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n });\n });\n}\n\n// We're blocking these RPC methods for v1, will revisit later.\nexport const BLOCKED_RPC_METHODS = Object.freeze([\n 'wallet_requestPermissions',\n 'wallet_revokePermissions',\n // We disallow all of these confirmations for now, since the screens are not ready for Snaps.\n 'eth_sendTransaction',\n 'eth_decrypt',\n 'eth_getEncryptionPublicKey',\n 'wallet_addEthereumChain',\n 'wallet_watchAsset',\n 'wallet_registerOnboarding',\n 'wallet_scanQRCode',\n]);\n\nexport const MULTICHAIN_API_METHODS = Object.freeze([\n 'wallet_createSession',\n 'wallet_invokeMethod',\n 'wallet_getSession',\n 'wallet_revokeSession',\n]);\n\n/**\n * Check whether a validated request should be routed to the multichain API.\n *\n * @param args - The request arguments.\n * @returns True if the request is a multichain request, otherwise false.\n */\nexport function isMultichainRequest(args: RequestArguments) {\n return MULTICHAIN_API_METHODS.includes(args.method);\n}\n\n/**\n * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertSnapOutboundRequest(args: RequestArguments) {\n // Disallow any non `wallet_` or `snap_` methods for separation of concerns.\n assert(\n String.prototype.startsWith.call(args.method, 'wallet_') ||\n String.prototype.startsWith.call(args.method, 'snap_'),\n 'The global Snap API only allows RPC methods starting with `wallet_*` and `snap_*`.',\n rpcErrors.methodNotSupported,\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Asserts the validity of request arguments for an ethereum outbound request using the `ethereum.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertEthereumOutboundRequest(args: RequestArguments) {\n // Disallow snaps methods for separation of concerns.\n assert(\n !String.prototype.startsWith.call(args.method, 'snap_'),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n}\n\n/**\n * Gets a sanitized value to be used for passing to the underlying MetaMask provider.\n *\n * @param value - An unsanitized value from a snap.\n * @returns A sanitized value ready to be passed to a MetaMask provider.\n */\nexport function sanitizeRequestArguments(value: unknown): RequestArguments {\n // Before passing to getSafeJson we run the value through JSON serialization.\n // This lets request arguments contain undefined which is normally disallowed.\n const json = JSON.parse(JSON.stringify(value));\n return getSafeJson(json) as RequestArguments;\n}\n\n/**\n * Check if the input is a valid response.\n *\n * @param response - The response.\n * @returns True if the response is valid, otherwise false.\n */\nexport function isValidResponse(response: Record) {\n if (!isObject(response)) {\n return false;\n }\n\n // We know that the response is valid JSON already and we don't\n // need the size to be exact.\n const size = getJsonSizeUnsafe(response);\n return size < MAX_RESPONSE_JSON_SIZE;\n}\n"]}
+\ No newline at end of file
+diff --git a/dist/webpack/iframe/bundle.js b/dist/webpack/iframe/bundle.js
+index 6dad83cb6021428beec9b8d7fddb9ea4eed6208f..c3be66f661ac6a74ba45ac23c5fc2a9c363e8270 100644
+--- a/dist/webpack/iframe/bundle.js
++++ b/dist/webpack/iframe/bundle.js
+@@ -1,2 +1,2 @@
+ /*! For license information please see bundle.js.LICENSE.txt */
+-(()=>{var __webpack_modules__={4:(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__)=>{(function(){if(!this.ST)return()=>{};with(this.ST)with(this.RH)with(this.G)return function(){"use strict";__webpack_require__.d(__webpack_exports__,{J:()=>r});var e=__webpack_require__(8464),t=__webpack_require__(4729);function r(){return(0,e.YP)((0,t.Yj)(),"SVG",(e=>!!e.includes("