DCIPs/EIPS/eip-747.md

129 lines
7.5 KiB
Markdown
Raw Normal View History

---
eip: 747
title: wallet_watchAsset RPC Method
description: Adds a new RPC method that allows websites to prompt users to watch an asset
author: Dan Finlay (@danfinlay), Esteban Mino (@estebanmino), Gavin John (@Pandapip1)
discussions-to: https://ethereum-magicians.org/t/eip-747-eth-watchtoken/1048
status: Last Call
last-call-deadline: 2023-03-13
type: Standards Track
category: Interface
created: 2018-08-13
requires: 20, 1046, 1193
---
## Abstract
This EIP standardizes a new wallet-scoped RPC method, `wallet_watchAsset`, to allow a client to suggest a token for the user's wallet to track.
## Motivation
Today, one of the major uses of Ethereum wallets is to track users' assets.
Without this EIP, each wallet either needs to pre-load a list of approved assets, or users must manually add assets to their wallet.
In the first case, wallets are burdened with both the security of managing this list, as well as the bandwidth of mass polling for known assets on their wallet.
In the second case, the user experience is terrible.
## Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
A new RPC method, `wallet_watchAsset` is added. `wallet_watchAsset` requests that a specified asset be listed to the user's wallet. It MUST immediately (i.e. before prompting the user) return `true` if the request was valid, or error if it was not. The meaning of "listed to the user's wallet" is dependent on the wallet implementation. A successful call to `wallet_watchAsset` MUST indicate that the wallet recognized the request and that it contained no issues, but doesn't indicate whether the user was prompted or whether the asset was actually added to the wallet.
### `wallet_watchAsset` Parameters
The `wallet_watchAsset` method takes a single parameter, a `WatchAssetParameters` object, which is defined as follows:
```typescript
interface WatchAssetParameters {
type: string; // The asset's interface, e.g. 'ERC1046'
options: any;
}
```
The `type` string SHOULD be the commonly accepted name of the interface implemented by the asset's contract, e.g. `ERC1046`. Defining the global identifiers for different asset types is beyond the scope of this EIP.
This interface SHOULD be extended or modified depending on the asset `type`. These changes MUST be specified in separate EIPs.
### `wallet_watchAsset` Returns
`wallet_watchAsset` immediately (i.e. without waiting for user interaction) returns the boolean value `true` to indicate that the request was recognized (regardless of whether the user was prompted), or errors if the request is invalid. An error might occur in the following circumstances (not comprehensive):
- The asset type is unrecognized/unsupported
- The asset was blocked due to an allowlist or denylist (this makes the request 'invalid' since the root cause requires developer action)
- Downloading the image failed to load
- The wallet didn't load some of the metadata required to display the asset, in order to protect against a potential SSRF attack
### `ERC1046` type
The format of the options field is:
```typescript
interface ERC1046WatchAssetOptions {
{
address: string; // The hexadecimal address of the token contract
chainId?: number; // The chain ID of the asset. If empty, defaults to the current chain ID.
};
}
```
`address` is required, and the other fields are optional. `address` MUST be the `0x`-prefixed checksummed hexadecimal address of the token contract. `chainId` MUST be the chain ID to which the asset belongs.
If the checksum fails, the request MUST be considered invalid.
If the wallet does not recognize the `chainId`, or the `chainId` is blank and the wallet does not have a concept of "active" chain, the call MUST fail.
`wallet_watchAsset` MUST fetch the [ERC-1046](./eip-1046.md) `tokenURI` and check the `interop` field to determine the type of the token. If the parsing fails, or the type is unknown, the RPC call MUST error.
`wallet_watchAsset` SHOULD check the `name` and `symbol` fields, and the contract `address` and `chainId` against a list of well-known tokens. If the name and/or symbol are similar to ones on the list but the `chainId`/`address` don't match, a warning SHOULD be presented to the user.
The wallet SHOULD whitelist and/or blacklist specific ports and schemes to avoid SSRF attacks.
### Legacy `ERC20` type
The format of the options field is:
```typescript
interface ERC20WatchAssetOptions {
{
address: string; // The hexadecimal address of the token contract
chainId?: number; // The chain ID of the asset. If empty, defaults to the current chain ID.
};
}
```
`address` is required, and the other fields are optional. `address` MUST be the `0x`-prefixed checksummed hexadecimal address of the token contract. `chainId` MUST be the chain ID to which the asset belongs.
If the checksum fails, the request MUST be considered invalid.
If the wallet does not recognize the `chainId`, or the `chainId` is blank and the wallet does not have a concept of "active" chain, the call MUST fail.
`wallet_watchAsset` SHOULD check the `name` and `symbol` fields, and the contract `address` and `chainId` against a list of well-known tokens. If the name and/or symbol are similar to ones on the list but the `chainId`/`address` don't match, a warning SHOULD be presented to the user.
If possible, it is RECOMMENDED to instead use the `ERC1046` type, which supports images and custom metadata.
## Rationale
Displaying a user's assets is a basic feature that every modern DApp user expects. Most wallets currently either manage their own asset lists, which they store client-side, or they query a centralized API for balances, which reduces decentralization and allows correlating account holders with IP addresses. Additionally, refreshing/polling an asset list from the network can be costly, especially on bandwidth-constrained devices. Also, maintaining an asset list becomes a political act, provoking harassment and inducing pressure to list obscure assets.
Automatically listing assets makes assets into a sort of spam mail: Users suddenly see new assets that they don't care about in their wallet. This can be used to send unsolicited information, or even to conduct phishing scams. This phenomenon is already common with airdropped tokens, a major cause of network congestion, because spamming people with new tokens has, so far, been rewarded with increased user attention.
When a user is manually adding a asset, they had likely previously learned about it from a website. At that moment, there was a natural alignment of interests, where both parties wanted the user to track the token. This is a natural point to introduce an API to easily allow these parties to collaborate.
## Security Considerations
### Server-Side Request Forgery
Wallets should be careful about making arbitrary requests to URLs. As such, it is recommended for wallets to sanitize the URI by whitelisting specific schemes and ports. A vulnerable wallet could be tricked into, for example, modifying data on a locally-hosted redis database.
### Validation
Wallets should warn users if the symbol or name matches or is similar to another token, to avoid phishing scams.
### Fingerprinting
To avoid fingerprinting based on wallet behavior and/or listed assets, the RPC call must return as soon as the user is prompted or an error occurs, without waiting for the user to accept or deny the prompt.
## Copyright
Copyright and related rights waived via [CC0](../LICENSE.md).