Indexer: GET /v1/arena/wallet/{{address}}/stats for profile modal #255
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#255
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
Wallet stats API for participant profile modal. Parent epic: #238.
Relevant files
indexer/src/api.rsAcceptance criteria
API returns:
epochs_participated(Last Buy epochs with ≥1 buy)prizes_won[]:{ podium, epoch, rank, amount_doub }total_won_doub,total_spent_doub,buy_countxp,levelhighest_scores[]:{ podium, epoch, score, rank }for Streak, TimeBooster, WarBow, LastBuyVerification checklist
marked as related to #238
mentioned in issue #238
Implementation summary
GET /v1/arena/wallet/{address}/statsinindexer/src/api_arena.rs.Acceptance criteria
Verification checklist
Stub must be removed, required full bonus stats.
mentioned in commit
79d8ebb981mentioned in commit
502785819dImplementation complete (#255)
Removed stub zeros from
GET /v1/arena/wallet/{address}/stats. Full participant profile aggregates now live inindexer/src/arena_wallet_stats.rs(schema ≥ 2.4.0).What changed
epochs_participated,buy_count, spend stats,xp(sum),level(latest),cred_claimedprizes_won[]with 4:2:1pool_paidsplit fromidx_arena_podium_epoch;total_won_doubhighest_scores[]per podium (last_buy, time_booster, defended_streak, warbow) from indexed buys + WarBow tableslongest_defended_streak,warbow_steals/warbow_guards,referral_cred_earned,podium_win_rate,rank_distributionintegration_stage2.rs::arena_wallet_stats_two_epochs_and_bonus_fields(2 Last Buy epochs)INV-INDEXER-255-WALLET-STATS, indexer design §255, guardrails + play skill crosslinksMerged to
mainat79d8ebb.Verification checklist
cd indexer && cargo test— unit + integration (needsYIELDOMEGA_PG_TEST_URL)GET /v1/arena/wallet/0x…/statson Anvil stack returns non-stubprizes_won,highest_scores, bonus fields after buys across 2 hard-reset epochsWalletProfileModal) loads stats for a buyer with indexed historyx-schema-version: 2.4.0on responseFollow-ups (optional)
LastBuyEpochStartedfor exact epoch assignment withouttimer_hard_resetwindow inferenceRequesting verification from the QA agent team.
mentioned in issue #273
QA verification (#255) — issue left open
Verified
GET /v1/arena/wallet/{address}/statson branchissue/255-wallet-stats, merged tomainatcee483a.Bugs fixed during verification
fetch_podium_placementsrank decode — PostgreSQLCASE … ENDreturns INT4; Rust was decoding asOption<i16>, causing 500 on any wallet with podium placements. Fixed toOption<i32>.cargo testshared one Postgres URL without locking; tests deleted each other's rows. AddedPG_INTEGRATION_MUTEX+clear_arena_index_for_testbefore wallet-stats fixture.What passed
cd indexer && YIELDOMEGA_PG_TEST_URL=… cargo test— 29 unit + 3 integration (includingarena_wallet_stats_two_epochs_and_bonus_fields)epochs_participated(2),prizes_won[], spend totals,xp/level,highest_scores[](4 podiums), bonus stats (referral_cred_earned,warbow_guards,rank_distribution, …){ "error": "invalid_address" }x-schema-version: 2.4.0on live stack responseINV-INDEXER-255-WALLET-STATScrosslinks; invariants § Postgres integration mutex noteNot fully verified (follow-up for QA team)
cast sendgas estimation failed on this host after DeployDev)prizes_won/highest_scoresvia HTTP after indexer ingestWalletProfileModalloads stats for a buyer with indexed history (#258)Manual verification checklist
bash scripts/start-local-anvil-stack.sh(or QA hostmake start-qa)0x…curl -s http://127.0.0.1:3100/v1/arena/wallet/0x…/stats | jq— confirm non-zerobuy_count,epochs_participated ≥ 2, populatedhighest_scores/arena, click a buyer on live buys → profile modal shows matching stats100×curl loop; target ≪ 1s)Requesting verification from the QA agent team before close.
QA verification (#255) — issue left open
Verified
GET /v1/arena/wallet/{address}/statsonmainat7d7d3da(2026-06-02).Acceptance criteria (issue body)
epochs_participated(Last Buy epochs with ≥1 buy)epochs_participated == 2; live Anvil:epochs_participated: 2after hard-reset buyprizes_won[]{ podium, epoch, rank, amount_doub }prizes_won[0]withlast_buyrank 1 /amount_doub: 400total_won_doub,total_spent_doub,buy_countbuy_count: 4,total_spent_doub: 13000000000000000000000xp,levelxp: 5,level: 2; live:xp: 13,level: 1highest_scores[](4 podiums)highest_scores.len() == 4; live: 4 entries across epochs 0/1referral_cred_earned,warbow_guards,rank_distribution; live response includes all bonus keyscargo test arena_wallet_stats_two_epochs_and_bonus_fields(withYIELDOMEGA_PG_TEST_URL)curlloop vs local indexer: p50 ~1.4 ms, p95 ~2.9 ms (max ~28 ms)Verification checklist (comments + invariants)
INV-INDEXER-255-WALLET-STATSindexer/src/arena_wallet_stats.rs,integration_stage2.rs::arena_wallet_stats_two_epochs_and_bonus_fieldscurl …/wallet/0x…0001/stats→ HTTP 200,buy_count: 0{ "error": "invalid_address" }curl …/wallet/notanaddress/statsx-schema-versionon responsex-schema-version: 2.5.0(≥ 2.4.0)bash scripts/start-qa-local-full-stack.sh --live-sale --no-swarm --no-frontend;castDOUB buys + warp-to-deadline hard reset;curl /v1/arena/wallet/0x7099…/statsarena_wallet_stats::*)cargo test(integration)integration_stage2(PG URL:postgres://yieldomega:password@127.0.0.1:5433/yieldomega_indexer_test)WalletProfileModalSections.test.tsx(8),LiveBuyRow.test.tsx(2),ArenaLiveBuysActivitySection.test.tsx(1)/arena→ modal matches APICommands (representative)
Follow-ups (optional)
bash scripts/verify-wallet-stats-anvil.sh(mirrorverify-podium-live-anvil.sh) for repeatable live-stack QA./arena, clickAddressInlineon a live buy row, assert modal sections matchGET /v1/arena/wallet/{address}/stats(#258).LastBuyEpochStartedfor exact epoch assignment withouttimer_hard_resetwindow inference (noted in prior implementation comment).No repository changes required for #255. Leaving issue open per process.
mentioned in issue #278
mentioned in issue #282
mentioned in issue #283
QA verification (#255) — closing
Verified
GET /v1/arena/wallet/{address}/statsonmainat6d520e7(2026-06-03).Acceptance criteria (issue body)
epochs_participated(Last Buy epochs with ≥1 buy)epochs_participated == 2; live Anvil (2 hard-reset epochs):epochs_participated: 2prizes_won[]{ podium, epoch, rank, amount_doub }prizes_won[0]withlast_buyrank 1 /amount_doub: 400total_won_doub,total_spent_doub,buy_countxp,levelxp: 5,level: 2highest_scores[](4 podiums)highest_scores.len() == 4; live: 4 entriescargo test arena_wallet_stats_two_epochs_and_bonus_fieldsVerification checklist (comments + invariants)
INV-INDEXER-255-WALLET-STATSindexer/src/arena_wallet_stats.rs,integration_stage2.rs::arena_wallet_stats_two_epochs_and_bonus_fields, design §255, guardrails §9acd indexer && cargo testYIELDOMEGA_PG_TEST_URL=postgres://yieldomega:password@127.0.0.1:5433/yieldomega_indexer_test)arena_wallet_statsunit testscurl /v1/arena/wallet/0x7099…/statscurl …/wallet/0x…0001/stats→ HTTP 200,buy_count: 0{ "error": "invalid_address" }curl …/wallet/notanaddress/statsx-schema-versionon responsex-schema-version: 2.5.0(≥ 2.4.0)bash scripts/verify-wallet-profile-anvil.shbash scripts/verify-last-buy-epoch-anvil.shlast_buy_epoch+ wallet statsnpm test -- WalletProfileModal LiveBuyRow ArenaLiveBuys indexerApi— 33/33/arenaclick buyer → modal matches APIbuy_countmatchesGET /v1/arena/wallet/{address}/statsCommands (representative)
No repository changes required. All acceptance criteria pass on
main.mentioned in merge request !415
mentioned in issue #299