1- import type {
2- AddApprovalRequest ,
3- UpdateRequestState ,
1+ import {
2+ ORIGIN_METAMASK ,
3+ type AddApprovalRequest ,
4+ type UpdateRequestState ,
45} from '@metamask/approval-controller' ;
56import type {
67 RestrictedMessenger ,
@@ -1458,6 +1459,8 @@ export class SnapController extends BaseController<
14581459 * Checks all installed snaps against the block list and
14591460 * blocks/unblocks snaps as appropriate. See {@link SnapController.blockSnap}
14601461 * for more information.
1462+ *
1463+ * Also updates any preinstalled Snaps to the latest allowlisted version.
14611464 */
14621465 async updateBlockedSnaps ( ) : Promise < void > {
14631466 this . #assertCanUsePlatform( ) ;
@@ -1486,6 +1489,34 @@ export class SnapController extends BaseController<
14861489 return this . #unblockSnap( snapId as SnapId ) ;
14871490 } ) ,
14881491 ) ;
1492+
1493+ await Promise . all (
1494+ Object . values ( this . state . snaps )
1495+ . filter ( ( snap ) => snap . preinstalled )
1496+ . map ( async ( snap ) => {
1497+ const resolvedVersion = ( await this . #resolveAllowlistVersion(
1498+ snap . id ,
1499+ '*' as SemVerRange ,
1500+ ) ) as unknown as SemVerVersion ;
1501+
1502+ if ( gtVersion ( resolvedVersion , snap . version ) ) {
1503+ const location = this . #detectSnapLocation( snap . id , {
1504+ versionRange : resolvedVersion as unknown as SemVerRange ,
1505+ fetch : this . #fetchFunction,
1506+ allowLocal : false ,
1507+ } ) ;
1508+
1509+ await this . updateSnap (
1510+ ORIGIN_METAMASK ,
1511+ snap . id ,
1512+ location ,
1513+ resolvedVersion ,
1514+ true ,
1515+ true ,
1516+ ) ;
1517+ }
1518+ } ) ,
1519+ ) ;
14891520 }
14901521
14911522 /**
@@ -2650,7 +2681,7 @@ export class SnapController extends BaseController<
26502681 pendingInstalls . push ( snapId ) ;
26512682 }
26522683
2653- result [ snapId ] = await this . processRequestedSnap (
2684+ result [ snapId ] = await this . # processRequestedSnap(
26542685 origin ,
26552686 snapId ,
26562687 location ,
@@ -2704,10 +2735,7 @@ export class SnapController extends BaseController<
27042735 * @param versionRange - The semver range of the snap to install.
27052736 * @returns The resulting snap object, or an error if something went wrong.
27062737 */
2707- // TODO: Either fix this lint violation or explain why it's necessary to
2708- // ignore.
2709- // eslint-disable-next-line no-restricted-syntax
2710- private async processRequestedSnap (
2738+ async #processRequestedSnap(
27112739 origin : string ,
27122740 snapId : SnapId ,
27132741 location : SnapLocation ,
@@ -2872,21 +2900,24 @@ export class SnapController extends BaseController<
28722900 * @param location - The location implementation of the snap.
28732901 * @param newVersionRange - A semver version range in which the maximum version will be chosen.
28742902 * @param emitEvent - An optional boolean flag to indicate whether this update should emit an event.
2903+ * @param automaticUpdate
28752904 * @returns The snap metadata if updated, `null` otherwise.
28762905 */
2906+ // TODO: Make hash private
28772907 async updateSnap (
28782908 origin : string ,
28792909 snapId : SnapId ,
28802910 location : SnapLocation ,
28812911 newVersionRange : string = DEFAULT_REQUESTED_SNAP_VERSION ,
28822912 emitEvent = true ,
2913+ automaticUpdate = false ,
28832914 ) : Promise < TruncatedSnap > {
28842915 this . #assertCanInstallSnaps( ) ;
28852916 this . #assertCanUsePlatform( ) ;
28862917
28872918 const snap = this . getExpect ( snapId ) ;
28882919
2889- if ( snap . preinstalled ) {
2920+ if ( snap . preinstalled && ! automaticUpdate ) {
28902921 throw new Error ( 'Preinstalled Snaps cannot be manually updated.' ) ;
28912922 }
28922923
@@ -2896,11 +2927,15 @@ export class SnapController extends BaseController<
28962927 ) ;
28972928 }
28982929
2899- let pendingApproval = this . #createApproval( {
2900- origin,
2901- snapId,
2902- type : SNAP_APPROVAL_UPDATE ,
2903- } ) ;
2930+ let pendingApproval ;
2931+
2932+ if ( ! automaticUpdate ) {
2933+ pendingApproval = this . #createApproval( {
2934+ origin,
2935+ snapId,
2936+ type : SNAP_APPROVAL_UPDATE ,
2937+ } ) ;
2938+ }
29042939
29052940 try {
29062941 this . messagingSystem . publish (
@@ -2953,26 +2988,35 @@ export class SnapController extends BaseController<
29532988 manifest . initialConnections ?? { } ,
29542989 ) ;
29552990
2956- this . #updateApproval( pendingApproval . id , {
2957- permissions : newPermissions ,
2958- newVersion : manifest . version ,
2959- newPermissions,
2960- approvedPermissions,
2961- unusedPermissions,
2962- newConnections,
2963- unusedConnections,
2964- approvedConnections,
2965- loading : false ,
2966- } ) ;
2991+ let approvedNewPermissions ;
2992+ let requestData ;
29672993
2968- const { permissions : approvedNewPermissions , ...requestData } =
2969- ( await pendingApproval . promise ) as PermissionsRequest ;
2994+ if ( automaticUpdate ) {
2995+ // TODO: This probably doesn't work as it doesn't account for initialConnections.
2996+ approvedNewPermissions = newPermissions ;
2997+ } else {
2998+ assert ( pendingApproval ) ;
2999+ this . #updateApproval( pendingApproval . id , {
3000+ permissions : newPermissions ,
3001+ newVersion : manifest . version ,
3002+ newPermissions,
3003+ approvedPermissions,
3004+ unusedPermissions,
3005+ newConnections,
3006+ unusedConnections,
3007+ approvedConnections,
3008+ loading : false ,
3009+ } ) ;
29703010
2971- pendingApproval = this . #createApproval( {
2972- origin,
2973- snapId,
2974- type : SNAP_APPROVAL_RESULT ,
2975- } ) ;
3011+ const { permissions : approvedNewPermissions , ...requestData } =
3012+ ( await pendingApproval . promise ) as PermissionsRequest ;
3013+
3014+ pendingApproval = this . #createApproval( {
3015+ origin,
3016+ snapId,
3017+ type : SNAP_APPROVAL_RESULT ,
3018+ } ) ;
3019+ }
29763020
29773021 if ( this . isRunning ( snapId ) ) {
29783022 await this . stopSnap ( snapId , SnapStatusEvents . Stop ) ;
@@ -3034,10 +3078,13 @@ export class SnapController extends BaseController<
30343078 ) ;
30353079 }
30363080
3037- this . #updateApproval( pendingApproval . id , {
3038- loading : false ,
3039- type : SNAP_APPROVAL_UPDATE ,
3040- } ) ;
3081+ if ( ! automaticUpdate ) {
3082+ assert ( pendingApproval ) ;
3083+ this . #updateApproval( pendingApproval . id , {
3084+ loading : false ,
3085+ type : SNAP_APPROVAL_UPDATE ,
3086+ } ) ;
3087+ }
30413088
30423089 return truncatedSnap ;
30433090 } catch ( error ) {
@@ -3046,11 +3093,14 @@ export class SnapController extends BaseController<
30463093 const errorString =
30473094 error instanceof Error ? error . message : error . toString ( ) ;
30483095
3049- this . #updateApproval( pendingApproval . id , {
3050- loading : false ,
3051- error : errorString ,
3052- type : SNAP_APPROVAL_UPDATE ,
3053- } ) ;
3096+ if ( ! automaticUpdate ) {
3097+ assert ( pendingApproval ) ;
3098+ this . #updateApproval( pendingApproval . id , {
3099+ loading : false ,
3100+ error : errorString ,
3101+ type : SNAP_APPROVAL_UPDATE ,
3102+ } ) ;
3103+ }
30543104
30553105 this . messagingSystem . publish (
30563106 'SnapController:snapInstallFailed' ,
0 commit comments