All Insights01 / Design & UX · 8 min read

The Web3 UX Manifesto: Designing for Cryptographic & Asynchronous State

Why copying Web2 SaaS templates breaks onchain applications, and how we design interfaces around client-side ZK proving, passkey account abstraction, and deterministic transaction states.

01. The Fallacy of the "Clean" Web2 Wrapper

For the last four years, the standard advice in crypto design has been to make Web3 look like Web2. Teams hire generalist product designers who strip away technical indicators, wrap everything in minimal cards, and hand the Figma file to frontend engineers. The result looks great in a static pitch deck and falls apart the moment a real user connects a wallet on mainnet.

Onchain software has fundamentally different physics than a REST API. In Web2, clicking a button triggers an optimistic database write that resolves in 80 milliseconds. In Web3, a single user action might require generating a Groth16 zero-knowledge witness in a browser WebWorker, querying an offchain MPC cluster, simulating slippage across two liquidity pools, and awaiting block finality. Hiding those mechanics behind a generic spinner does not simplify the product. It makes the user feel blind when custody of their capital is on the line.

02. Designing Around Client-Side Zero-Knowledge Proving

When we engineered the interface for Civitas, our confidential payroll protocol on Solana, the hardest UX challenge was not visual layout. Every employee claim requires generating a Groth16 proof over a 20-level Poseidon Merkle tree directly inside the browser using snarkjs and WebAssembly. On a standard laptop or mobile browser, witness generation and proving take between 2.8 and 4.1 seconds.

If a user clicks "Claim Salary" and the browser thread freezes for four seconds, they assume the app crashed and refresh the tab, destroying the ephemeral witness state. We solved this by moving proving into a dedicated WebWorker and designing a real-time 4-stage cryptographic progress drawer: (1) Fetching blinded MPC share from Nillion nilDB, (2) Computing Poseidon Merkle path locally, (3) Generating 256-byte Groth16 proof, and (4) Submitting to the Solana alt_bn128 verifier.

CIVITAS CLIENT-SIDE PROVING STATE MACHINE (UX TELEMETRY)SOURCE
type ClaimUxPhase =
  | { step: 1; label: 'Fetching blinded voucher share from Nillion nilDB...' }
  | { step: 2; label: 'Verifying depth-20 Poseidon Merkle path in local WASM...' }
  | { step: 3; label: 'Computing 256-byte Groth16 zero-knowledge proof (~3.2s)...' }
  | { step: 4; label: 'Dispatching nullifier & scheduling 5x jittered USDC payout...' }

03. Killing Seed-Phrase Friction with Passkey Account Abstraction

When we built ChainPot V4 on Base, our target users were not DeFi power users. Rotating savings circles (ROSCAs / chit funds) are used by everyday savers who want predictable USDC contributions and transparent yields via Compound V3. Asking a first-time saver to install a browser extension, write down 12 seed words, and buy ETH on Base just to pay $0.01 in gas kills 85% of the funnel before the first deposit.

We integrated ERC-4337 smart accounts paired with WebAuthn biometric passkeys (FaceID / TouchID) and a USDC-sponsored Paymaster. Users create a non-custodial smart account in four seconds using their device biometrics, and gas fees are abstracted away completely. Good Web3 UX means matching the security model to the human workflow.