EIP 747: wallet_watchAsset

Hi there, I wanted to get a final round of comments on wallet_watchAsset before we add it to MetaMask.

We’ve made a properly formatted EIP document here:

You can read the original discussion here:

In particular, I’m curious to hear what people think about using a tokenImage URL as an image parameter. Is there a more secure option people can think of?

Thanks! We appreciate it! Co-authored with @estebanmino

Forgive the fund-recovery tag, clicking remove on it isn’t working.

6 Likes

One change I might consider:

Changing the Image parameter to be an Object, with a type property, so that it can be forward-compatible with future (non-DNS-based) image hosting solutions.

Example

web3.eth.watchToken(tokenAddress, tokenSymbol, tokenDecimals { 
  type: 'url',
  value: imageUrl,
})

// Leaves a path open for new formats, like swarm:
web3.eth.watchToken(otherTokenAddress, otherTokenSymbol, otherTokenDecimals { 
  type: 'swarm',
  value: swarmHash,
})

Another open question: Would we want the method to declare the format of token being suggested? ERC-20 is old and dated, and we should be looking forward.

What if instead, the method was eth_watchAsset, and included a format field to describe the asset being added (like erc-20, or erc-721, even!).

A bit more on NFTs

I don’t want to go too deep down the 721 rabbit hole, but just thinking ahead a bit:
One thing NFTs require is a special way of looking up their individual images. Adding an NFT might also include a short template string, highly restricted, that instructs the client on how to add the given NFT to the user’s wallet.

That feature might require an additional parameter, or maybe we should just pack more of these into a big, unordered options object. Ordered params are annoying anyways.

Thoughts on using an options object vs a series of parameters?

1 Like

Removed the fund-recovery tag, kind of unclear how to do that in the UI.

That tag got me to click though!

I support making this method support arbitrary asset types. It would, presumably, include the asset type identifier (e.g., ERC20, ERC777, ERC721, etc.) and an object that includes parameters specific to that asset type. If the wallet understands the referenced asset type, it will proceed to parse the object for details.

The method would return an error if it doesn’t understand the asset type (error response structure should be well defined so they are easy to switch on in dapps) and if the provided parameters don’t match what is expected for the asset then it would similarly error.

There may be value in creating a workflow (similar to how BIP does SLIPs) for getting new asset types registered (with their associated parameters structure).

2 Likes

This looks like a great addition.

On first glance that feels very Metamask/wallet specific, and not necessarily something a client (like Ganache or geth) should implement. Would it be better to create a new prefix, perhaps something like metamask_watchToken or wallet_watchToken?

1 Like

I totally agree, and in fact we’ve already updated the EIP to reflect that change. I’ll now edit the subject post, too. (Was initially eth_watchToken, is now wallet_watchAsset, for those viewing after edits).

1 Like

I got pointed here after trying to get my BorisCoin added to MetaMask via Github PR, but I don’t have a “reputation” on EtherScan, so watching this with interest :slight_smile:

Is the flow something like:

  1. User visits BorisCoinDotClub with web3 enabled app
  2. BorisCoinDotClub prompts web3 provider to “track BorisCoin” or similar
  3. User accepts and web3 provider adds to wallet

Another thought is that this might be combined with receiving tokens in some way, but not sure how that would work.

1 Like

Yes, the flow will be very much like that. I’ve made a simple general purpose token-adding app that people can use for suggesting their tokens (only works with our current develop branch, you can pull a recent build like this one or take my word for it):

Add DanCoin on Ropsten.

2 Likes

I like this idea for a new RPC endpoint / method! Is the proposed name wallet_watchAsset / web3.wallet.watchAsset or eth_watchAsset / web3.eth.watchAsset?

@danfinlay

The RPC-type method would be wallet_watchAsset, MetaMask is initially releasing it namespaced under metamask_watchAsset. Generally, the web3.js library exposes underscored namespaces as objects, so that would imply web3.wallet.watchAsset, although this EIP reflects no official endorsement from web3.js, nor would any RPC provider be required to implement this method, since it would really only be useful at the signer/wallet layer, hence the wallet_ namespace.

We’re trying to make wallet_ happen, because for too long it’s been confusing when things were under eth_ whether they required a signature or not. Like eth_sendTransaction versus eth_sendRawTransaction. The namespace does not reflect the fact that one requires a signature and the other doesn’t, which is a large fundamental difference.

2 Likes

Thanks @danfinlay, this will be very useful. Great work.

Hello,
I first heared about this EIP at Devcon when metamask presented it’s implementation and I was wondering about the hability to expand the watchAsset capability beyound ERC20 and ERC721 tokens.

I am developping smart contracts that contain an (ERC20 based) Escrow. Users can deposit tokens to the escrow using the “allow-deposit” scheme of ERC20. This increases the user balance. This balanced can be withdrawn. In the operation of the Escrow, the balanced can be locked. The locked stake will either be returned of seized depending on the users actions.

My escrow has therefore a viewAccount(address) method that returns 2 uint256 (called “stake” and “locked”). I was wondering if there is any way to have these watched using an extension to EIP747. I’m not aware of any EIP that discusses the API of escrow smart contracts, but that might be a first step.

That’s a very interesting and unique use case, probably meriting a fresh thread.

We are definitely planning to expand this method to include ERC721 tokens, and as you can see, we’ve kept the image rendering logic fairly open ended. Maybe once we have ERC721 support, we devise some image display logic that allowed us to render that given escrow’s contained balance.

If that seems hacky, I’m sure we could also do other things, like making escrow its own type, although I’m certain this will be slower to get all the wallets to implement (we have a long list of “asset types” that we want to integrate, so finding common types is key to getting us to cover bases).

1 Like

@danfinlay there’s a UX problem that this spec does not adequately address: when the user has already added the asset (manually or through wallet_watchAsset), there should be a way to avoid asking them to add it repeatedly in a dApp.

IMO, this would be best achieved by specifying that a wallet_watchAsset should not prompt the user in case the asset is already monitored by the wallet, instead silently reporting success. This way a dApp could detect that the user has some tokens of a specific type and prompt the user to add it, which would just be a no-op in case they have already added these.

2 Likes

I think that’s a very reasonable extension.

I had also thought it might make sense to grant some sites (like etherscan, or whatever registry you prefer) permission to freely update your token list, and maybe even read from it (possibly as a separate permission).

1 Like

@danfinlay @phraktle Are there any news about this feature(checking if a token already exists in Metamask)? Now it’s like very tricky for me to know that info, I must store flags in localStorage… But if localStorage is deleted or browser/machine changed, that user must again confirm the token. Or when token is manually deleted in Metamask, localStorage must be deleted. And further “Add Token” popup is not showing explicitly every time, user sometimes must go to the Metamask and only then see the popup. Additionally I must save one flag for each account. So to much complications I think, this can be very useful feature…

Yes, this is in MetaMask now: https://metamask.github.io/metamask-docs/Best_Practices/Registering_Your_Token