Docs + frontend: indexer-first reads, eliminate browser RPC fallbacks for display data #301
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#301
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Document and implement an indexer-first data policy for Arena display surfaces. Browser JSON-RPC must not be used as a fallback when the indexer is unavailable or
VITE_INDEXER_URLis unset. RPC in the wallet client remains limited to transaction signing, gas estimation, allowance/balance checks required at submit time, and other writes — with backoff, coalescing, and rate-limit awareness.This issue bundles documentation updates, frontend behavior changes, and guardrail/invariant work. It does not include podium prize amounts (see linked issue for
GET /v1/arena/podiumspayout fields).Current codebase
Indexer already centralizes head RPC
The Rust indexer runs a background
chain_timerpoller (indexer/src/chain_timer.rs) that batcheseth_callreads at a sharedread_block_numberand serves:GET /v1/arena/timers— deadlines, epochs,total_doub_raised,pausedGET /v1/arena/podiums— UX-ordered leaders + scores (no prize amounts today)GET /v1/arena/buys,/activity,/wallet/{address}/stats, vault-funding, donate-poolsSee
docs/indexer/design.md§ Arena HTTP.Frontend still falls back to browser RPC in multiple places
usePodiumReads.tsVITE_INDEXER_URLset; else 8×podium+ epoch multicall ~1 HzArenaTimerChips.tsxpodiumDeadlineRPCuseArenaSaleSession.tsindexerOn = indexerBaseUrl() && !isArenaV2) — core sale reads always via wagmi multicalluseWarbowBpMovingEventWatchuseWatchContractEventwhen indexer offuseArenaHeroTimer.tswagmi-config.tsDocs currently describe indexer as optional and RPC as acceptable fallback, e.g.
docs/frontend/arena-views.md(“GET /v1/arena/podiumsor RPC”),skills/play-active-time-arena/SKILL.md, and comments inusePodiumReads.ts.Why this hurts production
Why the new implementation is needed
useReadContractsfor data the indexer can serve.Constraints & guardrails
yieldomega-guardrailsSKILL): prizes, winners, routing remain contract truth; indexer is derived.buy,claimCred, WarBow actions,topUpPodiumPools, approvals — no indexer substitution.nextBuyAllowedAt, simulate) — document as allowed exception.docs/testing/e2e-anvil.md.IndexerStatusBar/ cached stale state — not browser RPC backfill.Relevant files
Docs (update/create policy sections):
AGENTS.md— Cloud agent verification tabledocs/frontend/arena-views.mddocs/frontend/design.mddocs/frontend/wallet-connection.mddocs/indexer/design.md§ API guidelinesdocs/testing/invariants-and-business-logic.mddocs/testing/manual-qa-checklists.mdskills/play-active-time-arena/SKILL.md.cursor/skills/yieldomega-guardrails/SKILL.mdFrontend (remove display RPC fallbacks / enable indexer for v2 session):
frontend/src/pages/arena/usePodiumReads.tsfrontend/src/pages/arena/ArenaTimerChips.tsxfrontend/src/pages/arena/useArenaSaleSession.tsfrontend/src/pages/arena/useArenaHeroTimer.tsfrontend/src/pages/arena/arenaV2SaleSessionBridge.tsfrontend/src/lib/indexerApi.tsfrontend/src/providers/IndexerConnectivityContext.tsxIndexer (if gaps block frontend):
indexer/src/api_arena.rs— extend timers/sale-state fields if v2 session needs more than timers todayindexer/src/chain_timer.rs/sale_state.rsRecommended direction
Documentation
docs/frontend/arena-views.md+ link fromAGENTS.md).VITE_INDEXER_URLis required for production Arena; unset = degraded/dev-only with visible banner.Frontend
usePodiumReads: RemoveuseReadContractspodium/epoch path; when indexer off or failing, return empty/placeholder +source: "unavailable".ArenaTimerChips: Indexer-only for deadlines.useArenaSaleSession: Remove!isArenaV2gate; mapGET /v1/arena/timers(and extend indexer if needed) via existinguseArenaSaleStateQuery/arenaV2SaleSessionBridge.useWarbowBpMovingEventWatch: Disable contract event watches when indexer configured (already partial); rely on indexer poll + invalidation only.refetchIntervaldisplay reads; migrate or justify in docs.Indexer (only if required for v2 session)
GET /v1/arena/timers(or a thinGET /v1/arena/head) exposes all fieldsarenaV2SaleSessionBridgeneeds so frontend can drop core multicall entirely.Invariants
INV-FRONTEND-INDEXER-FIRST-DISPLAY: no wagmi read path for podium/timers/sale head whenVITE_INDEXER_URLset.Acceptance criteria
VITE_INDEXER_URL.VITE_INDEXER_URLset, browser makes no recurringeth_callmulticalls for podiums, podium deadlines, or core sale head fields (verify via DevTools /VITE_RPC_DEBUG=1).VITE_INDEXER_URLunset, UI shows dev/degraded banner; no hidden RPC polling for those surfaces.cd frontend && npm run typecheck && npm run lint && npm testPASS.cd indexer && cargo clippy --all-targets -- -D warnings && cargo testPASS (if indexer API touched).Test plan (functional paths)
start-qa-local-full-stack.sh, open/arenawith indexer URL/arenaVITE_INDEXER_URL, restart Vite/arena/protocole2e-anvil.shwithout indexerverify-podium-live-anvil.shTest plan (attack, hack, abuse vectors)
reportIndexerFetchAttemptfails; submit-timedeadline/nextBuyAllowedAtstill read via RPC at click (allowed exception)frontendlint/grep check in CI optional: banenabled: !indexerOnpatterns in arena hooksVerification criteria
Out of scope (separate issue)
GET /v1/arena/podiumsandArenaSimplePagewiring.mentioned in issue #302
mentioned in commit
a907b30e10mentioned in commit
3508d688damentioned in merge request !446
Implementation complete for https://gitlab.com/PlasticDigits/yieldomega/-/work_items/301 — MR: https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/76
Summary
GET /v1/arena/timersnow includes Arena v2 sale-head fields batched atread_block_number.coreReadRowsFromArenaTimers.INV-FRONTEND-301-INDEXER-FIRST-DISPLAYand canonical policy docs indocs/frontend/arena-views.md.Verification (all PASS)
cd frontend && npm run typecheck && npm run lint && npm testDATABASE_POOL_MAX=5 cargo clippy --all-targets -- -D warnings && cargo testbash scripts/verify-podium-live-anvil.shindexerFirstDisplay.test.tsIssue remains open pending MR review/merge.
mentioned in commit
cbeb0db44ementioned in commit
67196222d3mentioned in commit
60cf970f15mentioned in commit
2c14558b4bmentioned in commit
6a27b7c8bcmentioned in merge request !451
mentioned in issue #303
mentioned in issue #305
mentioned in issue #306
mentioned in issue #309
mentioned in merge request !456
mentioned in issue #321
mentioned in issue #322
mentioned in merge request !468
mentioned in commit
93c0cff974mentioned in commit
cbb2a904b9mentioned in issue #330
mentioned in issue #331
mentioned in merge request !504
mentioned in issue #332
mentioned in issue #333
mentioned in issue #338
mentioned in issue #339
mentioned in merge request !506
mentioned in issue #343
mentioned in issue #356
mentioned in issue #361
mentioned in merge request !533
mentioned in merge request !534
mentioned in issue #362
mentioned in issue #367
mentioned in issue #370