Skip to main content

Snaps exports

A snap can export the following functions.

onRpcRequest​

To communicate with dapps and other snaps, the snap must implement its own JSON-RPC API by exposing an exported function called onRpcRequest. Whenever the snap receives a JSON-RPC request, the onRpcRequest handler function is called with the following parameters.

Does my snap need to have an RPC API?

No, that's up to you! If your snap can do something useful without receiving and responding to JSON-RPC requests, then you can skip exporting onRpcRequest. However, if you want to do something such as manage the user's keys for a particular protocol and create a dapp that sends transactions for that protocol via your snap, for example, you must specify an RPC API.

Parameters​

  • RpcHandlerArgs - The origin and the JSON-RPC request.
import { JsonRpcRequest } from '@metamask/types';

interface RpcHandlerArgs = {
origin: string;
request: JsonRpcRequest<unknown[] | { [key: string]: unknown }>;
};

Returns​

type RpcHandlerReturn = Promise<unknown> | unknown;

RpcHandlerReturn - A promise containing the return of the implemented method.

Examples​

TypeScript​

import { OnRpcRequestHandler } from '@metamask/snap-types';

export const onRpcRequest: OnRpcRequestHandler = async ({
origin,
request,
}) => {
switch (request.method) {
case 'hello':
return 'world!';

default:
throw new Error('Method not found.');
}
};

JavaScript​

module.exports.onRpcRequest = async ({ origin, request }) => {
switch (request.method) {
case 'hello':
return 'world!';

default:
throw new Error('Method not found.');
}
};

onTransaction​

If the snap wants to provide transaction insights before a user signs a transaction, the snap must export a function called onTransaction. Whenever there's a contract interaction, and a transaction is submitted via the extension, this function is called. The raw unsigned transaction payload is passed to the onTransaction handler function.

note

For the extension to call the onTransaction method of the snap, you must request the endowment:transaction-insight permission.

Parameters​

  • onTransactionArgs - The raw transaction payload and the CAIP-2 chain ID. For more details on the transaction object see SIP-3.
interface OnTransactionArgs {
transaction: Record<string, unknown>;
chainId: string;
}

Returns​

type OnTransactionHandlerReturn = Promise<OnTransactionResponse>;

interface OnTransactionResponse {
insights: { [key: string]: unknown };
}
  • onTransactionResponse - The insights object returned by the snap is displayed alongside the confirmation for the transaction that onTransaction was called with. Keys and values are displayed in the order received, with each key rendered as a title and each value rendered as a string.

Examples​

TypeScript​

import { OnTransactionHandler } from "@metamask/snap-types";

export const onTransaction: OnTransactionHandler = async ({
transaction,
chainId,
}) => {
const insights = /* Get insights */;
return { insights };
};

JavaScript​

module.exports.onTransaction = async ({
transaction,
chainId,
}) => {
const insights = /* Get insights */;
return { insights };
};

onCronjob​

If a snap wants to run periodic actions for the user, the snap must export a function called onCronjob. This function is called at the specified times with the specified payloads defined in the endowment:cronjob permission.

note

For the extension to call the onCronjob method of the snap, you must request the endowment:cronjob permission.

Parameters​

  • onCronjobArgs - Exclusively containing an RPC request specified in the endowment:cronjob permission.
interface onCronjobArgs {
request: JsonRpcRequest<unknown[] | { [key: string]: unknown }>;
}

Examples​

TypeScript​

import { OnCronjobHandler } from '@metamask/snap-types';

export const onCronjob: OnCronjobHandler = async ({ request }) => {
switch (request.method) {
case 'exampleMethodOne':
return wallet.request({
method: 'snap_notify',
params: [
{
type: 'inApp',
message: `Hello, world!`,
},
],
});

default:
throw new Error('Method not found.');
}
};

JavaScript​

module.exports.onCronjob = async ({ request }) => {
switch (request.method) {
case 'exampleMethodOne':
return wallet.request({
method: 'snap_notify',
params: [
{
type: 'inApp',
message: `Hello, world!`,
},
],
});

default:
throw new Error('Method not found.');
}
};