Case study · Crypto wallet · Mobile app · 2020

Your keys. Your crypto.

Harmony Wallet is a self-custody mobile wallet for the Harmony (ONE) blockchain. You can create or recover a wallet, send and receive tokens across shards, pay with a QR code and stake ONE with validators. I designed the whole app in 2020: 38 screens across five flows, all built from one design system.

Product
Harmony Wallet, a non-custodial crypto wallet with staking
Role
UX/UI designer: information architecture, flows, visual design, design system
Platform
iOS and Android, designed on a 390 × 844 frame
Scope
38 screens, 5 flows, 1 design system
Year
2020
Harmony Wallet: the dark welcome screen reading 'Your keys. Your crypto.' beside the wallet home with a 49.6546 ONE balance card. 38 screens, 5 flows, 1 design system.
01 · The challenge

Self-custody puts all the risk on the user.

There's no bank to call. If someone loses their recovery phrase or sends to the wrong address, the money is gone. The design had to make people feel in control at every step without hiding how the blockchain works.

01

Keys are scary

New users have to write down 12 words before they can do anything. If that step feels like a chore, people skip it, and a skipped backup is a lost wallet.

02

Numbers have to be exact

Balances run to four or more decimals, addresses are 42 characters long, and every transfer has a network fee. All of it has to stay readable on a phone.

03

Harmony has shards

Tokens live on numbered shards, so a transfer needs a from-shard and a to-shard. That idea has to fit into a normal send form.

04

Nothing can be undone

A transfer is final once it's signed, so the app can never say "sent" until it really has been sent.

05

Staking is dense

Validators come with returns, fees, stake history and delegator lists, which is a lot of data for a 390px screen.

The brief. Design a complete mobile wallet that covers onboarding, recovery, sending, receiving, QR payments, staking and security. It should feel secure, calm and easy to use with one thumb, and every screen should come from one shared system.
02 · Goals and principles

Four rules behind every screen.

01

One clear action

Each screen has a single green primary button. Every other action is outline, black or grey.

02

Money is the hero

Balances sit on black cards in the largest, tightest type in the app, with the fiat value and daily change right underneath.

03

Thumb-first

Confirmations, fees and pickers open as bottom sheets. Key buttons are 56px tall and full width, inside the bottom half of the screen.

04

Say what happened

Every money movement has its own review, pending and success states, each with its own icon and wording.

03 · Screen map

The whole app on one page.

I mapped the app before drawing any screens. Four tabs (Wallet, Market, Staking, Profile) sit around a raised Send button. Each flow is its own stack, and every decision opens as a bottom sheet on top of the screen it belongs to.

All 38 Harmony Wallet screens grouped into five flows: onboarding and access, wallet, send and receive, staking, and profile and security.
FlowScreensWhat it covers
01 · Onboarding and access9Welcome, three onboarding slides, create a wallet, recovery phrase backup, recover by phrase or private key, PIN unlock
02 · Wallet5Home, token detail with history, manage tokens, add a custom token
03 · Send and receive8Send form, review sheet, sent state, receipt, receive request, QR code, scanner, scan confirm
04 · Staking9Validators, validator profile, portfolio, delegate, fees, claim rewards, signing, success
05 · Profile and security7Settings, currency, recovery phrase, change PIN, PIN errors, log out
04 · Design system · Colour

Green for action. Black for money.

The palette is small on purpose. One green means "do this" or "you gained". Black holds money and navigation. Neutrals keep forms quiet. Red only ever means a loss, an error or a log out. The Harmony logo keeps its own blue-to-teal gradient, so the product brand still comes through.

Every colour is a named token in a single theme, and no screen uses a raw hex value.

The core palette of eight colours, an 11-step primary green ramp from 5 to 100, and four accent pairs for tokens, warnings, errors and success.
TokenHexUsed for
Primary#038E43Primary buttons, links, active states, positive amounts
Emerald#00DF66Highlights on black: gains, active tab, scan line
Abyss#111111Balance cards, nav bar, scanner, welcome, headings
Obsidian#333333Body text, pressed dark buttons
Ivory#D9D9D9Input borders, dividers, sheet handle
Mist#F5F5F5Soft buttons, segmented tracks, rows
White#FFFFFFPages, sheets, cards
Danger#E5484DErrors, losses, log out

