UNPKG

@metamask/snaps-utils

Version:
131 lines 5.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.assertIsJsonRpcSuccess = exports.isOriginAllowed = exports.assertIsKeyringOrigins = exports.KeyringOriginsStruct = exports.assertIsRpcOrigins = exports.RpcOriginsStruct = void 0; const permission_controller_1 = require("@metamask/permission-controller"); const superstruct_1 = require("@metamask/superstruct"); const utils_1 = require("@metamask/utils"); const AllowedOriginsStruct = (0, superstruct_1.array)((0, superstruct_1.refine)((0, superstruct_1.string)(), 'Allowed origin', (value) => { const wildcards = value.split('*').length - 1; if (wildcards > 2) { return 'No more than two wildcards ("*") are allowed in an origin specifier.'; } return true; })); exports.RpcOriginsStruct = (0, superstruct_1.refine)((0, superstruct_1.object)({ dapps: (0, superstruct_1.optional)((0, superstruct_1.boolean)()), snaps: (0, superstruct_1.optional)((0, superstruct_1.boolean)()), allowedOrigins: (0, superstruct_1.optional)(AllowedOriginsStruct), }), 'RPC origins', (value) => { const hasOrigins = Boolean(value.snaps === true || value.dapps === true || (value.allowedOrigins && value.allowedOrigins.length > 0)); if (hasOrigins) { return true; } return 'Must specify at least one JSON-RPC origin.'; }); /** * Asserts that the given value is a valid {@link RpcOrigins} object. * * @param value - The value to assert. * @param ErrorWrapper - An optional error wrapper to use. Defaults to * {@link AssertionError}. * @throws If the value is not a valid {@link RpcOrigins} object. */ function assertIsRpcOrigins(value, ErrorWrapper) { (0, utils_1.assertStruct)(value, exports.RpcOriginsStruct, 'Invalid JSON-RPC origins', ErrorWrapper); } exports.assertIsRpcOrigins = assertIsRpcOrigins; exports.KeyringOriginsStruct = (0, superstruct_1.object)({ allowedOrigins: (0, superstruct_1.optional)(AllowedOriginsStruct), }); /** * Assert that the given value is a valid {@link KeyringOrigins} object. * * @param value - The value to assert. * @param ErrorWrapper - An optional error wrapper to use. Defaults to * {@link AssertionError}. * @throws If the value is not a valid {@link KeyringOrigins} object. */ function assertIsKeyringOrigins(value, ErrorWrapper) { (0, utils_1.assertStruct)(value, exports.KeyringOriginsStruct, 'Invalid keyring origins', ErrorWrapper); } exports.assertIsKeyringOrigins = assertIsKeyringOrigins; /** * Create regular expression for matching against an origin while allowing wildcards. * * The "*" symbol is treated as a wildcard and will match 0 or more characters. * * @param matcher - The string to create the regular expression with. * @returns The regular expression. */ function createOriginRegExp(matcher) { // Escape potential Regex characters const escaped = matcher.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); // Support wildcards const regex = escaped.replace(/\\\*/gu, '.*'); return RegExp(`^${regex}$`, 'u'); } /** * Check whether an origin is allowed or not using a matcher string. * * The matcher string may be a specific origin to match or include wildcards. * The "*" symbol is treated as a wildcard and will match 0 or more characters. * Note: this means that https://*metamask.io matches both https://metamask.io * and https://snaps.metamask.io. * * @param matcher - The matcher string. * @param origin - The origin. * @returns Whether the origin is allowed. */ function checkAllowedOrigin(matcher, origin) { // If the matcher is a single wildcard or identical to the origin we can return true immediately. if (matcher === '*' || matcher === origin) { return true; } const regex = createOriginRegExp(matcher); return regex.test(origin); } /** * Check if the given origin is allowed by the given JSON-RPC origins object. * * @param origins - The JSON-RPC origins object. * @param subjectType - The type of the origin. * @param origin - The origin to check. * @returns Whether the origin is allowed. */ function isOriginAllowed(origins, subjectType, origin) { // The MetaMask client is always allowed. if (origin === 'metamask') { return true; } // If the origin is in the `allowedOrigins` list, it is allowed. if (origins.allowedOrigins?.some((matcher) => checkAllowedOrigin(matcher, origin))) { return true; } // If the origin is a website and `dapps` is true, it is allowed. if (subjectType === permission_controller_1.SubjectType.Website && origins.dapps) { return true; } // If the origin is a snap and `snaps` is true, it is allowed. return Boolean(subjectType === permission_controller_1.SubjectType.Snap && origins.snaps); } exports.isOriginAllowed = isOriginAllowed; /** * Assert that the given value is a successful JSON-RPC response. If the value * is not a success response, an error is thrown. If the value is an JSON-RPC * error, the error message is included in the thrown error. * * @param value - The value to check. * @throws If the value is not a JSON-RPC success response. */ function assertIsJsonRpcSuccess(value) { if (!(0, utils_1.isJsonRpcSuccess)(value)) { if ((0, utils_1.isJsonRpcFailure)(value)) { throw new Error(`JSON-RPC request failed: ${value.error.message}`); } throw new Error('Invalid JSON-RPC response.'); } } exports.assertIsJsonRpcSuccess = assertIsJsonRpcSuccess; //# sourceMappingURL=json-rpc.cjs.map