Review: CL8Y Bridge End-to-End UX Verification Checklist v1.0 (draft)

@PlasticDigits per your standing 'additional specs' request: drafting a bridge E2E UX verification checklist to close the biggest remaining gap. No spec currently exists for bridge UX comprehensively — #113 (tooltip finding) was a micro-slice of what a full spec would systematically cover.

Review inline here. Once approved I'll commit to `cl8y-ecosystem-qa/specs/` and open mirror tracking issue on cl8y-bridge-monorepo per the usual pattern.


CL8Y Bridge — End-to-End UX Verification Checklist

Flow: Cross-chain bridge user experience — chain+token selection, approvals, transfer submission, progress tracking, history, verify, settings, error handling, responsive layout Author: @Brouie (AVE) Version: 1.0 — 2026-04-22 Repo: cl8y-bridge-monorepo Surface: https://bridge.cl8y.com/ Status: Draft for dev review

1. Purpose & Scope

This checklist covers visual / manual UX verification of the CL8Y bridge frontend across all primary user flows spanning 4 chains (Terra Classic, BSC, opBNB, Solana). It complements automated E2E matrix testing (Playwright, operator integration, multichain-rs tests) by covering what those don't catch: pre-transaction UX, progressive disclosure, error-state clarity, multi-wallet flows, responsive layout, and accessibility.

