{"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { HandlerType } from '@metamask/snaps-utils';\nimport { create } from '@metamask/superstruct';\nimport type { CaipChainId, JsonRpcRequest } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { nanoid } from '@reduxjs/toolkit';\n\nimport { rootLogger } from './logger';\nimport type { SimulationOptions } from './options';\nimport { handleRequest } from './request';\nimport type { InstalledSnap } from './simulation';\nimport { addJsonRpcMock, removeJsonRpcMock } from './store';\nimport {\n  assertIsResponseWithInterface,\n  JsonRpcMockOptionsStruct,\n  NameLookupOptionsStruct,\n  SignatureOptionsStruct,\n  TransactionOptionsStruct,\n} from './structs';\nimport type {\n  CronjobOptions,\n  JsonRpcMockOptions,\n  KeyringOptions,\n  NameLookupOptions,\n  RequestOptions,\n  SignatureOptions,\n  SnapRequest,\n  SnapResponseWithInterface,\n  SnapResponseWithoutInterface,\n  TransactionOptions,\n} from './types';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * This is the main entry point to interact with the snap. It is returned by\n * {@link installSnap}, and has methods to send requests to the snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * const snap = await installSnap();\n * const response = await snap.request({ method: 'hello' });\n *\n * expect(response).toRespondWith('Hello, world!');\n */\nexport type SnapHelpers = {\n  /**\n   * Send a JSON-RPC request to the snap.\n   *\n   * @param request - The request. This is similar to a JSON-RPC request, but\n   * has an extra `origin` field.\n   * @returns The response promise, with extra {@link SnapRequestObject} fields.\n   */\n  request(request: RequestOptions): SnapRequest;\n\n  /**\n   * Send a transaction to the snap.\n   *\n   * @param transaction - The transaction. This is similar to an Ethereum\n   * transaction object, but has an extra `origin` field. Any missing fields\n   * will be filled in with default values.\n   * @returns The response.\n   */\n  onTransaction(\n    transaction?: Partial<TransactionOptions>,\n  ): Promise<SnapResponseWithInterface>;\n\n  /**\n   * Send a transaction to the snap.\n   *\n   * @param transaction - The transaction. This is similar to an Ethereum\n   * transaction object, but has an extra `origin` field. Any missing fields\n   * will be filled in with default values.\n   * @returns The response.\n   * @deprecated Use {@link onTransaction} instead.\n   */\n  sendTransaction(\n    transaction?: Partial<TransactionOptions>,\n  ): Promise<SnapResponseWithInterface>;\n\n  /**\n   * Send a signature request to the snap.\n   *\n   * @param signature - The signature request object. Contains the params from\n   * the various signature methods, but has an extra `origin` and `signatureMethod` field.\n   * Any missing fields will be filled in with default values.\n   * @returns The response.\n   */\n  onSignature(\n    signature?: Partial<SignatureOptions>,\n  ): Promise<SnapResponseWithInterface>;\n\n  /**\n   * Run a cronjob in the snap. This is similar to {@link request}, but the\n   * request will be sent to the `onCronjob` method of the snap.\n   *\n   * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n   * request, and is normally specified in the snap manifest, under the\n   * `endowment:cronjob` permission.\n   * @returns The response promise, with extra {@link SnapRequestObject} fields.\n   */\n  onCronjob(cronjob?: Partial<CronjobOptions>): SnapRequest;\n\n  /**\n   * Run a cronjob in the snap. This is similar to {@link request}, but the\n   * request will be sent to the `onCronjob` method of the snap.\n   *\n   * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n   * request, and is normally specified in the snap manifest, under the\n   * `endowment:cronjob` permission.\n   * @returns The response promise, with extra {@link SnapRequestObject} fields.\n   * @deprecated Use {@link onCronjob} instead.\n   */\n  runCronjob(cronjob: CronjobOptions): SnapRequest;\n\n  /**\n   * Run a background event in the snap. This is similar to {@link request}, but the\n   * request will be sent to the `onCronjob` method of the snap.\n   *\n   * @param backgroundEvent - The background event request. This is similar to a JSON-RPC\n   * request, and is normally specified in the `request` param of the `snap_scheduleBackgroundEvent` method.\n   * @returns The response promise, with extra {@link SnapRequestObject} fields.\n   */\n  onBackgroundEvent(backgroundEvent: CronjobOptions): SnapRequest;\n\n  /**\n   * Get the response from the snap's `onHomePage` method.\n   *\n   * @returns The response.\n   */\n  onHomePage(): Promise<SnapResponseWithInterface>;\n\n  /**\n   * Get the response from the snap's `onSettingsPage` method.\n   *\n   * @returns The response.\n   */\n  onSettingsPage(): Promise<SnapResponseWithInterface>;\n\n  /**\n   * Send a keyring request to the Snap.\n   *\n   * @param keyringRequest - Keyring request.\n   * @returns The response.\n   */\n  onKeyringRequest(keyringRequest: KeyringOptions): SnapRequest;\n\n  /**\n   * Get the response from the Snap's `onInstall` handler.\n   *\n   * @returns The response.\n   */\n  onInstall(request?: Pick<RequestOptions, 'origin'>): SnapRequest;\n\n  /**\n   * Get the response from the Snap's `onUpdate` handler.\n   *\n   * @returns The response.\n   */\n  onUpdate(request?: Pick<RequestOptions, 'origin'>): SnapRequest;\n\n  /**\n   * Get the response from the Snap's `onStart` handler.\n   *\n   * @returns The response.\n   */\n  onStart(request?: Pick<RequestOptions, 'origin'>): SnapRequest;\n\n  /**\n   * Get the response from the Snap's `onNameLookup` handler.\n   *\n   * @returns The response.\n   */\n  onNameLookup(\n    request: NameLookupOptions,\n  ): Promise<SnapResponseWithoutInterface>;\n\n  /**\n   * Send a JSON-RPC protocol request to the Snap.\n   *\n   * @param scope - A CAIP-2 scope.\n   * @param request - The request. This is similar to a JSON-RPC request, but\n   * has an extra `origin` field.\n   * @returns The response promise, with extra {@link SnapRequestObject} fields.\n   */\n  onProtocolRequest(\n    scope: CaipChainId,\n    request: RequestOptions,\n  ): Promise<SnapResponseWithoutInterface>;\n\n  /**\n   * Send a JSON-RPC client request to the Snap.\n   *\n   * @param request - The JSON-RPC request.\n   * @returns The response promise, with extra {@link SnapRequestObject} fields.\n   */\n  onClientRequest(request: Omit<RequestOptions, 'origin'>): SnapRequest;\n\n  /**\n   * Mock a JSON-RPC request. This will cause the snap to respond with the\n   * specified response when a request with the specified method is sent.\n   *\n   * @param mock - The mock options.\n   * @param mock.method - The JSON-RPC request method.\n   * @param mock.result - The JSON-RPC response, which will be returned when a\n   * request with the specified method is sent.\n   * @example\n   * import { installSnap } from '@metamask/snaps-jest';\n   *\n   * // In the test\n   * const snap = await installSnap();\n   * snap.mockJsonRpc({ method: 'eth_accounts', result: ['0x1234'] });\n   *\n   * // In the Snap\n   * const response =\n   *   await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n   *\n   * @example\n   * import { installSnap } from '@metamask/snaps-jest';\n   *\n   * // In the test\n   * const snap = await installSnap();\n   * snap.mockJsonRpc((request) => {\n   *  if (request.method === 'eth_accounts') {\n   *    return ['0x1234'];\n   *  }\n   * });\n   *\n   * // In the Snap\n   * const response =\n   *   await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n   */\n  mockJsonRpc(mock: JsonRpcMockOptions): {\n    /**\n     * Remove the mock.\n     */\n    unmock(): void;\n  };\n\n  /**\n   * Mock a JSON-RPC request once. This will cause the snap to respond with the\n   * specified response when a request with the specified method is sent.\n   *\n   * @param mock - The mock options.\n   * @param mock.method - The JSON-RPC request method.\n   * @param mock.result - The JSON-RPC response, which will be returned when a\n   * request with the specified method is sent.\n   * @example\n   * import { installSnap } from '@metamask/snaps-jest';\n   *\n   * // In the test\n   * const snap = await installSnap();\n   * snap.mockJsonRpcOnce({ method: 'eth_accounts', result: ['0x1234'] });\n   *\n   * // In the Snap\n   * const response =\n   *   await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n   *\n   * const response2 =\n   *   await ethereum.request({ method: 'eth_accounts' }); // Default behavior\n   *\n   * @example\n   * import { installSnap } from '@metamask/snaps-jest';\n   *\n   * // In the test\n   * const snap = await installSnap();\n   * snap.mockJsonRpcOnce((request) => {\n   *  if (request.method === 'eth_accounts') {\n   *    return ['0x1234'];\n   *  }\n   * });\n   *\n   * // In the Snap\n   * const response =\n   *   await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n   *\n   * const response2 =\n   *   await ethereum.request({ method: 'eth_accounts' }); // Default behavior\n   */\n  mockJsonRpcOnce(mock: JsonRpcMockOptions): {\n    /**\n     * Remove the mock.\n     */\n    unmock(): void;\n  };\n\n  /**\n   * Close the page running the snap. This is mainly useful for cleaning up\n   * the test environment, and calling it is not strictly necessary.\n   *\n   * @returns A promise that resolves when the page is closed.\n   */\n  close(): Promise<void>;\n};\n\n/**\n * Get the helper functions for the Snap.\n *\n * @param snap - The installed Snap.\n * @param snap.snapId - The ID of the Snap.\n * @param snap.store - The Redux store.\n * @param snap.executionService - The execution service.\n * @param snap.runSaga - The `runSaga` function.\n * @param snap.controllerMessenger - The controller messenger.\n * @param snap.options - The simulation options.\n * @returns The Snap helpers.\n */\nexport function getHelpers({\n  snapId,\n  store,\n  executionService,\n  runSaga,\n  controllerMessenger,\n  options,\n}: InstalledSnap & { options: SimulationOptions }): SnapHelpers {\n  const onTransaction = async (\n    request: TransactionOptions,\n  ): Promise<SnapResponseWithInterface> => {\n    log('Sending transaction %o.', request);\n\n    const {\n      origin: transactionOrigin,\n      chainId,\n      ...transaction\n    } = create(request, TransactionOptionsStruct);\n\n    const response = await handleRequest({\n      snapId,\n      store,\n      executionService,\n      runSaga,\n      controllerMessenger,\n      simulationOptions: options,\n      handler: HandlerType.OnTransaction,\n      request: {\n        method: '',\n        params: {\n          chainId,\n          transaction,\n          transactionOrigin,\n        },\n      },\n    });\n\n    assertIsResponseWithInterface(response);\n\n    return response;\n  };\n\n  // This can't be async because it returns a `SnapRequest`.\n  // eslint-disable-next-line @typescript-eslint/promise-function-async\n  const onCronjob = (request: CronjobOptions) => {\n    log('Running cronjob %o.', options);\n\n    return handleRequest({\n      snapId,\n      store,\n      executionService,\n      controllerMessenger,\n      simulationOptions: options,\n      runSaga,\n      handler: HandlerType.OnCronjob,\n      request,\n    });\n  };\n\n  // This can't be async because it returns a `SnapRequest`.\n  // eslint-disable-next-line @typescript-eslint/promise-function-async\n  const onKeyringRequest = (request: KeyringOptions) => {\n    log('Sending keyring request %o.', request);\n\n    return handleRequest({\n      snapId,\n      store,\n      executionService,\n      runSaga,\n      controllerMessenger,\n      simulationOptions: options,\n      handler: HandlerType.OnKeyringRequest,\n      request,\n    });\n  };\n\n  const mockJsonRpc = (mock: JsonRpcMockOptions, once: boolean) => {\n    log('Mocking JSON-RPC request %o.', mock);\n\n    const id = nanoid();\n\n    if (typeof mock === 'function') {\n      store.dispatch(addJsonRpcMock({ id, implementation: mock, once }));\n    } else {\n      const { method, result } = create(mock, JsonRpcMockOptionsStruct);\n      const implementation = (request: JsonRpcRequest) => {\n        if (request.method === method) {\n          return result;\n        }\n        return undefined;\n      };\n      store.dispatch(addJsonRpcMock({ id, implementation, once }));\n    }\n\n    return {\n      unmock() {\n        log('Unmocking JSON-RPC request %o.', mock);\n\n        store.dispatch(removeJsonRpcMock(id));\n      },\n    };\n  };\n\n  return {\n    // This can't be async because it returns a `SnapRequest`.\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\n    request: (request) => {\n      log('Sending request %o.', request);\n\n      return handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnRpcRequest,\n        request,\n      });\n    },\n\n    onTransaction,\n    sendTransaction: onTransaction,\n\n    onKeyringRequest,\n\n    // This can't be async because it returns a `SnapRequest`.\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\n    onInstall: (request?: Pick<RequestOptions, 'origin'>) => {\n      log('Running onInstall handler.');\n\n      return handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnInstall,\n        request: {\n          method: '',\n          ...request,\n        },\n      });\n    },\n\n    // This can't be async because it returns a `SnapRequest`.\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\n    onUpdate: (request?: Pick<RequestOptions, 'origin'>) => {\n      log('Running onUpdate handler.');\n\n      return handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnUpdate,\n        request: {\n          method: '',\n          ...request,\n        },\n      });\n    },\n\n    // This can't be async because it returns a `SnapRequest`.\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\n    onStart: (request?: Pick<RequestOptions, 'origin'>) => {\n      log('Running onStart handler.');\n\n      return handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnStart,\n        request: {\n          method: '',\n          ...request,\n        },\n      });\n    },\n\n    onNameLookup: async (\n      nameLookupOptions: NameLookupOptions,\n    ): Promise<SnapResponseWithoutInterface> => {\n      log('Requesting name lookup %o.', nameLookupOptions);\n\n      const params = create(nameLookupOptions, NameLookupOptionsStruct);\n\n      const response = await handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnNameLookup,\n        request: {\n          method: '',\n          params,\n        },\n      });\n\n      return response;\n    },\n\n    onSignature: async (\n      request: unknown,\n    ): Promise<SnapResponseWithInterface> => {\n      log('Requesting signature %o.', request);\n\n      const { origin: signatureOrigin, ...signature } = create(\n        request,\n        SignatureOptionsStruct,\n      );\n\n      const response = await handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnSignature,\n        request: {\n          method: '',\n          params: {\n            signature,\n            signatureOrigin,\n          },\n        },\n      });\n\n      assertIsResponseWithInterface(response);\n\n      return response;\n    },\n\n    onCronjob,\n    runCronjob: onCronjob,\n    onBackgroundEvent: onCronjob,\n\n    onHomePage: async (): Promise<SnapResponseWithInterface> => {\n      log('Rendering home page.');\n\n      const response = await handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnHomePage,\n        request: {\n          method: '',\n        },\n      });\n\n      assertIsResponseWithInterface(response);\n\n      return response;\n    },\n\n    onSettingsPage: async (): Promise<SnapResponseWithInterface> => {\n      log('Rendering settings page.');\n\n      const response = await handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnSettingsPage,\n        request: {\n          method: '',\n        },\n      });\n\n      assertIsResponseWithInterface(response);\n\n      return response;\n    },\n\n    onProtocolRequest: async (\n      scope,\n      rawRequest,\n    ): Promise<SnapResponseWithoutInterface> => {\n      log('Sending protocol request.');\n\n      const request = {\n        jsonrpc: '2.0' as const,\n        id: rawRequest.id ?? 1,\n        method: rawRequest.method,\n        ...(rawRequest.params ? { params: rawRequest.params } : {}),\n      };\n\n      const response = await handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnProtocolRequest,\n        request: {\n          origin: rawRequest.origin,\n          method: '',\n          params: {\n            scope,\n            request,\n          },\n        },\n      });\n\n      return response;\n    },\n\n    // This can't be async because it returns a `SnapRequest`.\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\n    onClientRequest: (request) => {\n      log('Sending client request.');\n\n      return handleRequest({\n        snapId,\n        store,\n        executionService,\n        controllerMessenger,\n        simulationOptions: options,\n        runSaga,\n        handler: HandlerType.OnClientRequest,\n        request,\n      });\n    },\n\n    mockJsonRpc(mock: JsonRpcMockOptions) {\n      return mockJsonRpc(mock, false);\n    },\n\n    mockJsonRpcOnce(mock: JsonRpcMockOptions) {\n      return mockJsonRpc(mock, true);\n    },\n\n    close: async () => {\n      log('Closing execution service.');\n      await executionService.terminateAllSnaps();\n    },\n  };\n}\n"]}