@metamask/snaps-controllers 1.0.0-prerelease.1 → 1.0.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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.0.0]
10
+ ### Changed
11
+ - Make `updateBlockedSnaps` update the registry ([#1625](https://github.com/MetaMask/snaps/pull/1625))
12
+ - Move source code and snap state back to controller state ([#1634](https://github.com/MetaMask/snaps/pull/1634))
13
+
9
14
  ## [1.0.0-prerelease.1]
10
15
  ### Added
11
16
  - Add export for `getRpcCaveatOrigins` ([#1533](https://github.com/MetaMask/snaps/pull/1533))
@@ -510,7 +515,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
510
515
  ### Added
511
516
  - First semi-stable release.
512
517
 
513
- [Unreleased]: https://github.com/MetaMask/snaps/compare/v1.0.0-prerelease.1...HEAD
518
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/v1.0.0...HEAD
519
+ [1.0.0]: https://github.com/MetaMask/snaps/compare/v1.0.0-prerelease.1...v1.0.0
514
520
  [1.0.0-prerelease.1]: https://github.com/MetaMask/snaps/compare/v0.32.2...v1.0.0-prerelease.1
515
521
  [0.32.2]: https://github.com/MetaMask/snaps/compare/v0.32.1...v0.32.2
516
522
  [0.32.1]: https://github.com/MetaMask/snaps/compare/v0.32.0...v0.32.1
@@ -8,7 +8,7 @@ import { StateMachine } from '@xstate/fsm';
8
8
  import type { Patch } from 'immer';
9
9
  import { ExecuteSnapAction, ExecutionServiceEvents, HandleRpcRequestAction, SnapErrorJson, TerminateAllSnapsAction, TerminateSnapAction } from '../services';
10
10
  import { detectSnapLocation, SnapLocation } from './location';
11
- import { GetMetadata, GetResult, SnapsRegistryMetadata } from './registry';
11
+ import { GetMetadata, GetResult, SnapsRegistryMetadata, Update } from './registry';
12
12
  import { Timer } from './Timer';
13
13
  export declare const controllerName = "SnapController";
14
14
  export declare const SNAP_APPROVAL_INSTALL = "wallet_installSnap";
@@ -56,14 +56,6 @@ export interface SnapRuntimeData {
56
56
  * @see {@link SnapController:constructor}
57
57
  */
58
58
  interpreter: StateMachine.Service<StatusContext, StatusEvents, StatusStates>;
59
- /**
60
- * The snap source code
61
- */
62
- sourceCode: null | string;
63
- /**
64
- * The snap state (encrypted)
65
- */
66
- state: null | string;
67
59
  }
68
60
  export declare type SnapError = {
69
61
  message: string;
@@ -74,7 +66,7 @@ declare type CloseAllConnectionsFunction = (origin: string) => void;
74
66
  declare type StoredSnaps = Record<SnapId, Snap>;
75
67
  export declare type SnapControllerState = {
76
68
  snaps: StoredSnaps;
77
- snapStates: {};
69
+ snapStates: Record<SnapId, string | null>;
78
70
  snapErrors: {
79
71
  [internalID: string]: SnapError & {
80
72
  internalID: string;
@@ -238,7 +230,7 @@ export declare type SnapTerminated = {
238
230
  payload: [snap: TruncatedSnap];
239
231
  };
240
232
  export declare type SnapControllerEvents = SnapAdded | SnapBlocked | SnapInstalled | SnapRemoved | SnapStateChange | SnapUnblocked | SnapUpdated | SnapRolledback | SnapTerminated;
241
- export declare type AllowedActions = GetEndowments | GetPermissions | GetSubjects | GetSubjectMetadata | HasPermission | HasPermissions | RevokePermissions | RevokeAllPermissions | RevokePermissionForAllSubjects | GrantPermissions | AddApprovalRequest | HandleRpcRequestAction | ExecuteSnapAction | TerminateAllSnapsAction | TerminateSnapAction | UpdateCaveat | UpdateRequestState | GetResult | GetMetadata;
233
+ export declare type AllowedActions = GetEndowments | GetPermissions | GetSubjects | GetSubjectMetadata | HasPermission | HasPermissions | RevokePermissions | RevokeAllPermissions | RevokePermissionForAllSubjects | GrantPermissions | AddApprovalRequest | HandleRpcRequestAction | ExecuteSnapAction | TerminateAllSnapsAction | TerminateSnapAction | UpdateCaveat | UpdateRequestState | GetResult | GetMetadata | Update;
242
234
  export declare type AllowedEvents = ExecutionServiceEvents;
243
235
  declare type SnapControllerMessenger = RestrictedControllerMessenger<typeof controllerName, SnapControllerActions | AllowedActions, SnapControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
244
236
  declare type FeatureFlags = {
@@ -313,7 +305,6 @@ declare type SnapControllerArgs = {
313
305
  export declare class SnapController extends BaseController<string, SnapControllerState, SnapControllerMessenger> {
314
306
  #private;
315
307
  private readonly maxRequestTime;
316
- private readonly snapsRuntimeData;
317
308
  constructor({ closeAllConnections, messenger, state, environmentEndowmentPermissions, excludedPermissions, idleTimeCheckInterval, maxIdleTime, maxRequestTime, fetchFunction, featureFlags, detectSnapLocation: detectSnapLocationFunction, }: SnapControllerArgs);
318
309
  /**
319
310
  * Checks all installed snaps against the block list and
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
- };
7
2
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
3
  if (kind === "m") throw new TypeError("Private method is not writable");
9
4
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
5
  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
6
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
7
  };
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;
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _SnapController_instances, _SnapController_closeAllConnections, _SnapController_environmentEndowmentPermissions, _SnapController_excludedPermissions, _SnapController_featureFlags, _SnapController_fetchFunction, _SnapController_idleTimeCheckInterval, _SnapController_maxIdleTime, _SnapController_detectSnapLocation, _SnapController_snapsRuntimeData, _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");
@@ -80,12 +80,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
80
80
  anonymous: false,
81
81
  },
82
82
  snapStates: {
83
- persist: () => {
84
- return Object.keys(this.state.snaps).reduce((acc, cur) => {
85
- acc[cur] = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, cur).state;
86
- return acc;
87
- }, {});
88
- },
83
+ persist: true,
89
84
  anonymous: false,
90
85
  },
91
86
  snaps: {
@@ -94,7 +89,6 @@ class SnapController extends base_controller_1.BaseControllerV2 {
94
89
  .map((snap) => {
95
90
  return {
96
91
  ...snap,
97
- sourceCode: __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snap.id).sourceCode,
98
92
  // At the time state is rehydrated, no snap will be running.
99
93
  status: snaps_utils_1.SnapStatus.Stopped,
100
94
  };
@@ -110,15 +104,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
110
104
  name,
111
105
  state: {
112
106
  ...defaultState,
113
- ...{
114
- ...state,
115
- snaps: Object.values(state?.snaps ?? {}).reduce((memo, snap) => {
116
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
117
- const { sourceCode, ...rest } = snap;
118
- memo[snap.id] = rest;
119
- return memo;
120
- }, {}),
121
- },
107
+ ...state,
122
108
  },
123
109
  });
124
110
  _SnapController_instances.add(this);
@@ -130,6 +116,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
130
116
  _SnapController_idleTimeCheckInterval.set(this, void 0);
131
117
  _SnapController_maxIdleTime.set(this, void 0);
132
118
  _SnapController_detectSnapLocation.set(this, void 0);
119
+ _SnapController_snapsRuntimeData.set(this, void 0);
133
120
  _SnapController_rollbackSnapshots.set(this, void 0);
134
121
  _SnapController_timeoutForLastRequestStatus.set(this, void 0);
135
122
  _SnapController_statusMachine.set(this, void 0);
@@ -146,7 +133,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
146
133
  this._onOutboundRequest = this._onOutboundRequest.bind(this);
147
134
  this._onOutboundResponse = this._onOutboundResponse.bind(this);
148
135
  __classPrivateFieldSet(this, _SnapController_rollbackSnapshots, new Map(), "f");
149
- this.snapsRuntimeData = new Map();
136
+ __classPrivateFieldSet(this, _SnapController_snapsRuntimeData, new Map(), "f");
150
137
  __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_pollForLastRequestStatus).call(this);
151
138
  /* eslint-disable @typescript-eslint/unbound-method */
152
139
  this.messagingSystem.subscribe('ExecutionService:unhandledError', this._onUnhandledSnapError);
@@ -166,6 +153,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
166
153
  * for more information.
167
154
  */
168
155
  async updateBlockedSnaps() {
156
+ await this.messagingSystem.call('SnapsRegistry:update');
169
157
  const blockedSnaps = await this.messagingSystem.call('SnapsRegistry:get', Object.values(this.state.snaps).reduce((blockListArg, snap) => {
170
158
  blockListArg[snap.id] = {
171
159
  version: snap.version,
@@ -213,14 +201,13 @@ class SnapController extends base_controller_1.BaseControllerV2 {
213
201
  * @param snapId - The id of the Snap to start.
214
202
  */
215
203
  async startSnap(snapId) {
216
- const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
217
- if (this.state.snaps[snapId].enabled === false) {
204
+ const snap = this.state.snaps[snapId];
205
+ if (snap.enabled === false) {
218
206
  throw new Error(`Snap "${snapId}" is disabled.`);
219
207
  }
220
- (0, utils_1.assert)(runtime.sourceCode);
221
208
  await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_startSnap).call(this, {
222
209
  snapId,
223
- sourceCode: runtime.sourceCode,
210
+ sourceCode: snap.sourceCode,
224
211
  });
225
212
  }
226
213
  /**
@@ -360,8 +347,9 @@ class SnapController extends base_controller_1.BaseControllerV2 {
360
347
  * @param newSnapState - The new state of the snap.
361
348
  */
362
349
  async updateSnapState(snapId, newSnapState) {
363
- const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
364
- runtime.state = newSnapState;
350
+ this.update((state) => {
351
+ state.snapStates[snapId] = newSnapState;
352
+ });
365
353
  }
366
354
  /**
367
355
  * Clears the state of the snap with the given id.
@@ -370,8 +358,9 @@ class SnapController extends base_controller_1.BaseControllerV2 {
370
358
  * @param snapId - The id of the Snap whose state should be cleared.
371
359
  */
372
360
  clearSnapState(snapId) {
373
- const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
374
- runtime.state = null;
361
+ this.update((state) => {
362
+ state.snapStates[snapId] = null;
363
+ });
375
364
  }
376
365
  /**
377
366
  * Adds error from a snap to the SnapController state.
@@ -414,7 +403,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
414
403
  * @throws If the snap state decryption fails.
415
404
  */
416
405
  async getSnapState(snapId) {
417
- const { state } = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
406
+ const state = this.state.snapStates[snapId];
418
407
  return state ?? null;
419
408
  }
420
409
  /**
@@ -461,7 +450,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
461
450
  await this.disableSnap(snapId);
462
451
  this.revokeAllSnapPermissions(snapId);
463
452
  __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_removeSnapFromSubjects).call(this, snapId);
464
- this.snapsRuntimeData.delete(snapId);
453
+ __classPrivateFieldGet(this, _SnapController_snapsRuntimeData, "f").delete(snapId);
465
454
  this.update((state) => {
466
455
  delete state.snaps[snapId];
467
456
  delete state.snapStates[snapId];
@@ -558,9 +547,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
558
547
  pendingUpdates.push(snapId);
559
548
  let rollbackSnapshot = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRollbackSnapshot).call(this, snapId);
560
549
  if (rollbackSnapshot === undefined) {
561
- const prevSourceCode = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId).sourceCode;
562
550
  rollbackSnapshot = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_createRollbackSnapshot).call(this, snapId);
563
- rollbackSnapshot.sourceCode = prevSourceCode;
564
551
  rollbackSnapshot.newVersion = version;
565
552
  }
566
553
  else {
@@ -864,7 +851,7 @@ class SnapController extends base_controller_1.BaseControllerV2 {
864
851
  }
865
852
  }
866
853
  exports.SnapController = SnapController;
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() {
854
+ _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_snapsRuntimeData = new WeakMap(), _SnapController_rollbackSnapshots = new WeakMap(), _SnapController_timeoutForLastRequestStatus = new WeakMap(), _SnapController_statusMachine = new WeakMap(), _SnapController_instances = new WeakSet(), _SnapController_initializeStateMachine = function _SnapController_initializeStateMachine() {
868
855
  const disableGuard = ({ snapId }) => {
869
856
  return this.getExpect(snapId).enabled;
870
857
  };
@@ -987,7 +974,7 @@ async function _SnapController_blockSnap(snapId, blockedSnapInfo) {
987
974
  throw new Error(`Cannot install version "${snapInfo.version}" of snap "${snapId}": The snap is not on the allow list.`);
988
975
  }
989
976
  }, _SnapController_stopSnapsLastRequestPastMax = async function _SnapController_stopSnapsLastRequestPastMax() {
990
- const entries = [...this.snapsRuntimeData.entries()];
977
+ const entries = [...__classPrivateFieldGet(this, _SnapController_snapsRuntimeData, "f").entries()];
991
978
  return Promise.all(entries
992
979
  .filter(([_snapId, runtime]) => runtime.activeReferences === 0 &&
993
980
  runtime.pendingInboundRequests.length === 0 &&
@@ -1195,6 +1182,7 @@ async function _SnapController_getEndowments(snapId) {
1195
1182
  initialPermissions: manifest.result.initialPermissions,
1196
1183
  manifest: manifest.result,
1197
1184
  status: __classPrivateFieldGet(this, _SnapController_statusMachine, "f").config.initial,
1185
+ sourceCode,
1198
1186
  version,
1199
1187
  versionHistory,
1200
1188
  };
@@ -1212,8 +1200,6 @@ async function _SnapController_getEndowments(snapId) {
1212
1200
  rollbackSnapshot.statePatches = inversePatches;
1213
1201
  }
1214
1202
  }
1215
- const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
1216
- runtime.sourceCode = sourceCode;
1217
1203
  this.messagingSystem.publish(`SnapController:snapAdded`, snap, svgIcon?.toString());
1218
1204
  return { ...snap, sourceCode };
1219
1205
  }, _SnapController_fetchSnap =
@@ -1376,7 +1362,6 @@ async function _SnapController_executeWithTimeout(snapId, promise, timer) {
1376
1362
  (0, utils_1.assert)(__classPrivateFieldGet(this, _SnapController_rollbackSnapshots, "f").get(snapId) === undefined, new Error(`Snap "${snapId}" rollback snapshot already exists.`));
1377
1363
  __classPrivateFieldGet(this, _SnapController_rollbackSnapshots, "f").set(snapId, {
1378
1364
  statePatches: [],
1379
- sourceCode: '',
1380
1365
  permissions: { revoked: null, granted: [], requestData: null },
1381
1366
  newVersion: '',
1382
1367
  });
@@ -1405,7 +1390,7 @@ async function _SnapController_rollbackSnap(snapId) {
1405
1390
  if (this.get(snapId)?.status !== snaps_utils_1.SnapStatus.Stopped) {
1406
1391
  __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_transition).call(this, snapId, snaps_utils_1.SnapStatusEvents.Stop);
1407
1392
  }
1408
- const { statePatches, sourceCode, permissions } = rollbackSnapshot;
1393
+ const { statePatches, permissions } = rollbackSnapshot;
1409
1394
  if (statePatches?.length) {
1410
1395
  this.applyPatches(statePatches);
1411
1396
  }
@@ -1416,10 +1401,6 @@ async function _SnapController_rollbackSnap(snapId) {
1416
1401
  state.snaps[snapId].status = snaps_utils_1.SnapStatus.Stopped;
1417
1402
  });
1418
1403
  }
1419
- if (sourceCode) {
1420
- const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
1421
- runtime.sourceCode = sourceCode;
1422
- }
1423
1404
  if (permissions.revoked && Object.keys(permissions.revoked).length) {
1424
1405
  this.messagingSystem.call('PermissionController:grantPermissions', {
1425
1406
  approvedPermissions: permissions.revoked,
@@ -1447,13 +1428,13 @@ async function _SnapController_rollbackSnaps(snapIds) {
1447
1428
  await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_rollbackSnap).call(this, snapId);
1448
1429
  }
1449
1430
  }, _SnapController_getRuntime = function _SnapController_getRuntime(snapId) {
1450
- return this.snapsRuntimeData.get(snapId);
1431
+ return __classPrivateFieldGet(this, _SnapController_snapsRuntimeData, "f").get(snapId);
1451
1432
  }, _SnapController_getRuntimeExpect = function _SnapController_getRuntimeExpect(snapId) {
1452
1433
  const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntime).call(this, snapId);
1453
1434
  (0, utils_1.assert)(runtime !== undefined, new Error(`Snap "${snapId}" runtime data not found`));
1454
1435
  return runtime;
1455
1436
  }, _SnapController_setupRuntime = function _SnapController_setupRuntime(snapId, data) {
1456
- if (this.snapsRuntimeData.has(snapId)) {
1437
+ if (__classPrivateFieldGet(this, _SnapController_snapsRuntimeData, "f").has(snapId)) {
1457
1438
  return;
1458
1439
  }
1459
1440
  const snap = this.get(snapId);
@@ -1464,7 +1445,7 @@ async function _SnapController_rollbackSnaps(snapIds) {
1464
1445
  __classPrivateFieldGet(this, _SnapController_statusMachine, "f").config.initial,
1465
1446
  });
1466
1447
  (0, fsm_2.forceStrict)(interpreter);
1467
- this.snapsRuntimeData.set(snapId, {
1448
+ __classPrivateFieldGet(this, _SnapController_snapsRuntimeData, "f").set(snapId, {
1468
1449
  lastRequest: null,
1469
1450
  rpcHandler: null,
1470
1451
  installPromise: null,
@@ -1 +1 @@
1
- {"version":3,"file":"SnapController.js","sourceRoot":"","sources":["../../src/snaps/SnapController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AddApprovalRequest,\n UpdateRequestState,\n} from '@metamask/approval-controller';\nimport {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n Caveat,\n GetEndowments,\n GetPermissions,\n GetSubjects,\n GrantPermissions,\n HasPermission,\n HasPermissions,\n PermissionConstraint,\n PermissionsRequest,\n RequestedPermissions,\n RevokeAllPermissions,\n RevokePermissionForAllSubjects,\n RevokePermissions,\n SubjectPermissions,\n ValidPermission,\n UpdateCaveat,\n GetSubjectMetadata,\n SubjectType,\n} from '@metamask/permission-controller';\nimport {\n caveatMappers,\n WALLET_SNAP_PERMISSION_KEY,\n} from '@metamask/rpc-methods';\nimport { BlockReason } from '@metamask/snaps-registry';\nimport {\n assertIsSnapManifest,\n DEFAULT_ENDOWMENTS,\n DEFAULT_REQUESTED_SNAP_VERSION,\n InstallSnapsResult,\n normalizeRelative,\n PersistedSnap,\n ProcessSnapResult,\n RequestedSnapPermissions,\n resolveVersionRange,\n Snap,\n SnapCaveatType,\n SnapId,\n SnapManifest,\n SnapPermissions,\n SnapRpcHook,\n SnapRpcHookArgs,\n SnapStatus,\n SnapStatusEvents,\n StatusContext,\n StatusEvents,\n StatusStates,\n TruncatedSnap,\n TruncatedSnapFields,\n ValidatedSnapId,\n assertIsValidSnapId,\n validateSnapShasum,\n VirtualFile,\n logError,\n logWarning,\n} from '@metamask/snaps-utils';\nimport {\n assert,\n Duration,\n gtRange,\n gtVersion,\n hasProperty,\n inMilliseconds,\n isNonEmptyArray,\n isValidSemVerRange,\n Json,\n NonEmptyArray,\n satisfiesVersionRange,\n SemVerRange,\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 { log } from '../logging';\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 {\n GetMetadata,\n GetResult,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryStatus,\n} from './registry';\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';\nexport const SNAP_APPROVAL_RESULT = 'wallet_installSnapResult';\n\nconst TRUNCATED_SNAP_PROPERTIES = new Set<TruncatedSnapFields>([\n 'initialPermissions',\n 'id',\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\ntype PendingApproval = {\n id: string;\n promise: Promise<unknown>;\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 GetRegistryMetadata = {\n type: `${typeof controllerName}:getRegistryMetadata`;\n handler: SnapController['getRegistryMetadata'];\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 | GetRegistryMetadata;\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?: BlockReason];\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 | GetSubjects\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 | UpdateCaveat\n | UpdateRequestState\n | GetResult\n | GetMetadata;\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\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 requireAllowlist?: true;\n allowLocalSnaps?: true;\n};\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 * Excluded permissions with its associated error message used to forbid certain permssions.\n */\n excludedPermissions: Record<string, 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 * How frequently to check whether a snap is idle.\n */\n idleTimeCheckInterval?: number;\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: ValidatedSnapId;\n origin: string;\n location: SnapLocation;\n versionRange: SemVerRange;\n};\n\n// When we set a snap, we need all required properties to be present and\n// validated.\ntype SetSnapArgs = Omit<AddSnapArgs, 'location' | 'versionRange'> & {\n manifest: VirtualFile<SnapManifest>;\n files: VirtualFile[];\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 #excludedPermissions: Record<string, string>;\n\n #featureFlags: FeatureFlags;\n\n #fetchFunction: typeof fetch;\n\n #idleTimeCheckInterval: number;\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 #timeoutForLastRequestStatus?: number;\n\n #statusMachine!: StateMachine.Machine<\n StatusContext,\n StatusEvents,\n StatusStates\n >;\n\n constructor({\n closeAllConnections,\n messenger,\n state,\n environmentEndowmentPermissions = [],\n excludedPermissions = {},\n idleTimeCheckInterval = inMilliseconds(5, Duration.Second),\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.#excludedPermissions = excludedPermissions;\n this.#featureFlags = featureFlags;\n this.#fetchFunction = fetchFunction;\n this.#idleTimeCheckInterval = idleTimeCheckInterval;\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 [SnapStatusEvents.Stop]: SnapStatus.Stopped,\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 [SnapStatusEvents.Update]: SnapStatus.Updating,\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 this.messagingSystem.registerActionHandler(\n `${controllerName}:getRegistryMetadata`,\n async (...args) => this.getRegistryMetadata(...args),\n );\n }\n\n #pollForLastRequestStatus() {\n this.#timeoutForLastRequestStatus = setTimeout(() => {\n this.#stopSnapsLastRequestPastMax().catch((error) => {\n // TODO: Decide how to handle errors.\n logError(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.messagingSystem.call(\n 'SnapsRegistry:get',\n Object.values(this.state.snaps).reduce<SnapsRegistryRequest>(\n (blockListArg, snap) => {\n blockListArg[snap.id] = {\n version: snap.version,\n checksum: snap.manifest.source.shasum,\n };\n return blockListArg;\n },\n {},\n ),\n );\n\n await Promise.all(\n Object.entries(blockedSnaps).map(async ([snapId, { status, reason }]) => {\n if (status === SnapsRegistryStatus.Blocked) {\n return this.#blockSnap(snapId, reason);\n }\n\n return this.#unblockSnap(snapId);\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?: BlockReason,\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 logError(\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 async #assertIsInstallAllowed(\n snapId: ValidatedSnapId,\n snapInfo: SnapsRegistryInfo,\n ) {\n const results = await this.messagingSystem.call('SnapsRegistry:get', {\n [snapId]: snapInfo,\n });\n const result = results[snapId];\n if (result.status === SnapsRegistryStatus.Blocked) {\n throw new Error(\n `Cannot install version \"${\n snapInfo.version\n }\" of snap \"${snapId}\": The version is blocked. ${\n result.reason?.explanation ?? ''\n }`,\n );\n } else if (\n this.#featureFlags.requireAllowlist &&\n result.status !== SnapsRegistryStatus.Verified\n ) {\n throw new Error(\n `Cannot install version \"${snapInfo.version}\" of snap \"${snapId}\": The snap is not on the allow list.`,\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 logError(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: string): Promise<void> {\n const runtime = this.#getRuntimeExpect(snapId);\n runtime.state = newSnapState;\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 ?? null;\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 this.#removeSnapFromSubjects(snapId);\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 * Removes a snap's permission (caveat) from all subjects.\n *\n * @param snapId - The id of the Snap.\n */\n #removeSnapFromSubjects(snapId: SnapId) {\n const subjects = this.messagingSystem.call(\n 'PermissionController:getSubjectNames',\n );\n for (const subject of subjects) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n subject,\n ) as SubjectPermissions<PermissionConstraint>;\n const snapIdsCaveat = (subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds) ??\n {}) as Caveat<string, Json>;\n\n const caveatHasSnap = Boolean(\n (snapIdsCaveat.value as Record<string, unknown>)?.[snapId],\n );\n if (caveatHasSnap) {\n const newCaveatValue = {\n ...(snapIdsCaveat.value as Record<string, unknown>),\n };\n delete newCaveatValue[snapId];\n if (Object.keys(newCaveatValue).length > 0) {\n this.messagingSystem.call(\n 'PermissionController:updateCaveat',\n subject,\n WALLET_SNAP_PERMISSION_KEY,\n SnapCaveatType.SnapIds,\n newCaveatValue,\n );\n } else {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [subject]: [WALLET_SNAP_PERMISSION_KEY],\n });\n }\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 const permissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) ?? {};\n const snaps =\n permissions[WALLET_SNAP_PERMISSION_KEY]?.caveats?.find(\n (caveat) => caveat.type === SnapCaveatType.SnapIds,\n )?.value ?? {};\n return Object.keys(snaps).reduce<InstallSnapsResult>(\n (permittedSnaps, snapId) => {\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 return permittedSnaps;\n },\n {},\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 const pendingUpdates = [];\n const pendingInstalls = [];\n\n try {\n for (const [snapId, { version: rawVersion }] of Object.entries(\n requestedSnaps,\n )) {\n assertIsValidSnapId(snapId);\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 location = this.#detectSnapLocation(snapId, {\n versionRange: version,\n fetch: this.#fetchFunction,\n allowLocal: this.#featureFlags.allowLocalSnaps,\n });\n\n // Existing snaps may need to be updated, unless they should be re-installed (e.g. local snaps)\n // Everything else is treated as an install\n const isUpdate = this.has(snapId) && !location.shouldAlwaysReload;\n\n if (isUpdate && this.#isValidUpdate(snapId, version)) {\n pendingUpdates.push(snapId);\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 } else if (!isUpdate) {\n pendingInstalls.push(snapId);\n }\n\n result[snapId] = await this.processRequestedSnap(\n origin,\n snapId,\n location,\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 location - The location implementation 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: ValidatedSnapId,\n location: SnapLocation,\n versionRange: SemVerRange,\n ): Promise<ProcessSnapResult> {\n const existingSnap = this.getTruncated(snapId);\n\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 return await this.updateSnap(origin, snapId, location, versionRange);\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 let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_INSTALL,\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 // Existing snaps that should be re-installed should not maintain their existing permissions\n if (existingSnap && location.shouldAlwaysReload) {\n this.revokeAllSnapPermissions(snapId);\n }\n\n try {\n const { sourceCode } = await this.#add({\n origin,\n id: snapId,\n location,\n versionRange,\n });\n\n await this.authorize(snapId, pendingApproval);\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\n\n await this.#startSnap({\n snapId,\n sourceCode,\n });\n\n const truncated = this.getTruncatedExpect(snapId);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n });\n\n this.messagingSystem.publish(`SnapController:snapInstalled`, truncated);\n\n return truncated;\n } catch (error) {\n logError(`Error when adding snap.`, error);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n error: error instanceof Error ? error.message : error.toString(),\n });\n\n throw error;\n }\n }\n\n #createApproval({\n origin,\n snapId,\n type,\n }: {\n origin: string;\n snapId: ValidatedSnapId;\n type: string;\n }): PendingApproval {\n const id = nanoid();\n const promise = this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type,\n requestData: {\n // Mirror previous installation metadata\n metadata: { id, origin: snapId, dappOrigin: origin },\n snapId,\n },\n requestState: {\n loading: true,\n },\n },\n true,\n );\n\n return { id, promise };\n }\n\n #updateApproval(id: string, requestState: Record<string, Json>) {\n try {\n this.messagingSystem.call('ApprovalController:updateRequestState', {\n id,\n requestState,\n });\n } catch {\n // Do nothing\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 location - The location implementation of the snap.\n * @param newVersionRange - A semver version range in which the maximum version will be chosen.\n * @returns The snap metadata if updated, `null` otherwise.\n */\n async updateSnap(\n origin: string,\n snapId: ValidatedSnapId,\n location: SnapLocation,\n newVersionRange: string = DEFAULT_REQUESTED_SNAP_VERSION,\n ): Promise<TruncatedSnap> {\n if (!isValidSemVerRange(newVersionRange)) {\n throw new Error(\n `Received invalid snap version range: \"${newVersionRange}\".`,\n );\n }\n\n let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n try {\n const snap = this.getExpect(snapId);\n\n const newSnap = await this.#fetchSnap(snapId, location);\n\n const newVersion = newSnap.manifest.result.version;\n if (!gtVersion(newVersion, snap.version)) {\n throw ethErrors.rpc.invalidParams(\n `Snap \"${snapId}@${snap.version}\" is already installed. Couldn't update to a version inside requested \"${newVersionRange}\" range.`,\n );\n }\n\n if (!satisfiesVersionRange(newVersion, newVersionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${newVersion}\" which doesn't satisfy requested version range \"${newVersionRange}\".`,\n );\n }\n\n await this.#assertIsInstallAllowed(snapId, {\n version: newVersion,\n checksum: newSnap.manifest.result.source.shasum,\n });\n\n const processedPermissions = this.#processSnapPermissions(\n newSnap.manifest.result.initialPermissions,\n );\n\n this.#validateSnapPermissions(processedPermissions);\n\n const { newPermissions, unusedPermissions, approvedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n this.#updateApproval(pendingApproval.id, {\n permissions: newPermissions,\n newVersion: newSnap.manifest.result.version,\n newPermissions,\n approvedPermissions,\n unusedPermissions,\n loading: false,\n });\n\n const { permissions: approvedNewPermissions, ...requestData } =\n (await pendingApproval.promise) as PermissionsRequest;\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\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 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 normalizedSourcePath = normalizeRelative(\n newSnap.manifest.result.source.location.npm.filePath,\n );\n\n const sourceCode = newSnap.files\n .find((file) => file.path === normalizedSourcePath)\n ?.toString();\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `Invalid source code for snap \"${snapId}\".`,\n );\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 this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n return truncatedSnap;\n } catch (error) {\n logError(`Error when updating snap,`, error);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n error: error instanceof Error ? error.message : error.toString(),\n type: SNAP_APPROVAL_UPDATE,\n });\n throw error;\n }\n }\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n async getRegistryMetadata(\n snapId: SnapId,\n ): Promise<SnapsRegistryMetadata | null> {\n return await this.messagingSystem.call('SnapsRegistry:getMetadata', snapId);\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, versionRange } = args;\n\n this.#setupRuntime(snapId, { sourceCode: null, state: null });\n const runtime = this.#getRuntimeExpect(snapId);\n if (!runtime.installPromise) {\n log(`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 const manifest = fetchedSnap.manifest.result;\n assertIsSnapManifest(manifest);\n if (!satisfiesVersionRange(manifest.version, versionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${manifest.version}\" which doesn't satisfy requested version range \"${versionRange}\".`,\n );\n }\n await this.#assertIsInstallAllowed(snapId, {\n version: manifest.version,\n checksum: manifest.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 logError(\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 { id: snapId, origin, manifest, files, isUpdate = false } = args;\n\n assertIsSnapManifest(manifest.result);\n const { version } = manifest.result;\n\n const normalizedSourcePath = normalizeRelative(\n manifest.result.source.location.npm.filePath,\n );\n\n const { iconPath } = manifest.result.source.location.npm;\n const normalizedIconPath = iconPath && normalizeRelative(iconPath);\n\n const sourceCode = files\n .find((file) => file.path === normalizedSourcePath)\n ?.toString();\n\n const svgIcon = normalizedIconPath\n ? files.find((file) => file.path === normalizedIconPath)\n : undefined;\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `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 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 const { iconPath } = manifest.result.source.location.npm;\n const svgIcon = iconPath ? await location.fetch(iconPath) : undefined;\n\n const files = [sourceCode];\n if (svgIcon) {\n files.push(svgIcon);\n }\n\n validateSnapShasum({ manifest, sourceCode, svgIcon });\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 Object.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 #validateSnapPermissions(\n processedPermissions: Record<string, Pick<PermissionConstraint, 'caveats'>>,\n ) {\n const permissionKeys = Object.keys(processedPermissions);\n\n const handlerPermissions = Object.values(handlerEndowments);\n\n assert(\n permissionKeys.some((key) => handlerPermissions.includes(key)),\n `A snap must request at least one of the following permissions: ${handlerPermissions.join(\n ', ',\n )}.`,\n );\n\n const excludedPermissionErrors = permissionKeys.reduce<string[]>(\n (errors, permission) => {\n if (hasProperty(this.#excludedPermissions, permission)) {\n errors.push(this.#excludedPermissions[permission]);\n }\n\n return errors;\n },\n [],\n );\n\n assert(\n excludedPermissionErrors.length === 0,\n `One or more permissions are not allowed:\\n${excludedPermissionErrors.join(\n '\\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 snapId - The id of the Snap.\n * @param pendingApproval - Pending approval to update.\n * @returns The snap's approvedPermissions.\n */\n private async authorize(\n snapId: SnapId,\n pendingApproval: PendingApproval,\n ): Promise<void> {\n log(`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\n this.#validateSnapPermissions(processedPermissions);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n permissions: processedPermissions,\n });\n\n const { permissions: approvedPermissions, ...requestData } =\n (await pendingApproval.promise) 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 as Record<string, unknown>), 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 logWarning(\n `${SnapEndowments.LongRunning} will soon be deprecated. For more information please see https://github.com/MetaMask/snaps-monorepo/issues/945.`,\n );\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 // Always set to stopped even if it wasn't running initially\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.#transition(snapId, SnapStatusEvents.Stop);\n }\n\n const { statePatches, sourceCode, permissions } = rollbackSnapshot;\n\n if (statePatches?.length) {\n this.applyPatches(statePatches);\n }\n\n // Reset snap status, as we may have been in another state when we stored state patches\n // But now we are 100% in a stopped state\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.update((state) => {\n state.snaps[snapId].status = SnapStatus.Stopped;\n });\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":";;;;;;;;;;;;;;;AAIA,+DAGmC;AACnC,2EAmByC;AACzC,uDAG+B;AAE/B,uDA8B+B;AAC/B,2CAcyB;AACzB,qCAAqE;AACrE,mDAA2C;AAE3C,mCAAgC;AAEhC,gCAAsD;AACtD,wCAAiC;AASjC,oCAA6D;AAC7D,6CAIsB;AACtB,0CAAuD;AACvD,yCAA8D;AAC9D,yCAQoB;AACpB,iDAA8C;AAC9C,mCAAgC;AAEnB,QAAA,cAAc,GAAG,gBAAgB,CAAC;AAE/C,qCAAqC;AACxB,QAAA,qBAAqB,GAAG,oBAAoB,CAAC;AAC7C,QAAA,oBAAoB,GAAG,mBAAmB,CAAC;AAC3C,QAAA,oBAAoB,GAAG,0BAA0B,CAAC;AAE/D,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAsB;IAC7D,oBAAoB;IACpB,IAAI;IACJ,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC,CAAC;AAmcH,MAAM,YAAY,GAAwB;IACxC,UAAU,EAAE,EAAE;IACd,KAAK,EAAE,EAAE;IACT,UAAU,EAAE,EAAE;CACf,CAAC;AAEF;;;;;GAKG;AACH,SAAS,YAAY,CAAC,IAAU;IAC9B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAC5C,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE;QAClB,IAAI,yBAAyB,CAAC,GAAG,CAAC,GAAU,CAAC,EAAE;YAC7C,UAAU,CAAC,GAA0B,CAAC,GAAG,IAAI,CAC3C,GAA0B,CACpB,CAAC;SACV;QAED,OAAO,UAAU,CAAC;IACpB,CAAC,EACD,EAAE,CACH,CAAC;IAEF,4EAA4E;IAC5E,OAAO,aAA8B,CAAC;AACxC,CAAC;AAED,MAAM,IAAI,GAAG,gBAAgB,CAAC;AAE9B;;;;;GAKG;AAEH,MAAa,cAAe,SAAQ,kCAInC;IAgCC,YAAY,EACV,mBAAmB,EACnB,SAAS,EACT,KAAK,EACL,+BAA+B,GAAG,EAAE,EACpC,mBAAmB,GAAG,EAAE,EACxB,qBAAqB,GAAG,IAAA,sBAAc,EAAC,CAAC,EAAE,gBAAQ,CAAC,MAAM,CAAC,EAC1D,WAAW,GAAG,IAAA,sBAAc,EAAC,EAAE,EAAE,gBAAQ,CAAC,MAAM,CAAC,EACjD,cAAc,GAAG,IAAA,sBAAc,EAAC,EAAE,EAAE,gBAAQ,CAAC,MAAM,CAAC,EACpD,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EACjD,YAAY,GAAG,EAAE,EACjB,kBAAkB,EAAE,0BAA0B,GAAG,6BAAkB,GAChD;QACnB,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE;gBACR,UAAU,EAAE;oBACV,OAAO,EAAE,KAAK;oBACd,SAAS,EAAE,KAAK;iBACjB;gBACD,UAAU,EAAE;oBACV,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,KAAK;iBACjB;gBACD,KAAK,EAAE;oBACL,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;wBACjB,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;6BACxB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;4BACZ,OAAO;gCACL,GAAG,IAAI;gCACP,4DAA4D;gCAC5D,MAAM,EAAE,wBAAU,CAAC,OAAO;6BAC3B,CAAC;wBACJ,CAAC,CAAC;6BACD,MAAM,CAAC,CAAC,IAA0B,EAAE,IAAI,EAAE,EAAE;4BAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;4BACrB,OAAO,IAAI,CAAC;wBACd,CAAC,EAAE,EAAE,CAAC,CAAC;oBACX,CAAC;oBACD,SAAS,EAAE,KAAK;iBACjB;aACF;YACD,IAAI;YACJ,KAAK,EAAE;gBACL,GAAG,YAAY;gBACf,GAAG,KAAK;aACT;SACF,CAAC,CAAC;;QA9EL,sDAAkD;QAElD,kEAA2C;QAE3C,sDAA6C;QAE7C,+CAA4B;QAE5B,gDAA6B;QAE7B,wDAA+B;QAE/B,8CAAqB;QAKrB,qDAA+C;QAE/C,mDAAgD;QAEhD,oDAAkD;QAElD,8DAAsC;QAEtC,gDAIE;QAmDA,uBAAA,IAAI,uCAAwB,mBAAmB,MAAA,CAAC;QAChD,uBAAA,IAAI,mDAAoC,+BAA+B,MAAA,CAAC;QACxE,uBAAA,IAAI,uCAAwB,mBAAmB,MAAA,CAAC;QAChD,uBAAA,IAAI,gCAAiB,YAAY,MAAA,CAAC;QAClC,uBAAA,IAAI,iCAAkB,aAAa,MAAA,CAAC;QACpC,uBAAA,IAAI,yCAA0B,qBAAqB,MAAA,CAAC;QACpD,uBAAA,IAAI,+BAAgB,WAAW,MAAA,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,uBAAA,IAAI,sCAAuB,0BAA0B,MAAA,CAAC;QACtD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,uBAAA,IAAI,qCAAsB,IAAI,GAAG,EAAE,MAAA,CAAC;QACpC,uBAAA,IAAI,oCAAqB,IAAI,GAAG,EAAE,MAAA,CAAC;QACnC,uBAAA,IAAI,2EAA0B,MAA9B,IAAI,CAA4B,CAAC;QAEjC,sDAAsD;QACtD,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,iCAAiC,EACjC,IAAI,CAAC,qBAAqB,CAC3B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,kCAAkC,EAClC,IAAI,CAAC,kBAAkB,CACxB,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,mCAAmC,EACnC,IAAI,CAAC,mBAAmB,CACzB,CAAC;QACF,qDAAqD;QAErD,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,CAA0B,CAAC;QAC/B,uBAAA,IAAI,0EAAyB,MAA7B,IAAI,CAA2B,CAAC;QAEhC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACjD,uBAAA,IAAI,+DAAc,MAAlB,IAAI,EAAe,IAAI,CAAC,EAAE,EAAE;YAC1B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI;SAC5C,CAAC,CACH,CAAC;IACJ,CAAC;IA4KD;;;;OAIG;IACH,KAAK,CAAC,kBAAkB;QACtB,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAExD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAClD,mBAAmB,EACnB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CACpC,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE;YACrB,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;gBACtB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM;aACtC,CAAC;YACF,OAAO,YAAY,CAAC;QACtB,CAAC,EACD,EAAE,CACH,CACF,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;YACtE,IAAI,MAAM,KAAK,8BAAmB,CAAC,OAAO,EAAE;gBAC1C,OAAO,uBAAA,IAAI,4DAAW,MAAf,IAAI,EAAY,MAAM,EAAE,MAAM,CAAC,CAAC;aACxC;YAED,OAAO,uBAAA,IAAI,8DAAa,MAAjB,IAAI,EAAc,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAqGD,qBAAqB,CAAC,MAAc,EAAE,KAAoB;QACxD,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,8BAAgB,CAAC,KAAK,CAAC;aAC1C,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;aACpC,KAAK,CAAC,CAAC,aAAa,EAAE,EAAE;YACvB,qCAAqC;YACrC,IAAA,sBAAQ,EAAC,aAAa,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;QAC/C,sFAAsF;QACtF,yFAAyF;QACzF,OAAO,CAAC,sBAAsB;aAC3B,MAAM,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC;aACrE,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,uBAAuB,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,mBAAmB,CAAC,MAAc;QAChC,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,uBAAuB,IAAI,CAAC,CAAC;QACrC,IAAI,OAAO,CAAC,uBAAuB,KAAK,CAAC,EAAE;YACzC,OAAO,CAAC,sBAAsB;iBAC3B,MAAM,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC;iBACpE,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;SAC/D;IACH,CAAC;IAsBD;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEtC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,gBAAgB,CAAC,CAAC;SAClD;QAED,MAAM,uBAAA,IAAI,4DAAW,MAAf,IAAI,EAAY;YACpB,MAAM;YACN,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,MAAc;QACvB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAEvB,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE;YACpC,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,qCAAqC,CAAC,CAAC;SACvE;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,MAAc;QAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;SAChD;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,8BAAgB,CAAC,IAAI,CAAC,CAAC;SACrD;QAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,QAAQ,CACnB,MAAc,EACd,cAE6B,8BAAgB,CAAC,IAAI;QAElD,MAAM,OAAO,GAAG,uBAAA,IAAI,6DAAY,MAAhB,IAAI,EAAa,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CAAC,aAAa,MAAM,mBAAmB,CAAC,CAAC;SACzD;QAED,yBAAyB;QACzB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;QAC3B,OAAO,CAAC,sBAAsB,GAAG,EAAE,CAAC;QACpC,OAAO,CAAC,uBAAuB,GAAG,CAAC,CAAC;QACpC,IAAI;YACF,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;gBAC1B,uBAAA,IAAI,2CAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;gBAClC,MAAM,uBAAA,IAAI,gEAAe,MAAnB,IAAI,EAAgB,MAAM,CAAC,CAAC;aACnC;SACF;gBAAS;YACR,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;gBAC1B,uBAAA,IAAI,6DAAY,MAAhB,IAAI,EAAa,MAAM,EAAE,WAAW,CAAC,CAAC;aACvC;SACF;IACH,CAAC;IAeD;;;;;;OAMG;IACH,SAAS,CAAC,MAAc;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,MAAc;QAChB,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAC,MAAc;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,MAAc;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAA,cAAM,EAAC,IAAI,KAAK,SAAS,EAAE,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,2EAA2E;IAC3E,YAAY,CAAC,MAAc;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE9B,OAAO,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,MAAc;QAC/B,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,eAAe,CAAC,MAAc,EAAE,YAAoB;QACxD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,MAAc;QAC3B,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,SAAoB;QAC/B,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,MAAM,EAAE,GAAG,IAAA,eAAM,GAAE,CAAC;YACpB,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG;gBACrB,GAAG,SAAS;gBACZ,UAAU,EAAE,EAAE;aACf,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,UAAkB;QAChC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,eAAe;QACb,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAAC,MAAc;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC5C,OAAO,KAAK,IAAI,IAAI,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACzB,uBAAA,IAAI,2CAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACtE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;QAEnE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;YACjB,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,OAAiB;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;SAChD;QAED,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAClD,qEAAqE;YACrE,oEAAoE;YACpE,wDAAwD;YACxD,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;YAEtC,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAAyB,MAAM,CAAC,CAAC;YAErC,uBAAA,IAAI,wCAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEtC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;gBACzB,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC3B,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,4BAA4B,EAAE,SAAS,CAAC,CAAC;QACxE,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IA8CD;;;;OAIG;IACK,wBAAwB,CAAC,MAAc;QAC7C,IACE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,qCAAqC,EAAE,MAAM,CAAC,EACxE;YACA,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,2CAA2C,EAC3C,MAAM,CACP,CAAC;SACH;IACH,CAAC;IAED;;;;OAIG;IACH,yBAAyB,CAAC,MAAc;QACtC,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,yBAAyB,CAAC,MAAc;QACtC,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;QAC/C,IAAA,cAAM,EACJ,OAAO,CAAC,gBAAgB,GAAG,CAAC,EAC5B,6DAA6D,CAC9D,CAAC;QACF,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,MAAc;QAC9B,MAAM,WAAW,GACf,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,qCAAqC,EACrC,MAAM,CACP,IAAI,EAAE,CAAC;QACV,MAAM,KAAK,GACT,WAAW,CAAC,wCAA0B,CAAC,EAAE,OAAO,EAAE,IAAI,CACpD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,4BAAc,CAAC,OAAO,CACnD,EAAE,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAC9B,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAEhD,IAAI,aAAa,IAAI,IAAI,EAAE,MAAM,KAAK,wBAAU,CAAC,UAAU,EAAE;gBAC3D,cAAc,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;aACxC;YACD,OAAO,cAAc,CAAC;QACxB,CAAC,EACD,EAAE,CACH,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,YAAY,CAChB,MAAc,EACd,cAAwC;QAExC,MAAM,MAAM,GAAuB,EAAE,CAAC;QAEtC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE5C,MAAM,cAAc,GAAG,EAAE,CAAC;QAC1B,MAAM,eAAe,GAAG,EAAE,CAAC;QAE3B,IAAI;YACF,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAC5D,cAAc,CACf,EAAE;gBACD,IAAA,iCAAmB,EAAC,MAAM,CAAC,CAAC;gBAE5B,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAA,iCAAmB,EAAC,UAAU,CAAC,CAAC;gBAEzD,IAAI,KAAK,EAAE;oBACT,MAAM,0BAAS,CAAC,GAAG,CAAC,aAAa,CAC/B,qFAAqF,UAAU,IAAI,CACpG,CAAC;iBACH;gBAED,MAAM,QAAQ,GAAG,uBAAA,IAAI,0CAAoB,MAAxB,IAAI,EAAqB,MAAM,EAAE;oBAChD,YAAY,EAAE,OAAO;oBACrB,KAAK,EAAE,uBAAA,IAAI,qCAAe;oBAC1B,UAAU,EAAE,uBAAA,IAAI,oCAAc,CAAC,eAAe;iBAC/C,CAAC,CAAC;gBAEH,+FAA+F;gBAC/F,2CAA2C;gBAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;gBAElE,IAAI,QAAQ,IAAI,uBAAA,IAAI,gEAAe,MAAnB,IAAI,EAAgB,MAAM,EAAE,OAAO,CAAC,EAAE;oBACpD,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC5B,IAAI,gBAAgB,GAAG,uBAAA,IAAI,sEAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;oBACzD,IAAI,gBAAgB,KAAK,SAAS,EAAE;wBAClC,gBAAgB,GAAG,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAAyB,MAAM,CAAC,CAAC;wBACxD,gBAAgB,CAAC,UAAU,GAAG,OAAO,CAAC;qBACvC;yBAAM;wBACL,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;qBACxD;iBACF;qBAAM,IAAI,CAAC,QAAQ,EAAE;oBACpB,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;iBAC9B;gBAED,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAC9C,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,CACR,CAAC;aACH;YACD,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,uBAAA,IAAI,yCAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;SACrE;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YACvE,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAClC,MAAM,gBAAgB,GAAG,CAAC,GAAG,uBAAA,IAAI,yCAAmB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7D,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CACvD,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAClC,CAAC;YACF,MAAM,uBAAA,IAAI,gEAAe,MAAnB,IAAI,EAAgB,eAAe,CAAC,CAAC;YAE3C,MAAM,KAAK,CAAC;SACb;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;OASG;IACK,KAAK,CAAC,oBAAoB,CAChC,MAAc,EACd,MAAuB,EACvB,QAAsB,EACtB,YAAyB;QAEzB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE/C,6CAA6C;QAC7C,IAAI,YAAY,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE;YAChD,IAAI,IAAA,6BAAqB,EAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE;gBAC7D,OAAO,YAAY,CAAC;aACrB;YAED,IAAI,uBAAA,IAAI,oCAAc,CAAC,mBAAmB,KAAK,IAAI,EAAE;gBACnD,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;aACtE;YACD,MAAM,0BAAS,CAAC,GAAG,CAAC,aAAa,CAC/B,iDAAiD,MAAM,IAAI,YAAY,CAAC,OAAO,sCAAsC,YAAY,GAAG,CACrI,CAAC;SACH;QAED,IAAI,eAAe,GAAG,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB;YACzC,MAAM;YACN,MAAM;YACN,IAAI,EAAE,6BAAqB;SAC5B,CAAC,CAAC;QAEH,oDAAoD;QACpD,IAAI,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YAC1C,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,8BAAgB,CAAC,IAAI,CAAC,CAAC;SACpD;QAED,4FAA4F;QAC5F,IAAI,YAAY,IAAI,QAAQ,CAAC,kBAAkB,EAAE;YAC/C,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;SACvC;QAED,IAAI;YACF,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,uBAAA,IAAI,sDAAK,MAAT,IAAI,EAAM;gBACrC,MAAM;gBACN,EAAE,EAAE,MAAM;gBACV,QAAQ;gBACR,YAAY;aACb,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAE9C,eAAe,GAAG,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB;gBACrC,MAAM;gBACN,MAAM;gBACN,IAAI,EAAE,4BAAoB;aAC3B,CAAC,CAAC;YAEH,MAAM,uBAAA,IAAI,4DAAW,MAAf,IAAI,EAAY;gBACpB,MAAM;gBACN,UAAU;aACX,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAElD,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,6BAAqB;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,8BAA8B,EAAE,SAAS,CAAC,CAAC;YAExE,OAAO,SAAS,CAAC;SAClB;QAAC,OAAO,KAAK,EAAE;YACd,IAAA,sBAAQ,EAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAE3C,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,6BAAqB;gBAC3B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE;aACjE,CAAC,CAAC;YAEH,MAAM,KAAK,CAAC;SACb;IACH,CAAC;IA4CD;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,UAAU,CACd,MAAc,EACd,MAAuB,EACvB,QAAsB,EACtB,kBAA0B,4CAA8B;QAExD,IAAI,CAAC,IAAA,0BAAkB,EAAC,eAAe,CAAC,EAAE;YACxC,MAAM,IAAI,KAAK,CACb,yCAAyC,eAAe,IAAI,CAC7D,CAAC;SACH;QAED,IAAI,eAAe,GAAG,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB;YACzC,MAAM;YACN,MAAM;YACN,IAAI,EAAE,4BAAoB;SAC3B,CAAC,CAAC;QAEH,IAAI;YACF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAEpC,MAAM,OAAO,GAAG,MAAM,uBAAA,IAAI,4DAAW,MAAf,IAAI,EAAY,MAAM,EAAE,QAAQ,CAAC,CAAC;YAExD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;YACnD,IAAI,CAAC,IAAA,iBAAS,EAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;gBACxC,MAAM,0BAAS,CAAC,GAAG,CAAC,aAAa,CAC/B,SAAS,MAAM,IAAI,IAAI,CAAC,OAAO,0EAA0E,eAAe,UAAU,CACnI,CAAC;aACH;YAED,IAAI,CAAC,IAAA,6BAAqB,EAAC,UAAU,EAAE,eAAe,CAAC,EAAE;gBACvD,MAAM,IAAI,KAAK,CACb,mCAAmC,MAAM,wBAAwB,UAAU,oDAAoD,eAAe,IAAI,CACnJ,CAAC;aACH;YAED,MAAM,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAAyB,MAAM,EAAE;gBACzC,OAAO,EAAE,UAAU;gBACnB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM;aAChD,CAAC,CAAC;YAEH,MAAM,oBAAoB,GAAG,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAC3C,CAAC;YAEF,uBAAA,IAAI,0EAAyB,MAA7B,IAAI,EAA0B,oBAAoB,CAAC,CAAC;YAEpD,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAC9D,uBAAA,IAAI,6EAA4B,MAAhC,IAAI,EAA6B,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAEjE,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,EAAE,EAAE;gBACvC,WAAW,EAAE,cAAc;gBAC3B,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO;gBAC3C,cAAc;gBACd,mBAAmB;gBACnB,iBAAiB;gBACjB,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YAEH,MAAM,EAAE,WAAW,EAAE,sBAAsB,EAAE,GAAG,WAAW,EAAE,GAC3D,CAAC,MAAM,eAAe,CAAC,OAAO,CAAuB,CAAC;YAExD,eAAe,GAAG,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB;gBACrC,MAAM;gBACN,MAAM;gBACN,IAAI,EAAE,4BAAoB;aAC3B,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;gBAC1B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,8BAAgB,CAAC,IAAI,CAAC,CAAC;aACpD;YAED,uBAAA,IAAI,6DAAY,MAAhB,IAAI,EAAa,MAAM,EAAE,8BAAgB,CAAC,MAAM,CAAC,CAAC;YAElD,uBAAA,IAAI,sDAAK,MAAT,IAAI,EAAM;gBACR,MAAM;gBACN,EAAE,EAAE,MAAM;gBACV,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,MAAM,qBAAqB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC7D,IAAI,IAAA,uBAAe,EAAC,qBAAqB,CAAC,EAAE;gBAC1C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,wCAAwC,EAAE;oBAClE,CAAC,MAAM,CAAC,EAAE,qBAAqB;iBAChC,CAAC,CAAC;aACJ;YAED,IAAI,IAAA,uBAAe,EAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,EAAE;gBACxD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,uCAAuC,EAAE;oBACjE,mBAAmB,EAAE,sBAAsB;oBAC3C,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;oBAC3B,WAAW;iBACZ,CAAC,CAAC;aACJ;YAED,MAAM,gBAAgB,GAAG,uBAAA,IAAI,sEAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;YAC3D,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAClC,gBAAgB,CAAC,WAAW,CAAC,OAAO,GAAG,iBAAiB,CAAC;gBACzD,gBAAgB,CAAC,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAChD,sBAAsB,CACvB,CAAC;gBACF,gBAAgB,CAAC,WAAW,CAAC,WAAW,GAAG,WAAW,CAAC;aACxD;YAED,MAAM,oBAAoB,GAAG,IAAA,+BAAiB,EAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CACrD,CAAC;YAEF,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK;iBAC7B,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAoB,CAAC;gBACnD,EAAE,QAAQ,EAAE,CAAC;YAEf,IAAA,cAAM,EACJ,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EACvD,iCAAiC,MAAM,IAAI,CAC5C,CAAC;YAEF,IAAI;gBACF,MAAM,uBAAA,IAAI,4DAAW,MAAf,IAAI,EAAY,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;aAC/C;YAAC,MAAM;gBACN,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,oCAAoC,CAAC,CAAC;aACrE;YAED,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YACtD,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,4BAA4B,EAC5B,aAAa,EACb,IAAI,CAAC,OAAO,CACb,CAAC;YAEF,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,4BAAoB;aAC3B,CAAC,CAAC;YAEH,OAAO,aAAa,CAAC;SACtB;QAAC,OAAO,KAAK,EAAE;YACd,IAAA,sBAAQ,EAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YAE7C,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE;gBAChE,IAAI,EAAE,4BAAoB;aAC3B,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;SACb;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,mBAAmB,CACvB,MAAc;QAEd,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;IAC9E,CAAC;IAiVD;;;;;;;;;OASG;IACK,KAAK,CAAC,SAAS,CACrB,MAAc,EACd,eAAgC;QAEhC,IAAA,aAAG,EAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC;QAEpC,IAAI;YACF,MAAM,oBAAoB,GACxB,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAAyB,kBAAkB,CAAC,CAAC;YAEnD,uBAAA,IAAI,0EAAyB,MAA7B,IAAI,EAA0B,oBAAoB,CAAC,CAAC;YAEpD,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,EAAE,EAAE;gBACvC,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,oBAAoB;aAClC,CAAC,CAAC;YAEH,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,WAAW,EAAE,GACxD,CAAC,MAAM,eAAe,CAAC,OAAO,CAAuB,CAAC;YAExD,IAAI,IAAA,uBAAe,EAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE;gBACrD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,uCAAuC,EAAE;oBACjE,mBAAmB;oBACnB,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;oBAC3B,WAAW;iBACZ,CAAC,CAAC;aACJ;SACF;gBAAS;YACR,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;YAC/C,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;SAC/B;IACH,CAAC;IAED,OAAO;QACL,KAAK,CAAC,OAAO,EAAE,CAAC;QAEhB,IAAI,uBAAA,IAAI,mDAA6B,EAAE;YACrC,YAAY,CAAC,uBAAA,IAAI,mDAA6B,CAAC,CAAC;SACjD;QAED,sDAAsD;QACtD,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,iCAAiC,EACjC,IAAI,CAAC,qBAAqB,CAC3B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,kCAAkC,EAClC,IAAI,CAAC,kBAAkB,CACxB,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,mCAAmC,EACnC,IAAI,CAAC,mBAAmB,CACzB,CAAC;QACF,qDAAqD;IACvD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,aAAa,CAAC,EAClB,MAAM,EACN,MAAM,EACN,OAAO,EAAE,WAAW,EACpB,OAAO,GAC8B;QACrC,MAAM,cAAc,GAAG,8BAAiB,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC7C,oCAAoC,EACpC,MAAM,EACN,cAAc,CACf,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,8BAA8B,cAAc,IAAI,CAChE,CAAC;SACH;QAED,IAAI,cAAc,KAAK,2BAAc,CAAC,GAAG,EAAE;YACzC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACvC,8CAA8C,EAC9C,MAAM,CACP,CAAC;YACF,MAAM,MAAM,GAAG,OAAO,EAAE,WAAW,KAAK,mCAAW,CAAC,IAAI,CAAC;YAEzD,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC3C,qCAAqC,EACrC,MAAM,CACP,CAAC;YAEF,MAAM,aAAa,GAAG,WAAW,EAAE,CAAC,2BAAc,CAAC,GAAG,CAAC,CAAC;YACxD,IAAA,cAAM,EAAC,aAAa,CAAC,CAAC;YAEtB,MAAM,OAAO,GAAG,IAAA,yBAAmB,EAAC,aAAa,CAAC,CAAC;YACnD,IAAA,cAAM,EAAC,OAAO,CAAC,CAAC;YAEhB,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBAC7D,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,wDAAwD,MAAM,IAAI,CAClF,CAAC;aACH;SACF;QAED,MAAM,OAAO,GAAG,MAAM,uBAAA,IAAI,uEAAsB,MAA1B,IAAI,EAAuB,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CACb,gDAAgD,MAAM,IAAI,CAC3D,CAAC;SACH;QAED,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5D,CAAC;CA4WF;AApmED,wCAomEC;;IAz9DG,MAAM,YAAY,GAAG,CAAC,EAAE,MAAM,EAAiB,EAAE,EAAE;QACjD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;IACxC,CAAC,CAAC;IAEF,MAAM,YAAY,GAId;QACF,OAAO,EAAE,wBAAU,CAAC,UAAU;QAC9B,MAAM,EAAE;YACN,CAAC,wBAAU,CAAC,UAAU,CAAC,EAAE;gBACvB,EAAE,EAAE;oBACF,CAAC,8BAAgB,CAAC,KAAK,CAAC,EAAE;wBACxB,MAAM,EAAE,wBAAU,CAAC,OAAO;wBAC1B,IAAI,EAAE,YAAY;qBACnB;iBACF;aACF;YACD,CAAC,wBAAU,CAAC,QAAQ,CAAC,EAAE;gBACrB,EAAE,EAAE;oBACF,CAAC,8BAAgB,CAAC,KAAK,CAAC,EAAE;wBACxB,MAAM,EAAE,wBAAU,CAAC,OAAO;wBAC1B,IAAI,EAAE,YAAY;qBACnB;oBACD,CAAC,8BAAgB,CAAC,IAAI,CAAC,EAAE,wBAAU,CAAC,OAAO;iBAC5C;aACF;YACD,CAAC,wBAAU,CAAC,OAAO,CAAC,EAAE;gBACpB,EAAE,EAAE;oBACF,CAAC,8BAAgB,CAAC,IAAI,CAAC,EAAE,wBAAU,CAAC,OAAO;oBAC3C,CAAC,8BAAgB,CAAC,KAAK,CAAC,EAAE,wBAAU,CAAC,OAAO;iBAC7C;aACF;YACD,CAAC,wBAAU,CAAC,OAAO,CAAC,EAAE;gBACpB,EAAE,EAAE;oBACF,CAAC,8BAAgB,CAAC,KAAK,CAAC,EAAE;wBACxB,MAAM,EAAE,wBAAU,CAAC,OAAO;wBAC1B,IAAI,EAAE,YAAY;qBACnB;oBACD,CAAC,8BAAgB,CAAC,MAAM,CAAC,EAAE,wBAAU,CAAC,QAAQ;iBAC/C;aACF;YACD,CAAC,wBAAU,CAAC,OAAO,CAAC,EAAE;gBACpB,EAAE,EAAE;oBACF,CAAC,8BAAgB,CAAC,KAAK,CAAC,EAAE;wBACxB,MAAM,EAAE,wBAAU,CAAC,OAAO;wBAC1B,IAAI,EAAE,YAAY;qBACnB;oBACD,CAAC,8BAAgB,CAAC,MAAM,CAAC,EAAE,wBAAU,CAAC,QAAQ;iBAC/C;aACF;SACF;KACF,CAAC;IACF,uBAAA,IAAI,iCAAkB,IAAA,mBAAa,EAAC,YAAY,CAAC,MAAA,CAAC;IAClD,IAAA,qBAAe,EAAC,uBAAA,IAAI,qCAAe,CAAC,CAAC;AACvC,CAAC;IAOC,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,iBAAiB,EAClC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,CAC1C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,MAAM,EACvB,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAC/B,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,eAAe,EAChC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAC9C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,gBAAgB,EACjC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAC/C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,MAAM,EACvB,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAC/B,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,qBAAqB,EACtC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CACtC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,kBAAkB,EACnC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,CACjD,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,SAAS,EAC1B,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CACtC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,UAAU,EAC3B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAC7C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,SAAS,EAC1B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAC5C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,eAAe,EAChC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,CAC7C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,UAAU,EAC3B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAC9C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,kBAAkB,EACnC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,CAC3C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,SAAS,EAC1B,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CACvC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,4BAA4B,EAC7C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,CACrD,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,4BAA4B,EAC7C,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,CACrD,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,sBAAc,sBAAsB,EACvC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,CACrD,CAAC;AACJ,CAAC;IAGC,uBAAA,IAAI,+CAAgC,UAAU,CAAC,GAAG,EAAE;QAClD,uBAAA,IAAI,8EAA6B,MAAjC,IAAI,CAA+B,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAClD,qCAAqC;YACrC,IAAA,sBAAQ,EAAC,KAAK,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,uBAAA,IAAI,2EAA0B,MAA9B,IAAI,CAA4B,CAAC;IACnC,CAAC,EAAE,uBAAA,IAAI,6CAAuB,CAAsB,MAAA,CAAC;AACvD,CAAC;AAmCD;;;;;;GAMG;AACH,KAAK,oCACH,MAAc,EACd,eAA6B;IAE7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QACrB,OAAO;KACR;IAED,IAAI;QACF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;YACnC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,gBAAgB,GAAG,eAAe,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;KAChC;IAAC,OAAO,KAAK,EAAE;QACd,IAAA,sBAAQ,EACN,iDAAiD,MAAM,IAAI,EAC3D,KAAK,CACN,CAAC;KACH;IAED,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,GAAG,sBAAc,cAAc,EAC/B,MAAM,EACN,eAAe,CAChB,CAAC;AACJ,CAAC,qEASY,MAAc;IACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE;QAC1D,OAAO;KACR;IAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;QACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;QACpC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,sBAAc,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAC1E,CAAC,2CAED,KAAK,iDACH,MAAuB,EACvB,QAA2B;IAE3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,mBAAmB,EAAE;QACnE,CAAC,MAAM,CAAC,EAAE,QAAQ;KACnB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,MAAM,CAAC,MAAM,KAAK,8BAAmB,CAAC,OAAO,EAAE;QACjD,MAAM,IAAI,KAAK,CACb,2BACE,QAAQ,CAAC,OACX,cAAc,MAAM,8BAClB,MAAM,CAAC,MAAM,EAAE,WAAW,IAAI,EAChC,EAAE,CACH,CAAC;KACH;SAAM,IACL,uBAAA,IAAI,oCAAc,CAAC,gBAAgB;QACnC,MAAM,CAAC,MAAM,KAAK,8BAAmB,CAAC,QAAQ,EAC9C;QACA,MAAM,IAAI,KAAK,CACb,2BAA2B,QAAQ,CAAC,OAAO,cAAc,MAAM,uCAAuC,CACvG,CAAC;KACH;AACH,CAAC,gDAED,KAAK;IACH,MAAM,OAAO,GAAG,CAAC,GAAG,uBAAA,IAAI,wCAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC,GAAG,CAChB,OAAO;SACJ,MAAM,CACL,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,CACrB,OAAO,CAAC,gBAAgB,KAAK,CAAC;QAC9B,OAAO,CAAC,sBAAsB,CAAC,MAAM,KAAK,CAAC;QAC3C,wEAAwE;QACxE,OAAO,CAAC,WAAW;QACnB,uBAAA,IAAI,mCAAa;QACjB,IAAA,iBAAS,EAAC,OAAO,CAAC,WAAW,CAAC,GAAG,uBAAA,IAAI,mCAAa,CACrD;SACA,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,8BAAgB,CAAC,IAAI,CAAC,CAAC,CACzE,CAAC;AACJ,CAAC,mEA2CW,MAAc,EAAE,KAA0C;IACpE,MAAM,EAAE,WAAW,EAAE,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;IACvD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;QACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC;AAgGD;;;;GAIG;AACH,KAAK,wCAAgB,MAAc;IACjC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC;IAC1E,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,+BAA+B,EAC/B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAChC,CAAC;AACJ,CAAC,2FA0NuB,MAAc;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACxC,sCAAsC,CACvC,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC9B,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAClD,qCAAqC,EACrC,OAAO,CACoC,CAAC;QAC9C,MAAM,aAAa,GAAG,CAAC,kBAAkB,EAAE,CACzC,wCAA0B,CAC3B,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,4BAAc,CAAC,OAAO,CAAC;YAClE,EAAE,CAAyB,CAAC;QAE9B,MAAM,aAAa,GAAG,OAAO,CAC1B,aAAa,CAAC,KAAiC,EAAE,CAAC,MAAM,CAAC,CAC3D,CAAC;QACF,IAAI,aAAa,EAAE;YACjB,MAAM,cAAc,GAAG;gBACrB,GAAI,aAAa,CAAC,KAAiC;aACpD,CAAC;YACF,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC1C,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,mCAAmC,EACnC,OAAO,EACP,wCAA0B,EAC1B,4BAAc,CAAC,OAAO,EACtB,cAAc,CACf,CAAC;aACH;iBAAM;gBACL,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,wCAAwC,EAAE;oBAClE,CAAC,OAAO,CAAC,EAAE,CAAC,wCAA0B,CAAC;iBACxC,CAAC,CAAC;aACJ;SACF;KACF;AACH,CAAC,2EA6Pe,EACd,MAAM,EACN,MAAM,EACN,IAAI,GAKL;IACC,MAAM,EAAE,GAAG,IAAA,eAAM,GAAE,CAAC;IACpB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACvC,+BAA+B,EAC/B;QACE,MAAM;QACN,EAAE;QACF,IAAI;QACJ,WAAW,EAAE;YACX,wCAAwC;YACxC,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE;YACpD,MAAM;SACP;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,IAAI;SACd;KACF,EACD,IAAI,CACL,CAAC;IAEF,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;AACzB,CAAC,2EAEe,EAAU,EAAE,YAAkC;IAC5D,IAAI;QACF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,uCAAuC,EAAE;YACjE,EAAE;YACF,YAAY;SACb,CAAC,CAAC;KACJ;IAAC,MAAM;QACN,aAAa;KACd;AACH,CAAC;AAuLD;;;;;;;;GAQG;AACH,KAAK,8BAAM,IAAiB;IAC1B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAEpD,uBAAA,IAAI,+DAAc,MAAlB,IAAI,EAAe,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE;QAC3B,IAAA,aAAG,EAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;QAE9B,uEAAuE;QACvE,qCAAqC;QACrC,OAAO,CAAC,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACnC,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,4DAAW,MAAf,IAAI,EAAY,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC7C,IAAA,kCAAoB,EAAC,QAAQ,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAA,6BAAqB,EAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE;gBAC1D,MAAM,IAAI,KAAK,CACb,mCAAmC,MAAM,wBAAwB,QAAQ,CAAC,OAAO,oDAAoD,YAAY,IAAI,CACtJ,CAAC;aACH;YACD,MAAM,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAAyB,MAAM,EAAE;gBACzC,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;aACjC,CAAC,CAAC;YAEH,OAAO,uBAAA,IAAI,sDAAK,MAAT,IAAI,EAAM;gBACf,GAAG,IAAI;gBACP,GAAG,WAAW;gBACd,EAAE,EAAE,MAAM;aACX,CAAC,CAAC;QACL,CAAC,CAAC,EAAE,CAAC;KACN;IAED,IAAI;QACF,OAAO,MAAM,OAAO,CAAC,cAAc,CAAC;KACrC;IAAC,OAAO,KAAK,EAAE;QACd,uEAAuE;QACvE,aAAa;QACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;QAC9B,MAAM,KAAK,CAAC;KACb;AACH,CAAC,8BAED,KAAK,oCAAY,QAAgD;IAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;IAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,uBAAuB,CAAC,CAAC;KACzD;IAED,IAAI;QACF,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,qEAAoB,MAAxB,IAAI,EACvB,MAAM,EACN,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,8BAA8B,EAAE;YACxD,GAAG,QAAQ;YACX,UAAU,EAAE,MAAM,uBAAA,IAAI,gEAAe,MAAnB,IAAI,EAAgB,MAAM,CAAC;SAC9C,CAAC,CACH,CAAC;QACF,uBAAA,IAAI,6DAAY,MAAhB,IAAI,EAAa,MAAM,EAAE,8BAAgB,CAAC,KAAK,CAAC,CAAC;QACjD,OAAO,MAAM,CAAC;KACf;IAAC,OAAO,KAAK,EAAE;QACd,MAAM,uBAAA,IAAI,gEAAe,MAAnB,IAAI,EAAgB,MAAM,CAAC,CAAC;QAClC,MAAM,KAAK,CAAC;KACb;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,wCAAgB,MAAc;IACjC,IAAI,aAAa,GAAa,EAAE,CAAC;IAEjC,KAAK,MAAM,cAAc,IAAI,uBAAA,IAAI,uDAAiC,EAAE;QAClE,IACE,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,oCAAoC,EACpC,MAAM,EACN,cAAc,CACf,EACD;YACA,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAChD,oCAAoC,EACpC,MAAM,EACN,cAAc,CACf,CAAC;YAEF,IAAI,UAAU,EAAE;gBACd,gEAAgE;gBAChE,yCAAyC;gBACzC,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;oBAC1B,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,EACrD;oBACA,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;iBACjE;gBAED,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,UAAsB,CAAC,CAAC;aAC9D;SACF;KACF;IAED,MAAM,iBAAiB,GAAG;QACxB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,gCAAkB,EAAE,GAAG,aAAa,CAAC,CAAC;KACtD,CAAC;IAEF,IACE,iBAAiB,CAAC,MAAM;QACxB,oFAAoF;QACpF,qEAAqE;QACrE,gCAAkB,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,EAChD;QACA,IAAA,sBAAQ,EACN,yEAAyE,EACzE,aAAa,CACd,CAAC;KACH;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC,qDAgBI,IAAiB;IACpB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;IAEvE,IAAA,kCAAoB,EAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;IAEpC,MAAM,oBAAoB,GAAG,IAAA,+BAAiB,EAC5C,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAC7C,CAAC;IAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;IACzD,MAAM,kBAAkB,GAAG,QAAQ,IAAI,IAAA,+BAAiB,EAAC,QAAQ,CAAC,CAAC;IAEnE,MAAM,UAAU,GAAG,KAAK;SACrB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAoB,CAAC;QACnD,EAAE,QAAQ,EAAE,CAAC;IAEf,MAAM,OAAO,GAAG,kBAAkB;QAChC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC;QACxD,CAAC,CAAC,SAAS,CAAC;IAEd,IAAA,cAAM,EACJ,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EACvD,iCAAiC,MAAM,IAAI,CAC5C,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IAEpC,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAExC,MAAM,sBAAsB,GAAG,YAAY,EAAE,cAAc,IAAI,EAAE,CAAC;IAClE,MAAM,cAAc,GAAG;QACrB,GAAG,sBAAsB;QACzB;YACE,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,MAAM;SACP;KACF,CAAC;IAEF,MAAM,IAAI,GAAS;QACjB,2CAA2C;QAC3C,GAAG,YAAY;QAEf,sEAAsE;QACtE,kBAAkB;QAClB,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,IAAI;QAEb,EAAE,EAAE,MAAM;QACV,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB;QACtD,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,MAAM,EAAE,uBAAA,IAAI,qCAAe,CAAC,MAAM,CAAC,OAAgC;QACnE,UAAU;QACV,OAAO;QACP,cAAc;KACf,CAAC;IACF,+CAA+C;IAC/C,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAE7B,+BAA+B;IAC/B,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;QACpD,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAC9D,oEAAoE;IACpE,IAAI,QAAQ,EAAE;QACZ,MAAM,gBAAgB,GAAG,uBAAA,IAAI,sEAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;QAC3D,IAAI,gBAAgB,KAAK,SAAS,EAAE;YAClC,gBAAgB,CAAC,YAAY,GAAG,cAAc,CAAC;SAChD;KACF;IAED,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,0BAA0B,EAC1B,IAAI,EACJ,OAAO,EAAE,QAAQ,EAAE,CACpB,CAAC;IACF,OAAO,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,oCACH,MAAuB,EACvB,QAAsB;IAEtB,IAAI;QACF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,KAAK,CACrC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAC7C,CAAC;QACF,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QACzD,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtE,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3B,IAAI,OAAO,EAAE;YACX,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACrB;QAED,IAAA,gCAAkB,EAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAEtD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;KACtC;IAAC,OAAO,KAAK,EAAE;QACd,gFAAgF;QAChF,8GAA8G;QAC9G,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC;KAClE;AACH,CAAC,2FAeC,kBAAmC;IAEnC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAAE,EAAE;QACpE,IAAI,IAAA,mBAAW,EAAC,2BAAa,EAAE,iBAAiB,CAAC,EAAE;YACjD,OAAO,CAAC,iBAAiB,EAAE,2BAAa,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;SACrE;aAAM,IAAI,IAAA,mBAAW,EAAC,mCAAsB,EAAE,iBAAiB,CAAC,EAAE;YACjE,OAAO;gBACL,iBAAiB;gBACjB,mCAAsB,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC;aACjD,CAAC;SACH;QAED,yEAAyE;QACzE,OAAO;YACL,iBAAiB;YACjB,KAA8C;SAC/C,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC,6FAGC,oBAA2E;IAE3E,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAEzD,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,8BAAiB,CAAC,CAAC;IAE5D,IAAA,cAAM,EACJ,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9D,kEAAkE,kBAAkB,CAAC,IAAI,CACvF,IAAI,CACL,GAAG,CACL,CAAC;IAEF,MAAM,wBAAwB,GAAG,cAAc,CAAC,MAAM,CACpD,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE;QACrB,IAAI,IAAA,mBAAW,EAAC,uBAAA,IAAI,2CAAqB,EAAE,UAAU,CAAC,EAAE;YACtD,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,2CAAqB,CAAC,UAAU,CAAC,CAAC,CAAC;SACpD;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,EAAE,CACH,CAAC;IAEF,IAAA,cAAM,EACJ,wBAAwB,CAAC,MAAM,KAAK,CAAC,EACrC,6CAA6C,wBAAwB,CAAC,IAAI,CACxE,IAAI,CACL,EAAE,CACJ,CAAC;AACJ,CAAC,uFA+IqB,MAAc;IAClC,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;IAC/C,MAAM,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAC3C,IAAI,eAAe,EAAE;QACnB,OAAO,eAAe,CAAC;KACxB;IAED,MAAM,YAAY,GAAG,IAAI,2BAAY,CAAC,CAAC,CAAC,CAAC;IACzC,uFAAuF;IACvF,uEAAuE;IACvE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEvD,MAAM,UAAU,GAAG,KAAK,EAAE,EACxB,MAAM,EACN,OAAO,EAAE,WAAW,EACpB,OAAO,GACS,EAAE,EAAE;QACpB,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,KAAK,EAAE;YAC9C,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,gBAAgB,CAAC,CAAC;SAClD;QAED,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,wBAAU,CAAC,UAAU,EAAE;YAC7D,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,yDAAyD,CACzE,CAAC;SACH;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YAC3B,IAAI,iBAAiB,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,CAAC,iBAAiB,EAAE;gBACtB,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAC3C,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;aAC9C;iBAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,YAAY,EAAE;gBAChE,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;aACH;YAED,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAI;gBACF,MAAM,iBAAiB,CAAC;aACzB;oBAAS;gBACR,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAC/B,kEAAkE;gBAClE,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,iBAAiB,EAAE;oBACnD,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;iBAC9B;aACF;SACF;QAED,IAAI,QAAQ,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAA,mBAAW,EAAC,OAAO,EAAE,SAAS,CAAC,EAAE;YACpC,QAAQ,GAAG,EAAE,GAAI,OAAmC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;SACxE;aAAM,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,EAAE;YACpC,MAAM,0BAAS,CAAC,GAAG,CAAC,cAAc,CAAC;gBACjC,OAAO,EAAE,wDAAwD;gBACjE,IAAI,EAAE,OAAO,CAAC,OAAO;aACtB,CAAC,CAAC;SACJ;QAED,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7C,uBAAA,IAAI,4EAA2B,MAA/B,IAAI,EAA4B,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAE3D,MAAM,uBAAuB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CACvD,mCAAmC,EACnC,MAAM,EACN,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,CACpD,CAAC;QAEF,gEAAgE;QAChE,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,qEAAoB,MAAxB,IAAI,EACvB,MAAM,EACN,uBAAuB,EACvB,KAAK,CACN,CAAC;YACF,uBAAA,IAAI,6EAA4B,MAAhC,IAAI,EAA6B,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC;SACf;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,8BAAgB,CAAC,KAAK,CAAC,CAAC;YACpD,MAAM,KAAK,CAAC;SACb;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IAChC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,6CACH,MAAc,EACd,OAA8B,EAC9B,KAAa;IAEb,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC7C,oCAAoC,EACpC,MAAM,EACN,2BAAc,CAAC,WAAW,CAC3B,CAAC;IAEF,4CAA4C;IAC5C,IAAI,aAAa,EAAE;QACjB,IAAA,wBAAU,EACR,GAAG,2BAAc,CAAC,WAAW,kHAAkH,CAChJ,CAAC;QACF,OAAO,OAAO,CAAC;KAChB;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAW,EAAC,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC;IACxE,IAAI,MAAM,KAAK,mBAAW,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;KAC3C;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,iGAE0B,MAAc,EAAE,SAAkB,EAAE,KAAY;IACzE,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;IAC/C,OAAO,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;AAC7B,CAAC,mGAE2B,MAAc,EAAE,SAAkB;IAC5D,MAAM,OAAO,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;IAC/C,OAAO,CAAC,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,MAAM,CACpE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAC7C,CAAC;IAEF,IAAI,OAAO,CAAC,sBAAsB,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/C,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;KAClC;AACH,CAAC,qFAQoB,MAAc;IACjC,OAAO,uBAAA,IAAI,yCAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC,2FAUuB,MAAc;IACpC,IAAA,cAAM,EACJ,uBAAA,IAAI,yCAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EACjD,IAAI,KAAK,CAAC,SAAS,MAAM,qCAAqC,CAAC,CAChE,CAAC;IAEF,uBAAA,IAAI,yCAAmB,CAAC,GAAG,CAAC,MAAM,EAAE;QAClC,YAAY,EAAE,EAAE;QAChB,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;QAC9D,UAAU,EAAE,EAAE;KACf,CAAC,CAAC;IAEH,MAAM,mBAAmB,GAAG,uBAAA,IAAI,yCAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEhE,IAAA,cAAM,EACJ,mBAAmB,KAAK,SAAS,EACjC,IAAI,KAAK,CAAC,gCAAgC,MAAM,GAAG,CAAC,CACrD,CAAC;IACF,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,uCAAe,MAAc;IAChC,MAAM,gBAAgB,GAAG,uBAAA,IAAI,sEAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;IAC3D,IAAI,CAAC,gBAAgB,EAAE;QACrB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC7D;IAED,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,8BAAgB,CAAC,IAAI,CAAC,CAAC;IACnD,4DAA4D;IAC5D,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,wBAAU,CAAC,OAAO,EAAE;QACnD,uBAAA,IAAI,6DAAY,MAAhB,IAAI,EAAa,MAAM,EAAE,8BAAgB,CAAC,IAAI,CAAC,CAAC;KACjD;IAED,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC;IAEvD,IAAI,YAAY,EAAE,MAAM,EAAE;QACxB,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;KACjC;IAED,uFAAuF;IACvF,yCAAyC;IACzC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,wBAAU,CAAC,OAAO,EAAE;QACnD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,wBAAU,CAAC,OAAO,CAAC;QAClD,CAAC,CAAC,CAAC;KACJ;IAED,IAAI,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE;QAClE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,uCAAuC,EAAE;YACjE,mBAAmB,EAAE,WAAW,CAAC,OAA+B;YAChE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;YAC3B,WAAW,EAAE,WAAW,CAAC,WAAsC;SAChE,CAAC,CAAC;KACJ;IAED,IAAI,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;QAC/B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,wCAAwC,EAAE;YAClE,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,OAAgC;SACvD,CAAC,CAAC;KACJ;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAEtD,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,+BAA+B,EAC/B,aAAa,EACb,gBAAgB,CAAC,UAAU,CAC5B,CAAC;IAEF,uBAAA,IAAI,yCAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,KAAK,wCAAgB,OAAiB;IACpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,MAAM,uBAAA,IAAI,+DAAc,MAAlB,IAAI,EAAe,MAAM,CAAC,CAAC;KAClC;AACH,CAAC,mEAEW,MAAc;IACxB,OAAO,uBAAA,IAAI,wCAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC,+EAEiB,MAAc;IAC9B,MAAM,OAAO,GAAG,uBAAA,IAAI,6DAAY,MAAhB,IAAI,EAAa,MAAM,CAAC,CAAC;IACzC,IAAA,cAAM,EACJ,OAAO,KAAK,SAAS,EACrB,IAAI,KAAK,CAAC,SAAS,MAAM,0BAA0B,CAAC,CACrD,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC,uEAGC,MAAc,EACd,IAAyD;IAEzD,IAAI,uBAAA,IAAI,wCAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QACtC,OAAO;KACR;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,WAAW,GAAG,IAAA,eAAS,EAAC,uBAAA,IAAI,qCAAe,CAAC,CAAC;IACnD,WAAW,CAAC,KAAK,CAAC;QAChB,OAAO,EAAE,EAAE,MAAM,EAAE;QACnB,KAAK,EACH,IAAI,EAAE,MAAM;YACX,uBAAA,IAAI,qCAAe,CAAC,MAAM,CAAC,OAAiC;KAChE,CAAC,CAAC;IAEH,IAAA,iBAAW,EAAC,WAAW,CAAC,CAAC;IAEzB,uBAAA,IAAI,wCAAkB,CAAC,GAAG,CAAC,MAAM,EAAE;QACjC,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,cAAc,EAAE,IAAI;QACpB,gBAAgB,EAAE,CAAC;QACnB,sBAAsB,EAAE,EAAE;QAC1B,uBAAuB,EAAE,CAAC;QAC1B,WAAW;QACX,GAAG,IAAI;KACR,CAAC,CAAC;AACL,CAAC,mGAGC,MAAc,EACd,qBAA+C;IAU/C,MAAM,cAAc,GAClB,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,qCAAqC,EACrC,MAAM,CACP,IAAI,EAAE,CAAC;IAEV,MAAM,cAAc,GAAG,IAAA,eAAO,EAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;IACtE,qFAAqF;IACrF,oDAAoD;IACpD,MAAM,iBAAiB,GAAG,IAAA,eAAO,EAAC,cAAc,EAAE,qBAAqB,CAAC,CAAC;IAEzE,sEAAsE;IACtE,qGAAqG;IACrG,MAAM,mBAAmB,GAAG,IAAA,eAAO,EAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;IAEvE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;AACpE,CAAC,yEAiBc,MAAc,EAAE,eAA4B;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAE5C,IAAI,IAAA,6BAAqB,EAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE;QAChE,OAAO,KAAK,CAAC;KACd;IAED,IAAI,IAAA,eAAO,EAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE;QAClD,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import {\n AddApprovalRequest,\n UpdateRequestState,\n} from '@metamask/approval-controller';\nimport {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n Caveat,\n GetEndowments,\n GetPermissions,\n GetSubjects,\n GrantPermissions,\n HasPermission,\n HasPermissions,\n PermissionConstraint,\n PermissionsRequest,\n RequestedPermissions,\n RevokeAllPermissions,\n RevokePermissionForAllSubjects,\n RevokePermissions,\n SubjectPermissions,\n ValidPermission,\n UpdateCaveat,\n GetSubjectMetadata,\n SubjectType,\n} from '@metamask/permission-controller';\nimport {\n caveatMappers,\n WALLET_SNAP_PERMISSION_KEY,\n} from '@metamask/rpc-methods';\nimport { BlockReason } from '@metamask/snaps-registry';\nimport {\n assertIsSnapManifest,\n DEFAULT_ENDOWMENTS,\n DEFAULT_REQUESTED_SNAP_VERSION,\n InstallSnapsResult,\n normalizeRelative,\n PersistedSnap,\n ProcessSnapResult,\n RequestedSnapPermissions,\n resolveVersionRange,\n Snap,\n SnapCaveatType,\n SnapId,\n SnapManifest,\n SnapPermissions,\n SnapRpcHook,\n SnapRpcHookArgs,\n SnapStatus,\n SnapStatusEvents,\n StatusContext,\n StatusEvents,\n StatusStates,\n TruncatedSnap,\n TruncatedSnapFields,\n ValidatedSnapId,\n assertIsValidSnapId,\n validateSnapShasum,\n VirtualFile,\n logError,\n logWarning,\n} from '@metamask/snaps-utils';\nimport {\n assert,\n Duration,\n gtRange,\n gtVersion,\n hasProperty,\n inMilliseconds,\n isNonEmptyArray,\n isValidSemVerRange,\n Json,\n NonEmptyArray,\n satisfiesVersionRange,\n SemVerRange,\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 { log } from '../logging';\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 {\n GetMetadata,\n GetResult,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryStatus,\n Update,\n} from './registry';\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';\nexport const SNAP_APPROVAL_RESULT = 'wallet_installSnapResult';\n\nconst TRUNCATED_SNAP_PROPERTIES = new Set<TruncatedSnapFields>([\n 'initialPermissions',\n 'id',\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\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 snapStates: Record<SnapId, string | null>;\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 permissions: {\n revoked: unknown;\n granted: unknown[];\n requestData: unknown;\n };\n newVersion: string;\n};\n\ntype PendingApproval = {\n id: string;\n promise: Promise<unknown>;\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 GetRegistryMetadata = {\n type: `${typeof controllerName}:getRegistryMetadata`;\n handler: SnapController['getRegistryMetadata'];\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 | GetRegistryMetadata;\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?: BlockReason];\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 | GetSubjects\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 | UpdateCaveat\n | UpdateRequestState\n | GetResult\n | GetMetadata\n | Update;\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\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 requireAllowlist?: true;\n allowLocalSnaps?: true;\n};\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 * Excluded permissions with its associated error message used to forbid certain permssions.\n */\n excludedPermissions: Record<string, 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 * How frequently to check whether a snap is idle.\n */\n idleTimeCheckInterval?: number;\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: ValidatedSnapId;\n origin: string;\n location: SnapLocation;\n versionRange: SemVerRange;\n};\n\n// When we set a snap, we need all required properties to be present and\n// validated.\ntype SetSnapArgs = Omit<AddSnapArgs, 'location' | 'versionRange'> & {\n manifest: VirtualFile<SnapManifest>;\n files: VirtualFile[];\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 #excludedPermissions: Record<string, string>;\n\n #featureFlags: FeatureFlags;\n\n #fetchFunction: typeof fetch;\n\n #idleTimeCheckInterval: number;\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 #snapsRuntimeData: Map<SnapId, SnapRuntimeData>;\n\n #rollbackSnapshots: Map<SnapId, RollbackSnapshot>;\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 environmentEndowmentPermissions = [],\n excludedPermissions = {},\n idleTimeCheckInterval = inMilliseconds(5, Duration.Second),\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: true,\n anonymous: false,\n },\n snaps: {\n persist: (snaps) => {\n return Object.values(snaps)\n .map((snap) => {\n return {\n ...snap,\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 ...state,\n },\n });\n\n this.#closeAllConnections = closeAllConnections;\n this.#environmentEndowmentPermissions = environmentEndowmentPermissions;\n this.#excludedPermissions = excludedPermissions;\n this.#featureFlags = featureFlags;\n this.#fetchFunction = fetchFunction;\n this.#idleTimeCheckInterval = idleTimeCheckInterval;\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 [SnapStatusEvents.Stop]: SnapStatus.Stopped,\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 [SnapStatusEvents.Update]: SnapStatus.Updating,\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 this.messagingSystem.registerActionHandler(\n `${controllerName}:getRegistryMetadata`,\n async (...args) => this.getRegistryMetadata(...args),\n );\n }\n\n #pollForLastRequestStatus() {\n this.#timeoutForLastRequestStatus = setTimeout(() => {\n this.#stopSnapsLastRequestPastMax().catch((error) => {\n // TODO: Decide how to handle errors.\n logError(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 await this.messagingSystem.call('SnapsRegistry:update');\n\n const blockedSnaps = await this.messagingSystem.call(\n 'SnapsRegistry:get',\n Object.values(this.state.snaps).reduce<SnapsRegistryRequest>(\n (blockListArg, snap) => {\n blockListArg[snap.id] = {\n version: snap.version,\n checksum: snap.manifest.source.shasum,\n };\n return blockListArg;\n },\n {},\n ),\n );\n\n await Promise.all(\n Object.entries(blockedSnaps).map(async ([snapId, { status, reason }]) => {\n if (status === SnapsRegistryStatus.Blocked) {\n return this.#blockSnap(snapId, reason);\n }\n\n return this.#unblockSnap(snapId);\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?: BlockReason,\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 logError(\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 async #assertIsInstallAllowed(\n snapId: ValidatedSnapId,\n snapInfo: SnapsRegistryInfo,\n ) {\n const results = await this.messagingSystem.call('SnapsRegistry:get', {\n [snapId]: snapInfo,\n });\n const result = results[snapId];\n if (result.status === SnapsRegistryStatus.Blocked) {\n throw new Error(\n `Cannot install version \"${\n snapInfo.version\n }\" of snap \"${snapId}\": The version is blocked. ${\n result.reason?.explanation ?? ''\n }`,\n );\n } else if (\n this.#featureFlags.requireAllowlist &&\n result.status !== SnapsRegistryStatus.Verified\n ) {\n throw new Error(\n `Cannot install version \"${snapInfo.version}\" of snap \"${snapId}\": The snap is not on the allow list.`,\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 logError(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 snap = this.state.snaps[snapId];\n\n if (snap.enabled === false) {\n throw new Error(`Snap \"${snapId}\" is disabled.`);\n }\n\n await this.#startSnap({\n snapId,\n sourceCode: snap.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: string): Promise<void> {\n this.update((state) => {\n state.snapStates[snapId] = newSnapState;\n });\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 this.update((state) => {\n state.snapStates[snapId] = null;\n });\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.state.snapStates[snapId];\n return state ?? null;\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 this.#removeSnapFromSubjects(snapId);\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 * Removes a snap's permission (caveat) from all subjects.\n *\n * @param snapId - The id of the Snap.\n */\n #removeSnapFromSubjects(snapId: SnapId) {\n const subjects = this.messagingSystem.call(\n 'PermissionController:getSubjectNames',\n );\n for (const subject of subjects) {\n const subjectPermissions = this.messagingSystem.call(\n 'PermissionController:getPermissions',\n subject,\n ) as SubjectPermissions<PermissionConstraint>;\n const snapIdsCaveat = (subjectPermissions?.[\n WALLET_SNAP_PERMISSION_KEY\n ]?.caveats?.find((caveat) => caveat.type === SnapCaveatType.SnapIds) ??\n {}) as Caveat<string, Json>;\n\n const caveatHasSnap = Boolean(\n (snapIdsCaveat.value as Record<string, unknown>)?.[snapId],\n );\n if (caveatHasSnap) {\n const newCaveatValue = {\n ...(snapIdsCaveat.value as Record<string, unknown>),\n };\n delete newCaveatValue[snapId];\n if (Object.keys(newCaveatValue).length > 0) {\n this.messagingSystem.call(\n 'PermissionController:updateCaveat',\n subject,\n WALLET_SNAP_PERMISSION_KEY,\n SnapCaveatType.SnapIds,\n newCaveatValue,\n );\n } else {\n this.messagingSystem.call('PermissionController:revokePermissions', {\n [subject]: [WALLET_SNAP_PERMISSION_KEY],\n });\n }\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 const permissions =\n this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) ?? {};\n const snaps =\n permissions[WALLET_SNAP_PERMISSION_KEY]?.caveats?.find(\n (caveat) => caveat.type === SnapCaveatType.SnapIds,\n )?.value ?? {};\n return Object.keys(snaps).reduce<InstallSnapsResult>(\n (permittedSnaps, snapId) => {\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 return permittedSnaps;\n },\n {},\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 const pendingUpdates = [];\n const pendingInstalls = [];\n\n try {\n for (const [snapId, { version: rawVersion }] of Object.entries(\n requestedSnaps,\n )) {\n assertIsValidSnapId(snapId);\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 location = this.#detectSnapLocation(snapId, {\n versionRange: version,\n fetch: this.#fetchFunction,\n allowLocal: this.#featureFlags.allowLocalSnaps,\n });\n\n // Existing snaps may need to be updated, unless they should be re-installed (e.g. local snaps)\n // Everything else is treated as an install\n const isUpdate = this.has(snapId) && !location.shouldAlwaysReload;\n\n if (isUpdate && this.#isValidUpdate(snapId, version)) {\n pendingUpdates.push(snapId);\n let rollbackSnapshot = this.#getRollbackSnapshot(snapId);\n if (rollbackSnapshot === undefined) {\n rollbackSnapshot = this.#createRollbackSnapshot(snapId);\n rollbackSnapshot.newVersion = version;\n } else {\n throw new Error('This snap is already being updated.');\n }\n } else if (!isUpdate) {\n pendingInstalls.push(snapId);\n }\n\n result[snapId] = await this.processRequestedSnap(\n origin,\n snapId,\n location,\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 location - The location implementation 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: ValidatedSnapId,\n location: SnapLocation,\n versionRange: SemVerRange,\n ): Promise<ProcessSnapResult> {\n const existingSnap = this.getTruncated(snapId);\n\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 return await this.updateSnap(origin, snapId, location, versionRange);\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 let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_INSTALL,\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 // Existing snaps that should be re-installed should not maintain their existing permissions\n if (existingSnap && location.shouldAlwaysReload) {\n this.revokeAllSnapPermissions(snapId);\n }\n\n try {\n const { sourceCode } = await this.#add({\n origin,\n id: snapId,\n location,\n versionRange,\n });\n\n await this.authorize(snapId, pendingApproval);\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\n\n await this.#startSnap({\n snapId,\n sourceCode,\n });\n\n const truncated = this.getTruncatedExpect(snapId);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n });\n\n this.messagingSystem.publish(`SnapController:snapInstalled`, truncated);\n\n return truncated;\n } catch (error) {\n logError(`Error when adding snap.`, error);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_INSTALL,\n error: error instanceof Error ? error.message : error.toString(),\n });\n\n throw error;\n }\n }\n\n #createApproval({\n origin,\n snapId,\n type,\n }: {\n origin: string;\n snapId: ValidatedSnapId;\n type: string;\n }): PendingApproval {\n const id = nanoid();\n const promise = this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n origin,\n id,\n type,\n requestData: {\n // Mirror previous installation metadata\n metadata: { id, origin: snapId, dappOrigin: origin },\n snapId,\n },\n requestState: {\n loading: true,\n },\n },\n true,\n );\n\n return { id, promise };\n }\n\n #updateApproval(id: string, requestState: Record<string, Json>) {\n try {\n this.messagingSystem.call('ApprovalController:updateRequestState', {\n id,\n requestState,\n });\n } catch {\n // Do nothing\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 location - The location implementation of the snap.\n * @param newVersionRange - A semver version range in which the maximum version will be chosen.\n * @returns The snap metadata if updated, `null` otherwise.\n */\n async updateSnap(\n origin: string,\n snapId: ValidatedSnapId,\n location: SnapLocation,\n newVersionRange: string = DEFAULT_REQUESTED_SNAP_VERSION,\n ): Promise<TruncatedSnap> {\n if (!isValidSemVerRange(newVersionRange)) {\n throw new Error(\n `Received invalid snap version range: \"${newVersionRange}\".`,\n );\n }\n\n let pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n try {\n const snap = this.getExpect(snapId);\n\n const newSnap = await this.#fetchSnap(snapId, location);\n\n const newVersion = newSnap.manifest.result.version;\n if (!gtVersion(newVersion, snap.version)) {\n throw ethErrors.rpc.invalidParams(\n `Snap \"${snapId}@${snap.version}\" is already installed. Couldn't update to a version inside requested \"${newVersionRange}\" range.`,\n );\n }\n\n if (!satisfiesVersionRange(newVersion, newVersionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${newVersion}\" which doesn't satisfy requested version range \"${newVersionRange}\".`,\n );\n }\n\n await this.#assertIsInstallAllowed(snapId, {\n version: newVersion,\n checksum: newSnap.manifest.result.source.shasum,\n });\n\n const processedPermissions = this.#processSnapPermissions(\n newSnap.manifest.result.initialPermissions,\n );\n\n this.#validateSnapPermissions(processedPermissions);\n\n const { newPermissions, unusedPermissions, approvedPermissions } =\n this.#calculatePermissionsChange(snapId, processedPermissions);\n\n this.#updateApproval(pendingApproval.id, {\n permissions: newPermissions,\n newVersion: newSnap.manifest.result.version,\n newPermissions,\n approvedPermissions,\n unusedPermissions,\n loading: false,\n });\n\n const { permissions: approvedNewPermissions, ...requestData } =\n (await pendingApproval.promise) as PermissionsRequest;\n\n pendingApproval = this.#createApproval({\n origin,\n snapId,\n type: SNAP_APPROVAL_RESULT,\n });\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 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 normalizedSourcePath = normalizeRelative(\n newSnap.manifest.result.source.location.npm.filePath,\n );\n\n const sourceCode = newSnap.files\n .find((file) => file.path === normalizedSourcePath)\n ?.toString();\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `Invalid source code for snap \"${snapId}\".`,\n );\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 this.#updateApproval(pendingApproval.id, {\n loading: false,\n type: SNAP_APPROVAL_UPDATE,\n });\n\n return truncatedSnap;\n } catch (error) {\n logError(`Error when updating snap,`, error);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n error: error instanceof Error ? error.message : error.toString(),\n type: SNAP_APPROVAL_UPDATE,\n });\n throw error;\n }\n }\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n async getRegistryMetadata(\n snapId: SnapId,\n ): Promise<SnapsRegistryMetadata | null> {\n return await this.messagingSystem.call('SnapsRegistry:getMetadata', snapId);\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, versionRange } = args;\n\n this.#setupRuntime(snapId, { sourceCode: null, state: null });\n const runtime = this.#getRuntimeExpect(snapId);\n if (!runtime.installPromise) {\n log(`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 const manifest = fetchedSnap.manifest.result;\n assertIsSnapManifest(manifest);\n if (!satisfiesVersionRange(manifest.version, versionRange)) {\n throw new Error(\n `Version mismatch. Manifest for \"${snapId}\" specifies version \"${manifest.version}\" which doesn't satisfy requested version range \"${versionRange}\".`,\n );\n }\n await this.#assertIsInstallAllowed(snapId, {\n version: manifest.version,\n checksum: manifest.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 logError(\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 { id: snapId, origin, manifest, files, isUpdate = false } = args;\n\n assertIsSnapManifest(manifest.result);\n const { version } = manifest.result;\n\n const normalizedSourcePath = normalizeRelative(\n manifest.result.source.location.npm.filePath,\n );\n\n const { iconPath } = manifest.result.source.location.npm;\n const normalizedIconPath = iconPath && normalizeRelative(iconPath);\n\n const sourceCode = files\n .find((file) => file.path === normalizedSourcePath)\n ?.toString();\n\n const svgIcon = normalizedIconPath\n ? files.find((file) => file.path === normalizedIconPath)\n : undefined;\n\n assert(\n typeof sourceCode === 'string' && sourceCode.length > 0,\n `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 id: snapId,\n initialPermissions: manifest.result.initialPermissions,\n manifest: manifest.result,\n status: this.#statusMachine.config.initial as StatusStates['value'],\n sourceCode,\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 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 const { iconPath } = manifest.result.source.location.npm;\n const svgIcon = iconPath ? await location.fetch(iconPath) : undefined;\n\n const files = [sourceCode];\n if (svgIcon) {\n files.push(svgIcon);\n }\n\n validateSnapShasum({ manifest, sourceCode, svgIcon });\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 Object.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 #validateSnapPermissions(\n processedPermissions: Record<string, Pick<PermissionConstraint, 'caveats'>>,\n ) {\n const permissionKeys = Object.keys(processedPermissions);\n\n const handlerPermissions = Object.values(handlerEndowments);\n\n assert(\n permissionKeys.some((key) => handlerPermissions.includes(key)),\n `A snap must request at least one of the following permissions: ${handlerPermissions.join(\n ', ',\n )}.`,\n );\n\n const excludedPermissionErrors = permissionKeys.reduce<string[]>(\n (errors, permission) => {\n if (hasProperty(this.#excludedPermissions, permission)) {\n errors.push(this.#excludedPermissions[permission]);\n }\n\n return errors;\n },\n [],\n );\n\n assert(\n excludedPermissionErrors.length === 0,\n `One or more permissions are not allowed:\\n${excludedPermissionErrors.join(\n '\\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 snapId - The id of the Snap.\n * @param pendingApproval - Pending approval to update.\n * @returns The snap's approvedPermissions.\n */\n private async authorize(\n snapId: SnapId,\n pendingApproval: PendingApproval,\n ): Promise<void> {\n log(`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\n this.#validateSnapPermissions(processedPermissions);\n\n this.#updateApproval(pendingApproval.id, {\n loading: false,\n permissions: processedPermissions,\n });\n\n const { permissions: approvedPermissions, ...requestData } =\n (await pendingApproval.promise) 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 as Record<string, unknown>), 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 logWarning(\n `${SnapEndowments.LongRunning} will soon be deprecated. For more information please see https://github.com/MetaMask/snaps-monorepo/issues/945.`,\n );\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 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 // Always set to stopped even if it wasn't running initially\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.#transition(snapId, SnapStatusEvents.Stop);\n }\n\n const { statePatches, permissions } = rollbackSnapshot;\n\n if (statePatches?.length) {\n this.applyPatches(statePatches);\n }\n\n // Reset snap status, as we may have been in another state when we stored state patches\n // But now we are 100% in a stopped state\n if (this.get(snapId)?.status !== SnapStatus.Stopped) {\n this.update((state) => {\n state.snaps[snapId].status = SnapStatus.Stopped;\n });\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"]}
@@ -24,7 +24,11 @@ export declare type GetMetadata = {
24
24
  type: `${typeof controllerName}:getMetadata`;
25
25
  handler: SnapsRegistry['getMetadata'];
26
26
  };
27
- export declare type SnapsRegistryActions = GetResult | GetMetadata;
27
+ export declare type Update = {
28
+ type: `${typeof controllerName}:update`;
29
+ handler: SnapsRegistry['update'];
30
+ };
31
+ export declare type SnapsRegistryActions = GetResult | GetMetadata | Update;
28
32
  export declare type SnapsRegistryEvents = never;
29
33
  export declare type SnapsRegistryMessenger = RestrictedControllerMessenger<'SnapsRegistry', SnapsRegistryActions, SnapsRegistryEvents, SnapsRegistryActions['type'], SnapsRegistryEvents['type']>;
30
34
  export declare type SnapsRegistryState = {
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _JsonSnapsRegistry_instances, _JsonSnapsRegistry_url, _JsonSnapsRegistry_publicKey, _JsonSnapsRegistry_fetchFunction, _JsonSnapsRegistry_recentFetchThreshold, _JsonSnapsRegistry_refetchOnAllowlistMiss, _JsonSnapsRegistry_failOnUnavailableRegistry, _JsonSnapsRegistry_wasRecentlyFetched, _JsonSnapsRegistry_updateDatabase, _JsonSnapsRegistry_getDatabase, _JsonSnapsRegistry_getSingle, _JsonSnapsRegistry_get, _JsonSnapsRegistry_getMetadata, _JsonSnapsRegistry_verifySignature, _JsonSnapsRegistry_safeFetch;
13
+ var _JsonSnapsRegistry_instances, _JsonSnapsRegistry_url, _JsonSnapsRegistry_publicKey, _JsonSnapsRegistry_fetchFunction, _JsonSnapsRegistry_recentFetchThreshold, _JsonSnapsRegistry_refetchOnAllowlistMiss, _JsonSnapsRegistry_failOnUnavailableRegistry, _JsonSnapsRegistry_wasRecentlyFetched, _JsonSnapsRegistry_update, _JsonSnapsRegistry_getDatabase, _JsonSnapsRegistry_getSingle, _JsonSnapsRegistry_get, _JsonSnapsRegistry_getMetadata, _JsonSnapsRegistry_verifySignature, _JsonSnapsRegistry_safeFetch;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.JsonSnapsRegistry = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
@@ -57,13 +57,14 @@ class JsonSnapsRegistry extends base_controller_1.BaseControllerV2 {
57
57
  __classPrivateFieldSet(this, _JsonSnapsRegistry_failOnUnavailableRegistry, failOnUnavailableRegistry, "f");
58
58
  this.messagingSystem.registerActionHandler('SnapsRegistry:get', async (...args) => __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_get).call(this, ...args));
59
59
  this.messagingSystem.registerActionHandler('SnapsRegistry:getMetadata', async (...args) => __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_getMetadata).call(this, ...args));
60
+ this.messagingSystem.registerActionHandler('SnapsRegistry:update', async () => __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_update).call(this));
60
61
  }
61
62
  }
62
63
  exports.JsonSnapsRegistry = JsonSnapsRegistry;
63
64
  _JsonSnapsRegistry_url = new WeakMap(), _JsonSnapsRegistry_publicKey = new WeakMap(), _JsonSnapsRegistry_fetchFunction = new WeakMap(), _JsonSnapsRegistry_recentFetchThreshold = new WeakMap(), _JsonSnapsRegistry_refetchOnAllowlistMiss = new WeakMap(), _JsonSnapsRegistry_failOnUnavailableRegistry = new WeakMap(), _JsonSnapsRegistry_instances = new WeakSet(), _JsonSnapsRegistry_wasRecentlyFetched = function _JsonSnapsRegistry_wasRecentlyFetched() {
64
65
  return (this.state.lastUpdated &&
65
66
  Date.now() - this.state.lastUpdated < __classPrivateFieldGet(this, _JsonSnapsRegistry_recentFetchThreshold, "f"));
66
- }, _JsonSnapsRegistry_updateDatabase = async function _JsonSnapsRegistry_updateDatabase() {
67
+ }, _JsonSnapsRegistry_update = async function _JsonSnapsRegistry_update() {
67
68
  // No-op if we recently fetched the registry.
68
69
  if (__classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_wasRecentlyFetched).call(this)) {
69
70
  return;
@@ -84,7 +85,7 @@ _JsonSnapsRegistry_url = new WeakMap(), _JsonSnapsRegistry_publicKey = new WeakM
84
85
  }
85
86
  }, _JsonSnapsRegistry_getDatabase = async function _JsonSnapsRegistry_getDatabase() {
86
87
  if (this.state.database === null) {
87
- await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_updateDatabase).call(this);
88
+ await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_update).call(this);
88
89
  }
89
90
  // If the database is still null and we require it, throw.
90
91
  if (__classPrivateFieldGet(this, _JsonSnapsRegistry_failOnUnavailableRegistry, "f") && this.state.database === null) {
@@ -113,7 +114,7 @@ _JsonSnapsRegistry_url = new WeakMap(), _JsonSnapsRegistry_publicKey = new WeakM
113
114
  }
114
115
  // For now, if we have an allowlist miss, we can refetch once and try again.
115
116
  if (__classPrivateFieldGet(this, _JsonSnapsRegistry_refetchOnAllowlistMiss, "f") && !refetch) {
116
- await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_updateDatabase).call(this);
117
+ await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_update).call(this);
117
118
  return __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_getSingle).call(this, snapId, snapInfo, true);
118
119
  }
119
120
  return { status: registry_1.SnapsRegistryStatus.Unverified };
@@ -1 +1 @@
1
- {"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/snaps/registry/json.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { SnapsRegistryDatabase, verify } from '@metamask/snaps-registry';\nimport { SnapId } from '@metamask/snaps-utils';\nimport {\n assert,\n Duration,\n Hex,\n inMilliseconds,\n satisfiesVersionRange,\n} from '@metamask/utils';\n\nimport {\n SnapsRegistry,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryResult,\n SnapsRegistryStatus,\n} from './registry';\n\n// TODO: Replace with a Codefi URL\nconst SNAP_REGISTRY_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/registry.json';\n\nconst SNAP_REGISTRY_SIGNATURE_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/signature.json';\n\ntype JsonSnapsRegistryUrl = {\n registry: string;\n signature: string;\n};\n\nexport type JsonSnapsRegistryArgs = {\n messenger: SnapsRegistryMessenger;\n state?: SnapsRegistryState;\n fetchFunction?: typeof fetch;\n url?: JsonSnapsRegistryUrl;\n recentFetchThreshold?: number;\n refetchOnAllowlistMiss?: boolean;\n failOnUnavailableRegistry?: boolean;\n publicKey?: Hex;\n};\n\nexport type GetResult = {\n type: `${typeof controllerName}:get`;\n handler: SnapsRegistry['get'];\n};\n\nexport type GetMetadata = {\n type: `${typeof controllerName}:getMetadata`;\n handler: SnapsRegistry['getMetadata'];\n};\n\nexport type SnapsRegistryActions = GetResult | GetMetadata;\n\nexport type SnapsRegistryEvents = never;\n\nexport type SnapsRegistryMessenger = RestrictedControllerMessenger<\n 'SnapsRegistry',\n SnapsRegistryActions,\n SnapsRegistryEvents,\n SnapsRegistryActions['type'],\n SnapsRegistryEvents['type']\n>;\n\nexport type SnapsRegistryState = {\n database: SnapsRegistryDatabase | null;\n lastUpdated: number | null;\n};\n\nconst controllerName = 'SnapsRegistry';\n\nconst defaultState = {\n database: null,\n lastUpdated: null,\n};\n\nexport class JsonSnapsRegistry extends BaseController<\n typeof controllerName,\n SnapsRegistryState,\n SnapsRegistryMessenger\n> {\n #url: JsonSnapsRegistryUrl;\n\n #publicKey?: Hex;\n\n #fetchFunction: typeof fetch;\n\n #recentFetchThreshold: number;\n\n #refetchOnAllowlistMiss: boolean;\n\n #failOnUnavailableRegistry: boolean;\n\n constructor({\n messenger,\n state,\n url = {\n registry: SNAP_REGISTRY_URL,\n signature: SNAP_REGISTRY_SIGNATURE_URL,\n },\n publicKey,\n fetchFunction = globalThis.fetch.bind(globalThis),\n recentFetchThreshold = inMilliseconds(5, Duration.Minute),\n failOnUnavailableRegistry = true,\n refetchOnAllowlistMiss = true,\n }: JsonSnapsRegistryArgs) {\n super({\n messenger,\n metadata: {\n database: { persist: true, anonymous: false },\n lastUpdated: { persist: true, anonymous: false },\n },\n name: controllerName,\n state: {\n ...defaultState,\n ...state,\n },\n });\n this.#url = url;\n this.#publicKey = publicKey;\n this.#fetchFunction = fetchFunction;\n this.#recentFetchThreshold = recentFetchThreshold;\n this.#refetchOnAllowlistMiss = refetchOnAllowlistMiss;\n this.#failOnUnavailableRegistry = failOnUnavailableRegistry;\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:get',\n async (...args) => this.#get(...args),\n );\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:getMetadata',\n async (...args) => this.#getMetadata(...args),\n );\n }\n\n #wasRecentlyFetched() {\n return (\n this.state.lastUpdated &&\n Date.now() - this.state.lastUpdated < this.#recentFetchThreshold\n );\n }\n\n async #updateDatabase() {\n // No-op if we recently fetched the registry.\n if (this.#wasRecentlyFetched()) {\n return;\n }\n\n try {\n const database = await this.#safeFetch(this.#url.registry);\n\n if (this.#publicKey) {\n const signature = await this.#safeFetch(this.#url.signature);\n await this.#verifySignature(database, signature);\n }\n\n this.update((state) => {\n state.database = JSON.parse(database);\n state.lastUpdated = Date.now();\n });\n } catch {\n // Ignore\n }\n }\n\n async #getDatabase(): Promise<SnapsRegistryDatabase | null> {\n if (this.state.database === null) {\n await this.#updateDatabase();\n }\n\n // If the database is still null and we require it, throw.\n if (this.#failOnUnavailableRegistry && this.state.database === null) {\n throw new Error('Snaps registry is unavailable, installation blocked.');\n }\n return this.state.database;\n }\n\n async #getSingle(\n snapId: SnapId,\n snapInfo: SnapsRegistryInfo,\n refetch = false,\n ): Promise<SnapsRegistryResult> {\n const database = await this.#getDatabase();\n\n const blockedEntry = database?.blockedSnaps.find((blocked) => {\n if ('id' in blocked) {\n return (\n blocked.id === snapId &&\n satisfiesVersionRange(snapInfo.version, blocked.versionRange)\n );\n }\n\n return blocked.checksum === snapInfo.checksum;\n });\n\n if (blockedEntry) {\n return {\n status: SnapsRegistryStatus.Blocked,\n reason: blockedEntry.reason,\n };\n }\n\n const verified = database?.verifiedSnaps[snapId];\n const version = verified?.versions?.[snapInfo.version];\n if (version && version.checksum === snapInfo.checksum) {\n return { status: SnapsRegistryStatus.Verified };\n }\n // For now, if we have an allowlist miss, we can refetch once and try again.\n if (this.#refetchOnAllowlistMiss && !refetch) {\n await this.#updateDatabase();\n return this.#getSingle(snapId, snapInfo, true);\n }\n return { status: SnapsRegistryStatus.Unverified };\n }\n\n async #get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<SnapId, SnapsRegistryResult>> {\n return Object.entries(snaps).reduce<\n Promise<Record<SnapId, SnapsRegistryResult>>\n >(async (previousPromise, [snapId, snapInfo]) => {\n const result = await this.#getSingle(snapId, snapInfo);\n const acc = await previousPromise;\n acc[snapId] = result;\n return acc;\n }, Promise.resolve({}));\n }\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n async #getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null> {\n const database = await this.#getDatabase();\n return database?.verifiedSnaps[snapId]?.metadata ?? null;\n }\n\n /**\n * Verify the signature of the registry.\n *\n * @param database - The registry database.\n * @param signature - The signature of the registry.\n * @throws If the signature is invalid.\n * @private\n */\n async #verifySignature(database: string, signature: string) {\n assert(this.#publicKey, 'No public key provided.');\n\n const valid = await verify({\n registry: database,\n signature: JSON.parse(signature),\n publicKey: this.#publicKey,\n });\n\n assert(valid, 'Invalid registry signature.');\n }\n\n /**\n * Fetch the given URL, throwing if the response is not OK.\n *\n * @param url - The URL to fetch.\n * @returns The response body.\n * @private\n */\n async #safeFetch(url: string) {\n const response = await this.#fetchFunction(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}.`);\n }\n\n return await response.text();\n }\n}\n"]}
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/snaps/registry/json.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { SnapsRegistryDatabase, verify } from '@metamask/snaps-registry';\nimport { SnapId } from '@metamask/snaps-utils';\nimport {\n assert,\n Duration,\n Hex,\n inMilliseconds,\n satisfiesVersionRange,\n} from '@metamask/utils';\n\nimport {\n SnapsRegistry,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryResult,\n SnapsRegistryStatus,\n} from './registry';\n\n// TODO: Replace with a Codefi URL\nconst SNAP_REGISTRY_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/registry.json';\n\nconst SNAP_REGISTRY_SIGNATURE_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/signature.json';\n\ntype JsonSnapsRegistryUrl = {\n registry: string;\n signature: string;\n};\n\nexport type JsonSnapsRegistryArgs = {\n messenger: SnapsRegistryMessenger;\n state?: SnapsRegistryState;\n fetchFunction?: typeof fetch;\n url?: JsonSnapsRegistryUrl;\n recentFetchThreshold?: number;\n refetchOnAllowlistMiss?: boolean;\n failOnUnavailableRegistry?: boolean;\n publicKey?: Hex;\n};\n\nexport type GetResult = {\n type: `${typeof controllerName}:get`;\n handler: SnapsRegistry['get'];\n};\n\nexport type GetMetadata = {\n type: `${typeof controllerName}:getMetadata`;\n handler: SnapsRegistry['getMetadata'];\n};\n\nexport type Update = {\n type: `${typeof controllerName}:update`;\n handler: SnapsRegistry['update'];\n};\n\nexport type SnapsRegistryActions = GetResult | GetMetadata | Update;\n\nexport type SnapsRegistryEvents = never;\n\nexport type SnapsRegistryMessenger = RestrictedControllerMessenger<\n 'SnapsRegistry',\n SnapsRegistryActions,\n SnapsRegistryEvents,\n SnapsRegistryActions['type'],\n SnapsRegistryEvents['type']\n>;\n\nexport type SnapsRegistryState = {\n database: SnapsRegistryDatabase | null;\n lastUpdated: number | null;\n};\n\nconst controllerName = 'SnapsRegistry';\n\nconst defaultState = {\n database: null,\n lastUpdated: null,\n};\n\nexport class JsonSnapsRegistry extends BaseController<\n typeof controllerName,\n SnapsRegistryState,\n SnapsRegistryMessenger\n> {\n #url: JsonSnapsRegistryUrl;\n\n #publicKey?: Hex;\n\n #fetchFunction: typeof fetch;\n\n #recentFetchThreshold: number;\n\n #refetchOnAllowlistMiss: boolean;\n\n #failOnUnavailableRegistry: boolean;\n\n constructor({\n messenger,\n state,\n url = {\n registry: SNAP_REGISTRY_URL,\n signature: SNAP_REGISTRY_SIGNATURE_URL,\n },\n publicKey,\n fetchFunction = globalThis.fetch.bind(globalThis),\n recentFetchThreshold = inMilliseconds(5, Duration.Minute),\n failOnUnavailableRegistry = true,\n refetchOnAllowlistMiss = true,\n }: JsonSnapsRegistryArgs) {\n super({\n messenger,\n metadata: {\n database: { persist: true, anonymous: false },\n lastUpdated: { persist: true, anonymous: false },\n },\n name: controllerName,\n state: {\n ...defaultState,\n ...state,\n },\n });\n this.#url = url;\n this.#publicKey = publicKey;\n this.#fetchFunction = fetchFunction;\n this.#recentFetchThreshold = recentFetchThreshold;\n this.#refetchOnAllowlistMiss = refetchOnAllowlistMiss;\n this.#failOnUnavailableRegistry = failOnUnavailableRegistry;\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:get',\n async (...args) => this.#get(...args),\n );\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:getMetadata',\n async (...args) => this.#getMetadata(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:update',\n async () => this.#update(),\n );\n }\n\n #wasRecentlyFetched() {\n return (\n this.state.lastUpdated &&\n Date.now() - this.state.lastUpdated < this.#recentFetchThreshold\n );\n }\n\n async #update() {\n // No-op if we recently fetched the registry.\n if (this.#wasRecentlyFetched()) {\n return;\n }\n\n try {\n const database = await this.#safeFetch(this.#url.registry);\n\n if (this.#publicKey) {\n const signature = await this.#safeFetch(this.#url.signature);\n await this.#verifySignature(database, signature);\n }\n\n this.update((state) => {\n state.database = JSON.parse(database);\n state.lastUpdated = Date.now();\n });\n } catch {\n // Ignore\n }\n }\n\n async #getDatabase(): Promise<SnapsRegistryDatabase | null> {\n if (this.state.database === null) {\n await this.#update();\n }\n\n // If the database is still null and we require it, throw.\n if (this.#failOnUnavailableRegistry && this.state.database === null) {\n throw new Error('Snaps registry is unavailable, installation blocked.');\n }\n return this.state.database;\n }\n\n async #getSingle(\n snapId: SnapId,\n snapInfo: SnapsRegistryInfo,\n refetch = false,\n ): Promise<SnapsRegistryResult> {\n const database = await this.#getDatabase();\n\n const blockedEntry = database?.blockedSnaps.find((blocked) => {\n if ('id' in blocked) {\n return (\n blocked.id === snapId &&\n satisfiesVersionRange(snapInfo.version, blocked.versionRange)\n );\n }\n\n return blocked.checksum === snapInfo.checksum;\n });\n\n if (blockedEntry) {\n return {\n status: SnapsRegistryStatus.Blocked,\n reason: blockedEntry.reason,\n };\n }\n\n const verified = database?.verifiedSnaps[snapId];\n const version = verified?.versions?.[snapInfo.version];\n if (version && version.checksum === snapInfo.checksum) {\n return { status: SnapsRegistryStatus.Verified };\n }\n // For now, if we have an allowlist miss, we can refetch once and try again.\n if (this.#refetchOnAllowlistMiss && !refetch) {\n await this.#update();\n return this.#getSingle(snapId, snapInfo, true);\n }\n return { status: SnapsRegistryStatus.Unverified };\n }\n\n async #get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<SnapId, SnapsRegistryResult>> {\n return Object.entries(snaps).reduce<\n Promise<Record<SnapId, SnapsRegistryResult>>\n >(async (previousPromise, [snapId, snapInfo]) => {\n const result = await this.#getSingle(snapId, snapInfo);\n const acc = await previousPromise;\n acc[snapId] = result;\n return acc;\n }, Promise.resolve({}));\n }\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n async #getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null> {\n const database = await this.#getDatabase();\n return database?.verifiedSnaps[snapId]?.metadata ?? null;\n }\n\n /**\n * Verify the signature of the registry.\n *\n * @param database - The registry database.\n * @param signature - The signature of the registry.\n * @throws If the signature is invalid.\n * @private\n */\n async #verifySignature(database: string, signature: string) {\n assert(this.#publicKey, 'No public key provided.');\n\n const valid = await verify({\n registry: database,\n signature: JSON.parse(signature),\n publicKey: this.#publicKey,\n });\n\n assert(valid, 'Invalid registry signature.');\n }\n\n /**\n * Fetch the given URL, throwing if the response is not OK.\n *\n * @param url - The URL to fetch.\n * @returns The response body.\n * @private\n */\n async #safeFetch(url: string) {\n const response = await this.#fetchFunction(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}.`);\n }\n\n return await response.text();\n }\n}\n"]}
@@ -18,6 +18,7 @@ export declare type SnapsRegistryResult = {
18
18
  };
19
19
  export declare type SnapsRegistry = {
20
20
  get(snaps: SnapsRegistryRequest): Promise<Record<SnapId, SnapsRegistryResult>>;
21
+ update(): Promise<void>;
21
22
  /**
22
23
  * Get metadata for the given snap ID.
23
24
  *
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/snaps/registry/registry.ts"],"names":[],"mappings":";;;AASA,kCAAkC;AAClC,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,yEAAU,CAAA;IACV,mEAAO,CAAA;IACP,qEAAQ,CAAA;AACV,CAAC,EAJW,mBAAmB,GAAnB,2BAAmB,KAAnB,2BAAmB,QAI9B","sourcesContent":["import { BlockReason, SnapsRegistryDatabase } from '@metamask/snaps-registry';\nimport { SnapId } from '@metamask/snaps-utils';\nimport { SemVerVersion } from '@metamask/utils';\n\nexport type SnapsRegistryInfo = { version: SemVerVersion; checksum: string };\nexport type SnapsRegistryRequest = Record<SnapId, SnapsRegistryInfo>;\nexport type SnapsRegistryMetadata =\n SnapsRegistryDatabase['verifiedSnaps'][SnapId]['metadata'];\n\n// TODO: Decide on names for these\nexport enum SnapsRegistryStatus {\n Unverified,\n Blocked,\n Verified,\n}\n\nexport type SnapsRegistryResult = {\n status: SnapsRegistryStatus;\n reason?: BlockReason;\n};\n\nexport type SnapsRegistry = {\n get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<SnapId, SnapsRegistryResult>>;\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null>;\n};\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/snaps/registry/registry.ts"],"names":[],"mappings":";;;AASA,kCAAkC;AAClC,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,yEAAU,CAAA;IACV,mEAAO,CAAA;IACP,qEAAQ,CAAA;AACV,CAAC,EAJW,mBAAmB,GAAnB,2BAAmB,KAAnB,2BAAmB,QAI9B","sourcesContent":["import { BlockReason, SnapsRegistryDatabase } from '@metamask/snaps-registry';\nimport { SnapId } from '@metamask/snaps-utils';\nimport { SemVerVersion } from '@metamask/utils';\n\nexport type SnapsRegistryInfo = { version: SemVerVersion; checksum: string };\nexport type SnapsRegistryRequest = Record<SnapId, SnapsRegistryInfo>;\nexport type SnapsRegistryMetadata =\n SnapsRegistryDatabase['verifiedSnaps'][SnapId]['metadata'];\n\n// TODO: Decide on names for these\nexport enum SnapsRegistryStatus {\n Unverified,\n Blocked,\n Verified,\n}\n\nexport type SnapsRegistryResult = {\n status: SnapsRegistryStatus;\n reason?: BlockReason;\n};\n\nexport type SnapsRegistry = {\n get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<SnapId, SnapsRegistryResult>>;\n\n update(): Promise<void>;\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null>;\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/snaps-controllers",
3
- "version": "1.0.0-prerelease.1",
3
+ "version": "1.0.0",
4
4
  "description": "Controllers for MetaMask Snaps.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,10 +39,10 @@
39
39
  "@metamask/object-multiplex": "^1.2.0",
40
40
  "@metamask/permission-controller": "^4.0.0",
41
41
  "@metamask/post-message-stream": "^6.1.2",
42
- "@metamask/rpc-methods": "^1.0.0-prerelease.1",
43
- "@metamask/snaps-execution-environments": "^1.0.0-prerelease.1",
42
+ "@metamask/rpc-methods": "^1.0.0",
43
+ "@metamask/snaps-execution-environments": "^1.0.0",
44
44
  "@metamask/snaps-registry": "^1.2.1",
45
- "@metamask/snaps-utils": "^1.0.0-prerelease.1",
45
+ "@metamask/snaps-utils": "^1.0.0",
46
46
  "@metamask/utils": "^6.0.1",
47
47
  "@xstate/fsm": "^2.0.0",
48
48
  "concat-stream": "^2.0.0",