Snaps entry points
Snaps can expose the following entry points.
onCronjob
To run cron jobs 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 permission.
For MetaMask to call the Snap's onCronjob method, you must request the
endowment:cronjob permission.
Parameters
An object containing an RPC request specified in the endowment:cronjob permission.
Example
- TypeScript
- JavaScript
import type { OnCronjobHandler } from "@metamask/snaps-sdk"
export const onCronjob: OnCronjobHandler = async ({ request }) => {
switch (request.method) {
case "exampleMethodOne":
return snap.request({
method: "snap_notify",
params: {
type: "inApp",
message: "Hello, world!",
},
})
default:
throw new Error("Method not found.")
}
}
module.exports.onCronjob = async ({ request }) => {
switch (request.method) {
case "exampleMethodOne":
return snap.request({
method: "snap_notify",
params: {
type: "inApp",
message: "Hello, world!",
},
})
default:
throw new Error("Method not found.")
}
}
onHomePage
To display a home page within MetaMask, a Snap must expose
the onHomePage entry point.
MetaMask calls the onHomePage handler method when the user selects the Snap name in the Snaps menu.
For MetaMask to call the Snap's onHomePage method, you must request the
endowment:page-home permission.
Parameters
None.
Returns
One of the following:
- A
contentobject displayed using custom UI. - An
idreturned bysnap_createInterfacefor interactive UI.
Example
- JSX
- Functions
import type { OnHomePageHandler } from "@metamask/snaps-sdk";
import { Box, Heading, Text } from "@metamask/snaps-sdk/jsx";
export const onHomePage: OnHomePageHandler = async () => {
return {
content: (
<Box>
<Heading>Hello world!</Heading>
<Text>Welcome to my Snap home page!</Text>
</Box>
),
};
};
import { panel, text, heading } from "@metamask/snaps-sdk"
module.exports.onHomePage = async () => {
return {
content: panel([
heading("Hello world!"),
text("Welcome to my Snap home page!"),
]),
}
}
onInstall
To implement a lifecycle hook that runs an action upon
installation, a Snap must expose the onInstall entry point.
MetaMask calls the onInstall handler method after the Snap is installed successfully.
For MetaMask to call the Snap's onInstall method, you must request the
endowment:lifecycle-hooks permission.
Parameters
None.
Example
- JSX
- Functions
import type { OnInstallHandler } from "@metamask/snaps-sdk";
import { Box, Heading, Text } from "@metamask/snaps-sdk/jsx";
export const onInstall: OnInstallHandler = async () => {
await snap.request({
method: "snap_dialog",
params: {
type: "alert",
content: (
<Box>
<Heading>Thank you for installing my Snap</Heading>
<Text>
To use this Snap, visit the companion dapp at <a href="https://metamask.io">metamask.io</a>.
</Text>
</Box>
),
},
});
};
import { heading, panel, text } from "@metamask/snaps-sdk"
module.exports.onInstall = async () => {
await snap.request({
method: "snap_dialog",
params: {
type: "alert",
content: panel([
heading("Thank you for installing my Snap"),
text(
"To use this Snap, visit the companion dapp at [metamask.io](https://metamask.io)."
),
]),
},
})
}
onKeyringRequest
To implement the Account Management API to integrate
custom EVM accounts, an account management Snap must
expose the onKeyringRequest entry point.
Whenever the Snap receives an Account Management API request, MetaMask calls the onKeyringRequest
handler method.
For MetaMask to call the Snap's onKeyringRequest method, you must request the
endowment:keyring permission.
Parameters
An object containing:
origin- The origin as a string.request- The JSON-RPC request.
Returns
A promise containing the return of the implemented method.
Example
- TypeScript
- JavaScript
export const onKeyringRequest: OnKeyringRequestHandler = async ({
origin,
request,
}) => {
// Any custom logic or extra security checks here.
return handleKeyringRequest(keyring, request)
}
module.exports.onKeyringRequest = async ({ origin, request }) => {
// Any custom logic or extra security checks here.
return handleKeyringRequest(keyring, request)
}
onNameLookup
To provide custom name resolution, a Snap must export onNameLookup.
Whenever a user types in the send field, MetaMask calls this method.
MetaMask passes the user input to the onNameLookup handler method.
For MetaMask to call the Snap's onNameLookup method, you must request the
endowment:name-lookup permission.
Parameters
An object containing:
chainId- The CAIP-2 chain ID.addressordomain- One of these parameters is defined, and the other is undefined.
Example
- TypeScript
- JavaScript
import type { OnNameLookupHandler } from "@metamask/snaps-sdk"
export const onNameLookup: OnNameLookupHandler = async (request) => {
const { chainId, address, domain } = request
if (address) {
const shortAddress = address.substring(2, 5)
const chainIdDecimal = parseInt(chainId.split(":")[1], 10)
const resolvedDomain = `${shortAddress}.${chainIdDecimal}.test.domain`
return { resolvedDomains: [{ resolvedDomain, protocol: "test protocol" }] }
}
if (domain) {
const resolvedAddress = "0xc0ffee254729296a45a3885639AC7E10F9d54979"
return {
resolvedAddresses: [{ resolvedAddress, protocol: "test protocol", domainName: domain }],
}
}
return null
}
module.exports.onNameLookup = async ({ request }) => {
const { chainId, address, domain } = request
if (address) {
const shortAddress = address.substring(2, 5)
const chainIdDecimal = parseInt(chainId.split(":")[1], 10)
const resolvedDomain = `${shortAddress}.${chainIdDecimal}.test.domain`
return { resolvedDomains: [{ resolvedDomain, protocol: "test protocol" }] }
}
if (domain) {
const resolvedAddress = "0xc0ffee254729296a45a3885639AC7E10F9d54979"
return {
resolvedAddresses: [{ resolvedAddress, protocol: "test protocol", domainName: domain }],
}
}
return null
}
onRpcRequest
To implement a custom JSON-RPC API to communicate with
dapps and other Snaps, a Snap must expose the onRpcRequest entry point.
Whenever the Snap receives a JSON-RPC request, MetaMask calls the onRpcRequest handler method.
For MetaMask to call the Snap's onRpcRequest method, you must request the
endowment:rpc permission.
Parameters
An object containing:
origin- The origin as a string.request- The JSON-RPC request.
Returns
A promise containing the return of the implemented method.
Example
- TypeScript
- JavaScript
import type { OnRpcRequestHandler } from "@metamask/snaps-sdk"
export const onRpcRequest: OnRpcRequestHandler = async ({
origin,
request,
}) => {
switch (request.method) {
case "hello":
return "world!"
default:
throw new Error("Method not found.")
}
}
module.exports.onRpcRequest = async ({ origin, request }) => {
switch (request.method) {
case "hello":
return "world!"
default:
throw new Error("Method not found.")
}
}
onSignature
To provide signature insights before a user signs a message, a
Snap must expose the onSignature entry point.
Whenever a signing method is called, such as personal_sign or
eth_signTypedData_v4, MetaMask passes the raw unsigned signature payload to the onSignature
handler method.
For MetaMask to call the Snap's onSignature method, you must request the
endowment:signature-insight permission.
Parameters
An object containing:
signature- The raw signature payload.signatureOrigin- The signature origin ifallowSignatureOriginis set totrue.
Returns
- An optional
severityproperty that, if present, must be set toSeverityLevel.Critical. - A
contentobject displayed using custom UI after the user selects the Sign button. Due to current limitations of MetaMask's signature confirmation UI, the content will only be displayed if theseverityproperty is present and set toSeverityLevel.Critical.
Example
- JSX
- Functions
import type { OnSignatureHandler, SeverityLevel } from "@metamask/snaps-sdk";
import { Box, Heading, Text } from "@metamask/snaps-sdk/jsx";
export const onSignature: OnSignatureHandler = async ({
signature,
signatureOrigin,
}) => {
const insights = /* Get insights */;
return {
content: (
<Box>
<Heading>My Signature Insights</Heading>
<Text>Here are the insights:</Text>
{insights.map((insight) => (
<Text>{insight.value}</Text>
))}
</Box>
),
severity: SeverityLevel.Critical,
};
};
import type { OnSignatureHandler, SeverityLevel } from "@metamask/snaps-sdk";
import { panel, heading, text } from "@metamask/snaps-sdk";
export const onSignature: OnSignatureHandler = async ({
signature,
signatureOrigin,
}) => {
const insights = /* Get insights */;
return {
content: panel([
heading("My Signature Insights"),
text("Here are the insights:"),
...(insights.map((insight) => text(insight.value))),
]),
severity: SeverityLevel.Critical,
};
};
onTransaction
To provide transaction insights before a user signs a
transaction, a Snap must expose the onTransaction entry point.
When a user submits a transaction in the MetaMask extension, MetaMask calls the onTransaction
handler method.
MetaMask passes the raw unsigned transaction payload to onTransaction.
For MetaMask to call the Snap's onTransaction method, you must request the
endowment:transaction-insight permission.
Parameters
An object containing:
transaction- The raw transaction payload. Learn more about the parameters of a submitted transaction.chainId- The CAIP-2 chain ID.transactionOrigin- The transaction origin ifallowTransactionOriginis set totrue.
When interacting with EVM chain IDs, the provided chain ID uses the format namespace:reference, where the reference is a base 10 integer.
Returns
- An optional
severityproperty that, if present, must be set to"critical". This feature is only available in Flask. - One of the following:
- A
contentobject displayed using custom UI, alongside the confirmation for the transaction thatonTransactionwas called with. - An
idreturned bysnap_createInterfacefor interactive UI.
- A
Example
- JSX
- Functions
import type { OnTransactionHandler } from "@metamask/snaps-sdk";
import { Box, Heading, Text } from "@metamask/snaps-sdk/jsx";
export const onTransaction: OnTransactionHandler = async ({
transaction,
chainId,
transactionOrigin,
}) => {
const insights = /* Get insights */;
return {
content: (
<Box>
<Heading>My Transaction Insights</Heading>
<Text>Here are the insights:</Text>
{insights.map((insight) => (
<Text>{insight.value}</Text>
))}
</Box>
),
};
};
import type { OnTransactionHandler } from "@metamask/snaps-sdk";
import { panel, heading, text } from "@metamask/snaps-sdk";
export const onTransaction: OnTransactionHandler = async ({
transaction,
chainId,
transactionOrigin,
}) => {
const insights = /* Get insights */;
return {
content: panel([
heading("My Transaction Insights"),
text("Here are the insights:"),
...(insights.map((insight) => text(insight.value))),
]),
};
};
onUpdate
To implement a lifecycle hook that runs an action upon update, a
Snap must expose the onUpdate entry point.
MetaMask calls the onUpdate handler method after the Snap is updated successfully.
For MetaMask to call the Snap's onUpdate method, you must request the
endowment:lifecycle-hooks permission.
Parameters
None.