fix: resolve native token icons in QuickBuy Pay with list#31026
Conversation
Native EVM tokens (ETH on Linea, Optimism, Arbitrum, mainnet) rendered no icon because their CDN URL was built from the zero-address erc20 path, which only serves a real image on a few chains. Resolve native tokens through their canonical SLIP-44 asset id (e.g. eip155:59144/slip44:60), which the icon CDN serves on every chain. Co-authored-by: Cursor <cursoragent@cursor.com>
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
|
@cursor fix unit test in quick but |
|
The PR already exists and the description doesn't need updating. The fix is pushed. The |
The @metamask/bridge-controller mock was missing isNativeAddress and getNativeAssetForChainId, which are now used by getBridgeTokenImageSource. This caused all QuickBuyPayWithScreen tests to fail with 'isNativeAddress is not a function'. Co-authored-by: Xavier Brochard <xavier-brochard@users.noreply.github.com>
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
No E2E tests reference SocialLeaderboard, TraderPositionView, or QuickBuy components. The changed utility is only imported by QuickBuyActionFooter.tsx and QuickBuyPayWithRow.tsx (UI display components). No controllers, Engine, navigation, or critical infrastructure is modified. This is a purely isolated unit-level change affecting only token icon display in the QuickBuy flow, with no risk to any E2E test flows. Performance Test Selection: |


Description
Native EVM tokens (ETH on Linea, Optimism, Arbitrum, and mainnet) were rendering without their token icon in the QuickBuy "Pay with" list, falling back to the network badge / symbol monogram only.
Reason for the change: Native tokens come from
getNativeSourceTokenwith an emptyimageand the zero address. The icon helpergetBridgeTokenImageSourcethen fell back togetAssetImageUrl(token.address, token.chainId), which builds anerc20:0x0000…0000CAIP asset id for the zero address. The MetaMask icon CDN (static.cx.metamask.io) only serves a real image at thaterc20:0x0path on a handful of chains (e.g. Base, 9396 B); for Linea/Optimism/Arbitrum/mainnet it returns a ~675 B placeholder, so no icon shows. The canonical SLIP-44 path (slip44/60) serves the real 7930 B ETH icon on every chain.Solution: In
getBridgeTokenImageSource, when the token is native, resolve its asset id via the bridge-controller'sgetNativeAssetForChainId(chainId).assetId(e.g.eip155:59144/slip44:60) before building the CDN URL, with atry/catchfallback to the raw address for unsupported chains. ERC-20s and thetoken.imageshort-circuit are untouched, andisNativeAddresskeeps Solana/non-EVM natives working. The fix is intentionally contained to this QuickBuy helper, leaving the sharedgetAssetImageUrl/toAssetIduntouched to avoid app-wide regressions.Changelog
CHANGELOG entry: Fixed missing native token icons (e.g. Linea ETH) in the QuickBuy "Pay with" list.
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
After
Pre-merge author checklist
Pre-merge reviewer checklist
Made with Cursor
Note
Low Risk
Scoped UI helper change with try/catch fallback; no auth, payments, or shared bridge URL logic changes.
Overview
Fixes missing native token icons in the QuickBuy Pay with list (and related picker rows) when
token.imageis empty.getBridgeTokenImageSourcenow uses@metamask/bridge-controller’sisNativeAddressandgetNativeAssetForChainIdso CDN fallback URLs use the canonical SLIP-44 asset id instead of the zero address—addressing placeholder icons on Linea, Optimism, Arbitrum, mainnet, etc. ERC-20 behavior and thetoken.imageshortcut are unchanged; unsupported chains still fall back to the raw address inside atry/catch.Tests cover native SLIP-44 resolution and error fallback;
QuickBuyPayWithScreenmocks were extended for the new bridge-controller helpers.Reviewed by Cursor Bugbot for commit da99cba. Bugbot is set up for automated code reviews on this repo. Configure here.