An 11-step primary ramp

The green runs from 5 (#EAFBF1) to 100 (#038E43) in ten even steps. Only four steps do real work:

  • 100 is the base: buttons, links and the active tab.
  • 90 (#179B53) is the pressed state of a primary button.
  • 10 (#B4FFD6) is the tint behind info notes and selected options.
  • 5 (#EAFBF1) is the background of chips, success rows and selected cards.

Accent pairs

Each accent is a background and text pair: HRC20 token avatars #FFF7CC / #8A6D00, warnings #FFF4E5 / #8A4B00, errors at 5% danger, and confirmed states at 15% emerald.

Contrast, checked against WCAG AA

PairRatioResult
Obsidian #333333 on white (body text)12.63:1Passes AAA
Emerald #00DF66 on abyss #111111 (gains on black cards)10.56:1Passes AAA
Grey #737373 on white (captions)4.74:1Passes AA
White on primary #038E43 (15px button label)4.24:1Passes AA for large text and UI parts, short of 4.5:1 for small text
White on danger #E5484D (15px button label)3.91:1Passes 3:1 for UI parts, short of 4.5:1 for small text
Primary #038E43 on green 5 #EAFBF1 (chip text)3.95:1Short of 4.5:1 for small text
The fix. Three pairs fall a little short of AA for small text. Darkening the primary to #038941 and danger to #E12F35 brings both button labels to 4.51:1, and the change is barely visible. Green chip text should use the darker #038941 too, or move up to 15px semibold.
04 · Design system · Typography

One family, ten sizes.

Inter in four weights: 400, 500, 600 and 700. Its figures are clear at small sizes, which matters when a balance has six decimals. Money gets the biggest, tightest type. Everything else stays small and calm, so the numbers stand out.

Semibold is the workhorse, used 408 times across the screens for labels, buttons and row titles. Bold (109 uses) is kept for money and headings.

The Inter type specimen with weight usage counts, and a ten-step type scale from a 40px bold balance down to a 10px nav label.
StyleSize / weightTrackingExample
Balance40px · Bold-0.025em49.6546 ONE on the home card
Amount34px · Boldtight0.03278 ONE in a review sheet
Heading24px · BoldtightBack up your phrase
Title17px · Semibold—Confirm transfer
Body15px · Regular to Semibold—Buttons, inputs, descriptions (219 uses)
Label13px · Medium—Field labels, row meta (131 uses)
Small12px · Regular—Fiat values, helper text (226 uses)
Caption11px · Medium—Timestamps, chart labels
Overline11px · Semibold, uppercase0.14emYOU'RE SENDING
Nav10px · Medium—Wallet · Market · Staking · Profile
04 · Design system · Components

Built once, used on all 38 screens.

Five button styles, one input with three states, and a small set of selection controls cover every form in the app. Each component has a default and a pressed state, and inputs add focus and error.

Buttons in five styles, quick action tiles, inputs in default, focus and error states, segmented tabs, speed cards, chips, toggles, a select and a slider, plus a row of default and pressed button states.
ButtonDefaultPressedUsed for
PrimaryPrimary + green glowPrimary 90The one main action
DarkAbyssObsidianStrong secondary: Share, Next
Outline1.5px abyss borderMist fillAlternatives: Details, Log in
SoftMistIvory 60%Cancel, Copy
DangerDanger—Log out only
On darkWhite 30% borderWhite 10% fillSecondary on black screens

Specs

  • Buttons are 56px tall with a 16px radius and a 15px semibold label. The green glow (0 10px 30px at 35%) is only used on the primary button, so it's always the first thing you see.
  • Quick actions are 48px tiles with a 16px radius, inside the black balance card.
  • Inputs are 52px with a 16px radius and a 1.5px ivory border. On focus the border turns primary with a 4px ring at 15%. On error it turns danger, and a message appears below the field.
  • Selection covers segmented tabs on a mist track, three speed cards (Slow, Medium, Fast) with fee and time, filter chips, a toggle, a select and a stake slider.
  • Labels sit above fields, never inside them, so they stay visible while typing.
04 · Design system · Patterns

Sheets, rows and states.

The bigger pieces are put together from those components. They repeat across the app, so a user who learns one flow already knows how the next one works.

A bottom sheet for confirming a transfer, token, validator and transaction rows, info, warning and error notes, a three-step stepper, PIN boxes, the recovery grid and the floating navigation bar.
01

Bottom sheet

A 32px top radius, a 40 × 6px ivory handle, a close button on the right and one primary action at the bottom. It's used for every review, fee breakdown, picker and confirmation.

02

Rows

Token, validator and transaction rows share one layout: a 40px avatar, a name with meta below it, and the value right-aligned. Gains are green, losses are red, and pending items are grey.

03

Feedback notes

Three tinted notes, each with an icon: info on green 5, warning on amber and error on danger 5. Every note says what happened and what to do next.

04

Stepper, PIN and recovery grid

A 3-step stepper (Name, Backup, Verify). Four 64px PIN boxes with an on-screen keypad. A numbered 3 × 4 recovery grid, so the order of the words is never in doubt.

05

Navigation bar

A floating black bar, 72px tall with a 28px radius, sitting 20px above the home indicator. Send is a raised 64px green button with a 6px white ring, so the main action of the app is always one tap away.

04 · Design system · Foundations

Radius, space, depth and icons.

Underneath everything is a 390 × 844 frame with 20px side margins, a 4px spacing base, six radii, four shadows and one icon stroke.

Six radius samples from 12px to full, a 4px spacing scale, card, glow, float and sheet shadows, a grid of 24px line icons and the 390 by 844 frame.
RadiusUsed for
12pxSmall tiles, MAX tag
16pxButtons, inputs, list rows (218 uses)
24pxCards
28pxBalance card, nav bar
32pxTop of bottom sheets
FullAvatars, chips, icon buttons (307 uses)
ElevationValue
Card0 1px 2px at 4% + 0 8px 24px at 6%
Glow0 10px 30px primary at 35%, primary button only
Float0 12px 40px abyss at 35%, nav bar only
SheetLarge soft shadow over a 60% abyss scrim
  • Spacing uses a 4px base: 4, 8, 12, 16, 20, 24, 28. Screen margins are 20px, card padding 24px and row padding 14px. Gaps of 8px and 12px do most of the work (138 and 128 uses).
  • Icons are line icons on a 24px grid at a 1.8px stroke, with rounded caps and joins. 263 of the 315 strokes use 1.8px; the rest are charts and the scanner frame.
  • Safe areas. Content reserves 144px at the bottom so nothing hides behind the floating nav bar.
05 · Key flows

Five flows, 38 screens.

Each flow below shows four key screens and the decisions behind them.

Flow 01 · Onboarding

Set up in three calm steps

  • The onboarding slides use product-like illustrations (a price card, a QR transfer) instead of stock art, with a progress bar and Skip on every slide.
  • Creating a wallet is a 3-step stepper: Name, Backup, Verify. You can always see where you are and how much is left.
  • The recovery phrase is a numbered 3 × 4 grid with a security warning, plus Copy and "I've saved it" buttons.
Four onboarding screens: a live market data slide, a scan-to-pay slide, naming the wallet in step 1 of 3, and the numbered 12-word recovery phrase.
Flow 01 · Access

Get back in, safely

  • The welcome screen is black with a soft green glow, the logo in the centre and a clear promise: "Your keys. Your crypto."
  • Recovery is one screen with two tabs, recovery phrase and private key, instead of two near-identical pages.
  • Unlocking uses four PIN boxes, an on-screen keypad and fingerprint unlock.
Four access screens: the dark welcome screen, recovery by 12-word phrase, recovery by private key, and PIN entry with a keypad.
Flow 02 · Wallet

Money is the hero

  • The balance sits on a black card at 40px, with the fiat value, the daily change and a sync status underneath.
  • Send, Receive, Scan and Stake sit inside the card, right under the thumb.
  • Each token opens a detail page with a chart and its own history. Custom tokens are added from a contract address, and the app fills in the name and symbol by itself.
Four wallet screens: the home with the balance card and quick actions, a token detail with a chart, the manage tokens list and the add custom token form.
Flow 03 · Send

Review, confirm, done

  • Send shows the available balance at the top, puts token and shard side by side, and adds a MAX button and an inline balance error.
  • Network speed is three cards (Slow, Medium, Fast), each showing its fee and time.
  • A bottom sheet sums up the amount, fee, total and balance after the transfer before anything is signed.
  1. Review
  2. Confirm & send
  3. Amount sent · receipt

The rule. Nothing says "sent" until it has been sent. The receipt has copyable hashes and a link to the explorer.

Four send screens: entering details, the review bottom sheet, the Amount sent state and the transaction receipt.
Flow 03 · Receive and scan

Pay with a scan

  • Receive builds a request with an amount, token and shard, then shows a QR code on a black screen with the logo in the centre.
  • The scanner has green corner brackets, a moving scan line, a torch toggle and an option to scan from photos.
  • A scanned code opens a confirm sheet, so nothing moves until the user has checked it.
Four screens: the receive request form, a branded QR code, the scanner frame with a scan line, and the confirm sheet.
Flow 04 · Staking

Stake ONE with confidence

  • Validators opens with three network stats on a black card, then search, Elected and All filters, and a list sorted by expected return.
  • The validator profile stacks into cards that fit a phone: a summary with Delegate and Undelegate, general info and stake history.
  • Portfolio shows delegations at a glance. The delegate sheet has a slider and warns you before you stake your full balance.
Four staking screens: the validator list, a validator profile, the portfolio, and the delegate sheet with a full-balance warning.
Flow 04 · Rewards

Claiming has three honest states

  • Fees have their own tab, so the total is clear before signing.
  • Signing happens in an external wallet, and the app says so plainly while it waits.
  • After signing, the claim shows a pending state and then a final state with a link to the transaction.
  1. Fees
  2. Signed & sent · pending
  3. Rewards claimed
Four reward screens: the fees tab of the delegate sheet, the claim rewards sheet, a signed and sent pending state, and the rewards claimed state.
Flow 05 · Profile and security

Security you can find

  • Settings are grouped lists (Wallet, Security) with icon tiles, current values and a fingerprint toggle.
  • The recovery phrase is shown behind a warning, with the same numbered grid as onboarding.
  • A PIN mismatch turns every box red and shows a plain message. Log out opens a red-accented sheet that reminds you to back up your phrase first.
Four screens: grouped profile settings, the recovery phrase behind a warning, a change PIN mismatch error, and the log out sheet.
06 · Handoff

A design system that lives in code.

The app targets iOS and Android from a single React Native codebase, so the system was organised the way code would use it.

01

Theme tokens

Colours, type sizes, spacing, radii and shadows sit in one theme. Every screen reads from it, so a palette change, such as the contrast fix above, happens in one place.

02

Component library

Button, Input, Select, BottomSheet, PinPad, Stepper, TokenRow, ValidatorRow, StatCard and TabBar, each with variants, used across all 38 screens.

03

Navigation

A bottom tab navigator holds Wallet, Market, Staking and Profile, with Send as a raised centre action. Each flow is its own stack, and confirmations open as modal bottom sheets.

04

Native features

Fingerprint unlock uses the device's biometrics, and the QR scanner uses the camera with a torch toggle. Keys and the PIN stay in the device's secure storage, never on a server.

07 · Outcome

Where it landed.

A complete wallet UI, from the first launch to staking rewards, built from one shared theme and component library.

38
Screens, including every pending and success state
5
Flows, from onboarding to staking
10
Reusable components with variants
1
Design system behind every screen
08 · What I learned

In a wallet, colour is a trust signal.

01

Less green, clearer screens

Keeping green for action and gain made every screen easier to scan.

02

Honest states beat polish

Separate review, pending and success screens did more for trust than any visual detail.

03

Check contrast early

The brand green looked strong but sat just under AA for small white text. A one-step darker shade fixes it, and it's cheaper to catch at the token stage.

What's next
→

Usability testing

Test the send and delegate flows with five ONE holders.

→

Contrast tokens

Ship the darker primary and danger shades across the theme.

→

Dark mode

Build it from the same tokens.

→

Missing states

Design empty, offline and failed-transaction states.