Arena buys API: full BuyItem parity (new_deadline, buy_index, block_timestamp, log_index) #283
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#283
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?
Context / parent
Follow-up to #282 (expose
actual_seconds_addedonGET /v1/arena/buysfor timer-extension chip / #258 QA). That issue intentionally scoped toactual_seconds_addedonly. This issue completes the core log-identify + timer metadata slice of frontendBuyItemparity from the arena buys endpoint.Related: #254 (arena schema), #258 (wallet profile / buy detail UX), #255 (wallet stats already reads full buy rows from SQL).
Current codebase
Indexer — persisted but partially exposed
idx_arena_buy(indexer/migrations/20240601000000_arena_v2.up.sql) storesnew_deadline,buy_index,block_timestamp,log_index, plustotal_doub_raised_after,actual_seconds_added, etc. Primary key(tx_hash, log_index).TimeArenaBuylogs:indexer/src/decoder.rs,indexer/src/persist.rs.GET /v1/arena/buys(indexer/src/api_arena.rsarena_buys): after #282, exposesbuyer,charm_wad,doub_paid,block_number,tx_hash,timer_hard_reset,paid_with_cred,actual_seconds_added. Still omitsnew_deadline,buy_index,block_timestamp,log_indexat the HTTP boundary.GET /v1/arena/vault-funding/*andGET /v1/arena/podium-pool-donationsalready emitblock_timestampas unix-sec strings viaEXTRACT(EPOCH FROM block_timestamp)::text(api_arena.rs).new_deadline,actual_seconds_added, etc. (indexer/src/arena_wallet_stats.rs).Frontend —
BuyItemexpects fields; mapper stubs themfrontend/src/lib/indexerApi.ts:BuyItemincludeslog_index,block_timestamp,new_deadline,buy_index(required strings/numbers for detail UX).mapArenaBuyToBuyItemcurrently setslog_index: 0,new_deadline: "0",buy_index: "0"and omitsblock_timestamp— even when the API is extended, the mapper must pass through.${tx_hash}-${log_index}—ArenaLiveBuysActivitySection.tsx,ArenaBuyModals.tsx,ArenaSimplePage.tsx(pulseKey),peerBuyHeadSfxTick.tsnew_deadlineunix display —ArenaBuyModals.tsxtimeArenaUx.tsdetail rows (Log index, Block time, New deadline, Buy index)ArenaLiveBuysActivitySection.test.tsx,peerBuyHeadSfxTick.test.ts).Verify scripts
scripts/verify-wallet-profile-anvil.sh(#282) assertsactual_seconds_added+ wallet stats; should gain DB/API parity checks for the four fields (or extend a dedicatedverify-arena-buys-parity-anvil.shif cleaner).Why this is needed
log_index: 0for every row can cause list reuse bugs and missed peer-buy head SFX when multiple logs share UX assumptions.idx_arena_buyfor all core columns reduces ad-hocpsql/curldebugging.Constraints & guardrails
Buylogs in DB; indexer projects only — no client-side recomputation of deadlines or buy index./v1/timecurve/*— arena routes only (#266).block_timestampencoding: Prefer unix seconds string (nullable) consistent with vault-funding / donate-pools endpoints — not raw ISO in JSON unless documented and mirrored everywhere.log_indexencoding: JSON number (matchesBuyItem.log_index: number); DBINT; stable per(tx_hash, log_index)PK.new_deadline/buy_index: Decimal strings (same pattern ascharm_wad/actual_seconds_added).new_deadline,buy_index,block_timestamp,log_indexonly. Out of scope unless trivial:total_doub_raised_after, BP breakdown fields,block_hash,contract_address,price_per_charm_wad— track separately if product needs full legacyBuyItemparity.Prerequisite: Merge/deploy #282 (
actual_seconds_added) first.Recommended solution direction
A. Indexer — extend
GET /v1/arena/buysnew_deadline::text,buy_index::text,log_index,EXTRACT(EPOCH FROM block_timestamp)::text AS block_timestamp(nullable).new_deadline,buy_index,log_index,block_timestamp(omit ornullwhenblock_timestampIS NULL — document behavior).integration_stage2fixture: persisted buy with known values → HTTP asserts all four (+ #282actual_seconds_added) match DB.docs/indexer/design.md§ arena buys; addINV-INDEXER-*-ARENA-BUYS-PARITY(or extendINV-INDEXER-282-ARENA-BUYS-SECONDS) indocs/testing/invariants-and-business-logic.md.B. Frontend — pass-through
ArenaBuyItemwith the four fields (types aligned with JSON).mapArenaBuyToBuyItem; audit directfetchArenaBuysconsumers.indexerApi.test.tsfixture JSON.C. Verify script
verify-wallet-profile-anvil.sh(preferred) or addverify-arena-buys-parity-anvil.sh: after buy ingest,curl/v1/arena/buys?limit=1+psqlspot-check fornew_deadline,buy_index,log_index,block_timestampvs API.INV-FRONTEND-258-WALLET-PROFILE, arena-views § wallet-profile,.cursor/skills/yieldomega-guardrails/SKILL.md,docs/testing/ci.md.Relevant files
indexer/src/api_arena.rsindexer/tests/integration_stage2.rsindexer/migrations/20240601000000_arena_v2.up.sqlfrontend/src/lib/indexerApi.tsArenaBuyModals.tsx,timeArenaUx.ts, live-buy sectionsscripts/verify-wallet-profile-anvil.shdocs/indexer/design.md,docs/testing/invariants-and-business-logic.mdAcceptance criteria
GET /v1/arena/buysitems includenew_deadline,buy_index,log_index,block_timestamp(unix sec string or documentednull).idx_arena_buyfor thattx_hash/log_index.fetchArenaBuysAsBuyItemssurfaces all four onBuyItem(non-zerolog_indexwhen chain emitted non-zero).tx_hash+log_indexkeys (no longer alllog_index: 0from mapper).new_deadlinewhen present (existingUnixTimestampDisplaypath).PATHfor Foundry + Cargo ≥ 1.85).Test plan — functional paths
/v1/arena/buyslog_indexmatches receipt log indexblock_timestampnullnull/omitted per spec; frontend tolerateslimit/offsetBuylogs same tx (if testable)log_index; unique React keysbuyWithCreditems: []— no errorindexerApi.test.tsBuyItemmatches fixtureAutomated:
cd indexer && cargo clippy --all-targets -- -D warnings && cargo testcd frontend && npm run typecheck && npm test -- indexerApibash scripts/verify-wallet-profile-anvil.sh(extended) or new parity scriptTest plan — attack / abuse / misuse
BigIntthrownew_deadline/buy_indexmagnitudeslog_indexconfusion(tx_hash, log_index)round-trip in integration testblock_timestampspoofinglimitlimitANVIL_PORT/INDEXER_PORT; assertchainId == 31337tx_hash, differentlog_index→ distinct keysVerification criteria (sign-off)
curl -s http://127.0.0.1:<indexer>/v1/arena/buys?limit=1 | jq '.items[0] | {new_deadline,buy_index,log_index,block_timestamp}'— populated after buy.psql:SELECT new_deadline::text, buy_index::text, log_index, EXTRACT(EPOCH FROM block_timestamp)::text FROM idx_arena_buy ORDER BY block_number DESC LIMIT 1matches API.0).cargo test+npm run typecheckgreen in touched packages.Related issues
actual_seconds_added(prerequisite)marked as related to #282
marked as related to #258
marked as related to #254
mentioned in commit
11f72eb042mentioned in commit
b1b4f2a4cfmentioned in merge request !410
mentioned in commit
6d520e7a98Verification — all acceptance criteria PASS (no new MR)
Issue #283 is already implemented on
mainvia merge commitsb1b4f2aand11f72eb(MRcursor/arena-buys-parity-283-7d54). This pass re-verified the merged work; no additional code changes were required.Acceptance checklist
GET /v1/arena/buysincludesnew_deadline,buy_index,log_index,block_timestampindexer/src/api_arena.rsSELECT + JSON;integration_stage2.rs::api_arena_buys_actual_seconds_added_smokeidx_arena_buyfortx_hash/log_indexbash scripts/verify-wallet-profile-anvil.shparity assertions (see log below)fetchArenaBuysAsBuyItemssurfaces all four onBuyItemcd frontend && npm test -- indexerApi(22 tests)tx_hash+log_indexkeysmapArenaBuyToBuyItempasses throughlog_index; consumers use${tx_hash}-${log_index}keysnew_deadlinewhen presentArenaBuyModals.tsx→UnixTimestampDisplaypath (existing UI; mapper no longer stubs"0")bash scripts/verify-wallet-profile-anvil.shINV-INDEXER-283-ARENA-BUYS-PARITY,docs/indexer/design.md,docs/testing/ci.md, guardrails skillCommands run (2026-06-03)
Manual QA (browser)
Buy detail modal New deadline display — SKIP (not run in this Cloud Agent session; covered by mapper +
ArenaBuyModals.tsxwiring; recommend spot-check on/arenaduring #258 QA).Blockers
None.
Closing as complete — implementation merged and automated verification green.
mentioned in issue #258
mentioned in issue #364