Skip to content

Commit d2a8c29

Browse files
danrocgantunesrccharlyFrederikBoldingadonesky1
authored
SIP-26: Non-EVM protocol support (#147)
* Add draft of SIP-26 * Remove optional header fields * Add SIP number and remove unused optional fields * Rename diagram image * Rename components diagram in document * Update diagram and add components descriptions * Rename "Address Resolution Snaps" to "Account Address Resolution Snaps" * Update components diagram * Update `resolveAccountAddress` signature * Add link to CAIP-2 and remove commented text * Add Protocol Snaps * Update components diagram * Update `resolveAccountAddress` docs * Clarify: should -> MUST * Update `resolveAccountAddress` method * Remove mention to SIP-25 * Add note about Snap events * Minor text improvements * Add mention to CAIP-2 chain IDs Co-authored-by: Gustavo Antunes <[email protected]> * Update keyring-api repo URL Co-authored-by: Charly Chevalier <[email protected]> * Add note about Accounts Router and Protocol Snaps priority * chore: update SIP-26 following latest discussions * SIP-26: Update Snaps-specific parts of the specification (#153) * SIP-26: Update Snaps-specific parts of the specification * Minor updates * Reword slightly * Update SIPS/sip-26.md Co-authored-by: Alex Donesky <[email protected]> --------- Co-authored-by: Alex Donesky <[email protected]> * chore: update title Co-authored-by: Frederik Bolding <[email protected]> * Apply suggestions from code review Co-authored-by: Alex Donesky <[email protected]> * Update SIPS/sip-26.md --------- Co-authored-by: Gustavo Antunes <[email protected]> Co-authored-by: Charly Chevalier <[email protected]> Co-authored-by: Frederik Bolding <[email protected]> Co-authored-by: Alex Donesky <[email protected]>
1 parent f881be2 commit d2a8c29

File tree

2 files changed

+197
-0
lines changed

2 files changed

+197
-0
lines changed

SIPS/sip-26.md

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
---
2+
sip: 26
3+
title: Non-EVM protocol support
4+
status: Draft
5+
author: Daniel Rocha (@danroc), Frederik Bolding (@FrederikBolding), Alex Donesky (@adonesky1)
6+
created: 2024-08-28
7+
---
8+
9+
## Abstract
10+
11+
This SIP presents an architecture to enable Snaps to expose blockchain-specific
12+
methods to dapps, extending MetaMask's functionality to support a multichain
13+
ecosystem.
14+
15+
## Motivation
16+
17+
Currently, MetaMask is limited to EVM-compatible networks. This proposal aims
18+
to empower developers, both first- and third-party, to use Snaps to add native
19+
support for non-EVM-compatible chains within MetaMask.
20+
21+
## Specification
22+
23+
> Formal specifications are written in TypeScript.
24+
25+
### Language
26+
27+
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
28+
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" written
29+
in uppercase in this document are to be interpreted as described in [RFC
30+
2119](https://www.ietf.org/rfc/rfc2119.txt).
31+
32+
### High-Level architecture
33+
34+
The diagram below represents a high-level architecture of how the RPC Router
35+
integrates inside MetaMask to allow Snaps to expose protocol methods to dapps
36+
and the MetaMask clients.
37+
38+
![High-level architecture](../assets/sip-26/components-diagram.png)
39+
40+
- **Account Snaps**: Snaps that implement the [Keyring API][keyring-api] and are responsible
41+
for signing requests and managing accounts.
42+
43+
- **Protocol Snaps**: Snaps that implement protocol methods that do not require
44+
an account to be executed.
45+
46+
- **RPC Router**: Native component that forwards RPC requests to the
47+
appropriate Protocol Snap or Account Snap.
48+
49+
- **Keyring Controller**: Native component responsible for forwarding signing
50+
requests to the appropriate keyring implementation.
51+
52+
- **Accounts Controller**: Native component responsible for managing accounts
53+
inside MetaMask. It stores all non-sensitive account information.
54+
55+
- **Snaps Keyring**: Native component that acts as a bridge between the
56+
Keyring Controller and the Account Snaps.
57+
58+
### Components
59+
60+
Here is a brief description of the components involved in this architecture
61+
which will require to be implemented or modified.
62+
63+
#### RPC Router
64+
65+
The RPC Router will be a new native component responsible for routing JSON-RPC
66+
requests to the appropriate Snap or keyring.
67+
68+
To route a request, the RPC Router MUST extract the method name and [CAIP-2 chainId][caip-2]
69+
from the request object. It then determines whether the method is supported by
70+
a Protocol Snap or an Account Snap, with Account Snaps taking precedence over
71+
Protocol Snaps.
72+
73+
If the method is supported by an Account Snap, the RPC Router forwards the
74+
request to the Keyring Controller; otherwise, it forwards the request to the
75+
appropriate Protocol Snap.
76+
77+
#### Snaps Keyring
78+
79+
The Snaps Keyring is an existing native component that exposes the
80+
[snap_manageAccounts][snap-manage-accs] method, allowing Account Snaps to
81+
register, remove, and update accounts.
82+
83+
For example, this code can be used by an Account Snap to register a new account
84+
with the Account Router:
85+
86+
```typescript
87+
// This will notify the Account Router that a new account was created, and the
88+
// Account Router will register this account as available for signing requests
89+
// using the `eth_signTypedData_v4` method.
90+
await snap.request({
91+
method: "snap_manageAccounts",
92+
params: {
93+
method: "notify:accountCreated",
94+
params: {
95+
account: {
96+
id: "74bb3393-f267-48ee-855a-2ba575291ab0",
97+
type: "eip155:eoa",
98+
address: "0x1234567890123456789012345678901234567890",
99+
methods: ["eth_signTypedData_v4"],
100+
options: {},
101+
},
102+
},
103+
},
104+
});
105+
```
106+
107+
Similar events are available to notify about the removal and update of
108+
accounts: `notify:accountRemoved` and `notify:accountUpdated`.
109+
110+
Additionally, the Snaps Keyring expects the Account Snap to implement the
111+
Keyring API so it can forward signing requests to it through the
112+
[`keyring_submitRequest`][submit-request] method.
113+
114+
#### Account Snaps
115+
116+
As part of the Keyring API, non-EVM Account Snaps MUST also implement support
117+
for the `keyring_resolveAccountAddress` RPC method defined below. It is used
118+
by the RPC Router to extract the address of the account that should handle
119+
the signing request from the request object.
120+
121+
```typescript
122+
type ResolveAccountAddressRequest = {
123+
method: "keyring_resolveAccountAddress";
124+
params: {
125+
scope: CaipChainId;
126+
request: JsonRpcRequest;
127+
};
128+
};
129+
```
130+
`scope` - The [CAIP-2][caip-2] chainId the request is targeting
131+
132+
`request` - A `JsonRpcRequest` containing strictly JSON-serializable values.
133+
134+
The implementation MUST return a value of the type `{ address: string }` or `null`.
135+
136+
#### Protocol Snaps
137+
138+
Protocol Snaps implement and expose methods that do not require an account to
139+
execute and MUST list their supported methods and notifications in their manifest file:
140+
141+
```json5
142+
"initialPermissions": {
143+
"endowment:protocol": {
144+
"scopes": {
145+
"<caip2_chainId>": {
146+
"methods": [
147+
// List of supported methods
148+
],
149+
"notifications": [
150+
// List of supported notifications
151+
]
152+
}
153+
}
154+
}
155+
}
156+
```
157+
158+
Additionally protocol Snaps MUST implement the `onProtocolRequest` handler:
159+
160+
```typescript
161+
import { OnProtocolRequestHandler } from "@metamask/snap-sdk";
162+
163+
export const onProtocolRequest: OnProtocolRequestHandler = async ({
164+
origin,
165+
scope,
166+
request,
167+
}) => {
168+
// Return protocol responses
169+
};
170+
```
171+
172+
The interface for an `onProtocolRequest` handler function’s arguments is:
173+
174+
```typescript
175+
interface OnProtocolRequestArguments {
176+
origin: string;
177+
scope: CaipChainId;
178+
request: JsonRpcRequest;
179+
}
180+
```
181+
182+
`origin` - The origin making the protocol request (i.e. a dapp).
183+
184+
`scope` - The [CAIP-2][caip-2] chainId the request is targeting.
185+
186+
`request` - A `JsonRpcRequest` containing strictly JSON-serializable values.
187+
188+
Any JSON-serializable value is allowed as the return value for `onProtocolRequest`.
189+
190+
## Copyright
191+
192+
Copyright and related rights waived via [CC0](../LICENSE).
193+
194+
[keyring-api]: https://github.com/MetaMask/accounts/tree/main/packages/keyring-api
195+
[snap-manage-accs]: https://docs.metamask.io/snaps/reference/snaps-api/#snap_manageaccounts
196+
[submit-request]: https://docs.metamask.io/snaps/reference/keyring-api/account-management/#keyring_submitrequest
197+
[caip-2]: https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md

assets/sip-26/components-diagram.png

1.14 MB
Loading

0 commit comments

Comments
 (0)