{"id":"EIP-747","name":"wallet_watchAsset","status":"Final","chain":"both","category":{"id":"comprehension","name":"Comprehension & Display","description":"Making blockchain data readable to humans"},"journeyStages":[{"id":"asset-display","name":"Asset Discovery & Display","description":"Seeing tokens, NFTs, and balances"}],"uxImpact":"EIP-747 lets an app suggest an asset for a supporting wallet to track. A true wallet_watchAsset response acknowledges a valid request; it does not prove that a prompt appeared or that the token was added. Keep the token address and network visible, and let users check the wallet’s result.","officialUrl":"https://eips.ethereum.org/EIPS/eip-747","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"EIP-747","summary":"EIP-747 lets an app suggest an asset for a supporting wallet to track. A true wallet_watchAsset response acknowledges a valid request; it does not prove that a prompt appeared or that the token was added. Keep the token address and network visible, and let users check the wallet’s result.","applicability":{"whenToUse":["A supporting wallet can receive a user-initiated request to track an asset.","Users need a convenient way to find the received token in their wallet."],"whenToAvoid":["The wallet does not support the requested asset type or method.","Your flow requires proof that the token was added; a standard true result only acknowledges the request."]},"designerTakeaways":["Offer an explicit request to track a token.","Label a recognized request as sent, not as a confirmed addition.","Handle unsupported wallets and wallet-specific confirmation behavior."],"problemsSolved":[{"problem":"New tokens don't show in wallet","oldWay":"Find contract address, copy it, add token manually","newWay":"Offer a request to track the token and explain how to check its visibility in the wallet","impact":"high"},{"problem":"Users think tokens are lost","oldWay":"\"I swapped but don't see anything!\" (token not tracked)","newWay":"After a swap, offer to request wallet tracking without implying that it changes the on-chain balance","impact":"high"},{"problem":"Wrong tokens added by mistake","oldWay":"User adds scam token with similar name","newWay":"Show the selected network and independently checked contract address","impact":"medium"}],"uxPatterns":[{"name":"Add Token After Swap","description":"Prompt to track new token post-transaction","userFlow":["User receives a token","App offers a request to track it with address and network","User selects Add to wallet","App calls the wallet-supported watchAsset method","Show Request sent when the request is recognized","Ask the user to check the wallet; do not infer an added token from true"]},{"name":"Token Page Add Button","description":"Add token from info/detail page","userFlow":["User reviews the token address and network","App checks supported asset types and wallet behavior","User requests tracking","Wallet may prompt, decline or acknowledge without a prompt","Show the actual wallet-specific outcome or a request acknowledgement"]}],"uiComponents":[{"name":"AddToWalletButton","description":"Button to trigger wallet_watchAsset","states":["idle","requesting","request-recognized","unsupported","error","no-wallet"],"props":["token","onAdd","onError"]},{"name":"WatchRequestAcknowledgement","description":"Confirms that the wallet recognized the request, not that an asset was added.","states":["hidden","request-recognized","outcome-unknown"],"props":["token","onDismiss"]},{"name":"TokenPreview","description":"Shows token details before adding","states":["loading","loaded"],"props":["address","symbol","decimals","image"]}],"antiPatterns":[{"pattern":"Not prompting to add after swap","why":"User doesn't see new token, thinks it failed","instead":"Auto-prompt add token after receiving new asset","severity":"high"},{"pattern":"Adding tokens without user consent","why":"Spam tokens could fill wallet","instead":"Require an explicit user action before sending a tracking request","severity":"medium"},{"pattern":"Not showing contract address","why":"User can't verify it's the right token","instead":"Display address and verification status","severity":"medium"}],"specConstraints":[{"id":"watch-asset-immediate-status","constraint":"wallet_watchAsset must immediately return true for a valid request or error for an invalid one, before prompting.","appliesTo":"wallet","normativity":"normative","specQuote":"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.","specSection":"Specification","specUrl":"https://eips.ethereum.org/EIPS/747#specification","designImplication":"Separate request validation from user consent in the UI and show that a valid request is not proof that the asset was added."},{"id":"asset-metadata-safety","constraint":"Wallets may omit metadata required for display to protect against SSRF.","appliesTo":"wallet","normativity":"normative","specQuote":"- The wallet didn't load some of the metadata required to display the asset, in order to protect against a potential SSRF attack","specSection":"Specification > walletwatchAsset Returns","specUrl":"https://eips.ethereum.org/EIPS/747#walletwatchasset-returns","designImplication":"Design incomplete metadata states and avoid treating missing logo/name data as a malformed asset by default."},{"id":"asset-address-chain-validation","constraint":"Asset address must be checksummed and chainId must identify the asset’s chain.","appliesTo":"wallet","normativity":"normative","specQuote":"`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.","specSection":"Specification > ERC1046 type","specUrl":"https://eips.ethereum.org/EIPS/747#erc1046-type","designImplication":"Validate address and chain together before showing an add-asset confirmation and display the target chain explicitly."},{"id":"asset-checksum","constraint":"A checksum failure makes the asset request invalid.","appliesTo":"wallet","normativity":"normative","specQuote":"If the checksum fails, the request MUST be considered invalid.","specSection":"Specification > ERC1046 type","specUrl":"https://eips.ethereum.org/EIPS/747#erc1046-type","designImplication":"Show a corrective invalid-address state instead of silently normalizing an unchecksummed address."},{"id":"known-chain-required","constraint":"The wallet must fail when it does not recognize the requested chainId or cannot use an active-chain fallback.","appliesTo":"wallet","normativity":"normative","specQuote":"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.","specSection":"Specification > ERC1046 type","specUrl":"https://eips.ethereum.org/EIPS/747#erc1046-type","designImplication":"Ask the user to select or add a known chain before offering asset tracking, and do not imply that the wallet switched chains."},{"id":"metadata-type-validation","constraint":"wallet_watchAsset must validate the token type through ERC-1046 metadata and error for unknown or unparseable types.","appliesTo":"wallet","normativity":"normative","specQuote":"`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.","specSection":"Specification > ERC1046 type","specUrl":"https://eips.ethereum.org/EIPS/747#erc1046-type","designImplication":"Show a type-validation state and preserve the distinction between recognized metadata and a user-approved display request."},{"id":"url-safety","constraint":"Wallets should sanitize arbitrary metadata URLs by whitelisting schemes and ports.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"### Server-Side Request Forgery\n\nWallets 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.","specSection":"Security Considerations > Server-Side Request Forgery","specUrl":"https://eips.ethereum.org/EIPS/747#server-side-request-forgery","designImplication":"Use safe URL handling and a blocked-resource state for asset metadata rather than fetching arbitrary local or privileged endpoints."},{"id":"explicit-chain-consent","constraint":"A watch-asset request identifies a chain but does not itself change the active chain or prove the asset belongs to the current chain.","appliesTo":"wallet","normativity":"normative","specQuote":"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.","specSection":"Specification > ERC1046 type","specUrl":"https://eips.ethereum.org/EIPS/747#erc1046-type","designImplication":"Keep chain identity visible in the prompt and let users distinguish tracking an asset on another known chain from switching networks."},{"id":"asset-fingerprinting","constraint":"wallet_watchAsset should return after prompting or error rather than waiting for user acceptance, reducing wallet/asset fingerprinting.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"### Fingerprinting\n\nTo 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.","specSection":"Security Considerations > Fingerprinting","specUrl":"https://eips.ethereum.org/EIPS/747#fingerprinting","designImplication":"Make prompt-shown, accepted, denied, and unsupported states distinct while avoiding response timing that reveals the user’s asset list."},{"id":"known-asset-mismatch-warning","constraint":"Wallets should compare token identity and chain data with known assets and warn when a similar name or symbol points to a different address or chain.","appliesTo":"wallet","normativity":"normative","specQuote":"`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.","specSection":"Specification > ERC1046 type","specUrl":"https://eips.ethereum.org/EIPS/747#erc1046-type","designImplication":"Show the known-token comparison and mismatch warning near the asset name, address, and chain. Do not turn a similar name into a verified identity."},{"id":"metadata-rich-asset-request","constraint":"Wallets are recommended to use the ERC-1046 asset type when possible because it supports images and custom metadata.","appliesTo":"application","normativity":"normative","specQuote":"If possible, it is RECOMMENDED to instead use the `ERC1046` type, which supports images and custom metadata.","specSection":"Specification > Legacy ERC20 type","specUrl":"https://eips.ethereum.org/EIPS/747#legacy-erc20-type","designImplication":"Treat richer metadata as an optional request capability. Keep the core address, chain, and validation states usable when images or custom metadata are unavailable."},{"id":"token-name-phishing-warning","constraint":"Wallets should warn when an asset name or symbol matches or resembles another token.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"Wallets should warn users if the symbol or name matches or is similar to another token, to avoid phishing scams.","specSection":"Security Considerations > Validation","specUrl":"https://eips.ethereum.org/EIPS/747#validation","designImplication":"Use a phishing warning for similar names and symbols, and keep the checksummed contract address and chain prominent for comparison."}],"keyTakeaways":["EIP-747 = \"Add to Wallet\" button","Prompt to add tokens after swaps/receives","Show the contract address and network for independent review","Do not send tracking requests without user consent","Use wallet_watchAsset RPC method"],"technicalNotes":"The current EIP-747 specifies wallet_watchAsset({ type, options }). For ERC1046 and legacy ERC20, the specified options are { address, chainId? }, with a checksummed address. The ERC1046 path fetches tokenURI and checks interop. A valid request returns true immediately before user interaction; it says neither that a prompt appeared nor that the token was added. Some wallets retain older options such as symbol, decimals and image or older result behavior. Treat those as wallet-specific integrations, detect support, and do not infer completion from the standard acknowledgement.","lastUpdated":"2026-09-18","lastReviewed":"2026-09-18","sources":[{"label":"EIP-747 official specification","url":"https://eips.ethereum.org/EIPS/eip-747","type":"official-spec"}]},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/eip-747","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=EIP-747","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/EIP-747","markdown":"https://www.eipsfordesigners.com/standards/EIP-747/content.md","agent":"https://www.eipsfordesigners.com/standards/EIP-747/agent.md","api":"https://www.eipsfordesigners.com/api/standards/EIP-747","official":"https://eips.ethereum.org/EIPS/eip-747","discussion":"https://ethereum-magicians.org/search?q=EIP-747"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}