Expose actual_seconds_added on GET /v1/arena/buys (#282) #406

Merged
PlasticDigits merged 1 commit from cursor/arena-buys-seconds-282-f1de into main 2026-06-03 12:18:06 +00:00
PlasticDigits commented 2026-06-03 11:34:02 +00:00 (Migrated from gitlab.com)

Summary

Expose actual_seconds_added on GET /v1/arena/buys (already persisted in idx_arena_buy), wire the field through fetchArenaBuysAsBuyItems, add integration coverage and scripts/verify-wallet-profile-anvil.sh for #258 / #282 QA.

Rebased onto main (resolved doc/guardrail conflicts with #278 Last Buy epoch and #280 Arena CSS naming).

Verification checklist

Item Command Result
Indexer integration (incl. api_arena_buys_actual_seconds_added_smoke) cd indexer && cargo test --test integration_stage2 PASS
Frontend indexer API mapping cd frontend && npm test -- indexerApi PASS
Hermetic Anvil + indexer smoke (#282 / #258) bash scripts/verify-wallet-profile-anvil.sh PASS
Merge conflicts with main Rebase cursor/arena-buys-seconds-282-f1de onto origin/main PASS

Changes

  • Indexer: actual_seconds_added::text in arena_buys SQL/JSON; integration_stage2 smoke asserts API ↔ DB parity.
  • Frontend: ArenaBuyItem.actual_seconds_added + mapArenaBuyToBuyItem; indexerApi.test.ts fixture.
  • Script: scripts/verify-wallet-profile-anvil.sh — isolated Anvil (8548) + Postgres (5433) + indexer (3103); DOUB buy, /v1/arena/buys, wallet stats, optional donate-pools donor summary.
  • Docs: INV-INDEXER-282-ARENA-BUYS-SECONDS, wallet-profile cross-links, docs/indexer/design.md, docs/testing/ci.md, guardrails/skills.

Closes #282

## Summary Expose `actual_seconds_added` on **`GET /v1/arena/buys`** (already persisted in `idx_arena_buy`), wire the field through **`fetchArenaBuysAsBuyItems`**, add integration coverage and **`scripts/verify-wallet-profile-anvil.sh`** for [#258](https://gitlab.com/PlasticDigits/yieldomega/-/issues/258) / [#282](https://gitlab.com/PlasticDigits/yieldomega/-/issues/282) QA. Rebased onto `main` (resolved doc/guardrail conflicts with #278 Last Buy epoch and #280 Arena CSS naming). ## Verification checklist | Item | Command | Result | |------|---------|--------| | Indexer integration (incl. `api_arena_buys_actual_seconds_added_smoke`) | `cd indexer && cargo test --test integration_stage2` | PASS | | Frontend indexer API mapping | `cd frontend && npm test -- indexerApi` | PASS | | Hermetic Anvil + indexer smoke (#282 / #258) | `bash scripts/verify-wallet-profile-anvil.sh` | PASS | | Merge conflicts with `main` | Rebase `cursor/arena-buys-seconds-282-f1de` onto `origin/main` | PASS | ## Changes - **Indexer:** `actual_seconds_added::text` in `arena_buys` SQL/JSON; `integration_stage2` smoke asserts API ↔ DB parity. - **Frontend:** `ArenaBuyItem.actual_seconds_added` + `mapArenaBuyToBuyItem`; `indexerApi.test.ts` fixture. - **Script:** `scripts/verify-wallet-profile-anvil.sh` — isolated Anvil (8548) + Postgres (5433) + indexer (3103); DOUB buy, `/v1/arena/buys`, wallet stats, optional donate-pools donor summary. - **Docs:** `INV-INDEXER-282-ARENA-BUYS-SECONDS`, wallet-profile cross-links, `docs/indexer/design.md`, `docs/testing/ci.md`, guardrails/skills. Closes #282
PlasticDigits commented 2026-06-03 11:34:08 +00:00 (Migrated from gitlab.com)

mentioned in issue #282

mentioned in issue #282
ghost1 commented 2026-06-03 11:36:04 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: e0d9b4c04d2438ec3801e0e48526e7ad8079d976
Scope: Expose actual_seconds_added on GET /v1/arena/buys (indexer api_arena.rs), frontend indexerApi mapping/types, integration smoke + scripts/verify-wallet-profile-anvil.sh, docs/guardrails only.

Outcome: FINDINGS: 0 (no medium, high, or critical issues on this diff)

What was reviewed

  • Indexer: Added actual_seconds_added::text to the existing parameterized idx_arena_buy list query (LIMIT/OFFSET bound as $1/$2). Value is indexer-sourced from decoded ArenaBuy logs (already persisted in idx_arena_buy); no new request parameters or dynamic SQL.
  • Frontend: Optional string field mapped through existing parseBigInt / formatLocaleInteger paths; CSS class selection uses BigInt() in try/catch. No dangerouslySetInnerHTML or HTML injection surface introduced.
  • Auth / disclosure: GET /v1/arena/buys remains a public read surface (unchanged). actual_seconds_added is on-chain event data already stored and used server-side (e.g. wallet stats). Exposing it on the buys list does not grant new write access or bypass wallet-scoped endpoints.
  • Verify script: verify-wallet-profile-anvil.sh interpolates BUY_TX into local psql queries; BUY_TX is produced by local cast send on Anvil (dev-only smoke). Not a production attack path.

Prior threads

No prior security-review notes on this MR; nothing to re-report.

Inline comments: none (no qualifying findings).

<!-- cursor-security-review --> ## Security review **Commit reviewed:** `e0d9b4c04d2438ec3801e0e48526e7ad8079d976` **Scope:** Expose `actual_seconds_added` on `GET /v1/arena/buys` (indexer `api_arena.rs`), frontend `indexerApi` mapping/types, integration smoke + `scripts/verify-wallet-profile-anvil.sh`, docs/guardrails only. **Outcome:** `FINDINGS: 0` (no medium, high, or critical issues on this diff) ### What was reviewed - **Indexer:** Added `actual_seconds_added::text` to the existing parameterized `idx_arena_buy` list query (`LIMIT`/`OFFSET` bound as `$1`/`$2`). Value is indexer-sourced from decoded `ArenaBuy` logs (already persisted in `idx_arena_buy`); no new request parameters or dynamic SQL. - **Frontend:** Optional string field mapped through existing `parseBigInt` / `formatLocaleInteger` paths; CSS class selection uses `BigInt()` in try/catch. No `dangerouslySetInnerHTML` or HTML injection surface introduced. - **Auth / disclosure:** `GET /v1/arena/buys` remains a public read surface (unchanged). `actual_seconds_added` is on-chain event data already stored and used server-side (e.g. wallet stats). Exposing it on the buys list does not grant new write access or bypass wallet-scoped endpoints. - **Verify script:** `verify-wallet-profile-anvil.sh` interpolates `BUY_TX` into local `psql` queries; `BUY_TX` is produced by local `cast send` on Anvil (dev-only smoke). Not a production attack path. ### Prior threads No prior security-review notes on this MR; nothing to re-report. **Inline comments:** none (no qualifying findings).
ghost1 commented 2026-06-03 12:05:49 +00:00 (Migrated from gitlab.com)

added 8 commits

  • e0d9b4c0...5a4177b3 - 7 commits from branch main
  • 1b207c5a - Expose actual_seconds_added on GET /v1/arena/buys (#282)

Compare with previous version

added 8 commits <ul><li>e0d9b4c0...5a4177b3 - 7 commits from branch <code>main</code></li><li>1b207c5a - Expose actual_seconds_added on GET /v1/arena/buys (#282)</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/36/diffs?diff_id=1832235889&start_sha=e0d9b4c04d2438ec3801e0e48526e7ad8079d976)
PlasticDigits commented 2026-06-03 12:06:15 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-03 12:16:33 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: 1b207c5ac8495ceb8b9430dfd357042a731c780b
Scope: MR !406 full diff vs main — #282 actual_seconds_added on GET /v1/arena/buys + frontend mapping; rebased includes #278 Last Buy epoch ingest, #279 Anvil E2E trap/CL8Y extract, #280 Arena CSS rename, #281 dev-wallet seed minter alignment (DeployDev, anvil_deployer_key.sh, seed-evm-dev-wallets-anvil.sh), verify scripts/docs.

Outcome: FINDINGS: 0 (no medium, high, or critical issues on this diff)

What was reviewed

  • Indexer (#282): actual_seconds_added::text added to the existing parameterized idx_arena_buy list query ($1/$2 limit/offset). Data is chain-sourced and already persisted; no new user-controlled SQL fragments.
  • Indexer (#278): LastBuyEpochStarted → idx_arena_last_buy_epoch_started; idx_arena_buy.last_buy_epoch from ordered in-block head (apply_epoch_started after epoch log, before subsequent Buy in same tx). Wallet stats use COUNT(DISTINCT last_buy_epoch) with bound $1 address — no injection path.
  • Frontend (#282): Field mapped through existing parseBigInt / formatLocaleInteger / React text nodes; no dangerouslySetInnerHTML. Display values are numeric strings from indexer/chain.
  • Auth / disclosure: Arena read routes remain intentionally public. actual_seconds_added is already public in Buy events and DB; exposing it on /v1/arena/buys does not grant writes or bypass wallet-scoped validation (invalid_address on malformed paths unchanged).
  • Dev deploy (#281): YIELDOMEGA_SEED_MINTER_ADDRESS grants MINTER_ROLE only in DeployDev.s.sol (dev chain). Seed script enforces loopback RPC + chain id allowlist (31337/6342/6343) and _assert_minter_role before mint — local QA only, not production deploy path.
  • Scripts: verify-wallet-profile-anvil.sh interpolates BUY_TX into local psql (hash from local cast send on isolated Anvil). anvil_deployer_key.sh documents Foundry Anvil account #0 default PK for deploy alignment — dev-only, not production secrets.
  • #279 trap fix: Guarded PID kill prevents accidental kill 0 — reliability hardening, not a new exposure.

Prior threads

Prior review on e0d9b4c reported FINDINGS: 0 for the narrower #282 slice. Re-reviewed expanded rebase content above; no prior medium+ findings to re-report — still none on current HEAD.

Inline comments: none (no qualifying findings).

<!-- cursor-security-review --> ## Security review **Commit reviewed:** `1b207c5ac8495ceb8b9430dfd357042a731c780b` **Scope:** MR !406 full diff vs `main` — #282 `actual_seconds_added` on `GET /v1/arena/buys` + frontend mapping; rebased includes #278 Last Buy epoch ingest, #279 Anvil E2E trap/CL8Y extract, #280 Arena CSS rename, #281 dev-wallet seed minter alignment (`DeployDev`, `anvil_deployer_key.sh`, `seed-evm-dev-wallets-anvil.sh`), verify scripts/docs. **Outcome:** `FINDINGS: 0` (no medium, high, or critical issues on this diff) ### What was reviewed - **Indexer (#282):** `actual_seconds_added::text` added to the existing parameterized `idx_arena_buy` list query (`$1`/`$2` limit/offset). Data is chain-sourced and already persisted; no new user-controlled SQL fragments. - **Indexer (#278):** `LastBuyEpochStarted` → `idx_arena_last_buy_epoch_started`; `idx_arena_buy.last_buy_epoch` from ordered in-block head (`apply_epoch_started` after epoch log, before subsequent `Buy` in same tx). Wallet stats use `COUNT(DISTINCT last_buy_epoch)` with bound `$1` address — no injection path. - **Frontend (#282):** Field mapped through existing `parseBigInt` / `formatLocaleInteger` / React text nodes; no `dangerouslySetInnerHTML`. Display values are numeric strings from indexer/chain. - **Auth / disclosure:** Arena read routes remain intentionally public. `actual_seconds_added` is already public in `Buy` events and DB; exposing it on `/v1/arena/buys` does not grant writes or bypass wallet-scoped validation (`invalid_address` on malformed paths unchanged). - **Dev deploy (#281):** `YIELDOMEGA_SEED_MINTER_ADDRESS` grants `MINTER_ROLE` only in `DeployDev.s.sol` (dev chain). Seed script enforces loopback RPC + chain id allowlist (31337/6342/6343) and `_assert_minter_role` before mint — local QA only, not production deploy path. - **Scripts:** `verify-wallet-profile-anvil.sh` interpolates `BUY_TX` into local `psql` (hash from local `cast send` on isolated Anvil). `anvil_deployer_key.sh` documents Foundry Anvil account #0 default PK for deploy alignment — dev-only, not production secrets. - **#279 trap fix:** Guarded PID kill prevents accidental `kill 0` — reliability hardening, not a new exposure. ### Prior threads Prior review on `e0d9b4c` reported `FINDINGS: 0` for the narrower #282 slice. Re-reviewed expanded rebase content above; **no prior medium+ findings to re-report** — still none on current HEAD. **Inline comments:** none (no qualifying findings).
PlasticDigits commented 2026-06-03 12:18:06 +00:00 (Migrated from gitlab.com)

mentioned in commit 32ed77a179

mentioned in commit 32ed77a179ee556d7bbec945cc45976e39a64c7b
PlasticDigits (Migrated from gitlab.com) merged commit 32ed77a179 into main 2026-06-03 12:18:06 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega!406
No description provided.