Fix forbidden sale copy and wire WarBow wallet profile modal #482

Merged
PlasticDigits merged 4 commits from verify/issue-318-sale-copy-warbow-profile into main 2026-06-14 05:31:32 +00:00
PlasticDigits commented 2026-06-14 02:56:58 +00:00 (Migrated from gitlab.com)

Summary

Verification for GitLab #318 found the acceptance work was not yet on main. This MR:

  • Replaces forbidden pre-launch sale copy on the / play console with preLaunchBuyGateMessage() (arena framing).
  • Threads onOpenWalletProfile through ArenaWarbowHeroPanel rival rows (PlayerIdentity → profile modal, not explorer).
  • Updates TimeArena-facing revert/session strings and adds static/unit regression guards.

Test plan

Acceptance item Command / output Result
No user-visible "sale" on / play console cd frontend && npm test (arenaSimplePhase.test.ts, arenaCommandConsoleStatic.test.ts) PASS
WarBow rival rows open wallet profile modal Static: arenaCommandConsoleStatic.test.ts wires onOpenProfile={onOpenWalletProfile}; Playwright on preview: SKIP targets not indexed (lane visible, no rivals without stack buys) PASS (wiring) / SKIP (live targets)
Static/unit test guards forbidden copy preLaunchBuyGateMessage + revertMessage.test.ts TimeArena mappings PASS
npm run typecheck cd frontend && npm run typecheck PASS
npm run lint cd frontend && npm run lint PASS (0 errors)
npm test cd frontend && npm test — 635 tests PASS
E2E smoke / bash scripts/e2e-anvil.sh — 6/6 anvil arena specs PASS
Manual: no forbidden sale on live console Playwright preview http://127.0.0.1:4173/ body scan PASS
Native Postgres (indexer path) bash scripts/verify-cloud-postgres.sh PASS

Follow-ups

  • Add Playwright coverage for WarBow rival profile click when indexed targets exist on Anvil (currently SKIP without buys + indexer ingest).

Note

Low Risk
Frontend copy, event handling, and test-only guards; no contracts, auth, or payment logic changes.

Overview
Delivers GitLab #318 on the / play console: user-visible “sale” framing is replaced with arena wording, WarBow rival identity opens the wallet profile modal, and static/unit tests lock the behavior in.

Pre-launch and errors: ArenaSimplePage shows preLaunchBuyGateMessage() instead of inline phaseNarrative during saleStartPending. friendlyRevertMessage and buy preflight copy use arena phrasing (e.g. “The arena timer has expired”, “wait for arena state”). Timer-expired strings move from “round timer” to arena timer.

WarBow UX: AddressInline profile buttons call event.stopPropagation() so parent row handlers do not steal the click. WarBow steal target rows change from <button> to <div role="option"> so nested PlayerIdentity / profile actions work while row selection still ignores clicks inside .address-inline__profile-btn.

Regression guards: Tests in arenaSimplePhase, arenaPlaySurfaceCopy, arenaCommandConsoleStatic, and revertMessage assert forbidden “sale” copy stays off the play surface and onOpenWalletProfile is wired through ArenaWarbowHeroPanel.

Reviewed by Cursor Bugbot for commit f398cab132. Bugbot is set up for automated code reviews on this repo. Configure here.

