Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIP-26: Non-EVM protocol support #147

Merged
merged 26 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
df817e7
Add draft of SIP-26
danroc Aug 30, 2024
df59210
Remove optional header fields
danroc Sep 2, 2024
febeb1e
Add SIP number and remove unused optional fields
danroc Sep 2, 2024
7709ea8
Rename diagram image
danroc Sep 2, 2024
48b95a3
Rename components diagram in document
danroc Sep 2, 2024
ed17dd3
Update diagram and add components descriptions
danroc Sep 12, 2024
da3182a
Rename "Address Resolution Snaps" to "Account Address Resolution Snaps"
danroc Sep 13, 2024
1a782b5
Update components diagram
danroc Sep 13, 2024
3848c61
Update `resolveAccountAddress` signature
danroc Sep 13, 2024
d514496
Add link to CAIP-2 and remove commented text
danroc Sep 13, 2024
33194a3
Add Protocol Snaps
danroc Sep 13, 2024
0c9bb3f
Update components diagram
danroc Sep 13, 2024
b4f6618
Update `resolveAccountAddress` docs
danroc Sep 13, 2024
ea35e35
Clarify: should -> MUST
danroc Sep 13, 2024
5260fba
Update `resolveAccountAddress` method
danroc Sep 16, 2024
9696ca7
Remove mention to SIP-25
danroc Sep 16, 2024
cab089f
Add note about Snap events
danroc Sep 16, 2024
b81138d
Minor text improvements
danroc Sep 16, 2024
7a99884
Add mention to CAIP-2 chain IDs
danroc Sep 24, 2024
ddd9c7d
Update keyring-api repo URL
danroc Sep 24, 2024
a0c782c
Add note about Accounts Router and Protocol Snaps priority
danroc Sep 30, 2024
72fb0c2
chore: update SIP-26 following latest discussions
danroc Nov 12, 2024
739f165
SIP-26: Update Snaps-specific parts of the specification (#153)
FrederikBolding Nov 14, 2024
f59f3cc
chore: update title
danroc Nov 14, 2024
7b35ebc
Apply suggestions from code review
FrederikBolding Nov 14, 2024
8a0171a
Update SIPS/sip-26.md
FrederikBolding Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 197 additions & 0 deletions SIPS/sip-26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
sip: 26
title: Non-EVM protocol support
status: Draft
author: Daniel Rocha (@danroc), Frederik Bolding (@FrederikBolding), Alex Donesky (@adonesky1)
created: 2024-08-28
---

## Abstract

This SIP presents an architecture to enable Snaps to expose blockchain-specific
methods to dapps, extending MetaMask's functionality to support a multichain
ecosystem.

## Motivation

Currently, MetaMask is limited to EVM-compatible networks. This proposal aims
to empower developers, both first- and third-party, to use Snaps to add native
support for non-EVM-compatible chains within MetaMask.

## Specification

> Formal specifications are written in TypeScript.

### Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" written
in uppercase in this document are to be interpreted as described in [RFC
2119](https://www.ietf.org/rfc/rfc2119.txt).

### High-Level architecture

The diagram below represents a high-level architecture of how the RPC Router
integrates inside MetaMask to allow Snaps to expose protocol methods to dapps
and the MetaMask clients.

![High-level architecture](../assets/sip-26/components-diagram.png)

- **Account Snaps**: Snaps that implement the [Keyring API][keyring-api] and are responsible
for signing requests and managing accounts.

- **Protocol Snaps**: Snaps that implement protocol methods that do not require
an account to be executed.

- **RPC Router**: Native component that forwards RPC requests to the
appropriate Protocol Snap or Account Snap.

- **Keyring Controller**: Native component responsible for forwarding signing
requests to the appropriate keyring implementation.

- **Accounts Controller**: Native component responsible for managing accounts
inside MetaMask. It stores all non-sensitive account information.

- **Snaps Keyring**: Native component that acts as a bridge between the
Keyring Controller and the Account Snaps.

### Components

Here is a brief description of the components involved in this architecture
which will require to be implemented or modified.

#### RPC Router

The RPC Router will be a new native component responsible for routing JSON-RPC
requests to the appropriate Snap or keyring.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it confusing to separate keyring from Snap here since all the keyrings we route to are Snap keyrings?

Suggested change
requests to the appropriate Snap or keyring.
requests to the appropriate Snap.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I dunno this isn't a big deal and maybe its better as is

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I think this is fine as-is since we don't wanna route directly to keyring Snaps, but to the native keyring controlling them. It is a minor detail though


To route a request, the RPC Router MUST extract the method name and [CAIP-2 chainId][caip-2]
from the request object. It then determines whether the method is supported by
a Protocol Snap or an Account Snap, with Account Snaps taking precedence over
Protocol Snaps.

If the method is supported by an Account Snap, the RPC Router forwards the
request to the Keyring Controller; otherwise, it forwards the request to the
appropriate Protocol Snap.

#### Snaps Keyring

The Snaps Keyring is an existing native component that exposes the
[snap_manageAccounts][snap-manage-accs] method, allowing Account Snaps to
register, remove, and update accounts.

For example, this code can be used by an Account Snap to register a new account
with the Account Router:

```typescript
// This will notify the Account Router that a new account was created, and the
// Account Router will register this account as available for signing requests
// using the `eth_signTypedData_v4` method.
await snap.request({
method: "snap_manageAccounts",
params: {
method: "notify:accountCreated",
params: {
account: {
id: "74bb3393-f267-48ee-855a-2ba575291ab0",
type: "eip155:eoa",
address: "0x1234567890123456789012345678901234567890",
methods: ["eth_signTypedData_v4"],
Comment on lines +97 to +99
Copy link
Contributor

@adonesky1 adonesky1 Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] since this SIP is for non-evm snaps should we provide a non-evm example here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I'm still wondering how we plan to standardize non-evm account types. Currently our documentation only appears to describe eip155:eoa or eip155:erc4337

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been requesting this as well, we need a more generic type that allows any protocol. IIRC @danroc and team are thinking about how to do that.

options: {},
},
},
},
});
```

Similar events are available to notify about the removal and update of
accounts: `notify:accountRemoved` and `notify:accountUpdated`.

Additionally, the Snaps Keyring expects the Account Snap to implement the
Keyring API so it can forward signing requests to it through the
[`keyring_submitRequest`][submit-request] method.

#### Account Snaps

As part of the Keyring API, non-EVM Account Snaps MUST also implement support
for the `keyring_resolveAccountAddress` RPC method defined below. It is used
by the RPC Router to extract the address of the account that should handle
the signing request from the request object.

```typescript
type ResolveAccountAddressRequest = {
method: "keyring_resolveAccountAddress";
params: {
scope: CaipChainId;
request: JsonRpcRequest;
};
};
```
`scope` - The [CAIP-2][caip-2] chainId the request is targeting

`request` - A `JsonRpcRequest` containing strictly JSON-serializable values.
FrederikBolding marked this conversation as resolved.
Show resolved Hide resolved

FrederikBolding marked this conversation as resolved.
Show resolved Hide resolved
The implementation MUST return a value of the type `{ address: string }` or `null`.

#### Protocol Snaps

Protocol Snaps implement and expose methods that do not require an account to
execute and MUST list their supported methods and notifications in their manifest file:

```json5
"initialPermissions": {
"endowment:protocol": {
"scopes": {
"<caip2_chainId>": {
"methods": [
// List of supported methods
],
"notifications": [
// List of supported notifications
]
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as below, should resemble caip-25 permission: https://github.com/MetaMask/SIPs/pull/147/files#r1777172390

}
```

Additionally protocol Snaps MUST implement the `onProtocolRequest` handler:

```typescript
import { OnProtocolRequestHandler } from "@metamask/snap-sdk";

export const onProtocolRequest: OnProtocolRequestHandler = async ({
origin,
scope,
request,
}) => {
// Return protocol responses
};
```

The interface for an `onProtocolRequest` handler function’s arguments is:

```typescript
interface OnProtocolRequestArguments {
origin: string;
scope: CaipChainId;
request: JsonRpcRequest;
}
```

`origin` - The origin making the protocol request (i.e. a dapp).

`scope` - The [CAIP-2][caip-2] chainId the request is targeting.

`request` - A `JsonRpcRequest` containing strictly JSON-serializable values.

Any JSON-serializable value is allowed as the return value for `onProtocolRequest`.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE).

[keyring-api]: https://github.com/MetaMask/accounts/tree/main/packages/keyring-api
[snap-manage-accs]: https://docs.metamask.io/snaps/reference/snaps-api/#snap_manageaccounts
[submit-request]: https://docs.metamask.io/snaps/reference/keyring-api/account-management/#keyring_submitrequest
[caip-2]: https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md
Binary file added assets/sip-26/components-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading