{"version":3,"file":"getEntropy.cjs","sourceRoot":"","sources":["../../src/restricted/getEntropy.ts"],"names":[],"mappings":";;;AAMA,2EAA8E;AAC9E,qDAAiD;AAEjD,uDAA0D;AAE1D,uDAA0E;AAE1E,2CAA+C;AAG/C,wCAA4E;AAE5E,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAcxB,QAAA,oBAAoB,GAAG,IAAA,oBAAM,EAAC;IACzC,OAAO,EAAE,IAAA,qBAAO,EAAC,CAAC,CAAC;IACnB,IAAI,EAAE,IAAA,sBAAQ,EAAC,IAAA,oBAAM,GAAE,CAAC;IACxB,MAAM,EAAE,IAAA,sBAAQ,EAAC,IAAA,oBAAM,GAAE,CAAC;CAC3B,CAAC,CAAC;AAUH,MAAM,oBAAoB,GAItB,CAAC,EACH,cAAc,GAAG,IAAI,EACrB,WAAW,GAC2B,EAAE,EAAE;IAC1C,OAAO;QACL,cAAc,EAAE,sCAAc,CAAC,gBAAgB;QAC/C,UAAU;QACV,cAAc;QACd,oBAAoB,EAAE,wBAAwB,CAAC,WAAW,CAAC;QAC3D,YAAY,EAAE,CAAC,mCAAW,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAuC;IACtD,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEW,QAAA,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7C,UAAU;IACV,oBAAoB;IACpB,WAAW;CACH,CAAC,CAAC;AA8BZ;;;;;;;;;;;;;GAaG;AACH,SAAS,wBAAwB,CAAC,EAChC,eAAe,EACf,gBAAgB,EAChB,qBAAqB,GACL;IAChB,OAAO,KAAK,UAAU,UAAU,CAC9B,OAAkD;QAElD,MAAM,EACJ,MAAM,EACN,OAAO,EAAE,EAAE,MAAM,EAAE,GACpB,GAAG,OAAO,CAAC;QAEZ,IAAA,oBAAY,EACV,MAAM,EACN,4BAAoB,EACpB,sCAAsC,EACtC,sBAAS,CAAC,aAAa,CACxB,CAAC;QAEF,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAA,iCAAyB,EAC1C,eAAe,EACf,MAAM,CAAC,MAAM,CACd,CAAC;QAEF,OAAO,IAAA,6BAAqB,EAAC;YAC3B,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI;YACJ,KAAK,EAAE,+BAAiB;YACxB,sBAAsB,EAAE,qBAAqB,EAAE;SAChD,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n  PermissionSpecificationBuilder,\n  RestrictedMethodOptions,\n  ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { GetEntropyParams, GetEntropyResult } from '@metamask/snaps-sdk';\nimport { SIP_6_MAGIC_VALUE } from '@metamask/snaps-utils';\nimport type { Infer } from '@metamask/superstruct';\nimport { literal, object, optional, string } from '@metamask/superstruct';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { assertStruct } from '@metamask/utils';\n\nimport type { MethodHooksObject } from '../utils';\nimport { getValueFromEntropySource, deriveEntropyFromSeed } from '../utils';\n\nconst targetName = 'snap_getEntropy';\n\ntype GetEntropySpecificationBuilderOptions = {\n  allowedCaveats?: Readonly<NonEmptyArray<string>> | null;\n  methodHooks: GetEntropyHooks;\n};\n\ntype GetEntropySpecification = ValidPermissionSpecification<{\n  permissionType: PermissionType.RestrictedMethod;\n  targetName: typeof targetName;\n  methodImplementation: ReturnType<typeof getEntropyImplementation>;\n  allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n}>;\n\nexport const GetEntropyArgsStruct = object({\n  version: literal(1),\n  salt: optional(string()),\n  source: optional(string()),\n});\n\n/**\n * @property version - The version of the `snap_getEntropy` method. This must be\n * the numeric literal `1`.\n * @property salt - A string to use as the salt when deriving the entropy. If\n * omitted, the salt will be an empty string.\n */\nexport type GetEntropyArgs = Infer<typeof GetEntropyArgsStruct>;\n\nconst specificationBuilder: PermissionSpecificationBuilder<\n  PermissionType.RestrictedMethod,\n  GetEntropySpecificationBuilderOptions,\n  GetEntropySpecification\n> = ({\n  allowedCaveats = null,\n  methodHooks,\n}: GetEntropySpecificationBuilderOptions) => {\n  return {\n    permissionType: PermissionType.RestrictedMethod,\n    targetName,\n    allowedCaveats,\n    methodImplementation: getEntropyImplementation(methodHooks),\n    subjectTypes: [SubjectType.Snap],\n  };\n};\n\nconst methodHooks: MethodHooksObject<GetEntropyHooks> = {\n  getMnemonicSeed: true,\n  getUnlockPromise: true,\n  getClientCryptography: true,\n};\n\nexport const getEntropyBuilder = Object.freeze({\n  targetName,\n  specificationBuilder,\n  methodHooks,\n} as const);\n\nexport type GetEntropyHooks = {\n  /**\n   * Get the mnemonic seed of the provided source. If no source is provided, the\n   * mnemonic seed of the primary keyring will be returned.\n   *\n   * @param source - The optional ID of the source to get the mnemonic of.\n   * @returns The mnemonic seed of the provided source, or the default source if no\n   * source is provided.\n   */\n  getMnemonicSeed: (source?: string | undefined) => Promise<Uint8Array>;\n\n  /**\n   * Waits for the extension to be unlocked.\n   *\n   * @returns A promise that resolves once the extension is unlocked.\n   */\n  getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n  /**\n   * Get the cryptographic functions to use for the client. This may return an\n   * empty object or `undefined` to fall back to the default cryptographic\n   * functions.\n   *\n   * @returns The cryptographic functions to use for the client.\n   */\n  getClientCryptography: () => CryptographicFunctions | undefined;\n};\n\n/**\n * Builds the method implementation for `snap_getEntropy`. The implementation\n * is based on the reference implementation of\n * [SIP-6](https://metamask.github.io/SIPs/SIPS/sip-6).\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.getMnemonicSeed - A function to retrieve the BIP-39 seed\n * of the user.\n * @param hooks.getUnlockPromise - The method to get a promise that resolves\n * once the extension is unlocked.\n * @param hooks.getClientCryptography - A function to retrieve the cryptographic\n * functions to use for the client.\n * @returns The method implementation.\n */\nfunction getEntropyImplementation({\n  getMnemonicSeed,\n  getUnlockPromise,\n  getClientCryptography,\n}: GetEntropyHooks) {\n  return async function getEntropy(\n    options: RestrictedMethodOptions<GetEntropyParams>,\n  ): Promise<GetEntropyResult> {\n    const {\n      params,\n      context: { origin },\n    } = options;\n\n    assertStruct(\n      params,\n      GetEntropyArgsStruct,\n      'Invalid \"snap_getEntropy\" parameters',\n      rpcErrors.invalidParams,\n    );\n\n    await getUnlockPromise(true);\n    const seed = await getValueFromEntropySource(\n      getMnemonicSeed,\n      params.source,\n    );\n\n    return deriveEntropyFromSeed({\n      input: origin,\n      salt: params.salt,\n      seed,\n      magic: SIP_6_MAGIC_VALUE,\n      cryptographicFunctions: getClientCryptography(),\n    });\n  };\n}\n"]}