@metamask/snaps-controllers 3.0.0 → 3.1.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/dist/cjs/cronjob/CronjobController.js +1 -1
  3. package/dist/cjs/cronjob/CronjobController.js.map +1 -1
  4. package/dist/cjs/services/AbstractExecutionService.js +6 -7
  5. package/dist/cjs/services/AbstractExecutionService.js.map +1 -1
  6. package/dist/cjs/snaps/SnapController.js +73 -82
  7. package/dist/cjs/snaps/SnapController.js.map +1 -1
  8. package/dist/cjs/snaps/endowments/cronjob.js +4 -4
  9. package/dist/cjs/snaps/endowments/cronjob.js.map +1 -1
  10. package/dist/cjs/snaps/endowments/keyring.js +4 -4
  11. package/dist/cjs/snaps/endowments/keyring.js.map +1 -1
  12. package/dist/cjs/snaps/endowments/name-lookup.js +3 -3
  13. package/dist/cjs/snaps/endowments/name-lookup.js.map +1 -1
  14. package/dist/cjs/snaps/endowments/rpc.js +4 -4
  15. package/dist/cjs/snaps/endowments/rpc.js.map +1 -1
  16. package/dist/cjs/snaps/endowments/transaction-insight.js +3 -3
  17. package/dist/cjs/snaps/endowments/transaction-insight.js.map +1 -1
  18. package/dist/cjs/snaps/location/npm.js +41 -14
  19. package/dist/cjs/snaps/location/npm.js.map +1 -1
  20. package/dist/cjs/snaps/permissions.js +5 -5
  21. package/dist/cjs/snaps/permissions.js.map +1 -1
  22. package/dist/cjs/snaps/registry/json.js +30 -1
  23. package/dist/cjs/snaps/registry/json.js.map +1 -1
  24. package/dist/cjs/snaps/registry/registry.js.map +1 -1
  25. package/dist/esm/cronjob/CronjobController.js +1 -1
  26. package/dist/esm/cronjob/CronjobController.js.map +1 -1
  27. package/dist/esm/services/AbstractExecutionService.js +6 -7
  28. package/dist/esm/services/AbstractExecutionService.js.map +1 -1
  29. package/dist/esm/snaps/SnapController.js +70 -79
  30. package/dist/esm/snaps/SnapController.js.map +1 -1
  31. package/dist/esm/snaps/endowments/cronjob.js +4 -4
  32. package/dist/esm/snaps/endowments/cronjob.js.map +1 -1
  33. package/dist/esm/snaps/endowments/keyring.js +4 -4
  34. package/dist/esm/snaps/endowments/keyring.js.map +1 -1
  35. package/dist/esm/snaps/endowments/name-lookup.js +3 -3
  36. package/dist/esm/snaps/endowments/name-lookup.js.map +1 -1
  37. package/dist/esm/snaps/endowments/rpc.js +4 -4
  38. package/dist/esm/snaps/endowments/rpc.js.map +1 -1
  39. package/dist/esm/snaps/endowments/transaction-insight.js +3 -3
  40. package/dist/esm/snaps/endowments/transaction-insight.js.map +1 -1
  41. package/dist/esm/snaps/location/npm.js +42 -15
  42. package/dist/esm/snaps/location/npm.js.map +1 -1
  43. package/dist/esm/snaps/permissions.js +1 -1
  44. package/dist/esm/snaps/permissions.js.map +1 -1
  45. package/dist/esm/snaps/registry/json.js +31 -2
  46. package/dist/esm/snaps/registry/json.js.map +1 -1
  47. package/dist/esm/snaps/registry/registry.js.map +1 -1
  48. package/dist/types/cronjob/CronjobController.d.ts +1 -1
  49. package/dist/types/services/AbstractExecutionService.d.ts +1 -1
  50. package/dist/types/snaps/SnapController.d.ts +20 -32
  51. package/dist/types/snaps/location/npm.d.ts +1 -1
  52. package/dist/types/snaps/registry/json.d.ts +5 -1
  53. package/dist/types/snaps/registry/registry.d.ts +11 -1
  54. package/package.json +29 -22
@@ -27,11 +27,11 @@ _export(exports, {
27
27
  });
28
28
  const _basecontroller = require("@metamask/base-controller");
29
29
  const _permissioncontroller = require("@metamask/permission-controller");
