Arena buys API: expose actual_seconds_added + verify-wallet-profile-anvil.sh (#258 QA) #282
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#282
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 from #258 (wallet profile modal) QA: the
/arena“Just +Xs by …” timer-extension chip (data-testid="arena-simple-last-extension") never renders becauseGET /v1/arena/buysomits fields the DB already stores. A hermetic Anvil verify script is also missing (peer scripts exist for cred buy, podium live, donate pools, etc.).Current codebase
Indexer — persisted but not exposed
idx_arena_buy(migrationindexer/migrations/20240601000000_arena_v2.up.sql) storesactual_seconds_added,new_deadline,buy_index,block_timestamp,log_index, etc., populated fromTimeArenaBuylogs inindexer/src/decoder.rs/indexer/src/persist.rs.GET /v1/arena/buysinindexer/src/api_arena.rs(arena_buys) SELECTs onlybuyer,charm_wad,doub_paid,block_number,tx_hash,timer_hard_reset,paid_with_cred—actual_seconds_addedis dropped at the HTTP boundary.actual_seconds_addedfrom SQL (indexer/src/arena_wallet_stats.rs)./v1/arena/buys?limit=2(indexer/tests/integration_stage2.rs); no JSON field contract test.Frontend — expects field, mapper strips it
frontend/src/lib/indexerApi.ts:BuyItem.actual_seconds_addedis optional;ArenaBuyItemtype has no such field.fetchArenaBuysAsBuyItems→mapArenaBuyToBuyItemzeroesnew_deadline,buy_index, and never mapsactual_seconds_addedeven if the API were fixed.actual_seconds_added/timer_hard_reset):frontend/src/pages/arena/ArenaSimplePage.tsx—lastExtensionchip (requiressaleActive+secs > 0or hard reset)frontend/src/pages/arena/ArenaLiveBuysActivitySection.tsx— row tonefrontend/src/pages/arena/TimerHeroLiveBuys.tsx,frontend/src/lib/timeArenaUx.ts,frontend/src/lib/timeArenaBuyPreview.tsactual_seconds_added: "120"(LiveBuyRow.test.tsx,ArenaLiveBuysActivitySection.test.tsx).Verify scripts — pattern, no wallet-profile helper
scripts/verify-cred-buy-anvil.sh,scripts/verify-podium-live-anvil.sh,scripts/verify-donate-pools-anvil.sh, etc.yieldomega_anvil_deploy_dev, onchain action,curl/jqassertions, exit non-zero on failure.scripts/verify-wallet-profile-anvil.shtoday;INV-FRONTEND-258-WALLET-PROFILEpoints only at frontend unit tests (docs/testing/invariants-and-business-logic.md).Why this is needed
/arenashould show the live “Just +Ns by …” chip when a buy extends the Last Buy timer — currently impossible with indexer JSON as shipped.bash scripts/verify-wallet-profile-anvil.shgives agents and CI a repeatable hook for wallet-stats + buy-row + (optional) profile-modal prerequisites without ad-hoccast/curl.Constraints & guardrails
actual_seconds_addedin logs/DB must match chain semantics; indexer only projects decoded values — do not recompute caps client-side for API truth.scripts/verify-wallet-profile-anvil.sh./v1/timecurve/*— arena routes only (#266).ANVIL_PORT/INDEXER_PORT(seeverify-podium-live-anvil.sh) so local dev stacks on 8545/3100 are not killed unless documented; gitleaks-safe (unlocked Anvil accounts, no committed keys).actual_seconds_added(and wire frontend mapper/types). Optional follow-up (separate issue if needed): exposenew_deadline,buy_index,block_timestamp,log_indexon the same endpoint for fullBuyItemparity — do not block #258 QA on full parity unless cheap.Recommended solution direction
A. Indexer — extend
GET /v1/arena/buysactual_seconds_added::textto the SQL SELECT inarena_buys.actual_seconds_addedas a decimal string (same pattern ascharm_wad).integration_stage2(or dedicated test) with a persisted buy fixture asserting the field is present and matches ingested value.docs/indexer/design.mdarena HTTP section; add invariant rowINV-INDEXER-*-ARENA-BUYS-SECONDS(or extendINV-INDEXER-254-ARENA-SCHEMA) indocs/testing/invariants-and-business-logic.md.B. Frontend — pass-through
actual_seconds_added?: stringtoArenaBuyItem.mapArenaBuyToBuyItem(and any directfetchArenaBuysconsumers).indexerApi.test.tswith fixture JSON.C.
scripts/verify-wallet-profile-anvil.shMirror existing verify scripts:
YIELDOMEGA_DEPLOY_NO_COOLDOWN=1+yieldomega_anvil_deploy_dev.buy(uint256)onTimeArena.curlGET /v1/arena/buys?limit=1→actual_seconds_addedpresent and> 0(ortimer_hard_resettrue).curlGET /v1/arena/wallet/{buyer}/stats→ HTTP 200,buy_count >= 1.topUpPodiumPools+ assert donate-pools recent donor (unblocks #258 donate-row profile click QA)./arena//arena/protocolwithVITE_INDEXER_URLand click profile buttons (Playwright not required in-script unless added later).INV-FRONTEND-258-WALLET-PROFILE, arena-views § wallet-profile,.cursor/skills/yieldomega-guardrails/SKILL.md,docs/testing/ci.mdif CI job added.Relevant files
indexer/src/api_arena.rsindexer/tests/integration_stage2.rsfrontend/src/lib/indexerApi.tsfrontend/src/pages/arena/ArenaSimplePage.tsxscripts/verify-wallet-profile-anvil.sh(create)docs/indexer/design.md,docs/testing/invariants-and-business-logic.md,docs/testing/ci.mdscripts/verify-cred-buy-anvil.sh,scripts/lib/anvil_deploy_dev.shAcceptance criteria
GET /v1/arena/buysJSON items includeactual_seconds_added(string integer) for ingested DOUB/CRED buys.actual_seconds_addedin API matches the value stored inidx_arena_buyfor thattx_hash/log_index.fetchArenaBuysAsBuyItemssurfacesactual_seconds_addedon eachBuyItem./arenarendersarena-simple-last-extensionwhen the latest buy hasactual_seconds_added > 0ortimer_hard_reset.bash scripts/verify-wallet-profile-anvil.shexits 0 on a clean host (documentsPATHfor Foundry + Cargo ≥ 1.85).GET /v1/arena/wallet/{buyer}/statsreturnsbuy_count >= 1after the buy.Test plan — functional paths
/v1/arena/buysactual_seconds_added> 0timer_hard_reset(if feasible on Anvil config)timer_hard_reset: true; chip uses reset stylingbuyWithCreditems: []— no errorlimit/offsetWalletProfileModal(#258)Automated:
cd indexer && cargo test(new/extended integration assertion)cd frontend && npm test -- indexerApi(if added)bash scripts/verify-wallet-profile-anvil.shTest plan — attack / abuse / misuse
BigIntthrowBigIntin chip path — test with max realistic seconds (< timer cap)actual_seconds_addedin DB/v1/arena/wallet/{address}/stats0x); verify script uses lowercase checksummed buyer only/v1/arena/buyslimitlimitclamp 1–200; verify script uses small limitRPC_URL/INDEXER_PORTenv; fail ifchainId≠ 31337jqin scriptevalVerification criteria (sign-off)
curl -s http://127.0.0.1:<port>/v1/arena/buys?limit=1 | jq '.items[0].actual_seconds_added'— non-null after buy.psqlspot-check:SELECT actual_seconds_added FROM idx_arena_buy ORDER BY block_number DESC LIMIT 1matches API./arenashows timer-extension chip; profile button on chip opens modal with seven sections.bash scripts/verify-wallet-profile-anvil.sh— exit 0, logs include buyer address and statsbuy_count.cargo test+npm run typecheckin touched packages green.Related issues
marked as related to #258
mentioned in commit b39b47dbac116e49949ee0e17b96823471c491e3
mentioned in commit e0d9b4c04d2438ec3801e0e48526e7ad8079d976
test
Implementation complete (branch
cursor/arena-buys-seconds-282-f1de)mainis protected in this project, so changes are oncursor/arena-buys-seconds-282-f1de(merge request pending). Local agentmainincludes the merge commit for continuity.What changed
GET /v1/arena/buysnow returnsactual_seconds_added(decimal string fromidx_arena_buy, same pattern ascharm_wad).ArenaBuyItem+mapArenaBuyToBuyItempassactual_seconds_addedthrough toBuyItemso/arenacan renderarena-simple-last-extensionand live-buy tone styling.bash scripts/verify-wallet-profile-anvil.sh(defaults: Anvil 8548, indexer 3103, Postgres 5433): DeployDev → DOUB buy → API/DB seconds parity →GET /v1/arena/wallet/{buyer}/stats(buy_count >= 1) → optionaltopUpPodiumPoolsdonor row.INV-INDEXER-282-ARENA-BUYS-SECONDS; updatedINV-FRONTEND-258-WALLET-PROFILE; cross-links indocs/indexer/design.md,docs/frontend/arena-views.md,AGENTS.md,docs/testing/ci.md, guardrails skill,skills/play-time-arena-doub/SKILL.md.Automated verification (agent run)
cd indexer && cargo clippy --all-targets -- -D warningsYIELDOMEGA_PG_TEST_URL=postgres://yieldomega:password@127.0.0.1:5433/yieldomega_indexer_test cargo test --test integration_stage2cd frontend && npm test -- indexerApi && npm run typecheckbash scripts/verify-wallet-profile-anvil.sh→actual_seconds_added=120,buy_count=1QA checklist (please verify after merge)
cursor/arena-buys-seconds-282-f1de→mainbash scripts/verify-wallet-profile-anvil.shon a clean host (Foundry onPATH, Cargo ≥ 1.85, Postgres on:5433)curl -s http://127.0.0.1:<indexer>/v1/arena/buys?limit=1 | jq '.items[0].actual_seconds_added'— non-null, matchespsqlonidx_arena_buy/arenawith sale active showsarena-simple-last-extensionwhen latest buy hasactual_seconds_added > 0ortimer_hard_resetFollow-up (optional, out of scope)
Expose remaining
BuyItemfields on/v1/arena/buys(new_deadline,buy_index,block_timestamp,log_index) if full parity is needed — not required for #258 QA.Requesting verification from the QA agent team when the MR is merged.
mentioned in merge request !406
Merge request: https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/36 (!406) — source
cursor/arena-buys-seconds-282-f1de→main.mentioned in issue #283
marked as related to #283
mentioned in commit
1b207c5ac8mentioned in commit
32ed77a179mentioned in merge request !410
mentioned in merge request !414
mentioned in issue #258
mentioned in issue #364