feat(frontend): add circular wallet logos to Connect Wallet modal #490

Closed
opened 2026-07-14 11:12:36 +00:00 by PlasticDigits · 12 comments
PlasticDigits commented 2026-07-14 11:12:36 +00:00 (Migrated from gitlab.com)

Summary

QoL request: show a circular logo to the left of each wallet name in the Connect Wallet modal (Station, Keplr, Cosmostation, LuncDash, Galaxy Station), so users can recognize wallets by brand mark instead of text alone.

Screenshot of current text-only modal (no logos): rows show uppercase names + Extension/WalletConnect badges + optional Install.


Current codebase

The Connect Wallet UI is a custom modal (not cosmos-kit / wallet-kit). Wallet rows are text-only.

Piece Location Behavior today
Modal + option list frontend-dapp/src/components/wallet/WalletModal.tsx Static WALLET_OPTIONS mapped to rows; name + connection-type badge; no <img> / icon slot
Extension Ready / Install same + walletExtensionInstall.ts Ready pill when extension detected; Install CTA when missing (#139 / #160)
Row styles frontend-dapp/src/index.css (.wallet-option-*) Flex card layout; badges right-aligned
Connection stack @goblinhunt/cosmes via services/terraclassic/wallet.ts Controllers for Station / Keplr / Cosmostation / LuncDash / Galaxy Station
Header chip WalletButton.tsx + networkDisplay.ts Shows Terra chain logo when connected — not a per-wallet brand mark
Unit tests components/wallet/__tests__/WalletModal.test.tsx Badges, Install links, no Leap (#159)

Bridge sibling (reference only): cl8y-bridge-monorepo/packages/frontend uses WalletIcons.tsx + TerraWalletOption.tsx, but those are generic colored placeholder SVGs (globe/star/dollar), not official wallet trademarks. There are no copyable brand PNG/SVG assets under bridge public/.

Assets already in DEX: frontend-dapp/public/chains/* are chain icons only.


Why this is needed

  • Users scan by logo first; text-only rows increase cognitive load and mis-taps (especially Station vs Galaxy Station).
  • Matches retail DEX / bridge UX expectations and the design-system goal of clearer, brand-recognizable controls (docs/design-system.md, #488 / #489).
  • Install vs Ready states stay clearer when the brand mark is always visible beside the name.

Constraints / guardrails

  1. Logo authenticity: Prefer official brand kits when verifiable. Do not hotlink third-party CDN aggregators at runtime. Vendor trademarks remain theirs — use logos only to identify supported wallets in-product (fair identification), do not alter marks beyond sizing/cropping into a circle, and do not imply endorsement.
  2. Verified sources (prefer these):
    • Keplr — official: https://www.keplr.app/brand (Original Icon / Outline Icon for light+dark). Verified brand page.
    • Station — Terra docs brand assets: station-icon.png / station-favicon.svg via https://github.com/terra-money/docs (docs/learn/assets.mdx → /brand-assets/...). Prefer Station product icon, not generic Terra/Luna chain marks.
    • Cosmostation — official logo repo https://github.com/cosmostation/logo and Cosmostation brand Figma; use the wallet product mark, not a chain moniker image.
    • LuncDash / Galaxy Station — no clear public brand-kit page found during investigation. Options in order: (a) ask vendors / use assets published on their official sites (e.g. LuncDash site logo) only after visual verification against the live product; (b) fall back to the bridge’s placeholder circle glyphs from WalletIcons.tsx for those two only, with a short code comment noting “placeholder pending official asset”.
  3. Fallback: If any official asset cannot be confidently verified, use the bridge-style circular placeholder for that wallet rather than a wrong/unofficial logo from random crypto-logo sites.
  4. Do not reintroduce Leap (#159). Do not change connect / install / WalletConnect behavior — presentation only.
  5. Theme: Logos must remain legible on dark and light themes (theme-dark.css / theme-light.css). Prefer full-color icons on a neutral circular mask, or outline variants per theme when brand kits provide them (Keplr does).
  6. CSP / bundling: Serve icons as static files under frontend-dapp/public/ (e.g. public/wallets/) or as bundled SVG modules — no remote img URLs that expand CSP or enable supply-chain swap of marks.
  7. a11y: Icons are decorative when the wallet name is visible text; use empty alt="" / aria-hidden on the image, and keep existing aria-label on the row button. Do not replace the accessible name with the logo alone.
  8. Layout: Preserve Install CTA, Extension/WalletConnect/Ready badges, truncation + title for long names (#160). Icons must not squeeze badges off-screen on narrow viewports.
  9. Simulated Wallet (dev): Optional small distinct glyph or leave text-only with DEV badge — do not use a real vendor logo for the simulated path.

Relevant files

  • frontend-dapp/src/components/wallet/WalletModal.tsx — add icon slot next to name
  • frontend-dapp/src/index.css — .wallet-option-card / new .wallet-option-icon circle styles
  • frontend-dapp/src/components/wallet/__tests__/WalletModal.test.tsx — assert icons present
  • frontend-dapp/public/wallets/ (new) — static circle-ready assets
  • Optional: frontend-dapp/src/components/wallet/WalletIcons.tsx (new) — map WalletName → asset/component (mirror bridge structure)
  • Reference (placeholders only): ../cl8y-bridge-monorepo/packages/frontend/src/components/wallet/WalletIcons.tsx, TerraWalletOption.tsx
  • Docs touch if UX described: docs/frontend.md (Connect Wallet section)

  1. Add public/wallets/{station,keplr,cosmostation,luncdash,galaxy-station}.svg (or .png) — prefer SVG; normalize to square canvas.
  2. Extend WALLET_OPTIONS (or a parallel WALLET_ICON map keyed by WalletName) with a local iconSrc / React node.
  3. In each .wallet-option-card, render a fixed-size circle (e.g. 28–32px) with object-fit: cover / border-radius: 50% before the uppercase name.
  4. Style via design tokens (--control-surface, --chrome-border-soft) so the circle sits cleanly on dark/light without purple/glow clutter.
  5. For LuncDash / Galaxy Station: verify official marks if available; otherwise port bridge circular placeholders and document the fallback in the MR.
  6. Keep connection handlers, install URLs, and Ready logic untouched.

Acceptance criteria

  • Every production wallet row (Station, Keplr, Cosmostation, LuncDash, Galaxy Station) shows a circular logo immediately left of the name.
  • Logos are local static assets (or inlined SVG), not hotlinked CDNs.
  • Keplr and Cosmostation (and Station if obtainable) use verified official marks; any unverified wallet uses bridge-style placeholder, clearly noted in MR.
  • Dark + light themes: logos remain recognizable; no broken images.
  • Extension Install / Ready / WalletConnect badges and Install CTA still work and fit on mobile widths.
  • Simulated Wallet (dev) does not misuse a vendor trademark.
  • Leap remains absent.
  • Unit tests updated; existing connect behavior unchanged.
  • docs/frontend.md briefly notes logos if that section describes the modal.

Test plan (all paths)

Unit / component

  • WalletModal.test.tsx: each listed wallet row renders an icon element (by data-testid or alt/aria-hidden + src/role).
  • Missing-extension path still shows Install + dimmed card; icon still visible.
  • Installed-extension path still shows Ready; icon still visible.
  • WalletConnect rows (LuncDash, Galaxy Station) show icons without Install.
  • Dev Simulated Wallet row still appears only when DEV_MODE.
  • Leap not present.

Manual / visual

  • Open Connect Wallet from header on / (or Swap) — dark theme: five logos + badges.
  • Toggle light theme — logos still legible.
  • Narrow viewport (~320–375px): name truncates; icon + badges + Install remain usable.
  • Click each extension row with extension installed → connect flow unchanged.
  • Click Install → official install URL unchanged.
  • WalletConnect rows still open WC flow (smoke).
  • After connect, header chip still shows chain logo (not required to switch to wallet brand in this issue unless trivial).

Regression

  • make test-frontend (or scoped WalletModal tests) green.
  • No CSP console errors loading wallet assets.
  • No layout shift / overlap with EnvironmentRibbon / header.

Test plan — attack, hack & abuse vectors

Vector Risk Mitigation / test
Supply-chain logo swap Hotlinked CDN replaced with phishing lookalike Assert assets are local under public/wallets/ or bundled; CSP blocks unexpected hosts
Fake wallet branding Wrong logo implies wrong product (e.g. Station vs Galaxy Station) Visual review against official brand pages; MR lists asset provenance
XSS via SVG Malicious SVG with scripts/onload Prefer sanitized SVG (no <script>, no event handlers) or PNG; review assets in code review
Clickjacking / enlarged hit targets Icon-only target without name Keep full-row button; name remains visible text
Phishing Install CTA confusion Logo distracts from Install destination Install URLs remain from WALLET_EXTENSION_INSTALL_URL only; no logo-driven navigation
Trademark / endorsement claim Altered or misuse of marks No recolor/distort beyond circle crop; identification-only usage
Broken asset → blank row Failed load looks like missing wallet Use explicit dimensions + optional placeholder on onError; tests check src paths exist
Theme inversion attacks Invisible white-on-white icon hides choice Light + dark visual check; outline variants where provided

Verification criteria

Done when:

  1. QA can open Connect Wallet and identify each wallet by circular logo without reading the name (spot-check).
  2. Asset provenance is documented in the MR (URL / repo path per file), with placeholders explicitly called out.
  3. Automated WalletModal tests pass; no connect/install regressions.
  4. Issue screenshot (before) vs after confirms logos present and layout intact on mobile + desktop, dark + light.

Out of scope (unless trivial)

  • Replacing the connected header chip’s chain icon with the active wallet brand (nice follow-up, not required).
  • EVM / non-Terra wallets.
  • Changing WalletConnect project id or controller wiring.
## Summary QoL request: show a **circular logo** to the left of each wallet name in the Connect Wallet modal (Station, Keplr, Cosmostation, LuncDash, Galaxy Station), so users can recognize wallets by brand mark instead of text alone. Screenshot of current text-only modal (no logos): rows show uppercase names + Extension/WalletConnect badges + optional Install. --- ## Current codebase The Connect Wallet UI is a **custom modal** (not cosmos-kit / wallet-kit). Wallet rows are **text-only**. | Piece | Location | Behavior today | |-------|----------|----------------| | Modal + option list | `frontend-dapp/src/components/wallet/WalletModal.tsx` | Static `WALLET_OPTIONS` mapped to rows; name + connection-type badge; no `<img>` / icon slot | | Extension Ready / Install | same + `walletExtensionInstall.ts` | Ready pill when extension detected; Install CTA when missing (#139 / #160) | | Row styles | `frontend-dapp/src/index.css` (`.wallet-option-*`) | Flex card layout; badges right-aligned | | Connection stack | `@goblinhunt/cosmes` via `services/terraclassic/wallet.ts` | Controllers for Station / Keplr / Cosmostation / LuncDash / Galaxy Station | | Header chip | `WalletButton.tsx` + `networkDisplay.ts` | Shows **Terra chain** logo when connected — not a per-wallet brand mark | | Unit tests | `components/wallet/__tests__/WalletModal.test.tsx` | Badges, Install links, no Leap (#159) | **Bridge sibling (reference only):** `cl8y-bridge-monorepo/packages/frontend` uses `WalletIcons.tsx` + `TerraWalletOption.tsx`, but those are **generic colored placeholder SVGs** (globe/star/dollar), **not** official wallet trademarks. There are no copyable brand PNG/SVG assets under bridge `public/`. **Assets already in DEX:** `frontend-dapp/public/chains/*` are chain icons only. --- ## Why this is needed - Users scan by logo first; text-only rows increase cognitive load and mis-taps (especially Station vs Galaxy Station). - Matches retail DEX / bridge UX expectations and the design-system goal of clearer, brand-recognizable controls (`docs/design-system.md`, #488 / #489). - Install vs Ready states stay clearer when the brand mark is always visible beside the name. --- ## Constraints / guardrails 1. **Logo authenticity:** Prefer **official brand kits** when verifiable. Do **not** hotlink third-party CDN aggregators at runtime. Vendor trademarks remain theirs — use logos only to identify supported wallets in-product (fair identification), do not alter marks beyond sizing/cropping into a circle, and do not imply endorsement. 2. **Verified sources (prefer these):** - **Keplr** — official: https://www.keplr.app/brand (Original Icon / Outline Icon for light+dark). Verified brand page. - **Station** — Terra docs brand assets: `station-icon.png` / `station-favicon.svg` via https://github.com/terra-money/docs (`docs/learn/assets.mdx` → `/brand-assets/...`). Prefer Station product icon, not generic Terra/Luna chain marks. - **Cosmostation** — official logo repo https://github.com/cosmostation/logo and Cosmostation brand Figma; use the **wallet product** mark, not a chain moniker image. - **LuncDash / Galaxy Station** — no clear public brand-kit page found during investigation. Options in order: (a) ask vendors / use assets published on their official sites (e.g. LuncDash site logo) only after visual verification against the live product; (b) fall back to the bridge’s placeholder circle glyphs from `WalletIcons.tsx` for those two only, with a short code comment noting “placeholder pending official asset”. 3. **Fallback:** If any official asset cannot be confidently verified, use the bridge-style circular placeholder for that wallet rather than a wrong/unofficial logo from random crypto-logo sites. 4. **Do not** reintroduce Leap (#159). Do not change connect / install / WalletConnect behavior — presentation only. 5. **Theme:** Logos must remain legible on **dark and light** themes (`theme-dark.css` / `theme-light.css`). Prefer full-color icons on a neutral circular mask, or outline variants per theme when brand kits provide them (Keplr does). 6. **CSP / bundling:** Serve icons as **static files** under `frontend-dapp/public/` (e.g. `public/wallets/`) or as bundled SVG modules — no remote `img` URLs that expand CSP or enable supply-chain swap of marks. 7. **a11y:** Icons are decorative when the wallet name is visible text; use empty `alt=""` / `aria-hidden` on the image, and keep existing `aria-label` on the row button. Do not replace the accessible name with the logo alone. 8. **Layout:** Preserve Install CTA, Extension/WalletConnect/Ready badges, truncation + `title` for long names (#160). Icons must not squeeze badges off-screen on narrow viewports. 9. **Simulated Wallet (dev):** Optional small distinct glyph or leave text-only with DEV badge — do not use a real vendor logo for the simulated path. --- ## Relevant files - `frontend-dapp/src/components/wallet/WalletModal.tsx` — add icon slot next to name - `frontend-dapp/src/index.css` — `.wallet-option-card` / new `.wallet-option-icon` circle styles - `frontend-dapp/src/components/wallet/__tests__/WalletModal.test.tsx` — assert icons present - `frontend-dapp/public/wallets/` (new) — static circle-ready assets - Optional: `frontend-dapp/src/components/wallet/WalletIcons.tsx` (new) — map `WalletName` → asset/component (mirror bridge structure) - Reference (placeholders only): `../cl8y-bridge-monorepo/packages/frontend/src/components/wallet/WalletIcons.tsx`, `TerraWalletOption.tsx` - Docs touch if UX described: `docs/frontend.md` (Connect Wallet section) --- ## Recommended direction 1. Add `public/wallets/{station,keplr,cosmostation,luncdash,galaxy-station}.svg` (or `.png`) — prefer SVG; normalize to square canvas. 2. Extend `WALLET_OPTIONS` (or a parallel `WALLET_ICON` map keyed by `WalletName`) with a local `iconSrc` / React node. 3. In each `.wallet-option-card`, render a fixed-size circle (e.g. 28–32px) with `object-fit: cover` / `border-radius: 50%` **before** the uppercase name. 4. Style via design tokens (`--control-surface`, `--chrome-border-soft`) so the circle sits cleanly on dark/light without purple/glow clutter. 5. For LuncDash / Galaxy Station: verify official marks if available; otherwise port bridge circular placeholders and document the fallback in the MR. 6. Keep connection handlers, install URLs, and Ready logic untouched. --- ## Acceptance criteria - [ ] Every production wallet row (Station, Keplr, Cosmostation, LuncDash, Galaxy Station) shows a circular logo immediately left of the name. - [ ] Logos are local static assets (or inlined SVG), not hotlinked CDNs. - [ ] Keplr and Cosmostation (and Station if obtainable) use **verified official** marks; any unverified wallet uses bridge-style placeholder, clearly noted in MR. - [ ] Dark + light themes: logos remain recognizable; no broken images. - [ ] Extension Install / Ready / WalletConnect badges and Install CTA still work and fit on mobile widths. - [ ] Simulated Wallet (dev) does not misuse a vendor trademark. - [ ] Leap remains absent. - [ ] Unit tests updated; existing connect behavior unchanged. - [ ] `docs/frontend.md` briefly notes logos if that section describes the modal. --- ## Test plan (all paths) ### Unit / component - [ ] `WalletModal.test.tsx`: each listed wallet row renders an icon element (by `data-testid` or `alt`/`aria-hidden` + src/role). - [ ] Missing-extension path still shows Install + dimmed card; icon still visible. - [ ] Installed-extension path still shows Ready; icon still visible. - [ ] WalletConnect rows (LuncDash, Galaxy Station) show icons without Install. - [ ] Dev Simulated Wallet row still appears only when `DEV_MODE`. - [ ] Leap not present. ### Manual / visual - [ ] Open Connect Wallet from header on `/` (or Swap) — dark theme: five logos + badges. - [ ] Toggle light theme — logos still legible. - [ ] Narrow viewport (~320–375px): name truncates; icon + badges + Install remain usable. - [ ] Click each extension row with extension installed → connect flow unchanged. - [ ] Click Install → official install URL unchanged. - [ ] WalletConnect rows still open WC flow (smoke). - [ ] After connect, header chip still shows **chain** logo (not required to switch to wallet brand in this issue unless trivial). ### Regression - [ ] `make test-frontend` (or scoped WalletModal tests) green. - [ ] No CSP console errors loading wallet assets. - [ ] No layout shift / overlap with EnvironmentRibbon / header. --- ## Test plan — attack, hack & abuse vectors | Vector | Risk | Mitigation / test | |--------|------|-------------------| | **Supply-chain logo swap** | Hotlinked CDN replaced with phishing lookalike | Assert assets are local under `public/wallets/` or bundled; CSP blocks unexpected hosts | | **Fake wallet branding** | Wrong logo implies wrong product (e.g. Station vs Galaxy Station) | Visual review against official brand pages; MR lists asset provenance | | **XSS via SVG** | Malicious SVG with scripts/onload | Prefer sanitized SVG (no `<script>`, no event handlers) or PNG; review assets in code review | | **Clickjacking / enlarged hit targets** | Icon-only target without name | Keep full-row button; name remains visible text | | **Phishing Install CTA confusion** | Logo distracts from Install destination | Install URLs remain from `WALLET_EXTENSION_INSTALL_URL` only; no logo-driven navigation | | **Trademark / endorsement claim** | Altered or misuse of marks | No recolor/distort beyond circle crop; identification-only usage | | **Broken asset → blank row** | Failed load looks like missing wallet | Use explicit dimensions + optional placeholder on `onError`; tests check src paths exist | | **Theme inversion attacks** | Invisible white-on-white icon hides choice | Light + dark visual check; outline variants where provided | --- ## Verification criteria Done when: 1. QA can open Connect Wallet and identify each wallet by circular logo without reading the name (spot-check). 2. Asset provenance is documented in the MR (URL / repo path per file), with placeholders explicitly called out. 3. Automated WalletModal tests pass; no connect/install regressions. 4. Issue screenshot (before) vs after confirms logos present and layout intact on mobile + desktop, dark + light. --- ## Out of scope (unless trivial) - Replacing the connected header chip’s **chain** icon with the active **wallet** brand (nice follow-up, not required). - EVM / non-Terra wallets. - Changing WalletConnect project id or controller wiring.
PlasticDigits commented 2026-07-14 11:14:07 +00:00 (Migrated from gitlab.com)

Dont use placeholder instead use a unique svg icon for missing icons

Dont use placeholder instead use a unique svg icon for missing icons
PlasticDigits commented 2026-07-14 11:25:38 +00:00 (Migrated from gitlab.com)

mentioned in commit 5c045bee6b

mentioned in commit 5c045bee6b167418bab0958338df841a5e5cf99d
PlasticDigits commented 2026-07-14 11:26:00 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1028

mentioned in merge request !1028
PlasticDigits commented 2026-07-14 11:26:35 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1029

mentioned in merge request !1029
PlasticDigits commented 2026-07-14 11:26:49 +00:00 (Migrated from gitlab.com)

Verification screenshots (#490)

MR: !1029 ()

Desktop — dark theme

{'error': 'file is invalid'}

Desktop — light theme

{'error': 'file is invalid'}

Mobile (~375px) — dark

{'error': 'file is invalid'}

Mobile (~375px) — light

{'error': 'file is invalid'}

Notes

  • All five production wallets show circular local logos; Simulated Wallet uses an original DEV glyph (not a vendor mark).
  • No generic bridge placeholders (addresses reopen note).
  • Install / Extension / WalletConnect / Ready chrome preserved; names truncate on narrow widths as designed (#160).
## Verification screenshots (#490) MR: !1029 () ### Desktop — dark theme {'error': 'file is invalid'} ### Desktop — light theme {'error': 'file is invalid'} ### Mobile (~375px) — dark {'error': 'file is invalid'} ### Mobile (~375px) — light {'error': 'file is invalid'} ### Notes - All five production wallets show circular local logos; Simulated Wallet uses an original DEV glyph (not a vendor mark). - No generic bridge placeholders (addresses reopen note). - Install / Extension / WalletConnect / Ready chrome preserved; names truncate on narrow widths as designed (#160).
PlasticDigits commented 2026-07-14 11:27:53 +00:00 (Migrated from gitlab.com)

Verification screenshots (#490)

MR: !1029 (branch fix/490-wallet-modal-circular-logos)

Desktop — dark theme

490-connect-wallet-dark

Desktop — light theme

490-connect-wallet-light

Mobile (~375px) — dark

490-connect-wallet-mobile-dark

Mobile (~375px) — light

490-connect-wallet-mobile-light

Notes

  • All five production wallets show circular local logos; Simulated Wallet uses an original DEV glyph (not a vendor mark).
  • No generic bridge placeholders (addresses reopen note).
  • Install / Extension / WalletConnect / Ready chrome preserved; names truncate on narrow widths as designed (#160).
## Verification screenshots (#490) MR: !1029 (branch `fix/490-wallet-modal-circular-logos`) ### Desktop — dark theme ![490-connect-wallet-dark](/uploads/27de74f6682e24b1986bcf29a0fa9bc2/490-connect-wallet-dark.png) ### Desktop — light theme ![490-connect-wallet-light](/uploads/bc593fe788d312f5d40d8607e71f8a7c/490-connect-wallet-light.png) ### Mobile (~375px) — dark ![490-connect-wallet-mobile-dark](/uploads/865baf4a5ac6c19c5883995c10f0eb0a/490-connect-wallet-mobile-dark.png) ### Mobile (~375px) — light ![490-connect-wallet-mobile-light](/uploads/cba930252ca58ea6be9b6dc5b3122c94/490-connect-wallet-mobile-light.png) ### Notes - All five production wallets show circular local logos; Simulated Wallet uses an original DEV glyph (not a vendor mark). - No generic bridge placeholders (addresses reopen note). - Install / Extension / WalletConnect / Ready chrome preserved; names truncate on narrow widths as designed (#160).
PlasticDigits commented 2026-07-14 11:28:26 +00:00 (Migrated from gitlab.com)

mentioned in commit 37345ae46b

mentioned in commit 37345ae46b502b37e95a1744cf270b72b121cac9
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-07-14 11:28:27 +00:00
PlasticDigits commented 2026-08-18 00:20:44 +00:00 (Migrated from gitlab.com)

mentioned in issue #554

mentioned in issue #554
PlasticDigits commented 2026-08-18 15:21:52 +00:00 (Migrated from gitlab.com)

mentioned in issue PlasticDigits2/ustr-cmm#17

mentioned in issue PlasticDigits2/ustr-cmm#17
PlasticDigits commented 2026-08-18 15:22:41 +00:00 (Migrated from gitlab.com)

mentioned in issue #566

mentioned in issue #566
PlasticDigits commented 2026-08-18 15:22:43 +00:00 (Migrated from gitlab.com)

marked as related to #566

marked as related to #566
PlasticDigits commented 2026-08-26 04:23:24 +00:00 (Migrated from gitlab.com)

mentioned in issue #672

mentioned in issue #672
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#490
No description provided.