This documentation covers the JSON-RPC methods provided by the SnapInterfaceController
for generating user interfaces in MetaMask Snaps.
The MetaMask Snaps platform provides a JSON-RPC API for Snaps (third-party extensions) to create and interact with user interfaces within the MetaMask environment. These interfaces allow Snaps to display information, collect user input, and provide interactive experiences without requiring direct DOM access.
Displays a dialog to the user with customizable content and interface elements.
interface DialogParams {
type: DialogType;
content: DialogContent;
}
type DialogType = 'alert' | 'confirmation' | 'prompt';
type DialogContent = {
prompt?: string;
description?: string;
placeholder?: string;
textAreaContent?: string | null;
};
- Alert: Displays a message to the user with an acknowledgment button.
- Confirmation: Asks the user to confirm or reject an action.
- Prompt: Requests text input from the user.
- For
alert
: Returnsnull
when the user acknowledges the alert. - For
confirmation
: Returnstrue
if the user confirms,false
if they reject. - For
prompt
: Returns the user-entered string if confirmed, ornull
if canceled.
// Display an alert
await ethereum.request({
method: 'snap_dialog',
params: {
type: 'alert',
content: {
prompt: 'Operation Successful',
description: 'Your transaction has been submitted to the network.'
}
}
});
// Request confirmation
const confirmed = await ethereum.request({
method: 'snap_dialog',
params: {
type: 'confirmation',
content: {
prompt: 'Confirm Transaction',
description: 'Do you want to send 0.1 ETH to 0x1234...?'
}
}
});
// Request user input
const userInput = await ethereum.request({
method: 'snap_dialog',
params: {
type: 'prompt',
content: {
prompt: 'Enter password',
description: 'Please provide your password to continue',
placeholder: 'Password'
}
}
});
Allows a Snap to manage its persistent state.
interface ManageStateParams {
operation: ManageStateOperation;
newState?: Record<string, unknown>;
}
type ManageStateOperation = 'clear' | 'get' | 'update';
- get: Retrieves the current state.
- update: Updates the state with new values.
- clear: Clears all stored state.
- For
get
: Returns the current state object. - For
update
: Returnsnull
after updating. - For
clear
: Returnsnull
after clearing.
// Get current state
const state = await ethereum.request({
method: 'snap_manageState',
params: { operation: 'get' }
});
// Update state
await ethereum.request({
method: 'snap_manageState',
params: {
operation: 'update',
newState: { userPreference: 'dark-mode' }
}
});
// Clear state
await ethereum.request({
method: 'snap_manageState',
params: { operation: 'clear' }
});
Displays a notification to the user.
interface NotifyParams {
type: NotificationType;
message: string;
}
type NotificationType = 'native' | 'inApp';
- native: Sends a native system notification.
- inApp: Displays a notification within the MetaMask interface.
Returns null
after showing the notification.
// Display an in-app notification
await ethereum.request({
method: 'snap_notify',
params: {
type: 'inApp',
message: 'Transaction confirmed!'
}
});
// Send a native system notification
await ethereum.request({
method: 'snap_notify',
params: {
type: 'native',
message: 'Your funds have arrived'
}
});
Creates a custom interface element that can be displayed to the user.
interface CreateInterfaceParams {
ui: InterfaceDefinition;
}
type InterfaceDefinition = {
type: string;
// Additional properties depend on the interface type
};
Returns an interface handle that can be used with other interface methods.
// Create a custom form interface
const interfaceHandle = await ethereum.request({
method: 'snap_createInterface',
params: {
ui: {
type: 'form',
fields: [
{
type: 'text',
label: 'Username',
name: 'username',
required: true
},
{
type: 'password',
label: 'Password',
name: 'password',
required: true
}
],
submitButton: 'Login'
}
}
});
Displays a previously created interface to the user.
interface ShowInterfaceParams {
interfaceId: string;
}
Returns data based on user interaction with the interface.
// Show a previously created interface
const userResponse = await ethereum.request({
method: 'snap_showInterface',
params: {
interfaceId: interfaceHandle
}
});
Retrieves the current state of a created interface.
interface GetInterfaceStateParams {
interfaceId: string;
}
Returns the current state of the specified interface.
// Get the current state of an interface
const interfaceState = await ethereum.request({
method: 'snap_getInterfaceState',
params: {
interfaceId: interfaceHandle
}
});
Updates an existing interface with new properties or content.
interface UpdateInterfaceParams {
interfaceId: string;
updates: Partial<InterfaceDefinition>;
}
Returns null
after updating the interface.
// Update an existing interface
await ethereum.request({
method: 'snap_updateInterface',
params: {
interfaceId: interfaceHandle,
updates: {
fields: [
// Updated field definitions
]
}
}
});
Dismisses a currently displayed interface.
interface DismissInterfaceParams {
interfaceId: string;
}
Returns null
after dismissing the interface.
// Dismiss an interface
await ethereum.request({
method: 'snap_dismissInterface',
params: {
interfaceId: interfaceHandle
}
});
All methods may throw errors with the following structure:
interface SnapRpcError {
code: number;
message: string;
data?: unknown;
}
Common error codes:
-32603
: Internal error-32602
: Invalid parameters-32001
: User rejected request-32000
: Method not supported
- All UI interactions require user approval and are subject to the permissions granted to the Snap.
- Snaps should handle user rejection gracefully, as users may dismiss dialogs or reject confirmations.
- State management should implement proper validation to prevent injection attacks.
- Keep dialog messages clear and concise.
- Provide adequate context for confirmation requests.
- Use appropriate dialog types for the required interaction.
- Implement proper error handling for rejected requests.
- Minimize the frequency of notifications to avoid overwhelming users.
- Follow MetaMask's design guidelines when creating custom interfaces.
- Always validate and sanitize user input received through prompts.