| description | sidebar_position |
|---|---|
See the Snaps entry points reference. |
4 |
import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem";
Snaps can expose the following entry points.
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.
:::note
For MetaMask to call the Snap's onCronjob method, you must request the
endowment:cronjob permission.
:::
An object containing an RPC request specified in the endowment:cronjob permission.
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.")
}
}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.
:::note
For MetaMask to call the Snap's onHomePage method, you must request the
endowment:page-home permission.
:::
None.
One of the following:
- A
contentobject displayed using custom UI. - An
idreturned bysnap_createInterfacefor interactive UI.
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!"),
]),
}
}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.
:::note
For MetaMask to call the Snap's onInstall method, you must request the
endowment:lifecycle-hooks permission.
:::
None.
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)."
),
]),
},
})
}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.
:::note
For MetaMask to call the Snap's onKeyringRequest method, you must request the
endowment:keyring permission.
:::
An object containing:
origin- The origin as a string.request- The JSON-RPC request.
A promise containing the return of the implemented method.
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)
}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.
:::note
For MetaMask to call the Snap's onNameLookup method, you must request the
endowment:name-lookup permission.
:::
An object containing:
chainId- The CAIP-2 chain ID.addressordomain- One of these parameters is defined, and the other is undefined.
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
}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.
:::note
For MetaMask to call the Snap's onRpcRequest method, you must request the
endowment:rpc permission.
:::
An object containing:
origin- The origin as a string.request- The JSON-RPC request.
A promise containing the return of the implemented method.
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.")
}
}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.
:::note
For MetaMask to call the Snap's onSignature method, you must request the
endowment:signature-insight permission.
:::
An object containing:
signature- The raw signature payload.signatureOrigin- The signature origin ifallowSignatureOriginis set totrue.
- 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.
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,
};
};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.
:::note
For MetaMask to call the Snap's onTransaction method, you must request the
endowment:transaction-insight permission.
:::
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.
:::note
When interacting with EVM chain IDs, the provided chain ID uses the format namespace:reference, where the reference is a base 10 integer.
:::
- 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
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))),
]),
};
};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.
:::note
For MetaMask to call the Snap's onUpdate method, you must request the
endowment:lifecycle-hooks permission.
:::
None.
import type { OnUpdateHandler } from "@metamask/snaps-sdk";
import { Box, Heading, Text } from "@metamask/snaps-sdk/jsx";
export const onUpdate: OnUpdateHandler = async () => {
await snap.request({
method: "snap_dialog",
params: {
type: "alert",
content: (
<Box>
<Heading>Thank you for updating my Snap</Heading>
<Text>New features added in this version:</Text>
<Text>Added a dialog that appears when updating.</Text>
</Box>
),
},
})
}import type { OnUpdateHandler } from "@metamask/snaps-sdk";
import { heading, panel, text } from "@metamask/snaps-sdk";
export const onUpdate: OnUpdateHandler = async () => {
await snap.request({
method: "snap_dialog",
params: {
type: "alert",
content: panel([
heading("Thank you for updating my Snap"),
text("New features added in this version:"),
text("Added a dialog that appears when updating."),
]),
},
})
}To respond to interactive UI events, a Snap must export onUserInput.
id- The ID of the interface being acted on.event- An event object containing:type- The type of the event. Possible values areButtonClickEvent,FormSubmitEvent,InputChangeEvent, andFileInputEvent. These enums are exported from the@metamask/snaps-sdkmodule.name- The name of the component that fired the event. Optional when the event type isButtonClickEvent.value- When the event type isFormSubmitEvent, the values in the form as an object.
context- The context object passed to the interface when callingsnap_createInterface, ornull.
import type { OnUserInputHandler } from "@metamask/snaps-sdk"
import { UserInputEventType } from "@metamask/snaps-sdk"
export const onUserInput: OnUserInputHandler = async ({ id, event }) => {
if (event.type === UserInputEventType.FormSubmitEvent) {
console.log("The submitted form values are", event.value)
}
}const { UserInputEventType } = require("@metamask/snaps-sdk")
module.exports.onUserInput = async ({ id, event }) => {
if (event.type === UserInputEventType.FormSubmitEvent) {
console.log("The submitted form values are", event.value)
}
}