Skip to content

Commit bbdb24b

Browse files
committed
Preload encrypted state of preinstalled Snaps
1 parent 042d2fa commit bbdb24b

File tree

1 file changed

+75
-1
lines changed

1 file changed

+75
-1
lines changed

packages/snaps-controllers/src/snaps/SnapController.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
465470
export 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+
605616
type 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

657669
type 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

Comments
 (0)