@metamask/snaps-rpc-methods
Version:
MetaMask Snaps JSON-RPC method implementations
96 lines • 3.84 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.invokeKeyringHandler = void 0;
const rpc_errors_1 = require("@metamask/rpc-errors");
const snaps_utils_1 = require("@metamask/snaps-utils");
const utils_1 = require("@metamask/utils");
const invokeSnapSugar_1 = require("./invokeSnapSugar.cjs");
const hookNames = {
getAllowedKeyringMethods: true,
};
/**
* Invoke a keyring method of a Snap. This calls the `onKeyringRequest` handler
* of the Snap.
*
* The Snap must be installed and the dapp must have permission to communicate
* with the Snap, or the request is rejected. The dapp can install the Snap and
* request permission to communicate with it using [`wallet_requestSnaps`](https://docs.metamask.io/snaps/reference/snaps-api/wallet_requestsnaps).
*/
exports.invokeKeyringHandler = {
implementation: invokeKeyringImplementation,
hookNames,
actionNames: [
'PermissionController:hasPermission',
'SnapController:handleRequest',
'SnapController:getSnap',
],
};
/**
* The `wallet_invokeKeyring` method implementation.
* Invokes onKeyringRequest if the snap requested is installed and connected to the dapp.
*
* @param req - The JSON-RPC request object.
* @param res - The JSON-RPC response object.
* @param _next - The `json-rpc-engine` "next" callback. Not used by this
* function.
* @param end - The `json-rpc-engine` "end" callback.
* @param hooks - The RPC method hooks.
* @param hooks.getAllowedKeyringMethods - Get the list of allowed Keyring
* methods for a given origin.
* @param messenger - The messenger used to call controller actions.
* @returns Nothing.
*/
async function invokeKeyringImplementation(req,
// `InvokeKeyringResult` is an alias for `Json` (which is the default type
// argument for `PendingJsonRpcResponse`), but that may not be the case in the
// future. We use `InvokeKeyringResult` here to make it clear that this is the
// expected type of the result.
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-arguments
res, _next, end, { getAllowedKeyringMethods }, messenger) {
let params;
try {
params = (0, invokeSnapSugar_1.getValidatedParams)(req.params);
}
catch (error) {
return end(error);
}
const { origin } = req;
const { snapId, request } = params;
if (!origin ||
!messenger.call('PermissionController:hasPermission', origin, snaps_utils_1.WALLET_SNAP_PERMISSION_KEY)) {
return end(rpc_errors_1.rpcErrors.invalidRequest({
message: `The snap "${snapId}" is not connected to "${origin}". Please connect before invoking the snap.`,
}));
}
if (!messenger.call('SnapController:getSnap', snapId)) {
return end(
// Mirror error message from SnapController.
rpc_errors_1.rpcErrors.invalidRequest({
message: `The Snap "${snapId}" is not installed. Please install it before invoking it.`,
}));
}
if (!(0, utils_1.hasProperty)(request, 'method') || typeof request.method !== 'string') {
return end(rpc_errors_1.rpcErrors.invalidRequest({
message: 'The request must have a method.',
}));
}
const allowedMethods = getAllowedKeyringMethods();
if (!allowedMethods.includes(request.method)) {
return end(rpc_errors_1.rpcErrors.invalidRequest({
message: `The origin "${origin}" is not allowed to invoke the method "${request.method}".`,
}));
}
try {
res.result = (await messenger.call('SnapController:handleRequest', {
origin,
snapId,
request,
handler: snaps_utils_1.HandlerType.OnKeyringRequest,
}));
}
catch (error) {
return end(error);
}
return end();
}
//# sourceMappingURL=invokeKeyring.cjs.map