@metamask/snaps-rpc-methods
Version:
MetaMask Snaps JSON-RPC method implementations
99 lines • 3.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEntropyBuilder = exports.GetEntropyArgsStruct = void 0;
const permission_controller_1 = require("@metamask/permission-controller");
const rpc_errors_1 = require("@metamask/rpc-errors");
const snaps_utils_1 = require("@metamask/snaps-utils");
const superstruct_1 = require("@metamask/superstruct");
const utils_1 = require("@metamask/utils");
const utils_2 = require("../utils.cjs");
const targetName = 'snap_getEntropy';
exports.GetEntropyArgsStruct = (0, superstruct_1.object)({
version: (0, superstruct_1.literal)(1),
salt: (0, superstruct_1.optional)((0, superstruct_1.string)()),
source: (0, superstruct_1.optional)((0, superstruct_1.string)()),
});
const specificationBuilder = ({ allowedCaveats = null, methodHooks, messenger, }) => {
return {
permissionType: permission_controller_1.PermissionType.RestrictedMethod,
targetName,
allowedCaveats,
methodImplementation: getEntropyImplementation({ methodHooks, messenger }),
subjectTypes: [permission_controller_1.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)
* ```
*/
exports.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;
(0, utils_1.assertStruct)(params, exports.GetEntropyArgsStruct, 'Invalid "snap_getEntropy" parameters', rpc_errors_1.rpcErrors.invalidParams);
await getUnlockPromise(true);
const seed = await (0, utils_2.getValueFromEntropySource)(utils_2.getMnemonicSeed.bind(null, messenger), params.source);
return (0, utils_2.deriveEntropyFromSeed)({
input: origin,
salt: params.salt,
seed,
magic: snaps_utils_1.SIP_6_MAGIC_VALUE,
cryptographicFunctions: getClientCryptography(),
});
};
}
//# sourceMappingURL=getEntropy.cjs.map