## Summary Verification for GitLab #318 found the acceptance work was not yet on `main`. This MR: - Replaces forbidden pre-launch **sale** copy on the `/` play console with `preLaunchBuyGateMessage()` (arena framing). - Threads `onOpenWalletProfile` through `ArenaWarbowHeroPanel` rival rows (`PlayerIdentity` → profile modal, not explorer). - Updates TimeArena-facing revert/session strings and adds static/unit regression guards. ## Test plan | Acceptance item | Command / output | Result | |-----------------|------------------|--------| | No user-visible "sale" on `/` play console | `cd frontend && npm test` (`arenaSimplePhase.test.ts`, `arenaCommandConsoleStatic.test.ts`) | PASS | | WarBow rival rows open wallet profile modal | Static: `arenaCommandConsoleStatic.test.ts` wires `onOpenProfile={onOpenWalletProfile}`; Playwright on preview: SKIP targets not indexed (lane visible, no rivals without stack buys) | PASS (wiring) / SKIP (live targets) | | Static/unit test guards forbidden copy | `preLaunchBuyGateMessage` + `revertMessage.test.ts` TimeArena mappings | PASS | | `npm run typecheck` | `cd frontend && npm run typecheck` | PASS | | `npm run lint` | `cd frontend && npm run lint` | PASS (0 errors) | | `npm test` | `cd frontend && npm test` — 635 tests | PASS | | E2E smoke `/` | `bash scripts/e2e-anvil.sh` — 6/6 anvil arena specs | PASS | | Manual: no forbidden sale on live console | Playwright preview `http://127.0.0.1:4173/` body scan | PASS | | Native Postgres (indexer path) | `bash scripts/verify-cloud-postgres.sh` | PASS | ## Follow-ups - Add Playwright coverage for WarBow rival profile click when indexed targets exist on Anvil (currently SKIP without buys + indexer ingest). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Frontend copy, event handling, and test-only guards; no contracts, auth, or payment logic changes. > > **Overview** > Delivers GitLab **#318** on the `/` play console: user-visible **“sale”** framing is replaced with **arena** wording, WarBow rival identity opens the **wallet profile modal**, and static/unit tests lock the behavior in. > > **Pre-launch and errors:** `ArenaSimplePage` shows `preLaunchBuyGateMessage()` instead of inline `phaseNarrative` during `saleStartPending`. `friendlyRevertMessage` and buy preflight copy use arena phrasing (e.g. “The arena timer has expired”, “wait for arena state”). Timer-expired strings move from “round timer” to **arena timer**. > > **WarBow UX:** `AddressInline` profile buttons call `event.stopPropagation()` so parent row handlers do not steal the click. WarBow steal target rows change from `<button>` to `<div role="option">` so nested `PlayerIdentity` / profile actions work while row selection still ignores clicks inside `.address-inline__profile-btn`. > > **Regression guards:** Tests in `arenaSimplePhase`, `arenaPlaySurfaceCopy`, `arenaCommandConsoleStatic`, and `revertMessage` assert forbidden “sale” copy stays off the play surface and `onOpenWalletProfile` is wired through `ArenaWarbowHeroPanel`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f398cab1323fa99f06885098f6ac25a2c0140481. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
PlasticDigits commented 2026-06-14 02:57:05 +00:00 (Migrated from gitlab.com)

mentioned in issue #318

mentioned in issue #318
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:57:08 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:57:14 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-14 02:58:42 +00:00 (Migrated from gitlab.com)

Security review — MR !482

Commit reviewed: 954f5ea3e29ce7c311098d9696fc6b39c1ef867d

Scope: Frontend-only diff — forbidden “sale” copy replaced with arena framing (preLaunchBuyGateMessage, revertMessage mappings, session error string); WarBow rival rows wired to existing onOpenWalletProfile → WalletProfileModal; AddressInline profile click adds stopPropagation; WarBow target rows changed from nested <button> to <div role="option"> with keyboard handlers.

Method: Traced attacker-controlled inputs (indexer WarBow targets, manual steal-victim input, profile callback) through PlayerIdentity → AddressInline (viem isAddress gate) → TimeArenaPage state → WalletProfileModal → useWalletStats / useWalletProfileBalances (address length/prefix checks, parameterized indexer SQL, parseHexAddress for RPC). No contract, indexer, auth, or dependency changes in this diff.

Outcome: FINDINGS: 0 medium+

Inline threads: none (no medium+ issues to anchor on the diff).

Security review: no medium+ findings on this diff.

## Security review — MR !482 **Commit reviewed:** `954f5ea3e29ce7c311098d9696fc6b39c1ef867d` **Scope:** Frontend-only diff — forbidden “sale” copy replaced with arena framing (`preLaunchBuyGateMessage`, `revertMessage` mappings, session error string); WarBow rival rows wired to existing `onOpenWalletProfile` → `WalletProfileModal`; `AddressInline` profile click adds `stopPropagation`; WarBow target rows changed from nested `<button>` to `<div role="option">` with keyboard handlers. **Method:** Traced attacker-controlled inputs (indexer WarBow targets, manual steal-victim input, profile callback) through `PlayerIdentity` → `AddressInline` (`viem` `isAddress` gate) → `TimeArenaPage` state → `WalletProfileModal` → `useWalletStats` / `useWalletProfileBalances` (address length/prefix checks, parameterized indexer SQL, `parseHexAddress` for RPC). No contract, indexer, auth, or dependency changes in this diff. **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** none (no medium+ issues to anchor on the diff). Security review: no medium+ findings on this diff.
PlasticDigits commented 2026-06-14 05:12:14 +00:00 (Migrated from gitlab.com)

added 89 commits

  • 954f5ea3...e8448334 - 86 commits from branch main
  • 5bc5822a - Merge main into verify/issue-318-sale-copy-warbow-profile
  • d8840738 - fix(frontend): type WarBow target list refs as div elements
  • f398cab1 - test(frontend): align #318 copy guards after main merge

Compare with previous version

