For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at the same URL with .md appended (or via Accept: text/markdown).
Skip to main content

Create an account management Snap

Create an account management Snap to connect to custom EVM accounts.

Prerequisites​

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:

snap.manifest.json
"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.

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:

return { pending: false, result }

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.