diff --git a/packages/snaps-controllers/coverage.json b/packages/snaps-controllers/coverage.json index fffcd4a239..813ee1e36b 100644 --- a/packages/snaps-controllers/coverage.json +++ b/packages/snaps-controllers/coverage.json @@ -1,6 +1,6 @@ { "branches": 93.06, - "functions": 96.59, + "functions": 96.61, "lines": 98.08, "statements": 97.8 } diff --git a/packages/snaps-controllers/src/snaps/SnapController.test.tsx b/packages/snaps-controllers/src/snaps/SnapController.test.tsx index 9bc0b487ca..7c31cf10f1 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.test.tsx +++ b/packages/snaps-controllers/src/snaps/SnapController.test.tsx @@ -10022,6 +10022,38 @@ describe('SnapController', () => { }); }); + describe('SnapController:getRunnableSnaps', () => { + it('calls SnapController.getRunnableSnaps()', () => { + 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, + enabled: false, + }); + + const snapController = getSnapController( + getSnapControllerOptions({ + messenger, + state: { + snaps: getPersistedSnapsState( + mockSnap.stateObject, + mockSnap2.stateObject, + ), + }, + }), + ); + + const result = messenger.call('SnapController:getRunnableSnaps'); + expect(result).toStrictEqual([getTruncatedSnap()]); + + snapController.destroy(); + }); + }); + describe('SnapController:install', () => { it('calls SnapController.installSnaps()', async () => { const messenger = getSnapControllerMessenger(); diff --git a/packages/snaps-controllers/src/snaps/SnapController.ts b/packages/snaps-controllers/src/snaps/SnapController.ts index f93d78d01c..cdc245de16 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.ts +++ b/packages/snaps-controllers/src/snaps/SnapController.ts @@ -171,6 +171,7 @@ import type { } from './registry'; import { SnapsRegistryStatus } from './registry'; import { RequestQueue } from './RequestQueue'; +import { getRunnableSnaps } from './selectors'; import { Timer } from './Timer'; export const controllerName = 'SnapController'; @@ -406,6 +407,11 @@ export type GetAllSnaps = { handler: SnapController['getAllSnaps']; }; +export type GetRunnableSnaps = { + type: `${typeof controllerName}:getRunnableSnaps`; + handler: SnapController['getRunnableSnaps']; +}; + export type StopAllSnaps = { type: `${typeof controllerName}:stopAllSnaps`; handler: SnapController['stopAllSnaps']; @@ -465,6 +471,7 @@ export type SnapControllerActions = | GetPermittedSnaps | InstallSnaps | GetAllSnaps + | GetRunnableSnaps | IncrementActiveReferences | DecrementActiveReferences | GetRegistryMetadata @@ -1150,6 +1157,11 @@ export class SnapController extends BaseController< (...args) => this.getAllSnaps(...args), ); + this.messagingSystem.registerActionHandler( + `${controllerName}:getRunnableSnaps`, + (...args) => this.getRunnableSnaps(...args), + ); + this.messagingSystem.registerActionHandler( `${controllerName}:incrementActiveReferences`, (...args) => this.incrementActiveReferences(...args), @@ -2387,6 +2399,15 @@ export class SnapController extends BaseController< return Object.values(this.state.snaps).map(truncateSnap); } + /** + * Gets all runnable snaps. + * + * @returns All runnable snaps. + */ + getRunnableSnaps(): TruncatedSnap[] { + return getRunnableSnaps(this.getAllSnaps()); + } + /** * Gets the serialized permitted snaps of the given origin, if any. * diff --git a/packages/snaps-controllers/src/test-utils/controller.ts b/packages/snaps-controllers/src/test-utils/controller.ts index c4b33a9f8b..f71b8b072a 100644 --- a/packages/snaps-controllers/src/test-utils/controller.ts +++ b/packages/snaps-controllers/src/test-utils/controller.ts @@ -499,6 +499,7 @@ export const getSnapControllerMessenger = ( 'SnapController:disable', 'SnapController:remove', 'SnapController:getAll', + 'SnapController:getRunnableSnaps', 'SnapController:getPermitted', 'SnapController:install', 'SnapController:incrementActiveReferences',