@metamask/snaps-controllers 17.2.0 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/dist/multichain/MultichainRouter.cjs +33 -10
  3. package/dist/multichain/MultichainRouter.cjs.map +1 -1
  4. package/dist/multichain/MultichainRouter.d.cts +5 -7
  5. package/dist/multichain/MultichainRouter.d.cts.map +1 -1
  6. package/dist/multichain/MultichainRouter.d.mts +5 -7
  7. package/dist/multichain/MultichainRouter.d.mts.map +1 -1
  8. package/dist/multichain/MultichainRouter.mjs +34 -11
  9. package/dist/multichain/MultichainRouter.mjs.map +1 -1
  10. package/dist/services/AbstractExecutionService.cjs +5 -7
  11. package/dist/services/AbstractExecutionService.cjs.map +1 -1
  12. package/dist/services/AbstractExecutionService.d.cts +3 -2
  13. package/dist/services/AbstractExecutionService.d.cts.map +1 -1
  14. package/dist/services/AbstractExecutionService.d.mts +3 -2
  15. package/dist/services/AbstractExecutionService.d.mts.map +1 -1
  16. package/dist/services/AbstractExecutionService.mjs +5 -7
  17. package/dist/services/AbstractExecutionService.mjs.map +1 -1
  18. package/dist/services/iframe/IframeExecutionService.cjs +12 -2
  19. package/dist/services/iframe/IframeExecutionService.cjs.map +1 -1
  20. package/dist/services/iframe/IframeExecutionService.d.cts +1 -1
  21. package/dist/services/iframe/IframeExecutionService.d.cts.map +1 -1
  22. package/dist/services/iframe/IframeExecutionService.d.mts +1 -1
  23. package/dist/services/iframe/IframeExecutionService.d.mts.map +1 -1
  24. package/dist/services/iframe/IframeExecutionService.mjs +12 -2
  25. package/dist/services/iframe/IframeExecutionService.mjs.map +1 -1
  26. package/dist/services/node-js/NodeProcessExecutionService.cjs +1 -1
  27. package/dist/services/node-js/NodeProcessExecutionService.cjs.map +1 -1
  28. package/dist/services/node-js/NodeProcessExecutionService.d.cts +1 -1
  29. package/dist/services/node-js/NodeProcessExecutionService.d.cts.map +1 -1
  30. package/dist/services/node-js/NodeProcessExecutionService.d.mts +1 -1
  31. package/dist/services/node-js/NodeProcessExecutionService.d.mts.map +1 -1
  32. package/dist/services/node-js/NodeProcessExecutionService.mjs +1 -1
  33. package/dist/services/node-js/NodeProcessExecutionService.mjs.map +1 -1
  34. package/dist/services/webview/WebViewExecutionService.cjs +1 -1
  35. package/dist/services/webview/WebViewExecutionService.cjs.map +1 -1
  36. package/dist/services/webview/WebViewExecutionService.d.cts +1 -1
  37. package/dist/services/webview/WebViewExecutionService.d.cts.map +1 -1
  38. package/dist/services/webview/WebViewExecutionService.d.mts +1 -1
  39. package/dist/services/webview/WebViewExecutionService.d.mts.map +1 -1
  40. package/dist/services/webview/WebViewExecutionService.mjs +1 -1
  41. package/dist/services/webview/WebViewExecutionService.mjs.map +1 -1
  42. package/dist/snaps/SnapController.cjs +111 -26
  43. package/dist/snaps/SnapController.cjs.map +1 -1
  44. package/dist/snaps/SnapController.d.cts +10 -17
  45. package/dist/snaps/SnapController.d.cts.map +1 -1
  46. package/dist/snaps/SnapController.d.mts +10 -17
  47. package/dist/snaps/SnapController.d.mts.map +1 -1
  48. package/dist/snaps/SnapController.mjs +111 -26
  49. package/dist/snaps/SnapController.mjs.map +1 -1
  50. package/dist/utils.d.cts +1 -0
  51. package/dist/utils.d.cts.map +1 -1
  52. package/dist/utils.d.mts +1 -0
  53. package/dist/utils.d.mts.map +1 -1
  54. package/package.json +12 -11
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractExecutionService.cjs","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { JsonRpcEngine } from '@metamask/json-rpc-engine';\nimport { createStreamMiddleware } from '@metamask/json-rpc-middleware-stream';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport type { SnapRpcHookArgs } from '@metamask/snaps-utils';\nimport { SNAP_STREAM_NAMES, logError, logWarning } from '@metamask/snaps-utils';\nimport type {\n Json,\n JsonRpcError as JsonRpcErrorType,\n JsonRpcNotification,\n JsonRpcRequest,\n} from '@metamask/utils';\nimport {\n Duration,\n assertIsJsonRpcRequest,\n hasProperty,\n inMilliseconds,\n} from '@metamask/utils';\nimport { nanoid } from 'nanoid';\nimport { pipeline } from 'readable-stream';\nimport type { Duplex } from 'readable-stream';\n\nimport type {\n ExecutionService,\n ExecutionServiceMessenger,\n SnapErrorJson,\n SnapExecutionData,\n} from './ExecutionService';\nimport { log } from '../logging';\nimport { Timer } from '../snaps/Timer';\nimport { hasTimedOut, withTimeout } from '../utils';\n\nconst controllerName = 'ExecutionService';\n\nexport type SetupSnapProvider = (snapId: string, stream: Duplex) => void;\n\nexport type ExecutionServiceArgs = {\n setupSnapProvider: SetupSnapProvider;\n messenger: ExecutionServiceMessenger;\n initTimeout?: number;\n pingTimeout?: number;\n terminationTimeout?: number;\n usePing?: boolean;\n};\n\nexport type JobStreams = {\n command: Duplex;\n rpc: Duplex;\n _connection: BasePostMessageStream;\n};\n\nexport type Job<WorkerType> = {\n id: string;\n streams: JobStreams;\n rpcEngine: JsonRpcEngine;\n worker: WorkerType;\n};\n\nexport type TerminateJobArgs<WorkerType> = Partial<Job<WorkerType>> &\n Pick<Job<WorkerType>, 'id'>;\n\n/** \n Statuses used for diagnostic purposes\n - created: The initial state, no initialization has started \n - initializing: Snap execution environment is initializing\n - initialized: Snap execution environment has initialized\n - executing: Snap source code is being executed\n - running: Snap executed and ready for RPC requests\n */\ntype ExecutionStatus =\n | 'created'\n | 'initializing'\n | 'initialized'\n | 'executing'\n | 'running';\n\nexport abstract class AbstractExecutionService<WorkerType>\n implements ExecutionService\n{\n name: typeof controllerName = controllerName;\n\n state = null;\n\n readonly #jobs: Map<string, Job<WorkerType>>;\n\n readonly #status: Map<string, ExecutionStatus>;\n\n readonly #setupSnapProvider: SetupSnapProvider;\n\n readonly #messenger: ExecutionServiceMessenger;\n\n readonly #initTimeout: number;\n\n readonly #pingTimeout: number;\n\n readonly #terminationTimeout: number;\n\n readonly #usePing: boolean;\n\n constructor({\n setupSnapProvider,\n messenger,\n initTimeout = inMilliseconds(60, Duration.Second),\n pingTimeout = inMilliseconds(10, Duration.Second),\n terminationTimeout = inMilliseconds(1, Duration.Second),\n usePing = true,\n }: ExecutionServiceArgs) {\n this.#jobs = new Map();\n this.#status = new Map();\n this.#setupSnapProvider = setupSnapProvider;\n this.#messenger = messenger;\n this.#initTimeout = initTimeout;\n this.#pingTimeout = pingTimeout;\n this.#terminationTimeout = terminationTimeout;\n this.#usePing = usePing;\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.#messenger.registerActionHandler(\n `${controllerName}:handleRpcRequest`,\n async (snapId: string, options: SnapRpcHookArgs) =>\n this.handleRpcRequest(snapId, options),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:executeSnap`,\n async (data: SnapExecutionData) => this.executeSnap(data),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateSnap`,\n async (snapId: string) => this.terminateSnap(snapId),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateAllSnaps`,\n async () => this.terminateAllSnaps(),\n );\n }\n\n /**\n * Performs additional necessary work during job termination. **MUST** be\n * implemented by concrete implementations. See\n * {@link AbstractExecutionService.terminate} for details.\n *\n * @param job - The object corresponding to the job to be terminated.\n */\n protected abstract terminateJob(job: TerminateJobArgs<WorkerType>): void;\n\n /**\n * Terminates the Snap with the specified ID and deletes all its associated\n * data. Any subsequent messages targeting the Snap will fail with an error.\n * Throws an error if termination fails unexpectedly.\n *\n * @param snapId - The id of the Snap to be terminated.\n */\n public async terminateSnap(snapId: string): Promise<void> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n return;\n }\n\n try {\n // Ping worker and tell it to run teardown, continue with termination if it takes too long\n const result = await withTimeout(\n this.#command(snapId, {\n jsonrpc: '2.0',\n method: 'terminate',\n params: [],\n id: nanoid(),\n }),\n this.#terminationTimeout,\n );\n\n if (result === hasTimedOut || result !== 'OK') {\n logWarning(`Snap \"${snapId}\" failed to terminate gracefully.`);\n }\n } catch {\n // Ignore\n }\n\n Object.values(job.streams).forEach((stream) => {\n try {\n if (!stream.destroyed) {\n stream.destroy();\n }\n } catch (error) {\n logError('Error while destroying stream', error);\n }\n });\n\n this.terminateJob(job);\n\n this.#jobs.delete(snapId);\n this.#status.delete(snapId);\n log(`Snap \"${snapId}\" terminated.`);\n }\n\n /**\n * Initiates a job for a Snap.\n *\n * @param snapId - The ID of the Snap to initiate a job for.\n * @param timer - The timer to use for timeouts.\n * @returns Information regarding the created job.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initJob(snapId: string, timer: Timer): Promise<Job<WorkerType>> {\n const { streams, worker } = await this.#initStreams(snapId, timer);\n const rpcEngine = new JsonRpcEngine();\n\n const jsonRpcConnection = createStreamMiddleware();\n\n pipeline(\n jsonRpcConnection.stream,\n streams.command,\n jsonRpcConnection.stream,\n (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Command stream failure.`, error);\n }\n },\n );\n\n rpcEngine.push(jsonRpcConnection.middleware);\n\n const envMetadata = {\n id: snapId,\n streams,\n rpcEngine,\n worker,\n };\n this.#jobs.set(snapId, envMetadata);\n\n return envMetadata;\n }\n\n /**\n * Sets up the streams for an initiated job.\n *\n * @param snapId - The Snap ID.\n * @param timer - The timer to use for timeouts.\n * @returns The streams to communicate with the worker and the worker itself.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initStreams(\n snapId: string,\n timer: Timer,\n ): Promise<{ streams: JobStreams; worker: WorkerType }> {\n const result = await withTimeout(this.initEnvStream(snapId), timer);\n\n if (result === hasTimedOut) {\n // For certain environments, such as the iframe we may have already created the worker and wish to terminate it.\n this.terminateJob({ id: snapId });\n\n const status = this.#status.get(snapId);\n if (status === 'created') {\n // Currently this error can only be thrown by OffscreenExecutionService.\n throw new Error(\n `The executor for \"${snapId}\" couldn't start initialization. The offscreen document may not exist.`,\n );\n }\n throw new Error(\n `The executor for \"${snapId}\" failed to initialize. The iframe/webview/worker failed to load.`,\n );\n }\n\n const { worker, stream: envStream } = result;\n const mux = setupMultiplex(envStream, `Snap: \"${snapId}\"`);\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n\n // Handle out-of-band errors, i.e. errors thrown from the Snap outside of the req/res cycle.\n // Also keep track of outbound request/responses\n const notificationHandler = (\n message:\n | JsonRpcRequest\n | JsonRpcNotification<Json[] | Record<string, Json>>,\n ) => {\n if (hasProperty(message, 'id')) {\n return;\n }\n\n if (message.method === 'OutboundRequest') {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n } else if (message.method === 'OutboundResponse') {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n } else if (message.method === 'UnhandledError') {\n this.#messenger.publish(\n 'ExecutionService:unhandledError',\n snapId,\n (message.params as { error: SnapErrorJson }).error,\n );\n commandStream.removeListener('data', notificationHandler);\n } else {\n logError(\n new Error(\n `Received unexpected command stream notification \"${message.method}\".`,\n ),\n );\n }\n };\n\n commandStream.on('data', notificationHandler);\n\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n rpcStream.on('data', (chunk) => {\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n }\n });\n\n const originalWrite = rpcStream.write.bind(rpcStream);\n\n // @ts-expect-error Hack to inspect the messages being written to the stream.\n rpcStream.write = (chunk, encoding, callback) => {\n // Ignore chain switching notifications as it doesn't matter for the SnapProvider.\n if (chunk?.data?.method === 'metamask_chainChanged') {\n return true;\n }\n\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n }\n\n return originalWrite(chunk, encoding, callback);\n };\n\n // Typecast: stream type mismatch\n return {\n streams: {\n command: commandStream,\n rpc: rpcStream,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n _connection: envStream,\n },\n worker,\n };\n }\n\n /**\n * Abstract function implemented by implementing class that spins up a new worker for a job.\n *\n * Depending on the execution environment, this may run forever if the Snap fails to start up properly, therefore any call to this function should be wrapped in a timeout.\n */\n protected abstract initEnvStream(snapId: string): Promise<{\n worker: WorkerType;\n stream: BasePostMessageStream;\n }>;\n\n /**\n * Set the execution status of the Snap.\n *\n * @param snapId - The Snap ID.\n * @param status - The current execution status.\n */\n protected setSnapStatus(snapId: string, status: ExecutionStatus) {\n this.#status.set(snapId, status);\n }\n\n async terminateAllSnaps() {\n await Promise.all(\n [...this.#jobs.keys()].map(async (snapId) => this.terminateSnap(snapId)),\n );\n }\n\n /**\n * Initializes and executes a Snap, setting up the communication channels to the Snap etc.\n *\n * @param snapData - Data needed for Snap execution.\n * @param snapData.snapId - The ID of the Snap to execute.\n * @param snapData.sourceCode - The source code of the Snap to execute.\n * @param snapData.endowments - The endowments available to the executing Snap.\n * @returns A string `OK` if execution succeeded.\n * @throws If the execution service returns an error or execution times out.\n */\n async executeSnap({\n snapId,\n sourceCode,\n endowments,\n }: SnapExecutionData): Promise<string> {\n if (this.#jobs.has(snapId)) {\n throw new Error(`\"${snapId}\" is already running.`);\n }\n\n this.setSnapStatus(snapId, 'created');\n\n const timer = new Timer(this.#initTimeout);\n\n // This may resolve even if the environment has failed to start up fully\n const job = await this.#initJob(snapId, timer);\n\n // Certain environments use ping as part of their initialization and thus can skip it here\n if (this.#usePing) {\n // Ping the worker to ensure that it started up\n const pingResult = await withTimeout(\n this.#command(job.id, {\n jsonrpc: '2.0',\n method: 'ping',\n id: nanoid(),\n }),\n this.#pingTimeout,\n );\n\n if (pingResult === hasTimedOut) {\n throw new Error(\n `The executor for \"${snapId}\" was unreachable. The executor did not respond in time.`,\n );\n }\n }\n\n const rpcStream = job.streams.rpc;\n\n this.#setupSnapProvider(snapId, rpcStream);\n\n // Use the remaining time as the timer, but ensure that the\n // Snap gets at least half the init timeout.\n const remainingTime = Math.max(timer.remaining, this.#initTimeout / 2);\n\n this.setSnapStatus(snapId, 'initialized');\n\n const request = {\n jsonrpc: '2.0',\n method: 'executeSnap',\n params: { snapId, sourceCode, endowments },\n id: nanoid(),\n };\n\n assertIsJsonRpcRequest(request);\n\n this.setSnapStatus(snapId, 'executing');\n\n const result = await withTimeout(\n this.#command(job.id, request),\n remainingTime,\n );\n\n if (result === hasTimedOut) {\n throw new Error(`${snapId} failed to start.`);\n }\n\n if (result === 'OK') {\n this.setSnapStatus(snapId, 'running');\n }\n\n return result as string;\n }\n\n async #command(\n snapId: string,\n message: JsonRpcRequest,\n ): Promise<Json | undefined> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n throw new Error(`\"${snapId}\" is not currently running.`);\n }\n\n log('Parent: Sending Command', message);\n const response = await job.rpcEngine.handle(message);\n\n // We don't need full validation of the response here because we control it.\n if (hasProperty(response, 'error')) {\n const error = response.error as JsonRpcErrorType;\n throw new JsonRpcError(error.code, error.message, error.data);\n }\n\n return response.result;\n }\n\n /**\n * Handle RPC request.\n *\n * @param snapId - The ID of the recipient Snap.\n * @param options - Bag of options to pass to the RPC handler.\n * @returns Promise that can handle the request.\n */\n public async handleRpcRequest(\n snapId: string,\n options: SnapRpcHookArgs,\n ): Promise<unknown> {\n const { handler, request, origin } = options;\n\n return await this.#command(snapId, {\n id: nanoid(),\n jsonrpc: '2.0',\n method: 'snapRpc',\n params: {\n origin,\n handler,\n request: request as JsonRpcRequest,\n target: snapId,\n },\n });\n }\n}\n\n/**\n * Sets up stream multiplexing for the given stream.\n *\n * @param connectionStream - The stream to mux.\n * @param streamName - The name of the stream, for identification in errors.\n * @returns The multiplexed stream.\n */\nexport function setupMultiplex(\n connectionStream: Duplex,\n streamName: string,\n): ObjectMultiplex {\n const mux = new ObjectMultiplex();\n pipeline(connectionStream, mux, connectionStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`\"${streamName}\" stream failure.`, error);\n }\n });\n return mux;\n}\n"]}
1
+ {"version":3,"file":"AbstractExecutionService.cjs","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { JsonRpcEngine } from '@metamask/json-rpc-engine';\nimport { createStreamMiddleware } from '@metamask/json-rpc-middleware-stream';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport type { SnapRpcHookArgs } from '@metamask/snaps-utils';\nimport { SNAP_STREAM_NAMES, logError, logWarning } from '@metamask/snaps-utils';\nimport type {\n Json,\n JsonRpcError as JsonRpcErrorType,\n JsonRpcNotification,\n JsonRpcRequest,\n} from '@metamask/utils';\nimport {\n Duration,\n assertIsJsonRpcRequest,\n hasProperty,\n inMilliseconds,\n} from '@metamask/utils';\nimport { nanoid } from 'nanoid';\nimport { pipeline } from 'readable-stream';\nimport type { Duplex } from 'readable-stream';\n\nimport type {\n ExecutionService,\n ExecutionServiceMessenger,\n SnapErrorJson,\n SnapExecutionData,\n} from './ExecutionService';\nimport { log } from '../logging';\nimport { Timer } from '../snaps/Timer';\nimport { hasTimedOut, withTimeout } from '../utils';\n\nconst controllerName = 'ExecutionService';\n\nexport type SetupSnapProvider = (snapId: string, stream: Duplex) => void;\n\nexport type ExecutionServiceArgs = {\n setupSnapProvider: SetupSnapProvider;\n messenger: ExecutionServiceMessenger;\n initTimeout?: number;\n pingTimeout?: number;\n terminationTimeout?: number;\n usePing?: boolean;\n};\n\nexport type JobStreams = {\n command: Duplex;\n rpc: Duplex;\n connection: BasePostMessageStream;\n mux: ObjectMultiplex;\n};\n\nexport type Job<WorkerType> = {\n id: string;\n streams: JobStreams;\n rpcEngine: JsonRpcEngine;\n worker: WorkerType;\n};\n\nexport type TerminateJobArgs<WorkerType> = Partial<Job<WorkerType>> &\n Pick<Job<WorkerType>, 'id'>;\n\n/** \n Statuses used for diagnostic purposes\n - created: The initial state, no initialization has started \n - initializing: Snap execution environment is initializing\n - initialized: Snap execution environment has initialized\n - executing: Snap source code is being executed\n - running: Snap executed and ready for RPC requests\n */\ntype ExecutionStatus =\n | 'created'\n | 'initializing'\n | 'initialized'\n | 'executing'\n | 'running';\n\nexport abstract class AbstractExecutionService<WorkerType>\n implements ExecutionService\n{\n name: typeof controllerName = controllerName;\n\n state = null;\n\n readonly #jobs: Map<string, Job<WorkerType>>;\n\n readonly #status: Map<string, ExecutionStatus>;\n\n readonly #setupSnapProvider: SetupSnapProvider;\n\n readonly #messenger: ExecutionServiceMessenger;\n\n readonly #initTimeout: number;\n\n readonly #pingTimeout: number;\n\n readonly #terminationTimeout: number;\n\n readonly #usePing: boolean;\n\n constructor({\n setupSnapProvider,\n messenger,\n initTimeout = inMilliseconds(60, Duration.Second),\n pingTimeout = inMilliseconds(10, Duration.Second),\n terminationTimeout = inMilliseconds(1, Duration.Second),\n usePing = true,\n }: ExecutionServiceArgs) {\n this.#jobs = new Map();\n this.#status = new Map();\n this.#setupSnapProvider = setupSnapProvider;\n this.#messenger = messenger;\n this.#initTimeout = initTimeout;\n this.#pingTimeout = pingTimeout;\n this.#terminationTimeout = terminationTimeout;\n this.#usePing = usePing;\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.#messenger.registerActionHandler(\n `${controllerName}:handleRpcRequest`,\n async (snapId: string, options: SnapRpcHookArgs) =>\n this.handleRpcRequest(snapId, options),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:executeSnap`,\n async (data: SnapExecutionData) => this.executeSnap(data),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateSnap`,\n async (snapId: string) => this.terminateSnap(snapId),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateAllSnaps`,\n async () => this.terminateAllSnaps(),\n );\n }\n\n /**\n * Performs additional necessary work during job termination. **MUST** be\n * implemented by concrete implementations. See\n * {@link AbstractExecutionService.terminate} for details.\n *\n * @param job - The object corresponding to the job to be terminated.\n */\n protected abstract terminateJob(\n job: TerminateJobArgs<WorkerType>,\n ): Promise<void>;\n\n /**\n * Terminates the Snap with the specified ID and deletes all its associated\n * data. Any subsequent messages targeting the Snap will fail with an error.\n * Throws an error if termination fails unexpectedly.\n *\n * @param snapId - The id of the Snap to be terminated.\n */\n public async terminateSnap(snapId: string): Promise<void> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n return;\n }\n\n try {\n // Ping worker and tell it to run teardown, continue with termination if it takes too long\n const result = await withTimeout(\n this.#command(snapId, {\n jsonrpc: '2.0',\n method: 'terminate',\n id: nanoid(),\n }),\n this.#terminationTimeout,\n );\n\n if (result === hasTimedOut || result !== 'OK') {\n logWarning(`Snap \"${snapId}\" failed to terminate gracefully.`);\n }\n } catch {\n // Ignore\n }\n\n Object.values(job.streams).forEach((stream) => {\n try {\n if (!stream.destroyed) {\n stream.destroy();\n }\n } catch (error) {\n logError('Error while destroying stream', error);\n }\n });\n\n await this.terminateJob(job);\n\n this.#jobs.delete(snapId);\n this.#status.delete(snapId);\n log(`Snap \"${snapId}\" terminated.`);\n }\n\n /**\n * Initiates a job for a Snap.\n *\n * @param snapId - The ID of the Snap to initiate a job for.\n * @param timer - The timer to use for timeouts.\n * @returns Information regarding the created job.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initJob(snapId: string, timer: Timer): Promise<Job<WorkerType>> {\n const { streams, worker } = await this.#initStreams(snapId, timer);\n const rpcEngine = new JsonRpcEngine();\n\n const jsonRpcConnection = createStreamMiddleware();\n\n pipeline(\n jsonRpcConnection.stream,\n streams.command,\n jsonRpcConnection.stream,\n (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Command stream failure.`, error);\n }\n },\n );\n\n rpcEngine.push(jsonRpcConnection.middleware);\n\n const envMetadata = {\n id: snapId,\n streams,\n rpcEngine,\n worker,\n };\n this.#jobs.set(snapId, envMetadata);\n\n return envMetadata;\n }\n\n /**\n * Sets up the streams for an initiated job.\n *\n * @param snapId - The Snap ID.\n * @param timer - The timer to use for timeouts.\n * @returns The streams to communicate with the worker and the worker itself.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initStreams(\n snapId: string,\n timer: Timer,\n ): Promise<{ streams: JobStreams; worker: WorkerType }> {\n const result = await withTimeout(this.initEnvStream(snapId), timer);\n\n if (result === hasTimedOut) {\n // For certain environments, such as the iframe we may have already created the worker and wish to terminate it.\n await this.terminateJob({ id: snapId });\n\n const status = this.#status.get(snapId);\n if (status === 'created') {\n // Currently this error can only be thrown by OffscreenExecutionService.\n throw new Error(\n `The executor for \"${snapId}\" couldn't start initialization. The offscreen document may not exist.`,\n );\n }\n throw new Error(\n `The executor for \"${snapId}\" failed to initialize. The iframe/webview/worker failed to load.`,\n );\n }\n\n const { worker, stream: envStream } = result;\n const mux = setupMultiplex(envStream, `Snap: \"${snapId}\"`);\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n\n // Handle out-of-band errors, i.e. errors thrown from the Snap outside of the req/res cycle.\n // Also keep track of outbound request/responses\n const notificationHandler = (\n message:\n | JsonRpcRequest\n | JsonRpcNotification<Json[] | Record<string, Json>>,\n ) => {\n if (hasProperty(message, 'id')) {\n return;\n }\n\n if (message.method === 'OutboundRequest') {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n } else if (message.method === 'OutboundResponse') {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n } else if (message.method === 'UnhandledError') {\n this.#messenger.publish(\n 'ExecutionService:unhandledError',\n snapId,\n (message.params as { error: SnapErrorJson }).error,\n );\n commandStream.removeListener('data', notificationHandler);\n } else {\n logError(\n new Error(\n `Received unexpected command stream notification \"${message.method}\".`,\n ),\n );\n }\n };\n\n commandStream.on('data', notificationHandler);\n\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n rpcStream.on('data', (chunk) => {\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n }\n });\n\n const originalWrite = rpcStream.write.bind(rpcStream);\n\n // @ts-expect-error Hack to inspect the messages being written to the stream.\n rpcStream.write = (chunk, encoding, callback) => {\n // Ignore chain switching notifications as it doesn't matter for the SnapProvider.\n if (chunk?.data?.method === 'metamask_chainChanged') {\n return true;\n }\n\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n }\n\n return originalWrite(chunk, encoding, callback);\n };\n\n return {\n streams: {\n command: commandStream,\n rpc: rpcStream,\n connection: envStream,\n mux,\n },\n worker,\n };\n }\n\n /**\n * Abstract function implemented by implementing class that spins up a new worker for a job.\n *\n * Depending on the execution environment, this may run forever if the Snap fails to start up properly, therefore any call to this function should be wrapped in a timeout.\n */\n protected abstract initEnvStream(snapId: string): Promise<{\n worker: WorkerType;\n stream: BasePostMessageStream;\n }>;\n\n /**\n * Set the execution status of the Snap.\n *\n * @param snapId - The Snap ID.\n * @param status - The current execution status.\n */\n protected setSnapStatus(snapId: string, status: ExecutionStatus) {\n this.#status.set(snapId, status);\n }\n\n async terminateAllSnaps() {\n await Promise.all(\n [...this.#jobs.keys()].map(async (snapId) => this.terminateSnap(snapId)),\n );\n }\n\n /**\n * Initializes and executes a Snap, setting up the communication channels to the Snap etc.\n *\n * @param snapData - Data needed for Snap execution.\n * @param snapData.snapId - The ID of the Snap to execute.\n * @param snapData.sourceCode - The source code of the Snap to execute.\n * @param snapData.endowments - The endowments available to the executing Snap.\n * @returns A string `OK` if execution succeeded.\n * @throws If the execution service returns an error or execution times out.\n */\n async executeSnap({\n snapId,\n sourceCode,\n endowments,\n }: SnapExecutionData): Promise<string> {\n if (this.#jobs.has(snapId)) {\n throw new Error(`\"${snapId}\" is already running.`);\n }\n\n this.setSnapStatus(snapId, 'created');\n\n const timer = new Timer(this.#initTimeout);\n\n // This may resolve even if the environment has failed to start up fully\n const job = await this.#initJob(snapId, timer);\n\n // Certain environments use ping as part of their initialization and thus can skip it here\n if (this.#usePing) {\n // Ping the worker to ensure that it started up\n const pingResult = await withTimeout(\n this.#command(job.id, {\n jsonrpc: '2.0',\n method: 'ping',\n id: nanoid(),\n }),\n this.#pingTimeout,\n );\n\n if (pingResult === hasTimedOut) {\n throw new Error(\n `The executor for \"${snapId}\" was unreachable. The executor did not respond in time.`,\n );\n }\n }\n\n const rpcStream = job.streams.rpc;\n\n this.#setupSnapProvider(snapId, rpcStream);\n\n // Use the remaining time as the timer, but ensure that the\n // Snap gets at least half the init timeout.\n const remainingTime = Math.max(timer.remaining, this.#initTimeout / 2);\n\n this.setSnapStatus(snapId, 'initialized');\n\n const request = {\n jsonrpc: '2.0',\n method: 'executeSnap',\n params: { snapId, sourceCode, endowments },\n id: nanoid(),\n };\n\n assertIsJsonRpcRequest(request);\n\n this.setSnapStatus(snapId, 'executing');\n\n const result = await withTimeout(\n this.#command(job.id, request),\n remainingTime,\n );\n\n if (result === hasTimedOut) {\n throw new Error(`${snapId} failed to start.`);\n }\n\n if (result === 'OK') {\n this.setSnapStatus(snapId, 'running');\n }\n\n return result as string;\n }\n\n async #command(\n snapId: string,\n message: JsonRpcRequest,\n ): Promise<Json | undefined> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n throw new Error(`\"${snapId}\" is not currently running.`);\n }\n\n log('Parent: Sending Command', message);\n const response = await job.rpcEngine.handle(message);\n\n // We don't need full validation of the response here because we control it.\n if (hasProperty(response, 'error')) {\n const error = response.error as JsonRpcErrorType;\n throw new JsonRpcError(error.code, error.message, error.data);\n }\n\n return response.result;\n }\n\n /**\n * Handle RPC request.\n *\n * @param snapId - The ID of the recipient Snap.\n * @param options - Bag of options to pass to the RPC handler.\n * @returns Promise that can handle the request.\n */\n public async handleRpcRequest(\n snapId: string,\n options: SnapRpcHookArgs,\n ): Promise<unknown> {\n const { handler, request, origin } = options;\n\n return await this.#command(snapId, {\n id: nanoid(),\n jsonrpc: '2.0',\n method: 'snapRpc',\n params: {\n snapId,\n origin,\n handler,\n request: request as JsonRpcRequest,\n },\n });\n }\n}\n\n/**\n * Sets up stream multiplexing for the given stream.\n *\n * @param connectionStream - The stream to mux.\n * @param streamName - The name of the stream, for identification in errors.\n * @returns The multiplexed stream.\n */\nexport function setupMultiplex(\n connectionStream: Duplex,\n streamName: string,\n): ObjectMultiplex {\n const mux = new ObjectMultiplex();\n pipeline(connectionStream, mux, connectionStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`\"${streamName}\" stream failure.`, error);\n }\n });\n return mux;\n}\n"]}
@@ -17,7 +17,8 @@ export type ExecutionServiceArgs = {
17
17
  export type JobStreams = {
18
18
  command: Duplex;
19
19
  rpc: Duplex;
20
- _connection: BasePostMessageStream;
20
+ connection: BasePostMessageStream;
21
+ mux: ObjectMultiplex;
21
22
  };
22
23
  export type Job<WorkerType> = {
23
24
  id: string;
@@ -47,7 +48,7 @@ export declare abstract class AbstractExecutionService<WorkerType> implements Ex
47
48
  *
48
49
  * @param job - The object corresponding to the job to be terminated.
49
50
  */
50
- protected abstract terminateJob(job: TerminateJobArgs<WorkerType>): void;
51
+ protected abstract terminateJob(job: TerminateJobArgs<WorkerType>): Promise<void>;
51
52
  /**
52
53
  * Terminates the Snap with the specified ID and deletes all its associated
53
54
  * data. Any subsequent messages targeting the Snap will fail with an error.
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractExecutionService.d.cts","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kCAAkC;AAE1D,OAAO,eAAe,mCAAmC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAgB7D,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AAE9C,OAAO,KAAK,EACV,gBAAgB,EAChB,yBAAyB,EAEzB,iBAAiB,EAClB,+BAA2B;AAK5B,QAAA,MAAM,cAAc,qBAAqB,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,SAAS,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,qBAAqB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,UAAU,IAAI;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GACjE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;AAE9B;;;;;;;GAOG;AACH,KAAK,eAAe,GAChB,SAAS,GACT,cAAc,GACd,aAAa,GACb,WAAW,GACX,SAAS,CAAC;AAEd,8BAAsB,wBAAwB,CAAC,UAAU,CACvD,YAAW,gBAAgB;;IAE3B,IAAI,EAAE,OAAO,cAAc,CAAkB;IAE7C,KAAK,OAAQ;gBAkBD,EACV,iBAAiB,EACjB,SAAS,EACT,WAAiD,EACjD,WAAiD,EACjD,kBAAuD,EACvD,OAAc,GACf,EAAE,oBAAoB;IAwCvB;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,IAAI;IAExE;;;;;;OAMG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuLzD;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACxD,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;IAEF;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe;IAIzD,iBAAiB;IAMvB;;;;;;;;;OASG;IACG,WAAW,CAAC,EAChB,MAAM,EACN,UAAU,EACV,UAAU,GACX,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAyFtC;;;;;;OAMG;IACU,gBAAgB,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,OAAO,CAAC;CAepB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,MAAM,EACxB,UAAU,EAAE,MAAM,GACjB,eAAe,CAQjB"}
1
+ {"version":3,"file":"AbstractExecutionService.d.cts","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kCAAkC;AAE1D,OAAO,eAAe,mCAAmC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAgB7D,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AAE9C,OAAO,KAAK,EACV,gBAAgB,EAChB,yBAAyB,EAEzB,iBAAiB,EAClB,+BAA2B;AAK5B,QAAA,MAAM,cAAc,qBAAqB,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,SAAS,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,qBAAqB,CAAC;IAClC,GAAG,EAAE,eAAe,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,UAAU,IAAI;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GACjE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;AAE9B;;;;;;;GAOG;AACH,KAAK,eAAe,GAChB,SAAS,GACT,cAAc,GACd,aAAa,GACb,WAAW,GACX,SAAS,CAAC;AAEd,8BAAsB,wBAAwB,CAAC,UAAU,CACvD,YAAW,gBAAgB;;IAE3B,IAAI,EAAE,OAAO,cAAc,CAAkB;IAE7C,KAAK,OAAQ;gBAkBD,EACV,iBAAiB,EACjB,SAAS,EACT,WAAiD,EACjD,WAAiD,EACjD,kBAAuD,EACvD,OAAc,GACf,EAAE,oBAAoB;IAwCvB;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,CAC7B,GAAG,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC;IAEhB;;;;;;OAMG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqLzD;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACxD,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;IAEF;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe;IAIzD,iBAAiB;IAMvB;;;;;;;;;OASG;IACG,WAAW,CAAC,EAChB,MAAM,EACN,UAAU,EACV,UAAU,GACX,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAyFtC;;;;;;OAMG;IACU,gBAAgB,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,OAAO,CAAC;CAepB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,MAAM,EACxB,UAAU,EAAE,MAAM,GACjB,eAAe,CAQjB"}
@@ -17,7 +17,8 @@ export type ExecutionServiceArgs = {
17
17
  export type JobStreams = {
18
18
  command: Duplex;
19
19
  rpc: Duplex;
20
- _connection: BasePostMessageStream;
20
+ connection: BasePostMessageStream;
21
+ mux: ObjectMultiplex;
21
22
  };
22
23
  export type Job<WorkerType> = {
23
24
  id: string;
@@ -47,7 +48,7 @@ export declare abstract class AbstractExecutionService<WorkerType> implements Ex
47
48
  *
48
49
  * @param job - The object corresponding to the job to be terminated.
49
50
  */
50
- protected abstract terminateJob(job: TerminateJobArgs<WorkerType>): void;
51
+ protected abstract terminateJob(job: TerminateJobArgs<WorkerType>): Promise<void>;
51
52
  /**
52
53
  * Terminates the Snap with the specified ID and deletes all its associated
53
54
  * data. Any subsequent messages targeting the Snap will fail with an error.
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractExecutionService.d.mts","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kCAAkC;AAE1D,OAAO,eAAe,mCAAmC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAgB7D,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AAE9C,OAAO,KAAK,EACV,gBAAgB,EAChB,yBAAyB,EAEzB,iBAAiB,EAClB,+BAA2B;AAK5B,QAAA,MAAM,cAAc,qBAAqB,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,SAAS,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,qBAAqB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,UAAU,IAAI;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GACjE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;AAE9B;;;;;;;GAOG;AACH,KAAK,eAAe,GAChB,SAAS,GACT,cAAc,GACd,aAAa,GACb,WAAW,GACX,SAAS,CAAC;AAEd,8BAAsB,wBAAwB,CAAC,UAAU,CACvD,YAAW,gBAAgB;;IAE3B,IAAI,EAAE,OAAO,cAAc,CAAkB;IAE7C,KAAK,OAAQ;gBAkBD,EACV,iBAAiB,EACjB,SAAS,EACT,WAAiD,EACjD,WAAiD,EACjD,kBAAuD,EACvD,OAAc,GACf,EAAE,oBAAoB;IAwCvB;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,IAAI;IAExE;;;;;;OAMG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuLzD;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACxD,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;IAEF;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe;IAIzD,iBAAiB;IAMvB;;;;;;;;;OASG;IACG,WAAW,CAAC,EAChB,MAAM,EACN,UAAU,EACV,UAAU,GACX,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAyFtC;;;;;;OAMG;IACU,gBAAgB,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,OAAO,CAAC;CAepB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,MAAM,EACxB,UAAU,EAAE,MAAM,GACjB,eAAe,CAQjB"}
1
+ {"version":3,"file":"AbstractExecutionService.d.mts","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kCAAkC;AAE1D,OAAO,eAAe,mCAAmC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAgB7D,OAAO,KAAK,EAAE,MAAM,EAAE,wBAAwB;AAE9C,OAAO,KAAK,EACV,gBAAgB,EAChB,yBAAyB,EAEzB,iBAAiB,EAClB,+BAA2B;AAK5B,QAAA,MAAM,cAAc,qBAAqB,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,SAAS,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,qBAAqB,CAAC;IAClC,GAAG,EAAE,eAAe,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,UAAU,IAAI;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GACjE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;AAE9B;;;;;;;GAOG;AACH,KAAK,eAAe,GAChB,SAAS,GACT,cAAc,GACd,aAAa,GACb,WAAW,GACX,SAAS,CAAC;AAEd,8BAAsB,wBAAwB,CAAC,UAAU,CACvD,YAAW,gBAAgB;;IAE3B,IAAI,EAAE,OAAO,cAAc,CAAkB;IAE7C,KAAK,OAAQ;gBAkBD,EACV,iBAAiB,EACjB,SAAS,EACT,WAAiD,EACjD,WAAiD,EACjD,kBAAuD,EACvD,OAAc,GACf,EAAE,oBAAoB;IAwCvB;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,CAC7B,GAAG,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC;IAEhB;;;;;;OAMG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqLzD;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACxD,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;IAEF;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe;IAIzD,iBAAiB;IAMvB;;;;;;;;;OASG;IACG,WAAW,CAAC,EAChB,MAAM,EACN,UAAU,EACV,UAAU,GACX,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAyFtC;;;;;;OAMG;IACU,gBAAgB,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,OAAO,CAAC;CAepB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,MAAM,EACxB,UAAU,EAAE,MAAM,GACjB,eAAe,CAQjB"}
@@ -66,7 +66,6 @@ export class AbstractExecutionService {
66
66
  const result = await withTimeout(this.#command(snapId, {
67
67
  jsonrpc: '2.0',
68
68
  method: 'terminate',
69
- params: [],
70
69
  id: nanoid(),
71
70
  }), this.#terminationTimeout);
72
71
  if (result === hasTimedOut || result !== 'OK') {
@@ -86,7 +85,7 @@ export class AbstractExecutionService {
86
85
  logError('Error while destroying stream', error);
87
86
  }
88
87
  });
89
- this.terminateJob(job);
88
+ await this.terminateJob(job);
90
89
  this.#jobs.delete(snapId);
91
90
  this.#status.delete(snapId);
92
91
  log(`Snap "${snapId}" terminated.`);
@@ -130,7 +129,7 @@ export class AbstractExecutionService {
130
129
  const result = await withTimeout(this.initEnvStream(snapId), timer);
131
130
  if (result === hasTimedOut) {
132
131
  // For certain environments, such as the iframe we may have already created the worker and wish to terminate it.
133
- this.terminateJob({ id: snapId });
132
+ await this.terminateJob({ id: snapId });
134
133
  const status = this.#status.get(snapId);
135
134
  if (status === 'created') {
136
135
  // Currently this error can only be thrown by OffscreenExecutionService.
@@ -180,13 +179,12 @@ export class AbstractExecutionService {
180
179
  }
181
180
  return originalWrite(chunk, encoding, callback);
182
181
  };
183
- // Typecast: stream type mismatch
184
182
  return {
185
183
  streams: {
186
184
  command: commandStream,
187
185
  rpc: rpcStream,
188
- // eslint-disable-next-line @typescript-eslint/naming-convention
189
- _connection: envStream,
186
+ connection: envStream,
187
+ mux,
190
188
  },
191
189
  worker,
192
190
  };
@@ -284,10 +282,10 @@ export class AbstractExecutionService {
284
282
  jsonrpc: '2.0',
285
283
  method: 'snapRpc',
286
284
  params: {
285
+ snapId,
287
286
  origin,
288
287
  handler,
289
288
  request: request,
290
- target: snapId,
291
289
  },
292
290
  });
293
291
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractExecutionService.mjs","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { JsonRpcEngine } from '@metamask/json-rpc-engine';\nimport { createStreamMiddleware } from '@metamask/json-rpc-middleware-stream';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport type { SnapRpcHookArgs } from '@metamask/snaps-utils';\nimport { SNAP_STREAM_NAMES, logError, logWarning } from '@metamask/snaps-utils';\nimport type {\n Json,\n JsonRpcError as JsonRpcErrorType,\n JsonRpcNotification,\n JsonRpcRequest,\n} from '@metamask/utils';\nimport {\n Duration,\n assertIsJsonRpcRequest,\n hasProperty,\n inMilliseconds,\n} from '@metamask/utils';\nimport { nanoid } from 'nanoid';\nimport { pipeline } from 'readable-stream';\nimport type { Duplex } from 'readable-stream';\n\nimport type {\n ExecutionService,\n ExecutionServiceMessenger,\n SnapErrorJson,\n SnapExecutionData,\n} from './ExecutionService';\nimport { log } from '../logging';\nimport { Timer } from '../snaps/Timer';\nimport { hasTimedOut, withTimeout } from '../utils';\n\nconst controllerName = 'ExecutionService';\n\nexport type SetupSnapProvider = (snapId: string, stream: Duplex) => void;\n\nexport type ExecutionServiceArgs = {\n setupSnapProvider: SetupSnapProvider;\n messenger: ExecutionServiceMessenger;\n initTimeout?: number;\n pingTimeout?: number;\n terminationTimeout?: number;\n usePing?: boolean;\n};\n\nexport type JobStreams = {\n command: Duplex;\n rpc: Duplex;\n _connection: BasePostMessageStream;\n};\n\nexport type Job<WorkerType> = {\n id: string;\n streams: JobStreams;\n rpcEngine: JsonRpcEngine;\n worker: WorkerType;\n};\n\nexport type TerminateJobArgs<WorkerType> = Partial<Job<WorkerType>> &\n Pick<Job<WorkerType>, 'id'>;\n\n/** \n Statuses used for diagnostic purposes\n - created: The initial state, no initialization has started \n - initializing: Snap execution environment is initializing\n - initialized: Snap execution environment has initialized\n - executing: Snap source code is being executed\n - running: Snap executed and ready for RPC requests\n */\ntype ExecutionStatus =\n | 'created'\n | 'initializing'\n | 'initialized'\n | 'executing'\n | 'running';\n\nexport abstract class AbstractExecutionService<WorkerType>\n implements ExecutionService\n{\n name: typeof controllerName = controllerName;\n\n state = null;\n\n readonly #jobs: Map<string, Job<WorkerType>>;\n\n readonly #status: Map<string, ExecutionStatus>;\n\n readonly #setupSnapProvider: SetupSnapProvider;\n\n readonly #messenger: ExecutionServiceMessenger;\n\n readonly #initTimeout: number;\n\n readonly #pingTimeout: number;\n\n readonly #terminationTimeout: number;\n\n readonly #usePing: boolean;\n\n constructor({\n setupSnapProvider,\n messenger,\n initTimeout = inMilliseconds(60, Duration.Second),\n pingTimeout = inMilliseconds(10, Duration.Second),\n terminationTimeout = inMilliseconds(1, Duration.Second),\n usePing = true,\n }: ExecutionServiceArgs) {\n this.#jobs = new Map();\n this.#status = new Map();\n this.#setupSnapProvider = setupSnapProvider;\n this.#messenger = messenger;\n this.#initTimeout = initTimeout;\n this.#pingTimeout = pingTimeout;\n this.#terminationTimeout = terminationTimeout;\n this.#usePing = usePing;\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.#messenger.registerActionHandler(\n `${controllerName}:handleRpcRequest`,\n async (snapId: string, options: SnapRpcHookArgs) =>\n this.handleRpcRequest(snapId, options),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:executeSnap`,\n async (data: SnapExecutionData) => this.executeSnap(data),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateSnap`,\n async (snapId: string) => this.terminateSnap(snapId),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateAllSnaps`,\n async () => this.terminateAllSnaps(),\n );\n }\n\n /**\n * Performs additional necessary work during job termination. **MUST** be\n * implemented by concrete implementations. See\n * {@link AbstractExecutionService.terminate} for details.\n *\n * @param job - The object corresponding to the job to be terminated.\n */\n protected abstract terminateJob(job: TerminateJobArgs<WorkerType>): void;\n\n /**\n * Terminates the Snap with the specified ID and deletes all its associated\n * data. Any subsequent messages targeting the Snap will fail with an error.\n * Throws an error if termination fails unexpectedly.\n *\n * @param snapId - The id of the Snap to be terminated.\n */\n public async terminateSnap(snapId: string): Promise<void> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n return;\n }\n\n try {\n // Ping worker and tell it to run teardown, continue with termination if it takes too long\n const result = await withTimeout(\n this.#command(snapId, {\n jsonrpc: '2.0',\n method: 'terminate',\n params: [],\n id: nanoid(),\n }),\n this.#terminationTimeout,\n );\n\n if (result === hasTimedOut || result !== 'OK') {\n logWarning(`Snap \"${snapId}\" failed to terminate gracefully.`);\n }\n } catch {\n // Ignore\n }\n\n Object.values(job.streams).forEach((stream) => {\n try {\n if (!stream.destroyed) {\n stream.destroy();\n }\n } catch (error) {\n logError('Error while destroying stream', error);\n }\n });\n\n this.terminateJob(job);\n\n this.#jobs.delete(snapId);\n this.#status.delete(snapId);\n log(`Snap \"${snapId}\" terminated.`);\n }\n\n /**\n * Initiates a job for a Snap.\n *\n * @param snapId - The ID of the Snap to initiate a job for.\n * @param timer - The timer to use for timeouts.\n * @returns Information regarding the created job.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initJob(snapId: string, timer: Timer): Promise<Job<WorkerType>> {\n const { streams, worker } = await this.#initStreams(snapId, timer);\n const rpcEngine = new JsonRpcEngine();\n\n const jsonRpcConnection = createStreamMiddleware();\n\n pipeline(\n jsonRpcConnection.stream,\n streams.command,\n jsonRpcConnection.stream,\n (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Command stream failure.`, error);\n }\n },\n );\n\n rpcEngine.push(jsonRpcConnection.middleware);\n\n const envMetadata = {\n id: snapId,\n streams,\n rpcEngine,\n worker,\n };\n this.#jobs.set(snapId, envMetadata);\n\n return envMetadata;\n }\n\n /**\n * Sets up the streams for an initiated job.\n *\n * @param snapId - The Snap ID.\n * @param timer - The timer to use for timeouts.\n * @returns The streams to communicate with the worker and the worker itself.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initStreams(\n snapId: string,\n timer: Timer,\n ): Promise<{ streams: JobStreams; worker: WorkerType }> {\n const result = await withTimeout(this.initEnvStream(snapId), timer);\n\n if (result === hasTimedOut) {\n // For certain environments, such as the iframe we may have already created the worker and wish to terminate it.\n this.terminateJob({ id: snapId });\n\n const status = this.#status.get(snapId);\n if (status === 'created') {\n // Currently this error can only be thrown by OffscreenExecutionService.\n throw new Error(\n `The executor for \"${snapId}\" couldn't start initialization. The offscreen document may not exist.`,\n );\n }\n throw new Error(\n `The executor for \"${snapId}\" failed to initialize. The iframe/webview/worker failed to load.`,\n );\n }\n\n const { worker, stream: envStream } = result;\n const mux = setupMultiplex(envStream, `Snap: \"${snapId}\"`);\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n\n // Handle out-of-band errors, i.e. errors thrown from the Snap outside of the req/res cycle.\n // Also keep track of outbound request/responses\n const notificationHandler = (\n message:\n | JsonRpcRequest\n | JsonRpcNotification<Json[] | Record<string, Json>>,\n ) => {\n if (hasProperty(message, 'id')) {\n return;\n }\n\n if (message.method === 'OutboundRequest') {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n } else if (message.method === 'OutboundResponse') {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n } else if (message.method === 'UnhandledError') {\n this.#messenger.publish(\n 'ExecutionService:unhandledError',\n snapId,\n (message.params as { error: SnapErrorJson }).error,\n );\n commandStream.removeListener('data', notificationHandler);\n } else {\n logError(\n new Error(\n `Received unexpected command stream notification \"${message.method}\".`,\n ),\n );\n }\n };\n\n commandStream.on('data', notificationHandler);\n\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n rpcStream.on('data', (chunk) => {\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n }\n });\n\n const originalWrite = rpcStream.write.bind(rpcStream);\n\n // @ts-expect-error Hack to inspect the messages being written to the stream.\n rpcStream.write = (chunk, encoding, callback) => {\n // Ignore chain switching notifications as it doesn't matter for the SnapProvider.\n if (chunk?.data?.method === 'metamask_chainChanged') {\n return true;\n }\n\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n }\n\n return originalWrite(chunk, encoding, callback);\n };\n\n // Typecast: stream type mismatch\n return {\n streams: {\n command: commandStream,\n rpc: rpcStream,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n _connection: envStream,\n },\n worker,\n };\n }\n\n /**\n * Abstract function implemented by implementing class that spins up a new worker for a job.\n *\n * Depending on the execution environment, this may run forever if the Snap fails to start up properly, therefore any call to this function should be wrapped in a timeout.\n */\n protected abstract initEnvStream(snapId: string): Promise<{\n worker: WorkerType;\n stream: BasePostMessageStream;\n }>;\n\n /**\n * Set the execution status of the Snap.\n *\n * @param snapId - The Snap ID.\n * @param status - The current execution status.\n */\n protected setSnapStatus(snapId: string, status: ExecutionStatus) {\n this.#status.set(snapId, status);\n }\n\n async terminateAllSnaps() {\n await Promise.all(\n [...this.#jobs.keys()].map(async (snapId) => this.terminateSnap(snapId)),\n );\n }\n\n /**\n * Initializes and executes a Snap, setting up the communication channels to the Snap etc.\n *\n * @param snapData - Data needed for Snap execution.\n * @param snapData.snapId - The ID of the Snap to execute.\n * @param snapData.sourceCode - The source code of the Snap to execute.\n * @param snapData.endowments - The endowments available to the executing Snap.\n * @returns A string `OK` if execution succeeded.\n * @throws If the execution service returns an error or execution times out.\n */\n async executeSnap({\n snapId,\n sourceCode,\n endowments,\n }: SnapExecutionData): Promise<string> {\n if (this.#jobs.has(snapId)) {\n throw new Error(`\"${snapId}\" is already running.`);\n }\n\n this.setSnapStatus(snapId, 'created');\n\n const timer = new Timer(this.#initTimeout);\n\n // This may resolve even if the environment has failed to start up fully\n const job = await this.#initJob(snapId, timer);\n\n // Certain environments use ping as part of their initialization and thus can skip it here\n if (this.#usePing) {\n // Ping the worker to ensure that it started up\n const pingResult = await withTimeout(\n this.#command(job.id, {\n jsonrpc: '2.0',\n method: 'ping',\n id: nanoid(),\n }),\n this.#pingTimeout,\n );\n\n if (pingResult === hasTimedOut) {\n throw new Error(\n `The executor for \"${snapId}\" was unreachable. The executor did not respond in time.`,\n );\n }\n }\n\n const rpcStream = job.streams.rpc;\n\n this.#setupSnapProvider(snapId, rpcStream);\n\n // Use the remaining time as the timer, but ensure that the\n // Snap gets at least half the init timeout.\n const remainingTime = Math.max(timer.remaining, this.#initTimeout / 2);\n\n this.setSnapStatus(snapId, 'initialized');\n\n const request = {\n jsonrpc: '2.0',\n method: 'executeSnap',\n params: { snapId, sourceCode, endowments },\n id: nanoid(),\n };\n\n assertIsJsonRpcRequest(request);\n\n this.setSnapStatus(snapId, 'executing');\n\n const result = await withTimeout(\n this.#command(job.id, request),\n remainingTime,\n );\n\n if (result === hasTimedOut) {\n throw new Error(`${snapId} failed to start.`);\n }\n\n if (result === 'OK') {\n this.setSnapStatus(snapId, 'running');\n }\n\n return result as string;\n }\n\n async #command(\n snapId: string,\n message: JsonRpcRequest,\n ): Promise<Json | undefined> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n throw new Error(`\"${snapId}\" is not currently running.`);\n }\n\n log('Parent: Sending Command', message);\n const response = await job.rpcEngine.handle(message);\n\n // We don't need full validation of the response here because we control it.\n if (hasProperty(response, 'error')) {\n const error = response.error as JsonRpcErrorType;\n throw new JsonRpcError(error.code, error.message, error.data);\n }\n\n return response.result;\n }\n\n /**\n * Handle RPC request.\n *\n * @param snapId - The ID of the recipient Snap.\n * @param options - Bag of options to pass to the RPC handler.\n * @returns Promise that can handle the request.\n */\n public async handleRpcRequest(\n snapId: string,\n options: SnapRpcHookArgs,\n ): Promise<unknown> {\n const { handler, request, origin } = options;\n\n return await this.#command(snapId, {\n id: nanoid(),\n jsonrpc: '2.0',\n method: 'snapRpc',\n params: {\n origin,\n handler,\n request: request as JsonRpcRequest,\n target: snapId,\n },\n });\n }\n}\n\n/**\n * Sets up stream multiplexing for the given stream.\n *\n * @param connectionStream - The stream to mux.\n * @param streamName - The name of the stream, for identification in errors.\n * @returns The multiplexed stream.\n */\nexport function setupMultiplex(\n connectionStream: Duplex,\n streamName: string,\n): ObjectMultiplex {\n const mux = new ObjectMultiplex();\n pipeline(connectionStream, mux, connectionStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`\"${streamName}\" stream failure.`, error);\n }\n });\n return mux;\n}\n"]}
1
+ {"version":3,"file":"AbstractExecutionService.mjs","sourceRoot":"","sources":["../../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { JsonRpcEngine } from '@metamask/json-rpc-engine';\nimport { createStreamMiddleware } from '@metamask/json-rpc-middleware-stream';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport type { SnapRpcHookArgs } from '@metamask/snaps-utils';\nimport { SNAP_STREAM_NAMES, logError, logWarning } from '@metamask/snaps-utils';\nimport type {\n Json,\n JsonRpcError as JsonRpcErrorType,\n JsonRpcNotification,\n JsonRpcRequest,\n} from '@metamask/utils';\nimport {\n Duration,\n assertIsJsonRpcRequest,\n hasProperty,\n inMilliseconds,\n} from '@metamask/utils';\nimport { nanoid } from 'nanoid';\nimport { pipeline } from 'readable-stream';\nimport type { Duplex } from 'readable-stream';\n\nimport type {\n ExecutionService,\n ExecutionServiceMessenger,\n SnapErrorJson,\n SnapExecutionData,\n} from './ExecutionService';\nimport { log } from '../logging';\nimport { Timer } from '../snaps/Timer';\nimport { hasTimedOut, withTimeout } from '../utils';\n\nconst controllerName = 'ExecutionService';\n\nexport type SetupSnapProvider = (snapId: string, stream: Duplex) => void;\n\nexport type ExecutionServiceArgs = {\n setupSnapProvider: SetupSnapProvider;\n messenger: ExecutionServiceMessenger;\n initTimeout?: number;\n pingTimeout?: number;\n terminationTimeout?: number;\n usePing?: boolean;\n};\n\nexport type JobStreams = {\n command: Duplex;\n rpc: Duplex;\n connection: BasePostMessageStream;\n mux: ObjectMultiplex;\n};\n\nexport type Job<WorkerType> = {\n id: string;\n streams: JobStreams;\n rpcEngine: JsonRpcEngine;\n worker: WorkerType;\n};\n\nexport type TerminateJobArgs<WorkerType> = Partial<Job<WorkerType>> &\n Pick<Job<WorkerType>, 'id'>;\n\n/** \n Statuses used for diagnostic purposes\n - created: The initial state, no initialization has started \n - initializing: Snap execution environment is initializing\n - initialized: Snap execution environment has initialized\n - executing: Snap source code is being executed\n - running: Snap executed and ready for RPC requests\n */\ntype ExecutionStatus =\n | 'created'\n | 'initializing'\n | 'initialized'\n | 'executing'\n | 'running';\n\nexport abstract class AbstractExecutionService<WorkerType>\n implements ExecutionService\n{\n name: typeof controllerName = controllerName;\n\n state = null;\n\n readonly #jobs: Map<string, Job<WorkerType>>;\n\n readonly #status: Map<string, ExecutionStatus>;\n\n readonly #setupSnapProvider: SetupSnapProvider;\n\n readonly #messenger: ExecutionServiceMessenger;\n\n readonly #initTimeout: number;\n\n readonly #pingTimeout: number;\n\n readonly #terminationTimeout: number;\n\n readonly #usePing: boolean;\n\n constructor({\n setupSnapProvider,\n messenger,\n initTimeout = inMilliseconds(60, Duration.Second),\n pingTimeout = inMilliseconds(10, Duration.Second),\n terminationTimeout = inMilliseconds(1, Duration.Second),\n usePing = true,\n }: ExecutionServiceArgs) {\n this.#jobs = new Map();\n this.#status = new Map();\n this.#setupSnapProvider = setupSnapProvider;\n this.#messenger = messenger;\n this.#initTimeout = initTimeout;\n this.#pingTimeout = pingTimeout;\n this.#terminationTimeout = terminationTimeout;\n this.#usePing = usePing;\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.#messenger.registerActionHandler(\n `${controllerName}:handleRpcRequest`,\n async (snapId: string, options: SnapRpcHookArgs) =>\n this.handleRpcRequest(snapId, options),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:executeSnap`,\n async (data: SnapExecutionData) => this.executeSnap(data),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateSnap`,\n async (snapId: string) => this.terminateSnap(snapId),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateAllSnaps`,\n async () => this.terminateAllSnaps(),\n );\n }\n\n /**\n * Performs additional necessary work during job termination. **MUST** be\n * implemented by concrete implementations. See\n * {@link AbstractExecutionService.terminate} for details.\n *\n * @param job - The object corresponding to the job to be terminated.\n */\n protected abstract terminateJob(\n job: TerminateJobArgs<WorkerType>,\n ): Promise<void>;\n\n /**\n * Terminates the Snap with the specified ID and deletes all its associated\n * data. Any subsequent messages targeting the Snap will fail with an error.\n * Throws an error if termination fails unexpectedly.\n *\n * @param snapId - The id of the Snap to be terminated.\n */\n public async terminateSnap(snapId: string): Promise<void> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n return;\n }\n\n try {\n // Ping worker and tell it to run teardown, continue with termination if it takes too long\n const result = await withTimeout(\n this.#command(snapId, {\n jsonrpc: '2.0',\n method: 'terminate',\n id: nanoid(),\n }),\n this.#terminationTimeout,\n );\n\n if (result === hasTimedOut || result !== 'OK') {\n logWarning(`Snap \"${snapId}\" failed to terminate gracefully.`);\n }\n } catch {\n // Ignore\n }\n\n Object.values(job.streams).forEach((stream) => {\n try {\n if (!stream.destroyed) {\n stream.destroy();\n }\n } catch (error) {\n logError('Error while destroying stream', error);\n }\n });\n\n await this.terminateJob(job);\n\n this.#jobs.delete(snapId);\n this.#status.delete(snapId);\n log(`Snap \"${snapId}\" terminated.`);\n }\n\n /**\n * Initiates a job for a Snap.\n *\n * @param snapId - The ID of the Snap to initiate a job for.\n * @param timer - The timer to use for timeouts.\n * @returns Information regarding the created job.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initJob(snapId: string, timer: Timer): Promise<Job<WorkerType>> {\n const { streams, worker } = await this.#initStreams(snapId, timer);\n const rpcEngine = new JsonRpcEngine();\n\n const jsonRpcConnection = createStreamMiddleware();\n\n pipeline(\n jsonRpcConnection.stream,\n streams.command,\n jsonRpcConnection.stream,\n (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`Command stream failure.`, error);\n }\n },\n );\n\n rpcEngine.push(jsonRpcConnection.middleware);\n\n const envMetadata = {\n id: snapId,\n streams,\n rpcEngine,\n worker,\n };\n this.#jobs.set(snapId, envMetadata);\n\n return envMetadata;\n }\n\n /**\n * Sets up the streams for an initiated job.\n *\n * @param snapId - The Snap ID.\n * @param timer - The timer to use for timeouts.\n * @returns The streams to communicate with the worker and the worker itself.\n * @throws If the execution service returns an error or execution times out.\n */\n async #initStreams(\n snapId: string,\n timer: Timer,\n ): Promise<{ streams: JobStreams; worker: WorkerType }> {\n const result = await withTimeout(this.initEnvStream(snapId), timer);\n\n if (result === hasTimedOut) {\n // For certain environments, such as the iframe we may have already created the worker and wish to terminate it.\n await this.terminateJob({ id: snapId });\n\n const status = this.#status.get(snapId);\n if (status === 'created') {\n // Currently this error can only be thrown by OffscreenExecutionService.\n throw new Error(\n `The executor for \"${snapId}\" couldn't start initialization. The offscreen document may not exist.`,\n );\n }\n throw new Error(\n `The executor for \"${snapId}\" failed to initialize. The iframe/webview/worker failed to load.`,\n );\n }\n\n const { worker, stream: envStream } = result;\n const mux = setupMultiplex(envStream, `Snap: \"${snapId}\"`);\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n\n // Handle out-of-band errors, i.e. errors thrown from the Snap outside of the req/res cycle.\n // Also keep track of outbound request/responses\n const notificationHandler = (\n message:\n | JsonRpcRequest\n | JsonRpcNotification<Json[] | Record<string, Json>>,\n ) => {\n if (hasProperty(message, 'id')) {\n return;\n }\n\n if (message.method === 'OutboundRequest') {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n } else if (message.method === 'OutboundResponse') {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n } else if (message.method === 'UnhandledError') {\n this.#messenger.publish(\n 'ExecutionService:unhandledError',\n snapId,\n (message.params as { error: SnapErrorJson }).error,\n );\n commandStream.removeListener('data', notificationHandler);\n } else {\n logError(\n new Error(\n `Received unexpected command stream notification \"${message.method}\".`,\n ),\n );\n }\n };\n\n commandStream.on('data', notificationHandler);\n\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n rpcStream.on('data', (chunk) => {\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n }\n });\n\n const originalWrite = rpcStream.write.bind(rpcStream);\n\n // @ts-expect-error Hack to inspect the messages being written to the stream.\n rpcStream.write = (chunk, encoding, callback) => {\n // Ignore chain switching notifications as it doesn't matter for the SnapProvider.\n if (chunk?.data?.method === 'metamask_chainChanged') {\n return true;\n }\n\n if (chunk?.data && hasProperty(chunk?.data, 'id')) {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n }\n\n return originalWrite(chunk, encoding, callback);\n };\n\n return {\n streams: {\n command: commandStream,\n rpc: rpcStream,\n connection: envStream,\n mux,\n },\n worker,\n };\n }\n\n /**\n * Abstract function implemented by implementing class that spins up a new worker for a job.\n *\n * Depending on the execution environment, this may run forever if the Snap fails to start up properly, therefore any call to this function should be wrapped in a timeout.\n */\n protected abstract initEnvStream(snapId: string): Promise<{\n worker: WorkerType;\n stream: BasePostMessageStream;\n }>;\n\n /**\n * Set the execution status of the Snap.\n *\n * @param snapId - The Snap ID.\n * @param status - The current execution status.\n */\n protected setSnapStatus(snapId: string, status: ExecutionStatus) {\n this.#status.set(snapId, status);\n }\n\n async terminateAllSnaps() {\n await Promise.all(\n [...this.#jobs.keys()].map(async (snapId) => this.terminateSnap(snapId)),\n );\n }\n\n /**\n * Initializes and executes a Snap, setting up the communication channels to the Snap etc.\n *\n * @param snapData - Data needed for Snap execution.\n * @param snapData.snapId - The ID of the Snap to execute.\n * @param snapData.sourceCode - The source code of the Snap to execute.\n * @param snapData.endowments - The endowments available to the executing Snap.\n * @returns A string `OK` if execution succeeded.\n * @throws If the execution service returns an error or execution times out.\n */\n async executeSnap({\n snapId,\n sourceCode,\n endowments,\n }: SnapExecutionData): Promise<string> {\n if (this.#jobs.has(snapId)) {\n throw new Error(`\"${snapId}\" is already running.`);\n }\n\n this.setSnapStatus(snapId, 'created');\n\n const timer = new Timer(this.#initTimeout);\n\n // This may resolve even if the environment has failed to start up fully\n const job = await this.#initJob(snapId, timer);\n\n // Certain environments use ping as part of their initialization and thus can skip it here\n if (this.#usePing) {\n // Ping the worker to ensure that it started up\n const pingResult = await withTimeout(\n this.#command(job.id, {\n jsonrpc: '2.0',\n method: 'ping',\n id: nanoid(),\n }),\n this.#pingTimeout,\n );\n\n if (pingResult === hasTimedOut) {\n throw new Error(\n `The executor for \"${snapId}\" was unreachable. The executor did not respond in time.`,\n );\n }\n }\n\n const rpcStream = job.streams.rpc;\n\n this.#setupSnapProvider(snapId, rpcStream);\n\n // Use the remaining time as the timer, but ensure that the\n // Snap gets at least half the init timeout.\n const remainingTime = Math.max(timer.remaining, this.#initTimeout / 2);\n\n this.setSnapStatus(snapId, 'initialized');\n\n const request = {\n jsonrpc: '2.0',\n method: 'executeSnap',\n params: { snapId, sourceCode, endowments },\n id: nanoid(),\n };\n\n assertIsJsonRpcRequest(request);\n\n this.setSnapStatus(snapId, 'executing');\n\n const result = await withTimeout(\n this.#command(job.id, request),\n remainingTime,\n );\n\n if (result === hasTimedOut) {\n throw new Error(`${snapId} failed to start.`);\n }\n\n if (result === 'OK') {\n this.setSnapStatus(snapId, 'running');\n }\n\n return result as string;\n }\n\n async #command(\n snapId: string,\n message: JsonRpcRequest,\n ): Promise<Json | undefined> {\n const job = this.#jobs.get(snapId);\n if (!job) {\n throw new Error(`\"${snapId}\" is not currently running.`);\n }\n\n log('Parent: Sending Command', message);\n const response = await job.rpcEngine.handle(message);\n\n // We don't need full validation of the response here because we control it.\n if (hasProperty(response, 'error')) {\n const error = response.error as JsonRpcErrorType;\n throw new JsonRpcError(error.code, error.message, error.data);\n }\n\n return response.result;\n }\n\n /**\n * Handle RPC request.\n *\n * @param snapId - The ID of the recipient Snap.\n * @param options - Bag of options to pass to the RPC handler.\n * @returns Promise that can handle the request.\n */\n public async handleRpcRequest(\n snapId: string,\n options: SnapRpcHookArgs,\n ): Promise<unknown> {\n const { handler, request, origin } = options;\n\n return await this.#command(snapId, {\n id: nanoid(),\n jsonrpc: '2.0',\n method: 'snapRpc',\n params: {\n snapId,\n origin,\n handler,\n request: request as JsonRpcRequest,\n },\n });\n }\n}\n\n/**\n * Sets up stream multiplexing for the given stream.\n *\n * @param connectionStream - The stream to mux.\n * @param streamName - The name of the stream, for identification in errors.\n * @returns The multiplexed stream.\n */\nexport function setupMultiplex(\n connectionStream: Duplex,\n streamName: string,\n): ObjectMultiplex {\n const mux = new ObjectMultiplex();\n pipeline(connectionStream, mux, connectionStream, (error) => {\n if (error && !error.message?.match('Premature close')) {\n logError(`\"${streamName}\" stream failure.`, error);\n }\n });\n return mux;\n}\n"]}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IframeExecutionService = void 0;
4
4
  const post_message_stream_1 = require("@metamask/post-message-stream");
5
5
  const snaps_utils_1 = require("@metamask/snaps-utils");
6
+ const utils_1 = require("../../utils.cjs");
6
7
  const AbstractExecutionService_1 = require("../AbstractExecutionService.cjs");
7
8
  class IframeExecutionService extends AbstractExecutionService_1.AbstractExecutionService {
8
9
  iframeUrl;
@@ -14,8 +15,17 @@ class IframeExecutionService extends AbstractExecutionService_1.AbstractExecutio
14
15
  });
15
16
  this.iframeUrl = iframeUrl;
16
17
  }
17
- terminateJob(jobWrapper) {
18
- document.getElementById(jobWrapper.id)?.remove();
18
+ async terminateJob(jobWrapper) {
19
+ const iframe = document.getElementById(jobWrapper.id);
20
+ if (!iframe) {
21
+ return;
22
+ }
23
+ iframe.id = '';
24
+ await (0, utils_1.withTimeout)(new Promise((resolve) => {
25
+ iframe.addEventListener('load', () => resolve(), { once: true });
26
+ iframe.src = 'about:blank';
27
+ }), 10);
28
+ iframe.remove();
19
29
  }
20
30
  async initEnvStream(snapId) {
21
31
  this.setSnapStatus(snapId, 'initializing');
@@ -1 +1 @@
1
- {"version":3,"file":"IframeExecutionService.cjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":";;;AACA,uEAAwE;AACxE,uDAAqD;AAMrD,8EAAuE;AAMvE,MAAa,sBAAuB,SAAQ,mDAAgC;IACnE,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,YAAY,CAAC,UAAoC;QACzD,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACnD,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAY,EAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,6CAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF;AAzCD,wDAyCC","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../AbstractExecutionService';\nimport { AbstractExecutionService } from '../AbstractExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends AbstractExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected terminateJob(jobWrapper: TerminateJobArgs<Window>): void {\n document.getElementById(jobWrapper.id)?.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
1
+ {"version":3,"file":"IframeExecutionService.cjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":";;;AACA,uEAAwE;AACxE,uDAAqD;AAErD,2CAA0C;AAK1C,8EAAuE;AAMvE,MAAa,sBAAuB,SAAQ,mDAAgC;IACnE,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAAoC;QAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CACpC,UAAU,CAAC,EAAE,CACc,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QAEf,MAAM,IAAA,mBAAW,EACf,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC;QAC7B,CAAC,CAAC,EACF,EAAE,CACH,CAAC;QAEF,MAAM,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAY,EAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,6CAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF;AA7DD,wDA6DC","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport { withTimeout } from '../../utils';\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../AbstractExecutionService';\nimport { AbstractExecutionService } from '../AbstractExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends AbstractExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<Window>,\n ): Promise<void> {\n const iframe = document.getElementById(\n jobWrapper.id,\n ) as HTMLIFrameElement | null;\n\n if (!iframe) {\n return;\n }\n\n iframe.id = '';\n\n await withTimeout(\n new Promise<void>((resolve) => {\n iframe.addEventListener('load', () => resolve(), { once: true });\n iframe.src = 'about:blank';\n }),\n 10,\n );\n\n iframe.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
@@ -7,7 +7,7 @@ type IframeExecutionEnvironmentServiceArgs = {
7
7
  export declare class IframeExecutionService extends AbstractExecutionService<Window> {
8
8
  iframeUrl: URL;
9
9
  constructor({ iframeUrl, messenger, setupSnapProvider, ...args }: IframeExecutionEnvironmentServiceArgs);
10
- protected terminateJob(jobWrapper: TerminateJobArgs<Window>): void;
10
+ protected terminateJob(jobWrapper: TerminateJobArgs<Window>): Promise<void>;
11
11
  protected initEnvStream(snapId: string): Promise<{
12
12
  worker: Window;
13
13
  stream: BasePostMessageStream;
@@ -1 +1 @@
1
- {"version":3,"file":"IframeExecutionService.d.cts","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAI3E,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EACjB,wCAAoC;AACrC,OAAO,EAAE,wBAAwB,EAAE,wCAAoC;AAEvE,KAAK,qCAAqC,GAAG;IAC3C,SAAS,EAAE,GAAG,CAAC;CAChB,GAAG,oBAAoB,CAAC;AAEzB,qBAAa,sBAAuB,SAAQ,wBAAwB,CAAC,MAAM,CAAC;IACnE,SAAS,EAAE,GAAG,CAAC;gBAEV,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EACR,EAAE,qCAAqC;IASxC,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAAI;cAIlD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;CAiBH"}
1
+ {"version":3,"file":"IframeExecutionService.d.cts","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAK3E,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EACjB,wCAAoC;AACrC,OAAO,EAAE,wBAAwB,EAAE,wCAAoC;AAEvE,KAAK,qCAAqC,GAAG;IAC3C,SAAS,EAAE,GAAG,CAAC;CAChB,GAAG,oBAAoB,CAAC;AAEzB,qBAAa,sBAAuB,SAAQ,wBAAwB,CAAC,MAAM,CAAC;IACnE,SAAS,EAAE,GAAG,CAAC;gBAEV,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EACR,EAAE,qCAAqC;cASxB,YAAY,CAC1B,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,GACnC,OAAO,CAAC,IAAI,CAAC;cAsBA,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;CAiBH"}
@@ -7,7 +7,7 @@ type IframeExecutionEnvironmentServiceArgs = {
7
7
  export declare class IframeExecutionService extends AbstractExecutionService<Window> {
8
8
  iframeUrl: URL;
9
9
  constructor({ iframeUrl, messenger, setupSnapProvider, ...args }: IframeExecutionEnvironmentServiceArgs);
10
- protected terminateJob(jobWrapper: TerminateJobArgs<Window>): void;
10
+ protected terminateJob(jobWrapper: TerminateJobArgs<Window>): Promise<void>;
11
11
  protected initEnvStream(snapId: string): Promise<{
12
12
  worker: Window;
13
13
  stream: BasePostMessageStream;
@@ -1 +1 @@
1
- {"version":3,"file":"IframeExecutionService.d.mts","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAI3E,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EACjB,wCAAoC;AACrC,OAAO,EAAE,wBAAwB,EAAE,wCAAoC;AAEvE,KAAK,qCAAqC,GAAG;IAC3C,SAAS,EAAE,GAAG,CAAC;CAChB,GAAG,oBAAoB,CAAC;AAEzB,qBAAa,sBAAuB,SAAQ,wBAAwB,CAAC,MAAM,CAAC;IACnE,SAAS,EAAE,GAAG,CAAC;gBAEV,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EACR,EAAE,qCAAqC;IASxC,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAAI;cAIlD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;CAiBH"}
1
+ {"version":3,"file":"IframeExecutionService.d.mts","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAK3E,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EACjB,wCAAoC;AACrC,OAAO,EAAE,wBAAwB,EAAE,wCAAoC;AAEvE,KAAK,qCAAqC,GAAG;IAC3C,SAAS,EAAE,GAAG,CAAC;CAChB,GAAG,oBAAoB,CAAC;AAEzB,qBAAa,sBAAuB,SAAQ,wBAAwB,CAAC,MAAM,CAAC;IACnE,SAAS,EAAE,GAAG,CAAC;gBAEV,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EACR,EAAE,qCAAqC;cASxB,YAAY,CAC1B,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,GACnC,OAAO,CAAC,IAAI,CAAC;cAsBA,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;CAiBH"}
@@ -1,5 +1,6 @@
1
1
  import { WindowPostMessageStream } from "@metamask/post-message-stream";
2
2
  import { createWindow } from "@metamask/snaps-utils";
3
+ import { withTimeout } from "../../utils.mjs";
3
4
  import { AbstractExecutionService } from "../AbstractExecutionService.mjs";
4
5
  export class IframeExecutionService extends AbstractExecutionService {
5
6
  iframeUrl;
@@ -11,8 +12,17 @@ export class IframeExecutionService extends AbstractExecutionService {
11
12
  });
12
13
  this.iframeUrl = iframeUrl;
13
14
  }
14
- terminateJob(jobWrapper) {
15
- document.getElementById(jobWrapper.id)?.remove();
15
+ async terminateJob(jobWrapper) {
16
+ const iframe = document.getElementById(jobWrapper.id);
17
+ if (!iframe) {
18
+ return;
19
+ }
20
+ iframe.id = '';
21
+ await withTimeout(new Promise((resolve) => {
22
+ iframe.addEventListener('load', () => resolve(), { once: true });
23
+ iframe.src = 'about:blank';
24
+ }), 10);
25
+ iframe.remove();
16
26
  }
17
27
  async initEnvStream(snapId) {
18
28
  this.setSnapStatus(snapId, 'initializing');
@@ -1 +1 @@
1
- {"version":3,"file":"IframeExecutionService.mjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,sCAAsC;AACxE,OAAO,EAAE,YAAY,EAAE,8BAA8B;AAMrD,OAAO,EAAE,wBAAwB,EAAE,wCAAoC;AAMvE,MAAM,OAAO,sBAAuB,SAAQ,wBAAgC;IACnE,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,YAAY,CAAC,UAAoC;QACzD,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACnD,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../AbstractExecutionService';\nimport { AbstractExecutionService } from '../AbstractExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends AbstractExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected terminateJob(jobWrapper: TerminateJobArgs<Window>): void {\n document.getElementById(jobWrapper.id)?.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
1
+ {"version":3,"file":"IframeExecutionService.mjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,sCAAsC;AACxE,OAAO,EAAE,YAAY,EAAE,8BAA8B;AAErD,OAAO,EAAE,WAAW,EAAE,wBAAoB;AAK1C,OAAO,EAAE,wBAAwB,EAAE,wCAAoC;AAMvE,MAAM,OAAO,sBAAuB,SAAQ,wBAAgC;IACnE,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAAoC;QAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CACpC,UAAU,CAAC,EAAE,CACc,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QAEf,MAAM,WAAW,CACf,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC;QAC7B,CAAC,CAAC,EACF,EAAE,CACH,CAAC;QAEF,MAAM,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport { withTimeout } from '../../utils';\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../AbstractExecutionService';\nimport { AbstractExecutionService } from '../AbstractExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends AbstractExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<Window>,\n ): Promise<void> {\n const iframe = document.getElementById(\n jobWrapper.id,\n ) as HTMLIFrameElement | null;\n\n if (!iframe) {\n return;\n }\n\n iframe.id = '';\n\n await withTimeout(\n new Promise<void>((resolve) => {\n iframe.addEventListener('load', () => resolve(), { once: true });\n iframe.src = 'about:blank';\n }),\n 10,\n );\n\n iframe.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
@@ -23,7 +23,7 @@ class NodeProcessExecutionService extends __1.AbstractExecutionService {
23
23
  const stream = new node_1.ProcessParentMessageStream({ process: worker });
24
24
  return Promise.resolve({ worker, stream });
25
25
  }
26
- terminateJob(jobWrapper) {
26
+ async terminateJob(jobWrapper) {
27
27
  jobWrapper.worker?.kill();
28
28
  }
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NodeProcessExecutionService.cjs","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";;;AACA,6DAAgF;AAEhF,iDAAqC;AAGrC,oCAA8C;AAE9C,MAAa,2BAA4B,SAAQ,4BAAsC;IAC3E,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,IAAA,oBAAI,EACjB,OAAO,CAAC,OAAO,CAAC,qDAAqD,CAAC,EACtE;YACE,KAAK,EAAE,MAAM;SACd,CACF,CAAC;QAEF,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,iCAA0B,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,YAAY,CAAC,UAA0C;QAC/D,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;CACF;AAjCD,kEAiCC","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { ProcessParentMessageStream } from '@metamask/post-message-stream/node';\nimport type { ChildProcess } from 'child_process';\nimport { fork } from 'child_process';\n\nimport type { TerminateJobArgs } from '..';\nimport { AbstractExecutionService } from '..';\n\nexport class NodeProcessExecutionService extends AbstractExecutionService<ChildProcess> {\n protected async initEnvStream(snapId: string): Promise<{\n worker: ChildProcess;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const worker = fork(\n require.resolve('@metamask/snaps-execution-environments/node-process'),\n {\n stdio: 'pipe',\n },\n );\n\n // Capturing `stdout` and `stderr` from the worker prevents the worker from\n // writing to them directly, making it easier to capture them Jest.\n worker.stdout?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.log(data.toString());\n });\n\n worker.stderr?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.error(data.toString());\n });\n\n const stream = new ProcessParentMessageStream({ process: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected terminateJob(jobWrapper: TerminateJobArgs<ChildProcess>): void {\n jobWrapper.worker?.kill();\n }\n}\n"]}
1
+ {"version":3,"file":"NodeProcessExecutionService.cjs","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";;;AACA,6DAAgF;AAEhF,iDAAqC;AAGrC,oCAA8C;AAE9C,MAAa,2BAA4B,SAAQ,4BAAsC;IAC3E,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,IAAA,oBAAI,EACjB,OAAO,CAAC,OAAO,CAAC,qDAAqD,CAAC,EACtE;YACE,KAAK,EAAE,MAAM;SACd,CACF,CAAC;QAEF,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,iCAA0B,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAA0C;QAE1C,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;CACF;AAnCD,kEAmCC","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { ProcessParentMessageStream } from '@metamask/post-message-stream/node';\nimport type { ChildProcess } from 'child_process';\nimport { fork } from 'child_process';\n\nimport type { TerminateJobArgs } from '..';\nimport { AbstractExecutionService } from '..';\n\nexport class NodeProcessExecutionService extends AbstractExecutionService<ChildProcess> {\n protected async initEnvStream(snapId: string): Promise<{\n worker: ChildProcess;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const worker = fork(\n require.resolve('@metamask/snaps-execution-environments/node-process'),\n {\n stdio: 'pipe',\n },\n );\n\n // Capturing `stdout` and `stderr` from the worker prevents the worker from\n // writing to them directly, making it easier to capture them Jest.\n worker.stdout?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.log(data.toString());\n });\n\n worker.stderr?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.error(data.toString());\n });\n\n const stream = new ProcessParentMessageStream({ process: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<ChildProcess>,\n ): Promise<void> {\n jobWrapper.worker?.kill();\n }\n}\n"]}
@@ -8,6 +8,6 @@ export declare class NodeProcessExecutionService extends AbstractExecutionServic
8
8
  worker: ChildProcess;
9
9
  stream: BasePostMessageStream;
10
10
  }>;
11
- protected terminateJob(jobWrapper: TerminateJobArgs<ChildProcess>): void;
11
+ protected terminateJob(jobWrapper: TerminateJobArgs<ChildProcess>): Promise<void>;
12
12
  }
13
13
  //# sourceMappingURL=NodeProcessExecutionService.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeProcessExecutionService.d.cts","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB;AAGlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAW;AAC3C,OAAO,EAAE,wBAAwB,EAAE,qBAAW;AAE9C,qBAAa,2BAA4B,SAAQ,wBAAwB,CAAC,YAAY,CAAC;cACrE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,YAAY,CAAC;QACrB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;IA0BF,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GAAG,IAAI;CAGzE"}
1
+ {"version":3,"file":"NodeProcessExecutionService.d.cts","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB;AAGlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAW;AAC3C,OAAO,EAAE,wBAAwB,EAAE,qBAAW;AAE9C,qBAAa,2BAA4B,SAAQ,wBAAwB,CAAC,YAAY,CAAC;cACrE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,YAAY,CAAC;QACrB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;cA0Bc,YAAY,CAC1B,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC;CAGjB"}
@@ -8,6 +8,6 @@ export declare class NodeProcessExecutionService extends AbstractExecutionServic
8
8
  worker: ChildProcess;
9
9
  stream: BasePostMessageStream;
10
10
  }>;
11
- protected terminateJob(jobWrapper: TerminateJobArgs<ChildProcess>): void;
11
+ protected terminateJob(jobWrapper: TerminateJobArgs<ChildProcess>): Promise<void>;
12
12
  }
13
13
  //# sourceMappingURL=NodeProcessExecutionService.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeProcessExecutionService.d.mts","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB;AAGlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAW;AAC3C,OAAO,EAAE,wBAAwB,EAAE,qBAAW;AAE9C,qBAAa,2BAA4B,SAAQ,wBAAwB,CAAC,YAAY,CAAC;cACrE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,YAAY,CAAC;QACrB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;IA0BF,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GAAG,IAAI;CAGzE"}
1
+ {"version":3,"file":"NodeProcessExecutionService.d.mts","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sCAAsC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB;AAGlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAW;AAC3C,OAAO,EAAE,wBAAwB,EAAE,qBAAW;AAE9C,qBAAa,2BAA4B,SAAQ,wBAAwB,CAAC,YAAY,CAAC;cACrE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACrD,MAAM,EAAE,YAAY,CAAC;QACrB,MAAM,EAAE,qBAAqB,CAAC;KAC/B,CAAC;cA0Bc,YAAY,CAC1B,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC;CAGjB"}
@@ -22,7 +22,7 @@ export class NodeProcessExecutionService extends AbstractExecutionService {
22
22
  const stream = new ProcessParentMessageStream({ process: worker });
23
23
  return Promise.resolve({ worker, stream });
24
24
  }
25
- terminateJob(jobWrapper) {
25
+ async terminateJob(jobWrapper) {
26
26
  jobWrapper.worker?.kill();
27
27
  }
28
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NodeProcessExecutionService.mjs","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,0BAA0B,EAAE,2CAA2C;AAEhF,OAAO,EAAE,IAAI,EAAE,sBAAsB;AAGrC,OAAO,EAAE,wBAAwB,EAAE,qBAAW;AAE9C,MAAM,OAAO,2BAA4B,SAAQ,wBAAsC;IAC3E,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,IAAI,kBACD,qDAAqD,GACrE;YACE,KAAK,EAAE,MAAM;SACd,CACF,CAAC;QAEF,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,0BAA0B,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,YAAY,CAAC,UAA0C;QAC/D,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;CACF","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { ProcessParentMessageStream } from '@metamask/post-message-stream/node';\nimport type { ChildProcess } from 'child_process';\nimport { fork } from 'child_process';\n\nimport type { TerminateJobArgs } from '..';\nimport { AbstractExecutionService } from '..';\n\nexport class NodeProcessExecutionService extends AbstractExecutionService<ChildProcess> {\n protected async initEnvStream(snapId: string): Promise<{\n worker: ChildProcess;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const worker = fork(\n require.resolve('@metamask/snaps-execution-environments/node-process'),\n {\n stdio: 'pipe',\n },\n );\n\n // Capturing `stdout` and `stderr` from the worker prevents the worker from\n // writing to them directly, making it easier to capture them Jest.\n worker.stdout?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.log(data.toString());\n });\n\n worker.stderr?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.error(data.toString());\n });\n\n const stream = new ProcessParentMessageStream({ process: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected terminateJob(jobWrapper: TerminateJobArgs<ChildProcess>): void {\n jobWrapper.worker?.kill();\n }\n}\n"]}
1
+ {"version":3,"file":"NodeProcessExecutionService.mjs","sourceRoot":"","sources":["../../../src/services/node-js/NodeProcessExecutionService.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,0BAA0B,EAAE,2CAA2C;AAEhF,OAAO,EAAE,IAAI,EAAE,sBAAsB;AAGrC,OAAO,EAAE,wBAAwB,EAAE,qBAAW;AAE9C,MAAM,OAAO,2BAA4B,SAAQ,wBAAsC;IAC3E,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,IAAI,kBACD,qDAAqD,GACrE;YACE,KAAK,EAAE,MAAM;SACd,CACF,CAAC;QAEF,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACjC,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,0BAA0B,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAA0C;QAE1C,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;CACF","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { ProcessParentMessageStream } from '@metamask/post-message-stream/node';\nimport type { ChildProcess } from 'child_process';\nimport { fork } from 'child_process';\n\nimport type { TerminateJobArgs } from '..';\nimport { AbstractExecutionService } from '..';\n\nexport class NodeProcessExecutionService extends AbstractExecutionService<ChildProcess> {\n protected async initEnvStream(snapId: string): Promise<{\n worker: ChildProcess;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const worker = fork(\n require.resolve('@metamask/snaps-execution-environments/node-process'),\n {\n stdio: 'pipe',\n },\n );\n\n // Capturing `stdout` and `stderr` from the worker prevents the worker from\n // writing to them directly, making it easier to capture them Jest.\n worker.stdout?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.log(data.toString());\n });\n\n worker.stderr?.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.error(data.toString());\n });\n\n const stream = new ProcessParentMessageStream({ process: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<ChildProcess>,\n ): Promise<void> {\n jobWrapper.worker?.kill();\n }\n}\n"]}
@@ -32,7 +32,7 @@ class WebViewExecutionService extends AbstractExecutionService_1.AbstractExecuti
32
32
  });
33
33
  return { worker: webView, stream };
34
34
  }
35
- terminateJob(jobWrapper) {
35
+ async terminateJob(jobWrapper) {
36
36
  this.#removeWebView(jobWrapper.id);
37
37
  }
38
38
  }