From 5702d1ee294f2acbb9655c2bca0a93b114ac4757 Mon Sep 17 00:00:00 2001 From: Alexandra Tran Carrillo <12214231+alexandratran@users.noreply.github.com> Date: Wed, 17 Apr 2024 22:14:43 -0700 Subject: [PATCH] Document Snaps cron jobs feature (#1271) * Document Snaps cron jobs feature * update what's new * address reviewer feedback --- docs/whats-new.md | 2 + snaps/features/cron-jobs.md | 87 +++++++++++++++++++++ snaps/features/custom-evm-accounts/index.md | 2 +- snaps/features/custom-name-resolution.md | 2 +- snaps/features/custom-ui/index.md | 2 +- snaps/features/localization.md | 2 +- snaps/features/non-evm-networks.md | 2 +- snaps/features/static-files.md | 2 +- snaps/index.mdx | 2 +- snaps/reference/entry-points.md | 23 +----- snaps/reference/permissions.md | 9 ++- 11 files changed, 108 insertions(+), 27 deletions(-) create mode 100644 snaps/features/cron-jobs.md diff --git a/docs/whats-new.md b/docs/whats-new.md index 90f502a5704..13aa3086edb 100644 --- a/docs/whats-new.md +++ b/docs/whats-new.md @@ -11,6 +11,8 @@ of the [MetaMask developer page](https://metamask.io/developer/). ## April 2024 +- Documented [Snaps cron jobs](/snaps/features/cron-jobs). + ([#1271](https://github.com/MetaMask/metamask-docs/pull/1271)) - Updated [how to connect to MetaMask](/wallet/how-to/connect) with vanilla TypeScript and React TypeScript instructions. ([#1247](https://github.com/MetaMask/metamask-docs/pull/1247)) diff --git a/snaps/features/cron-jobs.md b/snaps/features/cron-jobs.md new file mode 100644 index 00000000000..887e633c3e2 --- /dev/null +++ b/snaps/features/cron-jobs.md @@ -0,0 +1,87 @@ +--- +description: Schedule periodic actions for your users. +sidebar_position: 1 +--- + +# Cron jobs + +You can schedule actions to run periodically at fixed times or intervals, also known as "cron jobs." +For example, you can display a dialog or notification in MetaMask at a specific time each day. + +## Steps + +### 1. Configure a cron job + +To configure a cron job, request the [`endowment:cronjob`](../reference/permissions.md#endowmentcronjob) +permission, specifying one or more cron jobs in the `jobs` array. +Define each job with a [cron expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm) +and a request object, which MetaMask sends to the Snap's cron job handler when the job is executed. + +For example, to configure a job that executes every minute, add the following to your Snap's manifest file: + +```json title="snap.manifest.json" +"initialPermissions": { + "endowment:cronjob": { + "jobs": [ + { + "expression": "* * * * *", + "request": { + "method": "execute" + } + } + ] + } +} +``` + +### 2. Implement a cron job handler + +Expose an [`onCronjob`](../reference/entry-points.md#oncronjob) entry point, which is triggered at +the specified schedule with the requests defined in the `endowment:cronjob` permission. +The following example handles the `execute` method specified in the previous example: + +```typescript title="index.ts" +import type { OnCronjobHandler } from "@metamask/snaps-sdk"; + +export const onCronjob: OnCronjobHandler = async ({ request }) => { + switch (request.method) { + case "execute": + // Cron jobs can execute any method that is available to the Snap. + return snap.request({ + method: "snap_dialog", + params: { + type: "alert", + content: panel([ + heading("Cron job"), + text("This dialog was triggered by a cron job."), + ]), + }, + }); + + default: + throw new Error("Method not found."); + } +}; +``` + +:::tip Access data from cron jobs +When accessing encrypted data from cron jobs using +[`snap_manageState`](../reference/snaps-api.md#snap_managestate), MetaMask requires the user to +enter their password if the wallet is locked. +This interaction can be confusing to the user, since the Snap accesses the data in the background +without the user being aware. + +If the cron job requires access to encrypted state, use +[`snap_getClientStatus`](../reference/snaps-api.md#snap_getclientstatus) to ensure that MetaMask is +unlocked before accessing state. +This will prevent an unexpected password request, improving the user's experience. + +If the cron job does not require access to sensitive data, store that data in +unencrypted state by setting `encrypted` to `false` when using +[`snap_manageState`](../reference/snaps-api.md#snap_managestate). +::: + +## Example + +See the [`@metamask/cronjob-example-snap`](https://github.com/MetaMask/snaps/tree/main/packages/examples/packages/cronjobs) +package for a full example of implementing cron jobs. diff --git a/snaps/features/custom-evm-accounts/index.md b/snaps/features/custom-evm-accounts/index.md index c5a2bca517b..2ca2138f3b5 100644 --- a/snaps/features/custom-evm-accounts/index.md +++ b/snaps/features/custom-evm-accounts/index.md @@ -1,6 +1,6 @@ --- description: Connect to custom EVM accounts using the Keyring API. -sidebar_position: 4 +sidebar_position: 2 tags: - Keyring API --- diff --git a/snaps/features/custom-name-resolution.md b/snaps/features/custom-name-resolution.md index 67aeff7087c..66750898cb1 100644 --- a/snaps/features/custom-name-resolution.md +++ b/snaps/features/custom-name-resolution.md @@ -1,6 +1,6 @@ --- description: Resolve names to addresses and vice versa. -sidebar_position: 6 +sidebar_position: 3 sidebar_custom_props: flask_only: true --- diff --git a/snaps/features/custom-ui/index.md b/snaps/features/custom-ui/index.md index 4e3da75a08a..eec21868856 100644 --- a/snaps/features/custom-ui/index.md +++ b/snaps/features/custom-ui/index.md @@ -1,6 +1,6 @@ --- description: Display custom user interface components. -sidebar_position: 1 +sidebar_position: 4 --- # Custom UI diff --git a/snaps/features/localization.md b/snaps/features/localization.md index 0cc39d5aa98..9c57209e1f4 100644 --- a/snaps/features/localization.md +++ b/snaps/features/localization.md @@ -1,6 +1,6 @@ --- description: Display your Snap's UI and metadata in the user's language. -sidebar_position: 2 +sidebar_position: 5 --- # Localization diff --git a/snaps/features/non-evm-networks.md b/snaps/features/non-evm-networks.md index 477b98f3729..8a90e1d96b3 100644 --- a/snaps/features/non-evm-networks.md +++ b/snaps/features/non-evm-networks.md @@ -1,6 +1,6 @@ --- description: Manage users' non-EVM accounts and assets. -sidebar_position: 3 +sidebar_position: 6 --- # Non-EVM networks diff --git a/snaps/features/static-files.md b/snaps/features/static-files.md index cae209105f6..772170bf9e5 100644 --- a/snaps/features/static-files.md +++ b/snaps/features/static-files.md @@ -1,6 +1,6 @@ --- description: Include and retrieve static files in the Snap bundle. -sidebar_position: 5 +sidebar_position: 8 --- # Static files diff --git a/snaps/index.mdx b/snaps/index.mdx index 464a87bc1fd..d1b4a6cefa5 100644 --- a/snaps/index.mdx +++ b/snaps/index.mdx @@ -62,7 +62,7 @@ The following Snaps features are available in the stable version of MetaMask: }, { icon: require("./assets/features/cronjob.png").default, - href: "reference/entry-points#oncronjob", + href: "features/cron-jobs", title: "Cron jobs", description: "Schedule periodic actions for your users." }, diff --git a/snaps/reference/entry-points.md b/snaps/reference/entry-points.md index 41c28a4cddb..8038963c532 100644 --- a/snaps/reference/entry-points.md +++ b/snaps/reference/entry-points.md @@ -12,30 +12,15 @@ Snaps can expose the following entry points. ## `onCronjob` -To run periodic actions for the user (cron jobs), a Snap must expose the `onCronjob` entry point. -MetaMask calls the `onCronjob` handler method at the specified times with the specified payloads -defined in the [`endowment:cronjob`](permissions.md#endowmentcronjob) permission. +To run [cron jobs](../features/cron-jobs.md) for the user, a Snap must expose the `onCronjob` entry point. +MetaMask calls the `onCronjob` handler method at the specified schedule with the requests defined in +the [`endowment:cronjob`](permissions.md#endowmentcronjob) permission. :::note For MetaMask to call the Snap's `onCronjob` method, you must request the [`endowment:cronjob`](permissions.md#endowmentcronjob) permission. ::: -:::info Access data from cron jobs -When accessing encrypted data from cron jobs using [`snap_manageState`](../reference/snaps-api.md#snap_managestate), -MetaMask requires the user to enter their password if the wallet is locked. -This interaction can be confusing to the user, since the Snap accesses the data in the background -without the user being aware. - -If your Snap's cron job does not need to access sensitive data, store that data in unencrypted state -by setting `encrypted` to `false` when using [`snap_manageState`](../reference/snaps-api.md#snap_managestate). -::: - -If the cron job's logic requires access to encrypted state, you can use -[`snap_getClientStatus`](../reference/snaps-api.md#snap_getclientstatus) to ensure that MetaMask is -unlocked before accessing state. -This will prevent an unexpected password request popup, improving the user's experience. - #### Parameters An object containing an RPC request specified in the `endowment:cronjob` permission. @@ -52,7 +37,7 @@ export const onCronjob: OnCronjobHandler = async ({ request }) => { switch (request.method) { case "exampleMethodOne": return snap.request({ - method: 'snap_notify', + method: "snap_notify", params: { type: "inApp", message: "Hello, world!", diff --git a/snaps/reference/permissions.md b/snaps/reference/permissions.md index 483116cdd12..9d2d38cbf7d 100644 --- a/snaps/reference/permissions.md +++ b/snaps/reference/permissions.md @@ -26,10 +26,17 @@ manifest file: ### `endowment:cronjob` -To run periodic actions for the user (cron jobs), a Snap must request the `endowment:cronjob` permission. +To run [cron jobs](../features/cron-jobs.md) for the user, a Snap must request the `endowment:cronjob` permission. This permission allows the Snap to specify cron jobs that trigger the [`onCronjob`](../reference/entry-points.md#oncronjob) entry point. +This permission takes an object with an array of `jobs`, each containing two parameters: + +- `expression` - A [cron expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm) + that defines the schedule of the job. +- `request` - A JSON-RPC request object that will be sent to the Snap's `onCronjob` entry point when + the job is executed. + :::tip You can modify the cron job's execution limit using [Snap-defined timeouts](#snap-defined-timeouts). :::