diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 4b5dffdef..5964ad9ef 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2660,6 +2660,10 @@ "message": "Connect to the $1 Snap.", "description": "The description for the `wallet_snap_*` permission. $1 is the name of the Snap." }, + "permission_cronjob": { + "message": "Schedule and execute periodic actions.", + "description": "The description for the `snap_cronjob` permission" + }, "permission_customConfirmation": { "message": "Display a confirmation in MetaMask.", "description": "The description for the `snap_confirm` permission" diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index c183b82af..99821fed2 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -49,6 +49,7 @@ import { import SmartTransactionsController from '@metamask/smart-transactions-controller'; ///: BEGIN:ONLY_INCLUDE_IN(flask) import { + CronjobController, SnapController, IframeExecutionService, } from '@metamask/snap-controllers'; @@ -753,6 +754,24 @@ export default class MetamaskController extends EventEmitter { }, }, }); + // --- Snaps Cronjob Controller configuration + const cronjobControllerMessenger = this.controllerMessenger.getRestricted({ + name: 'CronjobController', + allowedEvents: [ + 'SnapController:snapInstalled', + 'SnapController:snapUpdated', + 'SnapController:snapRemoved', + ], + allowedActions: [ + `${this.permissionController.name}:getPermissions`, + 'SnapController:handleRequest', + 'SnapController:getAll', + ], + }); + this.cronjobController = new CronjobController({ + state: initState.CronjobController, + messenger: cronjobControllerMessenger, + }); ///: END:ONLY_INCLUDE_IN this.detectTokensController = new DetectTokensController({ preferences: this.preferencesController, @@ -1042,6 +1061,7 @@ export default class MetamaskController extends EventEmitter { CollectiblesController: this.collectiblesController, ///: BEGIN:ONLY_INCLUDE_IN(flask) SnapController: this.snapController, + CronjobController: this.cronjobController, NotificationController: this.notificationController, ///: END:ONLY_INCLUDE_IN }); @@ -1083,6 +1103,7 @@ export default class MetamaskController extends EventEmitter { CollectiblesController: this.collectiblesController, ///: BEGIN:ONLY_INCLUDE_IN(flask) SnapController: this.snapController, + CronjobController: this.cronjobController, NotificationController: this.notificationController, ///: END:ONLY_INCLUDE_IN }, diff --git a/shared/constants/permissions.ts b/shared/constants/permissions.ts index ce5df7d1c..dbd39b51e 100644 --- a/shared/constants/permissions.ts +++ b/shared/constants/permissions.ts @@ -24,12 +24,10 @@ export const EndowmentPermissions = Object.freeze({ 'endowment:network-access': 'endowment:network-access', 'endowment:long-running': 'endowment:long-running', 'endowment:transaction-insight': 'endowment:transaction-insight', + 'endowment:cronjob': 'endowment:cronjob', } as const); // Methods / permissions in external packages that we are temporarily excluding. export const ExcludedSnapPermissions = new Set(['snap_dialog']); -export const ExcludedSnapEndowments = new Set([ - 'endowment:keyring', - 'endowment:cronjob', -]); +export const ExcludedSnapEndowments = new Set(['endowment:keyring']); ///: END:ONLY_INCLUDE_IN diff --git a/ui/helpers/utils/permission.js b/ui/helpers/utils/permission.js index 79a9a29e5..508ca3e0b 100644 --- a/ui/helpers/utils/permission.js +++ b/ui/helpers/utils/permission.js @@ -102,6 +102,11 @@ const PERMISSION_DESCRIPTIONS = deepFreeze({ leftIcon: 'fas fa-info', rightIcon: null, }, + [EndowmentPermissions['endowment:cronjob']]: { + label: (t) => t('permission_cronjob'), + leftIcon: 'fas fa-clock', + rightIcon: null, + }, ///: END:ONLY_INCLUDE_IN [UNKNOWN_PERMISSION]: { label: (t, permissionName) =>