Skip to content

Commit

Permalink
Add stopAllSnaps function to SnapController (#2674)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmalik88 authored Aug 30, 2024
1 parent 572e3fb commit 908c37b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 5 deletions.
8 changes: 4 additions & 4 deletions packages/snaps-controllers/coverage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"branches": 92.59,
"functions": 96.91,
"lines": 98.01,
"statements": 97.71
"branches": 92.6,
"functions": 96.95,
"lines": 98.02,
"statements": 97.72
}
35 changes: 35 additions & 0 deletions packages/snaps-controllers/src/snaps/SnapController.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9525,4 +9525,39 @@ describe('SnapController', () => {
snapController.destroy();
});
});

describe('SnapController:stopAllSnaps', () => {
it('calls SnapController.stopAllSnaps()', async () => {
const messenger = getSnapControllerMessenger();
const mockSnap = getMockSnapData({
id: MOCK_SNAP_ID,
origin: MOCK_ORIGIN,
});
const mockSnap2 = getMockSnapData({
id: `${MOCK_SNAP_ID}2` as SnapId,
origin: MOCK_ORIGIN,
});

const snapController = getSnapController(
getSnapControllerOptions({
messenger,
state: {
snaps: getPersistedSnapsState(
mockSnap.stateObject,
mockSnap2.stateObject,
),
},
}),
);

await snapController.startSnap(mockSnap.id);
await snapController.startSnap(mockSnap2.id);

await messenger.call('SnapController:stopAllSnaps');
expect(snapController.state.snaps[mockSnap.id].status).toBe('stopped');
expect(snapController.state.snaps[mockSnap2.id].status).toBe('stopped');

snapController.destroy();
});
});
});
34 changes: 33 additions & 1 deletion packages/snaps-controllers/src/snaps/SnapController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,11 @@ export type GetAllSnaps = {
handler: SnapController['getAllSnaps'];
};

export type StopAllSnaps = {
type: `${typeof controllerName}:stopAllSnaps`;
handler: SnapController['stopAllSnaps'];
};

export type IncrementActiveReferences = {
type: `${typeof controllerName}:incrementActiveReferences`;
handler: SnapController['incrementActiveReferences'];
Expand Down Expand Up @@ -428,7 +433,8 @@ export type SnapControllerActions =
| DisconnectOrigin
| RevokeDynamicPermissions
| GetSnapFile
| SnapControllerGetStateAction;
| SnapControllerGetStateAction
| StopAllSnaps;

// Controller Messenger Events

Expand Down Expand Up @@ -1105,6 +1111,11 @@ export class SnapController extends BaseController<
`${controllerName}:getFile`,
async (...args) => this.getSnapFile(...args),
);

this.messagingSystem.registerActionHandler(
`${controllerName}:stopAllSnaps`,
async (...args) => this.stopAllSnaps(...args),
);
}

#handlePreinstalledSnaps(preinstalledSnaps: PreinstalledSnap[]) {
Expand Down Expand Up @@ -1551,6 +1562,27 @@ export class SnapController extends BaseController<
}
}

/**
* Stops all running snaps, removes all hooks, closes all connections, and
* terminates their workers.
*
* @param statusEvent - The Snap status event that caused the snap to be
* stopped.
*/
public async stopAllSnaps(
statusEvent:
| SnapStatusEvents.Stop
| SnapStatusEvents.Crash = SnapStatusEvents.Stop,
): Promise<void> {
const snaps = Object.values(this.state.snaps).filter((snap) =>
this.isRunning(snap.id),
);
const promises = snaps.map(async (snap) =>
this.stopSnap(snap.id, statusEvent),
);
await Promise.allSettled(promises);
}

/**
* Terminates the specified snap and emits the `snapTerminated` event.
*
Expand Down

0 comments on commit 908c37b

Please sign in to comment.