What makes a good wallet icon
Where wallet icons appear, from connect modals to extension toolbars and home screens, what makes one hold up, and which files wallet teams should ship.
6 min read
A wallet's icon spends most of its life in places the wallet team doesn't design. It sits in a row of eight other wallets in some dApp's connect modal, at 16 px in a crowded browser toolbar, on a phone home screen masked into whatever shape the operating system likes, and inside a data URI that the wallet's own extension hands to the websites its user visits.
So a good wallet icon is mostly about surviving those contexts. This guide walks through each one and lists the files a wallet team should publish so that dApps and designers don't have to improvise.
Where wallet icons show up
| Context | Typical size | Who controls the container | Background |
|---|---|---|---|
| dApp connect modal | 28 to 48 px | The dApp | Light or dark, unknown in advance |
| Browser extension toolbar | 16 px, rendered at 2x on dense screens | The browser | The browser theme, light or dark |
| Phone home screen | Set by the OS | The operating system, which applies its own mask | Your icon's own background |
| EIP-6963 provider list | Whatever the dApp chooses | The dApp | Light or dark |
| Docs, blog posts, partner pages | 24 to 128 px | Whoever writes the page | Anything |
Two things stand out. The icon is almost always shown inside someone else's container, cropped, masked or placed on a background you didn't choose. And it lands on both light and dark surfaces, often within the same product.
The app icon is the identity
People install a wallet as an app or an extension, and they see its app icon every day: on their home screen, in their toolbar, in their app switcher. That rounded square, with the mark on the brand's own background, is what they recognize. When a dApp lists wallets, the most useful thing it can show is that same picture.
This is why wallets, unlike tokens, are usually shown as rounded squares. A dApp that clips every wallet into a circle, or shows only the bare mark, makes users work a little harder to match it to the app on their phone. Circle or square? covers mixing wallet squares with round token icons.
For the wallet team, that means the square app icon is the primary asset, not an afterthought for the app store. Design it first, and derive everything else from it.
What makes the icon hold up
Keep the mark in the center. Phone operating systems mask app icons into their own shapes, Android launchers can choose between several, and dApps may round the corners further or clip to a circle. Anything near the corners or edges will be cut somewhere, so treat the outer band as background only. Apple's and Android's design guidelines give the exact safe areas; check the current versions when you export.
Give the square icon its own background. A full-bleed background color makes the icon look the same on a white modal, a dark modal and a gray toolbar. A transparent app icon looks different in every one of those places and may disappear in some.
Design for 16 px. The toolbar is the harshest test: 16 by 16 CSS pixels next to a dozen other extensions. One bold shape, two or three colors, no text, no thin outlines, no subtle gradients. If the icon only works at 64 px, it doesn't work.
Be distinguishable from the neighbors. A connect modal is a lineup. Shields, keys, wallets and coins are common motifs, and blue is a common color. Put your icon in a mock modal next to the wallets your users are likely to have installed and check that it's identifiable at a glance by shape alone, not only by its name label.
Use the same mark everywhere. The extension toolbar, the mobile app, the EIP-6963 announcement and the press kit should show the same picture, so someone connecting from a dApp recognizes the icon they clicked in their toolbar a minute ago. Keep seasonal and campaign variants out of the provider info.
The EIP-6963 icon
EIP-6963 lets several injected wallets coexist in one browser. Each wallet announces itself with a provider info object containing a uuid, a name, an icon and an rdns identifier. The icon is a data URI: the image travels inside a string, with no network request. For an extension wallet, this is often the icon a dApp puts in its wallet list, so it deserves the same care as the app icon.
// provider is your EIP-1193 provider object
const info = Object.freeze({
uuid: crypto.randomUUID(),
name: 'Example Wallet',
icon: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...',
rdns: 'com.example.wallet',
})
function announce() {
window.dispatchEvent(
new CustomEvent('eip6963:announceProvider', {
detail: Object.freeze({ info, provider }),
}),
)
}
window.addEventListener('eip6963:requestProvider', announce)
announce()
Use the square app icon here, with its background, because you don't know what the dApp's modal looks like. The EIP asks for a square image with a minimum resolution, so read the current text before exporting. An optimized SVG is usually best: sharp at any size, and a simple icon fits in a few kilobytes. Check that it has a viewBox, no scripts or external references, and no live text.
To produce the string from a file:
echo "data:image/svg+xml;base64,$(base64 -w0 wallet-icon.svg)"
The -w0 flag turns off line wrapping in GNU base64; macOS base64 doesn't wrap by default, so leave the flag out there.
If you build the dApp side
The icon comes from whatever extension the user installed, so treat it as untrusted input. Render it with an <img> element, where SVG scripts don't run, and never inject it as inline markup. Check that it is an image data URI before using it:
type ProviderInfo = { uuid: string; name: string; icon: string; rdns: string }
export function WalletOption({ info }: { info: ProviderInfo }) {
const icon = info.icon.startsWith('data:image/') ? info.icon : undefined
return (
<button type="button">
{icon && <img src={icon} alt="" width={32} height={32} />}
<span>{info.name}</span>
</button>
)
}
The wallet's name is visible text inside the button, so the image gets an empty alt and the button's accessible name is the wallet name. More on that in making wallet connection modals accessible, and on untrusted SVG in Is SVG safe?.
What a wallet team should publish
dApp developers and designers need your icon in forms you can't predict, and without the right file they may resort to screenshots. A small, clearly labeled kit prevents that:
| Asset | Format | Used for |
|---|---|---|
| Square app icon, full-bleed background | SVG, plus PNG at 1024 px | Connect modals, docs, partner pages, app stores |
| Mark only, transparent background | SVG, light and dark versions | Interfaces that supply their own container |
| Single-color mark | SVG | Monochrome UIs, print, watermarks |
| Extension toolbar icons | PNG at the sizes your target browsers ask for | The manifest; Chrome's documentation lists 16, 32, 48 and 128 px |
| EIP-6963 icon | Optimized SVG as a data URI | The provider announcement |
| Name and spelling | Plain text | Labels, so nobody writes "Examplewallet" |
Put it all on one press page with a single download, state which uses are fine, and keep file names descriptive (example-wallet-app-icon.svg, not logo-final-2.svg). Press kits and brand guidelines covers what else that page should include.
To see how wallet marks and their background versions compare side by side, browse the wallets in the icon library; MetaMask, Phantom and Rainbow are a good place to start.