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
- Model explicit phases: editing, authorizing, submitted, confirming, reconciling, complete, failed, unknown.
- Reserve known outflows immediately but never invent fill price, P&L, or rewards.
- Invalidate affected queries after execution and reconcile against authoritative state.
- 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