added 89 commits <ul><li>954f5ea3...e8448334 - 86 commits from branch <code>main</code></li><li>5bc5822a - Merge main into verify/issue-318-sale-copy-warbow-profile</li><li>d8840738 - fix(frontend): type WarBow target list refs as div elements</li><li>f398cab1 - test(frontend): align #318 copy guards after main merge</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/112/diffs?diff_id=1850590364&start_sha=954f5ea3e29ce7c311098d9696fc6b39c1ef867d)
PlasticDigits commented 2026-06-14 05:12:17 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main:

  • ArenaSimplePage — kept preLaunchBuyGateMessage() for the pre-launch buy gate (#318).
  • revertMessage — merged arena timer/not-started copy with main's arena-phase and Kumbaya buy-router strings (no forbidden sale wording).
  • useArenaSaleSession — took main's arenaSaleSessionBuyPreflight extraction; updated preflight to say "arena state".
  • ArenaWarbowHeroPanel — combined profile-modal wiring with main's roving keyboard focus and profile-click stopPropagation.
  • Adjusted copy-guard tests for the merged surface.

Sanity: npm run typecheck, npm run lint, and targeted Vitest (#318 / WarBow / revert copy) — PASS.

Resolved merge conflicts with `main`: - **ArenaSimplePage** — kept `preLaunchBuyGateMessage()` for the pre-launch buy gate (#318). - **revertMessage** — merged arena timer/not-started copy with main's arena-phase and Kumbaya buy-router strings (no forbidden sale wording). - **useArenaSaleSession** — took main's `arenaSaleSessionBuyPreflight` extraction; updated preflight to say "arena state". - **ArenaWarbowHeroPanel** — combined profile-modal wiring with main's roving keyboard focus and profile-click `stopPropagation`. - Adjusted copy-guard tests for the merged surface. Sanity: `npm run typecheck`, `npm run lint`, and targeted Vitest (#318 / WarBow / revert copy) — PASS.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 05:12:33 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-14 05:14:40 +00:00 (Migrated from gitlab.com)

Security review — MR !482

Commit reviewed: f398cab1323fa99f06885098f6ac25a2c0140481

Scope: Frontend-only diff — forbidden “sale” copy replaced with arena framing (preLaunchBuyGateMessage, revertMessage mappings, arenaSaleSessionBuyPreflight string); WarBow rival rows wired to existing onOpenWalletProfile → WalletProfileModal; AddressInline profile click adds event.stopPropagation(); WarBow target rows changed from nested <button> to <div role="option"> with roving keyboard focus and targetIsInsideAddressAction click guard. Test-only copy guards. No contract, indexer, auth, or dependency changes in the MR diff.

Method: Traced attacker-controlled inputs (indexer WarBow targets via buildWarbowTargets + isAddress, manual steal-victim input, profile callback address) through PlayerIdentity → AddressInline (viem isAddress gate, React text rendering) → TimeArenaPage state → WalletProfileModal → useWalletStats / useWalletProfileBalances (0x+42-char enablement, parseHexAddress for RPC, parameterized indexer path). Compared against prior review on 954f5ea after main merge (5bc5822a, d8840738, f398cab).

Outcome: FINDINGS: 0 medium+

Inline threads: none (no medium+ issues to anchor on the diff).

Security review: no medium+ findings on this diff.

## Security review — MR !482 **Commit reviewed:** `f398cab1323fa99f06885098f6ac25a2c0140481` **Scope:** Frontend-only diff — forbidden “sale” copy replaced with arena framing (`preLaunchBuyGateMessage`, `revertMessage` mappings, `arenaSaleSessionBuyPreflight` string); WarBow rival rows wired to existing `onOpenWalletProfile` → `WalletProfileModal`; `AddressInline` profile click adds `event.stopPropagation()`; WarBow target rows changed from nested `<button>` to `<div role="option">` with roving keyboard focus and `targetIsInsideAddressAction` click guard. Test-only copy guards. No contract, indexer, auth, or dependency changes in the MR diff. **Method:** Traced attacker-controlled inputs (indexer WarBow targets via `buildWarbowTargets` + `isAddress`, manual steal-victim input, profile callback address) through `PlayerIdentity` → `AddressInline` (`viem` `isAddress` gate, React text rendering) → `TimeArenaPage` state → `WalletProfileModal` → `useWalletStats` / `useWalletProfileBalances` (0x+42-char enablement, `parseHexAddress` for RPC, parameterized indexer path). Compared against prior review on `954f5ea` after main merge (`5bc5822a`, `d8840738`, `f398cab`). **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** none (no medium+ issues to anchor on the diff). Security review: no medium+ findings on this diff.
PlasticDigits commented 2026-06-14 05:31:32 +00:00 (Migrated from gitlab.com)

mentioned in commit e4f06c1524

mentioned in commit e4f06c1524b9550d6a5abaa2ea8c4d419e87d907
PlasticDigits (Migrated from gitlab.com) merged commit e4f06c1524 into main 2026-06-14 05:31:32 +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!482
No description provided.