Add post-buy transaction result share popover (#365) #536

Merged
PlasticDigits merged 2 commits from issue-365-buy-result-share-popover into main 2026-07-07 06:36:53 +00:00
PlasticDigits commented 2026-07-07 04:22:30 +00:00 (Migrated from gitlab.com)

Summary

Implements GitLab #365: after every successful CHARM buy on /, a closable transaction-result share card replaces the ephemeral multi-toast stack (#337). The card collapses buy effects into ≤7 scannable rows (timer, rank, BP, XP/level, streak, flag), upgrades from preview → indexer-confirmed values when the viewer's buy reaches head, and supports Copy summary / Copy tx link. Defers while level-up celebration is active; rapid buys replace the card cleanly.

Tied to parent funnel epic #363.

Acceptance checklist

Criterion Command / step Result
Closable popover after successful wallet buy on / cd frontend && CI=1 npm run test:e2e -- --workers=5 e2e/anvil-arena-03-wallet-writes.spec.ts (after bash scripts/e2e-anvil.sh) PASS
Card summarizes timer, rank, BP, XP/level when data exists cd frontend && npm test -- arenaBuyShareSummary.test.ts PASS
Anti–cognitive-overload copy (≤7 rows, sparse emoji) arenaBuyShareSummary.test.ts + manual review of screenshots PASS
Fits one screenshot on mobile/tablet/desktop cd frontend && CI=1 npm run test:e2e -- --workers=1 e2e/buy-result-share-screenshots.spec.ts PASS
Preview → indexer upgrade for viewer wallet useArenaBuyResultSharePopover.ts + arenaBuyShareSummary.test.ts PASS
Dismiss + reduced-motion path ArenaBuyResultSharePopover.test.tsx PASS
No destructive overlap with level-up / WYWA celebrationActive defer in hook; WYWA on TimeArenaPage only PASS
npm run typecheck && npm run lint && npm test cd frontend && npm run typecheck && npm run lint && npm test PASS

Verification for third parties

  1. cd frontend && npm run typecheck && npm run lint && npm test
  2. cd frontend && npm run build && CI=1 npm run test:e2e -- --workers=1 e2e/buy-result-share-screenshots.spec.ts
  3. bash scripts/e2e-anvil.sh (or targeted e2e/anvil-arena-03-wallet-writes.spec.ts) — buy → popover visible → dismiss
  4. Review committed screenshots under docs/testing/screenshots/issue-365/
  5. Optional Rabby: connect on local stack, buy, confirm same card per docs/testing/rabby-cloud-agent-qa.md

Blockers

  • Full bash scripts/e2e-anvil.sh suite reported 2 unrelated failures on this VM (anvil-arena-01-mount AUDIT URL /audit vs /arena/protocol; anvil-arena-05 missing arena-xp-hero). #365-specific anvil-arena-03-wallet-writes buy popover test PASS.

Docs / invariants

  • INV-FRONTEND-365-BUY-RESULT-SHARE in docs/testing/invariants-and-business-logic.md
  • docs/frontend/arena-views.md §365
  • docs/testing/manual-qa-checklists.md §365
  • skills/play-time-arena-doub/SKILL.md
## Summary Implements GitLab #365: after every successful CHARM buy on `/`, a **closable transaction-result share card** replaces the ephemeral multi-toast stack (#337). The card collapses buy effects into ≤7 scannable rows (timer, rank, BP, XP/level, streak, flag), upgrades from preview → indexer-confirmed values when the viewer's buy reaches head, and supports **Copy summary** / **Copy tx link**. Defers while level-up celebration is active; rapid buys replace the card cleanly. Tied to parent funnel epic #363. ## Acceptance checklist | Criterion | Command / step | Result | |-----------|----------------|--------| | Closable popover after successful wallet buy on `/` | `cd frontend && CI=1 npm run test:e2e -- --workers=5 e2e/anvil-arena-03-wallet-writes.spec.ts` (after `bash scripts/e2e-anvil.sh`) | PASS | | Card summarizes timer, rank, BP, XP/level when data exists | `cd frontend && npm test -- arenaBuyShareSummary.test.ts` | PASS | | Anti–cognitive-overload copy (≤7 rows, sparse emoji) | `arenaBuyShareSummary.test.ts` + manual review of screenshots | PASS | | Fits one screenshot on mobile/tablet/desktop | `cd frontend && CI=1 npm run test:e2e -- --workers=1 e2e/buy-result-share-screenshots.spec.ts` | PASS | | Preview → indexer upgrade for viewer wallet | `useArenaBuyResultSharePopover.ts` + `arenaBuyShareSummary.test.ts` | PASS | | Dismiss + reduced-motion path | `ArenaBuyResultSharePopover.test.tsx` | PASS | | No destructive overlap with level-up / WYWA | `celebrationActive` defer in hook; WYWA on `TimeArenaPage` only | PASS | | `npm run typecheck && npm run lint && npm test` | `cd frontend && npm run typecheck && npm run lint && npm test` | PASS | ## Verification for third parties 1. `cd frontend && npm run typecheck && npm run lint && npm test` 2. `cd frontend && npm run build && CI=1 npm run test:e2e -- --workers=1 e2e/buy-result-share-screenshots.spec.ts` 3. `bash scripts/e2e-anvil.sh` (or targeted `e2e/anvil-arena-03-wallet-writes.spec.ts`) — buy → popover visible → dismiss 4. Review committed screenshots under `docs/testing/screenshots/issue-365/` 5. Optional Rabby: connect on local stack, buy, confirm same card per `docs/testing/rabby-cloud-agent-qa.md` ## Blockers - Full `bash scripts/e2e-anvil.sh` suite reported 2 unrelated failures on this VM (`anvil-arena-01-mount` AUDIT URL `/audit` vs `/arena/protocol`; `anvil-arena-05` missing `arena-xp-hero`). **#365-specific** `anvil-arena-03-wallet-writes` buy popover test **PASS**. ## Docs / invariants - `INV-FRONTEND-365-BUY-RESULT-SHARE` in `docs/testing/invariants-and-business-logic.md` - `docs/frontend/arena-views.md` §365 - `docs/testing/manual-qa-checklists.md` §365 - `skills/play-time-arena-doub/SKILL.md`
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-07-07 04:22:33 +00:00 (Migrated from gitlab.com)

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the [Cursor dashboard](https://www.cursor.com/dashboard/bugbot) to get automatic reviews on future PRs.
PlasticDigits commented 2026-07-07 04:24:41 +00:00 (Migrated from gitlab.com)

Security review — MR !536

Commit reviewed: 785cd4b74f92750098a9bd883cfe26c6f58f408d
Scope: Post-buy transaction result share popover (#365) — ArenaBuyResultSharePopover, useArenaBuyResultSharePopover, arenaBuyShareSummary, clipboard/share helpers, E2E screenshot hook, docs/tests/CSS.

Outcome: FINDINGS: 0 medium+

Inline threads: none

Areas reviewed

Area Result
XSS / HTML injection All user-visible strings (headline, row labels/values, copy banners) render via React text nodes; no dangerouslySetInnerHTML or href sinks in the diff.
CSS / class injection rowClassName maps a fixed tone union from parsed effect lines; no attacker-controlled class fragments.
Clipboard / tx link explorerTxUrl enforces ^0x[0-9a-fA-F]{64}$ before URL construction; copy actions use navigator.clipboard.writeText with validated or locally-built strings only.
E2E hook (__yieldomegaE2eShowBuyResult) Registered only when VITE_E2E_MOCK_WALLET=1 or __yieldomegaE2eBuyResultEnabled (Playwright init); not active in production bundles without mock-wallet flag. Overlay is display-only.
Indexer / preview data trust Share copy reuses existing resolveArenaBuyEffectToastLines / buildArenaBuyActualEffectLines paths (same trust boundary as superseded #337 toasts). findViewerBuyAtHead gates indexer upgrade to viewer wallet at head.
Authn/authz, SSRF, shell/SQL, secrets Not in diff scope; no new network calls or server endpoints.
EVM / contracts No onchain changes.

Security review: no medium+ findings on this diff.

## Security review — MR !536 **Commit reviewed:** `785cd4b74f92750098a9bd883cfe26c6f58f408d` **Scope:** Post-buy transaction result share popover (#365) — `ArenaBuyResultSharePopover`, `useArenaBuyResultSharePopover`, `arenaBuyShareSummary`, clipboard/share helpers, E2E screenshot hook, docs/tests/CSS. **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** none ### Areas reviewed | Area | Result | |------|--------| | **XSS / HTML injection** | All user-visible strings (`headline`, row labels/values, copy banners) render via React text nodes; no `dangerouslySetInnerHTML` or `href` sinks in the diff. | | **CSS / class injection** | `rowClassName` maps a fixed `tone` union from parsed effect lines; no attacker-controlled class fragments. | | **Clipboard / tx link** | `explorerTxUrl` enforces `^0x[0-9a-fA-F]{64}$` before URL construction; copy actions use `navigator.clipboard.writeText` with validated or locally-built strings only. | | **E2E hook (`__yieldomegaE2eShowBuyResult`)** | Registered only when `VITE_E2E_MOCK_WALLET=1` or `__yieldomegaE2eBuyResultEnabled` (Playwright init); not active in production bundles without mock-wallet flag. Overlay is display-only. | | **Indexer / preview data trust** | Share copy reuses existing `resolveArenaBuyEffectToastLines` / `buildArenaBuyActualEffectLines` paths (same trust boundary as superseded #337 toasts). `findViewerBuyAtHead` gates indexer upgrade to viewer wallet at head. | | **Authn/authz, SSRF, shell/SQL, secrets** | Not in diff scope; no new network calls or server endpoints. | | **EVM / contracts** | No onchain changes. | **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-07-07 06:32:35 +00:00 (Migrated from gitlab.com)

added 5 commits

  • 785cd4b7...ed8dea00 - 4 commits from branch main
  • 2a7ad1d3 - Merge origin/main into issue-365-buy-result-share-popover

Compare with previous version

added 5 commits <ul><li>785cd4b7...ed8dea00 - 4 commits from branch <code>main</code></li><li>2a7ad1d3 - Merge origin/main into issue-365-buy-result-share-popover</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/166/diffs?diff_id=1889254741&start_sha=785cd4b74f92750098a9bd883cfe26c6f58f408d)
PlasticDigits commented 2026-07-07 06:32:39 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main (merge commit 2a7ad1d3).

Conflict: docs/testing/invariants-and-business-logic.md — overlapping invariant rows for #337, #362, and #365.

Resolution: Kept MR #365 INV-FRONTEND-365-BUY-RESULT-SHARE and the legacy superseded #337 row; adopted main's updated #362 wording (arenaV2WarbowFlagSupplementContracts indexer-first supplement).

Sanity: npm run typecheck, npm run lint, and targeted Vitest for buy-result-share (arenaBuyShareSummary, ArenaBuyResultSharePopover, mobileBuyResultShareLayout) — all PASS.

Resolved merge conflicts with `main` (merge commit `2a7ad1d3`). **Conflict:** `docs/testing/invariants-and-business-logic.md` — overlapping invariant rows for #337, #362, and #365. **Resolution:** Kept MR #365 `INV-FRONTEND-365-BUY-RESULT-SHARE` and the legacy superseded #337 row; adopted `main`'s updated #362 wording (`arenaV2WarbowFlagSupplementContracts` indexer-first supplement). **Sanity:** `npm run typecheck`, `npm run lint`, and targeted Vitest for buy-result-share (`arenaBuyShareSummary`, `ArenaBuyResultSharePopover`, `mobileBuyResultShareLayout`) — all PASS.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-07-07 06:33:05 +00:00 (Migrated from gitlab.com)

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the [Cursor dashboard](https://www.cursor.com/dashboard/bugbot) to get automatic reviews on future PRs.
PlasticDigits commented 2026-07-07 06:35:33 +00:00 (Migrated from gitlab.com)

Security review — MR !536

Commit reviewed: 2a7ad1d3a926e05852661edaa0a52bca9c0a7fcc
Scope: Post-buy transaction result share popover (#365) — ArenaBuyResultSharePopover, useArenaBuyResultSharePopover, arenaBuyShareSummary, clipboard/share helpers, E2E screenshot hook, docs/tests/CSS. Re-reviewed after merge from main (conflict resolution in invariants docs only; no new #365 code paths in merge delta).

Outcome: FINDINGS: 0 medium+

Inline threads: none

Areas reviewed

Area Result
XSS / HTML injection All user-visible strings (headline, row labels/values, copy banners) render via React text nodes; no dangerouslySetInnerHTML or href sinks in the diff.
CSS / class injection rowClassName maps a fixed tone union from parsed effect lines; no attacker-controlled class fragments.
Clipboard / tx link explorerTxUrl enforces ^0x[0-9a-fA-F]{64}$ before URL construction; copy actions use navigator.clipboard.writeText with validated or locally-built strings only.
E2E hook (__yieldomegaE2eShowBuyResult) Registered only when VITE_E2E_MOCK_WALLET=1 or __yieldomegaE2eBuyResultEnabled (Playwright init); not active in production bundles without mock-wallet flag. Overlay is display-only.
Indexer / preview data trust Share copy reuses existing resolveArenaBuyEffectToastLines / buildArenaBuyActualEffectLines paths (same trust boundary as superseded #337 toasts). findViewerBuyAtHead gates indexer upgrade to viewer wallet at head.
Authn/authz, SSRF, shell/SQL, secrets Not in diff scope; no new network calls or server endpoints.
EVM / contracts No onchain changes.

Security review: no medium+ findings on this diff.

## Security review — MR !536 **Commit reviewed:** `2a7ad1d3a926e05852661edaa0a52bca9c0a7fcc` **Scope:** Post-buy transaction result share popover (#365) — `ArenaBuyResultSharePopover`, `useArenaBuyResultSharePopover`, `arenaBuyShareSummary`, clipboard/share helpers, E2E screenshot hook, docs/tests/CSS. Re-reviewed after merge from `main` (conflict resolution in invariants docs only; no new #365 code paths in merge delta). **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** none ### Areas reviewed | Area | Result | |------|--------| | **XSS / HTML injection** | All user-visible strings (`headline`, row labels/values, copy banners) render via React text nodes; no `dangerouslySetInnerHTML` or `href` sinks in the diff. | | **CSS / class injection** | `rowClassName` maps a fixed `tone` union from parsed effect lines; no attacker-controlled class fragments. | | **Clipboard / tx link** | `explorerTxUrl` enforces `^0x[0-9a-fA-F]{64}$` before URL construction; copy actions use `navigator.clipboard.writeText` with validated or locally-built strings only. | | **E2E hook (`__yieldomegaE2eShowBuyResult`)** | Registered only when `VITE_E2E_MOCK_WALLET=1` or `__yieldomegaE2eBuyResultEnabled` (Playwright init); not active in production bundles without mock-wallet flag. Overlay is display-only. | | **Indexer / preview data trust** | Share copy reuses existing `resolveArenaBuyEffectToastLines` / `buildArenaBuyActualEffectLines` paths (same trust boundary as superseded #337 toasts). `findViewerBuyAtHead` gates indexer upgrade to viewer wallet at head. | | **Authn/authz, SSRF, shell/SQL, secrets** | Not in diff scope; no new network calls or server endpoints. | | **EVM / contracts** | No onchain changes. | **Security review: no medium+ findings on this diff.**
PlasticDigits (Migrated from gitlab.com) merged commit d8a779f26e into main 2026-07-07 06:36:53 +00:00
PlasticDigits commented 2026-07-07 06:36:54 +00:00 (Migrated from gitlab.com)

mentioned in commit d8a779f26e

mentioned in commit d8a779f26e2ac9db4a5ffa77f2715ecb66f25290
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!536
No description provided.