mirror of
https://github.com/status-im/EIPs.git
synced 2025-02-23 20:28:21 +00:00
Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft, Review, or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing
249 lines
11 KiB
Markdown
249 lines
11 KiB
Markdown
---
|
|
eip: 3085
|
|
title: Wallet Add Ethereum Chain RPC Method (`wallet_addEthereumChain`)
|
|
author: Erik Marks (@rekmarks), Pedro Gomes (@pedrouid)
|
|
discussions-to: https://github.com/ethereum/EIPs/issues/3086
|
|
status: Draft
|
|
type: Standards Track
|
|
category: Interface
|
|
created: 2020-11-01
|
|
requires: 155, 695, 3091
|
|
---
|
|
|
|
## Simple Summary
|
|
|
|
An RPC method for adding Ethereum chains to wallet applications.
|
|
|
|
## Abstract
|
|
|
|
The `wallet_addEthereumChain` RPC method allows Ethereum applications ("dapps") to suggest chains to be added to the wallet application.
|
|
The caller must specify a chain ID and some chain metadata.
|
|
The wallet application may arbitrarily refuse or accept the request.
|
|
`null` is returned if the chain was added, and an error otherwise.
|
|
|
|
Important cautions for implementers of this method are included in the [Security Considerations](#security-considerations) section.
|
|
|
|
## Motivation
|
|
|
|
A dapp may require the user to interact with multiple Ethereum chains in order to function.
|
|
A may or may not be supported by the user's wallet application.
|
|
`wallet_addEthereumChain` enables dapps to request any necessary chains to be added to the user's wallet.
|
|
This provides UX benefits for dapps and wallets that want to provide such functionality.
|
|
|
|
## Specification
|
|
|
|
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC-2119](https://www.ietf.org/rfc/rfc2119.txt).
|
|
|
|
### `wallet_addEthereumChain`
|
|
|
|
The method accepts a single object parameter, with a `chainId` and some chain metadata.
|
|
The method returns `null` if the chain was added to the wallet, and an error otherwise.
|
|
|
|
The wallet **MAY** reject the request for any reason.
|
|
The wallet **MUST** reject the request if the `chainId` is improperly formatted.
|
|
The wallet **MUST** reject the request if the wallet does not support the chain with the specified `chainId`.
|
|
|
|
> Note that this method makes **no** statement about whether the wallet should change the user's currently selected chain, if the wallet has a concept thereof.
|
|
|
|
#### Parameters
|
|
|
|
`wallet_addEthereumChain` accepts a single object parameter, specified by the following TypeScript interface:
|
|
|
|
```typescript
|
|
interface AddEthereumChainParameter {
|
|
chainId: string;
|
|
blockExplorerUrls?: string[];
|
|
chainName?: string;
|
|
iconUrls?: string[];
|
|
nativeCurrency?: {
|
|
name: string;
|
|
symbol: string;
|
|
decimals: number;
|
|
};
|
|
rpcUrls?: string[];
|
|
}
|
|
```
|
|
|
|
Only the `chainId` is required per this specification, but a wallet **MAY** require any other fields listed, impose additional requirements on them, or ignore them outright.
|
|
|
|
- `chainId`
|
|
- **MUST** specify the integer ID of the chain as a hexadecimal string, per the [`eth_chainId`](./eip-695.md) Ethereum RPC method.
|
|
- The wallet **SHOULD** compare the specified `chainId` value with the `eth_chainId` return value from the endpoint.
|
|
If these values are not identical, the wallet **MUST** reject the request.
|
|
- `blockExplorerUrls`
|
|
- If provided, **MUST** specify one or more URLs of a block explorer web site for the chain.
|
|
- The block explorer API routes **SHOULD** be compatible with [EIP-3091](./eip-3091.md).
|
|
- `chainName`
|
|
- If provided, **MUST** specify a human-readable name for the chain.
|
|
- `iconUrls`
|
|
- If provided, **MUST** specify one or more URLs pointing to reasonably sized images that can be used to visually identify the chain.
|
|
- `nativeCurrency`
|
|
- If provided, **MUST** describe the native currency of the chain using the `name`, `symbol`, and `decimals` fields.
|
|
- `decimals` **MUST** be a non-negative integer.
|
|
- `name` and `symbol` **SHOULD** be human-readable strings.
|
|
- `rpcUrls`
|
|
- If provided, **MUST** specify one or more URLs of the RPC endpoint used to communicate with the chain.
|
|
|
|
All URL string fields **MUST** include the protocol component of the URL.
|
|
HTTPS **SHOULD** always be used over HTTP.
|
|
|
|
#### Returns
|
|
|
|
The method **MUST** return `null` if the request was successful, and an error otherwise.
|
|
|
|
If a chain with the provided parameters was already added, the request is considered successful, and the method **MUST** return `null`.
|
|
|
|
The wallet **SHOULD NOT** allow the same `chainId` to be added multiple times.
|
|
See [Security Considerations](#security-considerations) for more information.
|
|
|
|
### Examples
|
|
|
|
These examples use JSON-RPC, but the method could be implemented using other RPC protocols.
|
|
|
|
To add the Goerli test chain:
|
|
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"jsonrpc": "2.0",
|
|
"method": "wallet_addEthereumChain",
|
|
"params": [
|
|
{
|
|
"chainId": "0x5",
|
|
"chainName": "Goerli",
|
|
"rpcUrls": ["https://goerli.infura.io/v3/INSERT_API_KEY_HERE"],
|
|
"nativeCurrency": {
|
|
"name": "Goerli ETH",
|
|
"symbol": "gorETH",
|
|
"decimals": 18
|
|
},
|
|
"blockExplorerUrls": ["https://goerli.etherscan.io"]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
To add POA Network's xDAI chain:
|
|
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"jsonrpc": "2.0",
|
|
"method": "wallet_addEthereumChain",
|
|
"params": [
|
|
{
|
|
"chainId": "0x64",
|
|
"chainName": "xDAI Chain",
|
|
"rpcUrls": ["https://dai.poa.network"],
|
|
"iconUrls": [
|
|
"https://xdaichain.com/fake/example/url/xdai.svg",
|
|
"https://xdaichain.com/fake/example/url/xdai.png"
|
|
],
|
|
"nativeCurrency": {
|
|
"name": "xDAI",
|
|
"symbol": "xDAI",
|
|
"decimals": 18
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
In the above example, notice that the `iconUrls` array contains URLs pointing to two different image formats.
|
|
|
|
A success response:
|
|
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"jsonrpc": "2.0",
|
|
"result": null
|
|
}
|
|
```
|
|
|
|
A failure response:
|
|
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"jsonrpc": "2.0",
|
|
"error": {
|
|
"code": 4001,
|
|
"message": "The user rejected the request."
|
|
}
|
|
}
|
|
```
|
|
|
|
## Rationale
|
|
|
|
The design of `wallet_addEthereumChain` is deliberately ignorant of what it means to "add" a chain to a wallet.
|
|
The meaning of "adding" a chain to a wallet depends on the wallet implementation.
|
|
Ultimately, neither the user nor the dapp can now whether adding the chain "worked" until they have successfully interacted with it.
|
|
|
|
When calling the method, specifying the `chainId` will always be necessary, since in the universe of Ethereum chains, the [EIP-155](./eip-155.md) chain ID is effectively the GUID of a chain.
|
|
The remaining parameters amount to what, in the estimation of authors, a wallet will minimally require in order to effectively support a chain and accurately represent it to the user.
|
|
The network ID (per the `net_version` RPC method) was omitted since it is effectively superseded by the chain ID.
|
|
|
|
For [security reasons](#security-considerations), a wallet should always attempt to validate the chain metadata provided by the dapp, and may choose to fetch the metadata elsewhere entirely.
|
|
Either way, there's no way to know what the wallet will _need_ with respect to the chain metadata.
|
|
Therefore, all parameters except `chainId` are listed as optional, even though a wallet may require them in practice.
|
|
|
|
This specification does not mandate that the wallet "switches" its active chain, if the result is successful.
|
|
|
|
For related work, see [EIP-2015](./eip-2015.md).
|
|
|
|
## Security Considerations
|
|
|
|
`wallet_addEthereumChain` is a powerful method that exposes the end user to serious risks if implemented incorrectly.
|
|
Most of these risks can be avoided by validating the request data in the wallet, and clearly disambiguating different chains in the wallet UI.
|
|
|
|
### Chain IDs
|
|
|
|
Since the chain ID used for signing determines which chain a transaction is valid for, handling the chain ID correctly is of utmost importance.
|
|
The wallet should:
|
|
|
|
- Ensure that a submitted chain ID is valid.
|
|
- It should be submitted as a `0x`-prefixed hexadecimal string per [EIP-695](./eip-695.md), and parse to an integer number.
|
|
- Prevent the same chain ID from being added multiple times.
|
|
- See the next section for how to handle multiple RPC endpoints.
|
|
- Only use the submitted chain ID to sign transactions, **never** a chain ID received from an RPC endpoint.
|
|
- A malicious or faulty endpoint could return arbitrary chain IDs, and potentially cause the user to sign transactions for unintended chains.
|
|
- Verify that the specified chain ID matches the return value of `eth_chainId` from the endpoint, as described in [this specification](#parameters).
|
|
|
|
### RPC Endpoints and RPC URLs
|
|
|
|
Wallets generally interact with chains via an RPC endpoint, identified by some URL.
|
|
Most wallets ship with a set of chains and corresponding trusted RPC endpoints.
|
|
The endpoints identified by the `rpcUrls` parameter cannot be assumed to be honest, correct, or ultimately pointing to the same chain.
|
|
Moreover, even trusted endpoints endpoints can expose users to privacy risks depending on their data collection practices.
|
|
|
|
Therefore, the wallet should:
|
|
|
|
- Inform users that their on-chain activity and IP address will be exposed to the endpoint.
|
|
- If the endpoint is unknown to the wallet, inform users that the endpoint may behave in unexpected ways.
|
|
- Observe good web security practices when interacting with the endpoint, such as require HTTPS.
|
|
- Clearly inform the user which RPC URL is being used to communicate with a chain at any given moment, and inform the user of the risks of using multiple RPC endpoints to interact with the same chain.
|
|
|
|
### UX
|
|
|
|
Adding a new chain to the wallet can have significant implications for the functionality of the wallet and the experience of the user.
|
|
A chain should never be added without the explicit consent of the user, and different chains should be clearly differentiated in the wallet UI.
|
|
In service of these goals, the wallet should:
|
|
|
|
- When receiving a `wallet_addEthereumChain` request, display a user confirmation informing the user that a specific dapp has requested that the chain be added.
|
|
- The confirmation used in [EIP-1102](./eip-1102.md) may serve as a point of reference.
|
|
- Ensure that any chain metadata, such as `nativeCurrency` and `blockExplorerUrls`, are validated and used to maximum effect in the UI.
|
|
- If any images are provided via `iconUrls`, ensure that the user understands that the icons could misrepresent the actual chain added.
|
|
- If the wallet UI has a concept of a "currently selected" or "currently active" chain, ensure that the user understands when a chain added using `wallet_addEthereumChain` becomes selected.
|
|
|
|
### Validating Chain Data
|
|
|
|
A wallet that implements `wallet_addEthereumChain` should expect to encounter requests for chains completely unknown to the wallet maintainers.
|
|
That said, community resources exist that can be leveraged to verify requests for many Ethereum chains.
|
|
The wallet should maintain a list of known chains, and verify requests add chains against that list.
|
|
Indeed, unless there are good reasons not to, the wallet should _prefer its own chain metadata_ over anything submitted with a `wallet_addEthereumChain` request.
|
|
|
|
## Copyright
|
|
|
|
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|