verex

Verex — Trade/resolution latency UX (Jul 22 design)

Where the wait actually comes from

Traced both flows in the current code rather than guessing:

1. Pre-warm demo wallets — attack the root cause, not just the loading state (do this first)

Mint + approve don’t need to happen inside the trade request at all. Demo wallet indices are known in advance and both operations are idempotent (already conditionally skipped once satisfied — see trade.ts:124-132). Extend the seed flow to also pre-approve each demo wallet for the exchange (USDC) and the CT contract (setApprovalForAll), the same place seed.ts already tops up their USDC balance (seed.ts:320-328).

2. Optimistic UI update on submit — perceived-instant feedback for the wait that’s left

Even a single real confirmation is 2–15s on testnet — worth hiding via the standard trading-UX pattern (this is how Polymarket/every DEX front-end handles it): the moment the user clicks Buy/Sell/Resolve, update the UI to the expected end-state immediately, before the request resolves, then reconcile against the real response:

3. Staged progress instead of one static label — only for the cases that still chain multiple steps

After #1, the first trade a fresh demo wallet ever makes can still chain mint+approve+ fillOrder (pre-warming only covers wallets that went through the seed flow — fine for this app’s closed demo-wallet set, but worth having a fallback for). For that path specifically, replace the single "Submitting on-chain…" label with a 1–3 step inline list (“Funding → Approving → Filling”) that lights up as each await in trade.ts completes, instead of one opaque state for the whole chain.

Order of work + verification

# Item Verify
1 Pre-warm demo wallets (mint + approve) in seed.ts verified 2026-07-22 — ran the seed against a fresh local anvil, then cast call directly against the deployed contracts: wallet #1’s USDC allowance to the exchange and isApprovedForAll were both already set before any trade. POST /trade (BUY) as wallet #1 advanced the chain by exactly 1 block (fillOrder only, faucetMinted: false) — vs. 3 blocks (mint + approve + fillOrder) for wallet #6, which the seed loop doesn’t cover (only 1-5, matching the UI’s wallet picker) — a direct, empirical before/after comparison, not just code-reading.
2 Optimistic trade UI in TradePanel tsc --noEmit clean; logic traced by hand (the pending snapshot is cleared before setResult/setError so the pending and confirmed/error boxes never render simultaneously). Not visually verified in a browser — no browser/screenshot tool available in this environment; jay should click through a BUY once to confirm the pending box renders as expected before considering this fully done.
3 Optimistic resolve UI in ResolvePanel (optional/lower priority) not built — deferred, jay didn’t ask for this one specifically and it was flagged lower-priority in the original proposal
4 Staged progress for the fallback (unwarmed wallet) path — only if #1 turns out insufficient in practice not built — per the original recommendation, only worth doing if this turns out to matter

Next phase

Current status, precisely (jay confirmed this understanding 2026-07-22): trading’s remaining few-seconds wait is the intended state — real confirmation time for the one now-unavoidable fillOrder, made to feel instant by the optimistic preview, not actually eliminated (can’t be, without claiming a trade succeeded before it’s confirmed). Resolution’s few-seconds wait is not improved — it’s the original, untouched behavior, since §3 below was explicitly deferred rather than built. Next actionable items, in order:

  1. Optimistic resolve UI in ResolvePanel (was §3/item 3 above, “optional/lower priority” — jay asked 2026-07-22 whether to do this now that the gap is visible on a real chain). Same pattern as TradePanel: on clicking “Confirm Yes/No”, show the “RESOLVED — YES/NO” badge immediately (snapshotted, same drift-avoidance as the trade preview), reconcile via the existing router.refresh() on success, roll back to the confirm buttons on error. Small, self-contained — touches only ResolvePanel.tsx, no API change. Not yet built — this is the next thing to do when jay says go.
  2. Staged progress for the fallback (unwarmed-wallet) path (§3b / item 4) — still explicitly conditional on #1 (pre-warming) turning out insufficient in practice. No action unless that happens.
  3. Real-user deposit flow — raised by jay 2026-07-22 as a related but distinct, explicitly out-of-scope concern: pre-funding via seed.ts only works because demo wallets are server-held keys with known indices. A real user (external wallet, no server-held key) needs an actual deposit UX — bridge/on-ramp or a direct testnet-ETH + USDC transfer flow into their own address, plus the equivalent approve step happening client-side (MetaMask, not server-signed). Not designed yet — belongs with the S7 account-abstraction/session-key track mentioned in jun-19-verex-design.md, not this doc. Flagged here only so it isn’t lost.

Out of scope