@metamask/snaps-controllers 15.0.1 → 16.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 +20 -1
- package/dist/cronjob/CronjobController.cjs +17 -17
- package/dist/cronjob/CronjobController.cjs.map +1 -1
- package/dist/cronjob/CronjobController.d.cts +3 -2
- package/dist/cronjob/CronjobController.d.cts.map +1 -1
- package/dist/cronjob/CronjobController.d.mts +3 -2
- package/dist/cronjob/CronjobController.d.mts.map +1 -1
- package/dist/cronjob/CronjobController.mjs +17 -17
- package/dist/cronjob/CronjobController.mjs.map +1 -1
- package/dist/insights/SnapInsightsController.cjs +8 -8
- package/dist/insights/SnapInsightsController.cjs.map +1 -1
- package/dist/insights/SnapInsightsController.d.cts +3 -2
- package/dist/insights/SnapInsightsController.d.cts.map +1 -1
- package/dist/insights/SnapInsightsController.d.mts +3 -2
- package/dist/insights/SnapInsightsController.d.mts.map +1 -1
- package/dist/insights/SnapInsightsController.mjs +8 -8
- package/dist/insights/SnapInsightsController.mjs.map +1 -1
- package/dist/interface/SnapInterfaceController.cjs +16 -17
- package/dist/interface/SnapInterfaceController.cjs.map +1 -1
- package/dist/interface/SnapInterfaceController.d.cts +3 -2
- package/dist/interface/SnapInterfaceController.d.cts.map +1 -1
- package/dist/interface/SnapInterfaceController.d.mts +3 -2
- package/dist/interface/SnapInterfaceController.d.mts.map +1 -1
- package/dist/interface/SnapInterfaceController.mjs +16 -17
- package/dist/interface/SnapInterfaceController.mjs.map +1 -1
- package/dist/multichain/MultichainRouter.cjs.map +1 -1
- package/dist/multichain/MultichainRouter.d.cts +3 -3
- package/dist/multichain/MultichainRouter.d.cts.map +1 -1
- package/dist/multichain/MultichainRouter.d.mts +3 -3
- package/dist/multichain/MultichainRouter.d.mts.map +1 -1
- package/dist/multichain/MultichainRouter.mjs.map +1 -1
- package/dist/services/ExecutionService.cjs.map +1 -1
- package/dist/services/ExecutionService.d.cts +2 -2
- package/dist/services/ExecutionService.d.cts.map +1 -1
- package/dist/services/ExecutionService.d.mts +2 -2
- package/dist/services/ExecutionService.d.mts.map +1 -1
- package/dist/services/ExecutionService.mjs.map +1 -1
- package/dist/snaps/SnapController.cjs +94 -92
- package/dist/snaps/SnapController.cjs.map +1 -1
- package/dist/snaps/SnapController.d.cts +3 -2
- package/dist/snaps/SnapController.d.cts.map +1 -1
- package/dist/snaps/SnapController.d.mts +3 -2
- package/dist/snaps/SnapController.d.mts.map +1 -1
- package/dist/snaps/SnapController.mjs +94 -92
- package/dist/snaps/SnapController.mjs.map +1 -1
- package/dist/snaps/registry/json.cjs +7 -7
- package/dist/snaps/registry/json.cjs.map +1 -1
- package/dist/snaps/registry/json.d.cts +3 -2
- package/dist/snaps/registry/json.d.cts.map +1 -1
- package/dist/snaps/registry/json.d.mts +3 -2
- package/dist/snaps/registry/json.d.mts.map +1 -1
- package/dist/snaps/registry/json.mjs +7 -7
- package/dist/snaps/registry/json.mjs.map +1 -1
- package/dist/websocket/WebSocketService.cjs.map +1 -1
- package/dist/websocket/WebSocketService.d.cts +2 -2
- package/dist/websocket/WebSocketService.d.cts.map +1 -1
- package/dist/websocket/WebSocketService.d.mts +2 -2
- package/dist/websocket/WebSocketService.d.mts.map +1 -1
- package/dist/websocket/WebSocketService.mjs.map +1 -1
- package/package.json +8 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExecutionService.mjs","sourceRoot":"","sources":["../../src/services/ExecutionService.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"ExecutionService.mjs","sourceRoot":"","sources":["../../src/services/ExecutionService.ts"],"names":[],"mappings":"","sourcesContent":["import type { Messenger } from '@metamask/messenger';\nimport type { SnapRpcHookArgs } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\n\ntype TerminateSnap = (snapId: string) => Promise<void>;\ntype TerminateAll = () => Promise<void>;\ntype ExecuteSnap = (snapData: SnapExecutionData) => Promise<unknown>;\n\ntype HandleRpcRequest = (\n snapId: string,\n options: SnapRpcHookArgs,\n) => Promise<unknown>;\n\nexport type ExecutionService = {\n // These fields are required for modular initialisation of the execution\n // service in the MetaMask extension.\n name: 'ExecutionService';\n state: null;\n\n terminateSnap: TerminateSnap;\n terminateAllSnaps: TerminateAll;\n executeSnap: ExecuteSnap;\n handleRpcRequest: HandleRpcRequest;\n};\n\nexport type SnapExecutionData = {\n snapId: string;\n sourceCode: string;\n endowments: Json;\n};\n\nexport type SnapErrorJson = {\n message: string;\n code: number;\n data?: Json;\n};\n\ntype ControllerName = 'ExecutionService';\n\nexport type ErrorMessageEvent = {\n type: 'ExecutionService:unhandledError';\n payload: [string, SnapErrorJson];\n};\n\nexport type OutboundRequest = {\n type: 'ExecutionService:outboundRequest';\n payload: [string];\n};\n\nexport type OutboundResponse = {\n type: 'ExecutionService:outboundResponse';\n payload: [string];\n};\n\nexport type ExecutionServiceEvents =\n | ErrorMessageEvent\n | OutboundRequest\n | OutboundResponse;\n\n/**\n * Handles RPC request.\n */\nexport type HandleRpcRequestAction = {\n type: `${ControllerName}:handleRpcRequest`;\n handler: ExecutionService['handleRpcRequest'];\n};\n\n/**\n * Executes a given snap.\n */\nexport type ExecuteSnapAction = {\n type: `${ControllerName}:executeSnap`;\n handler: ExecutionService['executeSnap'];\n};\n\n/**\n * Terminates a given snap.\n */\nexport type TerminateSnapAction = {\n type: `${ControllerName}:terminateSnap`;\n handler: ExecutionService['terminateSnap'];\n};\n\n/**\n * Terminates all snaps.\n */\nexport type TerminateAllSnapsAction = {\n type: `${ControllerName}:terminateAllSnaps`;\n handler: ExecutionService['terminateAllSnaps'];\n};\n\nexport type ExecutionServiceActions =\n | HandleRpcRequestAction\n | ExecuteSnapAction\n | TerminateSnapAction\n | TerminateAllSnapsAction;\n\nexport type ExecutionServiceMessenger = Messenger<\n 'ExecutionService',\n ExecutionServiceActions,\n ExecutionServiceEvents\n>;\n"]}
|
|
@@ -90,13 +90,13 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
90
90
|
snapStates: {
|
|
91
91
|
includeInStateLogs: false,
|
|
92
92
|
persist: true,
|
|
93
|
-
|
|
93
|
+
includeInDebugSnapshot: false,
|
|
94
94
|
usedInUi: false,
|
|
95
95
|
},
|
|
96
96
|
unencryptedSnapStates: {
|
|
97
97
|
includeInStateLogs: false,
|
|
98
98
|
persist: true,
|
|
99
|
-
|
|
99
|
+
includeInDebugSnapshot: false,
|
|
100
100
|
usedInUi: false,
|
|
101
101
|
},
|
|
102
102
|
snaps: {
|
|
@@ -127,7 +127,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
127
127
|
return memo;
|
|
128
128
|
}, {}));
|
|
129
129
|
},
|
|
130
|
-
|
|
130
|
+
includeInDebugSnapshot: false,
|
|
131
131
|
// TODO: Ensure larger snap properties are not sent to the UI
|
|
132
132
|
// Currently these are stripped out manually in the extension
|
|
133
133
|
usedInUi: true,
|
|
@@ -162,21 +162,21 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
162
162
|
this.#trackEvent = trackEvent;
|
|
163
163
|
this.#pollForLastRequestStatus();
|
|
164
164
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
165
|
-
this.
|
|
166
|
-
this.
|
|
167
|
-
this.
|
|
165
|
+
this.messenger.subscribe('ExecutionService:unhandledError', this._onUnhandledSnapError);
|
|
166
|
+
this.messenger.subscribe('ExecutionService:outboundRequest', this._onOutboundRequest);
|
|
167
|
+
this.messenger.subscribe('ExecutionService:outboundResponse', this._onOutboundResponse);
|
|
168
168
|
/* eslint-enable @typescript-eslint/unbound-method */
|
|
169
|
-
this.
|
|
169
|
+
this.messenger.subscribe('SnapController:snapInstalled', ({ id }, origin) => {
|
|
170
170
|
this.#callLifecycleHook(origin, id, snaps_utils_1.HandlerType.OnInstall).catch((error) => {
|
|
171
171
|
(0, snaps_utils_1.logError)(`Error when calling \`onInstall\` lifecycle hook for snap "${id}": ${(0, snaps_sdk_1.getErrorMessage)(error)}`);
|
|
172
172
|
});
|
|
173
173
|
});
|
|
174
|
-
this.
|
|
174
|
+
this.messenger.subscribe('SnapController:snapUpdated', ({ id }, _oldVersion, origin) => {
|
|
175
175
|
this.#callLifecycleHook(origin, id, snaps_utils_1.HandlerType.OnUpdate).catch((error) => {
|
|
176
176
|
(0, snaps_utils_1.logError)(`Error when calling \`onUpdate\` lifecycle hook for snap "${id}": ${(0, snaps_sdk_1.getErrorMessage)(error)}`);
|
|
177
177
|
});
|
|
178
178
|
});
|
|
179
|
-
this.
|
|
179
|
+
this.messenger.subscribe('KeyringController:lock', this.#handleLock.bind(this));
|
|
180
180
|
this.#initializeStateMachine();
|
|
181
181
|
this.#registerMessageHandlers();
|
|
182
182
|
Object.values(this.state?.snaps ?? {}).forEach((snap) => this.#setupRuntime(snap.id));
|
|
@@ -184,7 +184,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
184
184
|
this.#handlePreinstalledSnaps(this.#preinstalledSnaps);
|
|
185
185
|
}
|
|
186
186
|
this.#trackSnapExport = (0, utils_2.throttleTracking)((snapId, handler, success, origin) => {
|
|
187
|
-
const snapMetadata = this.
|
|
187
|
+
const snapMetadata = this.messenger.call('SnapsRegistry:getMetadata', snapId);
|
|
188
188
|
this.#trackEvent({
|
|
189
189
|
event: 'Snap Export Used',
|
|
190
190
|
category: 'Snaps',
|
|
@@ -267,29 +267,29 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
267
267
|
* actions.
|
|
268
268
|
*/
|
|
269
269
|
#registerMessageHandlers() {
|
|
270
|
-
this.
|
|
271
|
-
this.
|
|
272
|
-
this.
|
|
273
|
-
this.
|
|
274
|
-
this.
|
|
275
|
-
this.
|
|
276
|
-
this.
|
|
277
|
-
this.
|
|
278
|
-
this.
|
|
279
|
-
this.
|
|
280
|
-
this.
|
|
281
|
-
this.
|
|
282
|
-
this.
|
|
283
|
-
this.
|
|
284
|
-
this.
|
|
285
|
-
this.
|
|
286
|
-
this.
|
|
287
|
-
this.
|
|
288
|
-
this.
|
|
289
|
-
this.
|
|
290
|
-
this.
|
|
291
|
-
this.
|
|
292
|
-
this.
|
|
270
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:init`, (...args) => this.init(...args));
|
|
271
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:clearSnapState`, (...args) => this.clearSnapState(...args));
|
|
272
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:get`, (...args) => this.get(...args));
|
|
273
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:getSnapState`, async (...args) => this.getSnapState(...args));
|
|
274
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:handleRequest`, async (...args) => this.handleRequest(...args));
|
|
275
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:has`, (...args) => this.has(...args));
|
|
276
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:updateRegistry`, async () => this.updateRegistry());
|
|
277
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:updateSnapState`, async (...args) => this.updateSnapState(...args));
|
|
278
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:enable`, (...args) => this.enableSnap(...args));
|
|
279
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:disable`, async (...args) => this.disableSnap(...args));
|
|
280
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:remove`, async (...args) => this.removeSnap(...args));
|
|
281
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:getPermitted`, (...args) => this.getPermittedSnaps(...args));
|
|
282
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:install`, async (...args) => this.installSnaps(...args));
|
|
283
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:getAll`, (...args) => this.getAllSnaps(...args));
|
|
284
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:getRunnableSnaps`, (...args) => this.getRunnableSnaps(...args));
|
|
285
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:incrementActiveReferences`, (...args) => this.incrementActiveReferences(...args));
|
|
286
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:decrementActiveReferences`, (...args) => this.decrementActiveReferences(...args));
|
|
287
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:disconnectOrigin`, (...args) => this.removeSnapFromSubject(...args));
|
|
288
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:revokeDynamicPermissions`, (...args) => this.revokeDynamicSnapPermissions(...args));
|
|
289
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:getFile`, async (...args) => this.getSnapFile(...args));
|
|
290
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:stopAllSnaps`, async (...args) => this.stopAllSnaps(...args));
|
|
291
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:isMinimumPlatformVersion`, (...args) => this.isMinimumPlatformVersion(...args));
|
|
292
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:setClientActive`, (...args) => this.setClientActive(...args));
|
|
293
293
|
}
|
|
294
294
|
/**
|
|
295
295
|
* Initialise the SnapController.
|
|
@@ -359,10 +359,10 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
359
359
|
this.#setupRuntime(snapId);
|
|
360
360
|
// Emit events
|
|
361
361
|
if (isUpdate) {
|
|
362
|
-
this.
|
|
362
|
+
this.messenger.publish('SnapController:snapUpdated', this.getTruncatedExpect(snapId), existingSnap.version, constants_1.METAMASK_ORIGIN, true);
|
|
363
363
|
}
|
|
364
364
|
else {
|
|
365
|
-
this.
|
|
365
|
+
this.messenger.publish('SnapController:snapInstalled', this.getTruncatedExpect(snapId), constants_1.METAMASK_ORIGIN, true);
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
}
|
|
@@ -384,8 +384,8 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
384
384
|
*/
|
|
385
385
|
async updateRegistry() {
|
|
386
386
|
this.#assertCanUsePlatform();
|
|
387
|
-
await this.
|
|
388
|
-
const blockedSnaps = await this.
|
|
387
|
+
await this.messenger.call('SnapsRegistry:update');
|
|
388
|
+
const blockedSnaps = await this.messenger.call('SnapsRegistry:get', Object.values(this.state.snaps).reduce((blockListArg, snap) => {
|
|
389
389
|
blockListArg[snap.id] = {
|
|
390
390
|
version: snap.version,
|
|
391
391
|
checksum: snap.manifest.source.shasum,
|
|
@@ -444,7 +444,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
444
444
|
catch (error) {
|
|
445
445
|
(0, snaps_utils_1.logError)(`Encountered error when stopping blocked snap "${snapId}".`, error);
|
|
446
446
|
}
|
|
447
|
-
this.
|
|
447
|
+
this.messenger.publish(`${exports.controllerName}:snapBlocked`, snapId, blockedSnapInfo);
|
|
448
448
|
}
|
|
449
449
|
/**
|
|
450
450
|
* Unblocks a snap so that it can be enabled and started again. Emits
|
|
@@ -461,10 +461,10 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
461
461
|
state.snaps[snapId].blocked = false;
|
|
462
462
|
delete state.snaps[snapId].blockInformation;
|
|
463
463
|
});
|
|
464
|
-
this.
|
|
464
|
+
this.messenger.publish(`${exports.controllerName}:snapUnblocked`, snapId);
|
|
465
465
|
}
|
|
466
466
|
async #assertIsInstallAllowed(snapId, { platformVersion, ...snapInfo }) {
|
|
467
|
-
const results = await this.
|
|
467
|
+
const results = await this.messenger.call('SnapsRegistry:get', {
|
|
468
468
|
[snapId]: snapInfo,
|
|
469
469
|
});
|
|
470
470
|
const result = results[snapId];
|
|
@@ -581,7 +581,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
581
581
|
this.update((state) => {
|
|
582
582
|
state.snaps[snapId].enabled = true;
|
|
583
583
|
});
|
|
584
|
-
this.
|
|
584
|
+
this.messenger.publish('SnapController:snapEnabled', this.getTruncatedExpect(snapId));
|
|
585
585
|
}
|
|
586
586
|
/**
|
|
587
587
|
* Disables the given snap. A snap can only be started if it is enabled.
|
|
@@ -599,7 +599,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
599
599
|
if (this.isRunning(snapId)) {
|
|
600
600
|
await this.stopSnap(snapId, snaps_utils_1.SnapStatusEvents.Stop);
|
|
601
601
|
}
|
|
602
|
-
this.
|
|
602
|
+
this.messenger.publish('SnapController:snapDisabled', this.getTruncatedExpect(snapId));
|
|
603
603
|
}
|
|
604
604
|
/**
|
|
605
605
|
* Stops the given snap, removes all hooks, closes all connections, and
|
|
@@ -659,7 +659,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
659
659
|
* @param snapId - The snap to terminate.
|
|
660
660
|
*/
|
|
661
661
|
async #terminateSnap(snapId) {
|
|
662
|
-
await this.
|
|
662
|
+
await this.messenger.call('ExecutionService:terminateSnap', snapId);
|
|
663
663
|
// Hack to give up execution for a bit to let gracefully terminating Snaps return.
|
|
664
664
|
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
665
665
|
const runtime = this.#getRuntimeExpect(snapId);
|
|
@@ -669,7 +669,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
669
669
|
.forEach((pendingRequest) => pendingRequest.timer.finish());
|
|
670
670
|
// Hack to give up execution for a bit to let timed out requests return.
|
|
671
671
|
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
672
|
-
this.
|
|
672
|
+
this.messenger.publish('SnapController:snapTerminated', this.getTruncatedExpect(snapId));
|
|
673
673
|
}
|
|
674
674
|
/**
|
|
675
675
|
* Returns whether the given snap is running.
|
|
@@ -1054,7 +1054,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1054
1054
|
});
|
|
1055
1055
|
// If the snap has been fully installed before, also emit snapUninstalled.
|
|
1056
1056
|
if (snap.status !== snaps_utils_1.SnapStatus.Installing) {
|
|
1057
|
-
this.
|
|
1057
|
+
this.messenger.publish(`SnapController:snapUninstalled`, truncated);
|
|
1058
1058
|
}
|
|
1059
1059
|
}));
|
|
1060
1060
|
}
|
|
@@ -1070,7 +1070,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1070
1070
|
}
|
|
1071
1071
|
}
|
|
1072
1072
|
#addSnapToSubject(origin, snapId) {
|
|
1073
|
-
const subjectPermissions = this.
|
|
1073
|
+
const subjectPermissions = this.messenger.call('PermissionController:getPermissions', origin);
|
|
1074
1074
|
const existingCaveat = subjectPermissions?.[snaps_rpc_methods_1.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat) => caveat.type === snaps_utils_1.SnapCaveatType.SnapIds);
|
|
1075
1075
|
const subjectHasSnap = Boolean(existingCaveat?.value?.[snapId]);
|
|
1076
1076
|
// If the subject is already connected to the snap, this is a no-op.
|
|
@@ -1079,7 +1079,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1079
1079
|
}
|
|
1080
1080
|
// If an existing caveat exists, we add the snap to that.
|
|
1081
1081
|
if (existingCaveat) {
|
|
1082
|
-
this.
|
|
1082
|
+
this.messenger.call('PermissionController:updateCaveat', origin, snaps_rpc_methods_1.WALLET_SNAP_PERMISSION_KEY, snaps_utils_1.SnapCaveatType.SnapIds, { ...existingCaveat.value, [snapId]: {} });
|
|
1083
1083
|
return;
|
|
1084
1084
|
}
|
|
1085
1085
|
const approvedPermissions = {
|
|
@@ -1094,7 +1094,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1094
1094
|
],
|
|
1095
1095
|
},
|
|
1096
1096
|
};
|
|
1097
|
-
this.
|
|
1097
|
+
this.messenger.call('PermissionController:grantPermissions', {
|
|
1098
1098
|
approvedPermissions,
|
|
1099
1099
|
subject: { origin },
|
|
1100
1100
|
});
|
|
@@ -1106,7 +1106,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1106
1106
|
* @param snapId - The id of the snap to remove.
|
|
1107
1107
|
*/
|
|
1108
1108
|
removeSnapFromSubject(origin, snapId) {
|
|
1109
|
-
const subjectPermissions = this.
|
|
1109
|
+
const subjectPermissions = this.messenger.call('PermissionController:getPermissions', origin);
|
|
1110
1110
|
const snapIdsCaveat = subjectPermissions?.[snaps_rpc_methods_1.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat) => caveat.type === snaps_utils_1.SnapCaveatType.SnapIds);
|
|
1111
1111
|
if (!snapIdsCaveat) {
|
|
1112
1112
|
return;
|
|
@@ -1118,10 +1118,10 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1118
1118
|
};
|
|
1119
1119
|
delete newCaveatValue[snapId];
|
|
1120
1120
|
if (Object.keys(newCaveatValue).length > 0) {
|
|
1121
|
-
this.
|
|
1121
|
+
this.messenger.call('PermissionController:updateCaveat', origin, snaps_rpc_methods_1.WALLET_SNAP_PERMISSION_KEY, snaps_utils_1.SnapCaveatType.SnapIds, newCaveatValue);
|
|
1122
1122
|
}
|
|
1123
1123
|
else {
|
|
1124
|
-
this.
|
|
1124
|
+
this.messenger.call('PermissionController:revokePermissions', {
|
|
1125
1125
|
[origin]: [snaps_rpc_methods_1.WALLET_SNAP_PERMISSION_KEY],
|
|
1126
1126
|
});
|
|
1127
1127
|
}
|
|
@@ -1136,7 +1136,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1136
1136
|
*/
|
|
1137
1137
|
revokeDynamicSnapPermissions(snapId, permissionNames) {
|
|
1138
1138
|
(0, utils_1.assert)(permissionNames.every((permissionName) => this.#dynamicPermissions.includes(permissionName)), 'Non-dynamic permissions cannot be revoked');
|
|
1139
|
-
this.
|
|
1139
|
+
this.messenger.call('PermissionController:revokePermissions', {
|
|
1140
1140
|
[snapId]: permissionNames,
|
|
1141
1141
|
});
|
|
1142
1142
|
}
|
|
@@ -1146,7 +1146,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1146
1146
|
* @param snapId - The id of the Snap.
|
|
1147
1147
|
*/
|
|
1148
1148
|
#removeSnapFromSubjects(snapId) {
|
|
1149
|
-
const subjects = this.
|
|
1149
|
+
const subjects = this.messenger.call('PermissionController:getSubjectNames');
|
|
1150
1150
|
for (const subject of subjects) {
|
|
1151
1151
|
this.removeSnapFromSubject(subject, snapId);
|
|
1152
1152
|
}
|
|
@@ -1157,8 +1157,8 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1157
1157
|
* @param snapId - The snap ID.
|
|
1158
1158
|
*/
|
|
1159
1159
|
#revokeAllSnapPermissions(snapId) {
|
|
1160
|
-
if (this.
|
|
1161
|
-
this.
|
|
1160
|
+
if (this.messenger.call('PermissionController:hasPermissions', snapId)) {
|
|
1161
|
+
this.messenger.call('PermissionController:revokeAllPermissions', snapId);
|
|
1162
1162
|
}
|
|
1163
1163
|
}
|
|
1164
1164
|
/**
|
|
@@ -1203,7 +1203,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1203
1203
|
* @returns The serialized permitted snaps for the origin.
|
|
1204
1204
|
*/
|
|
1205
1205
|
getPermittedSnaps(origin) {
|
|
1206
|
-
const permissions = this.
|
|
1206
|
+
const permissions = this.messenger.call('PermissionController:getPermissions', origin) ?? {};
|
|
1207
1207
|
const snaps = permissions[snaps_rpc_methods_1.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat) => caveat.type === snaps_utils_1.SnapCaveatType.SnapIds)?.value ?? {};
|
|
1208
1208
|
return Object.keys(snaps).reduce((permittedSnaps, snapId) => {
|
|
1209
1209
|
const snap = this.get(snapId);
|
|
@@ -1266,8 +1266,8 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1266
1266
|
result[snapId] = await this.#processRequestedSnap(origin, snapId, location, version);
|
|
1267
1267
|
}
|
|
1268
1268
|
// Once we finish all installs / updates, emit events.
|
|
1269
|
-
pendingInstalls.forEach((snapId) => this.
|
|
1270
|
-
pendingUpdates.forEach(({ snapId, oldVersion }) => this.
|
|
1269
|
+
pendingInstalls.forEach((snapId) => this.messenger.publish(`SnapController:snapInstalled`, this.getTruncatedExpect(snapId), origin, false));
|
|
1270
|
+
pendingUpdates.forEach(({ snapId, oldVersion }) => this.messenger.publish(`SnapController:snapUpdated`, this.getTruncatedExpect(snapId), oldVersion, origin, false));
|
|
1271
1271
|
snapIds.forEach((snapId) => this.#rollbackSnapshots.delete(snapId));
|
|
1272
1272
|
}
|
|
1273
1273
|
catch (error) {
|
|
@@ -1312,7 +1312,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1312
1312
|
snapId,
|
|
1313
1313
|
type: exports.SNAP_APPROVAL_INSTALL,
|
|
1314
1314
|
});
|
|
1315
|
-
this.
|
|
1315
|
+
this.messenger.publish('SnapController:snapInstallStarted', snapId, origin, false);
|
|
1316
1316
|
// Existing snaps must be stopped before overwriting
|
|
1317
1317
|
if (existingSnap && this.isRunning(snapId)) {
|
|
1318
1318
|
await this.stopSnap(snapId, snaps_utils_1.SnapStatusEvents.Stop);
|
|
@@ -1353,13 +1353,13 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1353
1353
|
type: exports.SNAP_APPROVAL_INSTALL,
|
|
1354
1354
|
error: errorString,
|
|
1355
1355
|
});
|
|
1356
|
-
this.
|
|
1356
|
+
this.messenger.publish('SnapController:snapInstallFailed', snapId, origin, false, errorString);
|
|
1357
1357
|
throw error;
|
|
1358
1358
|
}
|
|
1359
1359
|
}
|
|
1360
1360
|
#createApproval({ origin, snapId, type, }) {
|
|
1361
1361
|
const id = (0, nanoid_1.nanoid)();
|
|
1362
|
-
const promise = this.
|
|
1362
|
+
const promise = this.messenger.call('ApprovalController:addRequest', {
|
|
1363
1363
|
origin,
|
|
1364
1364
|
id,
|
|
1365
1365
|
type,
|
|
@@ -1376,7 +1376,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1376
1376
|
}
|
|
1377
1377
|
#updateApproval(id, requestState) {
|
|
1378
1378
|
try {
|
|
1379
|
-
this.
|
|
1379
|
+
this.messenger.call('ApprovalController:updateRequestState', {
|
|
1380
1380
|
id,
|
|
1381
1381
|
requestState,
|
|
1382
1382
|
});
|
|
@@ -1422,7 +1422,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1422
1422
|
type: exports.SNAP_APPROVAL_UPDATE,
|
|
1423
1423
|
});
|
|
1424
1424
|
try {
|
|
1425
|
-
this.
|
|
1425
|
+
this.messenger.publish('SnapController:snapInstallStarted', snapId, origin, true);
|
|
1426
1426
|
const oldManifest = snap.manifest;
|
|
1427
1427
|
const newSnap = await (0, utils_2.fetchSnap)(snapId, location);
|
|
1428
1428
|
const { sourceCode: sourceCodeFile, manifest: manifestFile } = newSnap;
|
|
@@ -1530,12 +1530,12 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1530
1530
|
type: exports.SNAP_APPROVAL_UPDATE,
|
|
1531
1531
|
});
|
|
1532
1532
|
}
|
|
1533
|
-
this.
|
|
1533
|
+
this.messenger.publish('SnapController:snapInstallFailed', snapId, origin, true, errorString);
|
|
1534
1534
|
throw error;
|
|
1535
1535
|
}
|
|
1536
1536
|
}
|
|
1537
1537
|
async #resolveAllowlistVersion(snapId, versionRange) {
|
|
1538
|
-
return await this.
|
|
1538
|
+
return await this.messenger.call('SnapsRegistry:resolveVersion', snapId, versionRange);
|
|
1539
1539
|
}
|
|
1540
1540
|
/**
|
|
1541
1541
|
* Returns a promise representing the complete installation of the requested snap.
|
|
@@ -1598,7 +1598,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1598
1598
|
}
|
|
1599
1599
|
try {
|
|
1600
1600
|
const runtime = this.#getRuntimeExpect(snapId);
|
|
1601
|
-
const result = await this.
|
|
1601
|
+
const result = await this.messenger.call('ExecutionService:executeSnap', {
|
|
1602
1602
|
...snapData,
|
|
1603
1603
|
endowments: await this.#getEndowments(snapId),
|
|
1604
1604
|
});
|
|
@@ -1626,8 +1626,8 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1626
1626
|
async #getEndowments(snapId) {
|
|
1627
1627
|
let allEndowments = [];
|
|
1628
1628
|
for (const permissionName of this.#environmentEndowmentPermissions) {
|
|
1629
|
-
if (this.
|
|
1630
|
-
const endowments = await this.
|
|
1629
|
+
if (this.messenger.call('PermissionController:hasPermission', snapId, permissionName)) {
|
|
1630
|
+
const endowments = await this.messenger.call('PermissionController:getEndowments', snapId, permissionName);
|
|
1631
1631
|
if (endowments) {
|
|
1632
1632
|
// We don't have any guarantees about the type of the endowments
|
|
1633
1633
|
// value, so we have to guard at runtime.
|
|
@@ -1727,7 +1727,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1727
1727
|
// In case the Snap uses a localized manifest, we need to get the
|
|
1728
1728
|
// proposed name from the localized manifest.
|
|
1729
1729
|
const { proposedName } = (0, snaps_utils_1.getLocalizedSnapManifest)(manifest.result, 'en', localizedFiles);
|
|
1730
|
-
this.
|
|
1730
|
+
this.messenger.call('SubjectMetadataController:addSubjectMetadata', {
|
|
1731
1731
|
subjectType: permission_controller_1.SubjectType.Snap,
|
|
1732
1732
|
name: proposedName,
|
|
1733
1733
|
origin: snap.id,
|
|
@@ -1813,11 +1813,11 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1813
1813
|
clearTimeout(this.#timeoutForLastRequestStatus);
|
|
1814
1814
|
}
|
|
1815
1815
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
1816
|
-
this.
|
|
1817
|
-
this.
|
|
1818
|
-
this.
|
|
1819
|
-
this.
|
|
1820
|
-
this.
|
|
1816
|
+
this.messenger.unsubscribe('ExecutionService:unhandledError', this._onUnhandledSnapError);
|
|
1817
|
+
this.messenger.unsubscribe('ExecutionService:outboundRequest', this._onOutboundRequest);
|
|
1818
|
+
this.messenger.unsubscribe('ExecutionService:outboundResponse', this._onOutboundResponse);
|
|
1819
|
+
this.messenger.clearEventSubscriptions('SnapController:snapInstalled');
|
|
1820
|
+
this.messenger.clearEventSubscriptions('SnapController:snapUpdated');
|
|
1821
1821
|
/* eslint-enable @typescript-eslint/unbound-method */
|
|
1822
1822
|
}
|
|
1823
1823
|
/**
|
|
@@ -1832,6 +1832,8 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1832
1832
|
*/
|
|
1833
1833
|
async handleRequest({ snapId, origin, handler: handlerType, request: rawRequest, }) {
|
|
1834
1834
|
this.#assertCanUsePlatform();
|
|
1835
|
+
const snap = this.get(snapId);
|
|
1836
|
+
(0, utils_1.assert)(snap, `The Snap "${snapId}" is not installed. Please install it before invoking it.`);
|
|
1835
1837
|
(0, utils_1.assert)(origin === constants_1.METAMASK_ORIGIN || (0, snaps_utils_1.isValidUrl)(origin), "'origin' must be a valid URL or 'metamask'.");
|
|
1836
1838
|
const request = {
|
|
1837
1839
|
jsonrpc: '2.0',
|
|
@@ -1841,7 +1843,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1841
1843
|
(0, utils_1.assertIsJsonRpcRequest)(request);
|
|
1842
1844
|
const permissionName = snaps_rpc_methods_1.handlerEndowments[handlerType];
|
|
1843
1845
|
(0, utils_1.assert)(typeof permissionName === 'string' || permissionName === null, "'permissionName' must be either a string or null.");
|
|
1844
|
-
const permissions = this.
|
|
1846
|
+
const permissions = this.messenger.call('PermissionController:getPermissions', snapId);
|
|
1845
1847
|
// If permissionName is null, the handler does not require a permission.
|
|
1846
1848
|
if (permissionName !== null &&
|
|
1847
1849
|
(!permissions || !(0, utils_1.hasProperty)(permissions, permissionName))) {
|
|
@@ -1853,7 +1855,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1853
1855
|
if (permissionName === snaps_rpc_methods_1.SnapEndowments.Rpc ||
|
|
1854
1856
|
permissionName === snaps_rpc_methods_1.SnapEndowments.Keyring) {
|
|
1855
1857
|
(0, utils_1.assert)(handlerPermissions);
|
|
1856
|
-
const subject = this.
|
|
1858
|
+
const subject = this.messenger.call('SubjectMetadataController:getSubjectMetadata', origin);
|
|
1857
1859
|
const origins = permissionName === snaps_rpc_methods_1.SnapEndowments.Rpc
|
|
1858
1860
|
? (0, snaps_rpc_methods_1.getRpcCaveatOrigins)(handlerPermissions)
|
|
1859
1861
|
: (0, snaps_rpc_methods_1.getKeyringCaveatOrigins)(handlerPermissions);
|
|
@@ -1866,10 +1868,10 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1866
1868
|
constants_1.CLIENT_ONLY_HANDLERS.includes(handlerType)) {
|
|
1867
1869
|
throw new Error(`"${handlerType}" can only be invoked by MetaMask.`);
|
|
1868
1870
|
}
|
|
1869
|
-
if (!
|
|
1871
|
+
if (!snap.enabled) {
|
|
1870
1872
|
throw new Error(`Snap "${snapId}" is disabled.`);
|
|
1871
1873
|
}
|
|
1872
|
-
if (
|
|
1874
|
+
if (snap.status === snaps_utils_1.SnapStatus.Installing) {
|
|
1873
1875
|
throw new Error(`Snap "${snapId}" is currently being installed. Please try again later.`);
|
|
1874
1876
|
}
|
|
1875
1877
|
const timeout = this.#getExecutionTimeout(handlerPermissions);
|
|
@@ -1891,7 +1893,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1891
1893
|
const transformedRequest = this.#transformSnapRpcRequest(snapId, handlerType, request);
|
|
1892
1894
|
const timer = new Timer_1.Timer(timeout);
|
|
1893
1895
|
this.#recordSnapRpcRequestStart(snapId, transformedRequest.id, timer);
|
|
1894
|
-
const handleRpcRequestPromise = this.
|
|
1896
|
+
const handleRpcRequestPromise = this.messenger.call('ExecutionService:handleRpcRequest', snapId, { origin, handler: handlerType, request: transformedRequest });
|
|
1895
1897
|
// This will either get the result or reject due to the timeout.
|
|
1896
1898
|
try {
|
|
1897
1899
|
const result = await (0, utils_2.withTimeout)(handleRpcRequestPromise, timer);
|
|
@@ -1955,11 +1957,11 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
1955
1957
|
* @returns An identifier that can be used to identify the interface.
|
|
1956
1958
|
*/
|
|
1957
1959
|
async #createInterface(snapId, content, contentType) {
|
|
1958
|
-
return this.
|
|
1960
|
+
return this.messenger.call('SnapInterfaceController:createInterface', snapId, content, undefined, contentType);
|
|
1959
1961
|
}
|
|
1960
1962
|
#assertInterfaceExists(snapId, id) {
|
|
1961
1963
|
// This will throw if the interface isn't accessible, but we assert nevertheless.
|
|
1962
|
-
(0, utils_1.assert)(this.
|
|
1964
|
+
(0, utils_1.assert)(this.messenger.call('SnapInterfaceController:getInterface', snapId, id));
|
|
1963
1965
|
}
|
|
1964
1966
|
/**
|
|
1965
1967
|
* Transform a RPC response if necessary.
|
|
@@ -2013,7 +2015,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2013
2015
|
* @returns The transformed result.
|
|
2014
2016
|
*/
|
|
2015
2017
|
#transformOnAssetsLookupResult(snapId, { params: requestedParams }, { assets }) {
|
|
2016
|
-
const permissions = this.
|
|
2018
|
+
const permissions = this.messenger.call('PermissionController:getPermissions', snapId);
|
|
2017
2019
|
// We know the permissions are guaranteed to be set here.
|
|
2018
2020
|
(0, utils_1.assert)(permissions);
|
|
2019
2021
|
const permission = permissions[snaps_rpc_methods_1.SnapEndowments.Assets];
|
|
@@ -2096,7 +2098,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2096
2098
|
case snaps_utils_1.HandlerType.OnUserInput: {
|
|
2097
2099
|
(0, utils_1.assert)(request.params && (0, utils_1.hasProperty)(request.params, 'id'));
|
|
2098
2100
|
const interfaceId = request.params.id;
|
|
2099
|
-
const { context } = this.
|
|
2101
|
+
const { context } = this.messenger.call('SnapInterfaceController:getInterface', snapId, interfaceId);
|
|
2100
2102
|
return {
|
|
2101
2103
|
...request,
|
|
2102
2104
|
params: { ...request.params, context },
|
|
@@ -2252,7 +2254,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2252
2254
|
// Calling this in reverse order to undo the changes
|
|
2253
2255
|
this.#handleInitialConnections(snapId, newInitialConnections ?? null, previousInitialConnections ?? {});
|
|
2254
2256
|
const truncatedSnap = this.getTruncatedExpect(snapId);
|
|
2255
|
-
this.
|
|
2257
|
+
this.messenger.publish('SnapController:snapRolledback', truncatedSnap, rollbackSnapshot.newVersion);
|
|
2256
2258
|
this.#rollbackSnapshots.delete(snapId);
|
|
2257
2259
|
}
|
|
2258
2260
|
/**
|
|
@@ -2302,7 +2304,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2302
2304
|
});
|
|
2303
2305
|
}
|
|
2304
2306
|
#calculatePermissionsChange(snapId, desiredPermissionsSet) {
|
|
2305
|
-
const oldPermissions = this.
|
|
2307
|
+
const oldPermissions = this.messenger.call('PermissionController:getPermissions', snapId) ?? {};
|
|
2306
2308
|
const newPermissions = (0, utils_2.permissionsDiff)(desiredPermissionsSet, oldPermissions);
|
|
2307
2309
|
// TODO(ritave): The assumption that these are unused only holds so long as we do not
|
|
2308
2310
|
// permit dynamic permission requests.
|
|
@@ -2313,7 +2315,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2313
2315
|
return { newPermissions, unusedPermissions, approvedPermissions };
|
|
2314
2316
|
}
|
|
2315
2317
|
#isSubjectConnectedToSnap(snapId, origin) {
|
|
2316
|
-
const subjectPermissions = this.
|
|
2318
|
+
const subjectPermissions = this.messenger.call('PermissionController:getPermissions', origin);
|
|
2317
2319
|
const existingCaveat = subjectPermissions?.[snaps_rpc_methods_1.WALLET_SNAP_PERMISSION_KEY]?.caveats?.find((caveat) => caveat.type === snaps_utils_1.SnapCaveatType.SnapIds);
|
|
2318
2320
|
return Boolean(existingCaveat?.value?.[snapId]);
|
|
2319
2321
|
}
|
|
@@ -2345,8 +2347,8 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2345
2347
|
if (Object.keys(newPermissions).includes(snaps_rpc_methods_1.SnapEndowments.EthereumProvider)) {
|
|
2346
2348
|
// This will return the globally selected network if the Snap doesn't have
|
|
2347
2349
|
// one set.
|
|
2348
|
-
const networkClientId = this.
|
|
2349
|
-
const { configuration } = this.
|
|
2350
|
+
const networkClientId = this.messenger.call('SelectedNetworkController:getNetworkClientIdForDomain', snapId);
|
|
2351
|
+
const { configuration } = this.messenger.call('NetworkController:getNetworkClientById', networkClientId);
|
|
2350
2352
|
const chainId = (0, utils_1.hexToNumber)(configuration.chainId);
|
|
2351
2353
|
// This needs to be assigned to have proper type inference.
|
|
2352
2354
|
const modifiedPermissions = {
|
|
@@ -2387,13 +2389,13 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2387
2389
|
#updatePermissions({ snapId, unusedPermissions = {}, newPermissions = {}, requestData, }) {
|
|
2388
2390
|
const unusedPermissionsKeys = Object.keys(unusedPermissions);
|
|
2389
2391
|
if ((0, utils_1.isNonEmptyArray)(unusedPermissionsKeys)) {
|
|
2390
|
-
this.
|
|
2392
|
+
this.messenger.call('PermissionController:revokePermissions', {
|
|
2391
2393
|
[snapId]: unusedPermissionsKeys,
|
|
2392
2394
|
});
|
|
2393
2395
|
}
|
|
2394
2396
|
if ((0, utils_1.isNonEmptyArray)(Object.keys(newPermissions))) {
|
|
2395
2397
|
const approvedPermissions = this.#getPermissionsToGrant(snapId, newPermissions);
|
|
2396
|
-
this.
|
|
2398
|
+
this.messenger.call('PermissionController:grantPermissions', {
|
|
2397
2399
|
approvedPermissions,
|
|
2398
2400
|
subject: { origin: snapId },
|
|
2399
2401
|
requestData,
|
|
@@ -2435,7 +2437,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2435
2437
|
#callLifecycleHooks(origin, handler) {
|
|
2436
2438
|
const snaps = this.getRunnableSnaps();
|
|
2437
2439
|
for (const { id } of snaps) {
|
|
2438
|
-
const hasLifecycleHooksEndowment = this.
|
|
2440
|
+
const hasLifecycleHooksEndowment = this.messenger.call('PermissionController:hasPermission', id, snaps_rpc_methods_1.SnapEndowments.LifecycleHooks);
|
|
2439
2441
|
if (!hasLifecycleHooksEndowment) {
|
|
2440
2442
|
continue;
|
|
2441
2443
|
}
|
|
@@ -2458,7 +2460,7 @@ class SnapController extends base_controller_1.BaseController {
|
|
|
2458
2460
|
async #callLifecycleHook(origin, snapId, handler) {
|
|
2459
2461
|
const permissionName = snaps_rpc_methods_1.handlerEndowments[handler];
|
|
2460
2462
|
(0, utils_1.assert)(permissionName, 'Lifecycle hook must have an endowment.');
|
|
2461
|
-
const hasPermission = this.
|
|
2463
|
+
const hasPermission = this.messenger.call('PermissionController:hasPermission', snapId, permissionName);
|
|
2462
2464
|
if (!hasPermission) {
|
|
2463
2465
|
return;
|
|
2464
2466
|
}
|