@@ -462,6 +462,11 @@ export type GetSnapFile = {
462462 handler : SnapController [ 'getSnapFile' ] ;
463463} ;
464464
465+ export type PreloadSnap = {
466+ type : `${typeof controllerName } :preloadSnap`;
467+ handler : SnapController [ 'preloadSnap' ] ;
468+ } ;
469+
465470export type SnapControllerGetStateAction = ControllerGetStateAction <
466471 typeof controllerName ,
467472 SnapControllerState
@@ -489,7 +494,8 @@ export type SnapControllerActions =
489494 | RevokeDynamicPermissions
490495 | GetSnapFile
491496 | SnapControllerGetStateAction
492- | StopAllSnaps ;
497+ | StopAllSnaps
498+ | PreloadSnap ;
493499
494500// Controller Messenger Events
495501
@@ -602,6 +608,11 @@ export type SnapControllerStateChangeEvent = ControllerStateChangeEvent<
602608 SnapControllerState
603609> ;
604610
611+ type KeyringControllerUnlock = {
612+ type : 'KeyringController:unlock' ;
613+ payload : [ ] ;
614+ } ;
615+
605616type KeyringControllerLock = {
606617 type : 'KeyringController:lock' ;
607618 payload : [ ] ;
@@ -652,6 +663,7 @@ export type AllowedEvents =
652663 | ExecutionServiceEvents
653664 | SnapInstalled
654665 | SnapUpdated
666+ | KeyringControllerUnlock
655667 | KeyringControllerLock ;
656668
657669type SnapControllerMessenger = RestrictedMessenger <
@@ -1010,6 +1022,11 @@ export class SnapController extends BaseController<
10101022 } ,
10111023 ) ;
10121024
1025+ this . messagingSystem . subscribe (
1026+ 'KeyringController:unlock' ,
1027+ this . #handleUnlock. bind ( this ) ,
1028+ ) ;
1029+
10131030 this . messagingSystem . subscribe (
10141031 'KeyringController:lock' ,
10151032 this . #handleLock. bind ( this ) ,
@@ -1204,6 +1221,11 @@ export class SnapController extends BaseController<
12041221 `${ controllerName } :stopAllSnaps` ,
12051222 async ( ...args ) => this . stopAllSnaps ( ...args ) ,
12061223 ) ;
1224+
1225+ this . messagingSystem . registerActionHandler (
1226+ `${ controllerName } :preloadSnap` ,
1227+ async ( ...args ) => this . preloadSnap ( ...args ) ,
1228+ ) ;
12071229 }
12081230
12091231 #handlePreinstalledSnaps( preinstalledSnaps : PreinstalledSnap [ ] ) {
@@ -1569,6 +1591,24 @@ export class SnapController extends BaseController<
15691591 } ) ;
15701592 }
15711593
1594+ /**
1595+ * Preload the state of the given Snap. This is a no-op if the Snap is already
1596+ * loaded.
1597+ *
1598+ * @param snapId - The id of the Snap to preload.
1599+ */
1600+ async preloadSnap ( snapId : SnapId ) : Promise < void > {
1601+ this . #assertCanUsePlatform( ) ;
1602+ const runtime = this . #getRuntimeExpect( snapId ) ;
1603+
1604+ if ( runtime . state !== undefined ) {
1605+ return ;
1606+ }
1607+
1608+ // Calling `getSnapState` caches the state in the Snap runtime data.
1609+ await this . getSnapState ( snapId , true ) ;
1610+ }
1611+
15721612 /**
15731613 * Starts the given snap. Throws an error if no such snap exists
15741614 * or if it is already running.
@@ -4245,6 +4285,40 @@ export class SnapController extends BaseController<
42454285 } ) ;
42464286 }
42474287
4288+ /**
4289+ * Handle the `KeyringController:unlock` event.
4290+ *
4291+ * Currently this preloads all preinstalled Snaps.
4292+ */
4293+ #handleUnlock( ) {
4294+ if ( this . #preinstalledSnaps) {
4295+ const promises = this . #preinstalledSnaps. map ( async ( { snapId } ) =>
4296+ this . preloadSnap ( snapId )
4297+ . then ( ( ) => ( { snapId, status : 'fulfilled' } ) )
4298+ . catch ( ( error ) => ( { snapId, status : 'rejected' , reason : error } ) ) ,
4299+ ) ;
4300+
4301+ Promise . all ( promises )
4302+ . then ( ( results ) => {
4303+ const failedSnaps = results . filter (
4304+ ( result ) => result . status === 'rejected' ,
4305+ ) ;
4306+
4307+ if ( failedSnaps . length > 0 ) {
4308+ logWarning (
4309+ `Failed to preload ${ failedSnaps . length } preinstalled Snap(s):` ,
4310+ failedSnaps ,
4311+ ) ;
4312+ }
4313+ } )
4314+ . catch ( ( error ) => {
4315+ // This should never happen since we catch all errors in the promises
4316+ // above, but just in case, we log it.
4317+ logError ( 'An unknown error occurred while preloading Snaps.' , error ) ;
4318+ } ) ;
4319+ }
4320+ }
4321+
42484322 /**
42494323 * Handle the `KeyringController:lock` event.
42504324 *
0 commit comments