30
- const _rpcmethods = require("@metamask/rpc-methods");
30
+ const _rpcerrors = require("@metamask/rpc-errors");
31
+ const _snapsrpcmethods = require("@metamask/snaps-rpc-methods");
31
32
  const _snapsutils = require("@metamask/snaps-utils");
32
33
  const _utils = require("@metamask/utils");
33
34
  const _fsm = require("@xstate/fsm");
34
- const _ethrpcerrors = require("eth-rpc-errors");
35
35
  const _nanoid = require("nanoid");
36
36
  const _fsm1 = require("../fsm");
37
37
  const _logging = require("../logging");
@@ -119,7 +119,6 @@ const TRUNCATED_SNAP_PROPERTIES = new Set([
119
119
  'blocked'
120
120
  ]);
121
121
  const defaultState = {
122
- snapErrors: {},
123
122
  snaps: {},
124
123
  snapStates: {}
125
124
  };
@@ -175,7 +174,7 @@ _initializeStateMachine = /*#__PURE__*/ new WeakSet(), /**
175
174
  * Safely revokes all permissions granted to a Snap.
176
175
  *
177
176
  * @param snapId - The snap ID.
178
- */ _revokeAllSnapPermissions = /*#__PURE__*/ new WeakSet(), _createApproval = /*#__PURE__*/ new WeakSet(), _updateApproval = /*#__PURE__*/ new WeakSet(), _add = /*#__PURE__*/ new WeakSet(), _startSnap = /*#__PURE__*/ new WeakSet(), _getEndowments = /*#__PURE__*/ new WeakSet(), /**
177
+ */ _revokeAllSnapPermissions = /*#__PURE__*/ new WeakSet(), _createApproval = /*#__PURE__*/ new WeakSet(), _updateApproval = /*#__PURE__*/ new WeakSet(), _resolveAllowlistVersion = /*#__PURE__*/ new WeakSet(), _add = /*#__PURE__*/ new WeakSet(), _startSnap = /*#__PURE__*/ new WeakSet(), _getEndowments = /*#__PURE__*/ new WeakSet(), /**
179
178
  * Sets a snap in state. Called when a snap is installed or updated. Performs
180
179
  * various validation checks on the received arguments, and will throw if
181
180
  * validation fails.
@@ -241,8 +240,8 @@ class SnapController extends _basecontroller.BaseControllerV2 {
241
240
  return _class_private_method_get(this, _unblockSnap, unblockSnap).call(this, snapId);
242
241
  }));
243
242
  }
244
- _onUnhandledSnapError(snapId, error) {
245
- this.stopSnap(snapId, _snapsutils.SnapStatusEvents.Crash).then(()=>this.addSnapError(error)).catch((stopSnapError)=>{
243
+ _onUnhandledSnapError(snapId, _error) {
244
+ this.stopSnap(snapId, _snapsutils.SnapStatusEvents.Crash).catch((stopSnapError)=>{
246
245
  // TODO: Decide how to handle errors.
247
246
  (0, _snapsutils.logError)(stopSnapError);
248
247
  });
@@ -418,35 +417,6 @@ class SnapController extends _basecontroller.BaseControllerV2 {
418
417
  });
419
418
  }
420
419
  /**
421
- * Adds error from a snap to the SnapController state.
422
- *
423
- * @param snapError - The error to store on the SnapController.
424
- */ addSnapError(snapError) {
425
- this.update((state)=>{
426
- const id = (0, _nanoid.nanoid)();
427
- state.snapErrors[id] = {
428
- ...snapError,
429
- internalID: id
430
- };
431
- });
432
- }
433
- /**
434
- * Removes an error by internalID from the SnapControllers state.
435
- *
436
- * @param internalID - The internal error ID to remove on the SnapController.
437
- */ removeSnapError(internalID) {
438
- this.update((state)=>{
439
- delete state.snapErrors[internalID];
440
- });
441
- }
442
- /**
443
- * Clears all errors from the SnapControllers state.
444
- */ clearSnapErrors() {
445
- this.update((state)=>{
446
- state.snapErrors = {};
447
- });
448
- }
449
- /**
450
420
  * Gets the own state of the snap with the given id.
451
421
  * This is distinct from the state MetaMask uses to manage snaps.
452
422
  *
@@ -458,6 +428,22 @@ class SnapController extends _basecontroller.BaseControllerV2 {
458
428
  return state ?? null;
459
429
  }
460
430
  /**
431
+ * Gets a static auxiliary snap file in a chosen file encoding.
432
+ *
433
+ * @param snapId - The id of the Snap whose state to get.
434
+ * @param path - The path to the requested file.
435
+ * @param encoding - An optional requested file encoding.
436
+ * @returns The file requested in the chosen file encoding or null if the file is not found.
437
+ */ getSnapFile(snapId, path, encoding = _snapsutils.AuxiliaryFileEncoding.Base64) {
438
+ const snap = this.getExpect(snapId);
439
+ const normalizedPath = (0, _snapsutils.normalizeRelative)(path);
440
+ const value = snap.auxiliaryFiles?.find((file)=>file.path === normalizedPath)?.value;
441
+ if (!value) {
442
+ return null;
443
+ }
444
+ return (0, _snapsutils.encodeAuxiliaryFile)(value, encoding);
445
+ }
446
+ /**
461
447
  * Completely clear the controller's state: delete all associated data,
462
448
  * handlers, event listeners, and permissions; tear down all snap providers.
463
449
  */ async clearState() {
@@ -520,7 +506,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
520
506
  * @param snapId - The id of the snap to remove.
521
507
  */ removeSnapFromSubject(origin, snapId) {
522
508
  const subjectPermissions = this.messagingSystem.call('PermissionController:getPermissions', origin);
523
- const snapIdsCaveat = subjectPermissions?.[_rpcmethods.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat)=>caveat.type === _snapsutils.SnapCaveatType.SnapIds);
509
+ const snapIdsCaveat = subjectPermissions?.[_snapsrpcmethods.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat)=>caveat.type === _snapsutils.SnapCaveatType.SnapIds);
524
510
  if (!snapIdsCaveat) {
525
511
  return;
526
512
  }
