← Back to the library
FrontendApplied · 9 min

Optimistic UI lies about money

“A transaction appears successful, disappears, or makes funds spendable before authoritative state catches up.”

THE PRINCIPLE

Display uncertainty explicitly. A transaction hash is not success, and a timeout is not failure.

FIRST MOVES

  1. Model explicit phases: editing, authorizing, submitted, confirming, reconciling, complete, failed, unknown.
  2. Reserve known outflows immediately but never invent fill price, P&L, or rewards.
  3. Invalidate affected queries after execution and reconcile against authoritative state.
  4. Persist attempt identity so refresh and another device can recover progress.

TOOLS: THEN → NOW

Redux for every kind of stateTanStack Query plus a focused workflow store/state machine
Boolean loading flagsDiscriminated unions and explicit transitions

PATTERN SNAPSHOT

type PaymentState =
  | { phase: "editing" }
  | { phase: "pending"; attemptId: string }
  | { phase: "reconciling"; attemptId: string }
  | { phase: "complete"; receiptId: string }
  | { phase: "unknown"; attemptId: string };

CLOSE THE AI. EXPLAIN THIS.

What evidence lets you remove an optimistic balance reservation?

Guide reviewed