@metamask/snaps-controllers 3.0.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -1
- package/dist/cjs/cronjob/CronjobController.js +1 -1
- package/dist/cjs/cronjob/CronjobController.js.map +1 -1
- package/dist/cjs/services/AbstractExecutionService.js +6 -7
- package/dist/cjs/services/AbstractExecutionService.js.map +1 -1
- package/dist/cjs/snaps/SnapController.js +72 -82
- package/dist/cjs/snaps/SnapController.js.map +1 -1
- package/dist/cjs/snaps/endowments/cronjob.js +4 -4
- package/dist/cjs/snaps/endowments/cronjob.js.map +1 -1
- package/dist/cjs/snaps/endowments/keyring.js +4 -4
- package/dist/cjs/snaps/endowments/keyring.js.map +1 -1
- package/dist/cjs/snaps/endowments/name-lookup.js +3 -3
- package/dist/cjs/snaps/endowments/name-lookup.js.map +1 -1
- package/dist/cjs/snaps/endowments/rpc.js +4 -4
- package/dist/cjs/snaps/endowments/rpc.js.map +1 -1
- package/dist/cjs/snaps/endowments/transaction-insight.js +3 -3
- package/dist/cjs/snaps/endowments/transaction-insight.js.map +1 -1
- package/dist/cjs/snaps/location/location.js.map +1 -1
- package/dist/cjs/snaps/location/npm.js +47 -16
- package/dist/cjs/snaps/location/npm.js.map +1 -1
- package/dist/cjs/snaps/permissions.js +5 -5
- package/dist/cjs/snaps/permissions.js.map +1 -1
- package/dist/cjs/snaps/registry/json.js +30 -1
- package/dist/cjs/snaps/registry/json.js.map +1 -1
- package/dist/cjs/snaps/registry/registry.js.map +1 -1
- package/dist/esm/cronjob/CronjobController.js +1 -1
- package/dist/esm/cronjob/CronjobController.js.map +1 -1
- package/dist/esm/services/AbstractExecutionService.js +6 -7
- package/dist/esm/services/AbstractExecutionService.js.map +1 -1
- package/dist/esm/snaps/SnapController.js +69 -79
- package/dist/esm/snaps/SnapController.js.map +1 -1
- package/dist/esm/snaps/endowments/cronjob.js +4 -4
- package/dist/esm/snaps/endowments/cronjob.js.map +1 -1
- package/dist/esm/snaps/endowments/keyring.js +4 -4
- package/dist/esm/snaps/endowments/keyring.js.map +1 -1
- package/dist/esm/snaps/endowments/name-lookup.js +3 -3
- package/dist/esm/snaps/endowments/name-lookup.js.map +1 -1
- package/dist/esm/snaps/endowments/rpc.js +4 -4
- package/dist/esm/snaps/endowments/rpc.js.map +1 -1
- package/dist/esm/snaps/endowments/transaction-insight.js +3 -3
- package/dist/esm/snaps/endowments/transaction-insight.js.map +1 -1
- package/dist/esm/snaps/location/location.js.map +1 -1
- package/dist/esm/snaps/location/npm.js +48 -17
- package/dist/esm/snaps/location/npm.js.map +1 -1
- package/dist/esm/snaps/permissions.js +1 -1
- package/dist/esm/snaps/permissions.js.map +1 -1
- package/dist/esm/snaps/registry/json.js +31 -2
- package/dist/esm/snaps/registry/json.js.map +1 -1
- package/dist/esm/snaps/registry/registry.js.map +1 -1
- package/dist/types/cronjob/CronjobController.d.ts +1 -1
- package/dist/types/services/AbstractExecutionService.d.ts +1 -1
- package/dist/types/snaps/SnapController.d.ts +20 -32
- package/dist/types/snaps/location/location.d.ts +2 -0
- package/dist/types/snaps/location/npm.d.ts +1 -1
- package/dist/types/snaps/registry/json.d.ts +5 -1
- package/dist/types/snaps/registry/registry.d.ts +11 -1
- 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
|
|
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,
|
|
245
|
-
this.stopSnap(snapId, _snapsutils.SnapStatusEvents.Crash).
|
|
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?.[
|
|
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,
|
|
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
|
-
|
|
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[
|
|
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);
|
|
@@ -613,12 +599,13 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
613
599
|
(0, _snapsutils.assertIsValidSnapId)(snapId);
|
|
614
600
|
const [error, version] = (0, _snapsutils.resolveVersionRange)(rawVersion);
|
|
615
601
|
if (error) {
|
|
616
|
-
throw
|
|
602
|
+
throw _rpcerrors.rpcErrors.invalidParams(`The "version" field must be a valid SemVer version range if specified. Received: "${rawVersion}".`);
|
|
617
603
|
}
|
|
618
604
|
const location = _class_private_field_get(this, _detectSnapLocation).call(this, snapId, {
|
|
619
605
|
versionRange: version,
|
|
620
606
|
fetch: _class_private_field_get(this, _fetchFunction),
|
|
621
|
-
allowLocal: _class_private_field_get(this, _featureFlags).allowLocalSnaps
|
|
607
|
+
allowLocal: _class_private_field_get(this, _featureFlags).allowLocalSnaps,
|
|
608
|
+
resolveVersion: async (range)=>_class_private_field_get(this, _featureFlags).requireAllowlist ? await _class_private_method_get(this, _resolveAllowlistVersion, resolveAllowlistVersion).call(this, snapId, range) : range
|
|
622
609
|
});
|
|
623
610
|
// Existing snaps may need to be updated, unless they should be re-installed (e.g. local snaps)
|
|
624
611
|
// Everything else is treated as an install
|
|
@@ -642,8 +629,8 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
642
629
|
result[snapId] = await this.processRequestedSnap(origin, snapId, location, version);
|
|
643
630
|
}
|
|
644
631
|
// 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));
|
|
632
|
+
pendingInstalls.forEach((snapId)=>this.messagingSystem.publish(`SnapController:snapInstalled`, this.getTruncatedExpect(snapId), origin));
|
|
633
|
+
pendingUpdates.forEach(({ snapId, oldVersion })=>this.messagingSystem.publish(`SnapController:snapUpdated`, this.getTruncatedExpect(snapId), oldVersion, origin));
|
|
647
634
|
snapIds.forEach((snapId)=>_class_private_field_get(this, _rollbackSnapshots).delete(snapId));
|
|
648
635
|
} catch (error) {
|
|
649
636
|
const installed = pendingInstalls.filter((snapId)=>this.has(snapId));
|
|
@@ -676,7 +663,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
676
663
|
return await this.updateSnap(origin, snapId, location, versionRange, // Since we are requesting an update from within processRequestedSnap,
|
|
677
664
|
// we disable the emitting of the snapUpdated event and rely on the caller
|
|
678
665
|
// to publish this event after the update is complete.
|
|
679
|
-
// This is
|
|
666
|
+
// This is necessary as installSnaps may be installing multiple snaps
|
|
680
667
|
// and we don't want to emit events prematurely.
|
|
681
668
|
false);
|
|
682
669
|
}
|
|
@@ -756,23 +743,25 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
756
743
|
try {
|
|
757
744
|
const snap = this.getExpect(snapId);
|
|
758
745
|
const newSnap = await _class_private_method_get(this, _fetchSnap, fetchSnap).call(this, snapId, location);
|
|
759
|
-
const
|
|
746
|
+
const { sourceCode: sourceCodeFile, manifest: manifestFile } = newSnap.files;
|
|
747
|
+
const manifest = manifestFile.result;
|
|
748
|
+
const newVersion = manifest.version;
|
|
760
749
|
if (!(0, _utils.gtVersion)(newVersion, snap.version)) {
|
|
761
|
-
throw
|
|
750
|
+
throw _rpcerrors.rpcErrors.invalidParams(`Snap "${snapId}@${snap.version}" is already installed. Couldn't update to a version inside requested "${newVersionRange}" range.`);
|
|
762
751
|
}
|
|
763
752
|
if (!(0, _utils.satisfiesVersionRange)(newVersion, newVersionRange)) {
|
|
764
753
|
throw new Error(`Version mismatch. Manifest for "${snapId}" specifies version "${newVersion}" which doesn't satisfy requested version range "${newVersionRange}".`);
|
|
765
754
|
}
|
|
766
755
|
await _class_private_method_get(this, _assertIsInstallAllowed, assertIsInstallAllowed).call(this, snapId, {
|
|
767
756
|
version: newVersion,
|
|
768
|
-
checksum:
|
|
757
|
+
checksum: manifest.source.shasum
|
|
769
758
|
});
|
|
770
|
-
const processedPermissions = (0, _permissions.processSnapPermissions)(
|
|
759
|
+
const processedPermissions = (0, _permissions.processSnapPermissions)(manifest.initialPermissions);
|
|
771
760
|
_class_private_method_get(this, _validateSnapPermissions, validateSnapPermissions).call(this, processedPermissions);
|
|
772
761
|
const { newPermissions, unusedPermissions, approvedPermissions } = _class_private_method_get(this, _calculatePermissionsChange, calculatePermissionsChange).call(this, snapId, processedPermissions);
|
|
773
762
|
_class_private_method_get(this, _updateApproval, updateApproval).call(this, pendingApproval.id, {
|
|
774
763
|
permissions: newPermissions,
|
|
775
|
-
newVersion:
|
|
764
|
+
newVersion: manifest.version,
|
|
776
765
|
newPermissions,
|
|
777
766
|
approvedPermissions,
|
|
778
767
|
unusedPermissions,
|
|
@@ -791,7 +780,6 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
791
780
|
_class_private_method_get(this, _set, set).call(this, {
|
|
792
781
|
origin,
|
|
793
782
|
id: snapId,
|
|
794
|
-
manifest: newSnap.manifest,
|
|
795
783
|
files: newSnap.files,
|
|
796
784
|
isUpdate: true
|
|
797
785
|
});
|
|
@@ -816,8 +804,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
816
804
|
rollbackSnapshot.permissions.granted = Object.keys(approvedNewPermissions);
|
|
817
805
|
rollbackSnapshot.permissions.requestData = requestData;
|
|
818
806
|
}
|
|
819
|
-
const
|
|
820
|
-
const sourceCode = newSnap.files.find((file)=>file.path === normalizedSourcePath)?.toString();
|
|
807
|
+
const sourceCode = sourceCodeFile.toString();
|
|
821
808
|
(0, _utils.assert)(typeof sourceCode === 'string' && sourceCode.length > 0, `Invalid source code for snap "${snapId}".`);
|
|
822
809
|
try {
|
|
823
810
|
await _class_private_method_get(this, _startSnap, startSnap).call(this, {
|
|
@@ -829,7 +816,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
829
816
|
}
|
|
830
817
|
const truncatedSnap = this.getTruncatedExpect(snapId);
|
|
831
818
|
if (emitEvent) {
|
|
832
|
-
this.messagingSystem.publish('SnapController:snapUpdated', truncatedSnap, snap.version);
|
|
819
|
+
this.messagingSystem.publish('SnapController:snapUpdated', truncatedSnap, snap.version, origin);
|
|
833
820
|
}
|
|
834
821
|
_class_private_method_get(this, _updateApproval, updateApproval).call(this, pendingApproval.id, {
|
|
835
822
|
loading: false,
|
|
@@ -899,6 +886,8 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
899
886
|
/* eslint-disable @typescript-eslint/unbound-method */ this.messagingSystem.unsubscribe('ExecutionService:unhandledError', this._onUnhandledSnapError);
|
|
900
887
|
this.messagingSystem.unsubscribe('ExecutionService:outboundRequest', this._onOutboundRequest);
|
|
901
888
|
this.messagingSystem.unsubscribe('ExecutionService:outboundResponse', this._onOutboundResponse);
|
|
889
|
+
this.messagingSystem.clearEventSubscriptions('SnapController:snapInstalled');
|
|
890
|
+
this.messagingSystem.clearEventSubscriptions('SnapController:snapUpdated');
|
|
902
891
|
/* eslint-enable @typescript-eslint/unbound-method */ }
|
|
903
892
|
/**
|
|
904
893
|
* Passes a JSON-RPC request object to the RPC handler function of a snap.
|
|
@@ -948,17 +937,15 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
948
937
|
super({
|
|
949
938
|
messenger,
|
|
950
939
|
metadata: {
|
|
951
|
-
snapErrors: {
|
|
952
|
-
persist: false,
|
|
953
|
-
anonymous: false
|
|
954
|
-
},
|
|
955
940
|
snapStates: {
|
|
956
941
|
persist: true,
|
|
957
942
|
anonymous: false
|
|
958
943
|
},
|
|
959
944
|
snaps: {
|
|
960
945
|
persist: (snaps)=>{
|
|
961
|
-
return Object.values(snaps)
|
|
946
|
+
return Object.values(snaps)// We should not persist snaps that are in the installing state,
|
|
947
|
+
// since they haven't completed installation and would be unusable
|
|
948
|
+
.filter((snap)=>snap.status !== _snapsutils.SnapStatus.Installing).map((snap)=>{
|
|
962
949
|
return {
|
|
963
950
|
...snap,
|
|
964
951
|
// At the time state is rehydrated, no snap will be running.
|
|
@@ -1001,6 +988,7 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
1001
988
|
_class_private_method_init(this, _revokeAllSnapPermissions);
|
|
1002
989
|
_class_private_method_init(this, _createApproval);
|
|
1003
990
|
_class_private_method_init(this, _updateApproval);
|
|
991
|
+
_class_private_method_init(this, _resolveAllowlistVersion);
|
|
1004
992
|
/**
|
|
1005
993
|
* Returns a promise representing the complete installation of the requested snap.
|
|
1006
994
|
* If the snap is already being installed, the previously pending promise will be returned.
|
|
@@ -1026,8 +1014,6 @@ class SnapController extends _basecontroller.BaseControllerV2 {
|
|
|
1026
1014
|
/**
|
|
1027
1015
|
* Fetches the manifest and source code of a snap.
|
|
1028
1016
|
*
|
|
1029
|
-
* This function is not hash private yet because of tests.
|
|
1030
|
-
*
|
|
1031
1017
|
* @param snapId - The id of the Snap.
|
|
1032
1018
|
* @param location - Source from which snap will be fetched.
|
|
1033
1019
|
* @returns A tuple of the Snap manifest object and the Snap source code.
|
|
@@ -1236,13 +1222,13 @@ function registerMessageHandlers() {
|
|
|
1236
1222
|
this.messagingSystem.registerActionHandler(`${controllerName}:remove`, async (...args)=>this.removeSnap(...args));
|
|
1237
1223
|
this.messagingSystem.registerActionHandler(`${controllerName}:getPermitted`, (...args)=>this.getPermittedSnaps(...args));
|
|
1238
1224
|
this.messagingSystem.registerActionHandler(`${controllerName}:install`, async (...args)=>this.installSnaps(...args));
|
|
1239
|
-
this.messagingSystem.registerActionHandler(`${controllerName}:removeSnapError`, (...args)=>this.removeSnapError(...args));
|
|
1240
1225
|
this.messagingSystem.registerActionHandler(`${controllerName}:getAll`, (...args)=>this.getAllSnaps(...args));
|
|
1241
1226
|
this.messagingSystem.registerActionHandler(`${controllerName}:incrementActiveReferences`, (...args)=>this.incrementActiveReferences(...args));
|
|
1242
1227
|
this.messagingSystem.registerActionHandler(`${controllerName}:decrementActiveReferences`, (...args)=>this.decrementActiveReferences(...args));
|
|
1243
1228
|
this.messagingSystem.registerActionHandler(`${controllerName}:getRegistryMetadata`, async (...args)=>this.getRegistryMetadata(...args));
|
|
1244
1229
|
this.messagingSystem.registerActionHandler(`${controllerName}:disconnectOrigin`, (...args)=>this.removeSnapFromSubject(...args));
|
|
1245
1230
|
this.messagingSystem.registerActionHandler(`${controllerName}:revokeDynamicPermissions`, (...args)=>this.revokeDynamicSnapPermissions(...args));
|
|
1231
|
+
this.messagingSystem.registerActionHandler(`${controllerName}:getFile`, (...args)=>this.getSnapFile(...args));
|
|
1246
1232
|
}
|
|
1247
1233
|
function pollForLastRequestStatus() {
|
|
1248
1234
|
_class_private_field_set(this, _timeoutForLastRequestStatus, setTimeout(()=>{
|
|
@@ -1286,7 +1272,7 @@ async function assertIsInstallAllowed(snapId, snapInfo) {
|
|
|
1286
1272
|
if (result.status === _registry.SnapsRegistryStatus.Blocked) {
|
|
1287
1273
|
throw new Error(`Cannot install version "${snapInfo.version}" of snap "${snapId}": The version is blocked. ${result.reason?.explanation ?? ''}`);
|
|
1288
1274
|
} 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
|
|
1275
|
+
throw new Error(`Cannot install version "${snapInfo.version}" of snap "${snapId}": The snap is not on the allowlist.`);
|
|
1290
1276
|
}
|
|
1291
1277
|
}
|
|
1292
1278
|
async function stopSnapsLastRequestPastMax() {
|
|
@@ -1352,6 +1338,9 @@ function updateApproval(id, requestState) {
|
|
|
1352
1338
|
// Do nothing
|
|
1353
1339
|
}
|
|
1354
1340
|
}
|
|
1341
|
+
async function resolveAllowlistVersion(snapId, versionRange) {
|
|
1342
|
+
return await this.messagingSystem.call('SnapsRegistry:resolveVersion', snapId, versionRange);
|
|
1343
|
+
}
|
|
1355
1344
|
async function add(args) {
|
|
1356
1345
|
const { id: snapId, location, versionRange } = args;
|
|
1357
1346
|
_class_private_method_get(this, _setupRuntime, setupRuntime).call(this, snapId, {
|
|
@@ -1365,7 +1354,7 @@ async function add(args) {
|
|
|
1365
1354
|
// to null in the authorize() method.
|
|
1366
1355
|
runtime.installPromise = (async ()=>{
|
|
1367
1356
|
const fetchedSnap = await _class_private_method_get(this, _fetchSnap, fetchSnap).call(this, snapId, location);
|
|
1368
|
-
const manifest = fetchedSnap.manifest.result;
|
|
1357
|
+
const manifest = fetchedSnap.files.manifest.result;
|
|
1369
1358
|
if (!(0, _utils.satisfiesVersionRange)(manifest.version, versionRange)) {
|
|
1370
1359
|
throw new Error(`Version mismatch. Manifest for "${snapId}" specifies version "${manifest.version}" which doesn't satisfy requested version range "${versionRange}".`);
|
|
1371
1360
|
}
|
|
@@ -1435,15 +1424,16 @@ async function getEndowments(snapId) {
|
|
|
1435
1424
|
return dedupedEndowments;
|
|
1436
1425
|
}
|
|
1437
1426
|
function set(args) {
|
|
1438
|
-
const { id: snapId, origin,
|
|
1427
|
+
const { id: snapId, origin, files, isUpdate = false } = args;
|
|
1428
|
+
const { manifest, sourceCode: sourceCodeFile, svgIcon, auxiliaryFiles: rawAuxiliaryFiles } = files;
|
|
1439
1429
|
(0, _snapsutils.assertIsSnapManifest)(manifest.result);
|
|
1440
1430
|
const { version } = manifest.result;
|
|
1441
|
-
const
|
|
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;
|
|
1431
|
+
const sourceCode = sourceCodeFile.toString();
|
|
1446
1432
|
(0, _utils.assert)(typeof sourceCode === 'string' && sourceCode.length > 0, `Invalid source code for snap "${snapId}".`);
|
|
1433
|
+
const auxiliaryFiles = rawAuxiliaryFiles.map((file)=>({
|
|
1434
|
+
path: file.path,
|
|
1435
|
+
value: file.toString('base64')
|
|
1436
|
+
}));
|
|
1447
1437
|
const snapsState = this.state.snaps;
|
|
1448
1438
|
const existingSnap = snapsState[snapId];
|
|
1449
1439
|
const previousVersionHistory = existingSnap?.versionHistory ?? [];
|
|
@@ -1468,7 +1458,8 @@ function set(args) {
|
|
|
1468
1458
|
status: _class_private_field_get(this, _statusMachine).config.initial,
|
|
1469
1459
|
sourceCode,
|
|
1470
1460
|
version,
|
|
1471
|
-
versionHistory
|
|
1461
|
+
versionHistory,
|
|
1462
|
+
auxiliaryFiles
|
|
1472
1463
|
};
|
|
1473
1464
|
// If the snap was blocked, it isn't any longer
|
|
1474
1465
|
delete snap.blockInformation;
|
|
@@ -1496,19 +1487,15 @@ async function fetchSnap(snapId, location) {
|
|
|
1496
1487
|
const sourceCode = await location.fetch(manifest.result.source.location.npm.filePath);
|
|
1497
1488
|
const { iconPath } = manifest.result.source.location.npm;
|
|
1498
1489
|
const svgIcon = iconPath ? await location.fetch(iconPath) : undefined;
|
|
1499
|
-
const
|
|
1500
|
-
|
|
1501
|
-
];
|
|
1502
|
-
if (svgIcon) {
|
|
1503
|
-
files.push(svgIcon);
|
|
1504
|
-
}
|
|
1505
|
-
(0, _snapsutils.validateFetchedSnap)({
|
|
1490
|
+
const auxiliaryFiles = manifest.result.source.files ? await Promise.all(manifest.result.source.files.map(async (filePath)=>location.fetch(filePath))) : [];
|
|
1491
|
+
const files = {
|
|
1506
1492
|
manifest,
|
|
1507
1493
|
sourceCode,
|
|
1508
|
-
svgIcon
|
|
1509
|
-
|
|
1494
|
+
svgIcon,
|
|
1495
|
+
auxiliaryFiles
|
|
1496
|
+
};
|
|
1497
|
+
(0, _snapsutils.validateFetchedSnap)(files);
|
|
1510
1498
|
return {
|
|
1511
|
-
manifest,
|
|
1512
1499
|
files,
|
|
1513
1500
|
location
|
|
1514
1501
|
};
|
|
@@ -1577,8 +1564,11 @@ function getRpcRequestHandler(snapId) {
|
|
|
1577
1564
|
_class_private_method_get(this, _recordSnapRpcRequestFinish, recordSnapRpcRequestFinish).call(this, snapId, request.id);
|
|
1578
1565
|
return result;
|
|
1579
1566
|
} catch (error) {
|
|
1580
|
-
|
|
1581
|
-
|
|
1567
|
+
const [jsonRpcError, handled] = (0, _snapsutils.unwrapError)(error);
|
|
1568
|
+
if (!handled) {
|
|
1569
|
+
await this.stopSnap(snapId, _snapsutils.SnapStatusEvents.Crash);
|
|
1570
|
+
}
|
|
1571
|
+
throw jsonRpcError;
|
|
1582
1572
|
}
|
|
1583
1573
|
};
|
|
1584
1574
|
runtime.rpcHandler = rpcHandler;
|