@@ -531,11 +517,11 @@ class SnapController extends _basecontroller.BaseControllerV2 {
531
517
  };
532
518
  delete newCaveatValue[snapId];
533
519
  if (Object.keys(newCaveatValue).length > 0) {
534
- this.messagingSystem.call('PermissionController:updateCaveat', origin, _rpcmethods.WALLET_SNAP_PERMISSION_KEY, _snapsutils.SnapCaveatType.SnapIds, newCaveatValue);
520
+ this.messagingSystem.call('PermissionController:updateCaveat', origin, _snapsrpcmethods.WALLET_SNAP_PERMISSION_KEY, _snapsutils.SnapCaveatType.SnapIds, newCaveatValue);
535
521
  } else {
536
522
  this.messagingSystem.call('PermissionController:revokePermissions', {
537
523
  [origin]: [
538
- _rpcmethods.WALLET_SNAP_PERMISSION_KEY
524
+ _snapsrpcmethods.WALLET_SNAP_PERMISSION_KEY
539
525
  ]
540
526
  });
541
527
  }
@@ -584,7 +570,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
584
570
  * @returns The serialized permitted snaps for the origin.
585
571
  */ getPermittedSnaps(origin) {
586
572
  const permissions = this.messagingSystem.call('PermissionController:getPermissions', origin) ?? {};
587
- const snaps = permissions[_rpcmethods.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat)=>caveat.type === _snapsutils.SnapCaveatType.SnapIds)?.value ?? {};
573
+ const snaps = permissions[_snapsrpcmethods.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat)=>caveat.type === _snapsutils.SnapCaveatType.SnapIds)?.value ?? {};
588
574
  return Object.keys(snaps).reduce((permittedSnaps, snapId)=>{
589
575
  const snap = this.get(snapId);
590
576
  const truncatedSnap = this.getTruncated(snapId);
@@ -611,10 +597,12 @@ class SnapController extends _basecontroller.BaseControllerV2 {
611
597
  try {
612
598
  for (const [snapId, { version: rawVersion }] of Object.entries(requestedSnaps)){
613
599
  (0, _snapsutils.assertIsValidSnapId)(snapId);
614
- const [error, version] = (0, _snapsutils.resolveVersionRange)(rawVersion);
600
+ const [error, resolvedVersion] = (0, _snapsutils.resolveVersionRange)(rawVersion);
615
601
  if (error) {
616
- throw _ethrpcerrors.ethErrors.rpc.invalidParams(`The "version" field must be a valid SemVer version range if specified. Received: "${rawVersion}".`);
602
+ throw _rpcerrors.rpcErrors.invalidParams(`The "version" field must be a valid SemVer version range if specified. Received: "${rawVersion}".`);
617
603
  }
604
+ // If we are running in allowlist mode, try to match the version with an allowlist version.
605
+ const version = _class_private_field_get(this, _featureFlags).requireAllowlist ? await _class_private_method_get(this, _resolveAllowlistVersion, resolveAllowlistVersion).call(this, snapId, resolvedVersion) : resolvedVersion;
618
606
  const location = _class_private_field_get(this, _detectSnapLocation).call(this, snapId, {
619
607
  versionRange: version,
620
608
  fetch: _class_private_field_get(this, _fetchFunction),
@@ -642,8 +630,8 @@ class SnapController extends _basecontroller.BaseControllerV2 {
642
630
  result[snapId] = await this.processRequestedSnap(origin, snapId, location, version);
643
631
  }
644
632
  // Once we finish all installs / updates, emit events.
645
- pendingInstalls.forEach((snapId)=>this.messagingSystem.publish(`SnapController:snapInstalled`, this.getTruncatedExpect(snapId)));
646
- pendingUpdates.forEach(({ snapId, oldVersion })=>this.messagingSystem.publish(`SnapController:snapUpdated`, this.getTruncatedExpect(snapId), oldVersion));
633
+ pendingInstalls.forEach((snapId)=>this.messagingSystem.publish(`SnapController:snapInstalled`, this.getTruncatedExpect(snapId), origin));
634
+ pendingUpdates.forEach(({ snapId, oldVersion })=>this.messagingSystem.publish(`SnapController:snapUpdated`, this.getTruncatedExpect(snapId), oldVersion, origin));
647
635
  snapIds.forEach((snapId)=>_class_private_field_get(this, _rollbackSnapshots).delete(snapId));
648
636
  } catch (error) {
649
637
  const installed = pendingInstalls.filter((snapId)=>this.has(snapId));
@@ -676,7 +664,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
676
664
  return await this.updateSnap(origin, snapId, location, versionRange, // Since we are requesting an update from within processRequestedSnap,
677
665
  // we disable the emitting of the snapUpdated event and rely on the caller
678
666
  // to publish this event after the update is complete.
679
- // This is necesary as installSnaps may be installing multiple snaps
667
+ // This is necessary as installSnaps may be installing multiple snaps
680
668
  // and we don't want to emit events prematurely.
681
669
  false);
682
670
  }
@@ -756,23 +744,25 @@ class SnapController extends _basecontroller.BaseControllerV2 {
756
744
  try {
757
745
  const snap = this.getExpect(snapId);
758
746
  const newSnap = await _class_private_method_get(this, _fetchSnap, fetchSnap).call(this, snapId, location);
759
- const newVersion = newSnap.manifest.result.version;
747
+ const { sourceCode: sourceCodeFile, manifest: manifestFile } = newSnap.files;
748
+ const manifest = manifestFile.result;
749
+ const newVersion = manifest.version;
760
750
  if (!(0, _utils.gtVersion)(newVersion, snap.version)) {
761
- throw _ethrpcerrors.ethErrors.rpc.invalidParams(`Snap "${snapId}@${snap.version}" is already installed. Couldn't update to a version inside requested "${newVersionRange}" range.`);
751
+ throw _rpcerrors.rpcErrors.invalidParams(`Snap "${snapId}@${snap.version}" is already installed. Couldn't update to a version inside requested "${newVersionRange}" range.`);
762
752
  }
763
753
  if (!(0, _utils.satisfiesVersionRange)(newVersion, newVersionRange)) {
764
754
  throw new Error(`Version mismatch. Manifest for "${snapId}" specifies version "${newVersion}" which doesn't satisfy requested version range "${newVersionRange}".`);
765
755
  }
766
756
  await _class_private_method_get(this, _assertIsInstallAllowed, assertIsInstallAllowed).call(this, snapId, {
767
757
  version: newVersion,
768
- checksum: newSnap.manifest.result.source.shasum
758
+ checksum: manifest.source.shasum
769
759
  });
770
- const processedPermissions = (0, _permissions.processSnapPermissions)(newSnap.manifest.result.initialPermissions);
760
+ const processedPermissions = (0, _permissions.processSnapPermissions)(manifest.initialPermissions);
771
761
  _class_private_method_get(this, _validateSnapPermissions, validateSnapPermissions).call(this, processedPermissions);
772
762
  const { newPermissions, unusedPermissions, approvedPermissions } = _class_private_method_get(this, _calculatePermissionsChange, calculatePermissionsChange).call(this, snapId, processedPermissions);
773
763
  _class_private_method_get(this, _updateApproval, updateApproval).call(this, pendingApproval.id, {
774
764
  permissions: newPermissions,
775
- newVersion: newSnap.manifest.result.version,
765
+ newVersion: manifest.version,
776
766
  newPermissions,
777
767
  approvedPermissions,
778
768
  unusedPermissions,
@@ -791,7 +781,6 @@ class SnapController extends _basecontroller.BaseControllerV2 {
791
781
  _class_private_method_get(this, _set, set).call(this, {
792
782
  origin,
793
783
  id: snapId,
794
- manifest: newSnap.manifest,
795
784
  files: newSnap.files,
796
785
  isUpdate: true
797
786
  });
@@ -816,8 +805,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
816
805
  rollbackSnapshot.permissions.granted = Object.keys(approvedNewPermissions);
817
806
  rollbackSnapshot.permissions.requestData = requestData;
818
807
  }
819
- const normalizedSourcePath = (0, _snapsutils.normalizeRelative)(newSnap.manifest.result.source.location.npm.filePath);
820
- const sourceCode = newSnap.files.find((file)=>file.path === normalizedSourcePath)?.toString();
808
+ const sourceCode = sourceCodeFile.toString();
821
809
  (0, _utils.assert)(typeof sourceCode === 'string' && sourceCode.length > 0, `Invalid source code for snap "${snapId}".`);
822
810
  try {
823
811
  await _class_private_method_get(this, _startSnap, startSnap).call(this, {
@@ -829,7 +817,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
829
817
  }
830
818
  const truncatedSnap = this.getTruncatedExpect(snapId);
831
819
  if (emitEvent) {
832
- this.messagingSystem.publish('SnapController:snapUpdated', truncatedSnap, snap.version);
820
+ this.messagingSystem.publish('SnapController:snapUpdated', truncatedSnap, snap.version, origin);
833
821
  }
834
822
  _class_private_method_get(this, _updateApproval, updateApproval).call(this, pendingApproval.id, {
835
823
  loading: false,
@@ -899,6 +887,8 @@ class SnapController extends _basecontroller.BaseControllerV2 {
899
887
  /* eslint-disable @typescript-eslint/unbound-method */ this.messagingSystem.unsubscribe('ExecutionService:unhandledError', this._onUnhandledSnapError);
900
888
  this.messagingSystem.unsubscribe('ExecutionService:outboundRequest', this._onOutboundRequest);
901
889
  this.messagingSystem.unsubscribe('ExecutionService:outboundResponse', this._onOutboundResponse);
890
+ this.messagingSystem.clearEventSubscriptions('SnapController:snapInstalled');
891
+ this.messagingSystem.clearEventSubscriptions('SnapController:snapUpdated');
902
892
  /* eslint-enable @typescript-eslint/unbound-method */ }
903
893
  /**
904
894
  * Passes a JSON-RPC request object to the RPC handler function of a snap.
@@ -948,17 +938,15 @@ class SnapController extends _basecontroller.BaseControllerV2 {
948
938
  super({
949
939
  messenger,
950
940
  metadata: {
951
- snapErrors: {
952
- persist: false,
953
- anonymous: false
954
- },
955
941
  snapStates: {
956
942
  persist: true,
957
943
  anonymous: false
958
944
  },
959
945
  snaps: {
960
946
  persist: (snaps)=>{
961
- return Object.values(snaps).map((snap)=>{
947
+ return Object.values(snaps)// We should not persist snaps that are in the installing state,
948
+ // since they haven't completed installation and would be unusable
949
+ .filter((snap)=>snap.status !== _snapsutils.SnapStatus.Installing).map((snap)=>{
962
950
  return {
963
951
  ...snap,
964
952
  // At the time state is rehydrated, no snap will be running.
@@ -1001,6 +989,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
1001
989
  _class_private_method_init(this, _revokeAllSnapPermissions);
1002
990
  _class_private_method_init(this, _createApproval);
1003
991
  _class_private_method_init(this, _updateApproval);
992
+ _class_private_method_init(this, _resolveAllowlistVersion);
1004
993
  /**
1005
994
  * Returns a promise representing the complete installation of the requested snap.
1006
995
  * If the snap is already being installed, the previously pending promise will be returned.
@@ -1026,8 +1015,6 @@ class SnapController extends _basecontroller.BaseControllerV2 {
1026
1015
  /**
1027
1016
  * Fetches the manifest and source code of a snap.
1028
1017
  *
1029
- * This function is not hash private yet because of tests.
1030
- *
1031
1018
  * @param snapId - The id of the Snap.
1032
1019
  * @param location - Source from which snap will be fetched.
1033
1020
  * @returns A tuple of the Snap manifest object and the Snap source code.
@@ -1236,13 +1223,13 @@ function registerMessageHandlers() {
1236
1223
  this.messagingSystem.registerActionHandler(`${controllerName}:remove`, async (...args)=>this.removeSnap(...args));
1237
1224
  this.messagingSystem.registerActionHandler(`${controllerName}:getPermitted`, (...args)=>this.getPermittedSnaps(...args));
1238
1225
  this.messagingSystem.registerActionHandler(`${controllerName}:install`, async (...args)=>this.installSnaps(...args));
1239
- this.messagingSystem.registerActionHandler(`${controllerName}:removeSnapError`, (...args)=>this.removeSnapError(...args));
1240
1226
  this.messagingSystem.registerActionHandler(`${controllerName}:getAll`, (...args)=>this.getAllSnaps(...args));
1241
1227
  this.messagingSystem.registerActionHandler(`${controllerName}:incrementActiveReferences`, (...args)=>this.incrementActiveReferences(...args));
1242
1228
  this.messagingSystem.registerActionHandler(`${controllerName}:decrementActiveReferences`, (...args)=>this.decrementActiveReferences(...args));
1243
1229
  this.messagingSystem.registerActionHandler(`${controllerName}:getRegistryMetadata`, async (...args)=>this.getRegistryMetadata(...args));
1244
1230
  this.messagingSystem.registerActionHandler(`${controllerName}:disconnectOrigin`, (...args)=>this.removeSnapFromSubject(...args));
1245
1231
  this.messagingSystem.registerActionHandler(`${controllerName}:revokeDynamicPermissions`, (...args)=>this.revokeDynamicSnapPermissions(...args));
1232
+ this.messagingSystem.registerActionHandler(`${controllerName}:getFile`, (...args)=>this.getSnapFile(...args));
1246
1233
  }
1247
1234
  function pollForLastRequestStatus() {
1248
1235
  _class_private_field_set(this, _timeoutForLastRequestStatus, setTimeout(()=>{
@@ -1286,7 +1273,7 @@ async function assertIsInstallAllowed(snapId, snapInfo) {
1286
1273
  if (result.status === _registry.SnapsRegistryStatus.Blocked) {
1287
1274
  throw new Error(`Cannot install version "${snapInfo.version}" of snap "${snapId}": The version is blocked. ${result.reason?.explanation ?? ''}`);
1288
1275
  } else if (_class_private_field_get(this, _featureFlags).requireAllowlist && result.status !== _registry.SnapsRegistryStatus.Verified) {
1289
- throw new Error(`Cannot install version "${snapInfo.version}" of snap "${snapId}": The snap is not on the allow list.`);
1276
+ throw new Error(`Cannot install version "${snapInfo.version}" of snap "${snapId}": The snap is not on the allowlist.`);
1290
1277
  }
1291
1278
  }
1292
1279
  async function stopSnapsLastRequestPastMax() {
@@ -1352,6 +1339,9 @@ function updateApproval(id, requestState) {
1352
1339
  // Do nothing
1353
1340
  }
1354
1341
  }
1342
+ async function resolveAllowlistVersion(snapId, versionRange) {
1343
+ return await this.messagingSystem.call('SnapsRegistry:resolveVersion', snapId, versionRange);
1344
+ }
1355
1345
  async function add(args) {
1356
1346
  const { id: snapId, location, versionRange } = args;
1357
1347
  _class_private_method_get(this, _setupRuntime, setupRuntime).call(this, snapId, {
@@ -1365,7 +1355,7 @@ async function add(args) {
1365
1355
  // to null in the authorize() method.
1366
1356
  runtime.installPromise = (async ()=>{
1367
1357
  const fetchedSnap = await _class_private_method_get(this, _fetchSnap, fetchSnap).call(this, snapId, location);
1368
- const manifest = fetchedSnap.manifest.result;
1358
+ const manifest = fetchedSnap.files.manifest.result;
1369
1359
  if (!(0, _utils.satisfiesVersionRange)(manifest.version, versionRange)) {
1370
1360
  throw new Error(`Version mismatch. Manifest for "${snapId}" specifies version "${manifest.version}" which doesn't satisfy requested version range "${versionRange}".`);
1371
1361
  }
@@ -1435,15 +1425,16 @@ async function getEndowments(snapId) {
1435
1425
  return dedupedEndowments;
1436
1426
  }
1437
1427
  function set(args) {
1438
- const { id: snapId, origin, manifest, files, isUpdate = false } = args;
1428
+ const { id: snapId, origin, files, isUpdate = false } = args;
1429
+ const { manifest, sourceCode: sourceCodeFile, svgIcon, auxiliaryFiles: rawAuxiliaryFiles } = files;
1439
1430
  (0, _snapsutils.assertIsSnapManifest)(manifest.result);
1440
1431
  const { version } = manifest.result;
1441
- const normalizedSourcePath = (0, _snapsutils.normalizeRelative)(manifest.result.source.location.npm.filePath);
1442
- const { iconPath } = manifest.result.source.location.npm;
1443
- const normalizedIconPath = iconPath && (0, _snapsutils.normalizeRelative)(iconPath);
1444
- const sourceCode = files.find((file)=>file.path === normalizedSourcePath)?.toString();
1445
- const svgIcon = normalizedIconPath ? files.find((file)=>file.path === normalizedIconPath) : undefined;
1432
+ const sourceCode = sourceCodeFile.toString();
1446
1433
  (0, _utils.assert)(typeof sourceCode === 'string' && sourceCode.length > 0, `Invalid source code for snap "${snapId}".`);
1434
+ const auxiliaryFiles = rawAuxiliaryFiles.map((file)=>({
1435
+ path: file.path,
1436
+ value: file.toString('base64')
1437
+ }));
1447
1438
  const snapsState = this.state.snaps;
1448
1439
  const existingSnap = snapsState[snapId];
1449
1440
  const previousVersionHistory = existingSnap?.versionHistory ?? [];
@@ -1468,7 +1459,8 @@ function set(args) {
1468
1459
  status: _class_private_field_get(this, _statusMachine).config.initial,
1469
1460
  sourceCode,
1470
1461
  version,
1471
- versionHistory
1462
+ versionHistory,
1463
+ auxiliaryFiles
1472
1464
  };
1473
1465
  // If the snap was blocked, it isn't any longer
1474
1466
  delete snap.blockInformation;
@@ -1496,19 +1488,15 @@ async function fetchSnap(snapId, location) {
1496
1488
  const sourceCode = await location.fetch(manifest.result.source.location.npm.filePath);
1497
1489
  const { iconPath } = manifest.result.source.location.npm;
1498
1490
  const svgIcon = iconPath ? await location.fetch(iconPath) : undefined;
1499
- const files = [
1500
- sourceCode
1501
- ];
1502
- if (svgIcon) {
1503
- files.push(svgIcon);
1504
- }
1505
- (0, _snapsutils.validateFetchedSnap)({
1491
+ const auxiliaryFiles = manifest.result.source.files ? await Promise.all(manifest.result.source.files.map(async (filePath)=>location.fetch(filePath))) : [];
1492
+ const files = {
1506
1493
  manifest,
1507
1494
  sourceCode,
1508
- svgIcon
1509
- });
1495
+ svgIcon,
1496
+ auxiliaryFiles
1497
+ };
1498
+ (0, _snapsutils.validateFetchedSnap)(files);
1510
1499
  return {
1511
- manifest,
1512
1500
  files,
1513
1501
  location
1514
1502
  };
@@ -1577,8 +1565,11 @@ function getRpcRequestHandler(snapId) {
1577
1565
  _class_private_method_get(this, _recordSnapRpcRequestFinish, recordSnapRpcRequestFinish).call(this, snapId, request.id);
1578
1566
  return result;
1579
1567
  } catch (error) {
1580
- await this.stopSnap(snapId, _snapsutils.SnapStatusEvents.Crash);
1581
- throw error;
1568
+ const [jsonRpcError, handled] = (0, _snapsutils.unwrapError)(error);
1569
+ if (!handled) {
1570
+ await this.stopSnap(snapId, _snapsutils.SnapStatusEvents.Crash);
1571
+ }
1572
+ throw jsonRpcError;
1582
1573
  }
1583
1574
  };
1584
1575
  runtime.rpcHandler = rpcHandler;