@metamask/snaps-simulation
Version:
A simulation framework for MetaMask Snaps, enabling headless testing of Snaps in a controlled environment
101 lines • 4.13 kB
JavaScript
import { PermissionController, SubjectMetadataController, SubjectType } from "@metamask/permission-controller";
import { SnapInterfaceController } from "@metamask/snaps-controllers";
import { caveatSpecifications as snapsCaveatsSpecifications, endowmentCaveatSpecifications as snapsEndowmentCaveatSpecifications, processSnapPermissions } from "@metamask/snaps-rpc-methods";
import { getSafeJson } from "@metamask/utils";
import { getPermissionSpecifications } from "./methods/index.mjs";
import { UNRESTRICTED_METHODS } from "./methods/constants.mjs";
/**
* Get the controllers for the Snap.
*
* @param options - The options.
* @returns The controllers for the Snap.
*/
export function getControllers(options) {
const { controllerMessenger } = options;
const subjectMetadataController = new SubjectMetadataController({
messenger: controllerMessenger.getRestricted({
name: 'SubjectMetadataController',
allowedActions: [],
allowedEvents: [],
}),
subjectCacheLimit: 100,
});
const interfaceController = new SnapInterfaceController({
messenger: controllerMessenger.getRestricted({
name: 'SnapInterfaceController',
allowedActions: [
'PhishingController:testOrigin',
'ApprovalController:hasRequest',
'ApprovalController:acceptRequest',
'AccountsController:getAccountByAddress',
'AccountsController:getSelectedMultichainAccount',
'AccountsController:listMultichainAccounts',
'MultichainAssetsController:getState',
],
allowedEvents: [
'NotificationServicesController:notificationsListUpdated',
],
}),
});
const permissionController = getPermissionController(options);
return {
permissionController,
subjectMetadataController,
interfaceController,
};
}
/**
* Get the permission controller for the Snap.
*
* @param options - The options.
* @param options.controllerMessenger - The controller messenger.
* @param options.options - Miscellaneous options.
* @returns The permission controller for the Snap.
*/
function getPermissionController(options) {
const { controllerMessenger } = options;
const permissionSpecifications = getPermissionSpecifications(options);
return new PermissionController({
messenger: controllerMessenger.getRestricted({
name: 'PermissionController',
allowedActions: [
`ApprovalController:addRequest`,
`ApprovalController:hasRequest`,
`ApprovalController:acceptRequest`,
`ApprovalController:rejectRequest`,
`SnapController:getPermitted`,
`SnapController:install`,
`SubjectMetadataController:getSubjectMetadata`,
],
allowedEvents: [],
}),
caveatSpecifications: {
...snapsCaveatsSpecifications,
...snapsEndowmentCaveatSpecifications,
},
permissionSpecifications,
unrestrictedMethods: UNRESTRICTED_METHODS,
});
}
/**
* Register the Snap. This sets up the Snap's permissions and subject metadata.
*
* @param snapId - The ID of the Snap to install.
* @param manifest - The parsed manifest.
* @param controllers - The controllers for the Snap.
* @param controllers.permissionController - The permission controller.
* @param controllers.subjectMetadataController - The subject metadata controller.
*/
export async function registerSnap(snapId, manifest, { permissionController, subjectMetadataController, }) {
subjectMetadataController.addSubjectMetadata({
origin: snapId,
subjectType: SubjectType.Snap,
});
const approvedPermissions = processSnapPermissions(getSafeJson(manifest.initialPermissions));
permissionController.grantPermissions({
approvedPermissions,
subject: { origin: snapId },
preserveExistingPermissions: false,
});
}
//# sourceMappingURL=controllers.mjs.map