In-scope flows

  • A. Chain + token selection
  • B. Amount input + validation (inline + tooltip per #113)
  • C. Recipient address (manual, autofill, validation)
  • D. Wallet connection per chain (Terra, EVM, Solana)
  • E. Token approval (EVM chains)
  • F. Transfer submission + progress stepper
  • G. Transfer history page
  • H. Verify page
  • I. Settings
  • J. Error, loading, and empty states
  • K. Responsive layout (mobile / tablet / desktop)
  • L. Accessibility basics
  • M. Cross-browser smoke

Out-of-scope

  • Operator + canceler backend correctness (covered by backend tests / security reviews)
  • Contract-level security (covered by security audits + ust1-window-style sweeps)
  • Onchain matrix verification (covered by `verify-qa-onchain.sh` + mainnet E2E matrix)
  • Explorer integration correctness (assume block explorer is ground truth)

Required evidence per item

  • Screenshot or short recording
  • Viewport / browser noted per capture
  • `xchainhashid` for any on-chain transfer executed
  • Wallet used noted (Station, Keplr, Leap, MetaMask, Backpack, Phantom, Solflare)

2. Prerequisites

  • bridge.cl8y.com reachable and current bundle matches expected deploy
  • 4-chain test wallet coverage: Terra (Station + at least one other), BSC or opBNB EVM (MetaMask + one other), Solana (Backpack + Phantom)
  • Test funds on each chain: native gas + at least 2 bridgeable tokens
  • Registered token mappings on the bridge for test tokens
  • Operator + canceler online for the target environment
  • Block explorer URLs bookmarked for each chain

3. A. Chain + Token Selection

A1. Source chain selector

  • All 4 chains selectable (Terra Classic, BSC, opBNB, Solana)
  • Active source chain visually distinguished
  • Chain icons visible
  • Selection persists sensibly across navigation

A2. Destination chain selector

  • All valid destination chains shown
  • Same-chain option NOT offered (cannot bridge to self)
  • Unsupported source→destination combos filtered out before user tries (prevents dead routes)
  • Swap-direction arrow button works and updates both selectors

A3. Token selector

  • Tokens filtered by selected source chain
  • Only tokens with a mapping to the destination chain appear
  • Unsupported tokens do not show (e.g. CL8Y→Solana correctly absent from current config)
  • Token symbol + icon visible
  • Disabled tokens (e.g. `is_active: false` in registry) either filtered out or clearly marked

A4. Route validity

  • Invalid combos caught at selector layer (strongest UX per #113 close)
  • No dead-route attempts reach the amount/submit stage
  • Error tooltip or copy if somehow a dead route is reached (defensive)

4. B. Amount Input + Validation

B1. Amount input mechanics

  • Decimal input accepts token's actual decimals (18 for EVM ERC20, varies for Solana SPL)
  • MIN / MAX buttons populate respective bounds
  • Balance and MIN+MAX shown in the input header
  • Enter key does not accidentally submit form mid-input

B2. Below-minimum state (verified on #113 closed today)

  • Inline rose copy below amount field: 'Amount is below the minimum transfer amount (X token)'
  • Tooltip on disabled Bridge button (via parent span wrap): 'Amount below minimum (X token)'
  • Button styled as disabled, not primary-action
  • MIN value displayed matches on-chain minimum

B3. Above-maximum state (verified on #113 closed today)

  • Inline rose copy: 'Amount exceeds the maximum (X token)'
  • Tooltip: same message
  • MAX reflects either per-tx cap OR wallet balance, whichever is lower, with clear labeling

B4. Invalid amount (0, empty, non-numeric)

  • 0: falls into below-min behavior correctly
  • Empty: disabled state with 'Enter amount' style copy
  • Non-numeric: rejected at input level or validated with clear message

B5. Token with insufficient balance

  • If user selects token they don't hold: amount field still accepts but validation blocks submit
  • Clear 'insufficient balance' message vs the pre-tx generic validation

B6. Rate-limit awareness

  • If per-chain or per-token rate limits approach, user sees an advance warning BEFORE submitting
  • 'MAX: X · 01:37:24' timer visible (as observed on production) — helps user understand throttle

5. C. Recipient Address

C1. Manual entry

  • Recipient field accepts chain-appropriate format (`terra1...`, `0x...`, Solana base58)
  • Format validation: rejects mismatched prefix for destination chain
  • Short or malformed addresses blocked from submit

C2. Autofill with connected wallet

  • 'Autofill with connected wallet' link/button visible when appropriate
  • Fills correct destination-chain wallet if user has one connected
  • Hides or disables if no compatible wallet is connected

C3. Address display

  • Filled address shown in full or with clear truncation
  • Copy / clear action available
  • Warning if recipient address equals sender (same-wallet cross-chain is valid but worth acknowledging)

C4. Cross-format protection

  • Pasting a Terra address into an EVM recipient field: caught and rejected with clear message
  • Inverse: pasting 0x into Terra recipient: caught
  • Solana base58 → EVM: caught

6. D. Wallet Connection

D1. Terra wallet

  • 'Connect TC' button visible when no Terra wallet connected
  • Button switches to connected-state UI (address truncated, click for details) when connected
  • Supported wallets at minimum: Station. If Keplr / Leap supported: both should work with no quirks
  • Disconnect returns cleanly to pre-connect state

D2. EVM wallet

  • 'Connect EVM' button for BSC + opBNB
  • Network switch prompt if wallet is on wrong network
  • Chain icons clearly indicate which EVM chain is active
  • If source = BSC and wallet is on opBNB, UI prompts to switch before allowing approve/submit

D3. Solana wallet

  • 'Connect SOL' button
  • Supports Backpack, Phantom, Solflare (per meeting notes Solflare still pending — flag if present)
  • Each wallet's deep-link on mobile / browser-extension on desktop works

D4. Multiple wallets connected

  • User can have Terra + EVM + Solana connected simultaneously
  • Wallet display in header shows all three state indicators
  • Disconnecting one does not disconnect others

D5. Wallet mismatch (iPhone Keplr — ref bridge #5 longstanding)

  • iPhone Keplr switching chain connect order should not cause wrong-address binding
  • This is an edge case from existing #5 bug — spec should check for regression

7. E. Token Approval (EVM chains)

E1. Approval prompt

  • For ERC20 on BSC / opBNB, approve step happens before bridge submit
  • User sees clear 'Approve X token' prompt with amount requested
  • Unlimited vs exact-amount approval: tell user which is being requested

E2. Existing allowance

  • If user already has sufficient allowance, approve step is skipped
  • No redundant approval prompts

E3. Approval rejection

  • User rejects approval: UI returns to pre-approval state cleanly, no stuck spinner
  • Error message explains that approval is needed to proceed

E4. Gas + native balance check (pre-approval)

  • If wallet lacks native gas to submit approval, warn before prompt
  • Shows gas balance vs estimated approval gas cost

8. F. Transfer Submission + Progress Stepper

F1. Submit mechanics

  • Bridge button becomes primary-styled once all validation passes
  • Wallet prompt with readable transaction preview (not raw calldata)
  • Source-chain tx hash captured and displayed immediately on broadcast

F2. 4-step progress stepper

  • Step 1: Source tx submitted + confirmed
  • Step 2: Source tx validated by operator
  • Step 3: Destination approve-transaction submitted (if Solana inbound) OR destination tx executed directly (other routes)
  • Step 4: Destination withdraw-executed / tokens received

Per-step:

  • Visual indicator of current step
  • Timestamp per completed step
  • Tx hash clickable to appropriate chain explorer
  • Estimated time remaining based on typical operator latency

F3. Partial progress persistence

  • User navigates away and back: stepper state restored from history
  • Browser refresh during in-flight transfer: state recovered from indexer

F4. Failure at a step

  • Clear 'Failed at step N' state with reason (operator rejection, chain error, etc.)
  • Retry path surfaced where applicable (e.g. destination tx needs user action for Solana withdraw_execute)
  • Contact / support affordance if stuck (Telegram link, docs reference)

F5. Solana inbound withdraw flow (per #111 closure today)

  • User bridging TO Solana must call `withdraw_execute` themselves (not operator auto-executed)
  • UI must clearly prompt user for this action after operator approves
  • 'Execute withdrawal' button or equivalent that triggers the Solana tx
  • Sufficient Solana native gas to execute

F6. Completion state

  • Success banner with `xchainhashid` for traceability
  • Both source + destination tx hashes visible
  • Links to both chain explorers
  • 'Bridge another' CTA to reset form

9. G. Transfer History Page

G1. History list

  • Tab or page accessible from main nav
  • Shows user's recent transfers across all chains
  • Each row: source chain → destination chain, token, amount, status, timestamp
  • Click-through to per-transfer detail view

G2. Status filtering

  • Filter by status (all / in-progress / completed / failed)
  • Sort by newest / oldest

G3. Per-transfer detail

  • Full 4-step stepper for any past transfer
  • All tx hashes with explorer links
  • `xchainhashid` prominent
  • Resumable: if transfer is stuck at a step user can action, the detail page surfaces the action

G4. Empty state

  • First-time user with no transfers: clear empty state with 'Bridge your first transfer' CTA

G5. Post-deploy history

  • After a new bundle deploys, history from prior deploys should still be visible (indexer-backed, not frontend-local)

10. H. Verify Page

H1. Verify layout

  • Per-chain verification status visible
  • For each chain: operator last-seen block / height, bridge contract reachable, chain registered status
  • T2022 verification surface (per recent bridge #97 work) present and checkable

H2. Verify drill-down

  • Click into a chain to see per-token verification (token mappings, allowances, registered status)
  • 24/24 pattern from prior T2022 verification runs matches expected token count

H3. Verify errors

  • If a chain RPC is down / degraded, verify page shows a clear indicator, not a blank result
  • Indexer lag or gap detected: flagged

11. I. Settings

I1. Network selection

  • If bridge supports multiple environments (mainnet / testnet), selector is present
  • Current environment prominently displayed

I2. Slippage / tolerances

  • Any user-configurable tolerances accessible from settings

I3. RPC preferences

  • Per-chain RPC URL override (for power users) — may be out of scope depending on product direction

I4. Theme

  • Light / dark toggle accessible and persistent

12. J. Error, Loading, and Empty States

J1. Loading

  • Chain balance fetch: spinner or skeleton per chain, not a blank
  • Token mapping fetch: cached and doesn't block UI
  • Indexer lag acknowledged if >10s behind

J2. Errors

  • RPC down (one chain): isolated, other chains still usable
  • All RPCs down for a chain: clear message, no spinner hang
  • Operator offline: warn user before they submit; do not let them broadcast a tx that will get stuck
  • Rate-limited by wallet extension: backoff message, not a raw error

J3. Empty states

  • No connected wallet: clear CTA (verified #113 pattern for Terra)
  • No history: clear empty state
  • No available routes: if all tokens are disabled (maintenance mode), clear global banner

J4. First-time visitor

  • Incognito: landing usable without prior state
  • No stale wallet prompts
  • Clear intro to what the bridge does

13. K. Responsive Layout

K1. Desktop (≥1280px)

  • All primary surfaces fit without horizontal scroll
  • Wallet-connect buttons in header have space for all 3 chains
  • History table renders fully, no truncation

K2. Tablet (768-1279px)

  • Header adapts (wallets may collapse to a single 'Wallets' dropdown)
  • Form stays single-column, thumb-reachable

K3. Mobile (320-767px)

  • Bottom-nav or hamburger for main nav
  • Wallet deep-link flows work for mobile Station, Keplr, Phantom, Backpack
  • 4-step stepper readable on narrow screens

K4. Safe-area / notch

  • iOS safe-area padding respected

14. L. Accessibility Basics

L1. Keyboard

  • All interactive elements Tab-reachable
  • Focus indicators visible
  • Modals trap focus and restore on close

L2. Screen reader smoke

  • Landmarks present
  • Wallet connect buttons labeled
  • 4-step stepper progression announced via aria-live
  • Tx hash copy action has accessible label

L3. Color contrast

  • Rose error text on dark background: verify ≥4.5:1
  • Primary CTA button: verify legibility

L4. Motion

  • `prefers-reduced-motion` respected for progress animations

15. M. Cross-Browser Smoke

M1. Desktop browsers (minimum)

  • Chrome (latest): full flow
  • Firefox (latest): full flow — historically flakier for wallet extensions
  • Safari (latest): full flow + wallet compat check

M2. Mobile browsers

  • iOS Safari: wallet deep-link flows (Station, Phantom, Backpack)
  • Chrome Android: same
  • DuckDuckGo / Brave: if time allows

16. Execution Guidelines

16a. Test environments

  • Pre-mainnet (required): local bridge stack via `make start-qa` with operator + canceler + LocalTerra + Anvil + test Solana validator
  • Mainnet smoke (required): bridge.cl8y.com against small-value real transfers
  • Mobile physical (recommended): real iOS + real Android for wallet deep-link flows

16b. Capture standard

  • Full-page screenshots preferred for form states
  • Screen recording (≤30s) for multi-step transfer flow
  • Naming: `
    ---.png`
  • Include `xchainhashid` in any transfer-related capture

16c. Sign-off rules

  • Each section (A-M) needs ≥1 green pass before a frontend deployment
  • Transfer flow (F) requires at least one end-to-end real mainnet pass per bundle
  • Broken validation flows (B) block deploy
  • A11y or mobile regressions (L / K): non-blocking, filed as backlog

17. Open Questions for Your Review

  • Wallet scope finalization: which Terra wallets beyond Station are officially supported? Same for EVM (MetaMask only, or Rabby / Trust Wallet / Coinbase Wallet too?) and Solana (Backpack + Phantom definite, Solflare pending per meeting).
  • Solflare status: still pending from prior sessions — if it's going to ship, spec should include it
  • T2022 verification surface: how should the Verify page display T2022 status vs regular SPL tokens? Should this be a separate tab?
  • History storage: backend-indexed or browser-local? Impacts spec for 'history across deploys' item
  • Mobile wallet strategy: WalletConnect QR, mobile-wallet deep-links, or both?
  • Rate-limit surface: how should "per-chain rate limit approaching" be warned pre-submit vs post-submit?

18. References

  • Bridge frontend: `packages/frontend/` in cl8y-bridge-monorepo
  • Operator: `packages/operator/` + security review #115
  • Canceler: `packages/canceler/` + security review #114
  • Bridge #113 (validation UX fix, closed today) — reference for B2/B3
  • Bridge #109 (RPC fallback, closed today) — reference for J2
  • Bridge #111 (post-upgrade matrix, closed today) — reference for F5 Solana withdraw flow
  • Bridge #5 (iPhone Keplr, longstanding) — reference for D5
  • Mainnet endpoint: https://bridge.cl8y.com/
  • Sister specs: UST1-Window-Security-Checklist.md, YO-DOUB-Launch-UX-Flows.md, YO-TimeCurve-Verification-Spec.md, DEX Visual UX Checklist (ecosystem-qa #10 (closed))