{"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExecutionService } from '@metamask/snaps-controllers';\nimport type {\n  AccountSelectorState,\n  AssetSelectorState,\n  SnapId,\n} from '@metamask/snaps-sdk';\nimport type {\n  InstallSnapOptions,\n  SimulationAccount,\n  SimulationAsset,\n  Snap,\n} from '@metamask/snaps-simulation';\nimport { logInfo } from '@metamask/snaps-utils';\nimport { assert, createModuleLogger } from '@metamask/utils';\nimport type {\n  CaipAccountId,\n  CaipAssetType,\n  CaipChainId,\n} from '@metamask/utils';\n\nimport {\n  rootLogger,\n  getEnvironment,\n  getPseudoRandomUuidGenerator,\n  getScopesFromAssets,\n} from './internals';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * Get the options for {@link installSnap}.\n *\n * @param snapId - The ID of the Snap, or the options.\n * @param options - The options, if any.\n * @returns The options.\n */\nfunction getOptions<\n  Service extends new (...args: any[]) => InstanceType<typeof ExecutionService>,\n>(\n  snapId: SnapId | Partial<InstallSnapOptions<Service>> | undefined,\n  options: Partial<InstallSnapOptions<Service>>,\n): [SnapId | undefined, Partial<InstallSnapOptions<Service>>] {\n  if (typeof snapId === 'object') {\n    return [undefined, snapId];\n  }\n\n  return [snapId, options];\n}\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n *   it('should do something', async () => {\n *     const { request } = await installSnap('local:my-snap');\n *     const response = await request({\n *       method: 'foo',\n *       params: ['bar'],\n *     });\n *     expect(response).toRespondWith('bar');\n *   });\n * });\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap(): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n *   it('should do something', async () => {\n *     const { request } = await installSnap('local:my-snap');\n *     const response = await request({\n *       method: 'foo',\n *       params: ['bar'],\n *     });\n *     expect(response).toRespondWith('bar');\n *   });\n * });\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n  Service extends new (...args: any[]) => InstanceType<typeof ExecutionService>,\n>(options: Partial<InstallSnapOptions<Service>>): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n *   it('should do something', async () => {\n *     const { request } = await installSnap('local:my-snap');\n *     const response = await request({\n *       method: 'foo',\n *       params: ['bar'],\n *     });\n *     expect(response).toRespondWith('bar');\n *   });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n  Service extends new (...args: any[]) => InstanceType<typeof ExecutionService>,\n>(\n  snapId: SnapId,\n  options?: Partial<InstallSnapOptions<Service>>,\n): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n *   it('should do something', async () => {\n *     const { request } = await installSnap('local:my-snap');\n *     const response = await request({\n *       method: 'foo',\n *       params: ['bar'],\n *     });\n *     expect(response).toRespondWith('bar');\n *   });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n  Service extends new (...args: any[]) => InstanceType<typeof ExecutionService>,\n>(\n  snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n  options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n  const resolvedOptions = getOptions(snapId, options);\n\n  // TODO: Either fix this lint violation or explain why it's necessary to\n  //  ignore.\n  /* eslint-disable @typescript-eslint/unbound-method */\n  const {\n    request,\n    onTransaction,\n    sendTransaction,\n    onSignature,\n    onCronjob,\n    runCronjob,\n    onBackgroundEvent,\n    onHomePage,\n    onSettingsPage,\n    onKeyringRequest,\n    onInstall,\n    onUpdate,\n    onStart,\n    onNameLookup,\n    onProtocolRequest,\n    onClientRequest,\n    mockJsonRpc,\n    mockJsonRpcOnce,\n    close,\n  } = await getEnvironment().installSnap(...resolvedOptions);\n  /* eslint-enable @typescript-eslint/unbound-method */\n\n  return {\n    request,\n    onTransaction,\n    sendTransaction,\n    onSignature,\n    onCronjob,\n    runCronjob,\n    onBackgroundEvent,\n    onHomePage,\n    onSettingsPage,\n    onKeyringRequest,\n    onInstall,\n    onUpdate,\n    onStart,\n    onNameLookup,\n    onProtocolRequest,\n    onClientRequest,\n    mockJsonRpc,\n    mockJsonRpcOnce,\n    close: async () => {\n      log('Closing execution service.');\n      logInfo(\n        'Calling `snap.close()` is deprecated, and will be removed in a future release. Snaps are now automatically closed when the test ends.',\n      );\n\n      await close();\n    },\n  };\n}\n\n/**\n * Get the state of an AccountSelector based on a {@link SimulationAccount}.\n *\n * @param account - The {@link SimulationAccount} to get the state from.\n * @returns The state of the AccountSelector.\n */\nexport function getStateFromAccount(\n  account: SimulationAccount,\n): AccountSelectorState {\n  const { address, scopes } = account;\n  return {\n    addresses: scopes.map((scope) => `${scope}:${address}`) as CaipAccountId[],\n    accountId: account.id,\n  };\n}\n\n/**\n * Get the state of an AssetSelector based on a {@link SimulationAsset}.\n *\n * @param id - The Asset id as a CAIP-19 asset type.\n * @param assets - The {@link SimulationAsset} to get the state from.\n * @returns The state of the AssetSelector.\n */\nexport function getStateFromAsset(\n  id: CaipAssetType,\n  assets: Record<CaipAssetType, SimulationAsset>,\n): AssetSelectorState {\n  const asset = assets[id];\n\n  assert(asset, `Asset with ID \"${id}\" not found in simulation assets.`);\n\n  const { symbol, name } = asset;\n\n  return {\n    asset: id,\n    symbol,\n    name,\n  };\n}\n\n/**\n * Generate a pseudo-random UUID.\n *\n * @returns A pseudo-random UUID string.\n */\nconst getPseudoRandomUuid = getPseudoRandomUuidGenerator();\n\n/**\n * The base options for the {@link getMockAccount} function.\n */\nexport type BaseMockAccountOptions = {\n  /**\n   * The address of the account.\n   */\n  address: string;\n\n  /**\n   * The ID of the account. If not provided, a pseudo-random UUID will be\n   * generated.\n   */\n  id?: string;\n\n  /**\n   * Whether the account is selected by default.\n   */\n  selected?: boolean;\n\n  /**\n   * Whether the account is owned by the snap.\n   */\n  owned?: boolean;\n};\n\n/**\n * Options for creating a mock account with assets or scopes. If `scopes` are\n * not provided, they will be derived from the `assets`.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithAssets = BaseMockAccountOptions & {\n  /**\n   * The assets associated with the account. These should be in CAIP format.\n   */\n  assets: CaipAssetType[];\n\n  /**\n   * The scopes associated with the account. If not provided, they will be\n   * derived from the `assets`.\n   */\n  scopes?: CaipChainId[];\n};\n\n/**\n * Options for creating a mock account with scopes, and optionally assets.\n *\n * @see BaseMockAccountOptions\n */\nexport type MockAccountOptionsWithScopes = BaseMockAccountOptions & {\n  /**\n   * The scopes associated with the account. These should be in CAIP format.\n   */\n  scopes: CaipChainId[];\n\n  /**\n   * The assets associated with the account. If not provided, it will default\n   * to an empty array.\n   */\n  assets?: CaipAssetType[];\n};\n\nexport type GetMockAccountOptions =\n  | MockAccountOptionsWithAssets\n  | MockAccountOptionsWithScopes;\n\n/**\n * Get a mock account object for testing purposes.\n *\n * @param options - The options for creating the mock account.\n * @param options.address - The address of the account.\n * @param options.scopes - The scopes associated with the account, in CAIP\n * format. If not provided, they will be derived from the `assets`.\n * @param options.assets - The assets associated with the account, in CAIP\n * format. If not provided, it will default to an empty array.\n * @param options.selected - Whether the account is selected by default.\n * @param options.owned - Whether the account is owned by the snap.\n * @param options.id - The ID of the account. If not provided, a pseudo-random\n * UUID will be generated.\n * @returns A mock account object with the specified properties.\n */\nexport function getMockAccount({\n  address,\n  assets = [],\n  selected = false,\n  owned = false,\n  id = getPseudoRandomUuid(),\n  scopes = getScopesFromAssets(assets),\n}: GetMockAccountOptions): SimulationAccount {\n  return {\n    address,\n    id,\n    scopes,\n    selected,\n    owned,\n    assets,\n  };\n}\n"]}