Create an account management Snap
Create an account management Snap to connect to custom EVM accounts.
Prerequisites
- Set up a Snap. See the Snaps quickstart and how to develop a Snap.
- Read the account management Snap security guidelines.
Steps
1. Install the Keyring API
Install the @metamask/keyring-api
module in your
project directory using Yarn or npm:
yarn add @metamask/keyring-api
or
npm install @metamask/keyring-api
2. Add permissions
Specify the following permissions in your Snap manifest file:
"initialPermissions": {
"endowment:keyring": {
"allowedOrigins": [
"https://<dapp domain>"
]
},
"endowment:rpc": {
"dapps": true
},
"snap_manageAccounts": {},
"snap_manageState": {}
},
Add a list of dapp URLs allowed to call Keyring API methods on your Snap using the
endowment:keyring
permission.
3. Implement the Account Management API
Implement the Account Management API in your Snap. Make sure to limit the methods exposed to dapps.
class MySnapKeyring implements Keyring {
// Implement the required methods here.
}
4. Handle requests submitted by MetaMask
MetaMask submits EVM requests from dapps using the
keyring_submitRequest
method of the Keyring API.
See the EVM methods for externally owned accounts
and ERC-4337 accounts.
The following is an example of a personal_sign
request:
{
"id": "d6e23af6-4bea-48dd-aeb0-7d3c30ea67f9",
"scope": "",
"account": "69438371-bef3-4957-9f91-c3f22c1d75f3",
"request": {
"method": "personal_sign",
"params": [
"0x4578616d706c652060706572736f6e616c5f7369676e60206d657373616765",
"0x5874174dcf1ab6F7Efd8496f4f09404CD1c5bA84"
]
}
}
The request includes:
id
- The unique identifier for the request.scope
- The CAIP-2 chain ID of the selected chain. Currently, this property is always an empty string. Your Snap should use the chain ID present in the request object instead.account
- The ID of the account that should handle the request.request
- The request object.
Your Snap must respond with either a synchronous or asynchronous result:
- Synchronous
- Asynchronous
return { pending: false, result }
return { pending: true, redirect: { message, url } }
The redirect message and URL are displayed to the user to help them continue the transaction flow.
5. Notify MetaMask about events
Notify MetaMask when Account Management API events
take place, using the emitSnapKeyringEvent()
helper function.
For example, when an account is created:
try {
emitSnapKeyringEvent(snap, KeyringEvent.AccountCreated, { account })
// Update your Snap's state.
} catch (error) {
// Handle the error.
}
MetaMask returns an error if the account already exists or the account object is invalid.
6. Expose the Account Management API
Create an onKeyringRequest
entry point handler
method to expose the Account Management API methods to MetaMask and your dapp:
export const onKeyringRequest: OnKeyringRequestHandler = async ({
origin,
request,
}) => {
// Add custom logic here.
return handleKeyringRequest(keyring, request)
}
7. Create a companion dapp
Create a companion dapp to provide a user interface for your account management Snap, enabling them to create and interact with custom EVM accounts.
Example
See the example account management Snap source code for more information.