From 946f1ac88d0a4bfbf1d6af6861664a4efb9aa585 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Fri, 19 Jul 2024 14:21:02 +0200 Subject: [PATCH 1/2] Handle initial connections for preinstalled Snaps --- .../src/snaps/SnapController.test.tsx | 75 +++++++++++++++++++ .../src/snaps/SnapController.ts | 8 ++ 2 files changed, 83 insertions(+) diff --git a/packages/snaps-controllers/src/snaps/SnapController.test.tsx b/packages/snaps-controllers/src/snaps/SnapController.test.tsx index 42a235c95a..cd755ab439 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.test.tsx +++ b/packages/snaps-controllers/src/snaps/SnapController.test.tsx @@ -4695,6 +4695,81 @@ describe('SnapController', () => { snapController.destroy(); }); + it('supports preinstalled snaps with initial connections', async () => { + const rootMessenger = getControllerMessenger(); + jest.spyOn(rootMessenger, 'call'); + + // The snap should not have permission initially + rootMessenger.registerActionHandler( + 'PermissionController:getPermissions', + () => ({}), + ); + + const initialConnections = { + 'npm:filsnap': {}, + 'https://snaps.metamask.io': {}, + }; + + const preinstalledSnaps = [ + { + snapId: MOCK_SNAP_ID, + manifest: getSnapManifest({ + initialConnections, + }), + files: [ + { + path: DEFAULT_SOURCE_PATH, + value: stringToBytes(DEFAULT_SNAP_BUNDLE), + }, + { + path: DEFAULT_ICON_PATH, + value: stringToBytes(DEFAULT_SNAP_ICON), + }, + ], + }, + ]; + + const snapControllerOptions = getSnapControllerWithEESOptions({ + preinstalledSnaps, + rootMessenger, + }); + const [snapController] = getSnapControllerWithEES(snapControllerOptions); + + const approvedPermissions = { + [WALLET_SNAP_PERMISSION_KEY]: { + caveats: [ + { + type: SnapCaveatType.SnapIds, + value: { + [MOCK_SNAP_ID]: {}, + }, + }, + ], + }, + }; + + // After install the snap should have permissions + rootMessenger.registerActionHandler( + 'PermissionController:getPermissions', + () => MOCK_SNAP_PERMISSIONS, + ); + + expect(rootMessenger.call).toHaveBeenCalledWith( + 'PermissionController:grantPermissions', + { approvedPermissions, subject: { origin: 'npm:filsnap' } }, + ); + + expect(rootMessenger.call).toHaveBeenCalledWith( + 'PermissionController:grantPermissions', + { + approvedPermissions, + subject: { origin: 'https://snaps.metamask.io' }, + }, + ); + + snapController.destroy(); + }); + it('supports preinstalled snaps when Snap installation is disabled', async () => { const rootMessenger = getControllerMessenger(); jest.spyOn(rootMessenger, 'call'); diff --git a/packages/snaps-controllers/src/snaps/SnapController.ts b/packages/snaps-controllers/src/snaps/SnapController.ts index 212f6986da..2f85a23736 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.ts +++ b/packages/snaps-controllers/src/snaps/SnapController.ts @@ -1180,6 +1180,14 @@ export class SnapController extends BaseController< this.#updatePermissions({ snapId, newPermissions, unusedPermissions }); + if (manifest.initialConnections) { + this.#handleInitialConnections( + snapId, + existingSnap?.initialConnections ?? null, + manifest.initialConnections, + ); + } + // Set status this.update((state) => { state.snaps[snapId].status = SnapStatus.Stopped; From 5dd84c31fbe74294dadf4199a7c15b1ab3cad75e Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Fri, 19 Jul 2024 14:46:17 +0200 Subject: [PATCH 2/2] Update coverage --- packages/snaps-controllers/coverage.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/snaps-controllers/coverage.json b/packages/snaps-controllers/coverage.json index 82759009a6..9000fa3169 100644 --- a/packages/snaps-controllers/coverage.json +++ b/packages/snaps-controllers/coverage.json @@ -1,5 +1,5 @@ { - "branches": 92.46, + "branches": 92.5, "functions": 96.91, "lines": 98.01, "statements": 97.7