{"version":3,"file":"controllers.mjs","sourceRoot":"","sources":["../src/controllers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n  caip25CaveatBuilder,\n  Caip25CaveatType,\n} from '@metamask/chain-agnostic-permission';\nimport type {\n  MessengerActions,\n  MessengerEvents,\n  MockAnyNamespace,\n} from '@metamask/messenger';\nimport { Messenger } from '@metamask/messenger';\nimport type { PermissionControllerMessenger } from '@metamask/permission-controller';\nimport {\n  PermissionController,\n  SubjectMetadataController,\n  SubjectType,\n} from '@metamask/permission-controller';\nimport type {\n  ExecutionServiceMessenger,\n  SnapControllerMessenger,\n  SnapInterfaceControllerMessenger,\n  SnapRegistryControllerMessenger,\n} from '@metamask/snaps-controllers';\nimport { SnapInterfaceController } from '@metamask/snaps-controllers';\nimport {\n  caveatSpecifications as snapsCaveatsSpecifications,\n  endowmentCaveatSpecifications as snapsEndowmentCaveatSpecifications,\n  processSnapPermissions,\n} from '@metamask/snaps-rpc-methods';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { SnapManifest } from '@metamask/snaps-utils';\nimport type { Hex } from '@metamask/utils';\nimport { getSafeJson } from '@metamask/utils';\n\nimport { getPermissionSpecifications } from './methods';\nimport { UNRESTRICTED_METHODS } from './methods/constants';\nimport type { SimulationOptions } from './options';\nimport type { RestrictedMiddlewareHooks } from './simulation';\nimport type { RunSagaFunction } from './store';\n\nexport type RootControllerMessenger = Messenger<\n  MockAnyNamespace,\n  MessengerActions<\n    | ExecutionServiceMessenger\n    | PermissionControllerMessenger\n    | SnapControllerMessenger\n    | SnapInterfaceControllerMessenger\n    | SnapRegistryControllerMessenger\n  >,\n  MessengerEvents<\n    | ExecutionServiceMessenger\n    | PermissionControllerMessenger\n    | SnapControllerMessenger\n    | SnapInterfaceControllerMessenger\n    | SnapRegistryControllerMessenger\n  >\n>;\n\nexport type GetControllersOptions = {\n  controllerMessenger: Messenger<any, any, any>;\n  hooks: RestrictedMiddlewareHooks;\n  runSaga: RunSagaFunction;\n  options: SimulationOptions;\n};\n\nexport type Controllers = {\n  permissionController: PermissionController;\n  subjectMetadataController: SubjectMetadataController;\n  interfaceController: SnapInterfaceController;\n};\n\n/**\n * Get the controllers for the Snap.\n *\n * @param options - The options.\n * @returns The controllers for the Snap.\n */\nexport function getControllers(options: GetControllersOptions): Controllers {\n  const { controllerMessenger } = options;\n  const subjectMetadataController = new SubjectMetadataController({\n    messenger: new Messenger({\n      namespace: 'SubjectMetadataController',\n      parent: controllerMessenger,\n    }),\n    subjectCacheLimit: 100,\n  });\n\n  const interfaceControllerMessenger: SnapInterfaceControllerMessenger =\n    new Messenger({\n      namespace: 'SnapInterfaceController',\n      parent: controllerMessenger,\n    });\n\n  controllerMessenger.delegate({\n    messenger: interfaceControllerMessenger,\n    actions: [\n      'PhishingController:testOrigin',\n      'ApprovalController:hasRequest',\n      'ApprovalController:acceptRequest',\n      'AccountsController:getAccountByAddress',\n      'AccountsController:getSelectedMultichainAccount',\n      'AccountsController:listMultichainAccounts',\n      'MultichainAssetsController:getState',\n      'PermissionController:hasPermission',\n    ],\n    events: ['NotificationServicesController:notificationsListUpdated'],\n  });\n\n  const interfaceController = new SnapInterfaceController({\n    messenger: interfaceControllerMessenger,\n  });\n\n  const permissionController = getPermissionController(options);\n\n  return {\n    permissionController,\n    subjectMetadataController,\n    interfaceController,\n  };\n}\n\n/**\n * Get the permission controller for the Snap.\n *\n * @param options - The options.\n * @param options.controllerMessenger - The controller messenger.\n * @param options.options - Miscellaneous options.\n * @returns The permission controller for the Snap.\n */\nfunction getPermissionController(options: GetControllersOptions) {\n  const { controllerMessenger } = options;\n  const permissionSpecifications = getPermissionSpecifications(options);\n  const messenger = new Messenger({\n    namespace: 'PermissionController',\n    parent: controllerMessenger,\n  });\n\n  controllerMessenger.delegate({\n    messenger,\n    actions: [\n      `ApprovalController:addRequest`,\n      `ApprovalController:hasRequest`,\n      `ApprovalController:acceptRequest`,\n      `ApprovalController:rejectRequest`,\n      `SnapController:getPermitted`,\n      `SnapController:install`,\n      `SubjectMetadataController:getSubjectMetadata`,\n    ],\n  });\n\n  const simulatedAccounts = options.options.accounts;\n  const ethereumAccounts = simulatedAccounts\n    .filter((account) =>\n      account.scopes.some((scope) => scope.startsWith('eip155')),\n    )\n    .map((account) => ({\n      type: 'eip155:eoa',\n      address: account.address as Hex,\n    }));\n\n  return new PermissionController({\n    messenger,\n    caveatSpecifications: {\n      [Caip25CaveatType]: caip25CaveatBuilder({\n        findNetworkClientIdByChainId: (chainId) => chainId,\n        isNonEvmScopeSupported: (_scope) => true,\n        getNonEvmAccountAddresses: (scope) =>\n          simulatedAccounts\n            .filter((account) => account.scopes.includes(scope))\n            .map((account) => `${scope}:${account.address}`),\n        listAccounts: () => ethereumAccounts,\n      }),\n      ...snapsCaveatsSpecifications,\n      ...snapsEndowmentCaveatSpecifications,\n    },\n    permissionSpecifications,\n    unrestrictedMethods: UNRESTRICTED_METHODS,\n  });\n}\n\n/**\n * Register the Snap. This sets up the Snap's permissions and subject metadata.\n *\n * @param snapId - The ID of the Snap to install.\n * @param manifest - The parsed manifest.\n * @param controllers - The controllers for the Snap.\n * @param controllers.permissionController - The permission controller.\n * @param controllers.subjectMetadataController - The subject metadata controller.\n */\nexport async function registerSnap(\n  snapId: SnapId,\n  manifest: SnapManifest,\n  {\n    permissionController,\n    subjectMetadataController,\n  }: Omit<Controllers, 'interfaceController'>,\n) {\n  subjectMetadataController.addSubjectMetadata({\n    origin: snapId,\n    subjectType: SubjectType.Snap,\n  });\n\n  const approvedPermissions = processSnapPermissions(\n    getSafeJson(manifest.initialPermissions),\n  );\n\n  permissionController.grantPermissions({\n    approvedPermissions,\n    subject: { origin: snapId },\n    preserveExistingPermissions: false,\n  });\n}\n"]}