@metamask/snaps-controllers 0.31.0 → 0.32.0

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.
@@ -6,7 +6,7 @@ const child_process_1 = require("child_process");
6
6
  const __1 = require("..");
7
7
  class NodeProcessExecutionService extends __1.AbstractExecutionService {
8
8
  async initEnvStream() {
9
- const worker = (0, child_process_1.fork)(require.resolve('@metamask/snaps-execution-environments/dist/webpack/node-process/bundle.js'));
9
+ const worker = (0, child_process_1.fork)(require.resolve('@metamask/snaps-execution-environments/dist/browserify/node-process/bundle.js'));
10
10
  const stream = new post_message_stream_1.ProcessParentMessageStream({ process: worker });
11
11
  return Promise.resolve({ worker, stream });
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NodeProcessExecutionService.js","sourceRoot":"","sources":["../../../src/services/node/NodeProcessExecutionService.ts"],"names":[],"mappings":";;;AAAA,uEAGuC;AACvC,iDAAmD;AAEnD,0BAAmD;AAEnD,MAAa,2BAA4B,SAAQ,4BAAsC;IAC3E,KAAK,CAAC,aAAa;QAI3B,MAAM,MAAM,GAAG,IAAA,oBAAI,EACjB,OAAO,CAAC,OAAO,CACb,4EAA4E,CAC7E,CACF,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,gDAA0B,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,YAAY,CAAC,UAA6B;QAClD,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AAlBD,kEAkBC","sourcesContent":["import {\n ProcessParentMessageStream,\n BasePostMessageStream,\n} from '@metamask/post-message-stream';\nimport { ChildProcess, fork } from 'child_process';\n\nimport { AbstractExecutionService, Job } from '..';\n\nexport class NodeProcessExecutionService extends AbstractExecutionService<ChildProcess> {\n protected async initEnvStream(): Promise<{\n worker: ChildProcess;\n stream: BasePostMessageStream;\n }> {\n const worker = fork(\n require.resolve(\n '@metamask/snaps-execution-environments/dist/webpack/node-process/bundle.js',\n ),\n );\n\n const stream = new ProcessParentMessageStream({ process: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected terminateJob(jobWrapper: Job<ChildProcess>): void {\n jobWrapper.worker.kill();\n }\n}\n"]}
1
+ {"version":3,"file":"NodeProcessExecutionService.js","sourceRoot":"","sources":["../../../src/services/node/NodeProcessExecutionService.ts"],"names":[],"mappings":";;;AAAA,uEAGuC;AACvC,iDAAmD;AAEnD,0BAAmD;AAEnD,MAAa,2BAA4B,SAAQ,4BAAsC;IAC3E,KAAK,CAAC,aAAa;QAI3B,MAAM,MAAM,GAAG,IAAA,oBAAI,EACjB,OAAO,CAAC,OAAO,CACb,+EAA+E,CAChF,CACF,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,gDAA0B,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,YAAY,CAAC,UAA6B;QAClD,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AAlBD,kEAkBC","sourcesContent":["import {\n ProcessParentMessageStream,\n BasePostMessageStream,\n} from '@metamask/post-message-stream';\nimport { ChildProcess, fork } from 'child_process';\n\nimport { AbstractExecutionService, Job } from '..';\n\nexport class NodeProcessExecutionService extends AbstractExecutionService<ChildProcess> {\n protected async initEnvStream(): Promise<{\n worker: ChildProcess;\n stream: BasePostMessageStream;\n }> {\n const worker = fork(\n require.resolve(\n '@metamask/snaps-execution-environments/dist/browserify/node-process/bundle.js',\n ),\n );\n\n const stream = new ProcessParentMessageStream({ process: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected terminateJob(jobWrapper: Job<ChildProcess>): void {\n jobWrapper.worker.kill();\n }\n}\n"]}
@@ -7,7 +7,7 @@ const worker_threads_1 = require("worker_threads");
7
7
  const __1 = require("..");
8
8
  class NodeThreadExecutionService extends __1.AbstractExecutionService {
9
9
  async initEnvStream() {
10
- const worker = new worker_threads_1.Worker(require.resolve('@metamask/snaps-execution-environments/dist/webpack/node-thread/bundle.js'));
10
+ const worker = new worker_threads_1.Worker(require.resolve('@metamask/snaps-execution-environments/dist/browserify/node-thread/bundle.js'));
11
11
  const stream = new post_message_stream_1.ThreadParentMessageStream({ thread: worker });
12
12
  return Promise.resolve({ worker, stream });
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NodeThreadExecutionService.js","sourceRoot":"","sources":["../../../src/services/node/NodeThreadExecutionService.ts"],"names":[],"mappings":";;;AAAA,uEAGuC;AACvC,wDAAwD;AACxD,mDAAwC;AAExC,0BAAmD;AAEnD,MAAa,0BAA2B,SAAQ,4BAAgC;IACpE,KAAK,CAAC,aAAa;QAI3B,MAAM,MAAM,GAAG,IAAI,uBAAM,CACvB,OAAO,CAAC,OAAO,CACb,2EAA2E,CAC5E,CACF,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,+CAAyB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,KAAK,CAAC,YAAY,CAAC,UAAuB;QAClD,MAAM,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACtC,CAAC;CACF;AAjBD,gEAiBC","sourcesContent":["import {\n ThreadParentMessageStream,\n BasePostMessageStream,\n} from '@metamask/post-message-stream';\n// eslint-disable-next-line @typescript-eslint/no-shadow\nimport { Worker } from 'worker_threads';\n\nimport { AbstractExecutionService, Job } from '..';\n\nexport class NodeThreadExecutionService extends AbstractExecutionService<Worker> {\n protected async initEnvStream(): Promise<{\n worker: Worker;\n stream: BasePostMessageStream;\n }> {\n const worker = new Worker(\n require.resolve(\n '@metamask/snaps-execution-environments/dist/webpack/node-thread/bundle.js',\n ),\n );\n const stream = new ThreadParentMessageStream({ thread: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected async terminateJob(jobWrapper: Job<Worker>): Promise<void> {\n await jobWrapper.worker.terminate();\n }\n}\n"]}
1
+ {"version":3,"file":"NodeThreadExecutionService.js","sourceRoot":"","sources":["../../../src/services/node/NodeThreadExecutionService.ts"],"names":[],"mappings":";;;AAAA,uEAGuC;AACvC,wDAAwD;AACxD,mDAAwC;AAExC,0BAAmD;AAEnD,MAAa,0BAA2B,SAAQ,4BAAgC;IACpE,KAAK,CAAC,aAAa;QAI3B,MAAM,MAAM,GAAG,IAAI,uBAAM,CACvB,OAAO,CAAC,OAAO,CACb,8EAA8E,CAC/E,CACF,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,+CAAyB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,KAAK,CAAC,YAAY,CAAC,UAAuB;QAClD,MAAM,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACtC,CAAC;CACF;AAjBD,gEAiBC","sourcesContent":["import {\n ThreadParentMessageStream,\n BasePostMessageStream,\n} from '@metamask/post-message-stream';\n// eslint-disable-next-line @typescript-eslint/no-shadow\nimport { Worker } from 'worker_threads';\n\nimport { AbstractExecutionService, Job } from '..';\n\nexport class NodeThreadExecutionService extends AbstractExecutionService<Worker> {\n protected async initEnvStream(): Promise<{\n worker: Worker;\n stream: BasePostMessageStream;\n }> {\n const worker = new Worker(\n require.resolve(\n '@metamask/snaps-execution-environments/dist/browserify/node-thread/bundle.js',\n ),\n );\n const stream = new ThreadParentMessageStream({ thread: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected async terminateJob(jobWrapper: Job<Worker>): Promise<void> {\n await jobWrapper.worker.terminate();\n }\n}\n"]}
@@ -9,7 +9,7 @@ import { StateMachine } from '@xstate/fsm';
9
9
  import type { Patch } from 'immer';
10
10
  import { ExecuteSnapAction, ExecutionServiceEvents, HandleRpcRequestAction, SnapErrorJson, TerminateAllSnapsAction, TerminateSnapAction } from '../services';
11
11
  import { detectSnapLocation, SnapLocation } from './location';
12
- import { SnapsRegistry, SnapsRegistryMetadata } from './registry';
12
+ import { GetMetadata, GetResult, SnapsRegistryMetadata } from './registry';
13
13
  import { Timer } from './Timer';
14
14
  export declare const controllerName = "SnapController";
15
15
  export declare const SNAP_APPROVAL_INSTALL = "wallet_installSnap";
@@ -239,7 +239,7 @@ export declare type SnapTerminated = {
239
239
  payload: [snap: TruncatedSnap];
240
240
  };
241
241
  export declare type SnapControllerEvents = SnapAdded | SnapBlocked | SnapInstalled | SnapRemoved | SnapStateChange | SnapUnblocked | SnapUpdated | SnapRolledback | SnapTerminated;
242
- export declare type AllowedActions = GetEndowments | GetPermissions | GetSubjects | GetSubjectMetadata | HasPermission | HasPermissions | RevokePermissions | RevokeAllPermissions | RevokePermissionForAllSubjects | GrantPermissions | AddApprovalRequest | HandleRpcRequestAction | ExecuteSnapAction | TerminateAllSnapsAction | TerminateSnapAction | UpdateCaveat | UpdateRequestState;
242
+ export declare type AllowedActions = GetEndowments | GetPermissions | GetSubjects | GetSubjectMetadata | HasPermission | HasPermissions | RevokePermissions | RevokeAllPermissions | RevokePermissionForAllSubjects | GrantPermissions | AddApprovalRequest | HandleRpcRequestAction | ExecuteSnapAction | TerminateAllSnapsAction | TerminateSnapAction | UpdateCaveat | UpdateRequestState | GetResult | GetMetadata;
243
243
  export declare type AllowedEvents = ExecutionServiceEvents;
244
244
  declare type SnapControllerMessenger = RestrictedControllerMessenger<typeof controllerName, SnapControllerActions | AllowedActions, SnapControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
245
245
  declare type FeatureFlags = {
@@ -283,10 +283,6 @@ declare type SnapControllerArgs = {
283
283
  * How frequently to check whether a snap is idle.
284
284
  */
285
285
  idleTimeCheckInterval?: number;
286
- /**
287
- * A registry implementation used for checking for verified and blocked snaps.
288
- */
289
- registry: SnapsRegistry;
290
286
  /**
291
287
  * The maximum amount of time that a snap may be idle.
292
288
  */
@@ -319,7 +315,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
319
315
  #private;
320
316
  private readonly maxRequestTime;
321
317
  private readonly snapsRuntimeData;
322
- constructor({ closeAllConnections, messenger, state, environmentEndowmentPermissions, excludedPermissions, idleTimeCheckInterval, registry, maxIdleTime, maxRequestTime, fetchFunction, featureFlags, detectSnapLocation: detectSnapLocationFunction, }: SnapControllerArgs);
318
+ constructor({ closeAllConnections, messenger, state, environmentEndowmentPermissions, excludedPermissions, idleTimeCheckInterval, maxIdleTime, maxRequestTime, fetchFunction, featureFlags, detectSnapLocation: detectSnapLocationFunction, }: SnapControllerArgs);
323
319
  /**
324
320
  * Checks all installed snaps against the block list and
325
321
  * blocks/unblocks snaps as appropriate. See {@link SnapController.blockSnap}
@@ -10,7 +10,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
11
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
12
  };
13
- var _SnapController_instances, _SnapController_closeAllConnections, _SnapController_environmentEndowmentPermissions, _SnapController_excludedPermissions, _SnapController_featureFlags, _SnapController_fetchFunction, _SnapController_idleTimeCheckInterval, _SnapController_registry, _SnapController_maxIdleTime, _SnapController_detectSnapLocation, _SnapController_rollbackSnapshots, _SnapController_timeoutForLastRequestStatus, _SnapController_statusMachine, _SnapController_initializeStateMachine, _SnapController_registerMessageHandlers, _SnapController_pollForLastRequestStatus, _SnapController_blockSnap, _SnapController_unblockSnap, _SnapController_assertIsInstallAllowed, _SnapController_stopSnapsLastRequestPastMax, _SnapController_transition, _SnapController_terminateSnap, _SnapController_removeSnapFromSubjects, _SnapController_createApproval, _SnapController_updateApproval, _SnapController_add, _SnapController_startSnap, _SnapController_getEndowments, _SnapController_set, _SnapController_fetchSnap, _SnapController_processSnapPermissions, _SnapController_validateSnapPermissions, _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;
13
+ var _SnapController_instances, _SnapController_closeAllConnections, _SnapController_environmentEndowmentPermissions, _SnapController_excludedPermissions, _SnapController_featureFlags, _SnapController_fetchFunction, _SnapController_idleTimeCheckInterval, _SnapController_maxIdleTime, _SnapController_detectSnapLocation, _SnapController_rollbackSnapshots, _SnapController_timeoutForLastRequestStatus, _SnapController_statusMachine, _SnapController_initializeStateMachine, _SnapController_registerMessageHandlers, _SnapController_pollForLastRequestStatus, _SnapController_blockSnap, _SnapController_unblockSnap, _SnapController_assertIsInstallAllowed, _SnapController_stopSnapsLastRequestPastMax, _SnapController_transition, _SnapController_terminateSnap, _SnapController_removeSnapFromSubjects, _SnapController_createApproval, _SnapController_updateApproval, _SnapController_add, _SnapController_startSnap, _SnapController_getEndowments, _SnapController_set, _SnapController_fetchSnap, _SnapController_processSnapPermissions, _SnapController_validateSnapPermissions, _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;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.SnapController = exports.SNAP_APPROVAL_RESULT = exports.SNAP_APPROVAL_UPDATE = exports.SNAP_APPROVAL_INSTALL = exports.controllerName = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
@@ -71,7 +71,7 @@ const name = 'SnapController';
71
71
  * - Start: Initializes the snap in its SES realm with the authorized permissions.
72
72
  */
73
73
  class SnapController extends base_controller_1.BaseControllerV2 {
74
- constructor({ closeAllConnections, messenger, state, environmentEndowmentPermissions = [], excludedPermissions = {}, idleTimeCheckInterval = (0, utils_1.inMilliseconds)(5, utils_1.Duration.Second), registry = new registry_1.JsonSnapsRegistry(), 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, }) {
74
+ constructor({ closeAllConnections, messenger, state, environmentEndowmentPermissions = [], excludedPermissions = {}, idleTimeCheckInterval = (0, utils_1.inMilliseconds)(5, utils_1.Duration.Second), 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, }) {
75
75
  super({
76
76
  messenger,
77
77
  metadata: {
@@ -128,7 +128,6 @@ class SnapController extends base_controller_1.BaseControllerV2 {
128
128
  _SnapController_featureFlags.set(this, void 0);
129
129
  _SnapController_fetchFunction.set(this, void 0);
130
130
  _SnapController_idleTimeCheckInterval.set(this, void 0);
131
- _SnapController_registry.set(this, void 0);
132
131
  _SnapController_maxIdleTime.set(this, void 0);
133
132
  _SnapController_detectSnapLocation.set(this, void 0);
134
133
  _SnapController_rollbackSnapshots.set(this, void 0);
@@ -140,7 +139,6 @@ class SnapController extends base_controller_1.BaseControllerV2 {
140
139
  __classPrivateFieldSet(this, _SnapController_featureFlags, featureFlags, "f");
141
140
  __classPrivateFieldSet(this, _SnapController_fetchFunction, fetchFunction, "f");
142
141
  __classPrivateFieldSet(this, _SnapController_idleTimeCheckInterval, idleTimeCheckInterval, "f");
143
- __classPrivateFieldSet(this, _SnapController_registry, registry, "f");
144
142
  __classPrivateFieldSet(this, _SnapController_maxIdleTime, maxIdleTime, "f");
145
143
  this.maxRequestTime = maxRequestTime;
146
144
  __classPrivateFieldSet(this, _SnapController_detectSnapLocation, detectSnapLocationFunction, "f");
@@ -168,7 +166,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
168
166
  * for more information.
169
167
  */
170
168
  async updateBlockedSnaps() {
171
- const blockedSnaps = await __classPrivateFieldGet(this, _SnapController_registry, "f").get(Object.values(this.state.snaps).reduce((blockListArg, snap) => {
169
+ const blockedSnaps = await this.messagingSystem.call('SnapsRegistry:get', Object.values(this.state.snaps).reduce((blockListArg, snap) => {
172
170
  blockListArg[snap.id] = {
173
171
  version: snap.version,
174
172
  checksum: snap.manifest.source.shasum,
@@ -548,10 +546,6 @@ class SnapController extends base_controller_1.BaseControllerV2 {
548
546
  if (error) {
549
547
  throw eth_rpc_errors_1.ethErrors.rpc.invalidParams(`The "version" field must be a valid SemVer version range if specified. Received: "${rawVersion}".`);
550
548
  }
551
- const permissions = this.messagingSystem.call('PermissionController:getPermissions', origin);
552
- if (!(0, snaps_utils_1.isSnapPermitted)(permissions, snapId)) {
553
- throw eth_rpc_errors_1.ethErrors.provider.unauthorized(`Not authorized to install snap "${snapId}". Request the permission for the snap before attempting to install it.`);
554
- }
555
549
  const location = __classPrivateFieldGet(this, _SnapController_detectSnapLocation, "f").call(this, snapId, {
556
550
  versionRange: version,
557
551
  fetch: __classPrivateFieldGet(this, _SnapController_fetchFunction, "f"),
@@ -630,6 +624,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
630
624
  origin,
631
625
  id: snapId,
632
626
  location,
627
+ versionRange,
633
628
  });
634
629
  await this.authorize(snapId, pendingApproval);
635
630
  pendingApproval = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_createApproval).call(this, {
@@ -642,7 +637,10 @@ class SnapController extends base_controller_1.BaseControllerV2 {
642
637
  sourceCode,
643
638
  });
644
639
  const truncated = this.getTruncatedExpect(snapId);
645
- __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_updateApproval).call(this, pendingApproval.id, { loading: false });
640
+ __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_updateApproval).call(this, pendingApproval.id, {
641
+ loading: false,
642
+ type: exports.SNAP_APPROVAL_INSTALL,
643
+ });
646
644
  this.messagingSystem.publish(`SnapController:snapInstalled`, truncated);
647
645
  return truncated;
648
646
  }
@@ -650,6 +648,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
650
648
  (0, snaps_utils_1.logError)(`Error when adding snap.`, error);
651
649
  __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_updateApproval).call(this, pendingApproval.id, {
652
650
  loading: false,
651
+ type: exports.SNAP_APPROVAL_INSTALL,
653
652
  error: error instanceof Error ? error.message : error.toString(),
654
653
  });
655
654
  throw error;
@@ -689,6 +688,9 @@ class SnapController extends base_controller_1.BaseControllerV2 {
689
688
  if (!(0, utils_1.gtVersion)(newVersion, snap.version)) {
690
689
  throw eth_rpc_errors_1.ethErrors.rpc.invalidParams(`Snap "${snapId}@${snap.version}" is already installed. Couldn't update to a version inside requested "${newVersionRange}" range.`);
691
690
  }
691
+ if (!(0, utils_1.satisfiesVersionRange)(newVersion, newVersionRange)) {
692
+ throw new Error(`Version mismatch. Manifest for "${snapId}" specifies version "${newVersion}" which doesn't satisfy requested version range "${newVersionRange}".`);
693
+ }
692
694
  await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_assertIsInstallAllowed).call(this, snapId, {
693
695
  version: newVersion,
694
696
  checksum: newSnap.manifest.result.source.shasum,
@@ -719,7 +721,6 @@ class SnapController extends base_controller_1.BaseControllerV2 {
719
721
  id: snapId,
720
722
  manifest: newSnap.manifest,
721
723
  files: newSnap.files,
722
- versionRange: newVersionRange,
723
724
  isUpdate: true,
724
725
  });
725
726
  const unusedPermissionsKeys = Object.keys(unusedPermissions);
@@ -754,7 +755,10 @@ class SnapController extends base_controller_1.BaseControllerV2 {
754
755
  }
755
756
  const truncatedSnap = this.getTruncatedExpect(snapId);
756
757
  this.messagingSystem.publish('SnapController:snapUpdated', truncatedSnap, snap.version);
757
- __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_updateApproval).call(this, pendingApproval.id, { loading: false });
758
+ __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_updateApproval).call(this, pendingApproval.id, {
759
+ loading: false,
760
+ type: exports.SNAP_APPROVAL_UPDATE,
761
+ });
758
762
  return truncatedSnap;
759
763
  }
760
764
  catch (error) {
@@ -762,6 +766,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
762
766
  __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_updateApproval).call(this, pendingApproval.id, {
763
767
  loading: false,
764
768
  error: error instanceof Error ? error.message : error.toString(),
769
+ type: exports.SNAP_APPROVAL_UPDATE,
765
770
  });
766
771
  throw error;
767
772
  }
@@ -774,7 +779,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
774
779
  * verified.
775
780
  */
776
781
  async getRegistryMetadata(snapId) {
777
- return await __classPrivateFieldGet(this, _SnapController_registry, "f").getMetadata(snapId);
782
+ return await this.messagingSystem.call('SnapsRegistry:getMetadata', snapId);
778
783
  }
779
784
  /**
780
785
  * Initiates a request for the given snap's initial permissions.
@@ -859,7 +864,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
859
864
  }
860
865
  }
861
866
  exports.SnapController = SnapController;
862
- _SnapController_closeAllConnections = new WeakMap(), _SnapController_environmentEndowmentPermissions = new WeakMap(), _SnapController_excludedPermissions = new WeakMap(), _SnapController_featureFlags = new WeakMap(), _SnapController_fetchFunction = new WeakMap(), _SnapController_idleTimeCheckInterval = new WeakMap(), _SnapController_registry = new WeakMap(), _SnapController_maxIdleTime = new WeakMap(), _SnapController_detectSnapLocation = new WeakMap(), _SnapController_rollbackSnapshots = new WeakMap(), _SnapController_timeoutForLastRequestStatus = new WeakMap(), _SnapController_statusMachine = new WeakMap(), _SnapController_instances = new WeakSet(), _SnapController_initializeStateMachine = function _SnapController_initializeStateMachine() {
867
+ _SnapController_closeAllConnections = new WeakMap(), _SnapController_environmentEndowmentPermissions = new WeakMap(), _SnapController_excludedPermissions = new WeakMap(), _SnapController_featureFlags = new WeakMap(), _SnapController_fetchFunction = new WeakMap(), _SnapController_idleTimeCheckInterval = new WeakMap(), _SnapController_maxIdleTime = new WeakMap(), _SnapController_detectSnapLocation = new WeakMap(), _SnapController_rollbackSnapshots = new WeakMap(), _SnapController_timeoutForLastRequestStatus = new WeakMap(), _SnapController_statusMachine = new WeakMap(), _SnapController_instances = new WeakSet(), _SnapController_initializeStateMachine = function _SnapController_initializeStateMachine() {
863
868
  const disableGuard = ({ snapId }) => {
864
869
  return this.getExpect(snapId).enabled;
865
870
  };
@@ -880,6 +885,7 @@ _SnapController_closeAllConnections = new WeakMap(), _SnapController_environment
880
885
  target: snaps_utils_1.SnapStatus.Running,
881
886
  cond: disableGuard,
882
887
  },
888
+ [snaps_utils_1.SnapStatusEvents.Stop]: snaps_utils_1.SnapStatus.Stopped,
883
889
  },
884
890
  },
885
891
  [snaps_utils_1.SnapStatus.Running]: {
@@ -969,7 +975,7 @@ async function _SnapController_blockSnap(snapId, blockedSnapInfo) {
969
975
  });
970
976
  this.messagingSystem.publish(`${exports.controllerName}:snapUnblocked`, snapId);
971
977
  }, _SnapController_assertIsInstallAllowed = async function _SnapController_assertIsInstallAllowed(snapId, snapInfo) {
972
- const results = await __classPrivateFieldGet(this, _SnapController_registry, "f").get({
978
+ const results = await this.messagingSystem.call('SnapsRegistry:get', {
973
979
  [snapId]: snapInfo,
974
980
  });
975
981
  const result = results[snapId];
@@ -1064,7 +1070,7 @@ async function _SnapController_terminateSnap(snapId) {
1064
1070
  * @returns The resulting snap object.
1065
1071
  */
1066
1072
  async function _SnapController_add(args) {
1067
- const { id: snapId, location } = args;
1073
+ const { id: snapId, location, versionRange } = args;
1068
1074
  __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_setupRuntime).call(this, snapId, { sourceCode: null, state: null });
1069
1075
  const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
1070
1076
  if (!runtime.installPromise) {
@@ -1073,9 +1079,14 @@ async function _SnapController_add(args) {
1073
1079
  // to null in the authorize() method.
1074
1080
  runtime.installPromise = (async () => {
1075
1081
  const fetchedSnap = await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_fetchSnap).call(this, snapId, location);
1082
+ const manifest = fetchedSnap.manifest.result;
1083
+ (0, snaps_utils_1.assertIsSnapManifest)(manifest);
1084
+ if (!(0, utils_1.satisfiesVersionRange)(manifest.version, versionRange)) {
1085
+ throw new Error(`Version mismatch. Manifest for "${snapId}" specifies version "${manifest.version}" which doesn't satisfy requested version range "${versionRange}".`);
1086
+ }
1076
1087
  await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_assertIsInstallAllowed).call(this, snapId, {
1077
- version: fetchedSnap.manifest.result.version,
1078
- checksum: fetchedSnap.manifest.result.source.shasum,
1088
+ version: manifest.version,
1089
+ checksum: manifest.source.shasum,
1079
1090
  });
1080
1091
  return __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_set).call(this, {
1081
1092
  ...args,
@@ -1149,12 +1160,9 @@ async function _SnapController_getEndowments(snapId) {
1149
1160
  }
1150
1161
  return dedupedEndowments;
1151
1162
  }, _SnapController_set = function _SnapController_set(args) {
1152
- const { id: snapId, origin, manifest, files, versionRange = snaps_utils_1.DEFAULT_REQUESTED_SNAP_VERSION, isUpdate = false, } = args;
1163
+ const { id: snapId, origin, manifest, files, isUpdate = false } = args;
1153
1164
  (0, snaps_utils_1.assertIsSnapManifest)(manifest.result);
1154
1165
  const { version } = manifest.result;
1155
- if (!(0, utils_1.satisfiesVersionRange)(version, versionRange)) {
1156
- throw new Error(`Version mismatch. Manifest for "${snapId}" specifies version "${version}" which doesn't satisfy requested version range "${versionRange}"`);
1157
- }
1158
1166
  const normalizedSourcePath = (0, snaps_utils_1.normalizeRelative)(manifest.result.source.location.npm.filePath);
1159
1167
  const { iconPath } = manifest.result.source.location.npm;
1160
1168
  const normalizedIconPath = iconPath && (0, snaps_utils_1.normalizeRelative)(iconPath);
@@ -1255,7 +1263,10 @@ async function _SnapController_fetchSnap(snapId, location) {
1255
1263
  ];
1256
1264
  }));
1257
1265
  }, _SnapController_validateSnapPermissions = function _SnapController_validateSnapPermissions(processedPermissions) {
1258
- const excludedPermissionErrors = Object.keys(processedPermissions).reduce((errors, permission) => {
1266
+ const permissionKeys = Object.keys(processedPermissions);
1267
+ const handlerPermissions = Object.values(endowments_1.handlerEndowments);
1268
+ (0, utils_1.assert)(permissionKeys.some((key) => handlerPermissions.includes(key)), `A snap must request at least one of the following permissions: ${handlerPermissions.join(', ')}.`);
1269
+ const excludedPermissionErrors = permissionKeys.reduce((errors, permission) => {
1259
1270
  if ((0, utils_1.hasProperty)(__classPrivateFieldGet(this, _SnapController_excludedPermissions, "f"), permission)) {
1260
1271
  errors.push(__classPrivateFieldGet(this, _SnapController_excludedPermissions, "f")[permission]);
1261
1272
  }
@@ -1390,10 +1401,21 @@ async function _SnapController_rollbackSnap(snapId) {
1390
1401
  throw new Error('A snapshot does not exist for this snap.');
1391
1402
  }
1392
1403
  await this.stopSnap(snapId, snaps_utils_1.SnapStatusEvents.Stop);
1404
+ // Always set to stopped even if it wasn't running initially
1405
+ if (this.get(snapId)?.status !== snaps_utils_1.SnapStatus.Stopped) {
1406
+ __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_transition).call(this, snapId, snaps_utils_1.SnapStatusEvents.Stop);
1407
+ }
1393
1408
  const { statePatches, sourceCode, permissions } = rollbackSnapshot;
1394
1409
  if (statePatches?.length) {
1395
1410
  this.applyPatches(statePatches);
1396
1411
  }
1412
+ // Reset snap status, as we may have been in another state when we stored state patches
1413
+ // But now we are 100% in a stopped state
1414
+ if (this.get(snapId)?.status !== snaps_utils_1.SnapStatus.Stopped) {
1415
+ this.update((state) => {
1416
+ state.snaps[snapId].status = snaps_utils_1.SnapStatus.Stopped;
1417
+ });
1418
+ }
1397
1419
  if (sourceCode) {
1398
1420
  const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
1399
1421
  runtime.sourceCode = sourceCode;