@metamask/snaps-controllers 0.26.0 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/snaps/SnapController.d.ts +1 -1
- package/dist/snaps/SnapController.js +9 -7
- package/dist/snaps/SnapController.js.map +1 -1
- package/dist/snaps/location/http.js +4 -6
- package/dist/snaps/location/http.js.map +1 -1
- package/dist/snaps/location/location.d.ts +6 -0
- package/dist/snaps/location/location.js +2 -2
- package/dist/snaps/location/location.js.map +1 -1
- package/dist/snaps/location/npm.d.ts +2 -8
- package/dist/snaps/location/npm.js +5 -7
- package/dist/snaps/location/npm.js.map +1 -1
- package/dist/utils.d.ts +0 -7
- package/dist/utils.js +1 -17
- package/dist/utils.js.map +1 -1
- package/package.json +5 -5
|
@@ -331,7 +331,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
|
|
|
331
331
|
#private;
|
|
332
332
|
private readonly maxRequestTime;
|
|
333
333
|
private readonly snapsRuntimeData;
|
|
334
|
-
constructor({ closeAllConnections, messenger, state, getAppKey, environmentEndowmentPermissions,
|
|
334
|
+
constructor({ closeAllConnections, messenger, state, getAppKey, environmentEndowmentPermissions, idleTimeCheckInterval, checkBlockList, maxIdleTime, maxRequestTime, fetchFunction, featureFlags, detectSnapLocation: detectSnapLocationFunction, }: SnapControllerArgs);
|
|
335
335
|
/**
|
|
336
336
|
* Checks all installed snaps against the block list and
|
|
337
337
|
* blocks/unblocks snaps as appropriate. See {@link SnapController.blockSnap}
|
|
@@ -21,7 +21,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
21
21
|
}
|
|
22
22
|
return t;
|
|
23
23
|
};
|
|
24
|
-
var _SnapController_instances, _SnapController_closeAllConnections, _SnapController_environmentEndowmentPermissions, _SnapController_featureFlags, _SnapController_fetchFunction, _SnapController_idleTimeCheckInterval, _SnapController_checkSnapBlockList, _SnapController_maxIdleTime,
|
|
24
|
+
var _SnapController_instances, _SnapController_closeAllConnections, _SnapController_environmentEndowmentPermissions, _SnapController_featureFlags, _SnapController_fetchFunction, _SnapController_idleTimeCheckInterval, _SnapController_checkSnapBlockList, _SnapController_maxIdleTime, _SnapController_detectSnapLocation, _SnapController_rollbackSnapshots, _SnapController_getAppKey, _SnapController_timeoutForLastRequestStatus, _SnapController_statusMachine, _SnapController_initializeStateMachine, _SnapController_registerMessageHandlers, _SnapController_pollForLastRequestStatus, _SnapController_blockSnap, _SnapController_unblockSnap, _SnapController_assertIsUnblocked, _SnapController_stopSnapsLastRequestPastMax, _SnapController_transition, _SnapController_terminateSnap, _SnapController_getEncryptionKey, _SnapController_encryptSnapState, _SnapController_decryptSnapState, _SnapController_add, _SnapController_startSnap, _SnapController_getEndowments, _SnapController_set, _SnapController_fetchSnap, _SnapController_processSnapPermissions, _SnapController_getRpcRequestHandler, _SnapController_executeWithTimeout, _SnapController_recordSnapRpcRequestStart, _SnapController_recordSnapRpcRequestFinish, _SnapController_getRollbackSnapshot, _SnapController_createRollbackSnapshot, _SnapController_rollbackSnap, _SnapController_rollbackSnaps, _SnapController_getRuntime, _SnapController_getRuntimeExpect, _SnapController_setupRuntime, _SnapController_calculatePermissionsChange, _SnapController_isValidUpdate;
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.SnapController = exports.AppKeyType = exports.SNAP_APPROVAL_UPDATE = exports.SNAP_APPROVAL_INSTALL = exports.controllerName = void 0;
|
|
27
27
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -85,7 +85,7 @@ const name = 'SnapController';
|
|
|
85
85
|
* - Start: Initializes the snap in its SES realm with the authorized permissions.
|
|
86
86
|
*/
|
|
87
87
|
class SnapController extends base_controller_1.BaseControllerV2 {
|
|
88
|
-
constructor({ closeAllConnections, messenger, state, getAppKey, environmentEndowmentPermissions = [],
|
|
88
|
+
constructor({ closeAllConnections, messenger, state, getAppKey, environmentEndowmentPermissions = [], idleTimeCheckInterval = (0, utils_1.inMilliseconds)(5, utils_1.Duration.Second), checkBlockList, maxIdleTime = (0, utils_1.inMilliseconds)(30, utils_1.Duration.Second), maxRequestTime = (0, utils_1.inMilliseconds)(60, utils_1.Duration.Second), fetchFunction = globalThis.fetch.bind(globalThis), featureFlags = {}, detectSnapLocation: detectSnapLocationFunction = location_1.detectSnapLocation, }) {
|
|
89
89
|
var _a, _b;
|
|
90
90
|
super({
|
|
91
91
|
messenger,
|
|
@@ -135,7 +135,6 @@ class SnapController extends base_controller_1.BaseControllerV2 {
|
|
|
135
135
|
_SnapController_idleTimeCheckInterval.set(this, void 0);
|
|
136
136
|
_SnapController_checkSnapBlockList.set(this, void 0);
|
|
137
137
|
_SnapController_maxIdleTime.set(this, void 0);
|
|
138
|
-
_SnapController_npmRegistryUrl.set(this, void 0);
|
|
139
138
|
_SnapController_detectSnapLocation.set(this, void 0);
|
|
140
139
|
_SnapController_rollbackSnapshots.set(this, void 0);
|
|
141
140
|
_SnapController_getAppKey.set(this, void 0);
|
|
@@ -150,7 +149,6 @@ class SnapController extends base_controller_1.BaseControllerV2 {
|
|
|
150
149
|
__classPrivateFieldSet(this, _SnapController_checkSnapBlockList, checkBlockList, "f");
|
|
151
150
|
__classPrivateFieldSet(this, _SnapController_maxIdleTime, maxIdleTime, "f");
|
|
152
151
|
this.maxRequestTime = maxRequestTime;
|
|
153
|
-
__classPrivateFieldSet(this, _SnapController_npmRegistryUrl, npmRegistryUrl, "f");
|
|
154
152
|
__classPrivateFieldSet(this, _SnapController_detectSnapLocation, detectSnapLocationFunction, "f");
|
|
155
153
|
this._onUnhandledSnapError = this._onUnhandledSnapError.bind(this);
|
|
156
154
|
this._onOutboundRequest = this._onOutboundRequest.bind(this);
|
|
@@ -618,7 +616,10 @@ class SnapController extends base_controller_1.BaseControllerV2 {
|
|
|
618
616
|
*/
|
|
619
617
|
async processRequestedSnap(origin, snapId, versionRange) {
|
|
620
618
|
(0, snaps_utils_1.validateSnapId)(snapId);
|
|
621
|
-
const location = __classPrivateFieldGet(this, _SnapController_detectSnapLocation, "f").call(this, snapId, {
|
|
619
|
+
const location = __classPrivateFieldGet(this, _SnapController_detectSnapLocation, "f").call(this, snapId, {
|
|
620
|
+
versionRange,
|
|
621
|
+
fetch: __classPrivateFieldGet(this, _SnapController_fetchFunction, "f"),
|
|
622
|
+
});
|
|
622
623
|
const existingSnap = this.getTruncated(snapId);
|
|
623
624
|
// For devX we always re-install local snaps.
|
|
624
625
|
if (existingSnap && !location.shouldAlwaysReload) {
|
|
@@ -843,7 +844,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
|
|
|
843
844
|
}
|
|
844
845
|
}
|
|
845
846
|
exports.SnapController = SnapController;
|
|
846
|
-
_SnapController_closeAllConnections = new WeakMap(), _SnapController_environmentEndowmentPermissions = new WeakMap(), _SnapController_featureFlags = new WeakMap(), _SnapController_fetchFunction = new WeakMap(), _SnapController_idleTimeCheckInterval = new WeakMap(), _SnapController_checkSnapBlockList = new WeakMap(), _SnapController_maxIdleTime = new WeakMap(),
|
|
847
|
+
_SnapController_closeAllConnections = new WeakMap(), _SnapController_environmentEndowmentPermissions = new WeakMap(), _SnapController_featureFlags = new WeakMap(), _SnapController_fetchFunction = new WeakMap(), _SnapController_idleTimeCheckInterval = new WeakMap(), _SnapController_checkSnapBlockList = new WeakMap(), _SnapController_maxIdleTime = new WeakMap(), _SnapController_detectSnapLocation = new WeakMap(), _SnapController_rollbackSnapshots = new WeakMap(), _SnapController_getAppKey = new WeakMap(), _SnapController_timeoutForLastRequestStatus = new WeakMap(), _SnapController_statusMachine = new WeakMap(), _SnapController_instances = new WeakSet(), _SnapController_initializeStateMachine = function _SnapController_initializeStateMachine() {
|
|
847
848
|
const disableGuard = ({ snapId }) => {
|
|
848
849
|
return this.getExpect(snapId).enabled;
|
|
849
850
|
};
|
|
@@ -1101,7 +1102,8 @@ async function _SnapController_getEndowments(snapId) {
|
|
|
1101
1102
|
}
|
|
1102
1103
|
const sourceCode = (_a = files
|
|
1103
1104
|
.find((file) => file.path === manifest.result.source.location.npm.filePath)) === null || _a === void 0 ? void 0 : _a.toString();
|
|
1104
|
-
const svgIcon = files.find((file) =>
|
|
1105
|
+
const svgIcon = files.find((file) => manifest.result.source.location.npm.iconPath !== undefined &&
|
|
1106
|
+
file.path === manifest.result.source.location.npm.iconPath);
|
|
1105
1107
|
(0, utils_1.assert)(sourceCode !== undefined);
|
|
1106
1108
|
if (typeof sourceCode !== 'string' || sourceCode.length === 0) {
|
|
1107
1109
|
throw new Error(`Invalid source code for snap "${snapId}".`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapController.js","sourceRoot":"","sources":["../../src/snaps/SnapController.ts"],"names":[],"mappings":"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","sourcesContent":["import { AddApprovalRequest } from '@metamask/approval-controller';\nimport {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { encrypt, decrypt } from '@metamask/browser-passworder';\nimport {\n Caveat,\n GetEndowments,\n GetPermissions,\n GrantPermissions,\n HasPermission,\n HasPermissions,\n PermissionConstraint,\n PermissionsRequest,\n RequestedPermissions,\n RevokeAllPermissions,\n RevokePermissionForAllSubjects,\n RevokePermissions,\n SubjectPermissions,\n ValidPermission,\n} from '@metamask/permission-controller';\nimport { caveatMappers } from '@metamask/rpc-methods';\nimport {\n assertIsSnapManifest,\n BlockedSnapInfo,\n DEFAULT_ENDOWMENTS,\n DEFAULT_REQUESTED_SNAP_VERSION,\n fromEntries,\n getSnapPermissionName,\n gtVersion,\n gtRange,\n InstallSnapsResult,\n isValidSemVerRange,\n PersistedSnap,\n ProcessSnapResult,\n RequestedSnapPermissions,\n resolveVersionRange,\n satisfiesVersionRange,\n SemVerRange,\n Snap,\n SnapId,\n SnapManifest,\n SnapPermissions,\n SnapRpcHook,\n SnapRpcHookArgs,\n SnapStatus,\n SnapStatusEvents,\n SNAP_PREFIX,\n SNAP_PREFIX_REGEX,\n StatusContext,\n StatusEvents,\n StatusStates,\n TruncatedSnap,\n TruncatedSnapFields,\n ValidatedSnapId,\n validateSnapId,\n validateSnapShasum,\n VirtualFile,\n} from '@metamask/snaps-utils';\nimport {\n GetSubjectMetadata,\n SubjectType,\n} from '@metamask/subject-metadata-controller';\nimport {\n assert,\n Duration,\n hasProperty,\n inMilliseconds,\n isNonEmptyArray,\n isValidJson,\n Json,\n NonEmptyArray,\n timeSince,\n} from '@metamask/utils';\nimport { createMachine, interpret, StateMachine } from '@xstate/fsm';\nimport { ethErrors } from 'eth-rpc-errors';\nimport type { Patch } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport { forceStrict, validateMachine } from '../fsm';\nimport {\n ExecuteSnapAction,\n ExecutionServiceEvents,\n HandleRpcRequestAction,\n SnapErrorJson,\n TerminateAllSnapsAction,\n TerminateSnapAction,\n} from '../services';\nimport { hasTimedOut, setDiff, withTimeout } from '../utils';\nimport {\n endowmentCaveatMappers,\n handlerEndowments,\n SnapEndowments,\n} from './endowments';\nimport { getRpcCaveatOrigins } from './endowments/rpc';\nimport { detectSnapLocation, SnapLocation } from './location';\nimport { RequestQueue } from './RequestQueue';\nimport { Timer } from './Timer';\n\nexport const controllerName = 'SnapController';\n\n// TODO: Figure out how to name these\nexport const SNAP_APPROVAL_INSTALL = 'wallet_installSnap';\nexport const SNAP_APPROVAL_UPDATE = 'wallet_updateSnap';\n\nconst TRUNCATED_SNAP_PROPERTIES = new Set<TruncatedSnapFields>([\n 'initialPermissions',\n 'id',\n 'permissionName',\n 'version',\n 'enabled',\n 'blocked',\n]);\n\nexport type PendingRequest = {\n requestId: unknown;\n timer: Timer;\n};\n\n/**\n * A wrapper type for any data stored during runtime of Snaps.\n * It is not persisted in state as it contains non-serializable data and is only relevant for the\n * current session.\n */\nexport interface SnapRuntimeData {\n /**\n * A promise that resolves when the Snap has finished installing\n */\n installPromise: null | Promise<PersistedSnap>;\n\n /**\n * A Unix timestamp for the last time the Snap received an RPC request\n */\n lastRequest: null | number;\n\n /**\n * The current number of active references where this Snap is being used\n */\n activeReferences: number;\n\n /**\n * The current pending inbound requests, meaning requests that are processed by snaps.\n */\n pendingInboundRequests: PendingRequest[];\n\n /**\n * The current pending outbound requests, meaning requests made from snaps towards the MetaMask\n * extension.\n */\n pendingOutboundRequests: number;\n\n /**\n * RPC handler designated for the Snap\n */\n rpcHandler: null | SnapRpcHook;\n\n /**\n * The finite state machine interpreter for possible states that the Snap can be in such as\n * stopped, running, blocked\n *\n * @see {@link SnapController:constructor}\n */\n interpreter: StateMachine.Service<StatusContext, StatusEvents, StatusStates>;\n\n /**\n * The snap source code\n */\n sourceCode: null | string;\n\n /**\n * The snap state (encrypted)\n */\n state: null | string;\n}\n\nexport type SnapError = {\n message: string;\n code: number;\n data?: Json;\n};\n\n/**\n * The return type of {@link SnapController.#fetchSnap} and its sibling methods.\n */\ntype FetchSnapResult = {\n /**\n * The manifest of the fetched Snap.\n */\n manifest: VirtualFile<SnapManifest>;\n\n /**\n * Auxillary files references in manifest.\n */\n files: VirtualFile[];\n\n /**\n * Location that was used to fetch the snap.\n *\n * Helpful if you want to pass it forward since files will be still cached.\n */\n location: SnapLocation;\n};\n\n// Types that probably should be defined elsewhere in prod\ntype CloseAllConnectionsFunction = (origin: string) => void;\ntype StoredSnaps = Record<SnapId, Snap>;\n\nexport type SnapControllerState = {\n snaps: StoredSnaps;\n // This type needs to be defined but is always empty in practice.\n // eslint-disable-next-line @typescript-eslint/ban-types\n snapStates: {};\n snapErrors: {\n [internalID: string]: SnapError & { internalID: string };\n };\n};\n\nexport type PersistedSnapControllerState = SnapControllerState & {\n snaps: Record<SnapId, PersistedSnap>;\n snapStates: Record<SnapId, string>;\n};\n\ntype RollbackSnapshot = {\n statePatches: Patch[];\n sourceCode: string | null;\n permissions: {\n revoked: unknown;\n granted: unknown[];\n requestData: unknown;\n };\n newVersion: string;\n};\n\n// Controller Messenger Actions\n\n/**\n * Gets the specified Snap from state.\n */\nexport type GetSnap = {\n type: `${typeof controllerName}:get`;\n handler: SnapController['get'];\n};\n\n/**\n * Handles sending an inbound request to a snap and returns its result.\n */\nexport type HandleSnapRequest = {\n type: `${typeof controllerName}:handleRequest`;\n handler: SnapController['handleRequest'];\n};\n\n/**\n * Gets the specified Snap's persisted state.\n */\nexport type GetSnapState = {\n type: `${typeof controllerName}:getSnapState`;\n handler: SnapController['getSnapState'];\n};\n\n/**\n * Checks if the specified snap exists in state.\n */\nexport type HasSnap = {\n type: `${typeof controllerName}:has`;\n handler: SnapController['has'];\n};\n\n/**\n * Updates the specified Snap's persisted state.\n */\nexport type UpdateSnapState = {\n type: `${typeof controllerName}:updateSnapState`;\n handler: SnapController['updateSnapState'];\n};\n\n/**\n * Clears the specified Snap's persisted state.\n */\nexport type ClearSnapState = {\n type: `${typeof controllerName}:clearSnapState`;\n handler: SnapController['clearSnapState'];\n};\n\n/**\n * Checks all installed snaps against the blocklist.\n */\nexport type UpdateBlockedSnaps = {\n type: `${typeof controllerName}:updateBlockedSnaps`;\n handler: SnapController['updateBlockedSnaps'];\n};\n\nexport type EnableSnap = {\n type: `${typeof controllerName}:enable`;\n handler: SnapController['enableSnap'];\n};\n\nexport type DisableSnap = {\n type: `${typeof controllerName}:disable`;\n handler: SnapController['disableSnap'];\n};\n\nexport type RemoveSnap = {\n type: `${typeof controllerName}:remove`;\n handler: SnapController['removeSnap'];\n};\n\nexport type GetPermittedSnaps = {\n type: `${typeof controllerName}:getPermitted`;\n handler: SnapController['getPermittedSnaps'];\n};\n\nexport type GetAllSnaps = {\n type: `${typeof controllerName}:getAll`;\n handler: SnapController['getAllSnaps'];\n};\n\nexport type IncrementActiveReferences = {\n type: `${typeof controllerName}:incrementActiveReferences`;\n handler: SnapController['incrementActiveReferences'];\n};\n\nexport type DecrementActiveReferences = {\n type: `${typeof controllerName}:decrementActiveReferences`;\n handler: SnapController['decrementActiveReferences'];\n};\n\nexport type InstallSnaps = {\n type: `${typeof controllerName}:install`;\n handler: SnapController['installSnaps'];\n};\n\nexport type RemoveSnapError = {\n type: `${typeof controllerName}:removeSnapError`;\n handler: SnapController['removeSnapError'];\n};\n\nexport type SnapControllerActions =\n | ClearSnapState\n | GetSnap\n | GetSnapState\n | HandleSnapRequest\n | HasSnap\n | UpdateBlockedSnaps\n | UpdateSnapState\n | EnableSnap\n | DisableSnap\n | RemoveSnap\n | GetPermittedSnaps\n | InstallSnaps\n | RemoveSnapError\n | GetAllSnaps\n | IncrementActiveReferences\n | DecrementActiveReferences;\n\n// Controller Messenger Events\n\nexport type SnapStateChange = {\n type: `${typeof controllerName}:stateChange`;\n payload: [SnapControllerState, Patch[]];\n};\n\n/**\n * Emitted when a Snap has been added to state during installation.\n */\nexport type SnapAdded = {\n type: `${typeof controllerName}:snapAdded`;\n payload: [snap: Snap, svgIcon: string | undefined];\n};\n\n/**\n * Emitted when an installed snap has been blocked.\n */\nexport type SnapBlocked = {\n type: `${typeof controllerName}:snapBlocked`;\n payload: [snapId: string, blockedSnapInfo: BlockedSnapInfo];\n};\n\n/**\n * Emitted when a snap has been started after being added and authorized during\n * installation.\n */\nexport type SnapInstalled = {\n type: `${typeof controllerName}:snapInstalled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when a snap is removed.\n */\nexport type SnapRemoved = {\n type: `${typeof controllerName}:snapRemoved`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when an installed snap has been unblocked.\n */\nexport type SnapUnblocked = {\n type: `${typeof controllerName}:snapUnblocked`;\n payload: [snapId: string];\n};\n\n/**\n * Emitted when a snap is updated.\n */\nexport type SnapUpdated = {\n type: `${typeof controllerName}:snapUpdated`;\n payload: [snap: TruncatedSnap, oldVersion: string];\n};\n\n/**\n * Emitted when a snap is rolled back.\n */\nexport type SnapRolledback = {\n type: `${typeof controllerName}:snapRolledback`;\n payload: [snap: TruncatedSnap, failedVersion: string];\n};\n/**\n * Emitted when a Snap is terminated. This is different from the snap being\n * stopped as it can also be triggered when a snap fails initialization.\n */\nexport type SnapTerminated = {\n type: `${typeof controllerName}:snapTerminated`;\n payload: [snap: TruncatedSnap];\n};\n\nexport type SnapControllerEvents =\n | SnapAdded\n | SnapBlocked\n | SnapInstalled\n | SnapRemoved\n | SnapStateChange\n | SnapUnblocked\n | SnapUpdated\n | SnapRolledback\n | SnapTerminated;\n\nexport type AllowedActions =\n | GetEndowments\n | GetPermissions\n | GetSubjectMetadata\n | HasPermission\n | HasPermissions\n | RevokePermissions\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | GrantPermissions\n | AddApprovalRequest\n | HandleRpcRequestAction\n | ExecuteSnapAction\n | TerminateAllSnapsAction\n | TerminateSnapAction;\n\nexport type AllowedEvents = ExecutionServiceEvents;\n\ntype SnapControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n SnapControllerActions | AllowedActions,\n SnapControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nexport enum AppKeyType {\n StateEncryption = 'stateEncryption',\n}\n\ntype GetAppKey = (subject: string, appKeyType: AppKeyType) => Promise<string>;\n\ntype FeatureFlags = {\n /**\n * We still need to implement new UI approval page in metamask-extension before we can allow\n * DApps to update Snaps. After it's added, this flag can be removed.\n *\n * @see {SNAP_APPROVAL_UPDATE}\n * @see {SnapController.processRequestedSnap}\n */\n dappsCanUpdateSnaps?: true;\n};\n\ntype SemVerVersion = string;\ntype SnapInfo = { version: SemVerVersion; shasum: string };\nexport type CheckSnapBlockListArg = Record<SnapId, SnapInfo>;\n\nexport type CheckSnapBlockListResult = Record<\n SnapId,\n | {\n blocked: true;\n reason?: string;\n infoUrl?: string;\n }\n | { blocked: false }\n>;\n\n/**\n * Checks whether a version of a snap is blocked.\n */\nexport type CheckSnapBlockList = (\n snapsToCheck: CheckSnapBlockListArg,\n) => Promise<CheckSnapBlockListResult>;\n\ntype SnapControllerArgs = {\n /**\n * A teardown function that allows the host to clean up its instrumentation\n * for a running snap.\n */\n closeAllConnections: CloseAllConnectionsFunction;\n\n /**\n * The names of endowment permissions whose values are the names of JavaScript\n * APIs that will be added to the snap execution environment at runtime.\n */\n environmentEndowmentPermissions: string[];\n\n /**\n * The function that will be used by the controller fo make network requests.\n * Should be compatible with {@link fetch}.\n */\n fetchFunction?: typeof fetch;\n\n /**\n * Flags that enable or disable features in the controller.\n * See {@link FeatureFlags}.\n */\n featureFlags: FeatureFlags;\n\n /**\n * A function to get an \"app key\" for a specific subject.\n */\n getAppKey: GetAppKey;\n\n /**\n * How frequently to check whether a snap is idle.\n */\n idleTimeCheckInterval?: number;\n\n /**\n * A function that checks whether the specified snap and version is blocked.\n */\n checkBlockList: CheckSnapBlockList;\n\n /**\n * The maximum amount of time that a snap may be idle.\n */\n maxIdleTime?: number;\n\n /**\n * The controller messenger.\n */\n messenger: SnapControllerMessenger;\n\n /**\n * The maximum amount of time a snap may take to process an RPC request,\n * unless it is permitted to take longer.\n */\n maxRequestTime?: number;\n\n /**\n * The npm registry URL that will be used to fetch published snaps.\n */\n npmRegistryUrl?: string;\n\n /**\n * Persisted state that will be used for rehydration.\n */\n state?: PersistedSnapControllerState;\n\n /**\n * A function that takes Snap Id and converts it into a class that fetches files.\n *\n * Used for test overrides.\n */\n detectSnapLocation?: typeof detectSnapLocation;\n};\ntype AddSnapArgs = {\n id: SnapId;\n origin: string;\n location: SnapLocation;\n};\n\n// When we set a snap, we need all required properties to be present and\n// validated.\ntype SetSnapArgs = Omit<AddSnapArgs, 'id' | 'location'> & {\n id: ValidatedSnapId;\n manifest: VirtualFile<SnapManifest>;\n files: VirtualFile[];\n /**\n * @default '*'\n */\n // TODO(ritave): Used only for validation in #set, should be moved elsewhere.\n versionRange?: SemVerRange;\n isUpdate?: boolean;\n};\n\nconst defaultState: SnapControllerState = {\n snapErrors: {},\n snaps: {},\n snapStates: {},\n};\n\n/**\n * Truncates the properties of a snap to only ones that are easily serializable.\n *\n * @param snap - The snap to truncate.\n * @returns Object with serializable snap properties.\n */\nfunction truncateSnap(snap: Snap): TruncatedSnap {\n const truncatedSnap = Object.keys(snap).reduce<Partial<TruncatedSnap>>(\n (serialized, key) => {\n if (TRUNCATED_SNAP_PROPERTIES.has(key as any)) {\n serialized[key as keyof TruncatedSnap] = snap[\n key as keyof TruncatedSnap\n ] as any;\n }\n\n return serialized;\n },\n {},\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return truncatedSnap as TruncatedSnap;\n}\n\nconst name = 'SnapController';\n\n/*\n * A snap is initialized in three phases:\n * - Add: Loads the snap from a remote source and parses it.\n * - Authorize: Requests the snap's required permissions from the user.\n * - Start: Initializes the snap in its SES realm with the authorized permissions.\n */\n\nexport class SnapController extends BaseController<\n string,\n SnapControllerState,\n SnapControllerMessenger\n> {\n #closeAllConnections: CloseAllConnectionsFunction;\n\n #environmentEndowmentPermissions: string[];\n\n #featureFlags: FeatureFlags;\n\n #fetchFunction: typeof fetch;\n\n #idleTimeCheckInterval: number;\n\n #checkSnapBlockList: CheckSnapBlockList;\n\n #maxIdleTime: number;\n\n // This property cannot be hash private yet because of tests.\n private readonly maxRequestTime: number;\n\n #npmRegistryUrl?: string;\n\n #detectSnapLocation: typeof detectSnapLocation;\n\n // This property cannot be hash private yet because of tests.\n private readonly snapsRuntimeData: Map<SnapId, SnapRuntimeData>;\n\n #rollbackSnapshots: Map<SnapId, RollbackSnapshot>;\n\n #getAppKey: GetAppKey;\n\n #timeoutForLastRequestStatus?: number;\n\n #statusMachine!: StateMachine.Machine<\n StatusContext,\n StatusEvents,\n StatusStates\n >;\n\n constructor({\n closeAllConnections,\n messenger,\n state,\n getAppKey,\n environmentEndowmentPermissions = [],\n npmRegistryUrl,\n idleTimeCheckInterval = inMilliseconds(5, Duration.Second),\n checkBlockList,\n maxIdleTime = inMilliseconds(30, Duration.Second),\n maxRequestTime = inMilliseconds(60, Duration.Second),\n fetchFunction = globalThis.fetch.bind(globalThis),\n featureFlags = {},\n detectSnapLocation: detectSnapLocationFunction = detectSnapLocation,\n }: SnapControllerArgs) {\n super({\n messenger,\n metadata: {\n snapErrors: {\n persist: false,\n anonymous: false,\n },\n snapStates: {\n persist: () => {\n return Object.keys(this.state.snaps).reduce<\n Record<string, string | null>\n >((acc, cur) => {\n acc[cur] = this.#getRuntimeExpect(cur).state;\n return acc;\n }, {});\n },\n anonymous: false,\n },\n snaps: {\n persist: (snaps) => {\n return Object.values(snaps)\n .map((snap) => {\n return {\n ...snap,\n sourceCode: this.#getRuntimeExpect(snap.id).sourceCode,\n // At the time state is rehydrated, no snap will be running.\n status: SnapStatus.Stopped,\n };\n })\n .reduce((memo: Record<string, Snap>, snap) => {\n memo[snap.id] = snap;\n return memo;\n }, {});\n },\n anonymous: false,\n },\n },\n name,\n state: {\n ...defaultState,\n ...{\n ...state,\n snaps: Object.values(state?.snaps ?? {}).reduce(\n (memo: Record<string, Snap>, snap) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { sourceCode, ...rest } = snap;\n memo[snap.id] = rest;\n return memo;\n },\n {},\n ),\n },\n },\n });\n\n this.#closeAllConnections = closeAllConnections;\n this.#environmentEndowmentPermissions = environmentEndowmentPermissions;\n this.#featureFlags = featureFlags;\n this.#fetchFunction = fetchFunction;\n this.#getAppKey = getAppKey;\n this.#idleTimeCheckInterval = idleTimeCheckInterval;\n this.#checkSnapBlockList = checkBlockList;\n this.#maxIdleTime = maxIdleTime;\n this.maxRequestTime = maxRequestTime;\n this.#npmRegistryUrl = npmRegistryUrl;\n this.#detectSnapLocation = detectSnapLocationFunction;\n this._onUnhandledSnapError = this._onUnhandledSnapError.bind(this);\n this._onOutboundRequest = this._onOutboundRequest.bind(this);\n this._onOutboundResponse = this._onOutboundResponse.bind(this);\n this.#rollbackSnapshots = new Map();\n this.snapsRuntimeData = new Map();\n this.#pollForLastRequestStatus();\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.subscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.#initializeStateMachine();\n this.#registerMessageHandlers();\n\n Object.values(state?.snaps ?? {}).forEach((snap) =>\n this.#setupRuntime(snap.id, {\n sourceCode: snap.sourceCode,\n state: state?.snapStates?.[snap.id] ?? null,\n }),\n );\n }\n\n /**\n * We track status of a Snap using a finite-state-machine.\n * It keeps track of whether the snap is started / stopped / etc.\n *\n * @see {@link SnapController.transition} for interacting with the machine.\n */\n // We initialize the machine in the instance because the status is currently tightly coupled\n // with the SnapController - the guard checks for enabled status inside the SnapController state.\n // In the future, side-effects could be added to the machine during transitions.\n #initializeStateMachine() {\n const disableGuard = ({ snapId }: StatusContext) => {\n return this.getExpect(snapId).enabled;\n };\n\n const statusConfig: StateMachine.Config<\n StatusContext,\n StatusEvents,\n StatusStates\n > = {\n initial: SnapStatus.Installing,\n states: {\n [SnapStatus.Installing]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n [SnapStatus.Updating]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n [SnapStatus.Running]: {\n on: {\n [SnapStatusEvents.Stop]: SnapStatus.Stopped,\n [SnapStatusEvents.Crash]: SnapStatus.Crashed,\n },\n },\n [SnapStatus.Stopped]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Update]: SnapStatus.Updating,\n },\n },\n [SnapStatus.Crashed]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n },\n };\n this.#statusMachine = createMachine(statusConfig);\n validateMachine(this.#statusMachine);\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:clearSnapState`,\n (...args) => this.clearSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:get`,\n (...args) => this.get(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSnapState`,\n async (...args) => this.getSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:has`,\n (...args) => this.has(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateBlockedSnaps`,\n async () => this.updateBlockedSnaps(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateSnapState`,\n async (...args) => this.updateSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:enable`,\n (...args) => this.enableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disable`,\n async (...args) => this.disableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:remove`,\n async (...args) => this.removeSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getPermitted`,\n (...args) => this.getPermittedSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:install`,\n async (...args) => this.installSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:removeSnapError`,\n (...args) => this.removeSnapError(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAll`,\n (...args) => this.getAllSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:incrementActiveReferences`,\n (...args) => this.incrementActiveReferences(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:decrementActiveReferences`,\n (...args) => this.decrementActiveReferences(...args),\n );\n }\n\n #pollForLastRequestStatus() {\n this.#timeoutForLastRequestStatus = setTimeout(() => {\n this.#stopSnapsLastRequestPastMax().catch((error) => {\n // TODO: Decide how to handle errors.\n console.error(error);\n });\n\n this.#pollForLastRequestStatus();\n }, this.#idleTimeCheckInterval) as unknown as number;\n }\n\n /**\n * Checks all installed snaps against the block list and\n * blocks/unblocks snaps as appropriate. See {@link SnapController.blockSnap}\n * for more information.\n */\n async updateBlockedSnaps(): Promise<void> {\n const blockedSnaps = await this.#checkSnapBlockList(\n Object.values(this.state.snaps).reduce<CheckSnapBlockListArg>(\n (blockListArg, snap) => {\n blockListArg[snap.id] = {\n version: snap.version,\n shasum: snap.manifest.source.shasum,\n };\n return blockListArg;\n },\n {},\n ),\n );\n\n await Promise.all(\n Object.entries(blockedSnaps).map(\n async ([snapId, { blocked, ...blockData }]) => {\n if (blocked) {\n return this.#blockSnap(snapId, blockData);\n }\n\n return this.#unblockSnap(snapId);\n },\n ),\n );\n }\n\n /**\n * Blocks an installed snap and prevents it from being started again. Emits\n * {@link SnapBlocked}. Does nothing if the snap is not installed.\n *\n * @param snapId - The snap to block.\n * @param blockedSnapInfo - Information detailing why the snap is blocked.\n */\n async #blockSnap(\n snapId: SnapId,\n blockedSnapInfo: BlockedSnapInfo,\n ): Promise<void> {\n if (!this.has(snapId)) {\n return;\n }\n\n try {\n this.update((state: any) => {\n state.snaps[snapId].blocked = true;\n state.snaps[snapId].blockInformation = blockedSnapInfo;\n });\n\n await this.disableSnap(snapId);\n } catch (error) {\n console.error(\n `Encountered error when stopping blocked snap \"${snapId}\".`,\n error,\n );\n }\n\n this.messagingSystem.publish(\n `${controllerName}:snapBlocked`,\n snapId,\n blockedSnapInfo,\n );\n }\n\n /**\n * Unblocks a snap so that it can be enabled and started again. Emits\n * {@link SnapUnblocked}. Does nothing if the snap is not installed or already\n * unblocked.\n *\n * @param snapId - The id of the snap to unblock.\n */\n #unblockSnap(snapId: SnapId) {\n if (!this.has(snapId) || !this.state.snaps[snapId].blocked) {\n return;\n }\n\n this.update((state: any) => {\n state.snaps[snapId].blocked = false;\n delete state.snaps[snapId].blockInformation;\n });\n\n this.messagingSystem.publish(`${controllerName}:snapUnblocked`, snapId);\n }\n\n /**\n * Checks the block list to determine whether a version of a snap is blocked.\n *\n * @param snapId - The snap id to check.\n * @param snapInfo - Snap information containing version and shasum.\n * @returns Whether the version of the snap is blocked or not.\n */\n async isBlocked(\n snapId: ValidatedSnapId,\n snapInfo: SnapInfo,\n ): Promise<boolean> {\n const result = await this.#checkSnapBlockList({\n [snapId]: snapInfo,\n });\n return result[snapId].blocked;\n }\n\n /**\n * Asserts that a version of a snap is not blocked. Succeeds automatically\n * if {@link SnapController._checkSnapBlockList} is undefined.\n *\n * @param snapId - The id of the snap to check.\n * @param snapInfo - Snap information containing version and shasum.\n */\n async #assertIsUnblocked(snapId: ValidatedSnapId, snapInfo: SnapInfo) {\n if (await this.isBlocked(snapId, snapInfo)) {\n throw new Error(\n `Cannot install version \"${snapInfo.version}\" of snap \"${snapId}\": the version is blocked.`,\n );\n }\n }\n\n async #stopSnapsLastRequestPastMax() {\n const entries = [...this.snapsRuntimeData.entries()];\n return Promise.all(\n entries\n .filter(\n ([_snapId, runtime]) =>\n runtime.activeReferences === 0 &&\n runtime.pendingInboundRequests.length === 0 &&\n // lastRequest should always be set here but TypeScript wants this check\n runtime.lastRequest &&\n this.#maxIdleTime &&\n timeSince(runtime.lastRequest) > this.#maxIdleTime,\n )\n .map(async ([snapId]) => this.stopSnap(snapId, SnapStatusEvents.Stop)),\n );\n }\n\n _onUnhandledSnapError(snapId: SnapId, error: SnapErrorJson) {\n this.stopSnap(snapId, SnapStatusEvents.Crash)\n .then(() => this.addSnapError(error))\n .catch((stopSnapError) => {\n // TODO: Decide how to handle errors.\n console.error(stopSnapError);\n });\n }\n\n _onOutboundRequest(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n // Ideally we would only pause the pending request that is making the outbound request\n // but right now we don't have a way to know which request initiated the outbound request\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'running')\n .forEach((pendingRequest) => pendingRequest.timer.pause());\n runtime.pendingOutboundRequests += 1;\n }\n\n _onOutboundResponse(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingOutboundRequests -= 1;\n if (runtime.pendingOutboundRequests === 0) {\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'paused')\n .forEach((pendingRequest) => pendingRequest.timer.resume());\n }\n }\n\n /**\n * Transitions between states using `snapStatusStateMachineConfig` as the template to figure out\n * the next state. This transition function uses a very minimal subset of XState conventions:\n * - supports initial state\n * - .on supports raw event target string\n * - .on supports {target, cond} object\n * - the arguments for `cond` is the `SerializedSnap` instead of Xstate convention of `(event,\n * context) => boolean`\n *\n * @param snapId - The id of the snap to transition.\n * @param event - The event enum to use to transition.\n */\n #transition(snapId: SnapId, event: StatusEvents | StatusEvents['type']) {\n const { interpreter } = this.#getRuntimeExpect(snapId);\n interpreter.send(event);\n this.update((state: any) => {\n state.snaps[snapId].status = interpreter.state.value;\n });\n }\n\n /**\n * Starts the given snap. Throws an error if no such snap exists\n * or if it is already running.\n *\n * @param snapId - The id of the Snap to start.\n */\n async startSnap(snapId: SnapId): Promise<void> {\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (this.state.snaps[snapId].enabled === false) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n assert(runtime.sourceCode);\n\n await this.#startSnap({\n snapId,\n sourceCode: runtime.sourceCode,\n });\n }\n\n /**\n * Enables the given snap. A snap can only be started if it is enabled. A snap\n * can only be enabled if it isn't blocked.\n *\n * @param snapId - The id of the Snap to enable.\n */\n enableSnap(snapId: SnapId): void {\n this.getExpect(snapId);\n\n if (this.state.snaps[snapId].blocked) {\n throw new Error(`Snap \"${snapId}\" is blocked and cannot be enabled.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = true;\n });\n }\n\n /**\n * Disables the given snap. A snap can only be started if it is enabled.\n *\n * @param snapId - The id of the Snap to disable.\n * @returns A promise that resolves once the snap has been disabled.\n */\n async disableSnap(snapId: SnapId): Promise<void> {\n if (!this.has(snapId)) {\n throw new Error(`Snap \"${snapId}\" not found.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = false;\n });\n\n if (this.isRunning(snapId)) {\n return this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n return Promise.resolve();\n }\n\n /**\n * Stops the given snap, removes all hooks, closes all connections, and\n * terminates its worker.\n *\n * @param snapId - The id of the Snap to stop.\n * @param statusEvent - The Snap status event that caused the snap to be\n * stopped.\n */\n public async stopSnap(\n snapId: SnapId,\n statusEvent:\n | SnapStatusEvents.Stop\n | SnapStatusEvents.Crash = SnapStatusEvents.Stop,\n ): Promise<void> {\n const runtime = this.#getRuntime(snapId);\n if (!runtime) {\n throw new Error(`The snap \"${snapId}\" is not running.`);\n }\n\n // Reset request tracking\n runtime.lastRequest = null;\n runtime.pendingInboundRequests = [];\n runtime.pendingOutboundRequests = 0;\n try {\n if (this.isRunning(snapId)) {\n this.#closeAllConnections(snapId);\n await this.#terminateSnap(snapId);\n }\n } finally {\n if (this.isRunning(snapId)) {\n this.#transition(snapId, statusEvent);\n }\n }\n }\n\n /**\n * Terminates the specified snap and emits the `snapTerminated` event.\n *\n * @param snapId - The snap to terminate.\n */\n async #terminateSnap(snapId: SnapId) {\n await this.messagingSystem.call('ExecutionService:terminateSnap', snapId);\n this.messagingSystem.publish(\n 'SnapController:snapTerminated',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Returns whether the given snap is running.\n * Throws an error if the snap doesn't exist.\n *\n * @param snapId - The id of the Snap to check.\n * @returns `true` if the snap is running, otherwise `false`.\n */\n isRunning(snapId: SnapId): boolean {\n return this.getExpect(snapId).status === 'running';\n }\n\n /**\n * Returns whether the given snap has been added to state.\n *\n * @param snapId - The id of the Snap to check for.\n * @returns `true` if the snap exists in the controller state, otherwise `false`.\n */\n has(snapId: SnapId): boolean {\n return Boolean(this.get(snapId));\n }\n\n /**\n * Gets the snap with the given id if it exists, including all data.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @param snapId - The id of the Snap to get.\n * @returns The entire snap object from the controller state.\n */\n get(snapId: SnapId): Snap | undefined {\n return this.state.snaps[snapId];\n }\n\n /**\n * Gets the snap with the given id, throws if doesn't.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @see {@link SnapController.get}\n * @throws {@link Error}. If the snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns The entire snap object.\n */\n getExpect(snapId: SnapId): Snap {\n const snap = this.get(snapId);\n assert(snap !== undefined, new Error(`Snap \"${snapId}\" not found.`));\n return snap;\n }\n\n /**\n * Gets the snap with the given id if it exists, excluding any\n * non-serializable or expensive-to-serialize data.\n *\n * @param snapId - The id of the Snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n // TODO(ritave): this.get returns undefined, this.getTruncated returns null\n getTruncated(snapId: SnapId): TruncatedSnap | null {\n const snap = this.get(snapId);\n\n return snap ? truncateSnap(snap) : null;\n }\n\n /**\n * Gets the snap with the given id, throw if it doesn't exist.\n *\n * @throws {@link Error}. If snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n getTruncatedExpect(snapId: SnapId): TruncatedSnap {\n return truncateSnap(this.getExpect(snapId));\n }\n\n /**\n * Updates the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be updated.\n * @param newSnapState - The new state of the snap.\n */\n async updateSnapState(snapId: SnapId, newSnapState: Json): Promise<void> {\n const encrypted = await this.#encryptSnapState(snapId, newSnapState);\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.state = encrypted;\n }\n\n /**\n * Clears the state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be cleared.\n */\n clearSnapState(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.state = null;\n }\n\n /**\n * Adds error from a snap to the SnapController state.\n *\n * @param snapError - The error to store on the SnapController.\n */\n addSnapError(snapError: SnapError): void {\n this.update((state: any) => {\n const id = nanoid();\n state.snapErrors[id] = {\n ...snapError,\n internalID: id,\n };\n });\n }\n\n /**\n * Removes an error by internalID from the SnapControllers state.\n *\n * @param internalID - The internal error ID to remove on the SnapController.\n */\n removeSnapError(internalID: string) {\n this.update((state: any) => {\n delete state.snapErrors[internalID];\n });\n }\n\n /**\n * Clears all errors from the SnapControllers state.\n */\n clearSnapErrors() {\n this.update((state: any) => {\n state.snapErrors = {};\n });\n }\n\n /**\n * Gets the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state to get.\n * @returns A promise that resolves with the decrypted snap state or null if no state exists.\n * @throws If the snap state decryption fails.\n */\n async getSnapState(snapId: SnapId): Promise<Json> {\n const { state } = this.#getRuntimeExpect(snapId);\n return state ? this.#decryptSnapState(snapId, state) : null;\n }\n\n async #getEncryptionKey(snapId: SnapId): Promise<string> {\n return this.#getAppKey(snapId, AppKeyType.StateEncryption);\n }\n\n async #encryptSnapState(snapId: SnapId, state: Json): Promise<string> {\n const appKey = await this.#getEncryptionKey(snapId);\n return encrypt(appKey, state);\n }\n\n async #decryptSnapState(snapId: SnapId, encrypted: string): Promise<Json> {\n const appKey = await this.#getEncryptionKey(snapId);\n try {\n const value = await decrypt(appKey, encrypted);\n\n assert(isValidJson(value));\n return value;\n } catch (error) {\n throw new Error(\n 'Failed to decrypt snap state, the state must be corrupted.',\n );\n }\n }\n\n /**\n * Completely clear the controller's state: delete all associated data,\n * handlers, event listeners, and permissions; tear down all snap providers.\n */\n async clearState() {\n const snapIds = Object.keys(this.state.snaps);\n snapIds.forEach((snapId) => {\n this.#closeAllConnections(snapId);\n });\n\n await this.messagingSystem.call('ExecutionService:terminateAllSnaps');\n snapIds.forEach((snapId) => this.revokeAllSnapPermissions(snapId));\n\n this.update((state: any) => {\n state.snaps = {};\n state.snapStates = {};\n });\n }\n\n /**\n * Removes the given snap from state, and clears all associated handlers\n * and listeners.\n *\n * @param snapId - The id of the Snap.\n * @returns A promise that resolves once the snap has been removed.\n */\n async removeSnap(snapId: SnapId): Promise<void> {\n return this.removeSnaps([snapId]);\n }\n\n /**\n * Stops the given snaps, removes them from state, and clears all associated\n * permissions, handlers, and listeners.\n *\n * @param snapIds - The ids of the Snaps.\n */\n async removeSnaps(snapIds: string[]): Promise<void> {\n if (!Array.isArray(snapIds)) {\n throw new Error('Expected array of snap ids.');\n }\n\n await Promise.all(\n snapIds.map(async (snapId) => {\n const truncated = this.getTruncatedExpect(snapId);\n // Disable the snap and revoke all of its permissions before deleting\n // it. This ensures that the snap will not be restarted or otherwise\n // affect the host environment while we are deleting it.\n await this.disableSnap(snapId);\n this.revokeAllSnapPermissions(snapId);\n\n const permissionName = getSnapPermissionName(snapId);\n // Revoke all subjects access to the snap\n this.messagingSystem.call(\n 'PermissionController:revokePermissionForAllSubjects',\n permissionName,\n );\n\n this.snapsRuntimeData.delete(snapId);\n\n this.update((state: any) => {\n delete state.snaps[snapId];\n delete state.snapStates[snapId];\n });\n\n this.messagingSystem.publish(`SnapController:snapRemoved`, truncated);\n }),\n );\n }\n\n /**\n * Safely revokes all permissions granted to a Snap.\n *\n * @param snapId - The snap ID.\n */\n private revokeAllSnapPermissions(snapId: string) {\n if (\n this.messagingSystem.call('PermissionController:hasPermissions', snapId)\n ) {\n this.messagingSystem.call(\n 'PermissionController:revokeAllPermissions',\n snapId,\n );\n }\n }\n\n /**\n * Handles incrementing the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced.\n */\n incrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.activeReferences += 1;\n }\n\n /**\n * Handles decrement the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced..\n */\n decrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n assert(\n runtime.activeReferences > 0,\n 'SnapController reference management is in an invalid state.',\n );\n runtime.activeReferences -= 1;\n }\n\n /**\n * Gets all snaps in their truncated format.\n *\n * @returns All installed snaps in their truncated format.\n */\n getAllSnaps(): TruncatedSnap[] {\n return Object.values(this.state.snaps).map(truncateSnap);\n }\n\n /**\n * Gets the serialized permitted snaps of the given origin, if any.\n *\n * @param origin - The origin whose permitted snaps to retrieve.\n * @returns The serialized permitted snaps for the origin.\n */\n getPermittedSnaps(origin: string): InstallSnapsResult {\n return Object.values(\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) ?? {},\n ).reduce<InstallSnapsResult>((permittedSnaps, perm) => {\n if (perm.parentCapability.startsWith(SNAP_PREFIX)) {\n const snapId = perm.parentCapability.replace(SNAP_PREFIX_REGEX, '');\n const snap = this.get(snapId);\n const truncatedSnap = this.getTruncated(snapId);\n\n if (truncatedSnap && snap?.status !== SnapStatus.Installing) {\n permittedSnaps[snapId] = truncatedSnap;\n }\n }\n return permittedSnaps;\n }, {});\n }\n\n /**\n * Installs the snaps requested by the given origin, returning the snap\n * object if the origin is permitted to install it, and an authorization error\n * otherwise.\n *\n * @param origin - The origin that requested to install the snaps.\n * @param requestedSnaps - The snaps to install.\n * @returns An object of snap ids and snap objects, or errors if a\n * snap couldn't be installed.\n */\n async installSnaps(\n origin: string,\n requestedSnaps: RequestedSnapPermissions,\n ): Promise<InstallSnapsResult> {\n const result: InstallSnapsResult = {};\n\n const snapIds = Object.keys(requestedSnaps);\n\n // Existing snaps may need to be updated\n const pendingUpdates = snapIds.filter((snapId) => this.has(snapId));\n\n // Non-existing snaps will need to be installed\n const pendingInstalls = snapIds.filter(\n (snapId) => !pendingUpdates.includes(snapId),\n );\n\n try {\n for (const [snapId, { version: rawVersion }] of Object.entries(\n requestedSnaps,\n )) {\n const [error, version] = resolveVersionRange(rawVersion);\n\n if (error) {\n throw ethErrors.rpc.invalidParams(\n `The \"version\" field must be a valid SemVer version range if specified. Received: \"${rawVersion}\".`,\n );\n }\n\n const permissionName = getSnapPermissionName(snapId);\n\n if (\n !this.messagingSystem.call(\n 'PermissionController:hasPermission',\n origin,\n permissionName,\n )\n ) {\n throw ethErrors.provider.unauthorized(\n `Not authorized to install snap \"${snapId}\". Request the permission for the snap before attempting to install it.`,\n );\n }\n\n const isUpdate = pendingUpdates.includes(snapId);\n\n if (isUpdate && this.#isValidUpdate(snapId, version)) {\n let rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot === undefined) {\n const prevSourceCode = this.#getRuntimeExpect(snapId).sourceCode;\n rollbackSnapshot = this.#createRollbackSnapshot(snapId);\n rollbackSnapshot.sourceCode = prevSourceCode;\n rollbackSnapshot.newVersion = version;\n } else {\n throw new Error('This snap is already being updated.');\n }\n }\n\n result[snapId] = await this.processRequestedSnap(\n origin,\n snapId,\n version,\n );\n }\n snapIds.forEach((snapId) => this.#rollbackSnapshots.delete(snapId));\n } catch (error) {\n const installed = pendingInstalls.filter((snapId) => this.has(snapId));\n await this.removeSnaps(installed);\n const snapshottedSnaps = [...this.#rollbackSnapshots.keys()];\n const snapsToRollback = pendingUpdates.filter((snapId) =>\n snapshottedSnaps.includes(snapId),\n );\n await this.#rollbackSnaps(snapsToRollback);\n\n throw error;\n }\n return result;\n }\n\n /**\n * Adds, authorizes, and runs the given snap with a snap provider.\n * Results from this method should be efficiently serializable.\n *\n * @param origin - The origin requesting the snap.\n * @param snapId - The id of the snap.\n * @param versionRange - The semver range of the snap to install.\n * @returns The resulting snap object, or an error if something went wrong.\n */\n private async processRequestedSnap(\n origin: string,\n snapId: SnapId,\n versionRange: SemVerRange,\n ): Promise<ProcessSnapResult> {\n validateSnapId(snapId);\n\n const location = this.#detectSnapLocation(snapId, { versionRange });\n\n const existingSnap = this.getTruncated(snapId);\n // For devX we always re-install local snaps.\n if (existingSnap && !location.shouldAlwaysReload) {\n if (satisfiesVersionRange(existingSnap.version, versionRange)) {\n return existingSnap;\n }\n\n if (this.#featureFlags.dappsCanUpdateSnaps === true) {\n const updateResult = await this.updateSnap(\n origin,\n snapId,\n versionRange,\n location,\n );\n if (updateResult === null) {\n throw ethErrors.rpc.invalidParams(\n `Snap \"${snapId}@${existingSnap.version}\" is already installed. Couldn't update to a version inside requested \"${versionRange}\" range.`,\n );\n }\n return updateResult;\n }\n throw ethErrors.rpc.invalidParams(\n `Version mismatch with already installed snap. ${snapId}@${existingSnap.version} doesn't satisfy requested version ${versionRange}.`,\n );\n }\n\n // Existing snaps must be stopped before overwriting\n if (existingSnap && this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n try {\n const { sourceCode } = await this.#add({\n origin,\n id: snapId,\n location,\n });\n\n await this.authorize(origin, snapId);\n\n await this.#startSnap({\n snapId,\n sourceCode,\n });\n\n const truncated = this.getTruncatedExpect(snapId);\n\n this.messagingSystem.publish(`SnapController:snapInstalled`, truncated);\n return truncated;\n } catch (error) {\n console.error(`Error when adding snap.`, error);\n\n throw error;\n }\n }\n\n /**\n * Updates an installed snap. The flow is similar to\n * {@link SnapController.installSnaps}. The user will be asked if they want\n * to update, then approve any permission changes, and finally the snap will\n * be restarted.\n *\n * The update will fail if the user rejects any prompt or if the new version\n * of the snap is blocked.\n *\n * If the original version of the snap was blocked and the update succeeded,\n * the snap will be unblocked and enabled before it is restarted.\n *\n * @param origin - The origin requesting the snap update.\n * @param snapId - The id of the Snap to be updated.\n * @param newVersionRange - A semver version range in which the maximum version will be chosen.\n * @param location - Optional location that was already used during installation flow.\n * @returns The snap metadata if updated, `null` otherwise.\n */\n async updateSnap(\n origin: string,\n snapId: ValidatedSnapId,\n newVersionRange: string = DEFAULT_REQUESTED_SNAP_VERSION,\n location?: SnapLocation,\n ): Promise<TruncatedSnap | null> {\n const snap = this.getExpect(snapId);\n\n if (!isValidSemVerRange(newVersionRange)) {\n throw new Error(\n `Received invalid snap version range: \"${newVersionRange}\".`,\n );\n }\n const newSnap = await this.#fetchSnap(\n snapId,\n location ??\n this.#detectSnapLocation(snapId, { versionRange: newVersionRange }),\n );\n const newVersion = newSnap.manifest.result.version;\n if (!gtVersion(newVersion, snap.version)) {\n console.warn(\n `Tried updating snap \"${snapId}\" within \"${newVersionRange}\" version range, but newer version \"${snap.version}\" is already installed`,\n );\n return null;\n }\n\n await this.#assertIsUnblocked(snapId, {\n version: newVersion,\n shasum: newSnap.manifest.result.source.shasum,\n });\n\n const processedPermissions = this.#processSnapPermissions(\n newSnap.manifest.result.initialPermissions,\n );\n\n const { newPermissions, unusedPermissions, approvedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n const id = nanoid();\n const { permissions: approvedNewPermissions, ...requestData } =\n (await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type: SNAP_APPROVAL_UPDATE,\n requestData: {\n // First two keys mirror installation params\n metadata: { id, origin: snapId, dappOrigin: origin },\n permissions: newPermissions,\n snapId,\n newVersion: newSnap.manifest.result.version,\n newPermissions,\n approvedPermissions,\n unusedPermissions,\n },\n },\n true,\n )) as PermissionsRequest;\n\n if (this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n this.#transition(snapId, SnapStatusEvents.Update);\n\n this.#set({\n origin,\n id: snapId,\n manifest: newSnap.manifest,\n files: newSnap.files,\n versionRange: newVersionRange,\n isUpdate: true,\n });\n\n const unusedPermissionsKeys = Object.keys(unusedPermissions);\n if (isNonEmptyArray(unusedPermissionsKeys)) {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: unusedPermissionsKeys,\n });\n }\n\n if (isNonEmptyArray(Object.keys(approvedNewPermissions))) {\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions: approvedNewPermissions,\n subject: { origin: snapId },\n requestData,\n });\n }\n\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.permissions.revoked = unusedPermissions;\n rollbackSnapshot.permissions.granted = Object.keys(\n approvedNewPermissions,\n );\n rollbackSnapshot.permissions.requestData = requestData;\n }\n\n const sourceCode = newSnap.files\n .find(\n (file) =>\n file.path === newSnap.manifest.result.source.location.npm.filePath,\n )\n ?.toString();\n assert(sourceCode !== undefined);\n\n try {\n await this.#startSnap({ snapId, sourceCode });\n } catch {\n throw new Error(`Snap ${snapId} crashed with updated source code.`);\n }\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n this.messagingSystem.publish(\n 'SnapController:snapUpdated',\n truncatedSnap,\n snap.version,\n );\n\n return truncatedSnap;\n }\n\n /**\n * Returns a promise representing the complete installation of the requested snap.\n * If the snap is already being installed, the previously pending promise will be returned.\n *\n * @param args - Object containing the snap id and either the URL of the snap's manifest,\n * or the snap's manifest and source code. The object may also optionally contain a target\n * version.\n * @returns The resulting snap object.\n */\n async #add(args: AddSnapArgs): Promise<PersistedSnap> {\n const { id: snapId, location } = args;\n validateSnapId(snapId);\n\n this.#setupRuntime(snapId, { sourceCode: null, state: null });\n const runtime = this.#getRuntimeExpect(snapId);\n if (!runtime.installPromise) {\n console.info(`Adding snap: ${snapId}`);\n\n // If fetching and setting the snap succeeds, this property will be set\n // to null in the authorize() method.\n runtime.installPromise = (async () => {\n const fetchedSnap = await this.#fetchSnap(snapId, location);\n await this.#assertIsUnblocked(snapId, {\n version: fetchedSnap.manifest.result.version,\n shasum: fetchedSnap.manifest.result.source.shasum,\n });\n\n return this.#set({\n ...args,\n ...fetchedSnap,\n id: snapId,\n });\n })();\n }\n\n try {\n return await runtime.installPromise;\n } catch (error) {\n // Reset promise so users can retry installation in case the problem is\n // temporary.\n runtime.installPromise = null;\n throw error;\n }\n }\n\n async #startSnap(snapData: { snapId: string; sourceCode: string }) {\n const { snapId } = snapData;\n if (this.isRunning(snapId)) {\n throw new Error(`Snap \"${snapId}\" is already started.`);\n }\n\n try {\n const result = await this.#executeWithTimeout(\n snapId,\n this.messagingSystem.call('ExecutionService:executeSnap', {\n ...snapData,\n endowments: await this.#getEndowments(snapId),\n }),\n );\n this.#transition(snapId, SnapStatusEvents.Start);\n return result;\n } catch (error) {\n await this.#terminateSnap(snapId);\n throw error;\n }\n }\n\n /**\n * Gets the names of all endowments that will be added to the Snap's\n * Compartment when it executes. These should be the names of global\n * JavaScript APIs accessible in the root realm of the execution environment.\n *\n * Throws an error if the endowment getter for a permission returns a truthy\n * value that is not an array of strings.\n *\n * @param snapId - The id of the snap whose SES endowments to get.\n * @returns An array of the names of the endowments.\n */\n async #getEndowments(snapId: string): Promise<string[]> {\n let allEndowments: string[] = [];\n\n for (const permissionName of this.#environmentEndowmentPermissions) {\n if (\n this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n )\n ) {\n const endowments = await this.messagingSystem.call(\n 'PermissionController:getEndowments',\n snapId,\n permissionName,\n );\n\n if (endowments) {\n // We don't have any guarantees about the type of the endowments\n // value, so we have to guard at runtime.\n if (\n !Array.isArray(endowments) ||\n endowments.some((value) => typeof value !== 'string')\n ) {\n throw new Error('Expected an array of string endowment names.');\n }\n\n allEndowments = allEndowments.concat(endowments as string[]);\n }\n }\n }\n\n const dedupedEndowments = [\n ...new Set([...DEFAULT_ENDOWMENTS, ...allEndowments]),\n ];\n\n if (\n dedupedEndowments.length <\n // This is a bug in TypeScript: https://github.com/microsoft/TypeScript/issues/48313\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n DEFAULT_ENDOWMENTS.length + allEndowments.length\n ) {\n console.error(\n 'Duplicate endowments found. Default endowments should not be requested.',\n allEndowments,\n );\n }\n return dedupedEndowments;\n }\n\n /**\n * Sets a snap in state. Called when a snap is installed or updated. Performs\n * various validation checks on the received arguments, and will throw if\n * validation fails.\n *\n * The snap will be enabled and unblocked by the time this method returns,\n * regardless of its previous state.\n *\n * See {@link SnapController.add} and {@link SnapController.updateSnap} for\n * usage.\n *\n * @param args - The add snap args.\n * @returns The resulting snap object.\n */\n #set(args: SetSnapArgs): PersistedSnap {\n const {\n id: snapId,\n origin,\n manifest,\n files,\n versionRange = DEFAULT_REQUESTED_SNAP_VERSION,\n isUpdate = false,\n } = args;\n\n assertIsSnapManifest(manifest.result);\n const { version } = manifest.result;\n\n if (!satisfiesVersionRange(version, versionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${version}\" which doesn't satisfy requested version range \"${versionRange}\"`,\n );\n }\n\n const sourceCode = files\n .find(\n (file) => file.path === manifest.result.source.location.npm.filePath,\n )\n ?.toString();\n const svgIcon = files.find(\n (file) => file.path === manifest.result.source.location.npm.iconPath,\n );\n assert(sourceCode !== undefined);\n if (typeof sourceCode !== 'string' || sourceCode.length === 0) {\n throw new Error(`Invalid source code for snap \"${snapId}\".`);\n }\n\n const snapsState = this.state.snaps;\n\n const existingSnap = snapsState[snapId];\n\n const previousVersionHistory = existingSnap?.versionHistory ?? [];\n const versionHistory = [\n ...previousVersionHistory,\n {\n version,\n date: Date.now(),\n origin,\n },\n ];\n\n const snap: Snap = {\n // Restore relevant snap state if it exists\n ...existingSnap,\n\n // Note that the snap will be unblocked and enabled, regardless of its\n // previous state.\n blocked: false,\n enabled: true,\n\n // So we can easily correlate the snap with its permission\n permissionName: getSnapPermissionName(snapId),\n\n id: snapId,\n initialPermissions: manifest.result.initialPermissions,\n manifest: manifest.result,\n status: this.#statusMachine.config.initial as StatusStates['value'],\n version,\n versionHistory,\n };\n // If the snap was blocked, it isn't any longer\n delete snap.blockInformation;\n\n // store the snap back in state\n const { inversePatches } = this.update((state: any) => {\n state.snaps[snapId] = snap;\n });\n\n // checking for isUpdate here as this function is also used in\n // the install flow, we do not care to create snapshots for installs\n if (isUpdate) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.statePatches = inversePatches;\n }\n }\n\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.sourceCode = sourceCode;\n\n this.messagingSystem.publish(\n `SnapController:snapAdded`,\n snap,\n svgIcon?.toString(),\n );\n return { ...snap, sourceCode };\n }\n\n /**\n * Fetches the manifest and source code of a snap.\n *\n * This function is not hash private yet because of tests.\n *\n * @param snapId - The id of the Snap.\n * @param location - Source from which snap will be fetched.\n * @returns A tuple of the Snap manifest object and the Snap source code.\n */\n async #fetchSnap(\n snapId: ValidatedSnapId,\n location: SnapLocation,\n ): Promise<FetchSnapResult> {\n try {\n const manifest = await location.manifest();\n const sourceCode = await location.fetch(\n manifest.result.source.location.npm.filePath,\n );\n validateSnapShasum(manifest.result, sourceCode.toString());\n const { iconPath } = manifest.result.source.location.npm;\n\n const files = [sourceCode];\n if (iconPath) {\n files.push(await location.fetch(iconPath));\n }\n\n return { manifest, files, location };\n } catch (error) {\n // TODO(ritave): Export `getErrorMessage()` from @metamask/utils and use it here\n // https://github.com/MetaMask/utils/blob/62d022ef83c91fa4d150e51913be4441508a0ab1/src/assert.ts\n const message = error instanceof Error ? error.message : error.toString();\n throw new Error(`Failed to fetch Snap \"${snapId}\": ${message}.`);\n }\n }\n\n /**\n * Map initial permissions as defined in a Snap manifest to something that can\n * be processed by the PermissionsController. Each caveat mapping function\n * should return a valid permission caveat value.\n *\n * This function does not validate the caveat values, since that is done by\n * the PermissionsController itself, upon requesting the permissions.\n *\n * @param initialPermissions - The initial permissions to process.\n * @returns The processed permissions.\n * @private\n */\n #processSnapPermissions(\n initialPermissions: SnapPermissions,\n ): Record<string, Pick<PermissionConstraint, 'caveats'>> {\n return fromEntries(\n Object.entries(initialPermissions).map(([initialPermission, value]) => {\n if (hasProperty(caveatMappers, initialPermission)) {\n return [initialPermission, caveatMappers[initialPermission](value)];\n } else if (hasProperty(endowmentCaveatMappers, initialPermission)) {\n return [\n initialPermission,\n endowmentCaveatMappers[initialPermission](value),\n ];\n }\n\n // If we have no mapping, this may be a non-snap permission, return as-is\n return [\n initialPermission,\n value as Pick<PermissionConstraint, 'caveats'>,\n ];\n }),\n );\n }\n\n /**\n * Initiates a request for the given snap's initial permissions.\n * Must be called in order. See processRequestedSnap.\n *\n * This function is not hash private yet because of tests.\n *\n * @param origin - The origin of the install request.\n * @param snapId - The id of the Snap.\n * @returns The snap's approvedPermissions.\n */\n private async authorize(origin: string, snapId: SnapId): Promise<void> {\n console.info(`Authorizing snap: ${snapId}`);\n const snapsState = this.state.snaps;\n const snap = snapsState[snapId];\n const { initialPermissions } = snap;\n\n try {\n const processedPermissions =\n this.#processSnapPermissions(initialPermissions);\n const id = nanoid();\n const { permissions: approvedPermissions, ...requestData } =\n (await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type: SNAP_APPROVAL_INSTALL,\n requestData: {\n // Mirror previous installation metadata\n metadata: { id, origin: snapId, dappOrigin: origin },\n permissions: processedPermissions,\n snapId,\n },\n },\n true,\n )) as PermissionsRequest;\n\n if (isNonEmptyArray(Object.keys(approvedPermissions))) {\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin: snapId },\n requestData,\n });\n }\n } finally {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.installPromise = null;\n }\n }\n\n destroy() {\n super.destroy();\n\n if (this.#timeoutForLastRequestStatus) {\n clearTimeout(this.#timeoutForLastRequestStatus);\n }\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.unsubscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Passes a JSON-RPC request object to the RPC handler function of a snap.\n *\n * @param options - A bag of options.\n * @param options.snapId - The ID of the recipient snap.\n * @param options.origin - The origin of the RPC request.\n * @param options.handler - The handler to trigger on the snap for the request.\n * @param options.request - The JSON-RPC request object.\n * @returns The result of the JSON-RPC request.\n */\n async handleRequest({\n snapId,\n origin,\n handler: handlerType,\n request,\n }: SnapRpcHookArgs & { snapId: SnapId }): Promise<unknown> {\n const permissionName = handlerEndowments[handlerType];\n const hasPermission = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n );\n\n if (!hasPermission) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to use \"${permissionName}\".`,\n );\n }\n\n if (permissionName === SnapEndowments.Rpc) {\n const subject = this.messagingSystem.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n const isSnap = subject?.subjectType === SubjectType.Snap;\n\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n\n const rpcPermission = permissions?.[SnapEndowments.Rpc];\n assert(rpcPermission);\n\n const origins = getRpcCaveatOrigins(rpcPermission);\n assert(origins);\n\n if ((isSnap && !origins.snaps) || (!isSnap && !origins.dapps)) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to handle JSON-RPC requests from \"${origin}\".`,\n );\n }\n }\n\n const handler = await this.#getRpcRequestHandler(snapId);\n if (!handler) {\n throw new Error(\n `Snap RPC message handler not found for snap \"${snapId}\".`,\n );\n }\n\n return handler({ origin, handler: handlerType, request });\n }\n\n /**\n * Gets the RPC message handler for the given snap.\n *\n * @param snapId - The id of the Snap whose message handler to get.\n * @returns The RPC handler for the given snap.\n */\n #getRpcRequestHandler(snapId: SnapId): SnapRpcHook {\n const runtime = this.#getRuntimeExpect(snapId);\n const existingHandler = runtime.rpcHandler;\n if (existingHandler) {\n return existingHandler;\n }\n\n const requestQueue = new RequestQueue(5);\n // We need to set up this promise map to map snapIds to their respective startPromises,\n // because otherwise we would lose context on the correct startPromise.\n const startPromises = new Map<string, Promise<void>>();\n\n const rpcHandler = async ({\n origin,\n handler: handlerType,\n request,\n }: SnapRpcHookArgs) => {\n if (this.state.snaps[snapId].enabled === false) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n if (this.state.snaps[snapId].status === SnapStatus.Installing) {\n throw new Error(\n `Snap \"${snapId}\" is currently being installed. Please try again later.`,\n );\n }\n\n if (!this.isRunning(snapId)) {\n let localStartPromise = startPromises.get(snapId);\n if (!localStartPromise) {\n localStartPromise = this.startSnap(snapId);\n startPromises.set(snapId, localStartPromise);\n } else if (requestQueue.get(origin) >= requestQueue.maxQueueSize) {\n throw new Error(\n 'Exceeds maximum number of requests waiting to be resolved, please try again.',\n );\n }\n\n requestQueue.increment(origin);\n try {\n await localStartPromise;\n } finally {\n requestQueue.decrement(origin);\n // Only delete startPromise for a snap if its value hasn't changed\n if (startPromises.get(snapId) === localStartPromise) {\n startPromises.delete(snapId);\n }\n }\n }\n\n let _request = request;\n if (!hasProperty(request, 'jsonrpc')) {\n _request = { ...request, jsonrpc: '2.0' };\n } else if (request.jsonrpc !== '2.0') {\n throw ethErrors.rpc.invalidRequest({\n message: 'Invalid \"jsonrpc\" property. Must be \"2.0\" if provided.',\n data: request.jsonrpc,\n });\n }\n\n const timer = new Timer(this.maxRequestTime);\n this.#recordSnapRpcRequestStart(snapId, request.id, timer);\n\n const handleRpcRequestPromise = this.messagingSystem.call(\n 'ExecutionService:handleRpcRequest',\n snapId,\n { origin, handler: handlerType, request: _request },\n );\n\n // This will either get the result or reject due to the timeout.\n try {\n const result = await this.#executeWithTimeout(\n snapId,\n handleRpcRequestPromise,\n timer,\n );\n this.#recordSnapRpcRequestFinish(snapId, request.id);\n return result;\n } catch (error) {\n await this.stopSnap(snapId, SnapStatusEvents.Crash);\n throw error;\n }\n };\n\n runtime.rpcHandler = rpcHandler;\n return rpcHandler;\n }\n\n /**\n * Awaits the specified promise and rejects if the promise doesn't resolve\n * before the timeout.\n *\n * @param snapId - The snap id.\n * @param promise - The promise to await.\n * @param timer - An optional timer object to control the timeout.\n * @returns The result of the promise or rejects if the promise times out.\n * @template PromiseValue - The value of the Promise.\n */\n async #executeWithTimeout<PromiseValue>(\n snapId: SnapId,\n promise: Promise<PromiseValue>,\n timer?: Timer,\n ): Promise<PromiseValue> {\n const isLongRunning = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n SnapEndowments.LongRunning,\n );\n\n // Long running snaps have timeouts disabled\n if (isLongRunning) {\n return promise;\n }\n\n const result = await withTimeout(promise, timer ?? this.maxRequestTime);\n if (result === hasTimedOut) {\n throw new Error('The request timed out.');\n }\n return result;\n }\n\n #recordSnapRpcRequestStart(snapId: SnapId, requestId: unknown, timer: Timer) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests.push({ requestId, timer });\n runtime.lastRequest = null;\n }\n\n #recordSnapRpcRequestFinish(snapId: SnapId, requestId: unknown) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests = runtime.pendingInboundRequests.filter(\n (request) => request.requestId !== requestId,\n );\n\n if (runtime.pendingInboundRequests.length === 0) {\n runtime.lastRequest = Date.now();\n }\n }\n\n /**\n * Retrieves the rollback snapshot of a snap.\n *\n * @param snapId - The snap id.\n * @returns A `RollbackSnapshot` or `undefined` if one doesn't exist.\n */\n #getRollbackSnapshot(snapId: SnapId): RollbackSnapshot | undefined {\n return this.#rollbackSnapshots.get(snapId);\n }\n\n /**\n * Creates a `RollbackSnapshot` that is used to help ensure\n * atomicity in multiple snap updates.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If the snap exists before creation or if creation fails.\n * @returns A `RollbackSnapshot`.\n */\n #createRollbackSnapshot(snapId: SnapId): RollbackSnapshot {\n assert(\n this.#rollbackSnapshots.get(snapId) === undefined,\n new Error(`Snap \"${snapId}\" rollback snapshot already exists.`),\n );\n\n this.#rollbackSnapshots.set(snapId, {\n statePatches: [],\n sourceCode: '',\n permissions: { revoked: null, granted: [], requestData: null },\n newVersion: '',\n });\n\n const newRollbackSnapshot = this.#rollbackSnapshots.get(snapId);\n\n assert(\n newRollbackSnapshot !== undefined,\n new Error(`Snapshot creation failed for ${snapId}.`),\n );\n return newRollbackSnapshot;\n }\n\n /**\n * Rolls back a snap to its previous state, permissions\n * and source code based on the `RollbackSnapshot` that\n * is captured during the update process. After rolling back,\n * the function also emits an event indicating that the\n * snap has been rolled back and it clears the snapshot\n * for that snap.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If a snapshot does not exist.\n */\n async #rollbackSnap(snapId: SnapId) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (!rollbackSnapshot) {\n throw new Error('A snapshot does not exist for this snap.');\n }\n\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n\n const { statePatches, sourceCode, permissions } = rollbackSnapshot;\n\n if (statePatches?.length) {\n this.applyPatches(statePatches);\n }\n\n if (sourceCode) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.sourceCode = sourceCode;\n }\n\n if (permissions.revoked && Object.keys(permissions.revoked).length) {\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions: permissions.revoked as RequestedPermissions,\n subject: { origin: snapId },\n requestData: permissions.requestData as Record<string, unknown>,\n });\n }\n\n if (permissions.granted?.length) {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: permissions.granted as NonEmptyArray<string>,\n });\n }\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n\n this.messagingSystem.publish(\n 'SnapController:snapRolledback',\n truncatedSnap,\n rollbackSnapshot.newVersion,\n );\n\n this.#rollbackSnapshots.delete(snapId);\n }\n\n /**\n * Iterates through an array of snap ids\n * and calls `rollbackSnap` on them.\n *\n * @param snapIds - An array of snap ids.\n */\n async #rollbackSnaps(snapIds: SnapId[]) {\n for (const snapId of snapIds) {\n await this.#rollbackSnap(snapId);\n }\n }\n\n #getRuntime(snapId: SnapId): SnapRuntimeData | undefined {\n return this.snapsRuntimeData.get(snapId);\n }\n\n #getRuntimeExpect(snapId: SnapId): SnapRuntimeData {\n const runtime = this.#getRuntime(snapId);\n assert(\n runtime !== undefined,\n new Error(`Snap \"${snapId}\" runtime data not found`),\n );\n return runtime;\n }\n\n #setupRuntime(\n snapId: SnapId,\n data: { sourceCode: string | null; state: string | null },\n ) {\n if (this.snapsRuntimeData.has(snapId)) {\n return;\n }\n\n const snap = this.get(snapId);\n const interpreter = interpret(this.#statusMachine);\n interpreter.start({\n context: { snapId },\n value:\n snap?.status ??\n (this.#statusMachine.config.initial as StatusStates['value']),\n });\n\n forceStrict(interpreter);\n\n this.snapsRuntimeData.set(snapId, {\n lastRequest: null,\n rpcHandler: null,\n installPromise: null,\n activeReferences: 0,\n pendingInboundRequests: [],\n pendingOutboundRequests: 0,\n interpreter,\n ...data,\n });\n }\n\n #calculatePermissionsChange(\n snapId: SnapId,\n desiredPermissionsSet: RequestedSnapPermissions,\n ): {\n newPermissions: RequestedSnapPermissions;\n unusedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n approvedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n } {\n const oldPermissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n ) ?? {};\n\n const newPermissions = setDiff(desiredPermissionsSet, oldPermissions);\n // TODO(ritave): The assumption that these are unused only holds so long as we do not\n // permit dynamic permission requests.\n const unusedPermissions = setDiff(oldPermissions, desiredPermissionsSet);\n\n // It's a Set Intersection of oldPermissions and desiredPermissionsSet\n // oldPermissions ∖ (oldPermissions ∖ desiredPermissionsSet) ⟺ oldPermissions ∩ desiredPermissionsSet\n const approvedPermissions = setDiff(oldPermissions, unusedPermissions);\n\n return { newPermissions, unusedPermissions, approvedPermissions };\n }\n\n /**\n * Checks if a snap will pass version validation checks\n * with the new version range that is requested. The first\n * check that is done is to check if the existing snap version\n * falls inside the requested range. If it does, we want to return\n * false because we do not care to create a rollback snapshot in\n * that scenario. The second check is to ensure that the current\n * snap version is not greater than all possible versions in\n * the requested version range. If it is, then we also want\n * to return false in that scenario.\n *\n * @param snapId - The snap id.\n * @param newVersionRange - The new version range being requsted.\n * @returns `true` if validation checks pass and `false` if they do not.\n */\n #isValidUpdate(snapId: SnapId, newVersionRange: SemVerRange): boolean {\n const existingSnap = this.getExpect(snapId);\n\n if (satisfiesVersionRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n if (gtRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n return true;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SnapController.js","sourceRoot":"","sources":["../../src/snaps/SnapController.ts"],"names":[],"mappings":"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","sourcesContent":["import { AddApprovalRequest } from '@metamask/approval-controller';\nimport {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { encrypt, decrypt } from '@metamask/browser-passworder';\nimport {\n Caveat,\n GetEndowments,\n GetPermissions,\n GrantPermissions,\n HasPermission,\n HasPermissions,\n PermissionConstraint,\n PermissionsRequest,\n RequestedPermissions,\n RevokeAllPermissions,\n RevokePermissionForAllSubjects,\n RevokePermissions,\n SubjectPermissions,\n ValidPermission,\n} from '@metamask/permission-controller';\nimport { caveatMappers } from '@metamask/rpc-methods';\nimport {\n assertIsSnapManifest,\n BlockedSnapInfo,\n DEFAULT_ENDOWMENTS,\n DEFAULT_REQUESTED_SNAP_VERSION,\n fromEntries,\n getSnapPermissionName,\n gtVersion,\n gtRange,\n InstallSnapsResult,\n isValidSemVerRange,\n PersistedSnap,\n ProcessSnapResult,\n RequestedSnapPermissions,\n resolveVersionRange,\n satisfiesVersionRange,\n SemVerRange,\n Snap,\n SnapId,\n SnapManifest,\n SnapPermissions,\n SnapRpcHook,\n SnapRpcHookArgs,\n SnapStatus,\n SnapStatusEvents,\n SNAP_PREFIX,\n SNAP_PREFIX_REGEX,\n StatusContext,\n StatusEvents,\n StatusStates,\n TruncatedSnap,\n TruncatedSnapFields,\n ValidatedSnapId,\n validateSnapId,\n validateSnapShasum,\n VirtualFile,\n} from '@metamask/snaps-utils';\nimport {\n GetSubjectMetadata,\n SubjectType,\n} from '@metamask/subject-metadata-controller';\nimport {\n assert,\n Duration,\n hasProperty,\n inMilliseconds,\n isNonEmptyArray,\n isValidJson,\n Json,\n NonEmptyArray,\n timeSince,\n} from '@metamask/utils';\nimport { createMachine, interpret, StateMachine } from '@xstate/fsm';\nimport { ethErrors } from 'eth-rpc-errors';\nimport type { Patch } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport { forceStrict, validateMachine } from '../fsm';\nimport {\n ExecuteSnapAction,\n ExecutionServiceEvents,\n HandleRpcRequestAction,\n SnapErrorJson,\n TerminateAllSnapsAction,\n TerminateSnapAction,\n} from '../services';\nimport { hasTimedOut, setDiff, withTimeout } from '../utils';\nimport {\n endowmentCaveatMappers,\n handlerEndowments,\n SnapEndowments,\n} from './endowments';\nimport { getRpcCaveatOrigins } from './endowments/rpc';\nimport { detectSnapLocation, SnapLocation } from './location';\nimport { RequestQueue } from './RequestQueue';\nimport { Timer } from './Timer';\n\nexport const controllerName = 'SnapController';\n\n// TODO: Figure out how to name these\nexport const SNAP_APPROVAL_INSTALL = 'wallet_installSnap';\nexport const SNAP_APPROVAL_UPDATE = 'wallet_updateSnap';\n\nconst TRUNCATED_SNAP_PROPERTIES = new Set<TruncatedSnapFields>([\n 'initialPermissions',\n 'id',\n 'permissionName',\n 'version',\n 'enabled',\n 'blocked',\n]);\n\nexport type PendingRequest = {\n requestId: unknown;\n timer: Timer;\n};\n\n/**\n * A wrapper type for any data stored during runtime of Snaps.\n * It is not persisted in state as it contains non-serializable data and is only relevant for the\n * current session.\n */\nexport interface SnapRuntimeData {\n /**\n * A promise that resolves when the Snap has finished installing\n */\n installPromise: null | Promise<PersistedSnap>;\n\n /**\n * A Unix timestamp for the last time the Snap received an RPC request\n */\n lastRequest: null | number;\n\n /**\n * The current number of active references where this Snap is being used\n */\n activeReferences: number;\n\n /**\n * The current pending inbound requests, meaning requests that are processed by snaps.\n */\n pendingInboundRequests: PendingRequest[];\n\n /**\n * The current pending outbound requests, meaning requests made from snaps towards the MetaMask\n * extension.\n */\n pendingOutboundRequests: number;\n\n /**\n * RPC handler designated for the Snap\n */\n rpcHandler: null | SnapRpcHook;\n\n /**\n * The finite state machine interpreter for possible states that the Snap can be in such as\n * stopped, running, blocked\n *\n * @see {@link SnapController:constructor}\n */\n interpreter: StateMachine.Service<StatusContext, StatusEvents, StatusStates>;\n\n /**\n * The snap source code\n */\n sourceCode: null | string;\n\n /**\n * The snap state (encrypted)\n */\n state: null | string;\n}\n\nexport type SnapError = {\n message: string;\n code: number;\n data?: Json;\n};\n\n/**\n * The return type of {@link SnapController.#fetchSnap} and its sibling methods.\n */\ntype FetchSnapResult = {\n /**\n * The manifest of the fetched Snap.\n */\n manifest: VirtualFile<SnapManifest>;\n\n /**\n * Auxillary files references in manifest.\n */\n files: VirtualFile[];\n\n /**\n * Location that was used to fetch the snap.\n *\n * Helpful if you want to pass it forward since files will be still cached.\n */\n location: SnapLocation;\n};\n\n// Types that probably should be defined elsewhere in prod\ntype CloseAllConnectionsFunction = (origin: string) => void;\ntype StoredSnaps = Record<SnapId, Snap>;\n\nexport type SnapControllerState = {\n snaps: StoredSnaps;\n // This type needs to be defined but is always empty in practice.\n // eslint-disable-next-line @typescript-eslint/ban-types\n snapStates: {};\n snapErrors: {\n [internalID: string]: SnapError & { internalID: string };\n };\n};\n\nexport type PersistedSnapControllerState = SnapControllerState & {\n snaps: Record<SnapId, PersistedSnap>;\n snapStates: Record<SnapId, string>;\n};\n\ntype RollbackSnapshot = {\n statePatches: Patch[];\n sourceCode: string | null;\n permissions: {\n revoked: unknown;\n granted: unknown[];\n requestData: unknown;\n };\n newVersion: string;\n};\n\n// Controller Messenger Actions\n\n/**\n * Gets the specified Snap from state.\n */\nexport type GetSnap = {\n type: `${typeof controllerName}:get`;\n handler: SnapController['get'];\n};\n\n/**\n * Handles sending an inbound request to a snap and returns its result.\n */\nexport type HandleSnapRequest = {\n type: `${typeof controllerName}:handleRequest`;\n handler: SnapController['handleRequest'];\n};\n\n/**\n * Gets the specified Snap's persisted state.\n */\nexport type GetSnapState = {\n type: `${typeof controllerName}:getSnapState`;\n handler: SnapController['getSnapState'];\n};\n\n/**\n * Checks if the specified snap exists in state.\n */\nexport type HasSnap = {\n type: `${typeof controllerName}:has`;\n handler: SnapController['has'];\n};\n\n/**\n * Updates the specified Snap's persisted state.\n */\nexport type UpdateSnapState = {\n type: `${typeof controllerName}:updateSnapState`;\n handler: SnapController['updateSnapState'];\n};\n\n/**\n * Clears the specified Snap's persisted state.\n */\nexport type ClearSnapState = {\n type: `${typeof controllerName}:clearSnapState`;\n handler: SnapController['clearSnapState'];\n};\n\n/**\n * Checks all installed snaps against the blocklist.\n */\nexport type UpdateBlockedSnaps = {\n type: `${typeof controllerName}:updateBlockedSnaps`;\n handler: SnapController['updateBlockedSnaps'];\n};\n\nexport type EnableSnap = {\n type: `${typeof controllerName}:enable`;\n handler: SnapController['enableSnap'];\n};\n\nexport type DisableSnap = {\n type: `${typeof controllerName}:disable`;\n handler: SnapController['disableSnap'];\n};\n\nexport type RemoveSnap = {\n type: `${typeof controllerName}:remove`;\n handler: SnapController['removeSnap'];\n};\n\nexport type GetPermittedSnaps = {\n type: `${typeof controllerName}:getPermitted`;\n handler: SnapController['getPermittedSnaps'];\n};\n\nexport type GetAllSnaps = {\n type: `${typeof controllerName}:getAll`;\n handler: SnapController['getAllSnaps'];\n};\n\nexport type IncrementActiveReferences = {\n type: `${typeof controllerName}:incrementActiveReferences`;\n handler: SnapController['incrementActiveReferences'];\n};\n\nexport type DecrementActiveReferences = {\n type: `${typeof controllerName}:decrementActiveReferences`;\n handler: SnapController['decrementActiveReferences'];\n};\n\nexport type InstallSnaps = {\n type: `${typeof controllerName}:install`;\n handler: SnapController['installSnaps'];\n};\n\nexport type RemoveSnapError = {\n type: `${typeof controllerName}:removeSnapError`;\n handler: SnapController['removeSnapError'];\n};\n\nexport type SnapControllerActions =\n | ClearSnapState\n | GetSnap\n | GetSnapState\n | HandleSnapRequest\n | HasSnap\n | UpdateBlockedSnaps\n | UpdateSnapState\n | EnableSnap\n | DisableSnap\n | RemoveSnap\n | GetPermittedSnaps\n | InstallSnaps\n | RemoveSnapError\n | GetAllSnaps\n | IncrementActiveReferences\n | DecrementActiveReferences;\n\n// Controller Messenger Events\n\nexport type SnapStateChange = {\n type: `${typeof controllerName}:stateChange`;\n payload: [SnapControllerState, Patch[]];\n};\n\n/**\n * Emitted when a Snap has been added to state during installation.\n */\nexport type SnapAdded = {\n type: `${typeof controllerName}:snapAdded`;\n payload: [snap: Snap, svgIcon: string | undefined];\n};\n\n/**\n * Emitted when an installed snap has been blocked.\n */\nexport type SnapBlocked = {\n type: `${typeof controllerName}:snapBlocked`;\n payload: [snapId: string, blockedSnapInfo: BlockedSnapInfo];\n};\n\n/**\n * Emitted when a snap has been started after being added and authorized during\n * installation.\n */\nexport type SnapInstalled = {\n type: `${typeof controllerName}:snapInstalled`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when a snap is removed.\n */\nexport type SnapRemoved = {\n type: `${typeof controllerName}:snapRemoved`;\n payload: [snap: TruncatedSnap];\n};\n\n/**\n * Emitted when an installed snap has been unblocked.\n */\nexport type SnapUnblocked = {\n type: `${typeof controllerName}:snapUnblocked`;\n payload: [snapId: string];\n};\n\n/**\n * Emitted when a snap is updated.\n */\nexport type SnapUpdated = {\n type: `${typeof controllerName}:snapUpdated`;\n payload: [snap: TruncatedSnap, oldVersion: string];\n};\n\n/**\n * Emitted when a snap is rolled back.\n */\nexport type SnapRolledback = {\n type: `${typeof controllerName}:snapRolledback`;\n payload: [snap: TruncatedSnap, failedVersion: string];\n};\n/**\n * Emitted when a Snap is terminated. This is different from the snap being\n * stopped as it can also be triggered when a snap fails initialization.\n */\nexport type SnapTerminated = {\n type: `${typeof controllerName}:snapTerminated`;\n payload: [snap: TruncatedSnap];\n};\n\nexport type SnapControllerEvents =\n | SnapAdded\n | SnapBlocked\n | SnapInstalled\n | SnapRemoved\n | SnapStateChange\n | SnapUnblocked\n | SnapUpdated\n | SnapRolledback\n | SnapTerminated;\n\nexport type AllowedActions =\n | GetEndowments\n | GetPermissions\n | GetSubjectMetadata\n | HasPermission\n | HasPermissions\n | RevokePermissions\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | GrantPermissions\n | AddApprovalRequest\n | HandleRpcRequestAction\n | ExecuteSnapAction\n | TerminateAllSnapsAction\n | TerminateSnapAction;\n\nexport type AllowedEvents = ExecutionServiceEvents;\n\ntype SnapControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n SnapControllerActions | AllowedActions,\n SnapControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nexport enum AppKeyType {\n StateEncryption = 'stateEncryption',\n}\n\ntype GetAppKey = (subject: string, appKeyType: AppKeyType) => Promise<string>;\n\ntype FeatureFlags = {\n /**\n * We still need to implement new UI approval page in metamask-extension before we can allow\n * DApps to update Snaps. After it's added, this flag can be removed.\n *\n * @see {SNAP_APPROVAL_UPDATE}\n * @see {SnapController.processRequestedSnap}\n */\n dappsCanUpdateSnaps?: true;\n};\n\ntype SemVerVersion = string;\ntype SnapInfo = { version: SemVerVersion; shasum: string };\nexport type CheckSnapBlockListArg = Record<SnapId, SnapInfo>;\n\nexport type CheckSnapBlockListResult = Record<\n SnapId,\n | {\n blocked: true;\n reason?: string;\n infoUrl?: string;\n }\n | { blocked: false }\n>;\n\n/**\n * Checks whether a version of a snap is blocked.\n */\nexport type CheckSnapBlockList = (\n snapsToCheck: CheckSnapBlockListArg,\n) => Promise<CheckSnapBlockListResult>;\n\ntype SnapControllerArgs = {\n /**\n * A teardown function that allows the host to clean up its instrumentation\n * for a running snap.\n */\n closeAllConnections: CloseAllConnectionsFunction;\n\n /**\n * The names of endowment permissions whose values are the names of JavaScript\n * APIs that will be added to the snap execution environment at runtime.\n */\n environmentEndowmentPermissions: string[];\n\n /**\n * The function that will be used by the controller fo make network requests.\n * Should be compatible with {@link fetch}.\n */\n fetchFunction?: typeof fetch;\n\n /**\n * Flags that enable or disable features in the controller.\n * See {@link FeatureFlags}.\n */\n featureFlags: FeatureFlags;\n\n /**\n * A function to get an \"app key\" for a specific subject.\n */\n getAppKey: GetAppKey;\n\n /**\n * How frequently to check whether a snap is idle.\n */\n idleTimeCheckInterval?: number;\n\n /**\n * A function that checks whether the specified snap and version is blocked.\n */\n checkBlockList: CheckSnapBlockList;\n\n /**\n * The maximum amount of time that a snap may be idle.\n */\n maxIdleTime?: number;\n\n /**\n * The controller messenger.\n */\n messenger: SnapControllerMessenger;\n\n /**\n * The maximum amount of time a snap may take to process an RPC request,\n * unless it is permitted to take longer.\n */\n maxRequestTime?: number;\n\n /**\n * The npm registry URL that will be used to fetch published snaps.\n */\n npmRegistryUrl?: string;\n\n /**\n * Persisted state that will be used for rehydration.\n */\n state?: PersistedSnapControllerState;\n\n /**\n * A function that takes Snap Id and converts it into a class that fetches files.\n *\n * Used for test overrides.\n */\n detectSnapLocation?: typeof detectSnapLocation;\n};\ntype AddSnapArgs = {\n id: SnapId;\n origin: string;\n location: SnapLocation;\n};\n\n// When we set a snap, we need all required properties to be present and\n// validated.\ntype SetSnapArgs = Omit<AddSnapArgs, 'id' | 'location'> & {\n id: ValidatedSnapId;\n manifest: VirtualFile<SnapManifest>;\n files: VirtualFile[];\n /**\n * @default '*'\n */\n // TODO(ritave): Used only for validation in #set, should be moved elsewhere.\n versionRange?: SemVerRange;\n isUpdate?: boolean;\n};\n\nconst defaultState: SnapControllerState = {\n snapErrors: {},\n snaps: {},\n snapStates: {},\n};\n\n/**\n * Truncates the properties of a snap to only ones that are easily serializable.\n *\n * @param snap - The snap to truncate.\n * @returns Object with serializable snap properties.\n */\nfunction truncateSnap(snap: Snap): TruncatedSnap {\n const truncatedSnap = Object.keys(snap).reduce<Partial<TruncatedSnap>>(\n (serialized, key) => {\n if (TRUNCATED_SNAP_PROPERTIES.has(key as any)) {\n serialized[key as keyof TruncatedSnap] = snap[\n key as keyof TruncatedSnap\n ] as any;\n }\n\n return serialized;\n },\n {},\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return truncatedSnap as TruncatedSnap;\n}\n\nconst name = 'SnapController';\n\n/*\n * A snap is initialized in three phases:\n * - Add: Loads the snap from a remote source and parses it.\n * - Authorize: Requests the snap's required permissions from the user.\n * - Start: Initializes the snap in its SES realm with the authorized permissions.\n */\n\nexport class SnapController extends BaseController<\n string,\n SnapControllerState,\n SnapControllerMessenger\n> {\n #closeAllConnections: CloseAllConnectionsFunction;\n\n #environmentEndowmentPermissions: string[];\n\n #featureFlags: FeatureFlags;\n\n #fetchFunction: typeof fetch;\n\n #idleTimeCheckInterval: number;\n\n #checkSnapBlockList: CheckSnapBlockList;\n\n #maxIdleTime: number;\n\n // This property cannot be hash private yet because of tests.\n private readonly maxRequestTime: number;\n\n #detectSnapLocation: typeof detectSnapLocation;\n\n // This property cannot be hash private yet because of tests.\n private readonly snapsRuntimeData: Map<SnapId, SnapRuntimeData>;\n\n #rollbackSnapshots: Map<SnapId, RollbackSnapshot>;\n\n #getAppKey: GetAppKey;\n\n #timeoutForLastRequestStatus?: number;\n\n #statusMachine!: StateMachine.Machine<\n StatusContext,\n StatusEvents,\n StatusStates\n >;\n\n constructor({\n closeAllConnections,\n messenger,\n state,\n getAppKey,\n environmentEndowmentPermissions = [],\n idleTimeCheckInterval = inMilliseconds(5, Duration.Second),\n checkBlockList,\n maxIdleTime = inMilliseconds(30, Duration.Second),\n maxRequestTime = inMilliseconds(60, Duration.Second),\n fetchFunction = globalThis.fetch.bind(globalThis),\n featureFlags = {},\n detectSnapLocation: detectSnapLocationFunction = detectSnapLocation,\n }: SnapControllerArgs) {\n super({\n messenger,\n metadata: {\n snapErrors: {\n persist: false,\n anonymous: false,\n },\n snapStates: {\n persist: () => {\n return Object.keys(this.state.snaps).reduce<\n Record<string, string | null>\n >((acc, cur) => {\n acc[cur] = this.#getRuntimeExpect(cur).state;\n return acc;\n }, {});\n },\n anonymous: false,\n },\n snaps: {\n persist: (snaps) => {\n return Object.values(snaps)\n .map((snap) => {\n return {\n ...snap,\n sourceCode: this.#getRuntimeExpect(snap.id).sourceCode,\n // At the time state is rehydrated, no snap will be running.\n status: SnapStatus.Stopped,\n };\n })\n .reduce((memo: Record<string, Snap>, snap) => {\n memo[snap.id] = snap;\n return memo;\n }, {});\n },\n anonymous: false,\n },\n },\n name,\n state: {\n ...defaultState,\n ...{\n ...state,\n snaps: Object.values(state?.snaps ?? {}).reduce(\n (memo: Record<string, Snap>, snap) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { sourceCode, ...rest } = snap;\n memo[snap.id] = rest;\n return memo;\n },\n {},\n ),\n },\n },\n });\n\n this.#closeAllConnections = closeAllConnections;\n this.#environmentEndowmentPermissions = environmentEndowmentPermissions;\n this.#featureFlags = featureFlags;\n this.#fetchFunction = fetchFunction;\n this.#getAppKey = getAppKey;\n this.#idleTimeCheckInterval = idleTimeCheckInterval;\n this.#checkSnapBlockList = checkBlockList;\n this.#maxIdleTime = maxIdleTime;\n this.maxRequestTime = maxRequestTime;\n this.#detectSnapLocation = detectSnapLocationFunction;\n this._onUnhandledSnapError = this._onUnhandledSnapError.bind(this);\n this._onOutboundRequest = this._onOutboundRequest.bind(this);\n this._onOutboundResponse = this._onOutboundResponse.bind(this);\n this.#rollbackSnapshots = new Map();\n this.snapsRuntimeData = new Map();\n this.#pollForLastRequestStatus();\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.subscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.subscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.#initializeStateMachine();\n this.#registerMessageHandlers();\n\n Object.values(state?.snaps ?? {}).forEach((snap) =>\n this.#setupRuntime(snap.id, {\n sourceCode: snap.sourceCode,\n state: state?.snapStates?.[snap.id] ?? null,\n }),\n );\n }\n\n /**\n * We track status of a Snap using a finite-state-machine.\n * It keeps track of whether the snap is started / stopped / etc.\n *\n * @see {@link SnapController.transition} for interacting with the machine.\n */\n // We initialize the machine in the instance because the status is currently tightly coupled\n // with the SnapController - the guard checks for enabled status inside the SnapController state.\n // In the future, side-effects could be added to the machine during transitions.\n #initializeStateMachine() {\n const disableGuard = ({ snapId }: StatusContext) => {\n return this.getExpect(snapId).enabled;\n };\n\n const statusConfig: StateMachine.Config<\n StatusContext,\n StatusEvents,\n StatusStates\n > = {\n initial: SnapStatus.Installing,\n states: {\n [SnapStatus.Installing]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n [SnapStatus.Updating]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n [SnapStatus.Running]: {\n on: {\n [SnapStatusEvents.Stop]: SnapStatus.Stopped,\n [SnapStatusEvents.Crash]: SnapStatus.Crashed,\n },\n },\n [SnapStatus.Stopped]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n [SnapStatusEvents.Update]: SnapStatus.Updating,\n },\n },\n [SnapStatus.Crashed]: {\n on: {\n [SnapStatusEvents.Start]: {\n target: SnapStatus.Running,\n cond: disableGuard,\n },\n },\n },\n },\n };\n this.#statusMachine = createMachine(statusConfig);\n validateMachine(this.#statusMachine);\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:clearSnapState`,\n (...args) => this.clearSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:get`,\n (...args) => this.get(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSnapState`,\n async (...args) => this.getSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:handleRequest`,\n async (...args) => this.handleRequest(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:has`,\n (...args) => this.has(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateBlockedSnaps`,\n async () => this.updateBlockedSnaps(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateSnapState`,\n async (...args) => this.updateSnapState(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:enable`,\n (...args) => this.enableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disable`,\n async (...args) => this.disableSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:remove`,\n async (...args) => this.removeSnap(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getPermitted`,\n (...args) => this.getPermittedSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:install`,\n async (...args) => this.installSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:removeSnapError`,\n (...args) => this.removeSnapError(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAll`,\n (...args) => this.getAllSnaps(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:incrementActiveReferences`,\n (...args) => this.incrementActiveReferences(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:decrementActiveReferences`,\n (...args) => this.decrementActiveReferences(...args),\n );\n }\n\n #pollForLastRequestStatus() {\n this.#timeoutForLastRequestStatus = setTimeout(() => {\n this.#stopSnapsLastRequestPastMax().catch((error) => {\n // TODO: Decide how to handle errors.\n console.error(error);\n });\n\n this.#pollForLastRequestStatus();\n }, this.#idleTimeCheckInterval) as unknown as number;\n }\n\n /**\n * Checks all installed snaps against the block list and\n * blocks/unblocks snaps as appropriate. See {@link SnapController.blockSnap}\n * for more information.\n */\n async updateBlockedSnaps(): Promise<void> {\n const blockedSnaps = await this.#checkSnapBlockList(\n Object.values(this.state.snaps).reduce<CheckSnapBlockListArg>(\n (blockListArg, snap) => {\n blockListArg[snap.id] = {\n version: snap.version,\n shasum: snap.manifest.source.shasum,\n };\n return blockListArg;\n },\n {},\n ),\n );\n\n await Promise.all(\n Object.entries(blockedSnaps).map(\n async ([snapId, { blocked, ...blockData }]) => {\n if (blocked) {\n return this.#blockSnap(snapId, blockData);\n }\n\n return this.#unblockSnap(snapId);\n },\n ),\n );\n }\n\n /**\n * Blocks an installed snap and prevents it from being started again. Emits\n * {@link SnapBlocked}. Does nothing if the snap is not installed.\n *\n * @param snapId - The snap to block.\n * @param blockedSnapInfo - Information detailing why the snap is blocked.\n */\n async #blockSnap(\n snapId: SnapId,\n blockedSnapInfo: BlockedSnapInfo,\n ): Promise<void> {\n if (!this.has(snapId)) {\n return;\n }\n\n try {\n this.update((state: any) => {\n state.snaps[snapId].blocked = true;\n state.snaps[snapId].blockInformation = blockedSnapInfo;\n });\n\n await this.disableSnap(snapId);\n } catch (error) {\n console.error(\n `Encountered error when stopping blocked snap \"${snapId}\".`,\n error,\n );\n }\n\n this.messagingSystem.publish(\n `${controllerName}:snapBlocked`,\n snapId,\n blockedSnapInfo,\n );\n }\n\n /**\n * Unblocks a snap so that it can be enabled and started again. Emits\n * {@link SnapUnblocked}. Does nothing if the snap is not installed or already\n * unblocked.\n *\n * @param snapId - The id of the snap to unblock.\n */\n #unblockSnap(snapId: SnapId) {\n if (!this.has(snapId) || !this.state.snaps[snapId].blocked) {\n return;\n }\n\n this.update((state: any) => {\n state.snaps[snapId].blocked = false;\n delete state.snaps[snapId].blockInformation;\n });\n\n this.messagingSystem.publish(`${controllerName}:snapUnblocked`, snapId);\n }\n\n /**\n * Checks the block list to determine whether a version of a snap is blocked.\n *\n * @param snapId - The snap id to check.\n * @param snapInfo - Snap information containing version and shasum.\n * @returns Whether the version of the snap is blocked or not.\n */\n async isBlocked(\n snapId: ValidatedSnapId,\n snapInfo: SnapInfo,\n ): Promise<boolean> {\n const result = await this.#checkSnapBlockList({\n [snapId]: snapInfo,\n });\n return result[snapId].blocked;\n }\n\n /**\n * Asserts that a version of a snap is not blocked. Succeeds automatically\n * if {@link SnapController._checkSnapBlockList} is undefined.\n *\n * @param snapId - The id of the snap to check.\n * @param snapInfo - Snap information containing version and shasum.\n */\n async #assertIsUnblocked(snapId: ValidatedSnapId, snapInfo: SnapInfo) {\n if (await this.isBlocked(snapId, snapInfo)) {\n throw new Error(\n `Cannot install version \"${snapInfo.version}\" of snap \"${snapId}\": the version is blocked.`,\n );\n }\n }\n\n async #stopSnapsLastRequestPastMax() {\n const entries = [...this.snapsRuntimeData.entries()];\n return Promise.all(\n entries\n .filter(\n ([_snapId, runtime]) =>\n runtime.activeReferences === 0 &&\n runtime.pendingInboundRequests.length === 0 &&\n // lastRequest should always be set here but TypeScript wants this check\n runtime.lastRequest &&\n this.#maxIdleTime &&\n timeSince(runtime.lastRequest) > this.#maxIdleTime,\n )\n .map(async ([snapId]) => this.stopSnap(snapId, SnapStatusEvents.Stop)),\n );\n }\n\n _onUnhandledSnapError(snapId: SnapId, error: SnapErrorJson) {\n this.stopSnap(snapId, SnapStatusEvents.Crash)\n .then(() => this.addSnapError(error))\n .catch((stopSnapError) => {\n // TODO: Decide how to handle errors.\n console.error(stopSnapError);\n });\n }\n\n _onOutboundRequest(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n // Ideally we would only pause the pending request that is making the outbound request\n // but right now we don't have a way to know which request initiated the outbound request\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'running')\n .forEach((pendingRequest) => pendingRequest.timer.pause());\n runtime.pendingOutboundRequests += 1;\n }\n\n _onOutboundResponse(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingOutboundRequests -= 1;\n if (runtime.pendingOutboundRequests === 0) {\n runtime.pendingInboundRequests\n .filter((pendingRequest) => pendingRequest.timer.status === 'paused')\n .forEach((pendingRequest) => pendingRequest.timer.resume());\n }\n }\n\n /**\n * Transitions between states using `snapStatusStateMachineConfig` as the template to figure out\n * the next state. This transition function uses a very minimal subset of XState conventions:\n * - supports initial state\n * - .on supports raw event target string\n * - .on supports {target, cond} object\n * - the arguments for `cond` is the `SerializedSnap` instead of Xstate convention of `(event,\n * context) => boolean`\n *\n * @param snapId - The id of the snap to transition.\n * @param event - The event enum to use to transition.\n */\n #transition(snapId: SnapId, event: StatusEvents | StatusEvents['type']) {\n const { interpreter } = this.#getRuntimeExpect(snapId);\n interpreter.send(event);\n this.update((state: any) => {\n state.snaps[snapId].status = interpreter.state.value;\n });\n }\n\n /**\n * Starts the given snap. Throws an error if no such snap exists\n * or if it is already running.\n *\n * @param snapId - The id of the Snap to start.\n */\n async startSnap(snapId: SnapId): Promise<void> {\n const runtime = this.#getRuntimeExpect(snapId);\n\n if (this.state.snaps[snapId].enabled === false) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n assert(runtime.sourceCode);\n\n await this.#startSnap({\n snapId,\n sourceCode: runtime.sourceCode,\n });\n }\n\n /**\n * Enables the given snap. A snap can only be started if it is enabled. A snap\n * can only be enabled if it isn't blocked.\n *\n * @param snapId - The id of the Snap to enable.\n */\n enableSnap(snapId: SnapId): void {\n this.getExpect(snapId);\n\n if (this.state.snaps[snapId].blocked) {\n throw new Error(`Snap \"${snapId}\" is blocked and cannot be enabled.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = true;\n });\n }\n\n /**\n * Disables the given snap. A snap can only be started if it is enabled.\n *\n * @param snapId - The id of the Snap to disable.\n * @returns A promise that resolves once the snap has been disabled.\n */\n async disableSnap(snapId: SnapId): Promise<void> {\n if (!this.has(snapId)) {\n throw new Error(`Snap \"${snapId}\" not found.`);\n }\n\n this.update((state: any) => {\n state.snaps[snapId].enabled = false;\n });\n\n if (this.isRunning(snapId)) {\n return this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n return Promise.resolve();\n }\n\n /**\n * Stops the given snap, removes all hooks, closes all connections, and\n * terminates its worker.\n *\n * @param snapId - The id of the Snap to stop.\n * @param statusEvent - The Snap status event that caused the snap to be\n * stopped.\n */\n public async stopSnap(\n snapId: SnapId,\n statusEvent:\n | SnapStatusEvents.Stop\n | SnapStatusEvents.Crash = SnapStatusEvents.Stop,\n ): Promise<void> {\n const runtime = this.#getRuntime(snapId);\n if (!runtime) {\n throw new Error(`The snap \"${snapId}\" is not running.`);\n }\n\n // Reset request tracking\n runtime.lastRequest = null;\n runtime.pendingInboundRequests = [];\n runtime.pendingOutboundRequests = 0;\n try {\n if (this.isRunning(snapId)) {\n this.#closeAllConnections(snapId);\n await this.#terminateSnap(snapId);\n }\n } finally {\n if (this.isRunning(snapId)) {\n this.#transition(snapId, statusEvent);\n }\n }\n }\n\n /**\n * Terminates the specified snap and emits the `snapTerminated` event.\n *\n * @param snapId - The snap to terminate.\n */\n async #terminateSnap(snapId: SnapId) {\n await this.messagingSystem.call('ExecutionService:terminateSnap', snapId);\n this.messagingSystem.publish(\n 'SnapController:snapTerminated',\n this.getTruncatedExpect(snapId),\n );\n }\n\n /**\n * Returns whether the given snap is running.\n * Throws an error if the snap doesn't exist.\n *\n * @param snapId - The id of the Snap to check.\n * @returns `true` if the snap is running, otherwise `false`.\n */\n isRunning(snapId: SnapId): boolean {\n return this.getExpect(snapId).status === 'running';\n }\n\n /**\n * Returns whether the given snap has been added to state.\n *\n * @param snapId - The id of the Snap to check for.\n * @returns `true` if the snap exists in the controller state, otherwise `false`.\n */\n has(snapId: SnapId): boolean {\n return Boolean(this.get(snapId));\n }\n\n /**\n * Gets the snap with the given id if it exists, including all data.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @param snapId - The id of the Snap to get.\n * @returns The entire snap object from the controller state.\n */\n get(snapId: SnapId): Snap | undefined {\n return this.state.snaps[snapId];\n }\n\n /**\n * Gets the snap with the given id, throws if doesn't.\n * This should not be used if the snap is to be serializable, as e.g.\n * the snap sourceCode may be quite large.\n *\n * @see {@link SnapController.get}\n * @throws {@link Error}. If the snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns The entire snap object.\n */\n getExpect(snapId: SnapId): Snap {\n const snap = this.get(snapId);\n assert(snap !== undefined, new Error(`Snap \"${snapId}\" not found.`));\n return snap;\n }\n\n /**\n * Gets the snap with the given id if it exists, excluding any\n * non-serializable or expensive-to-serialize data.\n *\n * @param snapId - The id of the Snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n // TODO(ritave): this.get returns undefined, this.getTruncated returns null\n getTruncated(snapId: SnapId): TruncatedSnap | null {\n const snap = this.get(snapId);\n\n return snap ? truncateSnap(snap) : null;\n }\n\n /**\n * Gets the snap with the given id, throw if it doesn't exist.\n *\n * @throws {@link Error}. If snap doesn't exist\n * @param snapId - The id of the snap to get.\n * @returns A truncated version of the snap state, that is less expensive to serialize.\n */\n getTruncatedExpect(snapId: SnapId): TruncatedSnap {\n return truncateSnap(this.getExpect(snapId));\n }\n\n /**\n * Updates the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be updated.\n * @param newSnapState - The new state of the snap.\n */\n async updateSnapState(snapId: SnapId, newSnapState: Json): Promise<void> {\n const encrypted = await this.#encryptSnapState(snapId, newSnapState);\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.state = encrypted;\n }\n\n /**\n * Clears the state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state should be cleared.\n */\n clearSnapState(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.state = null;\n }\n\n /**\n * Adds error from a snap to the SnapController state.\n *\n * @param snapError - The error to store on the SnapController.\n */\n addSnapError(snapError: SnapError): void {\n this.update((state: any) => {\n const id = nanoid();\n state.snapErrors[id] = {\n ...snapError,\n internalID: id,\n };\n });\n }\n\n /**\n * Removes an error by internalID from the SnapControllers state.\n *\n * @param internalID - The internal error ID to remove on the SnapController.\n */\n removeSnapError(internalID: string) {\n this.update((state: any) => {\n delete state.snapErrors[internalID];\n });\n }\n\n /**\n * Clears all errors from the SnapControllers state.\n */\n clearSnapErrors() {\n this.update((state: any) => {\n state.snapErrors = {};\n });\n }\n\n /**\n * Gets the own state of the snap with the given id.\n * This is distinct from the state MetaMask uses to manage snaps.\n *\n * @param snapId - The id of the Snap whose state to get.\n * @returns A promise that resolves with the decrypted snap state or null if no state exists.\n * @throws If the snap state decryption fails.\n */\n async getSnapState(snapId: SnapId): Promise<Json> {\n const { state } = this.#getRuntimeExpect(snapId);\n return state ? this.#decryptSnapState(snapId, state) : null;\n }\n\n async #getEncryptionKey(snapId: SnapId): Promise<string> {\n return this.#getAppKey(snapId, AppKeyType.StateEncryption);\n }\n\n async #encryptSnapState(snapId: SnapId, state: Json): Promise<string> {\n const appKey = await this.#getEncryptionKey(snapId);\n return encrypt(appKey, state);\n }\n\n async #decryptSnapState(snapId: SnapId, encrypted: string): Promise<Json> {\n const appKey = await this.#getEncryptionKey(snapId);\n try {\n const value = await decrypt(appKey, encrypted);\n\n assert(isValidJson(value));\n return value;\n } catch (error) {\n throw new Error(\n 'Failed to decrypt snap state, the state must be corrupted.',\n );\n }\n }\n\n /**\n * Completely clear the controller's state: delete all associated data,\n * handlers, event listeners, and permissions; tear down all snap providers.\n */\n async clearState() {\n const snapIds = Object.keys(this.state.snaps);\n snapIds.forEach((snapId) => {\n this.#closeAllConnections(snapId);\n });\n\n await this.messagingSystem.call('ExecutionService:terminateAllSnaps');\n snapIds.forEach((snapId) => this.revokeAllSnapPermissions(snapId));\n\n this.update((state: any) => {\n state.snaps = {};\n state.snapStates = {};\n });\n }\n\n /**\n * Removes the given snap from state, and clears all associated handlers\n * and listeners.\n *\n * @param snapId - The id of the Snap.\n * @returns A promise that resolves once the snap has been removed.\n */\n async removeSnap(snapId: SnapId): Promise<void> {\n return this.removeSnaps([snapId]);\n }\n\n /**\n * Stops the given snaps, removes them from state, and clears all associated\n * permissions, handlers, and listeners.\n *\n * @param snapIds - The ids of the Snaps.\n */\n async removeSnaps(snapIds: string[]): Promise<void> {\n if (!Array.isArray(snapIds)) {\n throw new Error('Expected array of snap ids.');\n }\n\n await Promise.all(\n snapIds.map(async (snapId) => {\n const truncated = this.getTruncatedExpect(snapId);\n // Disable the snap and revoke all of its permissions before deleting\n // it. This ensures that the snap will not be restarted or otherwise\n // affect the host environment while we are deleting it.\n await this.disableSnap(snapId);\n this.revokeAllSnapPermissions(snapId);\n\n const permissionName = getSnapPermissionName(snapId);\n // Revoke all subjects access to the snap\n this.messagingSystem.call(\n 'PermissionController:revokePermissionForAllSubjects',\n permissionName,\n );\n\n this.snapsRuntimeData.delete(snapId);\n\n this.update((state: any) => {\n delete state.snaps[snapId];\n delete state.snapStates[snapId];\n });\n\n this.messagingSystem.publish(`SnapController:snapRemoved`, truncated);\n }),\n );\n }\n\n /**\n * Safely revokes all permissions granted to a Snap.\n *\n * @param snapId - The snap ID.\n */\n private revokeAllSnapPermissions(snapId: string) {\n if (\n this.messagingSystem.call('PermissionController:hasPermissions', snapId)\n ) {\n this.messagingSystem.call(\n 'PermissionController:revokeAllPermissions',\n snapId,\n );\n }\n }\n\n /**\n * Handles incrementing the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced.\n */\n incrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.activeReferences += 1;\n }\n\n /**\n * Handles decrement the activeReferences counter.\n *\n * @param snapId - The snap id of the snap that was referenced..\n */\n decrementActiveReferences(snapId: SnapId) {\n const runtime = this.#getRuntimeExpect(snapId);\n assert(\n runtime.activeReferences > 0,\n 'SnapController reference management is in an invalid state.',\n );\n runtime.activeReferences -= 1;\n }\n\n /**\n * Gets all snaps in their truncated format.\n *\n * @returns All installed snaps in their truncated format.\n */\n getAllSnaps(): TruncatedSnap[] {\n return Object.values(this.state.snaps).map(truncateSnap);\n }\n\n /**\n * Gets the serialized permitted snaps of the given origin, if any.\n *\n * @param origin - The origin whose permitted snaps to retrieve.\n * @returns The serialized permitted snaps for the origin.\n */\n getPermittedSnaps(origin: string): InstallSnapsResult {\n return Object.values(\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) ?? {},\n ).reduce<InstallSnapsResult>((permittedSnaps, perm) => {\n if (perm.parentCapability.startsWith(SNAP_PREFIX)) {\n const snapId = perm.parentCapability.replace(SNAP_PREFIX_REGEX, '');\n const snap = this.get(snapId);\n const truncatedSnap = this.getTruncated(snapId);\n\n if (truncatedSnap && snap?.status !== SnapStatus.Installing) {\n permittedSnaps[snapId] = truncatedSnap;\n }\n }\n return permittedSnaps;\n }, {});\n }\n\n /**\n * Installs the snaps requested by the given origin, returning the snap\n * object if the origin is permitted to install it, and an authorization error\n * otherwise.\n *\n * @param origin - The origin that requested to install the snaps.\n * @param requestedSnaps - The snaps to install.\n * @returns An object of snap ids and snap objects, or errors if a\n * snap couldn't be installed.\n */\n async installSnaps(\n origin: string,\n requestedSnaps: RequestedSnapPermissions,\n ): Promise<InstallSnapsResult> {\n const result: InstallSnapsResult = {};\n\n const snapIds = Object.keys(requestedSnaps);\n\n // Existing snaps may need to be updated\n const pendingUpdates = snapIds.filter((snapId) => this.has(snapId));\n\n // Non-existing snaps will need to be installed\n const pendingInstalls = snapIds.filter(\n (snapId) => !pendingUpdates.includes(snapId),\n );\n\n try {\n for (const [snapId, { version: rawVersion }] of Object.entries(\n requestedSnaps,\n )) {\n const [error, version] = resolveVersionRange(rawVersion);\n\n if (error) {\n throw ethErrors.rpc.invalidParams(\n `The \"version\" field must be a valid SemVer version range if specified. Received: \"${rawVersion}\".`,\n );\n }\n\n const permissionName = getSnapPermissionName(snapId);\n\n if (\n !this.messagingSystem.call(\n 'PermissionController:hasPermission',\n origin,\n permissionName,\n )\n ) {\n throw ethErrors.provider.unauthorized(\n `Not authorized to install snap \"${snapId}\". Request the permission for the snap before attempting to install it.`,\n );\n }\n\n const isUpdate = pendingUpdates.includes(snapId);\n\n if (isUpdate && this.#isValidUpdate(snapId, version)) {\n let rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot === undefined) {\n const prevSourceCode = this.#getRuntimeExpect(snapId).sourceCode;\n rollbackSnapshot = this.#createRollbackSnapshot(snapId);\n rollbackSnapshot.sourceCode = prevSourceCode;\n rollbackSnapshot.newVersion = version;\n } else {\n throw new Error('This snap is already being updated.');\n }\n }\n\n result[snapId] = await this.processRequestedSnap(\n origin,\n snapId,\n version,\n );\n }\n snapIds.forEach((snapId) => this.#rollbackSnapshots.delete(snapId));\n } catch (error) {\n const installed = pendingInstalls.filter((snapId) => this.has(snapId));\n await this.removeSnaps(installed);\n const snapshottedSnaps = [...this.#rollbackSnapshots.keys()];\n const snapsToRollback = pendingUpdates.filter((snapId) =>\n snapshottedSnaps.includes(snapId),\n );\n await this.#rollbackSnaps(snapsToRollback);\n\n throw error;\n }\n return result;\n }\n\n /**\n * Adds, authorizes, and runs the given snap with a snap provider.\n * Results from this method should be efficiently serializable.\n *\n * @param origin - The origin requesting the snap.\n * @param snapId - The id of the snap.\n * @param versionRange - The semver range of the snap to install.\n * @returns The resulting snap object, or an error if something went wrong.\n */\n private async processRequestedSnap(\n origin: string,\n snapId: SnapId,\n versionRange: SemVerRange,\n ): Promise<ProcessSnapResult> {\n validateSnapId(snapId);\n\n const location = this.#detectSnapLocation(snapId, {\n versionRange,\n fetch: this.#fetchFunction,\n });\n\n const existingSnap = this.getTruncated(snapId);\n // For devX we always re-install local snaps.\n if (existingSnap && !location.shouldAlwaysReload) {\n if (satisfiesVersionRange(existingSnap.version, versionRange)) {\n return existingSnap;\n }\n\n if (this.#featureFlags.dappsCanUpdateSnaps === true) {\n const updateResult = await this.updateSnap(\n origin,\n snapId,\n versionRange,\n location,\n );\n if (updateResult === null) {\n throw ethErrors.rpc.invalidParams(\n `Snap \"${snapId}@${existingSnap.version}\" is already installed. Couldn't update to a version inside requested \"${versionRange}\" range.`,\n );\n }\n return updateResult;\n }\n throw ethErrors.rpc.invalidParams(\n `Version mismatch with already installed snap. ${snapId}@${existingSnap.version} doesn't satisfy requested version ${versionRange}.`,\n );\n }\n\n // Existing snaps must be stopped before overwriting\n if (existingSnap && this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n try {\n const { sourceCode } = await this.#add({\n origin,\n id: snapId,\n location,\n });\n\n await this.authorize(origin, snapId);\n\n await this.#startSnap({\n snapId,\n sourceCode,\n });\n\n const truncated = this.getTruncatedExpect(snapId);\n\n this.messagingSystem.publish(`SnapController:snapInstalled`, truncated);\n return truncated;\n } catch (error) {\n console.error(`Error when adding snap.`, error);\n\n throw error;\n }\n }\n\n /**\n * Updates an installed snap. The flow is similar to\n * {@link SnapController.installSnaps}. The user will be asked if they want\n * to update, then approve any permission changes, and finally the snap will\n * be restarted.\n *\n * The update will fail if the user rejects any prompt or if the new version\n * of the snap is blocked.\n *\n * If the original version of the snap was blocked and the update succeeded,\n * the snap will be unblocked and enabled before it is restarted.\n *\n * @param origin - The origin requesting the snap update.\n * @param snapId - The id of the Snap to be updated.\n * @param newVersionRange - A semver version range in which the maximum version will be chosen.\n * @param location - Optional location that was already used during installation flow.\n * @returns The snap metadata if updated, `null` otherwise.\n */\n async updateSnap(\n origin: string,\n snapId: ValidatedSnapId,\n newVersionRange: string = DEFAULT_REQUESTED_SNAP_VERSION,\n location?: SnapLocation,\n ): Promise<TruncatedSnap | null> {\n const snap = this.getExpect(snapId);\n\n if (!isValidSemVerRange(newVersionRange)) {\n throw new Error(\n `Received invalid snap version range: \"${newVersionRange}\".`,\n );\n }\n const newSnap = await this.#fetchSnap(\n snapId,\n location ??\n this.#detectSnapLocation(snapId, { versionRange: newVersionRange }),\n );\n const newVersion = newSnap.manifest.result.version;\n if (!gtVersion(newVersion, snap.version)) {\n console.warn(\n `Tried updating snap \"${snapId}\" within \"${newVersionRange}\" version range, but newer version \"${snap.version}\" is already installed`,\n );\n return null;\n }\n\n await this.#assertIsUnblocked(snapId, {\n version: newVersion,\n shasum: newSnap.manifest.result.source.shasum,\n });\n\n const processedPermissions = this.#processSnapPermissions(\n newSnap.manifest.result.initialPermissions,\n );\n\n const { newPermissions, unusedPermissions, approvedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n const id = nanoid();\n const { permissions: approvedNewPermissions, ...requestData } =\n (await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type: SNAP_APPROVAL_UPDATE,\n requestData: {\n // First two keys mirror installation params\n metadata: { id, origin: snapId, dappOrigin: origin },\n permissions: newPermissions,\n snapId,\n newVersion: newSnap.manifest.result.version,\n newPermissions,\n approvedPermissions,\n unusedPermissions,\n },\n },\n true,\n )) as PermissionsRequest;\n\n if (this.isRunning(snapId)) {\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n }\n\n this.#transition(snapId, SnapStatusEvents.Update);\n\n this.#set({\n origin,\n id: snapId,\n manifest: newSnap.manifest,\n files: newSnap.files,\n versionRange: newVersionRange,\n isUpdate: true,\n });\n\n const unusedPermissionsKeys = Object.keys(unusedPermissions);\n if (isNonEmptyArray(unusedPermissionsKeys)) {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: unusedPermissionsKeys,\n });\n }\n\n if (isNonEmptyArray(Object.keys(approvedNewPermissions))) {\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions: approvedNewPermissions,\n subject: { origin: snapId },\n requestData,\n });\n }\n\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.permissions.revoked = unusedPermissions;\n rollbackSnapshot.permissions.granted = Object.keys(\n approvedNewPermissions,\n );\n rollbackSnapshot.permissions.requestData = requestData;\n }\n\n const sourceCode = newSnap.files\n .find(\n (file) =>\n file.path === newSnap.manifest.result.source.location.npm.filePath,\n )\n ?.toString();\n assert(sourceCode !== undefined);\n\n try {\n await this.#startSnap({ snapId, sourceCode });\n } catch {\n throw new Error(`Snap ${snapId} crashed with updated source code.`);\n }\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n this.messagingSystem.publish(\n 'SnapController:snapUpdated',\n truncatedSnap,\n snap.version,\n );\n\n return truncatedSnap;\n }\n\n /**\n * Returns a promise representing the complete installation of the requested snap.\n * If the snap is already being installed, the previously pending promise will be returned.\n *\n * @param args - Object containing the snap id and either the URL of the snap's manifest,\n * or the snap's manifest and source code. The object may also optionally contain a target\n * version.\n * @returns The resulting snap object.\n */\n async #add(args: AddSnapArgs): Promise<PersistedSnap> {\n const { id: snapId, location } = args;\n validateSnapId(snapId);\n\n this.#setupRuntime(snapId, { sourceCode: null, state: null });\n const runtime = this.#getRuntimeExpect(snapId);\n if (!runtime.installPromise) {\n console.info(`Adding snap: ${snapId}`);\n\n // If fetching and setting the snap succeeds, this property will be set\n // to null in the authorize() method.\n runtime.installPromise = (async () => {\n const fetchedSnap = await this.#fetchSnap(snapId, location);\n await this.#assertIsUnblocked(snapId, {\n version: fetchedSnap.manifest.result.version,\n shasum: fetchedSnap.manifest.result.source.shasum,\n });\n\n return this.#set({\n ...args,\n ...fetchedSnap,\n id: snapId,\n });\n })();\n }\n\n try {\n return await runtime.installPromise;\n } catch (error) {\n // Reset promise so users can retry installation in case the problem is\n // temporary.\n runtime.installPromise = null;\n throw error;\n }\n }\n\n async #startSnap(snapData: { snapId: string; sourceCode: string }) {\n const { snapId } = snapData;\n if (this.isRunning(snapId)) {\n throw new Error(`Snap \"${snapId}\" is already started.`);\n }\n\n try {\n const result = await this.#executeWithTimeout(\n snapId,\n this.messagingSystem.call('ExecutionService:executeSnap', {\n ...snapData,\n endowments: await this.#getEndowments(snapId),\n }),\n );\n this.#transition(snapId, SnapStatusEvents.Start);\n return result;\n } catch (error) {\n await this.#terminateSnap(snapId);\n throw error;\n }\n }\n\n /**\n * Gets the names of all endowments that will be added to the Snap's\n * Compartment when it executes. These should be the names of global\n * JavaScript APIs accessible in the root realm of the execution environment.\n *\n * Throws an error if the endowment getter for a permission returns a truthy\n * value that is not an array of strings.\n *\n * @param snapId - The id of the snap whose SES endowments to get.\n * @returns An array of the names of the endowments.\n */\n async #getEndowments(snapId: string): Promise<string[]> {\n let allEndowments: string[] = [];\n\n for (const permissionName of this.#environmentEndowmentPermissions) {\n if (\n this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n )\n ) {\n const endowments = await this.messagingSystem.call(\n 'PermissionController:getEndowments',\n snapId,\n permissionName,\n );\n\n if (endowments) {\n // We don't have any guarantees about the type of the endowments\n // value, so we have to guard at runtime.\n if (\n !Array.isArray(endowments) ||\n endowments.some((value) => typeof value !== 'string')\n ) {\n throw new Error('Expected an array of string endowment names.');\n }\n\n allEndowments = allEndowments.concat(endowments as string[]);\n }\n }\n }\n\n const dedupedEndowments = [\n ...new Set([...DEFAULT_ENDOWMENTS, ...allEndowments]),\n ];\n\n if (\n dedupedEndowments.length <\n // This is a bug in TypeScript: https://github.com/microsoft/TypeScript/issues/48313\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n DEFAULT_ENDOWMENTS.length + allEndowments.length\n ) {\n console.error(\n 'Duplicate endowments found. Default endowments should not be requested.',\n allEndowments,\n );\n }\n return dedupedEndowments;\n }\n\n /**\n * Sets a snap in state. Called when a snap is installed or updated. Performs\n * various validation checks on the received arguments, and will throw if\n * validation fails.\n *\n * The snap will be enabled and unblocked by the time this method returns,\n * regardless of its previous state.\n *\n * See {@link SnapController.add} and {@link SnapController.updateSnap} for\n * usage.\n *\n * @param args - The add snap args.\n * @returns The resulting snap object.\n */\n #set(args: SetSnapArgs): PersistedSnap {\n const {\n id: snapId,\n origin,\n manifest,\n files,\n versionRange = DEFAULT_REQUESTED_SNAP_VERSION,\n isUpdate = false,\n } = args;\n\n assertIsSnapManifest(manifest.result);\n const { version } = manifest.result;\n\n if (!satisfiesVersionRange(version, versionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${version}\" which doesn't satisfy requested version range \"${versionRange}\"`,\n );\n }\n\n const sourceCode = files\n .find(\n (file) => file.path === manifest.result.source.location.npm.filePath,\n )\n ?.toString();\n const svgIcon = files.find(\n (file) =>\n manifest.result.source.location.npm.iconPath !== undefined &&\n file.path === manifest.result.source.location.npm.iconPath,\n );\n assert(sourceCode !== undefined);\n if (typeof sourceCode !== 'string' || sourceCode.length === 0) {\n throw new Error(`Invalid source code for snap \"${snapId}\".`);\n }\n\n const snapsState = this.state.snaps;\n\n const existingSnap = snapsState[snapId];\n\n const previousVersionHistory = existingSnap?.versionHistory ?? [];\n const versionHistory = [\n ...previousVersionHistory,\n {\n version,\n date: Date.now(),\n origin,\n },\n ];\n\n const snap: Snap = {\n // Restore relevant snap state if it exists\n ...existingSnap,\n\n // Note that the snap will be unblocked and enabled, regardless of its\n // previous state.\n blocked: false,\n enabled: true,\n\n // So we can easily correlate the snap with its permission\n permissionName: getSnapPermissionName(snapId),\n\n id: snapId,\n initialPermissions: manifest.result.initialPermissions,\n manifest: manifest.result,\n status: this.#statusMachine.config.initial as StatusStates['value'],\n version,\n versionHistory,\n };\n // If the snap was blocked, it isn't any longer\n delete snap.blockInformation;\n\n // store the snap back in state\n const { inversePatches } = this.update((state: any) => {\n state.snaps[snapId] = snap;\n });\n\n // checking for isUpdate here as this function is also used in\n // the install flow, we do not care to create snapshots for installs\n if (isUpdate) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot !== undefined) {\n rollbackSnapshot.statePatches = inversePatches;\n }\n }\n\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.sourceCode = sourceCode;\n\n this.messagingSystem.publish(\n `SnapController:snapAdded`,\n snap,\n svgIcon?.toString(),\n );\n return { ...snap, sourceCode };\n }\n\n /**\n * Fetches the manifest and source code of a snap.\n *\n * This function is not hash private yet because of tests.\n *\n * @param snapId - The id of the Snap.\n * @param location - Source from which snap will be fetched.\n * @returns A tuple of the Snap manifest object and the Snap source code.\n */\n async #fetchSnap(\n snapId: ValidatedSnapId,\n location: SnapLocation,\n ): Promise<FetchSnapResult> {\n try {\n const manifest = await location.manifest();\n const sourceCode = await location.fetch(\n manifest.result.source.location.npm.filePath,\n );\n validateSnapShasum(manifest.result, sourceCode.toString());\n const { iconPath } = manifest.result.source.location.npm;\n\n const files = [sourceCode];\n if (iconPath) {\n files.push(await location.fetch(iconPath));\n }\n\n return { manifest, files, location };\n } catch (error) {\n // TODO(ritave): Export `getErrorMessage()` from @metamask/utils and use it here\n // https://github.com/MetaMask/utils/blob/62d022ef83c91fa4d150e51913be4441508a0ab1/src/assert.ts\n const message = error instanceof Error ? error.message : error.toString();\n throw new Error(`Failed to fetch Snap \"${snapId}\": ${message}.`);\n }\n }\n\n /**\n * Map initial permissions as defined in a Snap manifest to something that can\n * be processed by the PermissionsController. Each caveat mapping function\n * should return a valid permission caveat value.\n *\n * This function does not validate the caveat values, since that is done by\n * the PermissionsController itself, upon requesting the permissions.\n *\n * @param initialPermissions - The initial permissions to process.\n * @returns The processed permissions.\n * @private\n */\n #processSnapPermissions(\n initialPermissions: SnapPermissions,\n ): Record<string, Pick<PermissionConstraint, 'caveats'>> {\n return fromEntries(\n Object.entries(initialPermissions).map(([initialPermission, value]) => {\n if (hasProperty(caveatMappers, initialPermission)) {\n return [initialPermission, caveatMappers[initialPermission](value)];\n } else if (hasProperty(endowmentCaveatMappers, initialPermission)) {\n return [\n initialPermission,\n endowmentCaveatMappers[initialPermission](value),\n ];\n }\n\n // If we have no mapping, this may be a non-snap permission, return as-is\n return [\n initialPermission,\n value as Pick<PermissionConstraint, 'caveats'>,\n ];\n }),\n );\n }\n\n /**\n * Initiates a request for the given snap's initial permissions.\n * Must be called in order. See processRequestedSnap.\n *\n * This function is not hash private yet because of tests.\n *\n * @param origin - The origin of the install request.\n * @param snapId - The id of the Snap.\n * @returns The snap's approvedPermissions.\n */\n private async authorize(origin: string, snapId: SnapId): Promise<void> {\n console.info(`Authorizing snap: ${snapId}`);\n const snapsState = this.state.snaps;\n const snap = snapsState[snapId];\n const { initialPermissions } = snap;\n\n try {\n const processedPermissions =\n this.#processSnapPermissions(initialPermissions);\n const id = nanoid();\n const { permissions: approvedPermissions, ...requestData } =\n (await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type: SNAP_APPROVAL_INSTALL,\n requestData: {\n // Mirror previous installation metadata\n metadata: { id, origin: snapId, dappOrigin: origin },\n permissions: processedPermissions,\n snapId,\n },\n },\n true,\n )) as PermissionsRequest;\n\n if (isNonEmptyArray(Object.keys(approvedPermissions))) {\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions,\n subject: { origin: snapId },\n requestData,\n });\n }\n } finally {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.installPromise = null;\n }\n }\n\n destroy() {\n super.destroy();\n\n if (this.#timeoutForLastRequestStatus) {\n clearTimeout(this.#timeoutForLastRequestStatus);\n }\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.unsubscribe(\n 'ExecutionService:unhandledError',\n this._onUnhandledSnapError,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundRequest',\n this._onOutboundRequest,\n );\n\n this.messagingSystem.unsubscribe(\n 'ExecutionService:outboundResponse',\n this._onOutboundResponse,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Passes a JSON-RPC request object to the RPC handler function of a snap.\n *\n * @param options - A bag of options.\n * @param options.snapId - The ID of the recipient snap.\n * @param options.origin - The origin of the RPC request.\n * @param options.handler - The handler to trigger on the snap for the request.\n * @param options.request - The JSON-RPC request object.\n * @returns The result of the JSON-RPC request.\n */\n async handleRequest({\n snapId,\n origin,\n handler: handlerType,\n request,\n }: SnapRpcHookArgs & { snapId: SnapId }): Promise<unknown> {\n const permissionName = handlerEndowments[handlerType];\n const hasPermission = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n permissionName,\n );\n\n if (!hasPermission) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to use \"${permissionName}\".`,\n );\n }\n\n if (permissionName === SnapEndowments.Rpc) {\n const subject = this.messagingSystem.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n const isSnap = subject?.subjectType === SubjectType.Snap;\n\n const permissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n\n const rpcPermission = permissions?.[SnapEndowments.Rpc];\n assert(rpcPermission);\n\n const origins = getRpcCaveatOrigins(rpcPermission);\n assert(origins);\n\n if ((isSnap && !origins.snaps) || (!isSnap && !origins.dapps)) {\n throw new Error(\n `Snap \"${snapId}\" is not permitted to handle JSON-RPC requests from \"${origin}\".`,\n );\n }\n }\n\n const handler = await this.#getRpcRequestHandler(snapId);\n if (!handler) {\n throw new Error(\n `Snap RPC message handler not found for snap \"${snapId}\".`,\n );\n }\n\n return handler({ origin, handler: handlerType, request });\n }\n\n /**\n * Gets the RPC message handler for the given snap.\n *\n * @param snapId - The id of the Snap whose message handler to get.\n * @returns The RPC handler for the given snap.\n */\n #getRpcRequestHandler(snapId: SnapId): SnapRpcHook {\n const runtime = this.#getRuntimeExpect(snapId);\n const existingHandler = runtime.rpcHandler;\n if (existingHandler) {\n return existingHandler;\n }\n\n const requestQueue = new RequestQueue(5);\n // We need to set up this promise map to map snapIds to their respective startPromises,\n // because otherwise we would lose context on the correct startPromise.\n const startPromises = new Map<string, Promise<void>>();\n\n const rpcHandler = async ({\n origin,\n handler: handlerType,\n request,\n }: SnapRpcHookArgs) => {\n if (this.state.snaps[snapId].enabled === false) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n if (this.state.snaps[snapId].status === SnapStatus.Installing) {\n throw new Error(\n `Snap \"${snapId}\" is currently being installed. Please try again later.`,\n );\n }\n\n if (!this.isRunning(snapId)) {\n let localStartPromise = startPromises.get(snapId);\n if (!localStartPromise) {\n localStartPromise = this.startSnap(snapId);\n startPromises.set(snapId, localStartPromise);\n } else if (requestQueue.get(origin) >= requestQueue.maxQueueSize) {\n throw new Error(\n 'Exceeds maximum number of requests waiting to be resolved, please try again.',\n );\n }\n\n requestQueue.increment(origin);\n try {\n await localStartPromise;\n } finally {\n requestQueue.decrement(origin);\n // Only delete startPromise for a snap if its value hasn't changed\n if (startPromises.get(snapId) === localStartPromise) {\n startPromises.delete(snapId);\n }\n }\n }\n\n let _request = request;\n if (!hasProperty(request, 'jsonrpc')) {\n _request = { ...request, jsonrpc: '2.0' };\n } else if (request.jsonrpc !== '2.0') {\n throw ethErrors.rpc.invalidRequest({\n message: 'Invalid \"jsonrpc\" property. Must be \"2.0\" if provided.',\n data: request.jsonrpc,\n });\n }\n\n const timer = new Timer(this.maxRequestTime);\n this.#recordSnapRpcRequestStart(snapId, request.id, timer);\n\n const handleRpcRequestPromise = this.messagingSystem.call(\n 'ExecutionService:handleRpcRequest',\n snapId,\n { origin, handler: handlerType, request: _request },\n );\n\n // This will either get the result or reject due to the timeout.\n try {\n const result = await this.#executeWithTimeout(\n snapId,\n handleRpcRequestPromise,\n timer,\n );\n this.#recordSnapRpcRequestFinish(snapId, request.id);\n return result;\n } catch (error) {\n await this.stopSnap(snapId, SnapStatusEvents.Crash);\n throw error;\n }\n };\n\n runtime.rpcHandler = rpcHandler;\n return rpcHandler;\n }\n\n /**\n * Awaits the specified promise and rejects if the promise doesn't resolve\n * before the timeout.\n *\n * @param snapId - The snap id.\n * @param promise - The promise to await.\n * @param timer - An optional timer object to control the timeout.\n * @returns The result of the promise or rejects if the promise times out.\n * @template PromiseValue - The value of the Promise.\n */\n async #executeWithTimeout<PromiseValue>(\n snapId: SnapId,\n promise: Promise<PromiseValue>,\n timer?: Timer,\n ): Promise<PromiseValue> {\n const isLongRunning = this.messagingSystem.call(\n 'PermissionController:hasPermission',\n snapId,\n SnapEndowments.LongRunning,\n );\n\n // Long running snaps have timeouts disabled\n if (isLongRunning) {\n return promise;\n }\n\n const result = await withTimeout(promise, timer ?? this.maxRequestTime);\n if (result === hasTimedOut) {\n throw new Error('The request timed out.');\n }\n return result;\n }\n\n #recordSnapRpcRequestStart(snapId: SnapId, requestId: unknown, timer: Timer) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests.push({ requestId, timer });\n runtime.lastRequest = null;\n }\n\n #recordSnapRpcRequestFinish(snapId: SnapId, requestId: unknown) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.pendingInboundRequests = runtime.pendingInboundRequests.filter(\n (request) => request.requestId !== requestId,\n );\n\n if (runtime.pendingInboundRequests.length === 0) {\n runtime.lastRequest = Date.now();\n }\n }\n\n /**\n * Retrieves the rollback snapshot of a snap.\n *\n * @param snapId - The snap id.\n * @returns A `RollbackSnapshot` or `undefined` if one doesn't exist.\n */\n #getRollbackSnapshot(snapId: SnapId): RollbackSnapshot | undefined {\n return this.#rollbackSnapshots.get(snapId);\n }\n\n /**\n * Creates a `RollbackSnapshot` that is used to help ensure\n * atomicity in multiple snap updates.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If the snap exists before creation or if creation fails.\n * @returns A `RollbackSnapshot`.\n */\n #createRollbackSnapshot(snapId: SnapId): RollbackSnapshot {\n assert(\n this.#rollbackSnapshots.get(snapId) === undefined,\n new Error(`Snap \"${snapId}\" rollback snapshot already exists.`),\n );\n\n this.#rollbackSnapshots.set(snapId, {\n statePatches: [],\n sourceCode: '',\n permissions: { revoked: null, granted: [], requestData: null },\n newVersion: '',\n });\n\n const newRollbackSnapshot = this.#rollbackSnapshots.get(snapId);\n\n assert(\n newRollbackSnapshot !== undefined,\n new Error(`Snapshot creation failed for ${snapId}.`),\n );\n return newRollbackSnapshot;\n }\n\n /**\n * Rolls back a snap to its previous state, permissions\n * and source code based on the `RollbackSnapshot` that\n * is captured during the update process. After rolling back,\n * the function also emits an event indicating that the\n * snap has been rolled back and it clears the snapshot\n * for that snap.\n *\n * @param snapId - The snap id.\n * @throws {@link Error}. If a snapshot does not exist.\n */\n async #rollbackSnap(snapId: SnapId) {\n const rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (!rollbackSnapshot) {\n throw new Error('A snapshot does not exist for this snap.');\n }\n\n await this.stopSnap(snapId, SnapStatusEvents.Stop);\n\n const { statePatches, sourceCode, permissions } = rollbackSnapshot;\n\n if (statePatches?.length) {\n this.applyPatches(statePatches);\n }\n\n if (sourceCode) {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.sourceCode = sourceCode;\n }\n\n if (permissions.revoked && Object.keys(permissions.revoked).length) {\n this.messagingSystem.call('PermissionController:grantPermissions', {\n approvedPermissions: permissions.revoked as RequestedPermissions,\n subject: { origin: snapId },\n requestData: permissions.requestData as Record<string, unknown>,\n });\n }\n\n if (permissions.granted?.length) {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [snapId]: permissions.granted as NonEmptyArray<string>,\n });\n }\n\n const truncatedSnap = this.getTruncatedExpect(snapId);\n\n this.messagingSystem.publish(\n 'SnapController:snapRolledback',\n truncatedSnap,\n rollbackSnapshot.newVersion,\n );\n\n this.#rollbackSnapshots.delete(snapId);\n }\n\n /**\n * Iterates through an array of snap ids\n * and calls `rollbackSnap` on them.\n *\n * @param snapIds - An array of snap ids.\n */\n async #rollbackSnaps(snapIds: SnapId[]) {\n for (const snapId of snapIds) {\n await this.#rollbackSnap(snapId);\n }\n }\n\n #getRuntime(snapId: SnapId): SnapRuntimeData | undefined {\n return this.snapsRuntimeData.get(snapId);\n }\n\n #getRuntimeExpect(snapId: SnapId): SnapRuntimeData {\n const runtime = this.#getRuntime(snapId);\n assert(\n runtime !== undefined,\n new Error(`Snap \"${snapId}\" runtime data not found`),\n );\n return runtime;\n }\n\n #setupRuntime(\n snapId: SnapId,\n data: { sourceCode: string | null; state: string | null },\n ) {\n if (this.snapsRuntimeData.has(snapId)) {\n return;\n }\n\n const snap = this.get(snapId);\n const interpreter = interpret(this.#statusMachine);\n interpreter.start({\n context: { snapId },\n value:\n snap?.status ??\n (this.#statusMachine.config.initial as StatusStates['value']),\n });\n\n forceStrict(interpreter);\n\n this.snapsRuntimeData.set(snapId, {\n lastRequest: null,\n rpcHandler: null,\n installPromise: null,\n activeReferences: 0,\n pendingInboundRequests: [],\n pendingOutboundRequests: 0,\n interpreter,\n ...data,\n });\n }\n\n #calculatePermissionsChange(\n snapId: SnapId,\n desiredPermissionsSet: RequestedSnapPermissions,\n ): {\n newPermissions: RequestedSnapPermissions;\n unusedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n approvedPermissions: SubjectPermissions<\n ValidPermission<string, Caveat<string, any>>\n >;\n } {\n const oldPermissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n snapId,\n ) ?? {};\n\n const newPermissions = setDiff(desiredPermissionsSet, oldPermissions);\n // TODO(ritave): The assumption that these are unused only holds so long as we do not\n // permit dynamic permission requests.\n const unusedPermissions = setDiff(oldPermissions, desiredPermissionsSet);\n\n // It's a Set Intersection of oldPermissions and desiredPermissionsSet\n // oldPermissions ∖ (oldPermissions ∖ desiredPermissionsSet) ⟺ oldPermissions ∩ desiredPermissionsSet\n const approvedPermissions = setDiff(oldPermissions, unusedPermissions);\n\n return { newPermissions, unusedPermissions, approvedPermissions };\n }\n\n /**\n * Checks if a snap will pass version validation checks\n * with the new version range that is requested. The first\n * check that is done is to check if the existing snap version\n * falls inside the requested range. If it does, we want to return\n * false because we do not care to create a rollback snapshot in\n * that scenario. The second check is to ensure that the current\n * snap version is not greater than all possible versions in\n * the requested version range. If it is, then we also want\n * to return false in that scenario.\n *\n * @param snapId - The snap id.\n * @param newVersionRange - The new version range being requsted.\n * @returns `true` if validation checks pass and `false` if they do not.\n */\n #isValidUpdate(snapId: SnapId, newVersionRange: SemVerRange): boolean {\n const existingSnap = this.getExpect(snapId);\n\n if (satisfiesVersionRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n if (gtRange(existingSnap.version, newVersionRange)) {\n return false;\n }\n\n return true;\n }\n}\n"]}
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.HttpLocation = void 0;
|
|
4
4
|
const snaps_utils_1 = require("@metamask/snaps-utils");
|
|
5
5
|
const utils_1 = require("@metamask/utils");
|
|
6
|
-
const utils_2 = require("../../utils");
|
|
7
6
|
class HttpLocation {
|
|
8
7
|
constructor(url, opts = {}) {
|
|
9
8
|
var _a;
|
|
@@ -15,7 +14,7 @@ class HttpLocation {
|
|
|
15
14
|
// in most often case we'll only have one file contents in common case.
|
|
16
15
|
this.cache = new Map();
|
|
17
16
|
(0, utils_1.assertStruct)(url.toString(), snaps_utils_1.HttpSnapIdStruct, 'Invalid Snap Id: ');
|
|
18
|
-
this.fetchFn = (_a = opts.fetch) !== null && _a !== void 0 ? _a : globalThis.fetch;
|
|
17
|
+
this.fetchFn = (_a = opts.fetch) !== null && _a !== void 0 ? _a : globalThis.fetch.bind(globalThis);
|
|
19
18
|
this.fetchOptions = opts.fetchOptions;
|
|
20
19
|
this.url = url;
|
|
21
20
|
}
|
|
@@ -27,18 +26,17 @@ class HttpLocation {
|
|
|
27
26
|
const canonicalPath = new URL(snaps_utils_1.NpmSnapFileNames.Manifest, this.url).toString();
|
|
28
27
|
const contents = await (await this.fetchFn(canonicalPath, this.fetchOptions)).text();
|
|
29
28
|
const manifest = JSON.parse(contents);
|
|
30
|
-
(0, snaps_utils_1.assertIsSnapManifest)(manifest);
|
|
31
29
|
const vfile = new snaps_utils_1.VirtualFile({
|
|
32
30
|
value: contents,
|
|
33
|
-
result: manifest,
|
|
34
|
-
path:
|
|
31
|
+
result: (0, snaps_utils_1.createSnapManifest)(manifest),
|
|
32
|
+
path: snaps_utils_1.NpmSnapFileNames.Manifest,
|
|
35
33
|
data: { canonicalPath },
|
|
36
34
|
});
|
|
37
35
|
this.validatedManifest = vfile;
|
|
38
36
|
return this.manifest();
|
|
39
37
|
}
|
|
40
38
|
async fetch(path) {
|
|
41
|
-
const relativePath = (0,
|
|
39
|
+
const relativePath = (0, snaps_utils_1.normalizeRelative)(path);
|
|
42
40
|
const cached = this.cache.get(relativePath);
|
|
43
41
|
if (cached !== undefined) {
|
|
44
42
|
const { file, contents } = cached;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/snaps/location/http.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/snaps/location/http.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SnapManifest,\n VirtualFile,\n HttpSnapIdStruct,\n NpmSnapFileNames,\n createSnapManifest,\n normalizeRelative,\n} from '@metamask/snaps-utils';\nimport { assert, assertStruct } from '@metamask/utils';\n\nimport { SnapLocation } from './location';\n\nexport interface HttpOptions {\n /**\n * @default fetch\n */\n fetch?: typeof fetch;\n fetchOptions?: RequestInit;\n}\n\nexport class HttpLocation implements SnapLocation {\n // We keep contents separate because then we can use only one Blob in cache,\n // which we convert to Uint8Array when actually returning the file.\n //\n // That avoids deepCloning file contents.\n // I imagine ArrayBuffers are copy-on-write optimized, meaning\n // in most often case we'll only have one file contents in common case.\n private readonly cache = new Map<\n string,\n { file: VirtualFile; contents: Blob }\n >();\n\n private validatedManifest?: VirtualFile<SnapManifest>;\n\n private readonly url: URL;\n\n private readonly fetchFn: typeof fetch;\n\n private readonly fetchOptions?: RequestInit;\n\n constructor(url: URL, opts: HttpOptions = {}) {\n assertStruct(url.toString(), HttpSnapIdStruct, 'Invalid Snap Id: ');\n this.fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.fetchOptions = opts.fetchOptions;\n this.url = url;\n }\n\n async manifest(): Promise<VirtualFile<SnapManifest>> {\n if (this.validatedManifest) {\n return this.validatedManifest.clone();\n }\n\n // jest-fetch-mock doesn't handle new URL(), we need to convert .toString()\n const canonicalPath = new URL(\n NpmSnapFileNames.Manifest,\n this.url,\n ).toString();\n\n const contents = await (\n await this.fetchFn(canonicalPath, this.fetchOptions)\n ).text();\n const manifest = JSON.parse(contents);\n const vfile = new VirtualFile<SnapManifest>({\n value: contents,\n result: createSnapManifest(manifest),\n path: NpmSnapFileNames.Manifest,\n data: { canonicalPath },\n });\n this.validatedManifest = vfile;\n\n return this.manifest();\n }\n\n async fetch(path: string): Promise<VirtualFile> {\n const relativePath = normalizeRelative(path);\n const cached = this.cache.get(relativePath);\n if (cached !== undefined) {\n const { file, contents } = cached;\n const value = new Uint8Array(await contents.arrayBuffer());\n const vfile = file.clone();\n vfile.value = value;\n return vfile;\n }\n\n const canonicalPath = this.toCanonical(relativePath).toString();\n const response = await this.fetchFn(canonicalPath, this.fetchOptions);\n const vfile = new VirtualFile({\n value: '',\n path: relativePath,\n data: { canonicalPath },\n });\n const blob = await response.blob();\n assert(\n !this.cache.has(relativePath),\n 'Corrupted cache, multiple files with same path.',\n );\n this.cache.set(relativePath, { file: vfile, contents: blob });\n\n return this.fetch(relativePath);\n }\n\n get root(): URL {\n return new URL(this.url);\n }\n\n private toCanonical(path: string): URL {\n assert(!path.startsWith('/'), 'Tried to parse absolute path.');\n return new URL(path, this.url);\n }\n}\n"]}
|
|
@@ -17,6 +17,12 @@ export interface SnapLocation {
|
|
|
17
17
|
readonly shouldAlwaysReload?: boolean;
|
|
18
18
|
}
|
|
19
19
|
export declare type DetectSnapLocationOptions = NpmOptions & {
|
|
20
|
+
/**
|
|
21
|
+
* The function used to fetch data.
|
|
22
|
+
*
|
|
23
|
+
* @default globalThis.fetch
|
|
24
|
+
*/
|
|
25
|
+
fetch?: typeof fetch;
|
|
20
26
|
/**
|
|
21
27
|
* @default false
|
|
22
28
|
*/
|
|
@@ -20,11 +20,11 @@ function detectSnapLocation(location, opts) {
|
|
|
20
20
|
case 'npm:':
|
|
21
21
|
return new npm_1.NpmLocation(root, opts);
|
|
22
22
|
case 'local:':
|
|
23
|
-
return new local_1.LocalLocation(root);
|
|
23
|
+
return new local_1.LocalLocation(root, opts);
|
|
24
24
|
case 'http:':
|
|
25
25
|
case 'https:':
|
|
26
26
|
(0, utils_1.assert)(allowHttp, new TypeError('Fetching snaps through http/https is disabled.'));
|
|
27
|
-
return new http_1.HttpLocation(root);
|
|
27
|
+
return new http_1.HttpLocation(root, opts);
|
|
28
28
|
default:
|
|
29
29
|
throw new TypeError(`Unrecognized "${root.protocol}" snap location protocol.`);
|
|
30
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"location.js","sourceRoot":"","sources":["../../../src/snaps/location/location.ts"],"names":[],"mappings":";;;AACA,2CAAyC;AAEzC,iCAAsC;AACtC,mCAAwC;AACxC,+BAAgD;
|
|
1
|
+
{"version":3,"file":"location.js","sourceRoot":"","sources":["../../../src/snaps/location/location.ts"],"names":[],"mappings":";;;AACA,2CAAyC;AAEzC,iCAAsC;AACtC,mCAAwC;AACxC,+BAAgD;AAkChD;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,QAAsB,EACtB,IAAgC;;IAEhC,MAAM,SAAS,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,mCAAI,KAAK,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,QAAQ,IAAI,CAAC,QAAQ,EAAE;QACrB,KAAK,MAAM;YACT,OAAO,IAAI,iBAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,KAAK,QAAQ;YACX,OAAO,IAAI,qBAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACvC,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ;YACX,IAAA,cAAM,EACJ,SAAS,EACT,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAChE,CAAC;YACF,OAAO,IAAI,mBAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtC;YACE,MAAM,IAAI,SAAS,CACjB,iBAAiB,IAAI,CAAC,QAAQ,2BAA2B,CAC1D,CAAC;KACL;AACH,CAAC;AAvBD,gDAuBC","sourcesContent":["import { SnapManifest, VirtualFile } from '@metamask/snaps-utils';\nimport { assert } from '@metamask/utils';\n\nimport { HttpLocation } from './http';\nimport { LocalLocation } from './local';\nimport { NpmLocation, NpmOptions } from './npm';\n\ndeclare module '@metamask/snaps-utils' {\n interface DataMap {\n /**\n * Fully qualified, canonical path for the file in {@link https://github.com/MetaMask/SIPs/blob/main/SIPS/sip-8.md SIP-8 } URI format.\n */\n canonicalPath: string;\n }\n}\n\nexport interface SnapLocation {\n /**\n * All files are relative to the manifest, except the manifest itself.\n */\n manifest(): Promise<VirtualFile<SnapManifest>>;\n fetch(path: string): Promise<VirtualFile>;\n\n readonly shouldAlwaysReload?: boolean;\n}\n\nexport type DetectSnapLocationOptions = NpmOptions & {\n /**\n * The function used to fetch data.\n *\n * @default globalThis.fetch\n */\n fetch?: typeof fetch;\n /**\n * @default false\n */\n allowHttp?: boolean;\n};\n\n/**\n * Auto-magically detects which SnapLocation object to create based on the provided {@link location}.\n *\n * @param location - A {@link https://github.com/MetaMask/SIPs/blob/main/SIPS/sip-8.md SIP-8} uri.\n * @param opts - NPM options and feature flags.\n * @returns SnapLocation based on url.\n */\nexport function detectSnapLocation(\n location: string | URL,\n opts?: DetectSnapLocationOptions,\n): SnapLocation {\n const allowHttp = opts?.allowHttp ?? false;\n const root = new URL(location);\n switch (root.protocol) {\n case 'npm:':\n return new NpmLocation(root, opts);\n case 'local:':\n return new LocalLocation(root, opts);\n case 'http:':\n case 'https:':\n assert(\n allowHttp,\n new TypeError('Fetching snaps through http/https is disabled.'),\n );\n return new HttpLocation(root, opts);\n default:\n throw new TypeError(\n `Unrecognized \"${root.protocol}\" snap location protocol.`,\n );\n }\n}\n"]}
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { SemVerRange, SnapManifest, VirtualFile } from '@metamask/snaps-utils';
|
|
2
|
-
import { SnapLocation } from './location';
|
|
2
|
+
import { DetectSnapLocationOptions, SnapLocation } from './location';
|
|
3
3
|
export interface NpmOptions {
|
|
4
4
|
/**
|
|
5
5
|
* @default DEFAULT_REQUESTED_SNAP_VERSION
|
|
6
6
|
*/
|
|
7
7
|
versionRange?: SemVerRange;
|
|
8
|
-
/**
|
|
9
|
-
* The function used to fetch data.
|
|
10
|
-
*
|
|
11
|
-
* @default globalThis.fetch
|
|
12
|
-
*/
|
|
13
|
-
fetch?: typeof fetch;
|
|
14
8
|
/**
|
|
15
9
|
* Whether to allow custom NPM registries outside of {@link DEFAULT_NPM_REGISTRY}.
|
|
16
10
|
*
|
|
@@ -23,7 +17,7 @@ export declare class NpmLocation implements SnapLocation {
|
|
|
23
17
|
private readonly meta;
|
|
24
18
|
private validatedManifest?;
|
|
25
19
|
private files?;
|
|
26
|
-
constructor(url: URL, opts?:
|
|
20
|
+
constructor(url: URL, opts?: DetectSnapLocationOptions);
|
|
27
21
|
manifest(): Promise<VirtualFile<SnapManifest>>;
|
|
28
22
|
fetch(path: string): Promise<VirtualFile>;
|
|
29
23
|
get packageName(): string;
|
|
@@ -17,14 +17,13 @@ const gunzip_maybe_1 = __importDefault(require("gunzip-maybe"));
|
|
|
17
17
|
const pump_1 = __importDefault(require("pump"));
|
|
18
18
|
const readable_web_to_node_stream_1 = require("readable-web-to-node-stream");
|
|
19
19
|
const tar_stream_1 = require("tar-stream");
|
|
20
|
-
const utils_2 = require("../../utils");
|
|
21
20
|
const DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org';
|
|
22
21
|
class NpmLocation {
|
|
23
22
|
constructor(url, opts = {}) {
|
|
24
23
|
var _a, _b, _c;
|
|
25
24
|
_NpmLocation_instances.add(this);
|
|
26
25
|
const allowCustomRegistries = (_a = opts.allowCustomRegistries) !== null && _a !== void 0 ? _a : false;
|
|
27
|
-
const fetchFunction = (_b = opts.fetch) !== null && _b !== void 0 ? _b : globalThis.fetch;
|
|
26
|
+
const fetchFunction = (_b = opts.fetch) !== null && _b !== void 0 ? _b : globalThis.fetch.bind(globalThis);
|
|
28
27
|
const requestedRange = (_c = opts.versionRange) !== null && _c !== void 0 ? _c : snaps_utils_1.DEFAULT_REQUESTED_SNAP_VERSION;
|
|
29
28
|
(0, utils_1.assertStruct)(url.toString(), snaps_utils_1.NpmSnapIdStruct, 'Invalid Snap Id: ');
|
|
30
29
|
let registry;
|
|
@@ -66,15 +65,14 @@ class NpmLocation {
|
|
|
66
65
|
if (this.validatedManifest) {
|
|
67
66
|
return this.validatedManifest.clone();
|
|
68
67
|
}
|
|
69
|
-
const vfile = await this.fetch('
|
|
68
|
+
const vfile = await this.fetch('snap.manifest.json');
|
|
70
69
|
const result = JSON.parse(vfile.toString());
|
|
71
|
-
(0, snaps_utils_1.
|
|
72
|
-
vfile.result = result;
|
|
70
|
+
vfile.result = (0, snaps_utils_1.createSnapManifest)(result);
|
|
73
71
|
this.validatedManifest = vfile;
|
|
74
72
|
return this.manifest();
|
|
75
73
|
}
|
|
76
74
|
async fetch(path) {
|
|
77
|
-
const relativePath = (0,
|
|
75
|
+
const relativePath = (0, snaps_utils_1.normalizeRelative)(path);
|
|
78
76
|
if (!this.files) {
|
|
79
77
|
await __classPrivateFieldGet(this, _NpmLocation_instances, "m", _NpmLocation_lazyInit).call(this);
|
|
80
78
|
(0, utils_1.assert)(this.files !== undefined);
|
|
@@ -207,7 +205,7 @@ function createTarballStream(canonicalBase, files) {
|
|
|
207
205
|
const { name: headerName, type: headerType } = header;
|
|
208
206
|
if (headerType === 'file') {
|
|
209
207
|
// The name is a path if the header type is "file".
|
|
210
|
-
const path = headerName.replace(NPM_TARBALL_PATH_PREFIX, '
|
|
208
|
+
const path = headerName.replace(NPM_TARBALL_PATH_PREFIX, '');
|
|
211
209
|
return entryStream.pipe((0, concat_stream_1.default)((data) => {
|
|
212
210
|
const vfile = new snaps_utils_1.VirtualFile({
|
|
213
211
|
value: data,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../src/snaps/location/npm.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n assertIsSemVerVersion,\n assertIsSnapManifest,\n DEFAULT_REQUESTED_SNAP_VERSION,\n getTargetVersion,\n isValidUrl,\n NpmSnapIdStruct,\n SemVerRange,\n SemVerVersion,\n SnapManifest,\n VirtualFile,\n} from '@metamask/snaps-utils';\nimport { assert, assertStruct, isObject } from '@metamask/utils';\nimport concat from 'concat-stream';\nimport createGunzipStream from 'gunzip-maybe';\nimport pump from 'pump';\nimport { ReadableWebToNodeStream } from 'readable-web-to-node-stream';\nimport { Readable, Writable } from 'stream';\nimport { extract as tarExtract } from 'tar-stream';\n\nimport { ensureRelative } from '../../utils';\nimport { SnapLocation } from './location';\n\nconst DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org';\n\ninterface NpmMeta {\n registry: URL;\n packageName: string;\n requestedRange: SemVerRange;\n version?: string;\n fetch: typeof fetch;\n}\nexport interface NpmOptions {\n /**\n * @default DEFAULT_REQUESTED_SNAP_VERSION\n */\n versionRange?: SemVerRange;\n /**\n * The function used to fetch data.\n *\n * @default globalThis.fetch\n */\n fetch?: typeof fetch;\n /**\n * Whether to allow custom NPM registries outside of {@link DEFAULT_NPM_REGISTRY}.\n *\n * @default false\n */\n allowCustomRegistries?: boolean;\n}\n\nexport class NpmLocation implements SnapLocation {\n private readonly meta: NpmMeta;\n\n private validatedManifest?: VirtualFile<SnapManifest>;\n\n private files?: Map<string, VirtualFile>;\n\n constructor(url: URL, opts: NpmOptions = {}) {\n const allowCustomRegistries = opts.allowCustomRegistries ?? false;\n const fetchFunction = opts.fetch ?? globalThis.fetch;\n const requestedRange = opts.versionRange ?? DEFAULT_REQUESTED_SNAP_VERSION;\n\n assertStruct(url.toString(), NpmSnapIdStruct, 'Invalid Snap Id: ');\n\n let registry: string | URL;\n if (\n url.host === '' &&\n url.port === '' &&\n url.username === '' &&\n url.password === ''\n ) {\n registry = new URL(DEFAULT_NPM_REGISTRY);\n } else {\n registry = 'https://';\n if (url.username) {\n registry += url.username;\n if (url.password) {\n registry += `:${url.password}`;\n }\n registry += '@';\n }\n registry += url.host;\n registry = new URL(registry);\n assert(\n allowCustomRegistries,\n new TypeError(\n `Custom NPM registries are disabled, tried to use \"${registry.toString()}\".`,\n ),\n );\n }\n\n assert(\n registry.pathname === '/' &&\n registry.search === '' &&\n registry.hash === '',\n );\n\n assert(\n url.pathname !== '' && url.pathname !== '/',\n new TypeError('The package name in NPM location is empty.'),\n );\n let packageName = url.pathname;\n if (packageName.startsWith('/')) {\n packageName = packageName.slice(1);\n }\n\n this.meta = {\n requestedRange,\n registry,\n packageName,\n fetch: fetchFunction,\n };\n }\n\n async manifest(): Promise<VirtualFile<SnapManifest>> {\n if (this.validatedManifest) {\n return this.validatedManifest.clone();\n }\n\n const vfile = await this.fetch('./snap.manifest.json');\n const result = JSON.parse(vfile.toString());\n assertIsSnapManifest(result);\n vfile.result = result;\n this.validatedManifest = vfile as VirtualFile<SnapManifest>;\n\n return this.manifest();\n }\n\n async fetch(path: string): Promise<VirtualFile> {\n const relativePath = ensureRelative(path);\n if (!this.files) {\n await this.#lazyInit();\n assert(this.files !== undefined);\n }\n const vfile = this.files.get(relativePath);\n assert(\n vfile !== undefined,\n new TypeError(`File \"${path}\" not found in package.`),\n );\n return vfile.clone();\n }\n\n get packageName(): string {\n return this.meta.packageName;\n }\n\n get version(): string {\n assert(\n this.meta.version !== undefined,\n 'Tried to access version without first fetching NPM package.',\n );\n return this.meta.version;\n }\n\n get registry(): URL {\n return this.meta.registry;\n }\n\n get versionRange(): SemVerRange {\n return this.meta.requestedRange;\n }\n\n async #lazyInit() {\n assert(this.files === undefined);\n const [tarballResponse, actualVersion] = await fetchNpmTarball(\n this.meta.packageName,\n this.meta.requestedRange,\n this.meta.registry,\n this.meta.fetch,\n );\n this.meta.version = actualVersion;\n\n let canonicalBase = 'npm://';\n if (this.meta.registry.username !== '') {\n canonicalBase += this.meta.registry.username;\n if (this.meta.registry.password !== '') {\n canonicalBase += `:${this.meta.registry.password}`;\n }\n canonicalBase += '@';\n }\n canonicalBase += this.meta.registry.host;\n\n // TODO(ritave): Lazily extract files instead of up-front extracting all of them\n // We would need to replace tar-stream package because it requires immediate consumption of streams.\n await new Promise<void>((resolve, reject) => {\n this.files = new Map();\n pump(\n getNodeStream(tarballResponse),\n // The \"gz\" in \"tgz\" stands for \"gzip\". The tarball needs to be decompressed\n // before we can actually grab any files from it.\n createGunzipStream(),\n createTarballStream(\n `${canonicalBase}/${this.meta.packageName}/`,\n this.files,\n ),\n (error) => {\n error ? reject(error) : resolve();\n },\n );\n });\n }\n}\n\n/**\n * Fetches the tarball (`.tgz` file) of the specified package and version from\n * the public npm registry. Throws an error if fetching fails.\n *\n * @param packageName - The name of the package whose tarball to fetch.\n * @param versionRange - The SemVer range of the package to fetch. The highest\n * version satisfying the range will be fetched.\n * @param registryUrl - The URL of the npm registry to fetch the tarball from.\n * @param fetchFunction - The fetch function to use. Defaults to the global\n * {@link fetch}. Useful for Node.js compatibility.\n * @returns A tuple of the {@link Response} for the package tarball and the\n * actual version of the package.\n */\nasync function fetchNpmTarball(\n packageName: string,\n versionRange: SemVerRange,\n registryUrl: URL | string,\n fetchFunction: typeof fetch,\n): Promise<[ReadableStream, SemVerVersion]> {\n const packageMetadata = await (\n await fetchFunction(new URL(packageName, registryUrl).toString())\n ).json();\n\n if (!isObject(packageMetadata)) {\n throw new Error(\n `Failed to fetch package \"${packageName}\" metadata from npm.`,\n );\n }\n\n const versions = Object.keys((packageMetadata as any)?.versions ?? {}).map(\n (version) => {\n assertIsSemVerVersion(version);\n return version;\n },\n );\n\n const targetVersion = getTargetVersion(versions, versionRange);\n\n if (targetVersion === null) {\n throw new Error(\n `Failed to find a matching version in npm metadata for package \"${packageName}\" and requested semver range \"${versionRange}\".`,\n );\n }\n\n const tarballUrlString = (packageMetadata as any)?.versions?.[targetVersion]\n ?.dist?.tarball;\n\n if (\n !isValidUrl(tarballUrlString) ||\n !tarballUrlString.toString().endsWith('.tgz')\n ) {\n throw new Error(\n `Failed to find valid tarball URL in NPM metadata for package \"${packageName}\".`,\n );\n }\n\n // Override the tarball hostname/protocol with registryUrl hostname/protocol\n const newRegistryUrl = new URL(registryUrl);\n const newTarballUrl = new URL(tarballUrlString);\n newTarballUrl.hostname = newRegistryUrl.hostname;\n newTarballUrl.protocol = newRegistryUrl.protocol;\n\n // Perform a raw fetch because we want the Response object itself.\n const tarballResponse = await fetchFunction(newTarballUrl.toString());\n if (!tarballResponse.ok || !tarballResponse.body) {\n throw new Error(`Failed to fetch tarball for package \"${packageName}\".`);\n }\n return [tarballResponse.body, targetVersion];\n}\n\n/**\n * The paths of files within npm tarballs appear to always be prefixed with\n * \"package/\".\n */\nconst NPM_TARBALL_PATH_PREFIX = /^package\\//u;\n\n/**\n * Converts a {@link ReadableStream} to a Node.js {@link Readable}\n * stream. Returns the stream directly if it is already a Node.js stream.\n * We can't use the native Web {@link ReadableStream} directly because the\n * other stream libraries we use expect Node.js streams.\n *\n * @param stream - The stream to convert.\n * @returns The given stream as a Node.js Readable stream.\n */\nfunction getNodeStream(stream: ReadableStream): Readable {\n if (typeof stream.getReader !== 'function') {\n return stream as unknown as Readable;\n }\n\n return new ReadableWebToNodeStream(stream);\n}\n\n/**\n * Creates a `tar-stream` that will get the necessary files from an npm Snap\n * package tarball (`.tgz` file).\n *\n * @param canonicalBase - A base URI as specified in {@link https://github.com/MetaMask/SIPs/blob/main/SIPS/sip-8.md SIP-8}. Starting with 'npm:'. Will be used for canonicalPath vfile argument.\n * @param files - An object to write target file contents to.\n * @returns The {@link Writable} tarball extraction stream.\n */\nfunction createTarballStream(\n canonicalBase: string,\n files: Map<string, VirtualFile>,\n): Writable {\n assert(\n canonicalBase.endsWith('/'),\n \"Base needs to end with '/' for relative paths to be added as children instead of siblings.\",\n );\n\n assert(\n canonicalBase.startsWith('npm:'),\n 'Protocol mismatch, expected \"npm:\".',\n );\n // `tar-stream` is pretty old-school, so we create it first and then\n // instrument it by adding event listeners.\n const extractStream = tarExtract();\n\n // \"entry\" is fired for every discreet entity in the tarball. This includes\n // files and folders.\n extractStream.on('entry', (header, entryStream, next) => {\n const { name: headerName, type: headerType } = header;\n if (headerType === 'file') {\n // The name is a path if the header type is \"file\".\n const path = headerName.replace(NPM_TARBALL_PATH_PREFIX, './');\n return entryStream.pipe(\n concat((data) => {\n const vfile = new VirtualFile({\n value: data,\n path,\n data: {\n canonicalPath: new URL(path, canonicalBase).toString(),\n },\n });\n assert(\n !files.has(path),\n 'Malformed tarball, multiple files with the same path.',\n );\n files.set(path, vfile);\n return next();\n }),\n );\n }\n\n // If we get here, the entry is not a file, and we want to ignore. The entry\n // stream must be drained, or the extractStream will stop reading. This is\n // effectively a no-op for the current entry.\n entryStream.on('end', () => next());\n return entryStream.resume();\n });\n return extractStream;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../src/snaps/location/npm.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n assertIsSemVerVersion,\n createSnapManifest,\n DEFAULT_REQUESTED_SNAP_VERSION,\n getTargetVersion,\n isValidUrl,\n NpmSnapIdStruct,\n SemVerRange,\n SemVerVersion,\n SnapManifest,\n VirtualFile,\n normalizeRelative,\n} from '@metamask/snaps-utils';\nimport { assert, assertStruct, isObject } from '@metamask/utils';\nimport concat from 'concat-stream';\nimport createGunzipStream from 'gunzip-maybe';\nimport pump from 'pump';\nimport { ReadableWebToNodeStream } from 'readable-web-to-node-stream';\nimport { Readable, Writable } from 'stream';\nimport { extract as tarExtract } from 'tar-stream';\n\nimport { DetectSnapLocationOptions, SnapLocation } from './location';\n\nconst DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org';\n\ninterface NpmMeta {\n registry: URL;\n packageName: string;\n requestedRange: SemVerRange;\n version?: string;\n fetch: typeof fetch;\n}\nexport interface NpmOptions {\n /**\n * @default DEFAULT_REQUESTED_SNAP_VERSION\n */\n versionRange?: SemVerRange;\n /**\n * Whether to allow custom NPM registries outside of {@link DEFAULT_NPM_REGISTRY}.\n *\n * @default false\n */\n allowCustomRegistries?: boolean;\n}\n\nexport class NpmLocation implements SnapLocation {\n private readonly meta: NpmMeta;\n\n private validatedManifest?: VirtualFile<SnapManifest>;\n\n private files?: Map<string, VirtualFile>;\n\n constructor(url: URL, opts: DetectSnapLocationOptions = {}) {\n const allowCustomRegistries = opts.allowCustomRegistries ?? false;\n const fetchFunction = opts.fetch ?? globalThis.fetch.bind(globalThis);\n const requestedRange = opts.versionRange ?? DEFAULT_REQUESTED_SNAP_VERSION;\n\n assertStruct(url.toString(), NpmSnapIdStruct, 'Invalid Snap Id: ');\n\n let registry: string | URL;\n if (\n url.host === '' &&\n url.port === '' &&\n url.username === '' &&\n url.password === ''\n ) {\n registry = new URL(DEFAULT_NPM_REGISTRY);\n } else {\n registry = 'https://';\n if (url.username) {\n registry += url.username;\n if (url.password) {\n registry += `:${url.password}`;\n }\n registry += '@';\n }\n registry += url.host;\n registry = new URL(registry);\n assert(\n allowCustomRegistries,\n new TypeError(\n `Custom NPM registries are disabled, tried to use \"${registry.toString()}\".`,\n ),\n );\n }\n\n assert(\n registry.pathname === '/' &&\n registry.search === '' &&\n registry.hash === '',\n );\n\n assert(\n url.pathname !== '' && url.pathname !== '/',\n new TypeError('The package name in NPM location is empty.'),\n );\n let packageName = url.pathname;\n if (packageName.startsWith('/')) {\n packageName = packageName.slice(1);\n }\n\n this.meta = {\n requestedRange,\n registry,\n packageName,\n fetch: fetchFunction,\n };\n }\n\n async manifest(): Promise<VirtualFile<SnapManifest>> {\n if (this.validatedManifest) {\n return this.validatedManifest.clone();\n }\n\n const vfile = await this.fetch('snap.manifest.json');\n const result = JSON.parse(vfile.toString());\n vfile.result = createSnapManifest(result);\n this.validatedManifest = vfile as VirtualFile<SnapManifest>;\n\n return this.manifest();\n }\n\n async fetch(path: string): Promise<VirtualFile> {\n const relativePath = normalizeRelative(path);\n if (!this.files) {\n await this.#lazyInit();\n assert(this.files !== undefined);\n }\n const vfile = this.files.get(relativePath);\n assert(\n vfile !== undefined,\n new TypeError(`File \"${path}\" not found in package.`),\n );\n return vfile.clone();\n }\n\n get packageName(): string {\n return this.meta.packageName;\n }\n\n get version(): string {\n assert(\n this.meta.version !== undefined,\n 'Tried to access version without first fetching NPM package.',\n );\n return this.meta.version;\n }\n\n get registry(): URL {\n return this.meta.registry;\n }\n\n get versionRange(): SemVerRange {\n return this.meta.requestedRange;\n }\n\n async #lazyInit() {\n assert(this.files === undefined);\n const [tarballResponse, actualVersion] = await fetchNpmTarball(\n this.meta.packageName,\n this.meta.requestedRange,\n this.meta.registry,\n this.meta.fetch,\n );\n this.meta.version = actualVersion;\n\n let canonicalBase = 'npm://';\n if (this.meta.registry.username !== '') {\n canonicalBase += this.meta.registry.username;\n if (this.meta.registry.password !== '') {\n canonicalBase += `:${this.meta.registry.password}`;\n }\n canonicalBase += '@';\n }\n canonicalBase += this.meta.registry.host;\n\n // TODO(ritave): Lazily extract files instead of up-front extracting all of them\n // We would need to replace tar-stream package because it requires immediate consumption of streams.\n await new Promise<void>((resolve, reject) => {\n this.files = new Map();\n pump(\n getNodeStream(tarballResponse),\n // The \"gz\" in \"tgz\" stands for \"gzip\". The tarball needs to be decompressed\n // before we can actually grab any files from it.\n createGunzipStream(),\n createTarballStream(\n `${canonicalBase}/${this.meta.packageName}/`,\n this.files,\n ),\n (error) => {\n error ? reject(error) : resolve();\n },\n );\n });\n }\n}\n\n/**\n * Fetches the tarball (`.tgz` file) of the specified package and version from\n * the public npm registry. Throws an error if fetching fails.\n *\n * @param packageName - The name of the package whose tarball to fetch.\n * @param versionRange - The SemVer range of the package to fetch. The highest\n * version satisfying the range will be fetched.\n * @param registryUrl - The URL of the npm registry to fetch the tarball from.\n * @param fetchFunction - The fetch function to use. Defaults to the global\n * {@link fetch}. Useful for Node.js compatibility.\n * @returns A tuple of the {@link Response} for the package tarball and the\n * actual version of the package.\n */\nasync function fetchNpmTarball(\n packageName: string,\n versionRange: SemVerRange,\n registryUrl: URL | string,\n fetchFunction: typeof fetch,\n): Promise<[ReadableStream, SemVerVersion]> {\n const packageMetadata = await (\n await fetchFunction(new URL(packageName, registryUrl).toString())\n ).json();\n\n if (!isObject(packageMetadata)) {\n throw new Error(\n `Failed to fetch package \"${packageName}\" metadata from npm.`,\n );\n }\n\n const versions = Object.keys((packageMetadata as any)?.versions ?? {}).map(\n (version) => {\n assertIsSemVerVersion(version);\n return version;\n },\n );\n\n const targetVersion = getTargetVersion(versions, versionRange);\n\n if (targetVersion === null) {\n throw new Error(\n `Failed to find a matching version in npm metadata for package \"${packageName}\" and requested semver range \"${versionRange}\".`,\n );\n }\n\n const tarballUrlString = (packageMetadata as any)?.versions?.[targetVersion]\n ?.dist?.tarball;\n\n if (\n !isValidUrl(tarballUrlString) ||\n !tarballUrlString.toString().endsWith('.tgz')\n ) {\n throw new Error(\n `Failed to find valid tarball URL in NPM metadata for package \"${packageName}\".`,\n );\n }\n\n // Override the tarball hostname/protocol with registryUrl hostname/protocol\n const newRegistryUrl = new URL(registryUrl);\n const newTarballUrl = new URL(tarballUrlString);\n newTarballUrl.hostname = newRegistryUrl.hostname;\n newTarballUrl.protocol = newRegistryUrl.protocol;\n\n // Perform a raw fetch because we want the Response object itself.\n const tarballResponse = await fetchFunction(newTarballUrl.toString());\n if (!tarballResponse.ok || !tarballResponse.body) {\n throw new Error(`Failed to fetch tarball for package \"${packageName}\".`);\n }\n return [tarballResponse.body, targetVersion];\n}\n\n/**\n * The paths of files within npm tarballs appear to always be prefixed with\n * \"package/\".\n */\nconst NPM_TARBALL_PATH_PREFIX = /^package\\//u;\n\n/**\n * Converts a {@link ReadableStream} to a Node.js {@link Readable}\n * stream. Returns the stream directly if it is already a Node.js stream.\n * We can't use the native Web {@link ReadableStream} directly because the\n * other stream libraries we use expect Node.js streams.\n *\n * @param stream - The stream to convert.\n * @returns The given stream as a Node.js Readable stream.\n */\nfunction getNodeStream(stream: ReadableStream): Readable {\n if (typeof stream.getReader !== 'function') {\n return stream as unknown as Readable;\n }\n\n return new ReadableWebToNodeStream(stream);\n}\n\n/**\n * Creates a `tar-stream` that will get the necessary files from an npm Snap\n * package tarball (`.tgz` file).\n *\n * @param canonicalBase - A base URI as specified in {@link https://github.com/MetaMask/SIPs/blob/main/SIPS/sip-8.md SIP-8}. Starting with 'npm:'. Will be used for canonicalPath vfile argument.\n * @param files - An object to write target file contents to.\n * @returns The {@link Writable} tarball extraction stream.\n */\nfunction createTarballStream(\n canonicalBase: string,\n files: Map<string, VirtualFile>,\n): Writable {\n assert(\n canonicalBase.endsWith('/'),\n \"Base needs to end with '/' for relative paths to be added as children instead of siblings.\",\n );\n\n assert(\n canonicalBase.startsWith('npm:'),\n 'Protocol mismatch, expected \"npm:\".',\n );\n // `tar-stream` is pretty old-school, so we create it first and then\n // instrument it by adding event listeners.\n const extractStream = tarExtract();\n\n // \"entry\" is fired for every discreet entity in the tarball. This includes\n // files and folders.\n extractStream.on('entry', (header, entryStream, next) => {\n const { name: headerName, type: headerType } = header;\n if (headerType === 'file') {\n // The name is a path if the header type is \"file\".\n const path = headerName.replace(NPM_TARBALL_PATH_PREFIX, '');\n return entryStream.pipe(\n concat((data) => {\n const vfile = new VirtualFile({\n value: data,\n path,\n data: {\n canonicalPath: new URL(path, canonicalBase).toString(),\n },\n });\n assert(\n !files.has(path),\n 'Malformed tarball, multiple files with the same path.',\n );\n files.set(path, vfile);\n return next();\n }),\n );\n }\n\n // If we get here, the entry is not a file, and we want to ignore. The entry\n // stream must be drained, or the extractStream will stop reading. This is\n // effectively a no-op for the current entry.\n entryStream.on('end', () => next());\n return entryStream.resume();\n });\n return extractStream;\n}\n"]}
|
package/dist/utils.d.ts
CHANGED
|
@@ -125,11 +125,4 @@ export declare type Mutable<T extends Record<string, unknown>, TargetKey extends
|
|
|
125
125
|
} & {
|
|
126
126
|
[Key in keyof Omit<T, TargetKey>]: T[Key];
|
|
127
127
|
};
|
|
128
|
-
/**
|
|
129
|
-
* Ensures that a relative path starts with `./` prefix.
|
|
130
|
-
*
|
|
131
|
-
* @param path - Path to make relative.
|
|
132
|
-
* @returns The same path, with optional `./` prefix.
|
|
133
|
-
*/
|
|
134
|
-
export declare function ensureRelative(path: string): string;
|
|
135
128
|
export {};
|
package/dist/utils.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const utils_1 = require("@metamask/utils");
|
|
3
|
+
exports.withTimeout = exports.hasTimedOut = exports.delayWithTimer = exports.delay = exports.setDiff = void 0;
|
|
5
4
|
const Timer_1 = require("./snaps/Timer");
|
|
6
5
|
/**
|
|
7
6
|
* Takes two objects and does a Set Difference of them.
|
|
@@ -90,19 +89,4 @@ async function withTimeout(promise, timerOrMs) {
|
|
|
90
89
|
}
|
|
91
90
|
}
|
|
92
91
|
exports.withTimeout = withTimeout;
|
|
93
|
-
/**
|
|
94
|
-
* Ensures that a relative path starts with `./` prefix.
|
|
95
|
-
*
|
|
96
|
-
* @param path - Path to make relative.
|
|
97
|
-
* @returns The same path, with optional `./` prefix.
|
|
98
|
-
*/
|
|
99
|
-
function ensureRelative(path) {
|
|
100
|
-
(0, utils_1.assert)(!path.startsWith('/'));
|
|
101
|
-
(0, utils_1.assert)(path.search(/:|\/\//u) === -1, `Path "${path}" potentially an URI instead of local relative`);
|
|
102
|
-
if (path.startsWith('./')) {
|
|
103
|
-
return path;
|
|
104
|
-
}
|
|
105
|
-
return `./${path}`;
|
|
106
|
-
}
|
|
107
|
-
exports.ensureRelative = ensureRelative;
|
|
108
92
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC;;;;;;;;;;;;;GAaG;AACH,SAAgB,OAAO,CAGrB,OAAgB,EAAE,OAAgB;IAClC,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE;YACrB,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;SAClB;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EACD,EAAE,CACuB,CAAC;AAC9B,CAAC;AAbD,0BAaC;AAED;;;;;;;GAOG;AACH,SAAgB,KAAK,CACnB,EAAU,EACV,MAAe;IAEf,OAAO,cAAc,CAAC,IAAI,aAAK,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AALD,sBAKC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAC5B,KAAY,EACZ,MAAe;IAEf,IAAI,UAAmC,CAAC;IACxC,MAAM,OAAO,GAAQ,IAAI,OAAO,CAAS,CAAC,OAAY,EAAE,MAAM,EAAE,EAAE;QAChE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;YACf,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QACH,UAAU,GAAG,MAAM,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE;QACpB,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE;YAC/B,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,UAAU,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;SACvD;IACH,CAAC,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAnBD,wCAmBC;AAED;;;GAGG;AACU,QAAA,WAAW,GAAG,MAAM,CAC/B,sEAAsE,CACvE,CAAC;AAEF;;;;;;;;;;GAUG;AACI,KAAK,UAAU,WAAW,CAC/B,OAA8B,EAC9B,SAAyB;IAEzB,MAAM,KAAK,GACT,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,aAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,EAAE,mBAAW,CAAC,CAAC;IACxD,IAAI;QACF,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;KACpD;YAAS;QACR,YAAY,CAAC,MAAM,EAAE,CAAC;KACvB;AACH,CAAC;AAZD,kCAYC","sourcesContent":["import { Timer } from './snaps/Timer';\n\n/**\n * Takes two objects and does a Set Difference of them.\n * Set Difference is generally defined as follows:\n * ```\n * 𝑥 ∈ A ∖ B ⟺ 𝑥 ∈ A ∧ 𝑥 ∉ B\n * ```\n * Meaning that the returned object contains all properties of A expect those that also\n * appear in B. Notice that properties that appear in B, but not in A, have no effect.\n *\n * @see [Set Difference]{@link https://proofwiki.org/wiki/Definition:Set_Difference}\n * @param objectA - The object on which the difference is being calculated.\n * @param objectB - The object whose properties will be removed from objectA.\n * @returns The objectA without properties from objectB.\n */\nexport function setDiff<\n ObjectA extends Record<any, unknown>,\n ObjectB extends Record<any, unknown>,\n>(objectA: ObjectA, objectB: ObjectB): Diff<ObjectA, ObjectB> {\n return Object.entries(objectA).reduce<Record<any, unknown>>(\n (acc, [key, value]) => {\n if (!(key in objectB)) {\n acc[key] = value;\n }\n return acc;\n },\n {},\n ) as Diff<ObjectA, ObjectB>;\n}\n\n/**\n * A Promise that delays it's return for a given amount of milliseconds.\n *\n * @param ms - Milliseconds to delay the execution for.\n * @param result - The result to return from the Promise after delay.\n * @returns A promise that is void if no result provided, result otherwise.\n * @template Result - The `result`.\n */\nexport function delay<Result = void>(\n ms: number,\n result?: Result,\n): Promise<Result> & { cancel: () => void } {\n return delayWithTimer(new Timer(ms), result);\n}\n\n/**\n * A Promise that delays it's return by using a pausable Timer.\n *\n * @param timer - Timer used to control the delay.\n * @param result - The result to return from the Promise after delay.\n * @returns A promise that is void if no result provided, result otherwise.\n * @template Result - The `result`.\n */\nexport function delayWithTimer<Result = void>(\n timer: Timer,\n result?: Result,\n): Promise<Result> & { cancel: () => void } {\n let rejectFunc: (reason: Error) => void;\n const promise: any = new Promise<Result>((resolve: any, reject) => {\n timer.start(() => {\n result === undefined ? resolve() : resolve(result);\n });\n rejectFunc = reject;\n });\n\n promise.cancel = () => {\n if (timer.status !== 'finished') {\n timer.cancel();\n rejectFunc(new Error('The delay has been canceled.'));\n }\n };\n return promise;\n}\n\n/*\n * We use a Symbol instead of rejecting the promise so that Errors thrown\n * by the main promise will propagate.\n */\nexport const hasTimedOut = Symbol(\n 'Used to check if the requested promise has timeout (see withTimeout)',\n);\n\n/**\n * Executes the given Promise, if the Timer expires before the Promise settles, we return earlier.\n *\n * NOTE:** The given Promise is not cancelled or interrupted, and will continue to execute uninterrupted. We will just discard its result if it does not complete before the timeout.\n *\n * @param promise - The promise that you want to execute.\n * @param timerOrMs - The timer controlling the timeout or a ms value.\n * @returns The resolved `PromiseValue`, or the hasTimedOut symbol if\n * returning early.\n * @template PromiseValue- - The value of the Promise.\n */\nexport async function withTimeout<PromiseValue = void>(\n promise: Promise<PromiseValue>,\n timerOrMs: Timer | number,\n): Promise<PromiseValue | typeof hasTimedOut> {\n const timer =\n typeof timerOrMs === 'number' ? new Timer(timerOrMs) : timerOrMs;\n const delayPromise = delayWithTimer(timer, hasTimedOut);\n try {\n return await Promise.race([promise, delayPromise]);\n } finally {\n delayPromise.cancel();\n }\n}\n\n/**\n * Checks whether the type is composed of literal types\n *\n * @returns @type {true} if whole type is composed of literals, @type {false} if whole type is not literals, @type {boolean} if mixed\n * @example\n * ```\n * type t1 = IsLiteral<1 | 2 | \"asd\" | true>;\n * // t1 = true\n *\n * type t2 = IsLiteral<number | string>;\n * // t2 = false\n *\n * type t3 = IsLiteral<1 | string>;\n * // t3 = boolean\n *\n * const s = Symbol();\n * type t4 = IsLiteral<typeof s>;\n * // t4 = true\n *\n * type t5 = IsLiteral<symbol>\n * // t5 = false;\n * ```\n */\ntype IsLiteral<T> = T extends string | number | boolean | symbol\n ? Extract<string | number | boolean | symbol, T> extends never\n ? true\n : false\n : false;\n\n/**\n * Returns all keys of an object, that are literal, as an union\n *\n * @example\n * ```\n * type t1 = _LiteralKeys<{a: number, b: 0, c: 'foo', d: string}>\n * // t1 = 'b' | 'c'\n * ```\n * @see [Literal types]{@link https://www.typescriptlang.org/docs/handbook/literal-types.html}\n */\ntype LiteralKeys<T> = NonNullable<\n {\n [Key in keyof T]: IsLiteral<Key> extends true ? Key : never;\n }[keyof T]\n>;\n\n/**\n * Returns all keys of an object, that are not literal, as an union\n *\n * @example\n * ```\n * type t1 = _NonLiteralKeys<{a: number, b: 0, c: 'foo', d: string}>\n * // t1 = 'a' | 'd'\n * ```\n * @see [Literal types]{@link https://www.typescriptlang.org/docs/handbook/literal-types.html}\n */\ntype NonLiteralKeys<T> = NonNullable<\n {\n [Key in keyof T]: IsLiteral<Key> extends false ? Key : never;\n }[keyof T]\n>;\n\n/**\n * A set difference of two objects based on their keys\n *\n * @example\n * ```\n * type t1 = Diff<{a: string, b: string}, {a: number}>\n * // t1 = {b: string};\n * type t2 = Diff<{a: string, 0: string}, Record<string, unknown>>;\n * // t2 = { a?: string, 0: string};\n * type t3 = Diff<{a: string, 0: string, 1: string}, Record<1 | string, unknown>>;\n * // t3 = {a?: string, 0: string}\n * ```\n * @see {@link setDiff} for the main use-case\n */\nexport type Diff<A, B> = Omit<A, LiteralKeys<B>> &\n Partial<Pick<A, Extract<keyof A, NonLiteralKeys<B>>>>;\n\n/**\n * Makes every specified property of the specified object type mutable.\n *\n * @template T - The object whose readonly properties to make mutable.\n * @template TargetKey - The property key(s) to make mutable.\n */\nexport type Mutable<\n T extends Record<string, unknown>,\n TargetKey extends string,\n> = {\n -readonly [Key in keyof Pick<T, TargetKey>]: T[Key];\n} & {\n [Key in keyof Omit<T, TargetKey>]: T[Key];\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/snaps-controllers",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.1",
|
|
4
4
|
"description": "Controllers for MetaMask Snaps.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"@metamask/object-multiplex": "^1.1.0",
|
|
38
38
|
"@metamask/permission-controller": "^1.0.1",
|
|
39
39
|
"@metamask/post-message-stream": "^6.0.0",
|
|
40
|
-
"@metamask/rpc-methods": "^0.26.
|
|
41
|
-
"@metamask/snaps-execution-environments": "^0.26.
|
|
42
|
-
"@metamask/snaps-types": "^0.26.
|
|
43
|
-
"@metamask/snaps-utils": "^0.26.
|
|
40
|
+
"@metamask/rpc-methods": "^0.26.1",
|
|
41
|
+
"@metamask/snaps-execution-environments": "^0.26.1",
|
|
42
|
+
"@metamask/snaps-types": "^0.26.1",
|
|
43
|
+
"@metamask/snaps-utils": "^0.26.1",
|
|
44
44
|
"@metamask/subject-metadata-controller": "^1.0.1",
|
|
45
45
|
"@metamask/utils": "^3.3.1",
|
|
46
46
|
"@xstate/fsm": "^2.0.0",
|