UNPKG

@metamask/snaps-rpc-methods

Version:
96 lines 3.51 kB
import { PermissionType, SubjectType } from "@metamask/permission-controller"; import { rpcErrors } from "@metamask/rpc-errors"; import { SIP_6_MAGIC_VALUE } from "@metamask/snaps-utils"; import { literal, object, optional, string } from "@metamask/superstruct"; import { assertStruct } from "@metamask/utils"; import { deriveEntropyFromSeed, getMnemonicSeed, getValueFromEntropySource } from "../utils.mjs"; const targetName = 'snap_getEntropy'; export const GetEntropyArgsStruct = object({ version: literal(1), salt: optional(string()), source: optional(string()), }); const specificationBuilder = ({ allowedCaveats = null, methodHooks, messenger, }) => { return { permissionType: PermissionType.RestrictedMethod, targetName, allowedCaveats, methodImplementation: getEntropyImplementation({ methodHooks, messenger }), subjectTypes: [SubjectType.Snap], }; }; const methodHooks = { getUnlockPromise: true, getClientCryptography: true, }; /** * Get a deterministic 256-bit entropy value, specific to the Snap and the * user's account. You can use this entropy to generate a private key, or any * other value that requires a high level of randomness. Other Snaps can't * access this entropy, and it changes if the user's secret recovery phrase * changes. * * You can optionally specify a salt to generate different entropy for different * purposes. Using a salt results in entropy unrelated to the entropy generated * without a salt. * * This value is deterministic: it's always the same for the same Snap, user * account, and salt. * * @example * ```json name="Manifest" * { * "initialPermissions": { * "snap_getEntropy": {} * } * } * ``` * ```ts name="Usage" * const entropy = await snap.request({ * method: 'snap_getEntropy', * params: { * version: 1, * salt: 'foo', // Optional. * }, * }) * * // '0x...' * console.log(entropy) * ``` */ export const getEntropyBuilder = Object.freeze({ targetName, specificationBuilder, methodHooks, actionNames: ['KeyringController:withKeyringV2Unsafe'], }); /** * Builds the method implementation for `snap_getEntropy`. The implementation * is based on the reference implementation of * [SIP-6](https://metamask.github.io/SIPs/SIPS/sip-6). * * @param options - The options. * @param options.messenger - The messenger. * @param options.methodHooks - The RPC method hooks. * @param options.methodHooks.getUnlockPromise - The method to get a promise that resolves * once the extension is unlocked. * @param options.methodHooks.getClientCryptography - A function to retrieve the cryptographic * functions to use for the client. * @returns The method implementation. */ function getEntropyImplementation({ methodHooks: { getUnlockPromise, getClientCryptography }, messenger, }) { return async function getEntropy(options) { const { params, context: { origin }, } = options; assertStruct(params, GetEntropyArgsStruct, 'Invalid "snap_getEntropy" parameters', rpcErrors.invalidParams); await getUnlockPromise(true); const seed = await getValueFromEntropySource(getMnemonicSeed.bind(null, messenger), params.source); return deriveEntropyFromSeed({ input: origin, salt: params.salt, seed, magic: SIP_6_MAGIC_VALUE, cryptographicFunctions: getClientCryptography(), }); }; } //# sourceMappingURL=getEntropy.mjs.map