DCIPs/EIPS/eip-747.md

7.5 KiB

eip title description author discussions-to status last-call-deadline type category created requires
747 wallet_watchAsset RPC Method Adds a new RPC method that allows websites to prompt users to watch an asset Dan Finlay (@danfinlay), Esteban Mino (@estebanmino), Gavin John (@Pandapip1) https://ethereum-magicians.org/t/eip-747-eth-watchtoken/1048 Last Call 2023-03-13 Standards Track Interface 2018-08-13 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:

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:

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 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:

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 and related rights waived via CC0.