From b86033e7f6d7d1e24438fcfef07ee77dca46a171 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Wed, 5 Aug 2026 19:44:07 -0400 Subject: [PATCH 01/61] docs: consolidate battle docs into a single protocol whitepaper --- CLAUDE.md | 6 +- backend/API.md | 5 +- backend/env.example | 9 +- backend/prisma/schema.prisma | 4 +- backend/src/config/env.ts | 5 +- backend/src/features/battle-ledger/state.ts | 2 +- .../src/features/battle-signer/signer.kms.ts | 2 +- .../features/battle-signer/signer.registry.ts | 2 +- backend/src/features/settle-keeper/index.ts | 5 +- backend/src/server.ts | 2 +- backend/src/ws/battleRoomSocket.ts | 2 +- .../features/battle-ledger/drills.test.ts | 2 +- .../ethereum/src/BattleBatchRegistry.sol | 2 +- contracts/ethereum/src/CryptoPetsToken.sol | 2 +- .../ethereum/src/SeasonRewardDistributor.sol | 2 +- contracts/ethereum/subgraph/src/mapping.ts | 2 +- .../ethereum/test/BattleBatchRegistry.test.ts | 2 +- .../test/SeasonRewardDistributor.test.ts | 2 +- .../test-vectors/protocol-commitment.json | 2 +- contracts/test-vectors/protocol-consent.json | 2 +- contracts/test-vectors/protocol-intent.json | 2 +- contracts/test-vectors/protocol-merkle.json | 2 +- .../test-vectors/protocol-progression.json | 2 +- contracts/test-vectors/protocol-receipt.json | 2 +- contracts/test-vectors/protocol-ruleset.json | 2 +- contracts/test-vectors/protocol-seed.json | 2 +- contracts/test-vectors/protocol-snapshot.json | 2 +- docs/README.md | 8 + ...tle-architecture.md => battle-protocol.md} | 687 +++++++++++++++++- docs/plan-backend-battle-steps.md | 404 ---------- docs/plan-future-features-roadmap.md | 19 +- docs/runbook-backend-battles.md | 238 ------ docs/runbook-signing-key-compromise.md | 134 ---- docs/threat-model-backend-battles.md | 291 -------- .../panels/battle/battle-utils.ts | 4 +- .../panels/battle/index.module.css | 2 +- .../panels/battle/parts/battle-overlay.tsx | 6 +- frontend/src/config.ts | 2 +- frontend/src/hooks/battle/useBattlePanel.ts | 8 +- proto/cryptopets.proto | 2 +- protocol/README.md | 3 +- protocol/scripts/gen-vectors.ts | 18 +- protocol/src/combat/sim.ts | 12 +- protocol/src/combat/strike.ts | 4 +- protocol/src/index.ts | 2 - services/indexer-go/README.md | 2 +- .../indexer-go/internal/grpcsrv/verify.go | 2 +- services/indexer-go/pb/cryptopets_grpc.pb.go | 4 +- shared/src/hooks/index.ts | 2 +- verifier/README.md | 4 +- verifier/package.json | 2 +- verifier/src/index.ts | 8 +- 52 files changed, 771 insertions(+), 1173 deletions(-) rename docs/{plan-backend-battle-architecture.md => battle-protocol.md} (51%) delete mode 100644 docs/plan-backend-battle-steps.md delete mode 100644 docs/runbook-backend-battles.md delete mode 100644 docs/runbook-signing-key-compromise.md delete mode 100644 docs/threat-model-backend-battles.md diff --git a/CLAUDE.md b/CLAUDE.md index de90e5c9..7b483fc4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -140,7 +140,7 @@ New battles run through the backend-authoritative path (`BATTLE_BACKEND_MODE_ENA ### Settle keeper: the second EVM breed/mint transaction isn't the player's Battles no longer take this path at all as of §L Phase 6 (above). Breed and mint still do — they have no backend-authoritative equivalent and continue to settle on chain. -`GameLogic`'s async flows (`requestBattle`/`requestCreateFromDNA`/`requestMintStarter` → Pyth Entropy reveals → `settleX`) used to have the frontend send the settle transaction itself, meaning two wallet prompts per action even though settle is permissionless. A backend service, `backend/src/features/settle-keeper/`, now watches Pyth Entropy's `Revealed` event and sends the settle transaction from its own wallet; the frontend only falls back to prompting the player if the keeper hasn't settled within ~45s (keeper outage or not configured). Gated by `KEEPER_ENABLED` (off by default); see `backend/env.example` for the full var list. This fixes only the double-signature UX; the related security fix — `requestBattle` snapshotting sim inputs so a level-up between request and settle can't reroll a committed battle — already lives in `GameLogic.sol` itself. See `docs/plan-realtime-battle-ux.md` / `docs/plan-realtime-battle-impl.md` for the full design and threat model. +`GameLogic`'s async flows (`requestBattle`/`requestCreateFromDNA`/`requestMintStarter` → Pyth Entropy reveals → `settleX`) used to have the frontend send the settle transaction itself, meaning two wallet prompts per action even though settle is permissionless. A backend service, `backend/src/features/settle-keeper/`, now watches Pyth Entropy's `Revealed` event and sends the settle transaction from its own wallet; the frontend only falls back to prompting the player if the keeper hasn't settled within ~45s (keeper outage or not configured). Gated by `KEEPER_ENABLED` (off by default); see `backend/env.example` for the full var list. This fixes only the double-signature UX; the related security fix — `requestBattle` snapshotting sim inputs so a level-up between request and settle can't reroll a committed battle — already lives in `GameLogic.sol` itself. ### Battle fee funds the settle keeper's own gas (EVM) — retired Retired with the on-chain battle path (§L Phase 6): `GameConfig.battleFee`, `setBattleFee`, and `useFees().battleFee` are all gone, and the keeper settles breed and mint only. Kept because the `GameConfig` migration it forced is still live and its env-staleness warning still applies. The original text follows. @@ -148,7 +148,7 @@ Retired with the on-chain battle path (§L Phase 6): `GameConfig.battleFee`, `se The EVM settle keeper (above) sends `settleBattle` from its own wallet, but until this was added that transaction (~800k gas, `SETTLE_GAS_LIMIT` in `backend/src/features/settle-keeper/abi.ts`) was entirely unfunded — the player's `requestBattle` payment only ever covered the Pyth Entropy fee. `GameConfig.battleFee` (owner-tunable via `setBattleFee`) is now required on top of the entropy fee at `requestBattle` time, escrowed in the pending record, and refunded on `cancelBattle` (no settle tx is ever sent for a cancelled request); on a normal settle it just adds to the contract's withdrawable balance alongside the other protocol fees — there's no automatic reimbursement to the keeper wallet specifically, so it still needs manual top-ups from `withdraw()` proceeds. The frontend surfaces this via `useFees().battleFee` (chain-neutral — see the Solana section below) and shows it in the Start Battle button label. Because `GameConfig` isn't behind a proxy (see its own doc comment), adding this field required a fresh `GameConfig` deployment plus a new `setGameConfig(address)` setter on both `GameLogic` and `PetCore` (added together, deliberately — `PetCore` reads several other config values like `battleCooldown`/`poolSizes`, and pointing only one proxy at a new instance would let the two silently diverge). `scripts/upgrade-game-config.ts` handles the migration: it replays every existing tunable from the old `GameConfig` onto the new one before repointing anything, so live-tuned values (fees, skill balance, cooldowns) aren't reset to source defaults. This has been run against the live Base Sepolia deployment; any client env (`VITE_GAMECONFIG_ADDRESS`, `KEEPER_GAME_CONFIG_ADDRESS`) pointing at the old `GameConfig` address needs updating too, or fee reads fail outright (the old contract has no `battleFee()` at all) — check `frontend/.env`/`.env.local` and `backend/.env` aren't stale before assuming a deployment issue is something else. ### Solana battles are retired too (§L Phase 6) -`commit_battle`/`settle_battle`/`cancel_battle`, the `BattleRequest` account, the Solana settle keeper (`backend/src/features/settle-keeper-solana/`), and `GlobalState.battle_fee_lamports` are all gone. Solana battles now take the same backend-authoritative path as EVM ones, so `settle_breed`/`settle_mint` are the only remaining commit/settle flows, and both still require the player's own signature (their Metaplex Core mint CPI needs a real payer signature — see `docs/plan-realtime-battle-solana.md` Workstream S2 for why the keeper never generalized to them). +`commit_battle`/`settle_battle`/`cancel_battle`, the `BattleRequest` account, the Solana settle keeper (`backend/src/features/settle-keeper-solana/`), and `GlobalState.battle_fee_lamports` are all gone. Solana battles now take the same backend-authoritative path as EVM ones, so `settle_breed`/`settle_mint` are the only remaining commit/settle flows, and both still require the player's own signature: their Metaplex Core mint CPI needs a real payer signature, which is why the keeper never generalized to them. One thing deliberately stayed: `game/battle_sim.rs` and `game/xp.rs` have no caller left in the program but are **frozen, not deleted**. With `CombatSim.sol` gone, their golden-vector tests are the *only* remaining independent witness that `contracts/test-vectors/{battle,xp}.json` describe what actually settled on chain — the two live ports are the things those vectors check, so they cannot vouch for them. @@ -223,4 +223,4 @@ See `docs/testing.md` for the full per-package suite table. Test work is expecte This monorepo has split licensing; see the table in `README.md`. `contracts/ethereum`, `contracts/solana`, `indexer-go`, `proto`, `protocol`, and `verifier` are MIT; everything else (`frontend`, `backend`, `mobile`, `website`, `shared`, `image-generator`) is PolyForm Noncommercial 1.0.0 (root `LICENSE`). Match the license of whichever package you're editing when adding new files. -`protocol` (`@cryptopets/protocol`) is MIT deliberately: the backend-authoritative battle design (`docs/plan-backend-battle-architecture.md` §H) only holds up if outsiders can run the receipt verifier, and the verifier depends on this package. So it must never import from a PolyForm package (`tests/package.test.ts` enforces it), and it must stay free of clock reads, ambient randomness, and I/O (eslint enforces the first two). The TS combat engine lives here now, re-exported from `shared/src/utils/combat` so existing importers are unchanged. +`protocol` (`@cryptopets/protocol`) is MIT deliberately: the backend-authoritative battle design (`docs/battle-protocol.md` §H) only holds up if outsiders can run the receipt verifier, and the verifier depends on this package. So it must never import from a PolyForm package (`tests/package.test.ts` enforces it), and it must stay free of clock reads, ambient randomness, and I/O (eslint enforces the first two). The TS combat engine lives here now, re-exported from `shared/src/utils/combat` so existing importers are unchanged. diff --git a/backend/API.md b/backend/API.md index cb1af862..534f6372 100644 --- a/backend/API.md +++ b/backend/API.md @@ -238,8 +238,7 @@ requests (the `requestX` → Pyth Entropy reveals → `settleX` flow) from a backend-held wallet once entropy reveals, so the player only signs the request transaction — `settleX` is permissionless and needed no special authorization, it was just being sent from the player's wallet by default. Off unless -`KEEPER_ENABLED=true`. See `docs/plan-realtime-battle-ux.md` / -`docs/plan-realtime-battle-impl.md` for the design and threat model. +`KEEPER_ENABLED=true`. Battles are **not** settled here any more (§L Phase 6). `requestBattle`/`settleBattle` were removed from the contracts entirely, along with the Solana settle keeper and shadow @@ -248,7 +247,7 @@ mode; battles run through the backend-authoritative path below. ### Backend-authoritative battles (v2) `backend/src/routes/battle.ts` — the workflow described in -`docs/plan-backend-battle-architecture.md`. Submission and consent require a JWT +`docs/battle-protocol.md`. Submission and consent require a JWT (the wallet signature inside the body is what actually authorizes the action, per §D); the reads below require nothing, because every value they return is either already public on chain or is itself a signed artifact anyone is meant diff --git a/backend/env.example b/backend/env.example index 0e38ea5d..42c2291b 100644 --- a/backend/env.example +++ b/backend/env.example @@ -69,8 +69,7 @@ DIRECT_URL="postgresql://postgres.:@aws-1-.pooler # and mint only, which have no backend equivalent. # # Settles requestCreateFromDNA/requestMintStarter requests from this wallet once Pyth -# Entropy reveals, so the player only signs the request transaction -# (see docs/plan-realtime-battle-ux.md, docs/plan-realtime-battle-impl.md Phase 2). +# Entropy reveals, so the player only signs the request transaction. # Off by default. All four of RPC_URL/PRIVATE_KEY/CHAIN_ID/GAME_LOGIC_ADDRESS are # required once enabled; the keeper logs and no-ops (doesn't crash the server) if # any are missing. @@ -88,9 +87,9 @@ DIRECT_URL="postgresql://postgres.:@aws-1-.pooler # enable against anything else, so this can't accidentally run on a real network. # KEEPER_MOCK_REVEAL=true -# --- Backend-authoritative battles (docs/plan-backend-battle-architecture.md) --- -# Backend-authoritative battle mode (docs/plan-backend-battle-architecture.md §L Phase 3, -# operated per docs/runbook-backend-battles.md). Off by default, and a separate switch from +# --- Backend-authoritative battles (docs/battle-protocol.md) --- +# Backend-authoritative battle mode (docs/battle-protocol.md §L Phase 3, +# operated per its Appendix B). Off by default, and a separate switch from # the on-chain path rather than a replacement: Phase 3 runs both side by side. # # Off: the write routes (POST /intents, /accept, /authorizations) return 503, the outbox diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 29ba322a..d7965b45 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -147,7 +147,7 @@ model BattleConversation { } // ─── Backend-authoritative battles ──────────────────────────────────────────── -// Models for the design in docs/plan-backend-battle-architecture.md. The existing +// Models for the design in docs/battle-protocol.md. The existing // pet_roster / battle_history tables stay exactly as they are: they are projections // of on-chain events, and the legacy on-chain battle path keeps writing them. // Everything below is the durable workflow for battles the backend resolves itself. @@ -609,7 +609,7 @@ model BattleSigningKey { /// True when this key was retired because it was compromised, rather than routinely /// rotated. Persisted rather than derived: "this key may have signed things we did not /// authorise" is a fact about history that a restart must not downgrade to an ordinary - /// rotation. See docs/runbook-signing-key-compromise.md. + /// rotation. See docs/battle-protocol.md Appendix C. compromised Boolean @default(false) firstSeenAt DateTime @default(now()) @map("first_seen_at") diff --git a/backend/src/config/env.ts b/backend/src/config/env.ts index 3bdcde50..33161fc1 100644 --- a/backend/src/config/env.ts +++ b/backend/src/config/env.ts @@ -86,8 +86,7 @@ export const env = { process.env.ROSTER_READ_SOURCE?.trim().toLowerCase() === 'grpc' ? 'grpc' : 'postgres', /** - * Settle keeper (plan-realtime-battle-ux.md / plan-realtime-battle-impl.md Phase 2): - * settles GameLogic battle/breed/mint requests from this wallet once Pyth Entropy + * Settle keeper: settles GameLogic breed/mint requests from this wallet once Pyth Entropy * reveals, so the player doesn't send the settle transaction themselves. Off unless * KEEPER_ENABLED=true; the four fields below are required once it is (checked at * startSettleKeeper() time so a misconfigured keeper logs and no-ops rather than @@ -115,7 +114,7 @@ export const env = { }, /** - * Backend-authoritative battles (docs/plan-backend-battle-architecture.md). + * Backend-authoritative battles (docs/battle-protocol.md). * * Every wallet-signed object binds `chainId` and `deploymentId`, and that binding only * stops a replay if this server refuses payloads naming a different one. Both values are diff --git a/backend/src/features/battle-ledger/state.ts b/backend/src/features/battle-ledger/state.ts index 62a6973a..14e16d37 100644 --- a/backend/src/features/battle-ledger/state.ts +++ b/backend/src/features/battle-ledger/state.ts @@ -1,7 +1,7 @@ import { BattleState } from '@generated/prisma/enums'; /** - * The battle lifecycle from §J of docs/plan-backend-battle-architecture.md, as code. + * The battle lifecycle from §J of docs/battle-protocol.md, as code. * * Two properties are enforced here rather than left to the caller: * diff --git a/backend/src/features/battle-signer/signer.kms.ts b/backend/src/features/battle-signer/signer.kms.ts index 64d1dace..ceaecf74 100644 --- a/backend/src/features/battle-signer/signer.kms.ts +++ b/backend/src/features/battle-signer/signer.kms.ts @@ -20,7 +20,7 @@ import type { SignerBackend } from './signer.types'; export function createKmsSigner(provider: string): SignerBackend { throw new Error( `KMS signer provider "${provider}" is not implemented. Production signing must use a managed ` + - 'KMS/HSM key restricted to commitment and receipt digests (docs/plan-backend-battle-architecture.md §G). ' + + 'KMS/HSM key restricted to commitment and receipt digests (docs/battle-protocol.md §G). ' + 'Implement an adapter here rather than setting BATTLE_SIGNER_PRIVATE_KEY in production.', ); } diff --git a/backend/src/features/battle-signer/signer.registry.ts b/backend/src/features/battle-signer/signer.registry.ts index c724cc68..4b7e5498 100644 --- a/backend/src/features/battle-signer/signer.registry.ts +++ b/backend/src/features/battle-signer/signer.registry.ts @@ -27,7 +27,7 @@ import type { SigningKeyDescriptor } from './signer.types'; * later call passes a milder status. Downgrading that flag would quietly turn "this key may * have signed things we did not authorise" back into an ordinary rotation, and the whole * point of the distinction is that the two demand different responses - * (docs/runbook-signing-key-compromise.md). + * (docs/battle-protocol.md Appendix C). */ export async function persistSigningKey(key: SigningKeyDescriptor): Promise { const compromised = key.status === 'compromised'; diff --git a/backend/src/features/settle-keeper/index.ts b/backend/src/features/settle-keeper/index.ts index f2240ed9..20003aea 100644 --- a/backend/src/features/settle-keeper/index.ts +++ b/backend/src/features/settle-keeper/index.ts @@ -4,9 +4,8 @@ import { startKeeper, type SettleKeeperHandle } from './keeper'; /** * Settles GameLogic breed/mint requests from a backend-held wallet the moment * Pyth Entropy reveals, so the player never has to send the second (settle) - * transaction themselves. See docs/plan-realtime-battle-ux.md and - * docs/plan-realtime-battle-impl.md Phase 2 for the original design; battles no - * longer take this path at all (§L Phase 6), breed and mint still do. + * transaction themselves. Battles no longer take this path at all + * (docs/battle-protocol.md §L Phase 6), breed and mint still do. * * Off unless KEEPER_ENABLED=true: the feature simply doesn't start rather than failing, * so local dev / CI without a configured keeper wallet is unaffected. diff --git a/backend/src/server.ts b/backend/src/server.ts index fe938c3b..c6e10a49 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -27,7 +27,7 @@ const server = app.listen(env.port, '0.0.0.0', () => { // KEEPER_ENABLED is set. startSettleKeeper(); - // Backend-authoritative battles (docs/plan-backend-battle-architecture.md §L Phase 3). + // Backend-authoritative battles (docs/battle-protocol.md §L Phase 3). // Selects the signing backend (refuses an in-process key in production; see // @features/battle-signer) and starts the outbox worker that carries accepted battles // through to a signed receipt. diff --git a/backend/src/ws/battleRoomSocket.ts b/backend/src/ws/battleRoomSocket.ts index 8ca40dac..b38af8dc 100644 --- a/backend/src/ws/battleRoomSocket.ts +++ b/backend/src/ws/battleRoomSocket.ts @@ -9,7 +9,7 @@ import WebSocket, { WebSocketServer } from 'ws'; /** * The per-room, notification-only channel for backend-authoritative battles - * (docs/plan-backend-battle-architecture.md §J). + * (docs/battle-protocol.md §J). * * It replaced a global-broadcast socket that pushed chain-derived data for the * on-chain flow, filtered client-side by `(chainId, requestId)`. Broadcasting was diff --git a/backend/tests/features/battle-ledger/drills.test.ts b/backend/tests/features/battle-ledger/drills.test.ts index 311bcad1..b9bfbfd9 100644 --- a/backend/tests/features/battle-ledger/drills.test.ts +++ b/backend/tests/features/battle-ledger/drills.test.ts @@ -5,7 +5,7 @@ import { ethers } from 'ethers'; /** * The §L Phase 3 drills, executed rather than described. * - * `docs/runbook-backend-battles.md` documents the procedures; this file runs the mechanical + * `docs/battle-protocol.md` Appendix B documents the procedures; this file runs the mechanical * half of each one on every CI pass, so a drill cannot quietly stop being true between * incidents. What is deliberately not here is the human half — who is paged, who decides — * which is what the runbook prose is for. diff --git a/contracts/ethereum/src/BattleBatchRegistry.sol b/contracts/ethereum/src/BattleBatchRegistry.sol index 33faf86d..69057096 100644 --- a/contracts/ethereum/src/BattleBatchRegistry.sol +++ b/contracts/ethereum/src/BattleBatchRegistry.sol @@ -7,7 +7,7 @@ import "@openzeppelin/contracts/utils/Pausable.sol"; /** * @title BattleBatchRegistry * @notice Immutable publication record for batches of backend-resolved battle receipts. - * @dev docs/plan-backend-battle-architecture.md §I. Deliberately minimal: this contract + * @dev docs/battle-protocol.md §I. Deliberately minimal: this contract * stores roots and nothing else. It does not verify proofs, hold funds, or know what * a reward is — the claim path is a separate contract, so the thing every player's * history is anchored against stays small enough to audit in one sitting. diff --git a/contracts/ethereum/src/CryptoPetsToken.sol b/contracts/ethereum/src/CryptoPetsToken.sol index 8f91691f..3f4cf276 100644 --- a/contracts/ethereum/src/CryptoPetsToken.sol +++ b/contracts/ethereum/src/CryptoPetsToken.sol @@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; /** * @title CryptoPetsToken * @notice The CPET reward token. Fixed supply, minted once at deployment. - * @dev Funds `SeasonRewardDistributor` (docs/plan-backend-battle-architecture.md §I). + * @dev Funds `SeasonRewardDistributor` (docs/battle-protocol.md §I). * * **There is no mint function, and no owner.** §I's whole argument is that rewards are * bounded: the distributor caps what one wallet and one season may pay, and those caps diff --git a/contracts/ethereum/src/SeasonRewardDistributor.sol b/contracts/ethereum/src/SeasonRewardDistributor.sol index 0bdbae47..efad1b09 100644 --- a/contracts/ethereum/src/SeasonRewardDistributor.sol +++ b/contracts/ethereum/src/SeasonRewardDistributor.sol @@ -9,7 +9,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /** * @title SeasonRewardDistributor * @notice Capped, one-time reward claims against a per-season Merkle root. - * @dev docs/plan-backend-battle-architecture.md §I. Separate from BattleBatchRegistry on + * @dev docs/battle-protocol.md §I. Separate from BattleBatchRegistry on * purpose: that contract is the immutable record of what happened and must stay * minimal, while this one holds funds. Keeping the ledger away from the money means a * bug here cannot corrupt the history, and a pause here cannot stop battles. diff --git a/contracts/ethereum/subgraph/src/mapping.ts b/contracts/ethereum/subgraph/src/mapping.ts index 1aa060ac..ec0c4efb 100644 --- a/contracts/ethereum/subgraph/src/mapping.ts +++ b/contracts/ethereum/subgraph/src/mapping.ts @@ -4,7 +4,7 @@ // recover the parents that BreedSettled omits. // // No battle handlers: battles are resolved by the backend and published as signed -// receipts (docs/plan-backend-battle-architecture.md), never as chain events. +// receipts (docs/battle-protocol.md), never as chain events. import { NewPet, diff --git a/contracts/ethereum/test/BattleBatchRegistry.test.ts b/contracts/ethereum/test/BattleBatchRegistry.test.ts index b843ca67..77a0e89e 100644 --- a/contracts/ethereum/test/BattleBatchRegistry.test.ts +++ b/contracts/ethereum/test/BattleBatchRegistry.test.ts @@ -30,7 +30,7 @@ async function rejectsWithError(promise: Promise, signature: string): P } /** - * BattleBatchRegistry (docs/plan-backend-battle-architecture.md §I). + * BattleBatchRegistry (docs/battle-protocol.md §I). * * The contract's only real guarantee is ordering: batches are append-only, linked, and * sequence-contiguous. Most of what follows is aimed at that, because a registry that diff --git a/contracts/ethereum/test/SeasonRewardDistributor.test.ts b/contracts/ethereum/test/SeasonRewardDistributor.test.ts index 096f18e5..f68ec003 100644 --- a/contracts/ethereum/test/SeasonRewardDistributor.test.ts +++ b/contracts/ethereum/test/SeasonRewardDistributor.test.ts @@ -6,7 +6,7 @@ import { network } from "hardhat"; import { toFunctionSelector } from "viem"; /** - * SeasonRewardDistributor (docs/plan-backend-battle-architecture.md §I). + * SeasonRewardDistributor (docs/battle-protocol.md §I). * * Two things are being tested. First, that the Solidity leaf encoding is byte-identical to * the protocol's `rewardMerkleLeaf` — if it is not, no proof the backend ever builds will diff --git a/contracts/test-vectors/protocol-commitment.json b/contracts/test-vectors/protocol-commitment.json index 402c9e15..9f2e043c 100644 --- a/contracts/test-vectors/protocol-commitment.json +++ b/contracts/test-vectors/protocol-commitment.json @@ -1,5 +1,5 @@ { - "description": "BattleCommitment canonical-hash vectors (docs/plan-backend-battle-architecture.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/commitment. The snapshot enters the hash as snapshotHash, while the payload carries the full snapshot. A failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "BattleCommitment canonical-hash vectors (docs/battle-protocol.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/commitment. The snapshot enters the hash as snapshotHash, while the payload carries the full snapshot. A failure means the implementation drifted. Never edit an expectation to match new output.", "cases": [ { "name": "baseline", diff --git a/contracts/test-vectors/protocol-consent.json b/contracts/test-vectors/protocol-consent.json index c0cf7651..9ee10640 100644 --- a/contracts/test-vectors/protocol-consent.json +++ b/contracts/test-vectors/protocol-consent.json @@ -1,5 +1,5 @@ { - "description": "DefenseAuthorization canonical-hash and Solana sign-message vectors (docs/plan-backend-battle-architecture.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/consent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "DefenseAuthorization canonical-hash and Solana sign-message vectors (docs/battle-protocol.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/consent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.", "cases": [ { "name": "evm-all-pets", diff --git a/contracts/test-vectors/protocol-intent.json b/contracts/test-vectors/protocol-intent.json index f6103d6b..b82384ed 100644 --- a/contracts/test-vectors/protocol-intent.json +++ b/contracts/test-vectors/protocol-intent.json @@ -1,5 +1,5 @@ { - "description": "BattleIntent canonical-hash and Solana sign-message vectors (docs/plan-backend-battle-architecture.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/intent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "BattleIntent canonical-hash and Solana sign-message vectors (docs/battle-protocol.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/intent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.", "cases": [ { "name": "evm-direct-challenge", diff --git a/contracts/test-vectors/protocol-merkle.json b/contracts/test-vectors/protocol-merkle.json index 2dd5d1aa..6f7255db 100644 --- a/contracts/test-vectors/protocol-merkle.json +++ b/contracts/test-vectors/protocol-merkle.json @@ -1,5 +1,5 @@ { - "description": "Merkle leaf, root, and proof vectors (docs/plan-backend-battle-architecture.md §I). Generated by protocol/scripts/gen-vectors.ts from protocol/src/merkle. Layout notes for a Solidity implementation: leaf = keccak256(LEAF_DOMAIN || uint16 schemaVersion || receiptHash); node = keccak256(NODE_DOMAIN || min(a,b) || max(a,b)); all elements are fixed 32 bytes so abi.encodePacked matches; pairs are sorted so proofs carry no direction flags; an odd node is promoted unchanged rather than paired with itself. A failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "Merkle leaf, root, and proof vectors (docs/battle-protocol.md §I). Generated by protocol/scripts/gen-vectors.ts from protocol/src/merkle. Layout notes for a Solidity implementation: leaf = keccak256(LEAF_DOMAIN || uint16 schemaVersion || receiptHash); node = keccak256(NODE_DOMAIN || min(a,b) || max(a,b)); all elements are fixed 32 bytes so abi.encodePacked matches; pairs are sorted so proofs carry no direction flags; an odd node is promoted unchanged rather than paired with itself. A failure means the implementation drifted. Never edit an expectation to match new output.", "domains": { "leaf": "0xea935f3622687fcaec0f16c38a011768b07df58a102da1ee85881dc236e9b935", "node": "0xfc3a24400652b1e1b0cbd8aa53656a5a5af5f5ab615d7faeb2c37dd511e09ca1", diff --git a/contracts/test-vectors/protocol-progression.json b/contracts/test-vectors/protocol-progression.json index b249802f..84a39fb8 100644 --- a/contracts/test-vectors/protocol-progression.json +++ b/contracts/test-vectors/protocol-progression.json @@ -1,5 +1,5 @@ { - "description": "Progression-delta vectors in the frozen-snapshot shape (docs/plan-backend-battle-architecture.md §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/progression. The XP formula and decay themselves are pinned cross-language by contracts/test-vectors/xp.json; these cases pin the composition (which base applies to whom, which decay shift, and the level-threshold interaction). A failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "Progression-delta vectors in the frozen-snapshot shape (docs/battle-protocol.md §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/progression. The XP formula and decay themselves are pinned cross-language by contracts/test-vectors/xp.json; these cases pin the composition (which base applies to whom, which decay shift, and the level-threshold interaction). A failure means the implementation drifted. Never edit an expectation to match new output.", "cases": [ { "name": "attacker-wins-fresh", diff --git a/contracts/test-vectors/protocol-receipt.json b/contracts/test-vectors/protocol-receipt.json index e263b4c9..217ee3dc 100644 --- a/contracts/test-vectors/protocol-receipt.json +++ b/contracts/test-vectors/protocol-receipt.json @@ -1,5 +1,5 @@ { - "description": "BattleReceipt canonical-hash vectors (docs/plan-backend-battle-architecture.md §G). Generated by protocol/scripts/gen-vectors.ts from protocol/src/receipt. Each case is a coherent receipt: real quicknet beacons, a seed derived from the receipt own inputs, a combat-log hash from an actual simulation, and a recomputed progression delta. Derived fields are recorded so a reader can see what the encoding covered. A failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "BattleReceipt canonical-hash vectors (docs/battle-protocol.md §G). Generated by protocol/scripts/gen-vectors.ts from protocol/src/receipt. Each case is a coherent receipt: real quicknet beacons, a seed derived from the receipt own inputs, a combat-log hash from an actual simulation, and a recomputed progression delta. Derived fields are recorded so a reader can see what the encoding covered. A failure means the implementation drifted. Never edit an expectation to match new output.", "cases": [ { "name": "first-receipt-under-key", diff --git a/contracts/test-vectors/protocol-ruleset.json b/contracts/test-vectors/protocol-ruleset.json index 43b7b2ef..86393475 100644 --- a/contracts/test-vectors/protocol-ruleset.json +++ b/contracts/test-vectors/protocol-ruleset.json @@ -1,5 +1,5 @@ { - "description": "Ruleset canonical-hash vectors (docs/plan-backend-battle-architecture.md §F, §H). Generated by protocol/scripts/gen-vectors.ts from protocol/src/ruleset. A ruleset hash is chain-agnostic on purpose: the same rules can run on either chain. A failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "Ruleset canonical-hash vectors (docs/battle-protocol.md §F, §H). Generated by protocol/scripts/gen-vectors.ts from protocol/src/ruleset. A ruleset hash is chain-agnostic on purpose: the same rules can run on either chain. A failure means the implementation drifted. Never edit an expectation to match new output.", "cases": [ { "name": "source-defaults", diff --git a/contracts/test-vectors/protocol-seed.json b/contracts/test-vectors/protocol-seed.json index 2681ff68..b265d309 100644 --- a/contracts/test-vectors/protocol-seed.json +++ b/contracts/test-vectors/protocol-seed.json @@ -1,5 +1,5 @@ { - "description": "Battle seed derivation vectors (docs/plan-backend-battle-architecture.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/randomness. The layout is length-prefixed via the canonical encoder rather than the bare concatenation §E sketches; field order matches §E exactly. A failure means the implementation drifted, and every historical battle depends on this layout. Never edit an expectation to match new output.", + "description": "Battle seed derivation vectors (docs/battle-protocol.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/randomness. The layout is length-prefixed via the canonical encoder rather than the bare concatenation §E sketches; field order matches §E exactly. A failure means the implementation drifted, and every historical battle depends on this layout. Never edit an expectation to match new output.", "cases": [ { "name": "baseline", diff --git a/contracts/test-vectors/protocol-snapshot.json b/contracts/test-vectors/protocol-snapshot.json index 1f82e437..d1b248b9 100644 --- a/contracts/test-vectors/protocol-snapshot.json +++ b/contracts/test-vectors/protocol-snapshot.json @@ -1,5 +1,5 @@ { - "description": "BattleSnapshot canonical-hash vectors (docs/plan-backend-battle-architecture.md §C, §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/snapshot. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.", + "description": "BattleSnapshot canonical-hash vectors (docs/battle-protocol.md §C, §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/snapshot. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.", "cases": [ { "name": "evm-baseline", diff --git a/docs/README.md b/docs/README.md index b72bf89d..248abfa3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,6 +9,14 @@ package-specific docs live next to their code and are linked below. - [Testing strategy](./testing.md) — how tests and coverage are organized - [Development guide](../DEVELOPMENT.md) — setup, commands, env vars, local chains +## Cross-cutting docs + +| Doc | What it is | +| --- | --- | +| [Battle protocol](./battle-protocol.md) | The shipped backend-authoritative battle system. Part 1 plain words, Part 2 spec (§A–§M), Appendix A threat model, B operations runbook, C key-compromise runbook. | +| [Future features roadmap](./plan-future-features-roadmap.md) | Brainstorm for eleven unbuilt features. Not a build spec. | +| [Testing](./testing.md) | Per-package suite table and conventions. | + ## Package docs | Area | Doc | diff --git a/docs/plan-backend-battle-architecture.md b/docs/battle-protocol.md similarity index 51% rename from docs/plan-backend-battle-architecture.md rename to docs/battle-protocol.md index ff151954..7afbce09 100644 --- a/docs/plan-backend-battle-architecture.md +++ b/docs/battle-protocol.md @@ -1,21 +1,27 @@ -# Backend-authoritative battle architecture +# The CryptoPets battle protocol -Status: proposed architecture, not an implementation spec. +Status: implemented and live. This is the specification of the shipped system, not a proposal. +Where the text describes work as upcoming (§K, §L), read it as the record of how the migration +was sequenced. -This document has two halves. +This document has two halves and three appendices. - **Part 1** explains the whole design in plain words, with no jargon. Read it even if you plan to read Part 2. It takes about ten minutes. - **Part 2** is the precise specification: field lists, state machines, hash definitions, phases. Every section there starts with a one-line plain-words summary, so you can skim. +- **Appendix A** is the threat model, **B** the operations runbook, **C** the signing-key + compromise procedure. | If you want | Go to | |---|---| -| To understand what we are building and why | Part 1 | -| To decide whether to approve it | Part 1, then §A trust model | -| To build it | Part 2 | -| What to build first | §L implementation order | -| Unfamiliar word | Glossary at the end | +| To understand what we built and why | Part 1 | +| To evaluate the trust assumptions | Part 1, then §A trust model | +| To implement against it or verify a receipt | Part 2 | +| To attack it, or to review how we defend it | Appendix A | +| To operate it, or run a drill | Appendix B | +| To respond to a suspected key compromise | Appendix C | +| Unfamiliar word | Glossary at the end of Part 2 | --- @@ -732,7 +738,7 @@ The four-port combat rule is a `MUST` in `AGENTS.md`, restated in `CLAUDE.md`. I roadmap guidance, so accepting this document does not relax it. Amend both files **at Phase 6**, when the legacy on-chain path actually retires, not at acceptance. -**Done (Step 40).** The amendment split the four ports rather than loosening the rule: `CombatSim.sol` +**Done.** The amendment split the four ports rather than loosening the rule: `CombatSim.sol` and `combat.rs` are now `MUST NOT` change — frozen, because the battles they settled are permanent records that must stay replayable — while `protocol/src/combat/` and `services/indexer-go/internal/combat/` are `MUST` change together, since §F's circuit breaker depends on the two being independent. All four @@ -861,3 +867,666 @@ risk well beyond the battle problem. Not worth introducing solely to reduce comb | **Merkle proof** | The short evidence that your receipt was in that pile. | | **Nullifier** | A one-time marker preventing a reward from being claimed twice. | | **Equivocation** | Signing two conflicting statements about the same battle. Provable cheating. | + +--- + +# Appendix A: threat model + +Scope: the backend battle path specified in Part 2 above. The existing on-chain path +(`GameLogic.sol`, `settle_battle.rs`) keeps its own properties and is not re-analysed here. + +This appendix exists because moving battle resolution off-chain moves it inside our trust +boundary. §A states the trust model in one table; this is the expanded version: who attacks +what, what stops them, how we notice, and what is left over. + +## 1. Assets + +| Asset | Why it matters | Authority | +|---|---|---| +| Pet and item ownership | Transferable value | Chain | +| Reward custody and claims | Transferable value | Chain | +| Battle signing key | Signs commitments and receipts; forgery source | KMS | +| Root publisher key | Anchors batches on-chain | KMS + multisig | +| Off-chain progression (XP, rating, streak) | Determines rewards and matchmaking | Backend | +| Signed receipt corpus | The evidence players hold against us | Backend, published | +| Commitment sequence | Proves which round each battle was bound to | Backend, delivered to players | + +## 2. Actors + +| Actor | Assumed capability | +|---|---| +| Player | Can sign with their own wallet, replay traffic, script requests, disconnect at will | +| External attacker | Network position, can hit any public endpoint, no keys | +| Insider with database access | Read and write Postgres, no KMS signing scope | +| Insider with signer access | Can request signatures over well-formed commitments and receipts | +| Dishonest operator | Controls all backend processes, both combat implementations, and the database | +| drand network | Assumed honest and live; a threshold of nodes would have to collude to bias a round | + +The dishonest-operator row is the uncomfortable one and it is deliberate. Most controls below do not +stop that actor. They make the actor's lies detectable by anyone holding a commitment or a receipt. + +## 3. Threats + +Each row: what the attacker does, what stops or bounds it, how we notice, what is left. + +### T1: randomness reroll after seeing the value + +- **Attack.** Operator watches drand, computes the result, dislikes it, and claims the battle was + always bound to a later round. Recompute, publish, everything self-consistent. +- **Control.** Commit before reveal (§E). The round is chosen mechanically as + `currentVerifiedRound + 2`, and the signed `BattleCommitment` is returned synchronously in the + accept response, before the round exists. +- **Detection.** A reroll needs a second signature over the same `battleId`. Either player's stored + commitment plus the published receipt is a provable equivocation. +- **Residual.** Only detectable if players keep their commitment. The client persists it to local + storage and the endpoint serves it, but a player who never fetched it holds no evidence. +- **Non-control.** Persisting the chosen round in Postgres proves nothing. It is our database. + Merkle anchoring does not help either, because anchoring happens after computation. + +### T2: lying about the result + +- **Attack.** Publish a receipt whose winner does not follow from its own inputs. +- **Control.** None preventive. The receipt carries every input, so the result is recomputable. +- **Detection.** Public replay (§H). Anyone runs the verifier and the check fails. +- **Residual.** Only caught if someone runs the verifier. That is why it ships in Phase 3 while + nothing of value is at stake (Steps 30 to 32), and why we run it in CI against a corpus fixture + and monitor it ourselves. + +### T3: hiding a battle + +- **Attack.** Resolve a battle, dislike the outcome, never publish the receipt. +- **Control.** None preventive. Receipts are sequenced and hash-chained globally and per pet (§G). +- **Detection.** A gap breaks the chain. The per-pet chain also means a player who holds their own + commitment can show a committed battle with no corresponding receipt. +- **Residual.** Visible, not impossible. If omission risk becomes unacceptable, §I's delayed + direct-receipt claim fallback or an optimistic challenge protocol is the next step. + +### T4: signing-key compromise + +- **Attack.** Stolen key signs arbitrary commitments and receipts. +- **Control.** Key in KMS, never in API or worker environments. Signer accepts only the exact + commitment and receipt schemas, never a generic state-mutation payload. No asset custody, no + withdrawal authority. Separate keys per reward domain. Reward caps bound the economic damage + (§I). +- **Detection.** KMS request logging of every digest and key version. Signer throughput outside + expected range. Receipts that exist in the corpus but not in the ledger. Hash-chain forks. +- **Residual.** Real. Bounded, not eliminated. See + Appendix C. + +### T5: outcome grinding by submit-and-abandon + +- **Attack.** Submit many battles, abandon the ones that seed badly, keep the good ones. +- **Control.** No player-initiated cancellation after `committed` (§E). Disconnection, tab close, + and app kill do not affect resolution. Per-wallet and per-pet rate limits, daily battle caps. +- **Detection.** Abandonment rate per wallet. Win distribution per wallet against the expected + distribution for their matchups. +- **Residual.** A player can still choose which opponents to fight. That is matchmaking design, not + a randomness leak. + +### T6: manufactured beacon outage + +- **Attack.** Player degrades their own connectivity, or an attacker degrades ours, to escape a + battle already seeded against them. +- **Control.** The committed round is retried indefinitely and never substituted. On a genuine + permanent outage past the timeout, the battle ends `forfeited` with no progression change and both + pets stay locked for several rounds, so escaping costs more than losing (§E). +- **Detection.** drand fetch delay metric. Forfeit rate per wallet. +- **Residual.** A wallet that repeatedly forfeits is a rate-limit and abuse-policy matter. + +### T7: intent replay + +- **Attack.** Resubmit a captured signed intent to force extra battles. +- **Control.** `clientNonce` with a unique database constraint, `expiresAt`, and nonce consumption at + acceptance (§D). +- **Detection.** Repeated-nonce alert. +- **Residual.** None material. + +### T8: cross-chain or cross-deployment replay + +- **Attack.** Take a signature from staging and use it on production, or across chains. +- **Control.** Every signed object binds `chainId` and `deploymentId` (§D). Intents, + consents, commitments, and receipts all carry both, inside the hashed payload. +- **Detection.** Domain mismatch is a hard rejection, logged. +- **Residual.** None material, provided `deploymentId` is genuinely unique per environment. + +### T9: forged defender consent + +- **Attack.** Battle an unwilling defender, applying cooldown and rating changes to them. +- **Control.** `DefenseAuthorization` signed by the defender's wallet, bound to `rulesetHash`, with + level band, daily cap, validity window, and `revocationNonce`. Every receipt embeds the hash of + the authorization it relied on (§D). +- **Detection.** Receipts referencing an unknown or revoked authorization hash fail public replay. +- **Residual.** Consent is to a ruleset version, so a rules change invalidates outstanding + authorizations by design. Expect a re-consent prompt after every balance patch. + +### T10: stale ownership after an NFT transfer + +- **Attack.** Battle with a pet already sold, or snapshot a pet mid-transfer. +- **Control.** Ownership checked at the finalized source version, snapshot records + `sourceChainVersions` (§G). Reconciliation job between finalized chain ownership, snapshots, + receipts, and claims (§J). +- **Detection.** Reconciliation mismatch. +- **Residual.** Reorg depth on the source chain sets the finality wait, which is a latency cost, not + a correctness gap. + +### T11: concurrent battles with the same pet + +- **Attack.** Race two battles for one pet so one snapshot is stale or a cooldown is skipped. +- **Control.** Both pets locked in deterministic id order inside a serializable transaction. + Snapshot persisted before randomness exists. +- **Detection.** Serialization-failure rate, duplicate-battle-id alert. +- **Residual.** None material. This is a correctness test target, not a monitoring target. + +### T12: duplicate workers + +- **Attack.** Two workers process the same transition, double-crediting progression or forking a + hash chain. +- **Control.** Every transition idempotent, at-least-once processing assumed, each transition and its + outbox message committed atomically. A duplicate battle id with a different payload is a security + alert and never an upsert (§J). +- **Detection.** Hash-chain discontinuity alert. Duplicate-payload alert. +- **Residual.** None material. + +### T13: forged snapshot inputs + +- **Attack.** Inflate a pet's stats, level, or equipment inside the snapshot. +- **Control.** Snapshot fields derive from indexed chain state at a recorded source version. + Progression fields (`xp`, `streak`, `lastOpponentId`) are off-chain, so they are only checkable by + replaying that pet's prior receipts, which the per-pet hash chain makes tractable (§G). +- **Detection.** Public replay walking a pet's chain catches a snapshot that does not follow from the + previous receipt's `progressionDelta`. +- **Residual.** Equipment ownership must be verifiable from chain or from a signed inventory record + before equipment affects combat. Until then, keep equipment out of combat inputs. + +### T14: combat log leaks outcomes to spectators + +- **Attack.** Read the outcome of every resolving battle by connecting to the WebSocket. +- **Control.** `liveBattleSocket.ts` currently broadcasts every message to every client. That is + acceptable for chain-derived data and not acceptable for full combat logs. Subscriptions scope to + the existing `BattleRoom` and the socket becomes notification-only (§J). +- **Detection.** Route-level test asserting no cross-room delivery. +- **Residual.** Room ids are shareable by design, so a room link is a spectator link. + +### T15: commitment accepted but never delivered + +- **Attack.** Or, more likely, a bug. Accept succeeds, the player never receives the signed + commitment, and the only record of the chosen round is ours. T1 is then undetectable for that + battle. +- **Control.** Commitment signed and returned synchronously in the accept response, and also served + from a public endpoint so it is re-fetchable (Steps 23, 27). +- **Detection.** Dedicated alert on accept-succeeded-without-commitment-delivery (§J). +- **Residual.** A player who never fetches it still holds no evidence. The public endpoint bounds + this to non-malicious loss. + +### T16: fraudulent or omitted reward batch + +- **Attack.** Anchor a root covering receipts that were never signed, or omit signed receipts from + every batch. +- **Control.** Per-battle, per-wallet, per-batch, and per-season reward caps. One-time claims with + nullifiers. Emergency pause. Root publishers behind multisig and timelock. Published + receipt-to-root inclusion proofs (§I). +- **Detection.** Receipt-omission alert past the inclusion SLO. Root-anchor delay alert. Verifier + Merkle-inclusion check. +- **Residual.** An unanchored signed receipt is evidence of operator failure, not an on-chain claim. + +### T17: denial of service against popular opponents + +- **Attack.** Flood a specific defender to exhaust their daily cap or keep their pets locked. +- **Control.** Per-wallet and per-pet rate limits, defender daily battle cap set by the defender + themselves in their authorization (§D). +- **Detection.** Per-defender request-rate anomaly. +- **Residual.** A popular defender's cap is consumed by whoever gets there first. Matchmaking policy, + not a cryptographic problem. + +### T18: verifier collusion + +- **Attack.** The Go verifier does not constrain a dishonest operator, because the same operator runs + both processes and both ports descend from `CombatSim.sol`. +- **Control.** None, and none is claimed. The Go verifier's role is release safety: it catches + implementation drift, bad deploys, and transcription bugs, and it hard-stops receipt signing on any + mismatch (§F). +- **Detection.** Engine/verifier mismatch alert with both outputs and all inputs retained. +- **Residual.** Dishonest computation is caught by public replay (T2), not by this. + +### T19: database rollback or restore + +- **Attack.** Restore Postgres to an earlier point and lose or rewrite receipts, including via an + honest recovery. +- **Control.** Receipts are append-only and hash-chained, and the corpus is published, so an + external copy exists outside the database. Append-only audit events for every transition. +- **Detection.** Chain discontinuity between the restored database and the published corpus. +- **Residual.** Recovery procedure must reconcile against the published corpus, not just restore. + Point-in-time recovery drills have to include that reconciliation. + +### T20: a season nobody can fully claim + +- **Attack.** Not an attack so much as a self-inflicted one, which is why it is easy to miss. The + reward caps in `SeasonRewardDistributor` are enforced *per claim*, first come first served. Open a + season whose total exceeds its season cap, or whose distributor is underfunded, and early claimants + are paid in full while the last ones get a revert they did nothing to earn. An entitlement above + the per-wallet cap is worse: that wallet can never claim at all, and finds out only by trying. +- **Control.** `boundsViolations` refuses to open a season unless every entitlement fits the + per-wallet cap, the total fits the season cap, and the distributor already holds the full amount. + All three are checked before the root is posted, where the answer is still "do not open + this season" rather than "some people lost". The check is pure, so candidate caps can be tested + before any of them are committed to. +- **Detection.** Refusal at open time, with every failing reason reported at once. After opening, + a claim reverting with `ExceedsSeasonCap` means this check was bypassed. +- **Residual.** The caps still protect against a *bad* root, which is their real job; this control + only stops a *correct* season from being opened in an unpayable state. A distributor drained by + some other means after opening reintroduces the same race, so the balance is a precondition rather + than a guarantee. + +## 4. Invariants + +These are the properties tests and alerts exist to defend. Any one of them breaking is an incident, +not a bug report. + +1. A `BattleCommitment` is signed and returned to the player before its committed drand round + publishes. +2. The committed round is never substituted. Retry the same round or forfeit. +3. A battle that reaches `committed` always resolves. `rejected` exists only before `committed`. +4. The snapshot is persisted before any randomness for that battle exists. +5. The seed is derived only from the committed beacon value under the §E derivation. Never from + timestamps, uuids, or backend secrets. +6. A receipt is signed only when the TypeScript engine and the Go verifier agree exactly. +7. Every receipt links its predecessor in the global chain and in both per-pet chains. +8. One `battleId` has at most one signed commitment and at most one signed receipt. A conflicting + payload is an alert, never an upsert. +9. The signer accepts only commitment and receipt schemas, and holds no asset authority. +10. Off-chain XP is never represented as NFT state unless a successful aggregate claim applied it + on-chain. + +## 5. Accepted residual risk + +Stated plainly, because §9 of Part 1 commits to stating it plainly. + +- **A stolen signing key can sign lies.** Bounded by key isolation, schema restriction, reward caps, + and the runbook. Not eliminated. +- **We can refuse to publish.** The chains make it visible, not impossible. +- **The receipt proves what we published, not that we were honest.** Public replay is the control, + and it only works if replay actually happens. +- **The Go verifier does not constrain us**, only our deploys. + +## 6. Escalation threshold + +This design is proportionate while battle outcomes drive progression and capped, aggregate season +rewards. It stops being proportionate when a single battle's outcome carries significant transferable +value, or when reward caps have to be raised beyond what we would accept losing to a key compromise. + +At that point the next steps are §M's deferred options: per-battle backend signature verified +on-chain (Phase 3.5), optimistic settlement with bonded challenges, or proof-based settlement. That +threshold should be crossed deliberately, with a review, not drifted past by raising caps one +increment at a time. + +--- + +# Appendix B: operations runbook + +Operating the backend battle mode specified above. Covers the drills §L Phase 3 requires +before the mode carries anything of value: recovery, replay, key rotation, and incident +response. Key compromise has its own procedure in Appendix C; this one is for everything +short of that. + +## The drills are tests, not a checklist + +Each drill below is executed by `backend/tests/features/battle-ledger/drills.test.ts`, so it +runs on every CI pass rather than being performed once and slowly becoming untrue. A drill +that only ever lived in this file would describe a system nobody had checked in months. + +What the tests cannot cover is the human half — who gets paged, who decides, how long it +takes. That is what the procedures here are for. + +## Turning the mode on and off + +`BATTLE_BACKEND_MODE_ENABLED=true` enables it. Off by default. + +| Off | On | +| --- | --- | +| `POST /api/battle/intents`, `/accept`, `/authorizations` return **503** | accepted | +| `DELETE /api/battle/authorizations` still works | works | +| every read route and `/api/receipts/*` still works | works | +| the outbox worker does not start | runs | +| no signing key required | required | + +**Switching the mode off does not retract anything.** Receipts already issued stay served, +and the public corpus stays public. That asymmetry is the point: §H's claim is that anyone +can check what we did, and a feature flag that could un-publish past evidence would turn +every issued receipt into an assertion. Turning the mode off stops new battles only. + +Revocation is ungated for the same class of reason — refusing battles is never the +dangerous direction, so a defender must be able to withdraw consent even after the mode is +off. + +### Kill switch + +Set `BATTLE_BACKEND_MODE_ENABLED=false` and restart. Battles already in flight stop +advancing (the worker is gone) and stay in whatever state they reached; they resume when +the mode is turned back on, because state lives in the ledger rather than in the worker. +Pets stay locked in the meantime — see *Stuck battles* below if that window is long. + +## Drill 1: recovery + +**Scenario.** A dependency failed long enough that outbox messages exhausted their retries +and dead-lettered. Battles are parked mid-pipeline. + +Dead-lettering is deliberately not automatic-retry exhaustion to be undone by a cron. It +parks the battle for a person, because a message that failed eight times with exponential +backoff is usually failing for a reason that retrying will not fix. + +**Procedure.** + +1. List what is parked: `listDeadLetters()`. Each entry names the `battleId`, the `topic` + it died on, and `lastError`. +2. Group by `lastError`. One shared cause (drand unreachable, indexer-go down, signer + unconfigured) is the common case and means one fix. +3. Fix the cause. Confirm it is actually fixed before requeuing — a requeue against a still + broken dependency just burns the retry budget again. +4. Requeue each message: `requeueDeadLetter(id, new Date())`. Attempts reset so backoff + starts fresh. `lastError` is deliberately left in place; a requeue is not evidence the + cause is gone. +5. Watch the battles advance. Anything that dead-letters a second time on the same error is + not a transient failure and needs the incident procedure below. + +**What is safe about this.** Requeuing cannot double-apply anything. Every worker is +idempotent on its own transition — each checks the battle's current state and completes the +message as a no-op if another worker already moved it — so a message that actually +succeeded before dying is harmless to run again. + +## Drill 2: replay + +**Scenario.** Confirming that receipts this deployment issued verify independently. Run +routinely, not only during an incident: the value of a receipt is that someone outside can +check it, and a claim nobody has ever tested is not worth much. + +**Procedure.** + +1. Export a corpus: `GET /api/receipts?signingKeyId=` and page through `nextAfter`. +2. Fetch the published keys: `GET /api/battle/signing-keys`. +3. Run the standalone verifier over them, from a checkout with no access to this backend: + ```bash + pnpm --filter @cryptopets/verifier cli -- ./corpus.json --keys ./keys.json + ``` +4. Every check must pass and the exit code must be `0`. + +The verifier holds its own pinned ruleset bundles, so this works with the backend entirely +unreachable — which is the situation the drill is really rehearsing. + +**If it fails.** A failing check is not automatically our fault: confirm the corpus and key +list were fetched completely and that the ruleset the receipts name is one the verifier +holds (`ruleset-unavailable` means it is not). A genuine `combat-replay`, +`beacon-signature`, or `operator-signature` failure is an incident — go to Drill 4. + +## Drill 3: key rotation + +**Scenario.** Routine rotation, or a key approaching the end of its validity window. For a +*compromised* key, stop and use Appendix C instead. + +**Procedure.** + +1. Provision the new key in the KMS. It never leaves the KMS; the backend holds a reference. +2. Register the outgoing key as rotated: `registerRotatedKey(descriptor)` with `notAfter` + set. It stays published from `GET /api/battle/signing-keys` permanently. +3. Point the signer at the new key and restart. +4. Confirm `GET /api/battle/signing-keys` lists **both**, and that a receipt signed under + the old key still verifies. + +**The rule that matters.** A retired key is never removed from the published list. Receipts +signed under it must keep verifying forever, and delisting a key silently invalidates every +receipt it ever signed — a retroactive erasure of evidence, which is exactly what §G's +validity windows exist to make unnecessary. + +**Durability.** The registry is persisted in `battle_signing_key` and reloaded at startup, so +a rotated key keeps being published across restarts and deploys. Two properties are worth +knowing during an incident: + +- Any key that is not the one currently signing is reported as **rotated**, whatever the row + says. Swapping keys without calling `registerRotatedKey` still leaves the old key + published — the safe direction to fail in. +- **`compromised` is sticky.** Once a key is marked compromised it stays marked, and is never + reported active again, even if configuration points back at it. "This key may have signed + things we did not authorise" is a fact about history that a restart must not quietly + downgrade to a routine rotation. + +If `registerRotatedKey` logs a persistence failure, the key is published by the running +process but will not survive a restart. Re-run it once the database is reachable; it is +idempotent. + +## Drill 4: incident + +### Engine mismatch (`verification_failed`) + +The TypeScript engine and the Go verifier disagreed, so the battle was never signed. This is +the circuit breaker doing its job. + +1. **Do not sign it.** There is no override, deliberately: signing something two engines + disagree about is the one action that cannot be walked back. +2. Read `verificationDetail` on the ledger row. It holds both outputs and the field-level + mismatches. +3. Reproduce offline from the receipt's inputs — the snapshot, seed, and ruleset are all in + the row. +4. Whichever port is wrong, fix that port and rerun the golden vectors. **Never edit the + vectors** (`AGENTS.md`). +5. Affected battles stay `verification_failed`. They are not retried into existence; the + honest outcome is that the fight did not resolve. + +### Shadow mismatch + +Shadow mode (§L Phase 2) says the backend engine disagreed with the chain. Same substance as +above, with a stronger signal: the chain is the reference implementation. Blocks the Phase 3 +gate until resolved. `shadowSummary()` is the durable record. + +### Stuck battles + +A battle not advancing is one of: a dead letter (Drill 1), a committed drand round that has +not published (waits, then forfeits — by design), or a worker that is not running (check the +mode flag). + +Both pets stay locked until the battle reaches `signed` or a terminal state. If a battle is +genuinely unresolvable, moving it to a terminal state is what releases them; leaving it +pending indefinitely is worse for the player than a forfeit. + +### Drand outage + +Committed rounds are never substituted — §E allows only "keep waiting" or "give up". An +outage past `BATTLE_FORFEIT_AFTER_SECONDS` forfeits affected battles, with no progression +change. If an outage is ongoing, turn the mode off rather than let battles accumulate +toward mass forfeiture. + +## Drill 5: opening a reward season + +**Scenario.** A season's battles are anchored and it is time to pay out. This is the only +procedure here that moves real value, so it is the one worth rehearsing on a testnet first. + +**Procedure.** + +1. Confirm the receipts are **anchored**, not merely signed. `buildSeason` only counts + anchored receipts, but check the batch backlog is drained rather than discovering a + short season afterwards. +2. Build the season: sequence range, distributor address, token, and rates. The season is + written with its rates and range so anyone can recompute the root from the public corpus. +3. Fund the distributor with at least the season total. +4. Choose caps and dry-run them with `boundsViolations` before committing to any. It is + pure, so this costs nothing and answers "would this season open" directly. +5. `openSeasonOnChain`. It refuses unless every entitlement fits the per-wallet cap, the + total fits the season cap, and the distributor already holds the full amount — and + reports every failing reason at once rather than one transaction at a time. +6. Spot-check a claim proof against the on-chain root before announcing anything. + +**The rule that matters.** Caps are enforced per claim, first come first served. A season +opened over its cap, or underfunded, pays whoever claims first and reverts on whoever claims +last (threat T20). That is why the bound is checked *before* the root is posted: afterwards, +the season is immutable and the only remedy is a second season making people whole. + +**Sweeping.** `sweepUnclaimed` only works after the claim window closes, so it cannot be +used to pull funds out from under people still entitled to them. + +## Drill 6: a bad season root + +**Scenario.** A season was opened with wrong entitlements. + +1. **Pause the distributor.** This stops claims without touching battles — the registry and + the battle path are separate contracts precisely so one can be halted without the other. +2. Work out who was overpaid before the pause. Claims are events; the nullifier mapping says + who has claimed. +3. **The season cannot be corrected in place.** `openSeason` refuses to reopen a season, and + that refusal is deliberate: a rewritable root would let entitlements change after people + had read them. The remedy is a new season that makes the difference up. +4. Unpause once the replacement is ready, or leave paused and sweep after the window if the + season is being abandoned entirely. + +**Note on the owner key.** The distributor owner can open seasons, pause, and sweep after +close. It cannot rewrite an open season, mint, or take funds mid-window. That is the blast +radius to assume if the key is compromised — and it is why the owner should be a multisig +behind a timelock (§I) rather than a hot wallet. + +## What this mode deliberately does not do + +- **No reward inside a receipt.** Receipts carry no `rewardDelta` at any setting, and they + never will — rewards are computed *from* anchored receipts into a separate season tree, so + a receipt stays a statement about a fight rather than a promise of payment. Nothing pays + out until a season is deliberately built, funded, bounded, and opened (Drill 5). +- **No rating.** There is no rating or matchmaking-score system in this repo yet. §L Phase 3 + lists "off-chain XP, rating, and cooldown"; XP and cooldown exist in `pet_battle_progress`, + stored separately from NFT state. Rating is a game-design decision — what it measures, how + it decays, whether it is public — and is not something to invent as a side effect of + shipping this mode. +- **No NFT mutation.** Backend battles never write pet state on chain. Off-chain progression + lives in `pet_battle_progress`, keyed separately from `pet_roster`, so the two can never be + confused for each other. + +--- + +# Appendix C: signing key compromise runbook + +Applies to the KMS keys that sign `BattleCommitment` and `BattleReceipt` objects, and to the +root publisher key that anchors Merkle batches. See Appendix A, T4 and T16. + +Assume compromise means an attacker can produce signatures that verify against a published key. It +does not mean they can move assets: the battle signing key has no custody and no withdrawal +authority, and the root publisher sits behind multisig and timelock. That is what buys time here. + +**Bias towards pausing.** A false alarm costs players a few hours of battles. A missed compromise +costs the integrity of every receipt signed in the window. + +## Triggers + +Any one of these starts this runbook. Do not wait for confirmation of intent. + +- KMS audit log shows a signing request the pipeline cannot account for (no matching ledger row, no + matching digest). +- Signer throughput outside expected range, or signing requests from an unexpected principal, + network path, or region. +- A receipt or commitment exists in the public corpus with no corresponding ledger row. +- Hash-chain fork: two signed receipts claiming the same `previousReceiptHash`, or two commitments for + one `battleId`. +- A player produces a signed commitment or receipt we did not issue. +- Credential exposure: KMS principal credentials in a log, repo, image, or CI artifact. +- Cloud provider or KMS vendor notifies us of key or account compromise. + +## Roles + +| Role | Owns | +|---|---| +| Incident lead | Declares the incident, owns the timeline, makes the pause call | +| Signer owner | KMS policy changes, key disable, rotation | +| Chain owner | Root registry pause, multisig coordination | +| Verifier owner | Corpus re-verification, fork analysis | +| Comms owner | Player-facing status, disclosure | + +One person may hold several roles. The pause call is never blocked on availability: if the incident +lead is unreachable, the signer owner pauses. + +## Phase 1: contain (target: 15 minutes) + +Order matters. Stop the bleeding on-chain first, because that is the only irreversible surface. + +1. **Pause the on-chain surfaces.** Emergency pause on the root registry and the claim contract. No + new roots accepted, no claims processed. This is the only step that prevents economic loss. +2. **Disable the suspect key in KMS.** Deny all signing operations on that key version. Do not delete + the key and do not delete its public record, which is needed for later verification. +3. **Stop receipt signing.** Trip the signer circuit breaker. Battles already `committed` stay in + `verified` and are not lost. Battle acceptance also stops, since acceptance requires a signed + commitment and an unsigned acceptance would break invariant 1. +4. **Snapshot evidence.** KMS audit logs, signer access logs, ledger tables, published corpus, and + the current chain tips of all three receipt chains. Copy to write-once storage before anything is + rotated or restored. +5. **Freeze deploys.** No code or infrastructure changes to the signer path until Phase 4. +6. **Declare the incident** and record the suspected compromise window opening time. When unknown, + use the earliest plausible time, not the most convenient one. + +## Phase 2: assess (target: 4 hours) + +Establish the compromise window and what was signed inside it. + +1. **Reconcile KMS to ledger.** For every signing request in the window, match the digest to a ledger + row. Unmatched digests are forged-signature candidates and define the real window. +2. **Reconcile corpus to ledger.** Every published receipt and commitment must have a ledger row with + the same payload. Extra corpus entries mean forged artifacts were served. +3. **Run the verifier over the window.** `verifier` over the affected sequence range. Failures split + into: signature invalid, beacon invalid, replay mismatch, chain discontinuity. Replay mismatch on + an otherwise valid signature is the strongest evidence of forgery, because our pipeline cannot + produce it. +4. **Walk the chains.** Global chain and the per-pet chains for every pet touched in the window. Note + every fork point and both branches. A fork with two valid signatures is provable equivocation and + must be preserved exactly as found. +5. **Check batches.** Which anchored roots include window receipts. Which of those had claims against + them. Compute worst-case economic exposure against the caps. +6. **Classify.** Confirmed compromise, suspected, or false alarm. A false alarm exits at Phase 4 with + the pause lifted and a post-incident note. Do not skip Phase 4. + +## Phase 3: rotate and recover + +Only after the window is bounded. + +1. **Generate a new key** in a fresh KMS key with a new `signingKeyId`. New credentials, new + principal, minimal network path. Never reuse the old principal. +2. **Publish the key registry update.** New key with its `notBefore`. Old key marked compromised with + its validity end set to the window opening time, and **retained**, because historical receipts + still verify against it. Never remove a rotated-out key from the registry. +3. **Publish the compromise window** as a first-class record: `signingKeyId`, window start and end, + affected sequence ranges, and the list of receipts we attest to as pipeline-produced. Players and + third-party verifiers need this to interpret their own copies. +4. **Do not re-sign history under the new key.** Re-signing changes nothing about what happened and + destroys the evidence trail. Instead publish an attestation list: the receipt hashes we confirm + our pipeline produced, signed with the new key. Verifiers then treat an in-window receipt as valid + only if it appears in the attestation list. +5. **Do not renumber sequences.** Gaps and forks stay visible. Continue the chain from the last + attested receipt, recording the discontinuity explicitly. +6. **Handle in-flight battles.** Battles in `verified` at pause time resolve normally under the new + key. Battles in `committed` whose round has published resolve normally. Battles whose committed + round has passed the beacon timeout become `forfeited` with no progression change. +7. **Reverse or freeze bad claims.** Claims against forged inclusion stay paused. Nullifiers already + consumed cannot be reused, so genuine claimants inside a poisoned batch need a re-issued batch + under a new root rather than a retry. +8. **Lift the pauses** in the reverse of Phase 1: signer, then acceptance, then root registry, then + claims. Claims last, because they are the only irreversible surface. + +## Phase 4: post-incident + +- Timeline with detection latency, containment latency, and every decision point. +- Which detection fired, and which should have fired first. If detection came from a player, that is + the headline finding. +- Whether reward caps bounded the exposure as designed. If not, lower the caps before resuming. +- Whether the escalation threshold in Appendix A §6 has been reached. +- Public disclosure: what was signed, what was attested, what players should check themselves. The + design's entire premise is that we publish our homework, so a compromise is disclosed with the same + detail we would want if we were the player. + +## Never do these + +- Delete or unpublish an old public key. Historical verification depends on it. +- Delete a forged receipt from the corpus without recording it. The fork is the evidence. +- Re-sign or rewrite historical receipts under the new key. +- Renumber sequences or repair a chain by regenerating links. +- Substitute a different drand round for an unresolved battle, even to clear the queue. That breaks + invariant 2 and is exactly the behaviour T1 is designed to make impossible. +- Restore Postgres to a point before the published corpus without reconciling against it (T19). + +## Drill + +Run this as a live drill in Phase 3, before anything of value is at stake. The drill must +cover: pause, key disable, evidence snapshot, corpus reconciliation, +verifier run over a range, rotation with registry publication, attestation-list publication, and +resumption. Record the wall-clock time of each phase and correct the targets above to what the drill +actually achieves. diff --git a/docs/plan-backend-battle-steps.md b/docs/plan-backend-battle-steps.md deleted file mode 100644 index 3e402e77..00000000 --- a/docs/plan-backend-battle-steps.md +++ /dev/null @@ -1,404 +0,0 @@ -# Backend-authoritative battle: implementation steps - -Companion to [plan-backend-battle-architecture.md](./plan-backend-battle-architecture.md). That -document says what to build and why. This one splits it into commit-sized steps. - -Section references (§A, §E, §L) point at the architecture document. - -## How this runs - -- **One step, one commit.** Every step below is scoped so it can land on its own without breaking - the repo. If a step turns out to need two commits, split it and keep the numbering. -- **Every step has a verification command.** "Done" means that command passes, not that the code - looks right. -- **Branch per step group** (`feat/protocol-package`, `feat/battle-ledger`, ...), not per step. -- Steps 1 to 14 have no dependency on backend or chain work, so they can proceed while the - Phase 1 decisions in §L are still being settled. - -## Settled decisions - -Recorded here so later steps stop re-litigating them. - -| Decision | Choice | Where it came from | -|---|---|---| -| Canonical protocol code home | New MIT top-level `protocol/` package | §K licensing constraint | -| Public verifier home | New MIT top-level `verifier/` package (TypeScript CLI) | §H, §K | -| TS combat engine | Moves from `shared/src/utils/combat/` into `protocol/`, re-exported from `shared` | Verifier must replay combat and must be MIT | -| Randomness beacon | drand quicknet, 3s rounds, fixed offset of 2 rounds | §E latency budget | -| First reward chain | EVM only; Solana after EVM operations are stable | §I, §L Phase 5 | - -Open, and deliberately not blocking steps 1 to 14: exact reward economics (§I caps), whether -Phase 3.5 becomes the end state, and the KMS provider. - ---- - -## Group A: specification and licensing (§L Phase 1) - -### Step 1: threat model and key-compromise runbook -- Scope: write the threat model as its own document (the §J threat list expanded into attacker, - capability, control, detection, residual risk), plus the runbook for a suspected signing-key - compromise (pause roots, rotate key, republish key registry, re-verify affected receipts). -- Files: `docs/threat-model-backend-battles.md`, `docs/runbook-signing-key-compromise.md`. -- Verify: no command. Review only. -- Commit: `docs: add backend battle threat model and key-compromise runbook` - -### Step 2: reconcile the roadmap with backend combat -- Scope: the §K "update on acceptance" list. Team battles become backend orchestration over a - versioned ruleset, drop the "inherently low risk" claim, restate equipment guidance, mark the - settle keeper legacy for battle execution, correct stale dual-indexer text. -- Files: `docs/plan-future-features-roadmap.md`. -- Verify: no command. Review only. -- Commit: `docs: align future-features roadmap with backend-authoritative battles` - ---- - -## Group B: the `protocol/` package (§F, §G, build order 1 and 5) - -### Step 3: scaffold the MIT protocol package -- Scope: `@cryptopets/protocol` workspace package, MIT `LICENSE`, README stating the package is - intentionally MIT because outsiders run the verifier against it. tsconfig, vitest, eslint config - mirroring `shared`. Consumed as raw TypeScript, same as `shared` (no build step). -- Files: `protocol/{package.json,tsconfig.json,vitest.config.ts,eslint.config.js,LICENSE,README.md}`, - `protocol/src/index.ts`, `pnpm-workspace.yaml`, root `package.json` lint/test aggregates. -- Verify: `pnpm --filter @cryptopets/protocol test && pnpm --filter @cryptopets/protocol lint` -- Commit: `chore(protocol): scaffold MIT protocol package` - -### Step 4: move the combat engine into `protocol/` -- Scope: move `shared/src/utils/combat/*` to `protocol/src/combat/`, and its golden-vector test to - `protocol/tests/combat/`. `shared/src/utils/combat/index.ts` becomes a re-export so no frontend, - mobile, or backend import changes. Relicensing note in the package README. -- Files: `protocol/src/combat/*`, `protocol/tests/combat/goldenVectors.test.ts`, - `shared/src/utils/combat/index.ts`, `shared/package.json` (dependency on `@cryptopets/protocol`). -- Verify: `pnpm --filter @cryptopets/protocol test && pnpm --filter @shared/core test && pnpm --filter frontend build` -- Commit: `refactor(protocol): move TS combat engine out of shared into MIT protocol package` - -### Step 5: canonical encoding primitives -- Scope: the fixed binary encoder every hash in this design depends on. Length-prefixed fields, - explicit integer widths, no JSON. Domain-tag helper, keccak-256 wrapper (legacy Keccak, matching - the existing simulator hashing), hex and bigint rules. This is the step everything downstream - inherits its determinism from, so it gets its own tests. -- Files: `protocol/src/encoding/{writer.ts,hash.ts,domain.ts,index.ts}`, - `protocol/tests/encoding/*.test.ts`. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add canonical binary encoding and keccak hashing primitives` - -### Step 6: deployment and schema-version binding -- Scope: `chainId` plus `deploymentId` binding used by every signed object (§D), and the schema - version registry so a version bump is a code change, not a magic number at a call site. -- Files: `protocol/src/domain/{deployment.ts,schemaVersions.ts}`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): bind signed objects to chainId and deploymentId` - -### Step 7: battle intent -- Scope: `BattleIntent` type, canonical hash, EIP-712 typed data for EVM wallets, domain-separated - sign-message format for Solana. Expiry and nonce fields, no verification logic yet (that is - backend, Step 18). -- Files: `protocol/src/intent/*`, `contracts/test-vectors/protocol-intent.json`, - `protocol/tests/intent/*.test.ts`. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add wallet-signed battle intent schema and hashing` - -### Step 8: standing defence authorization -- Scope: `DefenseAuthorization` type (§D), canonical hash, EIP-712 and Solana formats, - `revocationNonce` semantics. Consent is bound to `rulesetHash`. -- Files: `protocol/src/consent/*`, `contracts/test-vectors/protocol-consent.json`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add standing defense-authorization schema and hashing` - -### Step 9: pet snapshot -- Scope: the "photo" (§C, §F). Frozen pet fields plus `lastOpponentId` and `streak`, so progression - is a pure function of the receipt's own inputs. `snapshotHash` over both pets. Equipment slots - present but empty until equipment ships. -- Files: `protocol/src/snapshot/*`, `contracts/test-vectors/protocol-snapshot.json`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add frozen pet snapshot schema and snapshot hashing` - -### Step 10: seed derivation -- Scope: the §E derivation exactly as specified, domain-separated over chainId, deploymentId, drand - randomness, battleId, snapshotHash, rulesetHash. Golden vectors, including one recorded real - quicknet beacon value. -- Files: `protocol/src/randomness/seed.ts`, `contracts/test-vectors/protocol-seed.json`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): derive battle seed from drand randomness with domain separation` - -### Step 11: drand beacon verification -- Scope: pinned quicknet chain hash and public key, BLS12-381 signature verification over - `@noble/curves`, round-to-time and time-to-round helpers, the fixed offset constant. Pure - verification, no network client (that is Step 20). Record the bundle-size cost in the README, as - §E requires. -- Files: `protocol/src/randomness/{drand.ts,beacon.ts}`, fixtures of real quicknet rounds, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): verify drand quicknet BLS beacon signatures against a pinned key` - -### Step 12: battle commitment -- Scope: `BattleCommitment` type (§E), canonical hash, `previousCommitmentHash` chain link, and a - chain-continuity checker. No signing here. -- Files: `protocol/src/commitment/*`, `contracts/test-vectors/protocol-commitment.json`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add battle commitment schema, hashing, and chain link` - -### Step 13: XP and progression port -- Scope: build order step 5, and the §F workstream. Port `services/indexer-go/internal/combat/xp.go` to - `protocol/src/combat/xp.ts`, reading streak state from the snapshot rather than chain state. - Produce a `progressionDelta` (xp, level, streak, rating inputs) as a pure function. -- Files: `protocol/src/combat/xp.ts`, `contracts/test-vectors/protocol-progression.json`, - `protocol/tests/combat/xp.test.ts` (runs the existing `contracts/test-vectors/xp.json` too). -- Verify: `pnpm --filter @cryptopets/protocol test` and `cd services/indexer-go && go test ./internal/combat` -- Commit: `feat(protocol): port XP and progression math to TypeScript with golden vectors` - -### Step 14: ruleset versioning -- Scope: `rulesetVersion` and `rulesetHash` over the combat config and skill/balance configuration, - plus the content-addressed ruleset bundle format §H requires for historical replay. -- Files: `protocol/src/ruleset/*`, `contracts/test-vectors/protocol-ruleset.json`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add content-addressed ruleset versioning and hashing` - -### Step 15: battle receipt -- Scope: `BattleReceipt` type (§G) with all three hash links, canonical hash, combat-log hash, and - the chain-continuity checkers for the global chain and both per-pet chains. -- Files: `protocol/src/receipt/*`, `contracts/test-vectors/protocol-receipt.json`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add signed battle receipt schema, hashing, and hash chains` - -### Step 16: Merkle leaves and proofs -- Scope: canonical Merkle leaf encoding for a receipt, tree construction, proof generation and - verification, matching whatever the EVM registry will accept (Step 33). Vectors so Solidity and - TypeScript cannot drift. -- Files: `protocol/src/merkle/*`, `contracts/test-vectors/protocol-merkle.json`, tests. -- Verify: `pnpm --filter @cryptopets/protocol test` -- Commit: `feat(protocol): add canonical Merkle leaf encoding, proofs, and vectors` - ---- - -## Group C: backend ledger and intent (§J, build order 2 and 3) - -### Step 17: Prisma models and migration -- Scope: the §J models. `BattleIntent`, `DefenseAuthorization`, `BattleLedger`, `BattleCommitment`, - `BattleReceipt`, `BattleBatch`, `BattleRuleset`, `PetBattleProgress`, `BattleOutbox`. Unique - constraint on the wallet idempotency nonce. `BattleHistory` is untouched, since the on-chain path - keeps running. -- Files: `backend/prisma/schema.prisma`, `backend/prisma/migrations/*`. -- Verify: `pnpm --filter backend build` and a migration applied against a scratch database. -- Commit: `feat(backend): add battle ledger, commitment, receipt, and progress models` - -### Step 18: ledger state machine -- Scope: the §J transition table as code, with every transition idempotent and each one writing its - outbox message in the same transaction. Deterministic pet lock ordering. No HTTP surface yet. -- Files: `backend/src/features/battle-ledger/{state.ts,transitions.ts,outbox.ts,index.ts}`, tests. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): add transactional battle ledger state machine and outbox` - -### Step 19: signed intent submission -- Scope: verify an EIP-712 or Solana-signed `BattleIntent`, check finalized attacker ownership, - consume the nonce, reject expiry and cross-deployment replay, create the ledger row in `accepted`. - A JWT can carry the request but never authorizes another wallet's battle. -- Files: `backend/src/features/battle-ledger/intent.service.ts`, `backend/src/routes/battle.ts`, - tests. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): accept wallet-signed battle intents` - -### Step 20: standing defender consent -- Scope: store, verify, and revoke `DefenseAuthorization`. Level band, daily battle cap, immediate - revocation with its timestamp available to receipts. -- Files: `backend/src/features/battle-ledger/consent.service.ts`, routes, tests. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): add standing defender consent with immediate revocation` - ---- - -## Group D: randomness, signing, execution (build order 4, 6, 7) - -### Step 21: drand client -- Scope: fetch quicknet rounds, verify with the `protocol/` verifier, cache verified rounds, retry - the same committed round indefinitely (§E), never substitute a known round. Metrics for fetch - delay. -- Files: `backend/src/features/battle-randomness/*`, tests with a stubbed HTTP transport. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): add verified drand quicknet round client with same-round retry` - -### Step 22: isolated signer -- Scope: signer interface accepting only the exact commitment and receipt schemas, digest-only - signing, KMS adapter plus a local dev adapter, key registry with validity periods including - rotated-out keys. No generic signing endpoint, ever. -- Files: `backend/src/features/battle-signer/*`, tests. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): add schema-restricted KMS signer for commitments and receipts` - -### Step 23: accept flow, snapshot and commitment delivery -- Scope: the one ordering that can never be relaxed. On acceptance: snapshot both pets, pick - `currentRound + 2`, persist, sign the `BattleCommitment`, and return it synchronously in the accept - response. Alert when accept succeeds but commitment delivery fails. -- Files: `backend/src/features/battle-ledger/accept.service.ts`, integration test asserting the - commitment is signed and returned before the committed round exists. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): sign and deliver battle commitment before the drand round publishes` - -### Step 24: seeded and computed worker -- Scope: worker driving `committed` to `seeded` to `computed`. Verify the beacon, derive the seed, - run `protocol/` combat plus progression, persist the combat log and its hash. -- Files: `backend/src/features/battle-worker/*`, tests. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): compute battles from verified drand seeds in a worker` - -### Step 25: independent Go verification -- Scope: §F release safety. `indexer-go` gains a snapshot-shaped verify entry point over its - existing combat and xp packages, exposed to the backend. Mismatch on winner, rounds, winner HP, - progression delta, or combat-log hash stops signing for that ruleset, alerts, and retains both - outputs. Never silently prefer one implementation. -- Files: `services/indexer-go/internal/combat/verify.go`, `services/indexer-go/internal/grpcsrv/*` (or an HTTP - endpoint), `proto/cryptopets.proto` if gRPC, `backend/src/features/battle-worker/verify.ts`. -- Verify: `cd services/indexer-go && go vet ./... && go test ./internal/combat` and `pnpm --filter backend test` -- Commit: `feat(indexer-go): verify backend battle results independently before signing` - -### Step 26: sign the receipt and append the hash chains -- Scope: `verified` to `signed` to `published`. Append to the global chain and both per-pet chains - inside one transaction, update `PetBattleProgress`. A duplicate battle id with a different payload - raises a security alert and is never an upsert. -- Files: `backend/src/features/battle-ledger/receipt.service.ts`, tests including a concurrency test. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): sign battle receipts and append global and per-pet hash chains` - ---- - -## Group E: public surfaces (build order 8, 10) - -### Step 27: read APIs -- Scope: battle state by id, signed commitment, signed receipt, combat log, active signing keys, - active rulesets, verify-receipt. Authoritative and re-fetchable, since the WebSocket stops being - trusted in Step 29. -- Files: `backend/src/routes/battle.ts`, `backend/src/graphql/*`, `backend/API.md`, tests. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): expose battle state, commitment, receipt, and key endpoints` - -### Step 28: public receipt corpus -- Scope: paginated export by pet, by wallet, and by sequence range, with no authentication, so - replay needs no special access (§H item 3). -- Files: `backend/src/routes/receipts.ts`, tests. -- Verify: `pnpm --filter backend test` -- Commit: `feat(backend): publish a paginated public receipt corpus` - -### Step 29: scope the WebSocket per room -- Scope: `backend/src/ws/liveBattleSocket.ts` stops broadcasting globally, since the payload now - carries full combat logs. Subscriptions scope to the existing `BattleRoom`. Notification only, - never authoritative. -- Files: `backend/src/ws/liveBattleSocket.ts`, `backend/src/features/battle-room/*`, frontend and - mobile subscribe calls, tests. -- Verify: `pnpm --filter backend test && pnpm --filter frontend test` -- Commit: `refactor(backend): scope live battle socket per room and make it notification-only` - ---- - -## Group F: the standalone verifier (§H, build order 9) - -### Step 30: scaffold the verifier CLI -- Scope: MIT `verifier/` package depending only on `@cryptopets/protocol`. No backend access, no - database. Reads a receipt file or a corpus URL. Checks operator signature and hash-chain - continuity first, since those need nothing else. -- Files: `verifier/{package.json,tsconfig.json,LICENSE,README.md}`, `verifier/src/*`, - `pnpm-workspace.yaml`. -- Verify: `pnpm --filter @cryptopets/verifier test` -- Commit: `feat(verifier): scaffold standalone MIT receipt verifier CLI` - -### Step 31: full verification checks -- Scope: drand BLS verification, seed derivation, combat replay, progression comparison, per-check - pass or fail output, non-zero exit on any failure. -- Files: `verifier/src/checks/*`, fixtures, tests. -- Verify: `pnpm --filter @cryptopets/verifier test` -- Commit: `feat(verifier): verify beacon, seed, combat replay, and progression` - -### Step 32: pinned ruleset artifacts and CI -- Scope: fetch and pin content-addressed ruleset bundles so historical battles reproduce exactly, - plus a CI job running the verifier over a committed corpus fixture on every PR. -- Files: `verifier/src/ruleset.ts`, `verifier/fixtures/*`, `.github/workflows/verifier.yml`. -- Verify: `pnpm --filter @cryptopets/verifier test` and a green workflow run. -- Commit: `feat(verifier): pin ruleset artifacts and run receipt verification in CI` - ---- - -## Group G: client (§J frontend behavior) - -### Step 33: submit intent and persist the commitment -- Scope: wallet signs the intent, client stores battle id and the signed commitment in local - storage so the player's own evidence survives a reload, subscribes to the room, refetches the - authoritative endpoint after reconnect. -- Files: `shared/src/hooks/*` (new backend battle hook), `frontend/src/*`, tests. -- Verify: `pnpm --filter frontend test && pnpm --filter frontend lint:check` -- Commit: `feat(frontend): submit signed battle intents and persist the signed commitment` - -### Step 34: client-side verification and replay -- Scope: verify the receipt signature, the drand BLS signature against the pinned key, and the hash - links, in the browser. Then replay the combat log and animate. Record the bundle-size delta. -- Files: `frontend/src/*`, `shared/src/hooks/*`, tests. -- Verify: `pnpm --filter frontend test && pnpm --filter frontend build` -- Commit: `feat(frontend): verify battle receipts client-side before replaying the fight` - ---- - -## Group H: shadow mode and launch (§L Phase 2 and 3) - -### Step 35: shadow the on-chain path -- Scope: recompute every settled on-chain battle through the `protocol/` engine and the Go verifier, - compare against `BattleResolved`, record mismatches. On-chain battles keep running unchanged. Stop - condition: zero deterministic mismatch over the agreed observation window. -- Files: `backend/src/features/battle-shadow/*`, metrics, tests. -- Verify: `pnpm --filter backend test`, then the observation window itself. -- Commit: `feat(backend): shadow-compute settled on-chain battles against the backend engine` - -### Step 36: rewardless backend battle mode -- Scope: backend battle mode behind a flag, alongside the on-chain mode. Off-chain XP, rating, and - cooldown stored distinctly from NFT state. Signed commitments and receipts, no transferable - reward. Recovery, replay, key-rotation, and incident drills documented and run. -- Files: `backend/src/features/battle-*`, `backend/env.example`, frontend mode switch, - `docs/runbook-backend-battles.md`. -- Verify: `pnpm --filter backend test && pnpm --filter frontend test` -- Commit: `feat: launch rewardless backend battle mode behind a flag` - ---- - -## Group I: anchoring and rewards (§L Phase 4 to 6) - -Deliberately coarse. Scope these into steps once Group H is operating, because the batch cadence, -caps, and claim shape depend on what shadow mode and the rewardless launch actually show. - -### Step 37: EVM root registry and batcher -- Commit: `feat(contracts): add battle batch root registry` and - `feat(backend): aggregate signed receipts into anchored Merkle batches` - -### Step 38: capped claim contract and proof API -- Commit: `feat(contracts): add capped aggregate reward claims with nullifiers` - -### Step 39: security review, drills, bounded rewards -- Commit: `feat: enable bounded aggregate season rewards` - -### Step 40: retire per-battle settlement and amend the four-port rule -- Scope: only here, at §L Phase 6, do `AGENTS.md` and `CLAUDE.md` change. The four-port combat rule - stays a `MUST` until the legacy on-chain path actually retires. Legacy receipts and events stay - replayable. -- Commit: `docs: retire per-battle settlement and amend the four-port combat rule` -- **Done.** The rule was split rather than relaxed: `CombatSim.sol` and `combat.rs` became - `MUST NOT` change (frozen, so the battles they settled stay replayable), while - `protocol/src/combat/` and `services/indexer-go/internal/combat/` stay `MUST` change together, since - §F's circuit breaker only works while those two are independent. All four golden-vector - suites keep running. The settle keepers stay deployable so in-flight requests can drain - rather than being stranded, and breed/mint still settle on chain — only battles retired. - ---- - -## Dependency map - -```mermaid -flowchart LR - A["1-2 docs"] --> B["3-16 protocol/"] - B --> C["17-20 ledger + intent"] - C --> D["21-26 randomness, signer, execution"] - B --> F["30-32 verifier/"] - D --> E["27-29 public APIs + ws"] - E --> F - D --> G["33-34 client"] - F --> H["35-36 shadow + rewardless launch"] - G --> H - H --> I["37-40 anchoring + rewards"] -``` - -Steps 3 to 16 are the critical path. Nothing else can start until the canonical encodings exist, -because every signature in this design is over one of them. diff --git a/docs/plan-future-features-roadmap.md b/docs/plan-future-features-roadmap.md index 89067f27..09318768 100644 --- a/docs/plan-future-features-roadmap.md +++ b/docs/plan-future-features-roadmap.md @@ -7,8 +7,7 @@ NFTs, agentic AI pets, and ERC20 tokenomics — listed here in the recommended d (see below), which is also the order the sections appear in below. Each section sketches where the feature lands in the existing architecture, what new data model it needs, and the open decisions a human should make before implementation starts. Nothing here is committed to; treat -it as a starting point for per-feature implementation plans in the style of -`plan-realtime-battle-impl.md`. +it as a starting point for per-feature implementation plans. Grounded against the repo as of this writing: `backend/prisma/schema.prisma` (existing `PetRoster`, `BattleHistory`, `BattleRoom`, `BattleDialogue`, `BattleConversation` models), @@ -38,10 +37,10 @@ stay server/backend-computed (leaderboard ranking, quest progress) don't need th give something a TS port if the client actually needs to simulate it before the chain confirms. **Combat authority is moving off-chain, and that reshapes several features below.** -`docs/plan-backend-battle-architecture.md` is the accepted architecture for battle execution: the +`docs/battle-protocol.md` is the accepted architecture for battle execution: the backend resolves fights from a frozen snapshot against a versioned ruleset, seeds them from a -pre-committed drand round, and publishes signed receipts anyone can replay -(`docs/plan-backend-battle-steps.md` sequences the work). Two consequences for this doc. First, a +pre-committed drand round, and publishes signed receipts anyone can replay. Two consequences +for this doc. First, a *new* combat mechanic is built once, in the canonical TypeScript engine (`protocol/src/combat/`, moved out of `shared/src/utils/combat/` into the MIT `protocol` package), with the Go port acting as an independent pre-signing verifier rather than a fourth hand-maintained implementation. @@ -191,7 +190,7 @@ Reading the graph: is itself part of the ruleset hash, and a receipt shape that survives replay. Authorization, snapshots, seed derivation, signer scope, and reward aggregation are all security-sensitive here. Treat this as a feature that inherits the full backend battle threat model - (`docs/threat-model-backend-battles.md`), not as a loop around a proven function. + (`docs/battle-protocol.md` Appendix A), not as a loop around a proven function. - **Inventory is the pivot feature.** It's a parallel asset type to pets (same ownership/indexing pattern), the second thing the marketplace can list besides pets, and the default reward payload for quests. Everything downstream of it moves faster once it exists — see feature 4 @@ -365,7 +364,7 @@ Both indexers are still live: the Node `RosterIndexer` is the source of truth in `indexer-go` is the promotable path, so "dual-indexer" describes the current state, not a leftover. What changes is that `indexer-go` picks up a second, unrelated job under backend-resolved combat: it becomes the independent pre-signing verifier that recomputes every battle result before a receipt is -signed (`docs/plan-backend-battle-steps.md` Step 25). That is a release-safety role, not an indexing +signed (`docs/battle-protocol.md` §F). That is a release-safety role, not an indexing role, and it does not depend on which indexer owns roster writes. Worth knowing before promotion, because an `indexer-go` outage then blocks receipt signing as well as roster freshness, so the two concerns need separate health signals. @@ -373,7 +372,7 @@ concerns need separate health signals. Snapshot inputs are the other connection. Backend battles freeze pet state at acceptance from indexed chain state at a recorded source version, so indexer lag and reorg handling stop being purely cosmetic: a snapshot taken from an unfinalized write is threat T10 in -`docs/threat-model-backend-battles.md`. The confirmation-depth work above is a prerequisite for +`docs/battle-protocol.md` Appendix A. The confirmation-depth work above is a prerequisite for that, not an optional polish item. This feature has little product-design risk — it's operational hardening of a path that already @@ -423,7 +422,7 @@ checkable. So: - Equipment ownership must be verifiable at snapshot time from chain state at a recorded source version, exactly like pet ownership. Backend-only equip state that no third party can confirm turns every geared receipt into an assertion (threat T13 in - `docs/threat-model-backend-battles.md`). + `docs/battle-protocol.md` Appendix A). - The snapshot carries the resolved modifiers, not a reference to a mutable item row. Unequipping after acceptance must not change a committed fight, the same reason pet stats are frozen. - `ItemDefinition.effect` becomes part of the ruleset hash if it feeds combat. A rebalance is then a @@ -824,7 +823,7 @@ a separate explicit decision if ever pursued. **Memory: build it on the per-pet receipt chain, don't invent a second one.** An agentic pet is only interesting if it has continuity, and continuity needs a bounded, ordered view of one pet's -past. [plan-backend-battle-architecture.md](./plan-backend-battle-architecture.md) §G already +past. [battle-protocol.md](./battle-protocol.md) §G already produces exactly that: every battle receipt links to the previous receipt involving that same pet (`attackerProgressPrevReceiptHash` / `defenderProgressPrevReceiptHash`), with `PetBattleProgress` holding the head pointer. Walking that link is the retrieval query this feature needs, already diff --git a/docs/runbook-backend-battles.md b/docs/runbook-backend-battles.md deleted file mode 100644 index 903b5a1c..00000000 --- a/docs/runbook-backend-battles.md +++ /dev/null @@ -1,238 +0,0 @@ -# Runbook: backend-authoritative battles - -Operating the backend battle mode described in -[plan-backend-battle-architecture.md](./plan-backend-battle-architecture.md). Covers the -four drills §L Phase 3 requires before the mode carries anything of value: recovery, replay, -key rotation, and incident response. - -Key compromise has its own runbook: -[runbook-signing-key-compromise.md](./runbook-signing-key-compromise.md). This one is for -everything short of that. - -## The drills are tests, not a checklist - -Each drill below is executed by `backend/tests/features/battle-ledger/drills.test.ts`, so it -runs on every CI pass rather than being performed once and slowly becoming untrue. A drill -that only ever lived in this file would describe a system nobody had checked in months. - -What the tests cannot cover is the human half — who gets paged, who decides, how long it -takes. That is what the procedures here are for. - -## Turning the mode on and off - -`BATTLE_BACKEND_MODE_ENABLED=true` enables it. Off by default. - -| Off | On | -| --- | --- | -| `POST /api/battle/intents`, `/accept`, `/authorizations` return **503** | accepted | -| `DELETE /api/battle/authorizations` still works | works | -| every read route and `/api/receipts/*` still works | works | -| the outbox worker does not start | runs | -| no signing key required | required | - -**Switching the mode off does not retract anything.** Receipts already issued stay served, -and the public corpus stays public. That asymmetry is the point: §H's claim is that anyone -can check what we did, and a feature flag that could un-publish past evidence would turn -every issued receipt into an assertion. Turning the mode off stops new battles only. - -Revocation is ungated for the same class of reason — refusing battles is never the -dangerous direction, so a defender must be able to withdraw consent even after the mode is -off. - -### Kill switch - -Set `BATTLE_BACKEND_MODE_ENABLED=false` and restart. Battles already in flight stop -advancing (the worker is gone) and stay in whatever state they reached; they resume when -the mode is turned back on, because state lives in the ledger rather than in the worker. -Pets stay locked in the meantime — see *Stuck battles* below if that window is long. - -## Drill 1: recovery - -**Scenario.** A dependency failed long enough that outbox messages exhausted their retries -and dead-lettered. Battles are parked mid-pipeline. - -Dead-lettering is deliberately not automatic-retry exhaustion to be undone by a cron. It -parks the battle for a person, because a message that failed eight times with exponential -backoff is usually failing for a reason that retrying will not fix. - -**Procedure.** - -1. List what is parked: `listDeadLetters()`. Each entry names the `battleId`, the `topic` - it died on, and `lastError`. -2. Group by `lastError`. One shared cause (drand unreachable, indexer-go down, signer - unconfigured) is the common case and means one fix. -3. Fix the cause. Confirm it is actually fixed before requeuing — a requeue against a still - broken dependency just burns the retry budget again. -4. Requeue each message: `requeueDeadLetter(id, new Date())`. Attempts reset so backoff - starts fresh. `lastError` is deliberately left in place; a requeue is not evidence the - cause is gone. -5. Watch the battles advance. Anything that dead-letters a second time on the same error is - not a transient failure and needs the incident procedure below. - -**What is safe about this.** Requeuing cannot double-apply anything. Every worker is -idempotent on its own transition — each checks the battle's current state and completes the -message as a no-op if another worker already moved it — so a message that actually -succeeded before dying is harmless to run again. - -## Drill 2: replay - -**Scenario.** Confirming that receipts this deployment issued verify independently. Run -routinely, not only during an incident: the value of a receipt is that someone outside can -check it, and a claim nobody has ever tested is not worth much. - -**Procedure.** - -1. Export a corpus: `GET /api/receipts?signingKeyId=` and page through `nextAfter`. -2. Fetch the published keys: `GET /api/battle/signing-keys`. -3. Run the standalone verifier over them, from a checkout with no access to this backend: - ```bash - pnpm --filter @cryptopets/verifier cli -- ./corpus.json --keys ./keys.json - ``` -4. Every check must pass and the exit code must be `0`. - -The verifier holds its own pinned ruleset bundles, so this works with the backend entirely -unreachable — which is the situation the drill is really rehearsing. - -**If it fails.** A failing check is not automatically our fault: confirm the corpus and key -list were fetched completely and that the ruleset the receipts name is one the verifier -holds (`ruleset-unavailable` means it is not). A genuine `combat-replay`, -`beacon-signature`, or `operator-signature` failure is an incident — go to Drill 4. - -## Drill 3: key rotation - -**Scenario.** Routine rotation, or a key approaching the end of its validity window. For a -*compromised* key, stop and use -[runbook-signing-key-compromise.md](./runbook-signing-key-compromise.md) instead. - -**Procedure.** - -1. Provision the new key in the KMS. It never leaves the KMS; the backend holds a reference. -2. Register the outgoing key as rotated: `registerRotatedKey(descriptor)` with `notAfter` - set. It stays published from `GET /api/battle/signing-keys` permanently. -3. Point the signer at the new key and restart. -4. Confirm `GET /api/battle/signing-keys` lists **both**, and that a receipt signed under - the old key still verifies. - -**The rule that matters.** A retired key is never removed from the published list. Receipts -signed under it must keep verifying forever, and delisting a key silently invalidates every -receipt it ever signed — a retroactive erasure of evidence, which is exactly what §G's -validity windows exist to make unnecessary. - -**Durability.** The registry is persisted in `battle_signing_key` and reloaded at startup, so -a rotated key keeps being published across restarts and deploys. Two properties are worth -knowing during an incident: - -- Any key that is not the one currently signing is reported as **rotated**, whatever the row - says. Swapping keys without calling `registerRotatedKey` still leaves the old key - published — the safe direction to fail in. -- **`compromised` is sticky.** Once a key is marked compromised it stays marked, and is never - reported active again, even if configuration points back at it. "This key may have signed - things we did not authorise" is a fact about history that a restart must not quietly - downgrade to a routine rotation. - -If `registerRotatedKey` logs a persistence failure, the key is published by the running -process but will not survive a restart. Re-run it once the database is reachable; it is -idempotent. - -## Drill 4: incident - -### Engine mismatch (`verification_failed`) - -The TypeScript engine and the Go verifier disagreed, so the battle was never signed. This is -the circuit breaker doing its job. - -1. **Do not sign it.** There is no override, deliberately: signing something two engines - disagree about is the one action that cannot be walked back. -2. Read `verificationDetail` on the ledger row. It holds both outputs and the field-level - mismatches. -3. Reproduce offline from the receipt's inputs — the snapshot, seed, and ruleset are all in - the row. -4. Whichever port is wrong, fix that port and rerun the golden vectors. **Never edit the - vectors** (`AGENTS.md`). -5. Affected battles stay `verification_failed`. They are not retried into existence; the - honest outcome is that the fight did not resolve. - -### Shadow mismatch - -Shadow mode (§L Phase 2) says the backend engine disagreed with the chain. Same substance as -above, with a stronger signal: the chain is the reference implementation. Blocks the Phase 3 -gate until resolved. `shadowSummary()` is the durable record. - -### Stuck battles - -A battle not advancing is one of: a dead letter (Drill 1), a committed drand round that has -not published (waits, then forfeits — by design), or a worker that is not running (check the -mode flag). - -Both pets stay locked until the battle reaches `signed` or a terminal state. If a battle is -genuinely unresolvable, moving it to a terminal state is what releases them; leaving it -pending indefinitely is worse for the player than a forfeit. - -### Drand outage - -Committed rounds are never substituted — §E allows only "keep waiting" or "give up". An -outage past `BATTLE_FORFEIT_AFTER_SECONDS` forfeits affected battles, with no progression -change. If an outage is ongoing, turn the mode off rather than let battles accumulate -toward mass forfeiture. - -## Drill 5: opening a reward season - -**Scenario.** A season's battles are anchored and it is time to pay out. This is the only -procedure here that moves real value, so it is the one worth rehearsing on a testnet first. - -**Procedure.** - -1. Confirm the receipts are **anchored**, not merely signed. `buildSeason` only counts - anchored receipts, but check the batch backlog is drained rather than discovering a - short season afterwards. -2. Build the season: sequence range, distributor address, token, and rates. The season is - written with its rates and range so anyone can recompute the root from the public corpus. -3. Fund the distributor with at least the season total. -4. Choose caps and dry-run them with `boundsViolations` before committing to any. It is - pure, so this costs nothing and answers "would this season open" directly. -5. `openSeasonOnChain`. It refuses unless every entitlement fits the per-wallet cap, the - total fits the season cap, and the distributor already holds the full amount — and - reports every failing reason at once rather than one transaction at a time. -6. Spot-check a claim proof against the on-chain root before announcing anything. - -**The rule that matters.** Caps are enforced per claim, first come first served. A season -opened over its cap, or underfunded, pays whoever claims first and reverts on whoever claims -last (threat T20). That is why the bound is checked *before* the root is posted: afterwards, -the season is immutable and the only remedy is a second season making people whole. - -**Sweeping.** `sweepUnclaimed` only works after the claim window closes, so it cannot be -used to pull funds out from under people still entitled to them. - -## Drill 6: a bad season root - -**Scenario.** A season was opened with wrong entitlements. - -1. **Pause the distributor.** This stops claims without touching battles — the registry and - the battle path are separate contracts precisely so one can be halted without the other. -2. Work out who was overpaid before the pause. Claims are events; the nullifier mapping says - who has claimed. -3. **The season cannot be corrected in place.** `openSeason` refuses to reopen a season, and - that refusal is deliberate: a rewritable root would let entitlements change after people - had read them. The remedy is a new season that makes the difference up. -4. Unpause once the replacement is ready, or leave paused and sweep after the window if the - season is being abandoned entirely. - -**Note on the owner key.** The distributor owner can open seasons, pause, and sweep after -close. It cannot rewrite an open season, mint, or take funds mid-window. That is the blast -radius to assume if the key is compromised — and it is why the owner should be a multisig -behind a timelock (§I) rather than a hot wallet. - -## What this mode deliberately does not do - -- **No reward inside a receipt.** Receipts carry no `rewardDelta` at any setting, and they - never will — rewards are computed *from* anchored receipts into a separate season tree, so - a receipt stays a statement about a fight rather than a promise of payment. Nothing pays - out until a season is deliberately built, funded, bounded, and opened (Drill 5). -- **No rating.** There is no rating or matchmaking-score system in this repo yet. §L Phase 3 - lists "off-chain XP, rating, and cooldown"; XP and cooldown exist in `pet_battle_progress`, - stored separately from NFT state. Rating is a game-design decision — what it measures, how - it decays, whether it is public — and is not something to invent as a side effect of - shipping this mode. -- **No NFT mutation.** Backend battles never write pet state on chain. Off-chain progression - lives in `pet_battle_progress`, keyed separately from `pet_roster`, so the two can never be - confused for each other. diff --git a/docs/runbook-signing-key-compromise.md b/docs/runbook-signing-key-compromise.md deleted file mode 100644 index 5205a15c..00000000 --- a/docs/runbook-signing-key-compromise.md +++ /dev/null @@ -1,134 +0,0 @@ -# Runbook: battle signing key compromise - -Applies to the KMS keys that sign `BattleCommitment` and `BattleReceipt` objects, and to the root -publisher key that anchors Merkle batches. See -[threat-model-backend-battles.md](./threat-model-backend-battles.md) T4 and T16. - -Assume compromise means an attacker can produce signatures that verify against a published key. It -does not mean they can move assets: the battle signing key has no custody and no withdrawal -authority, and the root publisher sits behind multisig and timelock. That is what buys time here. - -**Bias towards pausing.** A false alarm costs players a few hours of battles. A missed compromise -costs the integrity of every receipt signed in the window. - -## Triggers - -Any one of these starts this runbook. Do not wait for confirmation of intent. - -- KMS audit log shows a signing request the pipeline cannot account for (no matching ledger row, no - matching digest). -- Signer throughput outside expected range, or signing requests from an unexpected principal, - network path, or region. -- A receipt or commitment exists in the public corpus with no corresponding ledger row. -- Hash-chain fork: two signed receipts claiming the same `previousReceiptHash`, or two commitments for - one `battleId`. -- A player produces a signed commitment or receipt we did not issue. -- Credential exposure: KMS principal credentials in a log, repo, image, or CI artifact. -- Cloud provider or KMS vendor notifies us of key or account compromise. - -## Roles - -| Role | Owns | -|---|---| -| Incident lead | Declares the incident, owns the timeline, makes the pause call | -| Signer owner | KMS policy changes, key disable, rotation | -| Chain owner | Root registry pause, multisig coordination | -| Verifier owner | Corpus re-verification, fork analysis | -| Comms owner | Player-facing status, disclosure | - -One person may hold several roles. The pause call is never blocked on availability: if the incident -lead is unreachable, the signer owner pauses. - -## Phase 1: contain (target: 15 minutes) - -Order matters. Stop the bleeding on-chain first, because that is the only irreversible surface. - -1. **Pause the on-chain surfaces.** Emergency pause on the root registry and the claim contract. No - new roots accepted, no claims processed. This is the only step that prevents economic loss. -2. **Disable the suspect key in KMS.** Deny all signing operations on that key version. Do not delete - the key and do not delete its public record, which is needed for later verification. -3. **Stop receipt signing.** Trip the signer circuit breaker. Battles already `committed` stay in - `verified` and are not lost. Battle acceptance also stops, since acceptance requires a signed - commitment and an unsigned acceptance would break invariant 1. -4. **Snapshot evidence.** KMS audit logs, signer access logs, ledger tables, published corpus, and - the current chain tips of all three receipt chains. Copy to write-once storage before anything is - rotated or restored. -5. **Freeze deploys.** No code or infrastructure changes to the signer path until Phase 4. -6. **Declare the incident** and record the suspected compromise window opening time. When unknown, - use the earliest plausible time, not the most convenient one. - -## Phase 2: assess (target: 4 hours) - -Establish the compromise window and what was signed inside it. - -1. **Reconcile KMS to ledger.** For every signing request in the window, match the digest to a ledger - row. Unmatched digests are forged-signature candidates and define the real window. -2. **Reconcile corpus to ledger.** Every published receipt and commitment must have a ledger row with - the same payload. Extra corpus entries mean forged artifacts were served. -3. **Run the verifier over the window.** `verifier` over the affected sequence range. Failures split - into: signature invalid, beacon invalid, replay mismatch, chain discontinuity. Replay mismatch on - an otherwise valid signature is the strongest evidence of forgery, because our pipeline cannot - produce it. -4. **Walk the chains.** Global chain and the per-pet chains for every pet touched in the window. Note - every fork point and both branches. A fork with two valid signatures is provable equivocation and - must be preserved exactly as found. -5. **Check batches.** Which anchored roots include window receipts. Which of those had claims against - them. Compute worst-case economic exposure against the caps. -6. **Classify.** Confirmed compromise, suspected, or false alarm. A false alarm exits at Phase 4 with - the pause lifted and a post-incident note. Do not skip Phase 4. - -## Phase 3: rotate and recover - -Only after the window is bounded. - -1. **Generate a new key** in a fresh KMS key with a new `signingKeyId`. New credentials, new - principal, minimal network path. Never reuse the old principal. -2. **Publish the key registry update.** New key with its `notBefore`. Old key marked compromised with - its validity end set to the window opening time, and **retained**, because historical receipts - still verify against it. Never remove a rotated-out key from the registry. -3. **Publish the compromise window** as a first-class record: `signingKeyId`, window start and end, - affected sequence ranges, and the list of receipts we attest to as pipeline-produced. Players and - third-party verifiers need this to interpret their own copies. -4. **Do not re-sign history under the new key.** Re-signing changes nothing about what happened and - destroys the evidence trail. Instead publish an attestation list: the receipt hashes we confirm - our pipeline produced, signed with the new key. Verifiers then treat an in-window receipt as valid - only if it appears in the attestation list. -5. **Do not renumber sequences.** Gaps and forks stay visible. Continue the chain from the last - attested receipt, recording the discontinuity explicitly. -6. **Handle in-flight battles.** Battles in `verified` at pause time resolve normally under the new - key. Battles in `committed` whose round has published resolve normally. Battles whose committed - round has passed the beacon timeout become `forfeited` with no progression change. -7. **Reverse or freeze bad claims.** Claims against forged inclusion stay paused. Nullifiers already - consumed cannot be reused, so genuine claimants inside a poisoned batch need a re-issued batch - under a new root rather than a retry. -8. **Lift the pauses** in the reverse of Phase 1: signer, then acceptance, then root registry, then - claims. Claims last, because they are the only irreversible surface. - -## Phase 4: post-incident - -- Timeline with detection latency, containment latency, and every decision point. -- Which detection fired, and which should have fired first. If detection came from a player, that is - the headline finding. -- Whether reward caps bounded the exposure as designed. If not, lower the caps before resuming. -- Whether the escalation threshold in the threat model §6 has been reached. -- Public disclosure: what was signed, what was attested, what players should check themselves. The - design's entire premise is that we publish our homework, so a compromise is disclosed with the same - detail we would want if we were the player. - -## Never do these - -- Delete or unpublish an old public key. Historical verification depends on it. -- Delete a forged receipt from the corpus without recording it. The fork is the evidence. -- Re-sign or rewrite historical receipts under the new key. -- Renumber sequences or repair a chain by regenerating links. -- Substitute a different drand round for an unresolved battle, even to clear the queue. That breaks - invariant 2 and is exactly the behaviour T1 is designed to make impossible. -- Restore Postgres to a point before the published corpus without reconciling against it (T19). - -## Drill - -Run this as a live drill in Phase 3 of the implementation plan, before anything of value is at stake -(Step 36). The drill must cover: pause, key disable, evidence snapshot, corpus reconciliation, -verifier run over a range, rotation with registry publication, attestation-list publication, and -resumption. Record the wall-clock time of each phase and correct the targets above to what the drill -actually achieves. diff --git a/docs/threat-model-backend-battles.md b/docs/threat-model-backend-battles.md deleted file mode 100644 index 10a3f86c..00000000 --- a/docs/threat-model-backend-battles.md +++ /dev/null @@ -1,291 +0,0 @@ -# Threat model: backend-authoritative battles - -Scope: the design in [plan-backend-battle-architecture.md](./plan-backend-battle-architecture.md). -Step references point at [plan-backend-battle-steps.md](./plan-backend-battle-steps.md). - -This document exists because moving battle resolution off-chain moves it inside our trust boundary. -Section §A of the architecture document states the trust model in one table. This is the expanded -version: who attacks what, what stops them, how we notice, and what is left over. - -It covers the backend battle path only. The existing on-chain path (`GameLogic.sol`, -`settle_battle.rs`) keeps its own properties and is not re-analysed here. - -## 1. Assets - -| Asset | Why it matters | Authority | -|---|---|---| -| Pet and item ownership | Transferable value | Chain | -| Reward custody and claims | Transferable value | Chain | -| Battle signing key | Signs commitments and receipts; forgery source | KMS | -| Root publisher key | Anchors batches on-chain | KMS + multisig | -| Off-chain progression (XP, rating, streak) | Determines rewards and matchmaking | Backend | -| Signed receipt corpus | The evidence players hold against us | Backend, published | -| Commitment sequence | Proves which round each battle was bound to | Backend, delivered to players | - -## 2. Actors - -| Actor | Assumed capability | -|---|---| -| Player | Can sign with their own wallet, replay traffic, script requests, disconnect at will | -| External attacker | Network position, can hit any public endpoint, no keys | -| Insider with database access | Read and write Postgres, no KMS signing scope | -| Insider with signer access | Can request signatures over well-formed commitments and receipts | -| Dishonest operator | Controls all backend processes, both combat implementations, and the database | -| drand network | Assumed honest and live; a threshold of nodes would have to collude to bias a round | - -The dishonest-operator row is the uncomfortable one and it is deliberate. Most controls below do not -stop that actor. They make the actor's lies detectable by anyone holding a commitment or a receipt. - -## 3. Threats - -Each row: what the attacker does, what stops or bounds it, how we notice, what is left. - -### T1: randomness reroll after seeing the value - -- **Attack.** Operator watches drand, computes the result, dislikes it, and claims the battle was - always bound to a later round. Recompute, publish, everything self-consistent. -- **Control.** Commit before reveal (§E). The round is chosen mechanically as - `currentVerifiedRound + 2`, and the signed `BattleCommitment` is returned synchronously in the - accept response, before the round exists (Step 23). -- **Detection.** A reroll needs a second signature over the same `battleId`. Either player's stored - commitment plus the published receipt is a provable equivocation. -- **Residual.** Only detectable if players keep their commitment. The client persists it to local - storage (Step 33) and the endpoint serves it, but a player who never fetched it holds no evidence. -- **Non-control.** Persisting the chosen round in Postgres proves nothing. It is our database. - Merkle anchoring does not help either, because anchoring happens after computation. - -### T2: lying about the result - -- **Attack.** Publish a receipt whose winner does not follow from its own inputs. -- **Control.** None preventive. The receipt carries every input, so the result is recomputable. -- **Detection.** Public replay (§H). Anyone runs the verifier and the check fails. -- **Residual.** Only caught if someone runs the verifier. That is why it ships in Phase 3 while - nothing of value is at stake (Steps 30 to 32), and why we run it in CI against a corpus fixture - and monitor it ourselves. - -### T3: hiding a battle - -- **Attack.** Resolve a battle, dislike the outcome, never publish the receipt. -- **Control.** None preventive. Receipts are sequenced and hash-chained globally and per pet (§G). -- **Detection.** A gap breaks the chain. The per-pet chain also means a player who holds their own - commitment can show a committed battle with no corresponding receipt. -- **Residual.** Visible, not impossible. If omission risk becomes unacceptable, §I's delayed - direct-receipt claim fallback or an optimistic challenge protocol is the next step. - -### T4: signing-key compromise - -- **Attack.** Stolen key signs arbitrary commitments and receipts. -- **Control.** Key in KMS, never in API or worker environments. Signer accepts only the exact - commitment and receipt schemas, never a generic state-mutation payload. No asset custody, no - withdrawal authority. Separate keys per reward domain. Reward caps bound the economic damage - (Step 22, §I). -- **Detection.** KMS request logging of every digest and key version. Signer throughput outside - expected range. Receipts that exist in the corpus but not in the ledger. Hash-chain forks. -- **Residual.** Real. Bounded, not eliminated. See - [runbook-signing-key-compromise.md](./runbook-signing-key-compromise.md). - -### T5: outcome grinding by submit-and-abandon - -- **Attack.** Submit many battles, abandon the ones that seed badly, keep the good ones. -- **Control.** No player-initiated cancellation after `committed` (§E). Disconnection, tab close, - and app kill do not affect resolution. Per-wallet and per-pet rate limits, daily battle caps. -- **Detection.** Abandonment rate per wallet. Win distribution per wallet against the expected - distribution for their matchups. -- **Residual.** A player can still choose which opponents to fight. That is matchmaking design, not - a randomness leak. - -### T6: manufactured beacon outage - -- **Attack.** Player degrades their own connectivity, or an attacker degrades ours, to escape a - battle already seeded against them. -- **Control.** The committed round is retried indefinitely and never substituted. On a genuine - permanent outage past the timeout, the battle ends `forfeited` with no progression change and both - pets stay locked for several rounds, so escaping costs more than losing (§E). -- **Detection.** drand fetch delay metric. Forfeit rate per wallet. -- **Residual.** A wallet that repeatedly forfeits is a rate-limit and abuse-policy matter. - -### T7: intent replay - -- **Attack.** Resubmit a captured signed intent to force extra battles. -- **Control.** `clientNonce` with a unique database constraint, `expiresAt`, and nonce consumption at - acceptance (§D, Step 19). -- **Detection.** Repeated-nonce alert. -- **Residual.** None material. - -### T8: cross-chain or cross-deployment replay - -- **Attack.** Take a signature from staging and use it on production, or across chains. -- **Control.** Every signed object binds `chainId` and `deploymentId` (§D, Step 6). Intents, - consents, commitments, and receipts all carry both, inside the hashed payload. -- **Detection.** Domain mismatch is a hard rejection, logged. -- **Residual.** None material, provided `deploymentId` is genuinely unique per environment. - -### T9: forged defender consent - -- **Attack.** Battle an unwilling defender, applying cooldown and rating changes to them. -- **Control.** `DefenseAuthorization` signed by the defender's wallet, bound to `rulesetHash`, with - level band, daily cap, validity window, and `revocationNonce`. Every receipt embeds the hash of - the authorization it relied on (§D, Step 20). -- **Detection.** Receipts referencing an unknown or revoked authorization hash fail public replay. -- **Residual.** Consent is to a ruleset version, so a rules change invalidates outstanding - authorizations by design. Expect a re-consent prompt after every balance patch. - -### T10: stale ownership after an NFT transfer - -- **Attack.** Battle with a pet already sold, or snapshot a pet mid-transfer. -- **Control.** Ownership checked at the finalized source version, snapshot records - `sourceChainVersions` (§G). Reconciliation job between finalized chain ownership, snapshots, - receipts, and claims (§J). -- **Detection.** Reconciliation mismatch. -- **Residual.** Reorg depth on the source chain sets the finality wait, which is a latency cost, not - a correctness gap. - -### T11: concurrent battles with the same pet - -- **Attack.** Race two battles for one pet so one snapshot is stale or a cooldown is skipped. -- **Control.** Both pets locked in deterministic id order inside a serializable transaction - (Step 18). Snapshot persisted before randomness exists. -- **Detection.** Serialization-failure rate, duplicate-battle-id alert. -- **Residual.** None material. This is a correctness test target, not a monitoring target. - -### T12: duplicate workers - -- **Attack.** Two workers process the same transition, double-crediting progression or forking a - hash chain. -- **Control.** Every transition idempotent, at-least-once processing assumed, each transition and its - outbox message committed atomically. A duplicate battle id with a different payload is a security - alert and never an upsert (§J, Step 18). -- **Detection.** Hash-chain discontinuity alert. Duplicate-payload alert. -- **Residual.** None material. - -### T13: forged snapshot inputs - -- **Attack.** Inflate a pet's stats, level, or equipment inside the snapshot. -- **Control.** Snapshot fields derive from indexed chain state at a recorded source version. - Progression fields (`xp`, `streak`, `lastOpponentId`) are off-chain, so they are only checkable by - replaying that pet's prior receipts, which the per-pet hash chain makes tractable (§G). -- **Detection.** Public replay walking a pet's chain catches a snapshot that does not follow from the - previous receipt's `progressionDelta`. -- **Residual.** Equipment ownership must be verifiable from chain or from a signed inventory record - before equipment affects combat. Until then, keep equipment out of combat inputs. - -### T14: combat log leaks outcomes to spectators - -- **Attack.** Read the outcome of every resolving battle by connecting to the WebSocket. -- **Control.** `liveBattleSocket.ts` currently broadcasts every message to every client. That is - acceptable for chain-derived data and not acceptable for full combat logs. Subscriptions scope to - the existing `BattleRoom` and the socket becomes notification-only (§J, Step 29). -- **Detection.** Route-level test asserting no cross-room delivery. -- **Residual.** Room ids are shareable by design, so a room link is a spectator link. - -### T15: commitment accepted but never delivered - -- **Attack.** Or, more likely, a bug. Accept succeeds, the player never receives the signed - commitment, and the only record of the chosen round is ours. T1 is then undetectable for that - battle. -- **Control.** Commitment signed and returned synchronously in the accept response, and also served - from a public endpoint so it is re-fetchable (Steps 23, 27). -- **Detection.** Dedicated alert on accept-succeeded-without-commitment-delivery (§J). -- **Residual.** A player who never fetches it still holds no evidence. The public endpoint bounds - this to non-malicious loss. - -### T16: fraudulent or omitted reward batch - -- **Attack.** Anchor a root covering receipts that were never signed, or omit signed receipts from - every batch. -- **Control.** Per-battle, per-wallet, per-batch, and per-season reward caps. One-time claims with - nullifiers. Emergency pause. Root publishers behind multisig and timelock. Published - receipt-to-root inclusion proofs (§I). -- **Detection.** Receipt-omission alert past the inclusion SLO. Root-anchor delay alert. Verifier - Merkle-inclusion check (Step 32). -- **Residual.** An unanchored signed receipt is evidence of operator failure, not an on-chain claim. - -### T17: denial of service against popular opponents - -- **Attack.** Flood a specific defender to exhaust their daily cap or keep their pets locked. -- **Control.** Per-wallet and per-pet rate limits, defender daily battle cap set by the defender - themselves in their authorization (§D). -- **Detection.** Per-defender request-rate anomaly. -- **Residual.** A popular defender's cap is consumed by whoever gets there first. Matchmaking policy, - not a cryptographic problem. - -### T18: verifier collusion - -- **Attack.** The Go verifier does not constrain a dishonest operator, because the same operator runs - both processes and both ports descend from `CombatSim.sol`. -- **Control.** None, and none is claimed. The Go verifier's role is release safety: it catches - implementation drift, bad deploys, and transcription bugs, and it hard-stops receipt signing on any - mismatch (§F, Step 25). -- **Detection.** Engine/verifier mismatch alert with both outputs and all inputs retained. -- **Residual.** Dishonest computation is caught by public replay (T2), not by this. - -### T19: database rollback or restore - -- **Attack.** Restore Postgres to an earlier point and lose or rewrite receipts, including via an - honest recovery. -- **Control.** Receipts are append-only and hash-chained, and the corpus is published, so an - external copy exists outside the database. Append-only audit events for every transition. -- **Detection.** Chain discontinuity between the restored database and the published corpus. -- **Residual.** Recovery procedure must reconcile against the published corpus, not just restore. - Point-in-time recovery drills have to include that reconciliation (Step 36). - -### T20: a season nobody can fully claim - -- **Attack.** Not an attack so much as a self-inflicted one, which is why it is easy to miss. The - reward caps in `SeasonRewardDistributor` are enforced *per claim*, first come first served. Open a - season whose total exceeds its season cap, or whose distributor is underfunded, and early claimants - are paid in full while the last ones get a revert they did nothing to earn. An entitlement above - the per-wallet cap is worse: that wallet can never claim at all, and finds out only by trying. -- **Control.** `boundsViolations` refuses to open a season unless every entitlement fits the - per-wallet cap, the total fits the season cap, and the distributor already holds the full amount - (Step 39). All three are checked before the root is posted, where the answer is still "do not open - this season" rather than "some people lost". The check is pure, so candidate caps can be tested - before any of them are committed to. -- **Detection.** Refusal at open time, with every failing reason reported at once. After opening, - a claim reverting with `ExceedsSeasonCap` means this check was bypassed. -- **Residual.** The caps still protect against a *bad* root, which is their real job; this control - only stops a *correct* season from being opened in an unpayable state. A distributor drained by - some other means after opening reintroduces the same race, so the balance is a precondition rather - than a guarantee. - -## 4. Invariants - -These are the properties tests and alerts exist to defend. Any one of them breaking is an incident, -not a bug report. - -1. A `BattleCommitment` is signed and returned to the player before its committed drand round - publishes. -2. The committed round is never substituted. Retry the same round or forfeit. -3. A battle that reaches `committed` always resolves. `rejected` exists only before `committed`. -4. The snapshot is persisted before any randomness for that battle exists. -5. The seed is derived only from the committed beacon value under the §E derivation. Never from - timestamps, uuids, or backend secrets. -6. A receipt is signed only when the TypeScript engine and the Go verifier agree exactly. -7. Every receipt links its predecessor in the global chain and in both per-pet chains. -8. One `battleId` has at most one signed commitment and at most one signed receipt. A conflicting - payload is an alert, never an upsert. -9. The signer accepts only commitment and receipt schemas, and holds no asset authority. -10. Off-chain XP is never represented as NFT state unless a successful aggregate claim applied it - on-chain. - -## 5. Accepted residual risk - -Stated plainly, because §9 of the architecture document commits to stating it plainly. - -- **A stolen signing key can sign lies.** Bounded by key isolation, schema restriction, reward caps, - and the runbook. Not eliminated. -- **We can refuse to publish.** The chains make it visible, not impossible. -- **The receipt proves what we published, not that we were honest.** Public replay is the control, - and it only works if replay actually happens. -- **The Go verifier does not constrain us**, only our deploys. - -## 6. Escalation threshold - -This design is proportionate while battle outcomes drive progression and capped, aggregate season -rewards. It stops being proportionate when a single battle's outcome carries significant transferable -value, or when reward caps have to be raised beyond what we would accept losing to a key compromise. - -At that point the next steps are §M's deferred options: per-battle backend signature verified -on-chain (Phase 3.5), optimistic settlement with bonded challenges, or proof-based settlement. That -threshold should be crossed deliberately, with a review, not drifted past by raising caps one -increment at a time. diff --git a/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts b/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts index 5d693a6d..517f324d 100644 --- a/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts +++ b/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts @@ -20,8 +20,8 @@ export const shortAddress = (addr: string) => export const VALIDATION_MESSAGE = 'Please select your pet and an opponent'; export const BATTLE_FAIL_MESSAGE = 'Failed to start battle. Please try again.'; /** Shown briefly when the client-side live-replay disagrees with the on-chain - * BattleResolved result (plan-realtime-battle-ux.md's reconciliation rule — - * the on-chain result always wins; this is presentational, not a real error). */ + * BattleResolved result (the on-chain result always wins; this is + * presentational, not a real error). */ export const MISMATCH_NOTICE_MESSAGE = 'The on-chain referee ruled differently — syncing the true result…'; /** Personas captured at battle start, reused for the settle dialogue read. */ diff --git a/frontend/src/components/pet/interactions/panels/battle/index.module.css b/frontend/src/components/pet/interactions/panels/battle/index.module.css index 882badba..d9590a12 100644 --- a/frontend/src/components/pet/interactions/panels/battle/index.module.css +++ b/frontend/src/components/pet/interactions/panels/battle/index.module.css @@ -865,7 +865,7 @@ color: rgb(125 214 255 / 70%); } -/* Live combat-sim strike flourish (plan-realtime-battle-impl.md Phase 4) */ +/* Live combat-sim strike flourish */ .sceneFlourish { flex-shrink: 0; margin: 0 20px 8px; diff --git a/frontend/src/components/pet/interactions/panels/battle/parts/battle-overlay.tsx b/frontend/src/components/pet/interactions/panels/battle/parts/battle-overlay.tsx index 21367748..8ec57b79 100644 --- a/frontend/src/components/pet/interactions/panels/battle/parts/battle-overlay.tsx +++ b/frontend/src/components/pet/interactions/panels/battle/parts/battle-overlay.tsx @@ -46,15 +46,15 @@ export type BattleOverlayProps = { onBack: () => void; fighterName: string; opponentName: string; - // Live-replay animation (plan-realtime-battle-impl.md Phase 4) — null falls + // Live-replay animation — null falls // back to the static getLifePercent bars below (Solana, or an EVM deployment // with no GameConfig wired up). Presentation only; never the source of the // result banner, which always comes from battleOutcome (on-chain). liveHp1Percent?: number | null; liveHp2Percent?: number | null; liveFlourish?: string | null; - /** Round-by-round mechanical log (plan-realtime-battle-impl.md Phase 4's strike - * log, formatted) for the bottom log panel. Null — not just empty — when there's + /** Round-by-round mechanical log (the strike log, formatted) for the bottom + * log panel. Null — not just empty — when there's * no live-replay feature this deployment (Solana, or an EVM deployment with no * GameConfig wired up), same fallback rule as liveHp1Percent/liveHp2Percent. */ liveLog?: MechanicalLogLine[] | null; diff --git a/frontend/src/config.ts b/frontend/src/config.ts index 7a4ba340..f5942c21 100644 --- a/frontend/src/config.ts +++ b/frontend/src/config.ts @@ -4,7 +4,7 @@ export const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001'; /** * Per-room notification channel for backend-authoritative battles - * (`docs/plan-backend-battle-architecture.md` §J). + * (`docs/battle-protocol.md` §J). * * Lives here rather than in `petsContractParams` because it is chain-neutral: backend * battles run on both EVM and Solana, while that module is the EVM contract config and diff --git a/frontend/src/hooks/battle/useBattlePanel.ts b/frontend/src/hooks/battle/useBattlePanel.ts index 7aba92fa..eea6f033 100644 --- a/frontend/src/hooks/battle/useBattlePanel.ts +++ b/frontend/src/hooks/battle/useBattlePanel.ts @@ -102,9 +102,9 @@ export const useBattlePanel = ({ isStandaloneView }: UseBattlePanelArgs): UseBat // display still waits on the live animation finishing (see the gating effect // below), unless a mismatch was found, in which case it waits on the notice. const [hasResolvedEvent, setHasResolvedEvent] = useState(false); - // Client-side live-replay disagreed with the on-chain result (should be ~never - // — see plan-realtime-battle-ux.md's reconciliation rule). Shows a brief - // honest notice instead of silently correcting or showing the wrong winner. + // Client-side live-replay disagreed with the on-chain result (should be + // ~never). Shows a brief honest notice instead of silently correcting or + // showing the wrong winner. const [mismatchNotice, setMismatchNotice] = useState(false); // Personas captured at battle start. The backend pre-generates the result @@ -510,7 +510,7 @@ export const useBattlePanel = ({ isStandaloneView }: UseBattlePanelArgs): UseBat onTauntsComplete: handleTauntsComplete, fighterName: fighterDisplayName, opponentName: opponentDisplayName, - // Live-replay animation (plan-realtime-battle-impl.md Phase 4): only + // Live-replay animation: only // populated once entropy has revealed and the sim inputs are known; // battle-overlay falls back to its existing static HP display otherwise // (Solana, or an EVM deployment with no GameConfig wired up). diff --git a/proto/cryptopets.proto b/proto/cryptopets.proto index 08ee7bbd..7bccb0ce 100644 --- a/proto/cryptopets.proto +++ b/proto/cryptopets.proto @@ -20,7 +20,7 @@ service GameDataService { rpc EstimateWin(WinRequest) returns (WinResponse); // Independent recomputation of a backend-authoritative battle - // (docs/plan-backend-battle-architecture.md §F). Takes everything needed to + // (docs/battle-protocol.md §F). Takes everything needed to // rerun the fight and the progression composition — no database, no cache, // no chain state — so a mismatch against the TypeScript engine's own result // means the two implementations disagree, not that either read something diff --git a/protocol/README.md b/protocol/README.md index 8ae556aa..903258ae 100644 --- a/protocol/README.md +++ b/protocol/README.md @@ -3,8 +3,7 @@ Canonical definitions for the backend-authoritative battle protocol: canonical encodings, hashes, drand seed derivation, the versioned combat ruleset, and the receipt and commitment schemas. -Design: [docs/plan-backend-battle-architecture.md](../docs/plan-backend-battle-architecture.md). -Sequencing: [docs/plan-backend-battle-steps.md](../docs/plan-backend-battle-steps.md). +Design: [docs/battle-protocol.md](../docs/battle-protocol.md). ## Why this package exists, and why it is MIT diff --git a/protocol/scripts/gen-vectors.ts b/protocol/scripts/gen-vectors.ts index 1ac070fe..b41ddb17 100644 --- a/protocol/scripts/gen-vectors.ts +++ b/protocol/scripts/gen-vectors.ts @@ -152,7 +152,7 @@ export function intentFromFixture(fixture: IntentFixture): BattleIntent { function writeIntentVectors(): void { const out = { description: - 'BattleIntent canonical-hash and Solana sign-message vectors (docs/plan-backend-battle-architecture.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/intent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.', + 'BattleIntent canonical-hash and Solana sign-message vectors (docs/battle-protocol.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/intent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.', cases: intentCases.map((c) => { const intent = intentFromFixture(c.intent); const solana = c.intent.chainId.startsWith('solana:'); @@ -300,7 +300,7 @@ export function consentFromFixture(fixture: ConsentFixture): DefenseAuthorizatio function writeConsentVectors(): void { const out = { description: - 'DefenseAuthorization canonical-hash and Solana sign-message vectors (docs/plan-backend-battle-architecture.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/consent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.', + 'DefenseAuthorization canonical-hash and Solana sign-message vectors (docs/battle-protocol.md §D). Generated by protocol/scripts/gen-vectors.ts from protocol/src/consent. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.', cases: consentCases.map((c) => { const auth = consentFromFixture(c.auth); const solana = c.auth.chainId.startsWith('solana:'); @@ -477,7 +477,7 @@ export function snapshotFromFixture(fixture: SnapshotFixture): BattleSnapshot { function writeSnapshotVectors(): void { const out = { description: - 'BattleSnapshot canonical-hash vectors (docs/plan-backend-battle-architecture.md §C, §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/snapshot. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.', + 'BattleSnapshot canonical-hash vectors (docs/battle-protocol.md §C, §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/snapshot. They lock the canonical byte layout; a failure means the implementation drifted. Never edit an expectation to match new output.', cases: snapshotCases.map((c) => ({ name: c.name, note: c.note, @@ -582,7 +582,7 @@ export function seedInputsFromFixture(fixture: SeedFixture): SeedInputs { function writeSeedVectors(): void { const out = { description: - 'Battle seed derivation vectors (docs/plan-backend-battle-architecture.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/randomness. The layout is length-prefixed via the canonical encoder rather than the bare concatenation §E sketches; field order matches §E exactly. A failure means the implementation drifted, and every historical battle depends on this layout. Never edit an expectation to match new output.', + 'Battle seed derivation vectors (docs/battle-protocol.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/randomness. The layout is length-prefixed via the canonical encoder rather than the bare concatenation §E sketches; field order matches §E exactly. A failure means the implementation drifted, and every historical battle depends on this layout. Never edit an expectation to match new output.', cases: seedCases.map((c) => ({ name: c.name, note: c.note, @@ -723,7 +723,7 @@ export function commitmentFromFixture(fixture: CommitmentFixture): BattleCommitm function writeCommitmentVectors(): void { const out = { description: - 'BattleCommitment canonical-hash vectors (docs/plan-backend-battle-architecture.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/commitment. The snapshot enters the hash as snapshotHash, while the payload carries the full snapshot. A failure means the implementation drifted. Never edit an expectation to match new output.', + 'BattleCommitment canonical-hash vectors (docs/battle-protocol.md §E). Generated by protocol/scripts/gen-vectors.ts from protocol/src/commitment. The snapshot enters the hash as snapshotHash, while the payload carries the full snapshot. A failure means the implementation drifted. Never edit an expectation to match new output.', cases: commitmentCases.map((c) => ({ name: c.name, note: c.note, @@ -845,7 +845,7 @@ const progressionCases: { name: string; note: string; fixture: ProgressionFixtur function writeProgressionVectors(): void { const out = { description: - 'Progression-delta vectors in the frozen-snapshot shape (docs/plan-backend-battle-architecture.md §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/progression. The XP formula and decay themselves are pinned cross-language by contracts/test-vectors/xp.json; these cases pin the composition (which base applies to whom, which decay shift, and the level-threshold interaction). A failure means the implementation drifted. Never edit an expectation to match new output.', + 'Progression-delta vectors in the frozen-snapshot shape (docs/battle-protocol.md §F). Generated by protocol/scripts/gen-vectors.ts from protocol/src/progression. The XP formula and decay themselves are pinned cross-language by contracts/test-vectors/xp.json; these cases pin the composition (which base applies to whom, which decay shift, and the level-threshold interaction). A failure means the implementation drifted. Never edit an expectation to match new output.', cases: progressionCases.map((c) => { const params: ProgressionParams = { maxLevel: c.fixture.maxLevel }; const delta = computeProgression( @@ -960,7 +960,7 @@ const rulesetCases: { name: string; note: string; ruleset: Ruleset }[] = [ function writeRulesetVectors(): void { const out = { description: - 'Ruleset canonical-hash vectors (docs/plan-backend-battle-architecture.md §F, §H). Generated by protocol/scripts/gen-vectors.ts from protocol/src/ruleset. A ruleset hash is chain-agnostic on purpose: the same rules can run on either chain. A failure means the implementation drifted. Never edit an expectation to match new output.', + 'Ruleset canonical-hash vectors (docs/battle-protocol.md §F, §H). Generated by protocol/scripts/gen-vectors.ts from protocol/src/ruleset. A ruleset hash is chain-agnostic on purpose: the same rules can run on either chain. A failure means the implementation drifted. Never edit an expectation to match new output.', cases: rulesetCases.map((c) => ({ name: c.name, note: c.note, @@ -1188,7 +1188,7 @@ export function receiptFromFixture(fixture: ReceiptFixture): BattleReceipt { function writeReceiptVectors(): void { const out = { description: - 'BattleReceipt canonical-hash vectors (docs/plan-backend-battle-architecture.md §G). Generated by protocol/scripts/gen-vectors.ts from protocol/src/receipt. Each case is a coherent receipt: real quicknet beacons, a seed derived from the receipt own inputs, a combat-log hash from an actual simulation, and a recomputed progression delta. Derived fields are recorded so a reader can see what the encoding covered. A failure means the implementation drifted. Never edit an expectation to match new output.', + 'BattleReceipt canonical-hash vectors (docs/battle-protocol.md §G). Generated by protocol/scripts/gen-vectors.ts from protocol/src/receipt. Each case is a coherent receipt: real quicknet beacons, a seed derived from the receipt own inputs, a combat-log hash from an actual simulation, and a recomputed progression delta. Derived fields are recorded so a reader can see what the encoding covered. A failure means the implementation drifted. Never edit an expectation to match new output.', cases: receiptCases.map((c) => { const receipt = receiptFromFixture(c.receipt); return { @@ -1230,7 +1230,7 @@ function syntheticReceiptHash(index: number): Hex { function writeMerkleVectors(): void { const out = { description: - 'Merkle leaf, root, and proof vectors (docs/plan-backend-battle-architecture.md §I). Generated by protocol/scripts/gen-vectors.ts from protocol/src/merkle. Layout notes for a Solidity implementation: leaf = keccak256(LEAF_DOMAIN || uint16 schemaVersion || receiptHash); node = keccak256(NODE_DOMAIN || min(a,b) || max(a,b)); all elements are fixed 32 bytes so abi.encodePacked matches; pairs are sorted so proofs carry no direction flags; an odd node is promoted unchanged rather than paired with itself. A failure means the implementation drifted. Never edit an expectation to match new output.', + 'Merkle leaf, root, and proof vectors (docs/battle-protocol.md §I). Generated by protocol/scripts/gen-vectors.ts from protocol/src/merkle. Layout notes for a Solidity implementation: leaf = keccak256(LEAF_DOMAIN || uint16 schemaVersion || receiptHash); node = keccak256(NODE_DOMAIN || min(a,b) || max(a,b)); all elements are fixed 32 bytes so abi.encodePacked matches; pairs are sorted so proofs carry no direction flags; an odd node is promoted unchanged rather than paired with itself. A failure means the implementation drifted. Never edit an expectation to match new output.', domains: { leaf: MERKLE_LEAF_DOMAIN, node: MERKLE_NODE_DOMAIN, diff --git a/protocol/src/combat/sim.ts b/protocol/src/combat/sim.ts index 6ab88b2b..daebd7a6 100644 --- a/protocol/src/combat/sim.ts +++ b/protocol/src/combat/sim.ts @@ -16,8 +16,8 @@ export interface SimResult { } /** - * One resolved attack, in fight order, for blow-by-blow animation - * (plan-realtime-battle-impl.md Phase 4). Recorded inline as `simulate` runs + * One resolved attack, in fight order, for blow-by-blow animation. + * Recorded inline as `simulate` runs * the same computation the result is derived from — never a second pass, so * the log can't drift from the math it's describing. */ @@ -54,10 +54,10 @@ export interface SimOutcome { * Runs a full battle between pet 1 and pet 2 seeded by a 32-byte combat seed * (the on-chain uint256 `seed`/`randomness`). A move-for-move port of * CombatSim.simulate / combat::simulate / indexer-go's sim.go Simulate, with - * one addition: it also returns a per-strike log for live animation - * (plan-realtime-battle-impl.md Phase 4). Presentation only — the on-chain - * `BattleResolved` event is always the authoritative result; see this port's - * package README / the plan docs for the reconciliation rule. + * one addition: it also returns a per-strike log for live animation. + * Presentation only — the on-chain `BattleResolved` event is always the + * authoritative result; see this port's package README for the reconciliation + * rule. */ export function simulate( dna1: bigint, diff --git a/protocol/src/combat/strike.ts b/protocol/src/combat/strike.ts index cfcf2817..26601e3d 100644 --- a/protocol/src/combat/strike.ts +++ b/protocol/src/combat/strike.ts @@ -6,8 +6,8 @@ import type { Attrs } from './dna'; /** * One resolved attack. Mirrors indexer-go's strike.go `strike` return value * (newHpDef, atkHeal) plus extra fields (isMagic/crit/elementMult/ - * furyTriggered) the Go port doesn't need but the live-replay animation does - * (plan-realtime-battle-impl.md Phase 4). These extra fields are read off the + * furyTriggered) the Go port doesn't need but the live-replay animation does. + * These extra fields are read off the * exact same computation as the damage number, never recomputed separately — * there is one simulation code path, and the log is a write-only view onto it. */ diff --git a/protocol/src/index.ts b/protocol/src/index.ts index 1fbb9540..5801240c 100644 --- a/protocol/src/index.ts +++ b/protocol/src/index.ts @@ -4,8 +4,6 @@ * * See the package README for the constraints every module here must hold to * (no clock, no ambient randomness, no I/O, canonical encoding only). - * - * Modules land here in the order set by docs/plan-backend-battle-steps.md. */ /** Package identity, exported so a consumer can assert which protocol build it loaded. */ diff --git a/services/indexer-go/README.md b/services/indexer-go/README.md index fd3c481a..74a367f8 100644 --- a/services/indexer-go/README.md +++ b/services/indexer-go/README.md @@ -109,7 +109,7 @@ log (`SimulateWithLog` in `simlog.go`), and the progression delta for both pets the whole delta, not just the XP formula `xp.go` already covered). This is release safety, not a trust boundary — see -`docs/plan-backend-battle-architecture.md` §F's "what the Go verifier is for" +`docs/battle-protocol.md` §F's "what the Go verifier is for" before reusing it as anything stronger. The backend (`backend/src/features/battle-worker/verify.worker.ts`) calls it, converts the structured log back into `@cryptopets/protocol`'s `SimOutcome` shape, and hashes diff --git a/services/indexer-go/internal/grpcsrv/verify.go b/services/indexer-go/internal/grpcsrv/verify.go index e11aa67e..f5ab22af 100644 --- a/services/indexer-go/internal/grpcsrv/verify.go +++ b/services/indexer-go/internal/grpcsrv/verify.go @@ -13,7 +13,7 @@ import ( ) // VerifyBattle independently recomputes a backend-authoritative battle result -// (docs/plan-backend-battle-architecture.md §F). Unlike GetPetState/ +// (docs/battle-protocol.md §F). Unlike GetPetState/ // EstimateWin, it reads nothing from the roster cache and // needs no warm-up: every input arrives in the request, which is what makes // this a genuine second implementation of the computation rather than a diff --git a/services/indexer-go/pb/cryptopets_grpc.pb.go b/services/indexer-go/pb/cryptopets_grpc.pb.go index 5f9504dd..3ae69bd9 100644 --- a/services/indexer-go/pb/cryptopets_grpc.pb.go +++ b/services/indexer-go/pb/cryptopets_grpc.pb.go @@ -42,7 +42,7 @@ type GameDataServiceClient interface { // and returns pet_id1's win probability. UNAVAILABLE until the cache is warm. EstimateWin(ctx context.Context, in *WinRequest, opts ...grpc.CallOption) (*WinResponse, error) // Independent recomputation of a backend-authoritative battle - // (docs/plan-backend-battle-architecture.md §F). Takes everything needed to + // (docs/battle-protocol.md §F). Takes everything needed to // rerun the fight and the progression composition — no database, no cache, // no chain state — so a mismatch against the TypeScript engine's own result // means the two implementations disagree, not that either read something @@ -104,7 +104,7 @@ type GameDataServiceServer interface { // and returns pet_id1's win probability. UNAVAILABLE until the cache is warm. EstimateWin(context.Context, *WinRequest) (*WinResponse, error) // Independent recomputation of a backend-authoritative battle - // (docs/plan-backend-battle-architecture.md §F). Takes everything needed to + // (docs/battle-protocol.md §F). Takes everything needed to // rerun the fight and the progression composition — no database, no cache, // no chain state — so a mismatch against the TypeScript engine's own result // means the two implementations disagree, not that either read something diff --git a/shared/src/hooks/index.ts b/shared/src/hooks/index.ts index 38fff218..d7df36a9 100644 --- a/shared/src/hooks/index.ts +++ b/shared/src/hooks/index.ts @@ -67,7 +67,7 @@ export { } from './battle/useBattleDialogue'; export { useBattleTaunts, type GenerateTauntsVars } from './battle/useBattleTaunts'; export { useCreateBattleRoom, type CreateRoomVars } from './battle/useCreateBattleRoom'; -// Backend-authoritative battles (docs/plan-backend-battle-architecture.md §D, §E, §J). +// Backend-authoritative battles (docs/battle-protocol.md §D, §E, §J). export { BATTLE_CONFIG_QUERY_KEY, useBattleConfig, type BattleConfig } from './battle/useBattleConfig'; export { useBattleMode, type BattleMode, type BattleModeState } from './battle/useBattleMode'; export { diff --git a/verifier/README.md b/verifier/README.md index 1ef3f534..1c9574ee 100644 --- a/verifier/README.md +++ b/verifier/README.md @@ -1,9 +1,7 @@ # @cryptopets/verifier The standalone public verifier for CryptoPets backend-authoritative battle receipts (§H of -[docs/plan-backend-battle-architecture.md](../docs/plan-backend-battle-architecture.md)). - -Sequencing: [docs/plan-backend-battle-steps.md](../docs/plan-backend-battle-steps.md), Group F. +[docs/battle-protocol.md](../docs/battle-protocol.md)). ## Why this exists, and why it is MIT diff --git a/verifier/package.json b/verifier/package.json index c20f119b..b9c9c101 100644 --- a/verifier/package.json +++ b/verifier/package.json @@ -1,7 +1,7 @@ { "name": "@cryptopets/verifier", "version": "0.0.1", - "description": "Standalone MIT verifier for CryptoPets backend-authoritative battle receipts (docs/plan-backend-battle-architecture.md §H). No backend access, no database: every check runs against a receipt's own published contents plus public inputs (drand, a signing-key list) the caller supplies.", + "description": "Standalone MIT verifier for CryptoPets backend-authoritative battle receipts (docs/battle-protocol.md §H). No backend access, no database: every check runs against a receipt's own published contents plus public inputs (drand, a signing-key list) the caller supplies.", "license": "MIT", "type": "module", "main": "src/index.ts", diff --git a/verifier/src/index.ts b/verifier/src/index.ts index ca7e5690..fb52f427 100644 --- a/verifier/src/index.ts +++ b/verifier/src/index.ts @@ -1,12 +1,10 @@ /** * Standalone MIT verifier for CryptoPets backend-authoritative battle receipts - * (docs/plan-backend-battle-architecture.md §H). Depends only on `@cryptopets/protocol`: + * (docs/battle-protocol.md §H). Depends only on `@cryptopets/protocol`: * no backend access, no database. * - * See the package README for what is and is not covered yet — checks land in the order - * set by docs/plan-backend-battle-steps.md (Step 30: operator signature and hash-chain - * continuity; Step 31 adds the drand beacon, seed derivation, combat replay, and - * progression checks). + * Checks operator signature, hash-chain continuity, the drand beacon, seed derivation, + * combat replay, and progression. See the package README for what each one covers. */ export * from './checks'; From e6bd361e432b977cba1abd09816ca981e4cff84b Mon Sep 17 00:00:00 2001 From: heyradcode Date: Wed, 5 Aug 2026 20:43:31 -0400 Subject: [PATCH 02/61] feat(image-generator): point clients and metadata at the deployed service --- frontend/env.example | 2 +- render.yaml | 7 +++++-- services/image-generator/env.example | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/frontend/env.example b/frontend/env.example index 2f767196..c7b01a02 100644 --- a/frontend/env.example +++ b/frontend/env.example @@ -27,4 +27,4 @@ VITE_API_URL=http://localhost:3001 # Local dev: `pnpm dev:art` serves the service on :8787, and the value below is # what talks to it. Point at the deployed service in production. VITE_IMAGE_SERVICE_URL=http://localhost:8787 -# VITE_IMAGE_SERVICE_URL=https://art.cryptopets.io +# VITE_IMAGE_SERVICE_URL=https://do-not-stop-image-generator.onrender.com diff --git a/render.yaml b/render.yaml index 8dc3173f..2d84590e 100644 --- a/render.yaml +++ b/render.yaml @@ -98,9 +98,12 @@ services: healthCheckPath: /health envVars: # Must match this service's own URL, or metadata hands marketplaces - # image links that 404. + # image links that 404. Pinned rather than sync:false because a forgotten + # value here fails silently: the service boots, serves images, and only + # the metadata links are wrong. Change it if the service is renamed or + # moves to a custom domain. - key: PUBLIC_BASE_URL - sync: false + value: https://do-not-stop-image-generator.onrender.com # r2, not filesystem: free web services sleep when idle, and a service # that slept on local disk wakes up and regenerates art every pet owner # has already seen. Generated art must survive the instance. diff --git a/services/image-generator/env.example b/services/image-generator/env.example index b190462e..312dcbe7 100644 --- a/services/image-generator/env.example +++ b/services/image-generator/env.example @@ -5,7 +5,7 @@ # Absolute URL this service is reachable at. Metadata puts image URLs under it, # so a wrong value here hands marketplaces links that 404. Defaults to # http://localhost:$PORT, which is correct for dev and wrong for production. -# PUBLIC_BASE_URL=https://art.cryptopets.io +# PUBLIC_BASE_URL=https://do-not-stop-image-generator.onrender.com # How long an image request waits for generation before answering 503 with # Retry-After. The generation is NOT cancelled: it finishes and lands in the From 379b3bc2ae29e9a85f6214bf89a308f0c3d47505 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Wed, 5 Aug 2026 21:17:03 -0400 Subject: [PATCH 03/61] fix(image-generator): stop treating a missing R2 bucket as a cache miss --- services/image-generator/src/r2Store.test.ts | 8 ++++++++ services/image-generator/src/r2Store.ts | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/services/image-generator/src/r2Store.test.ts b/services/image-generator/src/r2Store.test.ts index c845e81c..60a261b9 100644 --- a/services/image-generator/src/r2Store.test.ts +++ b/services/image-generator/src/r2Store.test.ts @@ -62,6 +62,14 @@ describe('R2ImageStore.get', () => { const store = new R2ImageStore(CONFIG, clientRejecting(notFound(403))); await expect(store.get('k.png')).rejects.toThrow(); }); + + it('propagates a missing bucket, which R2 also reports as a 404', async () => { + const noSuchBucket = Object.assign(notFound(404), { name: 'NoSuchBucket' }); + const store = new R2ImageStore(CONFIG, clientRejecting(noSuchBucket)); + // Swallowed as a miss, this reads as "not cached yet" and /ready — whose + // store probe is a get() expecting to miss — calls the deploy healthy. + await expect(store.get('k.png')).rejects.toThrow(); + }); }); describe('R2ImageStore.put', () => { diff --git a/services/image-generator/src/r2Store.ts b/services/image-generator/src/r2Store.ts index 2e1f2a34..07239cfa 100644 --- a/services/image-generator/src/r2Store.ts +++ b/services/image-generator/src/r2Store.ts @@ -87,9 +87,16 @@ export class R2ImageStore implements ImageStore { } /** A missing key surfaces as NoSuchKey, or as a bare 404 when R2 answers a HEAD - * style response without the modelled error shape. */ + * style response without the modelled error shape. + * + * A missing *bucket* is also a 404, and must not be read as a miss. Doing so + * turns a misconfigured R2_BUCKET into "not cached yet, generate it", which + * then fails on the write with the real error — and makes /ready report the + * store healthy, since its probe is a get() it expects to miss. That is + * precisely the failure readiness.ts claims to catch. */ const isNotFound = (error: unknown): boolean => { if (error instanceof NoSuchKey) return true; const meta = (error as { $metadata?: { httpStatusCode?: number }; name?: string }); + if (meta.name === 'NoSuchBucket') return false; return meta.$metadata?.httpStatusCode === 404 || meta.name === 'NotFound'; }; From 2c33ca73273152d0bca073548d4ebab4fb6083b4 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Wed, 5 Aug 2026 21:33:43 -0400 Subject: [PATCH 04/61] docs: rebrand README to CryptoPets and add a gallery screenshot --- README.md | 35 ++++++++++++++++++++++++++--------- docs/screenshot.png | Bin 0 -> 1487606 bytes 2 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 docs/screenshot.png diff --git a/README.md b/README.md index 2f6d7712..4b5c74c6 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,21 @@ -# do-not-stop 🚀 +# CryptoPets 🚀 -A continuously evolving Web3 playground built with modern technologies, designed to grow, adapt, and experiment with the latest advancements in Ethereum/Solana development and contemporary React patterns. +A Web3 pet-battling game running on both Ethereum and Solana. Breed, train, and +battle NFT pets whose art is generated from their on-chain DNA, with battle +outcomes resolved from a committed random beacon and published as signed +receipts anyone can replay. **Live Demo:** https://cryptopets.vercel.app +![The CryptoPets gallery: a player's pets with stats, leaderboard, and daily quests](./docs/screenshot.png) + ## 📁 Project Structure This is a monorepo containing multiple interconnected projects: ### Applications - **[Frontend](./frontend)** - React + Vite web application with wallet integration -- **[Backend](./backend)** - Node.js + Express API server +- **[Backend](./backend)** - Node.js + Express API server, battle authority, and settle keeper - **[Mobile](./mobile)** - React Native cross-platform mobile app - **[Website](./website)** - Next.js marketing/documentation site @@ -18,13 +23,19 @@ This is a monorepo containing multiple interconnected projects: - **[Ethereum Contracts](./contracts/ethereum)** - Solidity smart contracts with Hardhat - **[Solana Programs](./contracts/solana)** - Rust-based Solana programs with Anchor +### Services +- **[Indexer](./services/indexer-go)** - Go cross-chain indexer; the only writer of the pet roster +- **[Image Generator](./services/image-generator)** - Pet NFT art and ERC-721 metadata, from Cloudflare Workers AI + ### Shared Code -- **[Shared Core](./shared)** - Common utilities and types used across projects +- **[Shared Core](./shared)** - Common utilities, types, and hooks used across clients +- **[Protocol](./protocol)** - The battle protocol: combat engine, canonical encodings, hashes, seed derivation +- **[Verifier](./verifier)** - Standalone verifier that replays a signed battle receipt against the protocol ## 📖 Documentation -See [docs/](./docs) for testing strategy and an index of all package-level docs. -The component map and data flow live in +See [docs/](./docs) for the battle protocol, testing strategy, and an index of +all package-level docs. The component map and data flow live in [CLAUDE.md](./CLAUDE.md#architecture). ## 🛠️ Development @@ -52,11 +63,13 @@ For detailed setup and commands, see [DEVELOPMENT.md](./DEVELOPMENT.md). **Frontend:** React 19, TypeScript, Vite, Wagmi, Viem, TanStack Query -**Backend:** Node.js, Express.js, TypeScript, JWT, Ethers.js, TweetNaCl +**Backend:** Node.js, Express.js, TypeScript, Prisma, PostgreSQL, GraphQL, JWT, Ethers.js, TweetNaCl **Mobile:** React Native, TypeScript -**Blockchain:** +**Services:** Go (indexer, gRPC), Cloudflare Workers AI + R2 (pet art) + +**Blockchain:** - Ethereum: Solidity, Hardhat - Solana: Rust, Anchor @@ -76,7 +89,11 @@ This monorepo uses two licenses depending on the package: | Package(s) | License | | --- | --- | | `contracts/ethereum`, `contracts/solana`, `services/indexer-go`, `proto`, `protocol`, `verifier` | [MIT](./contracts/LICENSE) — fully permissive | -| `frontend`, `backend`, `mobile`, `website`, `shared` (and anything else) | [PolyForm Noncommercial 1.0.0](./LICENSE) — free for any noncommercial purpose; commercial use requires permission | +| `frontend`, `backend`, `mobile`, `website`, `shared`, `services/image-generator` (and anything else) | [PolyForm Noncommercial 1.0.0](./LICENSE) — free for any noncommercial purpose; commercial use requires permission | + +`protocol` and `verifier` are MIT deliberately: a backend that decides battle +outcomes only holds up if outsiders can replay its receipts, which means the +verifier and everything it depends on has to be freely usable. Each package's `package.json` / `go.mod` directory points at the license that applies to it. For commercial licensing of the app layer, contact diff --git a/docs/screenshot.png b/docs/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..33e6738965a3439292e2f8965df7269bc1843a36 GIT binary patch literal 1487606 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

if+^=82 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 z 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�c621jvCon%Cg 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

^~+)RGj7G7s;A}2HTcV%rR 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

H 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 literal 0 HcmV?d00001 From 1edb4364a3943fa854bf3f0014ceca97196f6140 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 07:33:07 -0400 Subject: [PATCH 05/61] feat(backend): add a pet leaderboard query ranked on the merged battle record --- backend/src/graphql/resolvers.ts | 27 +++ backend/src/graphql/schema.ts | 43 +++++ .../repositories/leaderboard.repository.ts | 169 ++++++++++++++++++ backend/tests/graphql/resolvers.test.ts | 41 +++++ backend/tests/graphql/schema.test.ts | 23 ++- .../leaderboard.repository.test.ts | 117 ++++++++++++ 6 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 backend/src/repositories/leaderboard.repository.ts create mode 100644 backend/tests/repositories/leaderboard.repository.test.ts diff --git a/backend/src/graphql/resolvers.ts b/backend/src/graphql/resolvers.ts index 87ea771c..e532a7dc 100644 --- a/backend/src/graphql/resolvers.ts +++ b/backend/src/graphql/resolvers.ts @@ -1,5 +1,6 @@ import { findReadyOpponents, getAllPets, getPetById, searchPets, type RosterPet } from '@repositories/roster.repository'; import { findBattleProgress, withBattleProgress } from '@repositories/battleProgress.overlay'; +import { findPetLeaderboard } from '@repositories/leaderboard.repository'; import { tryGrpcEstimateWin } from '@grpc-client/estimateWin'; import { isSupportedChain, SUPPORTED_CHAINS } from '@typings/chain'; @@ -17,6 +18,12 @@ interface OpponentsArgs { pageSize?: number | null; } +interface LeaderboardArgs { + chain: string; + page?: number | null; + pageSize?: number | null; +} + interface BattleProgressArgs { chain: string; petIds: string[]; @@ -94,6 +101,26 @@ export const rootValue = { }; }, + leaderboard: async (args: LeaderboardArgs) => { + if (!isSupportedChain(args.chain)) { + throw new Error(`chain must be one of: ${SUPPORTED_CHAINS.join(', ')}`); + } + + const page = Math.max(0, args.page ?? 0); + const pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, args.pageSize ?? DEFAULT_PAGE_SIZE)); + + // No overlay here, for the same reason as `opponents`: the ranking is the merge, + // so `findPetLeaderboard` does it in the query. + const { entries, total } = await findPetLeaderboard({ chain: args.chain, page, pageSize }); + + return { + entries: entries.map(({ petId: id, ...rest }) => ({ id, ...rest })), + total, + page, + pageSize, + }; + }, + searchPets: async (args: SearchPetsArgs) => { if (!isSupportedChain(args.chain)) { throw new Error(`chain must be one of: ${SUPPORTED_CHAINS.join(', ')}`); diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index 74a48a7b..893faac0 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -54,6 +54,38 @@ export const schema = buildSchema(` readyAt: Float! } + """ + One ranked pet on the leaderboard. + + The battle record is the merged one: pet_battle_progress where a pet has fought a + backend battle, the frozen pet_roster counters otherwise — the same rule every + other pet read here applies. + """ + type LeaderboardEntry { + "1-based position in the full ranking, not within the page." + rank: Int! + "Pet id as a decimal string." + id: String! + chain: String! + owner: String! + name: String! + "On-chain DNA serialized as a decimal string." + dna: String! + level: Int! + rarity: Int! + winCount: Int! + lossCount: Int! + "Metaplex Core asset pubkey (Solana only); empty string on EVM." + asset: String! + } + + type LeaderboardPage { + entries: [LeaderboardEntry!]! + total: Int! + page: Int! + pageSize: Int! + } + type OpponentsPage { opponents: [OpponentPet!]! total: Int! @@ -77,6 +109,17 @@ export const schema = buildSchema(` pageSize: Int ): OpponentsPage! + """ + Pets ranked by battle record: wins descending, then losses ascending (the + win-rate tiebreak), then level, then pet id. Pets that have never fought are + omitted. Ranks are absolute, so page 2 continues where page 1 stopped. + """ + leaderboard( + chain: String! + page: Int + pageSize: Int + ): LeaderboardPage! + """ Search pets by name prefix or exact numeric ID across the whole roster. Returns up to 'limit' results (default 10, max 20). diff --git a/backend/src/repositories/leaderboard.repository.ts b/backend/src/repositories/leaderboard.repository.ts new file mode 100644 index 00000000..e7762d3a --- /dev/null +++ b/backend/src/repositories/leaderboard.repository.ts @@ -0,0 +1,169 @@ +import { prisma } from '@config/prisma'; +import { servedChainIdForFamily } from './battleProgress.overlay'; +import { servedDeploymentId } from '@features/battle-ledger/domain'; +import type { Chain } from '@typings/chain'; + +/** + * Read layer for the pet leaderboard. + * + * Ranks on the *merged* battle record, not on `pet_roster` alone. Since battles stopped + * settling on chain (§L Phase 6) the roster's `win_count`/`loss_count` are frozen at + * whatever the retired path left behind, while the live record accumulates in + * `pet_battle_progress` — so ranking on the roster would rank pets by a number that + * stopped moving, and ranking on progress alone would drop every pet whose whole record + * predates the backend path. + * + * Like `findReadyOpponents`, the merge happens in the query rather than afterwards: the + * ordering *is* the merge here, and a post-sort can only reorder rows a page already + * holds. Same consequence, too — no gRPC fast path, because indexer-go's cache holds + * chain state and has no view of `pet_battle_progress`. + */ + +/** One ranked pet. Carries what a leaderboard row displays, not the full roster shape. */ +export interface LeaderboardEntry { + /** 1-based position in the full ranking, not within the page. */ + rank: number; + chain: Chain; + petId: string; + owner: string; + name: string; + level: number; + rarity: number; + dna: string; + winCount: number; + lossCount: number; + /** Metaplex Core asset pubkey (Solana only); "" on EVM. Needed to address pet art. */ + asset: string; +} + +export interface FindLeaderboardParams { + chain: Chain; + page: number; + pageSize: number; +} + +/** The projected columns, before the rank is attached. */ +interface RankedRow { + chain: string; + petId: string; + owner: string; + name: string; + level: number; + rarity: number; + dna: string; + winCount: number; + lossCount: number; + asset: string; +} + +/** + * A page of the pet leaderboard, ordered by wins and its win-rate tiebreak. + * + * Ordering is wins DESC, then losses ASC, then level DESC, then pet id ASC. The losses + * tiebreak *is* the win-rate tiebreak: among pets on equal wins, fewer losses is a + * strictly higher win rate, so no division is needed and pets are never ranked on a + * ratio computed from a handful of fights. + * + * Pets that have never fought are excluded. A leaderboard of pets with no record would + * be a roster dump with a rank column, and on the current ordering they would all tie + * at the bottom anyway. + */ +export async function findPetLeaderboard( + params: FindLeaderboardParams +): Promise<{ entries: LeaderboardEntry[]; total: number }> { + const chainId = servedChainIdForFamily(params.chain); + const { rows, total } = chainId + ? await queryMerged(params, chainId) + : await queryChainStateOnly(params); + + const offset = params.page * params.pageSize; + return { + entries: rows.map((row, index) => ({ ...row, chain: row.chain as Chain, rank: offset + index + 1 })), + total, + }; +} + +/** The join against `pet_battle_progress`, for a chain family this deployment serves. */ +async function queryMerged( + params: FindLeaderboardParams, + chainId: string +): Promise<{ rows: RankedRow[]; total: number }> { + const deploymentId = servedDeploymentId(); + const skip = params.page * params.pageSize; + + // COALESCE for win/loss, GREATEST for level, matching `overlayRosterPet` and + // `findReadyOpponents`: a progress row supplies the battle record wholesale (nothing + // on chain writes it any more), while level keeps two live writers — backend battles + // raise the row, paid on-chain train()/levelUp() raise the roster. + const [rows, counted] = await Promise.all([ + prisma.$queryRaw` + SELECT r.chain, r.pet_id AS "petId", r.owner, r.name, r.rarity, r.dna, r.asset, + GREATEST(r.level, COALESCE(p.level, 0)) AS level, + COALESCE(p.win_count, r.win_count) AS "winCount", + COALESCE(p.loss_count, r.loss_count) AS "lossCount" + FROM pet_roster r + LEFT JOIN pet_battle_progress p + ON p.pet_id = r.pet_id + AND p.chain_id = ${chainId} + AND p.deployment_id = ${deploymentId} + WHERE r.chain = ${params.chain} + AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + ORDER BY COALESCE(p.win_count, r.win_count) DESC, + COALESCE(p.loss_count, r.loss_count) ASC, + GREATEST(r.level, COALESCE(p.level, 0)) DESC, + r.pet_id ASC + LIMIT ${params.pageSize} OFFSET ${skip} + `, + prisma.$queryRaw<{ total: bigint }[]>` + SELECT COUNT(*) AS total + FROM pet_roster r + LEFT JOIN pet_battle_progress p + ON p.pet_id = r.pet_id + AND p.chain_id = ${chainId} + AND p.deployment_id = ${deploymentId} + WHERE r.chain = ${params.chain} + AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + `, + ]); + + return { rows, total: Number(counted[0]?.total ?? 0) }; +} + +/** The same ranking without progression, for a chain family this deployment does not serve. */ +async function queryChainStateOnly( + params: FindLeaderboardParams +): Promise<{ rows: RankedRow[]; total: number }> { + const where = { + chain: params.chain, + OR: [{ winCount: { gt: 0 } }, { lossCount: { gt: 0 } }], + }; + + const [rows, total] = await Promise.all([ + prisma.petRoster.findMany({ + where, + select: { + chain: true, + petId: true, + owner: true, + name: true, + level: true, + rarity: true, + dna: true, + winCount: true, + lossCount: true, + asset: true, + }, + orderBy: [ + { winCount: 'desc' }, + { lossCount: 'asc' }, + { level: 'desc' }, + { petId: 'asc' }, + ], + skip: params.page * params.pageSize, + take: params.pageSize, + }), + prisma.petRoster.count({ where }), + ]); + + return { rows, total }; +} diff --git a/backend/tests/graphql/resolvers.test.ts b/backend/tests/graphql/resolvers.test.ts index 6aebdfc0..daa68893 100644 --- a/backend/tests/graphql/resolvers.test.ts +++ b/backend/tests/graphql/resolvers.test.ts @@ -7,6 +7,9 @@ vi.mock('@repositories/roster.repository', () => ({ vi.mock('../../src/grpc/estimateWin', () => ({ tryGrpcEstimateWin: vi.fn(), })); +vi.mock('@repositories/leaderboard.repository', () => ({ + findPetLeaderboard: vi.fn(), +})); // The overlay's own merge rule is covered in repositories/battleProgress.overlay.test.ts; // here it is stubbed to a pass-through so these tests stay about resolver shaping. vi.mock('@repositories/battleProgress.overlay', () => ({ @@ -16,6 +19,7 @@ vi.mock('@repositories/battleProgress.overlay', () => ({ import { rootValue } from '../../src/graphql/resolvers'; import { findReadyOpponents, getPetById } from '@repositories/roster.repository'; +import { findPetLeaderboard } from '@repositories/leaderboard.repository'; import { tryGrpcEstimateWin } from '../../src/grpc/estimateWin'; const ctx = { caller: '0xcaller' }; @@ -59,6 +63,43 @@ describe('opponents resolver', () => { }); }); +describe('leaderboard resolver', () => { + const entry = { + rank: 1, + chain: 'evm', + petId: '42', + owner: '0xowner', + name: 'Rex', + level: 5, + rarity: 1, + dna: '123', + winCount: 3, + lossCount: 1, + asset: '', + }; + + it('renames petId to id and passes the page through', async () => { + vi.mocked(findPetLeaderboard).mockResolvedValue({ entries: [entry], total: 1 }); + + const result = await rootValue.leaderboard({ chain: 'evm', page: 1 }, ctx); + + expect(result.total).toBe(1); + expect(result.page).toBe(1); + expect(result.entries[0]).toMatchObject({ id: '42', rank: 1 }); + expect(result.entries[0]).not.toHaveProperty('petId'); + }); + + it('throws for an unsupported chain', async () => { + await expect(rootValue.leaderboard({ chain: 'tron' }, ctx)).rejects.toThrow('chain must be one of'); + }); + + it('clamps pageSize to MAX_PAGE_SIZE=50', async () => { + vi.mocked(findPetLeaderboard).mockResolvedValue({ entries: [], total: 0 }); + await rootValue.leaderboard({ chain: 'evm', pageSize: 999 }, ctx); + expect(vi.mocked(findPetLeaderboard).mock.calls[0][0].pageSize).toBe(50); + }); +}); + describe('pet resolver', () => { it('returns the mapped pet when found', async () => { vi.mocked(getPetById).mockResolvedValue(rosterPet); diff --git a/backend/tests/graphql/schema.test.ts b/backend/tests/graphql/schema.test.ts index c242450c..f4f7255a 100644 --- a/backend/tests/graphql/schema.test.ts +++ b/backend/tests/graphql/schema.test.ts @@ -21,9 +21,9 @@ function fieldsOf(typeName: string): Record { describe('GraphQL schema — Query surface', () => { const query = fieldsOf('Query'); - it('exposes opponents, pet, searchPets, allPets, battleProgress, and winEstimate', () => { + it('exposes opponents, pet, searchPets, allPets, battleProgress, leaderboard, and winEstimate', () => { expect(Object.keys(query).sort()).toEqual([ - 'allPets', 'battleProgress', 'opponents', 'pet', 'searchPets', 'winEstimate', + 'allPets', 'battleProgress', 'leaderboard', 'opponents', 'pet', 'searchPets', 'winEstimate', ]); }); @@ -44,6 +44,25 @@ describe('GraphQL schema — Query surface', () => { it('returns a nullable WinEstimate (null = odds unavailable)', () => { expect(query.winEstimate?.type).toBe('WinEstimate'); }); + + it('returns a non-null LeaderboardPage from leaderboard', () => { + expect(query.leaderboard?.type).toBe('LeaderboardPage!'); + }); +}); + +describe('GraphQL schema — LeaderboardEntry', () => { + const entry = fieldsOf('LeaderboardEntry'); + + it('carries the rank plus the fields a row displays', () => { + for (const f of ['rank', 'id', 'chain', 'owner', 'name', 'dna', 'level', 'rarity', 'winCount', 'lossCount', 'asset']) { + expect(entry, `missing field ${f}`).toHaveProperty(f); + } + }); + + it('types rank as Int and carries `asset` so Solana rows can address pet art', () => { + expect(entry.rank?.type).toBe('Int!'); + expect(entry.asset?.type).toBe('String!'); + }); }); describe('GraphQL schema — OpponentPet v2 fields', () => { diff --git a/backend/tests/repositories/leaderboard.repository.test.ts b/backend/tests/repositories/leaderboard.repository.test.ts new file mode 100644 index 00000000..b43778b4 --- /dev/null +++ b/backend/tests/repositories/leaderboard.repository.test.ts @@ -0,0 +1,117 @@ +import { describe, expect, it, vi, beforeEach } from 'vitest'; + +vi.mock('@config/prisma', () => ({ + prisma: { + petRoster: { + findMany: vi.fn(), + count: vi.fn(), + }, + $queryRaw: vi.fn(), + }, +})); + +const servedChainIdForFamily = vi.fn(() => 'eip155:31337' as string | null); +vi.mock('../../src/repositories/battleProgress.overlay', () => ({ + servedChainIdForFamily: (chain: string) => servedChainIdForFamily(chain), +})); + +import { findPetLeaderboard } from '../../src/repositories/leaderboard.repository'; +import { prisma } from '@config/prisma'; + +const rankedRow = { + chain: 'evm', + petId: '7', + owner: '0xowner', + name: 'Rex', + level: 9, + rarity: 3, + dna: '123', + winCount: 12, + lossCount: 2, + asset: '', +}; + +/** `$queryRaw` is called twice per page: the rows, then their count. */ +function mockJoinQuery(rows: unknown[], total: number) { + vi.mocked(prisma.$queryRaw) + .mockResolvedValueOnce(rows as never) + .mockResolvedValueOnce([{ total: BigInt(total) }] as never); +} + +/** The SQL text of the nth `$queryRaw` call, whitespace-collapsed for matching. */ +function sqlOfCall(index: number): string { + const [template] = vi.mocked(prisma.$queryRaw).mock.calls[index] as unknown as [string[]]; + return template.join(' ? ').replace(/\s+/g, ' '); +} + +beforeEach(() => { + vi.clearAllMocks(); + servedChainIdForFamily.mockReturnValue('eip155:31337'); +}); + +describe('findPetLeaderboard', () => { + it('returns the ranked rows and their total', async () => { + mockJoinQuery([rankedRow], 1); + + const result = await findPetLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + + expect(result.total).toBe(1); + expect(result.entries[0].petId).toBe('7'); + expect(result.entries[0].rank).toBe(1); + }); + + it('numbers ranks absolutely, continuing across pages', async () => { + // A rank that restarted at 1 on every page would say the 21st pet is the best one. + mockJoinQuery([rankedRow, { ...rankedRow, petId: '8' }], 42); + + const result = await findPetLeaderboard({ chain: 'evm', page: 2, pageSize: 20 }); + + expect(result.entries.map((entry) => entry.rank)).toEqual([41, 42]); + }); + + it('ranks on the merged battle record, not the frozen roster counters', async () => { + // The roster's win/loss stopped moving when battles left the chain, so ordering on + // r.win_count alone would freeze the leaderboard at the retired path's last state. + mockJoinQuery([], 0); + + await findPetLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + + const sql = sqlOfCall(0); + expect(sql).toContain('LEFT JOIN pet_battle_progress p'); + expect(sql).toContain('ORDER BY COALESCE(p.win_count, r.win_count) DESC'); + expect(sql).toContain('COALESCE(p.loss_count, r.loss_count) ASC'); + expect(sql).toContain('GREATEST(r.level, COALESCE(p.level, 0)) DESC'); + expect(sql).toContain('r.pet_id ASC'); + }); + + it('excludes pets that have never fought, in the query and in the count', async () => { + mockJoinQuery([], 0); + + await findPetLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + + const battled = 'COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0'; + expect(sqlOfCall(0)).toContain(battled); + // The count must apply the same filter, or `total` would page past the last row. + expect(sqlOfCall(1)).toContain(battled); + }); + + it('falls back to chain state for a chain family this deployment does not serve', async () => { + servedChainIdForFamily.mockReturnValue(null); + vi.mocked(prisma.petRoster.findMany).mockResolvedValue([rankedRow] as never); + vi.mocked(prisma.petRoster.count).mockResolvedValue(1 as never); + + const result = await findPetLeaderboard({ chain: 'solana', page: 0, pageSize: 20 }); + + expect(prisma.$queryRaw).not.toHaveBeenCalled(); + expect(result.entries[0].rank).toBe(1); + + const args = vi.mocked(prisma.petRoster.findMany).mock.calls[0][0]; + expect(args?.orderBy).toEqual([ + { winCount: 'desc' }, + { lossCount: 'asc' }, + { level: 'desc' }, + { petId: 'asc' }, + ]); + expect(args?.where?.OR).toEqual([{ winCount: { gt: 0 } }, { lossCount: { gt: 0 } }]); + }); +}); From 6bbdc3731a271530b09530782ebf69d5aafc4844 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 07:49:26 -0400 Subject: [PATCH 06/61] feat(backend): rank players by their pets' combined battle record --- backend/src/graphql/resolvers.ts | 14 +- backend/src/graphql/schema.ts | 30 ++++ .../repositories/leaderboard.repository.ts | 140 +++++++++++++++++- backend/tests/graphql/resolvers.test.ts | 27 +++- backend/tests/graphql/schema.test.ts | 24 ++- .../leaderboard.repository.test.ts | 87 ++++++++++- 6 files changed, 316 insertions(+), 6 deletions(-) diff --git a/backend/src/graphql/resolvers.ts b/backend/src/graphql/resolvers.ts index e532a7dc..a1f27758 100644 --- a/backend/src/graphql/resolvers.ts +++ b/backend/src/graphql/resolvers.ts @@ -1,6 +1,6 @@ import { findReadyOpponents, getAllPets, getPetById, searchPets, type RosterPet } from '@repositories/roster.repository'; import { findBattleProgress, withBattleProgress } from '@repositories/battleProgress.overlay'; -import { findPetLeaderboard } from '@repositories/leaderboard.repository'; +import { findPetLeaderboard, findPlayerLeaderboard } from '@repositories/leaderboard.repository'; import { tryGrpcEstimateWin } from '@grpc-client/estimateWin'; import { isSupportedChain, SUPPORTED_CHAINS } from '@typings/chain'; @@ -121,6 +121,18 @@ export const rootValue = { }; }, + playerLeaderboard: async (args: LeaderboardArgs) => { + if (!isSupportedChain(args.chain)) { + throw new Error(`chain must be one of: ${SUPPORTED_CHAINS.join(', ')}`); + } + + const page = Math.max(0, args.page ?? 0); + const pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, args.pageSize ?? DEFAULT_PAGE_SIZE)); + const { entries, total } = await findPlayerLeaderboard({ chain: args.chain, page, pageSize }); + + return { entries, total, page, pageSize }; + }, + searchPets: async (args: SearchPetsArgs) => { if (!isSupportedChain(args.chain)) { throw new Error(`chain must be one of: ${SUPPORTED_CHAINS.join(', ')}`); diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index 893faac0..cf4d76de 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -86,6 +86,25 @@ export const schema = buildSchema(` pageSize: Int! } + "One ranked owner, over the same merged battle record as LeaderboardEntry." + type PlayerLeaderboardEntry { + "1-based position in the full ranking, not within the page." + rank: Int! + "Wallet address / pubkey. EVM addresses are lowercased; Solana pubkeys are not." + owner: String! + winCount: Int! + lossCount: Int! + "How many of this owner's pets have a battle record." + petCount: Int! + } + + type PlayerLeaderboardPage { + entries: [PlayerLeaderboardEntry!]! + total: Int! + page: Int! + pageSize: Int! + } + type OpponentsPage { opponents: [OpponentPet!]! total: Int! @@ -120,6 +139,17 @@ export const schema = buildSchema(` pageSize: Int ): LeaderboardPage! + """ + Owners ranked by their pets' combined battle record, ordered the same way as + the pet board. Only pets that have fought are summed, so petCount is "pets with + a record" and an owner whose pets have never fought does not appear. + """ + playerLeaderboard( + chain: String! + page: Int + pageSize: Int + ): PlayerLeaderboardPage! + """ Search pets by name prefix or exact numeric ID across the whole roster. Returns up to 'limit' results (default 10, max 20). diff --git a/backend/src/repositories/leaderboard.repository.ts b/backend/src/repositories/leaderboard.repository.ts index e7762d3a..6cb600f2 100644 --- a/backend/src/repositories/leaderboard.repository.ts +++ b/backend/src/repositories/leaderboard.repository.ts @@ -1,10 +1,13 @@ +import { Prisma } from '@generated/prisma/client'; + import { prisma } from '@config/prisma'; import { servedChainIdForFamily } from './battleProgress.overlay'; import { servedDeploymentId } from '@features/battle-ledger/domain'; import type { Chain } from '@typings/chain'; /** - * Read layer for the pet leaderboard. + * Read layer for the leaderboards: pets ranked individually, and owners ranked by their + * pets' combined record. * * Ranks on the *merged* battle record, not on `pet_roster` alone. Since battles stopped * settling on chain (§L Phase 6) the roster's `win_count`/`loss_count` are frozen at @@ -19,6 +22,18 @@ import type { Chain } from '@typings/chain'; * chain state and has no view of `pet_battle_progress`. */ +/** One ranked owner: their pets' battle records, summed. */ +export interface PlayerLeaderboardEntry { + /** 1-based position in the full ranking, not within the page. */ + rank: number; + /** Wallet address / pubkey. EVM addresses are folded to lowercase; see `ownerKey`. */ + owner: string; + winCount: number; + lossCount: number; + /** How many of this owner's pets have a battle record. */ + petCount: number; +} + /** One ranked pet. Carries what a leaderboard row displays, not the full roster shape. */ export interface LeaderboardEntry { /** 1-based position in the full ranking, not within the page. */ @@ -129,6 +144,129 @@ async function queryMerged( return { rows, total: Number(counted[0]?.total ?? 0) }; } +/** + * What one owner is grouped by. + * + * EVM addresses are folded, base58 Solana pubkeys are not — the same split + * `normalizeAccount` makes, and the same one `findReadyOpponents` applies to its consent + * match. It matters more here than there: indexer-go is not guaranteed to write the + * roster in one case, and an unfolded EVM group would list a single wallet twice with its + * record split between the rows. Folding base58 would do the opposite damage, merging two + * distinct pubkeys into one player. + */ +function ownerKey(chain: Chain): Prisma.Sql { + return chain === 'evm' ? Prisma.sql`LOWER(r.owner)` : Prisma.sql`r.owner`; +} + +/** + * A page of the player leaderboard: owners ranked by their pets' combined record. + * + * Same ordering rule as the pet board — wins DESC, then losses ASC as the win-rate + * tiebreak — with the owner key as the stable final tiebreak. Only pets that have fought + * are summed, so `petCount` reads as "pets with a record" rather than "pets owned", and + * an owner with no battled pets does not appear at all. + */ +export async function findPlayerLeaderboard( + params: FindLeaderboardParams +): Promise<{ entries: PlayerLeaderboardEntry[]; total: number }> { + const chainId = servedChainIdForFamily(params.chain); + const { rows, total } = chainId + ? await queryPlayersMerged(params, chainId) + : await queryPlayersFromChainState(params); + + const offset = params.page * params.pageSize; + return { + entries: rows.map((row, index) => ({ ...row, rank: offset + index + 1 })), + total, + }; +} + +/** The aggregate before its rank is attached. */ +interface PlayerRow { + owner: string; + winCount: number; + lossCount: number; + petCount: number; +} + +/** The owner aggregate over merged records, for a chain family this deployment serves. */ +async function queryPlayersMerged( + params: FindLeaderboardParams, + chainId: string +): Promise<{ rows: PlayerRow[]; total: number }> { + const deploymentId = servedDeploymentId(); + const skip = params.page * params.pageSize; + const owner = ownerKey(params.chain); + + // The SUMs are cast because Postgres widens them to bigint, which Prisma would hand + // back as a BigInt the GraphQL Int serializer cannot take. A player's battle count + // has no way to approach the int range. + const [rows, counted] = await Promise.all([ + prisma.$queryRaw` + SELECT ${owner} AS owner, + SUM(COALESCE(p.win_count, r.win_count))::int AS "winCount", + SUM(COALESCE(p.loss_count, r.loss_count))::int AS "lossCount", + COUNT(*)::int AS "petCount" + FROM pet_roster r + LEFT JOIN pet_battle_progress p + ON p.pet_id = r.pet_id + AND p.chain_id = ${chainId} + AND p.deployment_id = ${deploymentId} + WHERE r.chain = ${params.chain} + AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + GROUP BY ${owner} + ORDER BY "winCount" DESC, "lossCount" ASC, ${owner} ASC + LIMIT ${params.pageSize} OFFSET ${skip} + `, + prisma.$queryRaw<{ total: bigint }[]>` + SELECT COUNT(*) AS total FROM ( + SELECT 1 + FROM pet_roster r + LEFT JOIN pet_battle_progress p + ON p.pet_id = r.pet_id + AND p.chain_id = ${chainId} + AND p.deployment_id = ${deploymentId} + WHERE r.chain = ${params.chain} + AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + GROUP BY ${owner} + ) owners + `, + ]); + + return { rows, total: Number(counted[0]?.total ?? 0) }; +} + +/** The same aggregate without progression, for a chain family this deployment does not serve. */ +async function queryPlayersFromChainState( + params: FindLeaderboardParams +): Promise<{ rows: PlayerRow[]; total: number }> { + const skip = params.page * params.pageSize; + const owner = ownerKey(params.chain); + + const [rows, counted] = await Promise.all([ + prisma.$queryRaw` + SELECT ${owner} AS owner, + SUM(r.win_count)::int AS "winCount", + SUM(r.loss_count)::int AS "lossCount", + COUNT(*)::int AS "petCount" + FROM pet_roster r + WHERE r.chain = ${params.chain} + AND r.win_count + r.loss_count > 0 + GROUP BY ${owner} + ORDER BY "winCount" DESC, "lossCount" ASC, ${owner} ASC + LIMIT ${params.pageSize} OFFSET ${skip} + `, + prisma.$queryRaw<{ total: bigint }[]>` + SELECT COUNT(DISTINCT ${owner}) AS total + FROM pet_roster r + WHERE r.chain = ${params.chain} + AND r.win_count + r.loss_count > 0 + `, + ]); + + return { rows, total: Number(counted[0]?.total ?? 0) }; +} + /** The same ranking without progression, for a chain family this deployment does not serve. */ async function queryChainStateOnly( params: FindLeaderboardParams diff --git a/backend/tests/graphql/resolvers.test.ts b/backend/tests/graphql/resolvers.test.ts index daa68893..0796af44 100644 --- a/backend/tests/graphql/resolvers.test.ts +++ b/backend/tests/graphql/resolvers.test.ts @@ -9,6 +9,7 @@ vi.mock('../../src/grpc/estimateWin', () => ({ })); vi.mock('@repositories/leaderboard.repository', () => ({ findPetLeaderboard: vi.fn(), + findPlayerLeaderboard: vi.fn(), })); // The overlay's own merge rule is covered in repositories/battleProgress.overlay.test.ts; // here it is stubbed to a pass-through so these tests stay about resolver shaping. @@ -19,7 +20,7 @@ vi.mock('@repositories/battleProgress.overlay', () => ({ import { rootValue } from '../../src/graphql/resolvers'; import { findReadyOpponents, getPetById } from '@repositories/roster.repository'; -import { findPetLeaderboard } from '@repositories/leaderboard.repository'; +import { findPetLeaderboard, findPlayerLeaderboard } from '@repositories/leaderboard.repository'; import { tryGrpcEstimateWin } from '../../src/grpc/estimateWin'; const ctx = { caller: '0xcaller' }; @@ -100,6 +101,30 @@ describe('leaderboard resolver', () => { }); }); +describe('playerLeaderboard resolver', () => { + const entry = { rank: 1, owner: '0xowner', winCount: 20, lossCount: 4, petCount: 3 }; + + it('passes the page through unchanged (no petId to rename here)', async () => { + vi.mocked(findPlayerLeaderboard).mockResolvedValue({ entries: [entry], total: 1 }); + + const result = await rootValue.playerLeaderboard({ chain: 'evm', page: 2 }, ctx); + + expect(result.total).toBe(1); + expect(result.page).toBe(2); + expect(result.entries[0]).toEqual(entry); + }); + + it('throws for an unsupported chain', async () => { + await expect(rootValue.playerLeaderboard({ chain: 'tron' }, ctx)).rejects.toThrow('chain must be one of'); + }); + + it('clamps pageSize to MAX_PAGE_SIZE=50', async () => { + vi.mocked(findPlayerLeaderboard).mockResolvedValue({ entries: [], total: 0 }); + await rootValue.playerLeaderboard({ chain: 'evm', pageSize: 999 }, ctx); + expect(vi.mocked(findPlayerLeaderboard).mock.calls[0][0].pageSize).toBe(50); + }); +}); + describe('pet resolver', () => { it('returns the mapped pet when found', async () => { vi.mocked(getPetById).mockResolvedValue(rosterPet); diff --git a/backend/tests/graphql/schema.test.ts b/backend/tests/graphql/schema.test.ts index f4f7255a..a1d90c72 100644 --- a/backend/tests/graphql/schema.test.ts +++ b/backend/tests/graphql/schema.test.ts @@ -21,9 +21,10 @@ function fieldsOf(typeName: string): Record { describe('GraphQL schema — Query surface', () => { const query = fieldsOf('Query'); - it('exposes opponents, pet, searchPets, allPets, battleProgress, leaderboard, and winEstimate', () => { + it('exposes the pet reads, both leaderboards, battleProgress, and winEstimate', () => { expect(Object.keys(query).sort()).toEqual([ - 'allPets', 'battleProgress', 'leaderboard', 'opponents', 'pet', 'searchPets', 'winEstimate', + 'allPets', 'battleProgress', 'leaderboard', 'opponents', 'pet', 'playerLeaderboard', + 'searchPets', 'winEstimate', ]); }); @@ -48,6 +49,10 @@ describe('GraphQL schema — Query surface', () => { it('returns a non-null LeaderboardPage from leaderboard', () => { expect(query.leaderboard?.type).toBe('LeaderboardPage!'); }); + + it('returns a non-null PlayerLeaderboardPage from playerLeaderboard', () => { + expect(query.playerLeaderboard?.type).toBe('PlayerLeaderboardPage!'); + }); }); describe('GraphQL schema — LeaderboardEntry', () => { @@ -65,6 +70,21 @@ describe('GraphQL schema — LeaderboardEntry', () => { }); }); +describe('GraphQL schema — PlayerLeaderboardEntry', () => { + const entry = fieldsOf('PlayerLeaderboardEntry'); + + it('carries the rank, owner, and the summed record', () => { + for (const f of ['rank', 'owner', 'winCount', 'lossCount', 'petCount']) { + expect(entry, `missing field ${f}`).toHaveProperty(f); + } + }); + + it('has no pet-specific fields — a player row is an aggregate, not a pet', () => { + expect(entry).not.toHaveProperty('id'); + expect(entry).not.toHaveProperty('dna'); + }); +}); + describe('GraphQL schema — OpponentPet v2 fields', () => { const pet = fieldsOf('OpponentPet'); diff --git a/backend/tests/repositories/leaderboard.repository.test.ts b/backend/tests/repositories/leaderboard.repository.test.ts index b43778b4..0b837555 100644 --- a/backend/tests/repositories/leaderboard.repository.test.ts +++ b/backend/tests/repositories/leaderboard.repository.test.ts @@ -15,7 +15,7 @@ vi.mock('../../src/repositories/battleProgress.overlay', () => ({ servedChainIdForFamily: (chain: string) => servedChainIdForFamily(chain), })); -import { findPetLeaderboard } from '../../src/repositories/leaderboard.repository'; +import { findPetLeaderboard, findPlayerLeaderboard } from '../../src/repositories/leaderboard.repository'; import { prisma } from '@config/prisma'; const rankedRow = { @@ -44,6 +44,21 @@ function sqlOfCall(index: number): string { return template.join(' ? ').replace(/\s+/g, ' '); } +/** + * The SQL of any `Prisma.Sql` fragments interpolated into the nth call. + * + * `sqlOfCall` only sees the literal chunks, so the owner key — a nested fragment — is + * invisible to it. `$queryRaw` is mocked, so the nesting is never flattened. + */ +function fragmentsOfCall(index: number): string { + const [, ...values] = vi.mocked(prisma.$queryRaw).mock.calls[index] as unknown as [string[], ...unknown[]]; + return values + .filter((value): value is { sql: string } => typeof (value as { sql?: unknown })?.sql === 'string') + .map((fragment) => fragment.sql) + .join(' ') + .replace(/\s+/g, ' '); +} + beforeEach(() => { vi.clearAllMocks(); servedChainIdForFamily.mockReturnValue('eip155:31337'); @@ -115,3 +130,73 @@ describe('findPetLeaderboard', () => { expect(args?.where?.OR).toEqual([{ winCount: { gt: 0 } }, { lossCount: { gt: 0 } }]); }); }); + +describe('findPlayerLeaderboard', () => { + const playerRow = { owner: '0xowner', winCount: 20, lossCount: 4, petCount: 3 }; + + it('returns the ranked owners and their total', async () => { + mockJoinQuery([playerRow], 1); + + const result = await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + + expect(result.total).toBe(1); + expect(result.entries[0]).toMatchObject({ owner: '0xowner', rank: 1, petCount: 3 }); + }); + + it('numbers ranks absolutely, continuing across pages', async () => { + mockJoinQuery([playerRow, { ...playerRow, owner: '0xother' }], 30); + + const result = await findPlayerLeaderboard({ chain: 'evm', page: 1, pageSize: 20 }); + + expect(result.entries.map((entry) => entry.rank)).toEqual([21, 22]); + }); + + it('folds EVM owners to one group so a wallet is not listed twice', async () => { + // indexer-go is not guaranteed to write the roster in one case, and an unfolded + // group would split a single wallet's record across two rows. + mockJoinQuery([], 0); + + await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + + expect(fragmentsOfCall(0)).toContain('LOWER(r.owner)'); + }); + + it('leaves Solana pubkeys unfolded, since base58 is case-significant', async () => { + // Folding here would merge two distinct pubkeys into one player. + mockJoinQuery([], 0); + + await findPlayerLeaderboard({ chain: 'solana', page: 0, pageSize: 20 }); + + const fragments = fragmentsOfCall(0); + expect(fragments).toContain('r.owner'); + expect(fragments).not.toContain('LOWER('); + }); + + it('sums the merged record and counts owners, not pets', async () => { + mockJoinQuery([], 0); + + await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + + const sql = sqlOfCall(0); + expect(sql).toContain('SUM(COALESCE(p.win_count, r.win_count))::int'); + expect(sql).toContain('SUM(COALESCE(p.loss_count, r.loss_count))::int'); + expect(sql).toContain('ORDER BY "winCount" DESC, "lossCount" ASC'); + // The total counts grouped owners: COUNT(*) over the ungrouped join would count + // pets, and page the client past the last owner. + expect(sqlOfCall(1)).toContain('SELECT COUNT(*) AS total FROM ('); + expect(sqlOfCall(1)).toContain('GROUP BY'); + }); + + it('sums frozen roster counters for a chain family this deployment does not serve', async () => { + servedChainIdForFamily.mockReturnValue(null); + mockJoinQuery([playerRow], 1); + + const result = await findPlayerLeaderboard({ chain: 'solana', page: 0, pageSize: 20 }); + + expect(result.entries[0].rank).toBe(1); + const sql = sqlOfCall(0); + expect(sql).toContain('SUM(r.win_count)::int'); + expect(sql).not.toContain('pet_battle_progress'); + expect(sqlOfCall(1)).toContain('COUNT(DISTINCT'); + }); +}); From 94f7f6ba7539ff22ffa1a9eec4c408039b2aff05 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 08:04:46 -0400 Subject: [PATCH 07/61] feat(frontend): add pet and player leaderboard screens --- frontend/src/assets/nav-icons/leaderboard.svg | 1 + .../components/layout/sidebar/nav-items.ts | 9 + .../components/leaderboard/index.module.css | 164 ++++++++++++ frontend/src/components/leaderboard/index.tsx | 236 ++++++++++++++++++ frontend/src/components/ui/icon/index.tsx | 2 + frontend/src/constants/interactionRoutes.ts | 3 + frontend/src/pages/leaderboard/index.tsx | 7 + frontend/src/router/app-routes/index.tsx | 2 + .../tests/components/leaderboard.test.tsx | 148 +++++++++++ shared/src/hooks/index.ts | 14 ++ .../src/hooks/leaderboard/useLeaderboard.ts | 106 ++++++++ .../hooks/leaderboard/usePlayerLeaderboard.ts | 96 +++++++ 12 files changed, 788 insertions(+) create mode 100644 frontend/src/assets/nav-icons/leaderboard.svg create mode 100644 frontend/src/components/leaderboard/index.module.css create mode 100644 frontend/src/components/leaderboard/index.tsx create mode 100644 frontend/src/pages/leaderboard/index.tsx create mode 100644 frontend/tests/components/leaderboard.test.tsx create mode 100644 shared/src/hooks/leaderboard/useLeaderboard.ts create mode 100644 shared/src/hooks/leaderboard/usePlayerLeaderboard.ts diff --git a/frontend/src/assets/nav-icons/leaderboard.svg b/frontend/src/assets/nav-icons/leaderboard.svg new file mode 100644 index 00000000..df836137 --- /dev/null +++ b/frontend/src/assets/nav-icons/leaderboard.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/components/layout/sidebar/nav-items.ts b/frontend/src/components/layout/sidebar/nav-items.ts index b7bd0c8b..db17a367 100644 --- a/frontend/src/components/layout/sidebar/nav-items.ts +++ b/frontend/src/components/layout/sidebar/nav-items.ts @@ -3,6 +3,7 @@ import { BATTLE_PATH, BREED_PATH, DASHBOARD_HOME, + LEADERBOARD_PATH, LEVELUP_PATH, MARRIAGE_PATH, RENAME_PATH, @@ -17,6 +18,7 @@ import itemsIcon from '@assets/nav-icons/items.svg'; import shardIcon from '@assets/nav-icons/shard.svg'; import marriageIcon from '@assets/nav-icons/marriage.svg'; import renameIcon from '@assets/nav-icons/rename.svg'; +import leaderboardIcon from '@assets/nav-icons/leaderboard.svg'; export type NavItem = { id: string; @@ -48,4 +50,11 @@ export const NAV_ITEMS: readonly NavItem[] = [ { id: 'shard', label: 'Shard Forge', iconSrc: shardIcon, tone: 'cyan', deferred: true }, { id: 'marriage', label: 'Marriage', iconSrc: marriageIcon, tone: 'magenta', path: MARRIAGE_PATH }, { id: 'rename', label: 'Rename Pet', iconSrc: renameIcon, tone: 'cyan', path: RENAME_PATH }, + { + id: 'leaderboard', + label: 'Leaderboard', + iconSrc: leaderboardIcon, + tone: 'amber', + path: LEADERBOARD_PATH, + }, ]; diff --git a/frontend/src/components/leaderboard/index.module.css b/frontend/src/components/leaderboard/index.module.css new file mode 100644 index 00000000..cd53e4bc --- /dev/null +++ b/frontend/src/components/leaderboard/index.module.css @@ -0,0 +1,164 @@ +/* CSS Module — class names are local; reference via `import styles from './index.module.css'`. + Leaderboard: a read-only ranking table, amber accent to match the trophy. */ +.tabs { + display: flex; + gap: 8px; + margin-bottom: 14px; +} + +.tab { + padding: 6px 16px; + border-radius: 999px; + border: 1px solid rgb(251 191 36 / 25%); + background: transparent; + color: inherit; + font: inherit; + font-size: 0.9rem; + cursor: pointer; + opacity: 0.7; + transition: opacity 0.15s ease, border-color 0.15s ease, background 0.15s ease; +} + +.tab:hover { + opacity: 1; +} + +.tab.isActive { + opacity: 1; + border-color: rgb(251 191 36 / 60%); + background: rgb(251 191 36 / 12%); +} + +.list { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + gap: 6px; +} + +/* Fixed track widths so ranks, records and rates line up down the column; only the + name track flexes. */ +.row { + display: grid; + grid-template-columns: 3rem 2.2rem minmax(0, 1fr) 6.5rem 3.5rem; + align-items: center; + gap: 10px; + padding: 8px 12px; + border-radius: 10px; + border: 1px solid rgb(148 163 184 / 14%); + background: var(--cp-surface); +} + +/* The connected wallet's own rows, so a player finds themselves without reading + every address. */ +.row.isYou { + border-color: rgb(251 191 36 / 55%); + background: rgb(251 191 36 / 8%); +} + +.rank { + font-size: 1.05rem; + font-variant-numeric: tabular-nums; + text-align: center; +} + +.avatar { + font-size: 1.4rem; + line-height: 1; + text-align: center; +} + +.name { + display: flex; + flex-direction: column; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.sub { + font-size: 0.75rem; + opacity: 0.6; +} + +.record { + display: flex; + gap: 8px; + font-size: 0.9rem; + font-variant-numeric: tabular-nums; +} + +.wins { + color: rgb(52 211 153); +} + +.losses { + color: rgb(251 113 133); +} + +.rate { + text-align: right; + font-size: 0.9rem; + font-variant-numeric: tabular-nums; + opacity: 0.8; +} + +.pager { + display: flex; + align-items: center; + justify-content: center; + gap: 14px; + margin-top: 16px; +} + +.pager button { + padding: 5px 14px; + border-radius: 8px; + border: 1px solid rgb(148 163 184 / 25%); + background: transparent; + color: inherit; + font: inherit; + font-size: 0.85rem; + cursor: pointer; +} + +.pager button:disabled { + opacity: 0.35; + cursor: default; +} + +.pageLabel { + font-size: 0.85rem; + opacity: 0.7; + font-variant-numeric: tabular-nums; +} + +.empty, +.error { + margin: 24px 0; + text-align: center; + font-size: 0.9rem; +} + +.empty { + opacity: 0.7; +} + +.error { + color: rgb(251 113 133); +} + +@media (width <= 640px) { + /* The rate is the one column derivable from the record beside it, so it is what + goes when the row runs out of room. */ + .row { + grid-template-columns: 2.5rem 2rem minmax(0, 1fr) 5.5rem; + } + + .rate { + display: none; + } +} diff --git a/frontend/src/components/leaderboard/index.tsx b/frontend/src/components/leaderboard/index.tsx new file mode 100644 index 00000000..3b7d9e7b --- /dev/null +++ b/frontend/src/components/leaderboard/index.tsx @@ -0,0 +1,236 @@ +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { + useChainCapabilities, + useLeaderboard, + usePlayerLeaderboard, + type LeaderboardEntry, + type PlayerLeaderboardEntry, +} from '@shared/core'; + +import DashboardPanel from '@components/common/dashboard-panel'; +import StateCard from '@components/pet/interactions/state-card'; +import PetArt from '@components/pet/pet-art'; +import Icon, { TrophyIcon } from '@components/ui/icon'; +import { DASHBOARD_HOME } from '@constants/interactionRoutes'; +import { Tones } from '@constants/tones'; +import styles from './index.module.css'; + +/** Which ranking is showing. Pets is the default: it is the one with a pet in it. */ +type Board = 'pets' | 'players'; + +/** Win rate as a percentage, or null when the row has no battles to divide by. */ +function winRate(wins: number, losses: number): number | null { + const fought = wins + losses; + return fought === 0 ? null : Math.round((wins / fought) * 100); +} + +/** `0x1234…abcd`, since a full address is longer than the column it sits in. */ +function shortAddress(address: string): string { + return address.length > 12 ? `${address.slice(0, 6)}…${address.slice(-4)}` : address; +} + +/** Medal for the top three, plain number below. Rank is absolute, so this holds on page 2+. */ +function rankBadge(rank: number): string { + return rank === 1 ? '🥇' : rank === 2 ? '🥈' : rank === 3 ? '🥉' : `#${rank}`; +} + +const PetRow: React.FC<{ entry: LeaderboardEntry; isYou: boolean }> = ({ entry, isYou }) => { + const rate = winRate(entry.winCount, entry.lossCount); + return ( +

  • + {rankBadge(entry.rank)} + + + + + {entry.name} + Lv {entry.level} + + + {entry.winCount}W + {entry.lossCount}L + + {rate == null ? '—' : `${rate}%`} +
  • + ); +}; + +const PlayerRow: React.FC<{ entry: PlayerLeaderboardEntry; isYou: boolean }> = ({ + entry, + isYou, +}) => { + const rate = winRate(entry.winCount, entry.lossCount); + return ( +
  • + {rankBadge(entry.rank)} + + 👤 + + + {shortAddress(entry.owner)} + + {entry.petCount} pet{entry.petCount === 1 ? '' : 's'} + + + + {entry.winCount}W + {entry.lossCount}L + + {rate == null ? '—' : `${rate}%`} +
  • + ); +}; + +/** + * Leaderboard view: pets ranked by battle record, and their owners ranked by the same + * record summed. + * + * A read-only page rather than an interaction panel — nothing here selects a pet or + * signs anything, so it composes `DashboardPanel` directly instead of going through + * `InteractionStandalone`. + * + * Ranking is entirely the backend's. It ranks over the merged record + * (`pet_battle_progress` above the frozen `pet_roster` counters) inside the query that + * orders the rows, so this renders the page it is given and never re-sorts: a + * client-side sort could only reorder rows the server already picked, which would + * quietly disagree with `rank`. + */ +const Leaderboard: React.FC = () => { + const navigate = useNavigate(); + const { isConnected, activeKind, walletAddress } = useChainCapabilities(); + const [board, setBoard] = useState('pets'); + const [page, setPage] = useState(0); + + const pets = useLeaderboard({ chain: activeKind, page, enabled: board === 'pets' }); + const players = usePlayerLeaderboard({ + chain: activeKind, + page, + enabled: board === 'players', + }); + + const active = board === 'pets' ? pets : players; + const goBack = () => navigate(DASHBOARD_HOME); + + if (!isConnected) { + return ( + + + Leaderboard + + } + description="Connect your wallet to see the rankings" + back={goBack} + /> + ); + } + + // The owner strings the backend grouped by are lowercased on EVM and untouched on + // Solana, so compare the same way rather than assuming either case. + const you = + activeKind === 'evm' ? (walletAddress ?? '').toLowerCase() : (walletAddress ?? ''); + /** Folding base58 would let two distinct Solana pubkeys read as the same player. */ + const isYou = (owner: string) => (activeKind === 'evm' ? owner.toLowerCase() === you : owner === you); + + const showBoard = (next: Board) => { + setBoard(next); + // Page 3 of the pet board says nothing about where a player sits, and the two + // boards have different lengths. + setPage(0); + }; + + const lastPage = Math.max(0, Math.ceil(active.total / active.pageSize) - 1); + + return ( + + + Leaderboard + + } + description="Ranked by wins, then by fewest losses" + back={goBack} + > +
    + {(['pets', 'players'] as const).map((tab) => ( + + ))} +
    + + {active.error ? ( +

    {active.error.message}

    + ) : active.isLoading ? ( +
    +
    +
    + ) : active.total === 0 ? ( +

    + No battles on record yet. Win one and the board fills up. +

    + ) : ( + <> +
      + {board === 'pets' + ? pets.entries.map((entry) => ( + + )) + : players.entries.map((entry) => ( + + ))} +
    + + {lastPage > 0 && ( +
    + + + Page {page + 1} of {lastPage + 1} + + +
    + )} + + )} + + ); +}; + +export default Leaderboard; diff --git a/frontend/src/components/ui/icon/index.tsx b/frontend/src/components/ui/icon/index.tsx index 14db2cb2..cfedb5f1 100644 --- a/frontend/src/components/ui/icon/index.tsx +++ b/frontend/src/components/ui/icon/index.tsx @@ -15,6 +15,7 @@ import { GiShield, GiSparkles, GiSpellBook, + GiTrophy, GiUpgrade, } from 'react-icons/gi'; import { @@ -104,6 +105,7 @@ export { GiShield as ShieldIcon, GiSparkles as SparklesIcon, GiSpellBook as SpellbookIcon, + GiTrophy as TrophyIcon, GiUpgrade as LevelUpIcon, IoCheckmarkSharp as CheckIcon, IoClose as CloseIcon, diff --git a/frontend/src/constants/interactionRoutes.ts b/frontend/src/constants/interactionRoutes.ts index 4fa48983..528d1312 100644 --- a/frontend/src/constants/interactionRoutes.ts +++ b/frontend/src/constants/interactionRoutes.ts @@ -63,3 +63,6 @@ export const TRAIN_PATH = '/train'; export const MARRIAGE_PATH = '/marriage'; export const RENAME_PATH = '/rename'; export const DEFENSE_PATH = '/defense'; + +/** Read-only view, not an interaction — no pet selection, nothing to sign. */ +export const LEADERBOARD_PATH = '/leaderboard'; diff --git a/frontend/src/pages/leaderboard/index.tsx b/frontend/src/pages/leaderboard/index.tsx new file mode 100644 index 00000000..0f8a8a8b --- /dev/null +++ b/frontend/src/pages/leaderboard/index.tsx @@ -0,0 +1,7 @@ +import React from 'react'; +import Leaderboard from '@components/leaderboard'; + +/** Top-level `/leaderboard` page — pet and player rankings (read-only). */ +const LeaderboardPage: React.FC = () => ; + +export default LeaderboardPage; diff --git a/frontend/src/router/app-routes/index.tsx b/frontend/src/router/app-routes/index.tsx index a0bfeaea..b31b065f 100644 --- a/frontend/src/router/app-routes/index.tsx +++ b/frontend/src/router/app-routes/index.tsx @@ -14,6 +14,7 @@ const TrainPage = lazy(() => import('@pages/train')); const MarriagePage = lazy(() => import('@pages/marriage')); const RenamePage = lazy(() => import('@pages/rename')); const DefensePage = lazy(() => import('@pages/defense')); +const LeaderboardPage = lazy(() => import('@pages/leaderboard')); // SCRATCH — remove after visual verification. const BattleOverlayPreview = lazy(() => import('@pages/__preview/battle-overlay-preview')); @@ -40,6 +41,7 @@ const AppRoutes: React.FC = () => { } /> } /> } /> + } /> } /> } /> diff --git a/frontend/tests/components/leaderboard.test.tsx b/frontend/tests/components/leaderboard.test.tsx new file mode 100644 index 00000000..d9f6ebe2 --- /dev/null +++ b/frontend/tests/components/leaderboard.test.tsx @@ -0,0 +1,148 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { render, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { MemoryRouter } from 'react-router-dom'; + +const useChainCapabilities = vi.fn(); +const useLeaderboard = vi.fn(); +const usePlayerLeaderboard = vi.fn(); + +vi.mock('@shared/core', () => ({ + useChainCapabilities: () => useChainCapabilities(), + useLeaderboard: (opts: unknown) => useLeaderboard(opts), + usePlayerLeaderboard: (opts: unknown) => usePlayerLeaderboard(opts), + // PetArt reads these; the leaderboard only ever renders the emoji fallback here, + // since VITE_IMAGE_SERVICE_URL is unset in tests. + getPetAvatar: () => '🐾', + petArtUrl: () => null, +})); + +import Leaderboard from '@components/leaderboard'; + +const YOU = '0xAAAAbbbbCCCCddddEEEEffff0000111122223333'; + +const petEntry = (over: Partial> = {}) => ({ + rank: 1, + id: '1', + chain: 'evm', + owner: YOU.toLowerCase(), + name: 'Yasu', + dna: '9464978781602373', + level: 2, + rarity: 2, + winCount: 5, + lossCount: 2, + asset: '', + ...over, +}); + +const emptyResult = { entries: [], total: 0, pageSize: 20, isLoading: false, error: null }; + +const renderBoard = () => + render( + + + , + ); + +beforeEach(() => { + vi.clearAllMocks(); + useChainCapabilities.mockReturnValue({ + isConnected: true, + activeKind: 'evm', + walletAddress: YOU, + }); + useLeaderboard.mockReturnValue(emptyResult); + usePlayerLeaderboard.mockReturnValue(emptyResult); +}); + +describe('Leaderboard', () => { + it('asks for a wallet before showing rankings', () => { + useChainCapabilities.mockReturnValue({ + isConnected: false, + activeKind: null, + walletAddress: null, + }); + + renderBoard(); + + expect(screen.getByText(/Connect your wallet/i)).toBeInTheDocument(); + }); + + it('renders a pet row with its record and win rate', () => { + useLeaderboard.mockReturnValue({ ...emptyResult, entries: [petEntry()], total: 1 }); + + renderBoard(); + + const row = screen.getByText('Yasu').closest('li') as HTMLElement; + expect(within(row).getByText('5W')).toBeInTheDocument(); + expect(within(row).getByText('2L')).toBeInTheDocument(); + // 5 of 7 fights, rounded. + expect(within(row).getByText('71%')).toBeInTheDocument(); + }); + + it('medals the top three and numbers the rest, using the absolute rank', () => { + useLeaderboard.mockReturnValue({ + ...emptyResult, + entries: [ + petEntry({ rank: 21, id: '21', name: 'Twenty-first' }), + petEntry({ rank: 22, id: '22', name: 'Twenty-second' }), + ], + total: 40, + }); + + renderBoard(); + + // Page 2 rows are not medalled: rank is absolute, not per-page. + expect(screen.getByText('#21')).toBeInTheDocument(); + expect(screen.queryByText('🥇')).toBeNull(); + }); + + it('highlights the connected wallet regardless of address case', () => { + // The backend groups EVM owners lowercased; the wallet reports mixed case. + useLeaderboard.mockReturnValue({ + ...emptyResult, + entries: [petEntry(), petEntry({ rank: 2, id: '2', name: 'Someone else', owner: '0xdead' })], + total: 2, + }); + + renderBoard(); + + const mine = screen.getByText('Yasu').closest('li') as HTMLElement; + const theirs = screen.getByText('Someone else').closest('li') as HTMLElement; + expect(mine.className).not.toEqual(theirs.className); + }); + + it('switches to the player board and back to the first page', async () => { + useLeaderboard.mockReturnValue({ ...emptyResult, entries: [petEntry()], total: 1 }); + usePlayerLeaderboard.mockReturnValue({ + ...emptyResult, + entries: [{ rank: 1, owner: YOU.toLowerCase(), winCount: 8, lossCount: 4, petCount: 3 }], + total: 1, + }); + + renderBoard(); + await userEvent.click(screen.getByRole('tab', { name: 'Players' })); + + expect(screen.getByText('3 pets')).toBeInTheDocument(); + expect(screen.getByText('8W')).toBeInTheDocument(); + // Only the visible board is fetched, so the idle one costs nothing. + expect(usePlayerLeaderboard).toHaveBeenLastCalledWith( + expect.objectContaining({ page: 0, enabled: true }), + ); + expect(useLeaderboard).toHaveBeenLastCalledWith(expect.objectContaining({ enabled: false })); + }); + + it('says so when nothing has been fought yet', () => { + renderBoard(); + expect(screen.getByText(/No battles on record yet/i)).toBeInTheDocument(); + }); + + it('shows the failure instead of an empty board', () => { + useLeaderboard.mockReturnValue({ ...emptyResult, error: new Error('backend unreachable') }); + + renderBoard(); + + expect(screen.getByText('backend unreachable')).toBeInTheDocument(); + }); +}); diff --git a/shared/src/hooks/index.ts b/shared/src/hooks/index.ts index d7df36a9..34e07618 100644 --- a/shared/src/hooks/index.ts +++ b/shared/src/hooks/index.ts @@ -57,6 +57,20 @@ export { } from './pets/useSpousePet'; export { useIncomingProposals, type IncomingProposal } from './marriage/useIncomingProposals'; export { useWinEstimate, type WinEstimateResult } from './battle/useWinEstimate'; +// Leaderboards. Ranked server-side over the merged battle record, so a page arrives +// already ordered and `rank` is absolute rather than per-page. +export { + useLeaderboard, + type LeaderboardEntry, + type UseLeaderboardOptions, + type UseLeaderboardResult, +} from './leaderboard/useLeaderboard'; +export { + usePlayerLeaderboard, + type PlayerLeaderboardEntry, + type UsePlayerLeaderboardOptions, + type UsePlayerLeaderboardResult, +} from './leaderboard/usePlayerLeaderboard'; export { useBattleDialogue, type UseBattleDialogueOptions, diff --git a/shared/src/hooks/leaderboard/useLeaderboard.ts b/shared/src/hooks/leaderboard/useLeaderboard.ts new file mode 100644 index 00000000..76938b12 --- /dev/null +++ b/shared/src/hooks/leaderboard/useLeaderboard.ts @@ -0,0 +1,106 @@ +import { useQuery } from '@tanstack/react-query'; +import { useApiClient } from '../../contexts/ApiClientContext'; +import { useAuth } from '../../contexts/AuthContext'; +import type { PetChain } from '../../types/pet'; + +const LEADERBOARD_QUERY = ` + query Leaderboard($chain: String!, $page: Int, $pageSize: Int) { + leaderboard(chain: $chain, page: $page, pageSize: $pageSize) { + entries { + rank id chain owner name dna + level rarity winCount lossCount asset + } + total page pageSize + } + } +`; + +/** One ranked pet, as the backend ranks it. */ +export interface LeaderboardEntry { + /** 1-based position in the full ranking, not within the page. */ + rank: number; + id: string; + chain: PetChain; + owner: string; + name: string; + dna: string; + level: number; + rarity: number; + winCount: number; + lossCount: number; + /** Metaplex Core asset pubkey (Solana only); "" on EVM. Feeds `petArtUrl`. */ + asset: string; +} + +interface LeaderboardPage { + entries: LeaderboardEntry[]; + total: number; + page: number; + pageSize: number; +} + +interface GraphQLResponse { + data?: { leaderboard: LeaderboardPage }; + errors?: { message: string }[]; +} + +export interface UseLeaderboardOptions { + /** Active chain; the query is disabled until this is set. */ + chain: PetChain | null; + /** Zero-based page index. */ + page?: number; + enabled?: boolean; +} + +export interface UseLeaderboardResult { + entries: LeaderboardEntry[]; + total: number; + pageSize: number; + isLoading: boolean; + error: Error | null; +} + +/** + * Pets ranked by battle record, from the backend's `/graphql` endpoint. + * + * The ranking is the backend's, deliberately: it ranks on the merged record + * (`pet_battle_progress` over the frozen `pet_roster` counters) in the query that orders + * the rows, so a client-side re-sort of one page would only reorder rows the server + * already chose. Ranks are absolute, so `entry.rank` is correct on every page. + * + * Requires an authenticated session — `/graphql` sits behind the JWT middleware. + */ +export const useLeaderboard = ({ + chain, + page = 0, + enabled = true, +}: UseLeaderboardOptions): UseLeaderboardResult => { + const apiClient = useApiClient(); + const { isAuthenticated } = useAuth(); + const baseURL = apiClient.defaults.baseURL ?? ''; + + const query = useQuery({ + queryKey: ['leaderboard', baseURL, chain, page], + enabled: enabled && chain != null && isAuthenticated, + queryFn: async () => { + const { data } = await apiClient.post('/graphql', { + query: LEADERBOARD_QUERY, + variables: { chain, page }, + }); + + if (data.errors?.length) { + throw new Error(data.errors.map((e) => e.message).join('; ')); + } + + return data.data?.leaderboard ?? { entries: [], total: 0, page, pageSize: 20 }; + }, + }); + + return { + entries: query.data?.entries ?? [], + total: query.data?.total ?? 0, + pageSize: query.data?.pageSize ?? 20, + isLoading: query.isLoading, + error: query.error as Error | null, + }; +}; diff --git a/shared/src/hooks/leaderboard/usePlayerLeaderboard.ts b/shared/src/hooks/leaderboard/usePlayerLeaderboard.ts new file mode 100644 index 00000000..68ea23af --- /dev/null +++ b/shared/src/hooks/leaderboard/usePlayerLeaderboard.ts @@ -0,0 +1,96 @@ +import { useQuery } from '@tanstack/react-query'; +import { useApiClient } from '../../contexts/ApiClientContext'; +import { useAuth } from '../../contexts/AuthContext'; +import type { PetChain } from '../../types/pet'; + +const PLAYER_LEADERBOARD_QUERY = ` + query PlayerLeaderboard($chain: String!, $page: Int, $pageSize: Int) { + playerLeaderboard(chain: $chain, page: $page, pageSize: $pageSize) { + entries { rank owner winCount lossCount petCount } + total page pageSize + } + } +`; + +/** One ranked owner: their pets' battle records, summed. */ +export interface PlayerLeaderboardEntry { + /** 1-based position in the full ranking, not within the page. */ + rank: number; + /** EVM addresses arrive lowercased; Solana pubkeys keep their case. */ + owner: string; + winCount: number; + lossCount: number; + /** How many of this owner's pets have a battle record. */ + petCount: number; +} + +interface PlayerLeaderboardPage { + entries: PlayerLeaderboardEntry[]; + total: number; + page: number; + pageSize: number; +} + +interface GraphQLResponse { + data?: { playerLeaderboard: PlayerLeaderboardPage }; + errors?: { message: string }[]; +} + +export interface UsePlayerLeaderboardOptions { + /** Active chain; the query is disabled until this is set. */ + chain: PetChain | null; + /** Zero-based page index. */ + page?: number; + enabled?: boolean; +} + +export interface UsePlayerLeaderboardResult { + entries: PlayerLeaderboardEntry[]; + total: number; + pageSize: number; + isLoading: boolean; + error: Error | null; +} + +/** + * Owners ranked by their pets' combined battle record. + * + * Same server-side ranking as {@link useLeaderboard}, aggregated per owner. The owner + * string is the grouping key the backend used, so comparing it to a connected wallet + * needs the same case folding the backend applies (lowercase on EVM, untouched on + * Solana) rather than a raw equality check. + */ +export const usePlayerLeaderboard = ({ + chain, + page = 0, + enabled = true, +}: UsePlayerLeaderboardOptions): UsePlayerLeaderboardResult => { + const apiClient = useApiClient(); + const { isAuthenticated } = useAuth(); + const baseURL = apiClient.defaults.baseURL ?? ''; + + const query = useQuery({ + queryKey: ['playerLeaderboard', baseURL, chain, page], + enabled: enabled && chain != null && isAuthenticated, + queryFn: async () => { + const { data } = await apiClient.post('/graphql', { + query: PLAYER_LEADERBOARD_QUERY, + variables: { chain, page }, + }); + + if (data.errors?.length) { + throw new Error(data.errors.map((e) => e.message).join('; ')); + } + + return data.data?.playerLeaderboard ?? { entries: [], total: 0, page, pageSize: 20 }; + }, + }); + + return { + entries: query.data?.entries ?? [], + total: query.data?.total ?? 0, + pageSize: query.data?.pageSize ?? 20, + isLoading: query.isLoading, + error: query.error as Error | null, + }; +}; From 4fdc0086e68a6bb17fe55c9d91b747830391225f Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 08:23:51 -0400 Subject: [PATCH 08/61] feat: show a player their own leaderboard rank --- backend/src/graphql/resolvers.ts | 16 ++++- backend/src/graphql/schema.ts | 10 +++ .../repositories/leaderboard.repository.ts | 71 +++++++++++++++++++ backend/tests/graphql/resolvers.test.ts | 28 +++++++- backend/tests/graphql/schema.test.ts | 11 ++- .../leaderboard.repository.test.ts | 56 ++++++++++++++- .../layout/sidebar/index.module.css | 2 +- .../src/components/layout/sidebar/index.tsx | 53 ++++++++++---- .../tests/components/layout/sidebar.test.tsx | 59 ++++++++++++++- shared/src/hooks/index.ts | 1 + shared/src/hooks/leaderboard/usePlayerRank.ts | 58 +++++++++++++++ 11 files changed, 347 insertions(+), 18 deletions(-) create mode 100644 shared/src/hooks/leaderboard/usePlayerRank.ts diff --git a/backend/src/graphql/resolvers.ts b/backend/src/graphql/resolvers.ts index a1f27758..cde4bd40 100644 --- a/backend/src/graphql/resolvers.ts +++ b/backend/src/graphql/resolvers.ts @@ -1,6 +1,10 @@ import { findReadyOpponents, getAllPets, getPetById, searchPets, type RosterPet } from '@repositories/roster.repository'; import { findBattleProgress, withBattleProgress } from '@repositories/battleProgress.overlay'; -import { findPetLeaderboard, findPlayerLeaderboard } from '@repositories/leaderboard.repository'; +import { + findPetLeaderboard, + findPlayerLeaderboard, + findPlayerRank, +} from '@repositories/leaderboard.repository'; import { tryGrpcEstimateWin } from '@grpc-client/estimateWin'; import { isSupportedChain, SUPPORTED_CHAINS } from '@typings/chain'; @@ -133,6 +137,16 @@ export const rootValue = { return { entries, total, page, pageSize }; }, + playerRank: async (args: { chain: string }, context: GraphQLContext) => { + if (!isSupportedChain(args.chain)) { + throw new Error(`chain must be one of: ${SUPPORTED_CHAINS.join(', ')}`); + } + + // The session address, already normalized the way the board groups owners. An + // unauthenticated caller has no standing to report rather than an error. + return findPlayerRank(args.chain, context.caller); + }, + searchPets: async (args: SearchPetsArgs) => { if (!isSupportedChain(args.chain)) { throw new Error(`chain must be one of: ${SUPPORTED_CHAINS.join(', ')}`); diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index cf4d76de..c373ad1a 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -150,6 +150,16 @@ export const schema = buildSchema(` pageSize: Int ): PlayerLeaderboardPage! + """ + The authenticated caller's own standing on the player board. + + Returns null when the caller holds no pet that has fought — "unranked" is a real + answer, and a zeroed row could not be told apart from a player ranked last. The + owner is taken from the session, never from an argument, so this cannot be used + to enumerate other wallets' positions. + """ + playerRank(chain: String!): PlayerLeaderboardEntry + """ Search pets by name prefix or exact numeric ID across the whole roster. Returns up to 'limit' results (default 10, max 20). diff --git a/backend/src/repositories/leaderboard.repository.ts b/backend/src/repositories/leaderboard.repository.ts index 6cb600f2..2869e8cc 100644 --- a/backend/src/repositories/leaderboard.repository.ts +++ b/backend/src/repositories/leaderboard.repository.ts @@ -236,6 +236,77 @@ async function queryPlayersMerged( return { rows, total: Number(counted[0]?.total ?? 0) }; } +/** + * One owner's own standing, or null when they hold no pet that has fought. + * + * Exists so a player can be told their rank without the client paging the board looking + * for itself, which costs one request per page and gets worse as the game grows. + * + * `ROW_NUMBER` over the same ORDER BY the paged query uses, so the number here is the + * number that row would carry on its page — the page arithmetic (`offset + index + 1`) + * is the same function. Ties cannot diverge either, since the owner key makes the + * ordering strict. + * + * `owner` must already be normalized the way the JWT normalizes it (EVM lowercased, + * Solana base58 as-is), which is exactly how `ownerKey` groups. An unnormalized EVM + * address matches nothing and reads as "unranked", which is why the caller passes the + * authenticated address rather than anything user-supplied. + */ +export async function findPlayerRank( + chain: Chain, + owner: string +): Promise { + if (!owner) { + return null; + } + + const chainId = servedChainIdForFamily(chain); + const key = ownerKey(chain); + + // The two branches differ only in whether progression is joined, matching the two + // paged queries above. + const ranked = chainId + ? Prisma.sql` + SELECT ${key} AS owner, + SUM(COALESCE(p.win_count, r.win_count))::int AS "winCount", + SUM(COALESCE(p.loss_count, r.loss_count))::int AS "lossCount", + COUNT(*)::int AS "petCount", + ROW_NUMBER() OVER ( + ORDER BY SUM(COALESCE(p.win_count, r.win_count)) DESC, + SUM(COALESCE(p.loss_count, r.loss_count)) ASC, + ${key} ASC + )::int AS rank + FROM pet_roster r + LEFT JOIN pet_battle_progress p + ON p.pet_id = r.pet_id + AND p.chain_id = ${chainId} + AND p.deployment_id = ${servedDeploymentId()} + WHERE r.chain = ${chain} + AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + GROUP BY ${key} + ` + : Prisma.sql` + SELECT ${key} AS owner, + SUM(r.win_count)::int AS "winCount", + SUM(r.loss_count)::int AS "lossCount", + COUNT(*)::int AS "petCount", + ROW_NUMBER() OVER ( + ORDER BY SUM(r.win_count) DESC, SUM(r.loss_count) ASC, ${key} ASC + )::int AS rank + FROM pet_roster r + WHERE r.chain = ${chain} AND r.win_count + r.loss_count > 0 + GROUP BY ${key} + `; + + const rows = await prisma.$queryRaw` + SELECT owner, "winCount", "lossCount", "petCount", rank + FROM (${ranked}) ranked + WHERE owner = ${owner} + `; + + return rows[0] ?? null; +} + /** The same aggregate without progression, for a chain family this deployment does not serve. */ async function queryPlayersFromChainState( params: FindLeaderboardParams diff --git a/backend/tests/graphql/resolvers.test.ts b/backend/tests/graphql/resolvers.test.ts index 0796af44..b7481cc1 100644 --- a/backend/tests/graphql/resolvers.test.ts +++ b/backend/tests/graphql/resolvers.test.ts @@ -10,6 +10,7 @@ vi.mock('../../src/grpc/estimateWin', () => ({ vi.mock('@repositories/leaderboard.repository', () => ({ findPetLeaderboard: vi.fn(), findPlayerLeaderboard: vi.fn(), + findPlayerRank: vi.fn(), })); // The overlay's own merge rule is covered in repositories/battleProgress.overlay.test.ts; // here it is stubbed to a pass-through so these tests stay about resolver shaping. @@ -20,7 +21,11 @@ vi.mock('@repositories/battleProgress.overlay', () => ({ import { rootValue } from '../../src/graphql/resolvers'; import { findReadyOpponents, getPetById } from '@repositories/roster.repository'; -import { findPetLeaderboard, findPlayerLeaderboard } from '@repositories/leaderboard.repository'; +import { + findPetLeaderboard, + findPlayerLeaderboard, + findPlayerRank, +} from '@repositories/leaderboard.repository'; import { tryGrpcEstimateWin } from '../../src/grpc/estimateWin'; const ctx = { caller: '0xcaller' }; @@ -125,6 +130,27 @@ describe('playerLeaderboard resolver', () => { }); }); +describe('playerRank resolver', () => { + it('ranks the session wallet, not an argument', async () => { + // The owner comes from the JWT context, so this cannot be pointed at someone + // else's wallet to enumerate their standing. + vi.mocked(findPlayerRank).mockResolvedValue(null); + + await rootValue.playerRank({ chain: 'evm' }, { caller: '0xme' }); + + expect(findPlayerRank).toHaveBeenCalledWith('evm', '0xme'); + }); + + it('returns null for an unranked caller rather than a zeroed row', async () => { + vi.mocked(findPlayerRank).mockResolvedValue(null); + expect(await rootValue.playerRank({ chain: 'evm' }, ctx)).toBeNull(); + }); + + it('throws for an unsupported chain', async () => { + await expect(rootValue.playerRank({ chain: 'tron' }, ctx)).rejects.toThrow('chain must be one of'); + }); +}); + describe('pet resolver', () => { it('returns the mapped pet when found', async () => { vi.mocked(getPetById).mockResolvedValue(rosterPet); diff --git a/backend/tests/graphql/schema.test.ts b/backend/tests/graphql/schema.test.ts index a1d90c72..5230fb7c 100644 --- a/backend/tests/graphql/schema.test.ts +++ b/backend/tests/graphql/schema.test.ts @@ -24,7 +24,7 @@ describe('GraphQL schema — Query surface', () => { it('exposes the pet reads, both leaderboards, battleProgress, and winEstimate', () => { expect(Object.keys(query).sort()).toEqual([ 'allPets', 'battleProgress', 'leaderboard', 'opponents', 'pet', 'playerLeaderboard', - 'searchPets', 'winEstimate', + 'playerRank', 'searchPets', 'winEstimate', ]); }); @@ -53,6 +53,15 @@ describe('GraphQL schema — Query surface', () => { it('returns a non-null PlayerLeaderboardPage from playerLeaderboard', () => { expect(query.playerLeaderboard?.type).toBe('PlayerLeaderboardPage!'); }); + + it('returns a nullable PlayerLeaderboardEntry from playerRank (null = unranked)', () => { + expect(query.playerRank?.type).toBe('PlayerLeaderboardEntry'); + }); + + it('takes no owner argument on playerRank — the session decides whose rank it is', () => { + const args = (schema.getQueryType()?.getFields().playerRank?.args ?? []).map((a) => a.name); + expect(args).toEqual(['chain']); + }); }); describe('GraphQL schema — LeaderboardEntry', () => { diff --git a/backend/tests/repositories/leaderboard.repository.test.ts b/backend/tests/repositories/leaderboard.repository.test.ts index 0b837555..e78d754f 100644 --- a/backend/tests/repositories/leaderboard.repository.test.ts +++ b/backend/tests/repositories/leaderboard.repository.test.ts @@ -15,7 +15,11 @@ vi.mock('../../src/repositories/battleProgress.overlay', () => ({ servedChainIdForFamily: (chain: string) => servedChainIdForFamily(chain), })); -import { findPetLeaderboard, findPlayerLeaderboard } from '../../src/repositories/leaderboard.repository'; +import { + findPetLeaderboard, + findPlayerLeaderboard, + findPlayerRank, +} from '../../src/repositories/leaderboard.repository'; import { prisma } from '@config/prisma'; const rankedRow = { @@ -200,3 +204,53 @@ describe('findPlayerLeaderboard', () => { expect(sqlOfCall(1)).toContain('COUNT(DISTINCT'); }); }); + +describe('findPlayerRank', () => { + const rankedRowForOwner = { rank: 4, owner: '0xowner', winCount: 8, lossCount: 4, petCount: 3 }; + + it('returns the caller row with its rank', async () => { + vi.mocked(prisma.$queryRaw).mockResolvedValueOnce([rankedRowForOwner] as never); + + expect(await findPlayerRank('evm', '0xowner')).toEqual(rankedRowForOwner); + }); + + it('returns null for a player holding no pet that has fought', async () => { + // Unranked is a real answer. A zeroed row could not be told apart from a player + // who has fought and lost everything. + vi.mocked(prisma.$queryRaw).mockResolvedValueOnce([] as never); + + expect(await findPlayerRank('evm', '0xowner')).toBeNull(); + }); + + it('does not query at all for an unauthenticated caller', async () => { + expect(await findPlayerRank('evm', '')).toBeNull(); + expect(prisma.$queryRaw).not.toHaveBeenCalled(); + }); + + it('ranks with ROW_NUMBER over the ordering the paged board uses', async () => { + // The paged board numbers rows `offset + index + 1`; this has to be the same + // function, or a player's stated rank would not match where they appear. + vi.mocked(prisma.$queryRaw).mockResolvedValueOnce([] as never); + + await findPlayerRank('evm', '0xowner'); + + const fragments = fragmentsOfCall(0); + expect(fragments).toContain('ROW_NUMBER() OVER ('); + expect(fragments).toContain('SUM(COALESCE(p.win_count, r.win_count)) DESC'); + expect(fragments).toContain('SUM(COALESCE(p.loss_count, r.loss_count)) ASC'); + expect(fragments).toContain('LOWER(r.owner)'); + }); + + it('ranks on frozen counters for a chain family this deployment does not serve', async () => { + servedChainIdForFamily.mockReturnValue(null); + vi.mocked(prisma.$queryRaw).mockResolvedValueOnce([] as never); + + await findPlayerRank('solana', 'SoLpubkey'); + + const fragments = fragmentsOfCall(0); + expect(fragments).toContain('SUM(r.win_count) DESC'); + expect(fragments).not.toContain('pet_battle_progress'); + // base58 stays unfolded here too, for the reason the board folds only EVM. + expect(fragments).not.toContain('LOWER('); + }); +}); diff --git a/frontend/src/components/layout/sidebar/index.module.css b/frontend/src/components/layout/sidebar/index.module.css index c319a1bd..c03b9dbb 100644 --- a/frontend/src/components/layout/sidebar/index.module.css +++ b/frontend/src/components/layout/sidebar/index.module.css @@ -311,7 +311,7 @@ box-shadow: 0 0 5px rgb(125 214 255 / 40%); } -/* Rank footer (placeholder) */ +/* Rank footer — the player's own leaderboard standing */ .rank { flex-shrink: 0; border-top: 1px solid rgb(101 131 255 / 10%); diff --git a/frontend/src/components/layout/sidebar/index.tsx b/frontend/src/components/layout/sidebar/index.tsx index c2e8ba53..166f2109 100644 --- a/frontend/src/components/layout/sidebar/index.tsx +++ b/frontend/src/components/layout/sidebar/index.tsx @@ -2,20 +2,58 @@ import React from 'react'; import clsx from 'clsx'; import { useLocation, useNavigate } from 'react-router-dom'; +import { useChainCapabilities, usePlayerRank } from '@shared/core'; + import Icon, { PinFilledIcon, PinIcon } from '@components/ui/icon'; import { DASHBOARD_HOME } from '@constants/interactionRoutes'; import { useSidebarPin } from '@hooks/useSidebarPin'; import { NAV_ITEMS } from './nav-items'; import styles from './index.module.css'; +/** + * The player's own standing, from the leaderboard the sidebar links to. + * + * Its own component so the sidebar itself stays free of data fetching, and so the + * hook is not called on every re-render of a nav item. + * + * Three states, all real: a rank, unranked (connected but no pet has fought), and + * nothing at all while it loads or before a session exists. The last one renders + * no footer rather than a zero, which would be indistinguishable from a genuine + * last place. + */ +const RankFooter: React.FC = () => { + const { activeKind } = useChainCapabilities(); + const { rank, isLoading } = usePlayerRank(activeKind); + + if (isLoading) return null; + + return ( +
    + + 🏆 + +
    +
    + {rank ? `RANK #${rank.rank} GLOBAL` : 'UNRANKED'} +
    +
    + {rank + ? `${rank.winCount} Total Win${rank.winCount === 1 ? '' : 's'}` + : 'Win a battle to enter the board'} +
    +
    +
    + ); +}; + /** * Collapsible left navigation for the app shell. Collapsed to an icon rail by * default; expands on hover / keyboard focus (CSS-driven), or stays open when * pinned. Nav items drive the existing router so deep-links keep working; the * logo returns to the gallery. * - * Daily Quests and the rank footer are static placeholders pending real data - * (see FRONTEND_REDESIGN_PLAN.md §8 Q3). + * Daily Quests is still a static placeholder pending real data + * (see FRONTEND_REDESIGN_PLAN.md §8 Q3); the rank footer is live. */ const Sidebar: React.FC = () => { const navigate = useNavigate(); @@ -116,16 +154,7 @@ const Sidebar: React.FC = () => {
    - {/* Placeholder — global rank footer (pending leaderboard data) */} -
    - - 🏆 - -
    -
    RANK #3 GLOBAL
    -
    649 Total Wins
    -
    -
    + ); }; diff --git a/frontend/tests/components/layout/sidebar.test.tsx b/frontend/tests/components/layout/sidebar.test.tsx index 05656de7..86816d4f 100644 --- a/frontend/tests/components/layout/sidebar.test.tsx +++ b/frontend/tests/components/layout/sidebar.test.tsx @@ -1,8 +1,25 @@ -import { beforeEach, describe, expect, it } from 'vitest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; +// The rank footer reads the session and the leaderboard, so the sidebar now needs both. +// Mocked rather than provider-wrapped: these tests are about the rail's own behaviour, +// and wagmi/query providers would make every one of them a wallet test. +const useChainCapabilities = vi.fn(() => ({ activeKind: 'evm' as string | null })); +const usePlayerRank = vi.fn( + () => + ({ rank: null, isLoading: false }) as { + rank: { rank: number; winCount: number } | null; + isLoading: boolean; + }, +); + +vi.mock('@shared/core', () => ({ + useChainCapabilities: () => useChainCapabilities(), + usePlayerRank: (chain: string | null) => usePlayerRank(chain), +})); + import Sidebar from '@components/layout/sidebar'; const renderSidebar = () => @@ -16,6 +33,9 @@ const pinButton = () => screen.getByRole('button', { name: 'Keep sidebar open' } beforeEach(() => { localStorage.clear(); + vi.clearAllMocks(); + useChainCapabilities.mockReturnValue({ activeKind: 'evm' }); + usePlayerRank.mockReturnValue({ rank: null, isLoading: false }); }); describe('Sidebar pin', () => { @@ -56,3 +76,40 @@ describe('Sidebar pin', () => { expect(screen.getByRole('button', { name: 'Crypto Pets home' })).toBeInTheDocument(); }); }); + +describe('Sidebar rank footer', () => { + it('shows the player standing once it loads', () => { + usePlayerRank.mockReturnValue({ rank: { rank: 4, winCount: 8 }, isLoading: false }); + + renderSidebar(); + + expect(screen.getByText('RANK #4 GLOBAL')).toBeInTheDocument(); + expect(screen.getByText('8 Total Wins')).toBeInTheDocument(); + }); + + it('singularizes a lone win', () => { + usePlayerRank.mockReturnValue({ rank: { rank: 9, winCount: 1 }, isLoading: false }); + + renderSidebar(); + + expect(screen.getByText('1 Total Win')).toBeInTheDocument(); + }); + + // Unranked is a real state, not a zero: this used to read "RANK #3 GLOBAL / 649 + // Total Wins" for everyone, including a player who had never fought. + it('says unranked when no pet has fought', () => { + renderSidebar(); + + expect(screen.getByText('UNRANKED')).toBeInTheDocument(); + expect(screen.getByText(/Win a battle to enter the board/i)).toBeInTheDocument(); + }); + + it('renders no footer while the rank is still loading', () => { + usePlayerRank.mockReturnValue({ rank: null, isLoading: true }); + + renderSidebar(); + + expect(screen.queryByText('UNRANKED')).toBeNull(); + expect(screen.queryByText(/RANK #/)).toBeNull(); + }); +}); diff --git a/shared/src/hooks/index.ts b/shared/src/hooks/index.ts index 34e07618..d52fe1ab 100644 --- a/shared/src/hooks/index.ts +++ b/shared/src/hooks/index.ts @@ -71,6 +71,7 @@ export { type UsePlayerLeaderboardOptions, type UsePlayerLeaderboardResult, } from './leaderboard/usePlayerLeaderboard'; +export { usePlayerRank, type UsePlayerRankResult } from './leaderboard/usePlayerRank'; export { useBattleDialogue, type UseBattleDialogueOptions, diff --git a/shared/src/hooks/leaderboard/usePlayerRank.ts b/shared/src/hooks/leaderboard/usePlayerRank.ts new file mode 100644 index 00000000..80f5db84 --- /dev/null +++ b/shared/src/hooks/leaderboard/usePlayerRank.ts @@ -0,0 +1,58 @@ +import { useQuery } from '@tanstack/react-query'; +import { useApiClient } from '../../contexts/ApiClientContext'; +import { useAuth } from '../../contexts/AuthContext'; +import type { PetChain } from '../../types/pet'; +import type { PlayerLeaderboardEntry } from './usePlayerLeaderboard'; + +const PLAYER_RANK_QUERY = ` + query PlayerRank($chain: String!) { + playerRank(chain: $chain) { rank owner winCount lossCount petCount } + } +`; + +interface GraphQLResponse { + data?: { playerRank: PlayerLeaderboardEntry | null }; + errors?: { message: string }[]; +} + +export interface UsePlayerRankResult { + /** Null while loading, and for a player with no pet that has fought. */ + rank: PlayerLeaderboardEntry | null; + isLoading: boolean; +} + +/** + * The connected wallet's own standing on the player board. + * + * Separate from {@link usePlayerLeaderboard} because finding yourself in a paged board + * costs one request per page and gets worse as the game grows; the backend answers this + * with one ranked query. + * + * Whose rank it is comes from the session, not from an argument — there is deliberately + * no way to ask for someone else's. A null result means unranked, which is a real state + * and not an error: it is what a player who has never fought should be told. + */ +export const usePlayerRank = (chain: PetChain | null): UsePlayerRankResult => { + const apiClient = useApiClient(); + const { isAuthenticated } = useAuth(); + const baseURL = apiClient.defaults.baseURL ?? ''; + + const query = useQuery({ + queryKey: ['playerRank', baseURL, chain], + enabled: chain != null && isAuthenticated, + queryFn: async () => { + const { data } = await apiClient.post('/graphql', { + query: PLAYER_RANK_QUERY, + variables: { chain }, + }); + + if (data.errors?.length) { + throw new Error(data.errors.map((e) => e.message).join('; ')); + } + + return data.data?.playerRank ?? null; + }, + }); + + return { rank: query.data ?? null, isLoading: query.isLoading }; +}; From aec7519ead5f880b8470c9e03de08cd4a059613c Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 08:27:23 -0400 Subject: [PATCH 09/61] docs: record the shipped leaderboard and correct its frozen-counter premise --- CLAUDE.md | 4 ++- backend/API.md | 42 ++++++++++++++++++++++++++++ docs/plan-future-features-roadmap.md | 33 +++++++++++++++++++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7b483fc4..739ddacb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -187,7 +187,9 @@ Both apply the same rule: a pet with a progress row shows backend progression, o The merge is deliberately **not** in `roster.repository.ts`. `snapshot.builder.ts` seeds a first progress row from the roster's on-chain level and `intent.service.ts` checks ownership there; merging in the repository would feed overlaid progression back into the thing that produces it. -Matchmaking is the exception to the two-site split above: `findReadyOpponents` filters, bands and orders on level and cooldown, so it merges in the query itself (a raw `LEFT JOIN` against `pet_battle_progress`) rather than being overlaid afterwards. A post-filter can only drop rows a page already holds, which fixes the cooldown and leaves the level band reading frozen values. The cost is that this one query has **no gRPC fast path**: indexer-go's cache holds chain state and has no view of `pet_battle_progress`, a backend-owned table, so it can no longer answer it correctly. `getPetById` keeps its cache path, because there the resolver does the merge. +Two reads are exceptions to the two-site split above, and for the same reason: what they merge is also what they filter or order on, so the merge has to happen in the query. `findReadyOpponents` filters, bands and orders on level and cooldown; `leaderboard.repository.ts` (pet board, player board, `findPlayerRank`) ranks on win/loss. Both do a raw `LEFT JOIN` against `pet_battle_progress` rather than being overlaid afterwards, because an overlay applied to a page can only rewrite rows the query already chose — for matchmaking that fixes the cooldown and leaves the level band reading frozen values, and for the leaderboard it produces a page ordered by numbers nobody ranked on. The cost is that these queries have **no gRPC fast path**: indexer-go's cache holds chain state and has no view of `pet_battle_progress`, a backend-owned table, so it cannot answer them correctly. `getPetById` keeps its cache path, because there the resolver does the merge. + +The leaderboard is worth knowing about specifically because the naive version of it is wrong in a way that looks right: ranking on `pet_roster.win_count`/`loss_count` alone returns **nothing** on a deployment whose battles are all backend-settled, since those columns froze at §L Phase 6. `docs/plan-future-features-roadmap.md` §1 originally proposed exactly that; its "Built" banner records the correction. ### battle_history comes from the receipt now, not the indexer `battle_history` feeds the AI dialogue service's rivalry / head-to-head context. It used to be written by the indexer from on-chain settle events, with the dialogue endpoint filling gaps from the client's own result report. Both sources are gone: there are no settle events, and a client-reported result must never be able to restate what was signed. diff --git a/backend/API.md b/backend/API.md index 534f6372..ddc162e8 100644 --- a/backend/API.md +++ b/backend/API.md @@ -219,6 +219,48 @@ matchup UI degrades to "odds unavailable". Intended for a single confirmed matchup, not per opponents row. Optional `samples` arg overrides the server default (clamped to 10,000). +### Leaderboards + +```graphql +query($chain: String!, $page: Int, $pageSize: Int) { + leaderboard(chain: $chain, page: $page, pageSize: $pageSize) { + entries { rank id chain owner name dna level rarity winCount lossCount asset } + total page pageSize + } + playerLeaderboard(chain: $chain, page: $page, pageSize: $pageSize) { + entries { rank owner winCount lossCount petCount } + total page pageSize + } + playerRank(chain: $chain) { rank owner winCount lossCount petCount } +} +``` + +Three read-only rankings over the **merged** battle record — `pet_battle_progress` +where a pet has fought a backend battle, the frozen `pet_roster` counters otherwise. +Ranking on the roster alone is not a simplification but a bug: those counters stopped +moving when battles left the chain (§L Phase 6), so on a deployment whose battles are +all backend-settled the roster-only ranking is empty. + +Ordering is wins DESC, then losses ASC, then (pets only) level DESC, then the id or +owner key. The losses tiebreak *is* the win-rate tiebreak — among rows on equal wins, +fewer losses is a strictly higher rate — so nothing is ranked on a ratio drawn from a +handful of fights. Rows with no battles at all are excluded. + +| Field | Type | Notes | +| --- | --- | --- | +| `rank` | Int | 1-based over the **full** ranking, not the page; page 2 continues where page 1 stopped | +| `owner` | String | grouping key on the player board: EVM addresses lowercased, Solana pubkeys untouched, matching `normalizeAccount` | +| `petCount` | Int | pets **with a battle record**, not pets owned | + +`playerRank` reports the authenticated caller's own standing, so a client does not page +the whole board looking for itself. It takes no owner argument — whose rank it is comes +from the session — and returns **`null` for an unranked player** (no pet has fought) +rather than a zeroed row, which would be indistinguishable from genuine last place. + +Neither board has a gRPC fast path, for the same reason `opponents` lost its own: +indexer-go's cache holds chain state and has no view of `pet_battle_progress`, a +backend-owned table, so it cannot answer these correctly. Both read Postgres directly. + ### Battle data `battle_history` carries `loserPetId, seed (0x-hex), rounds, winnerHpRemaining, diff --git a/docs/plan-future-features-roadmap.md b/docs/plan-future-features-roadmap.md index 09318768..c77a98e7 100644 --- a/docs/plan-future-features-roadmap.md +++ b/docs/plan-future-features-roadmap.md @@ -78,7 +78,9 @@ what to build first, section 11 is what to build last. *Tier 1 — ship immediately.* Near-zero new infrastructure, no contract work on either chain, nothing else in this doc needs to exist first. -1. **Leaderboard** — `PetRoster.winCount`/`lossCount` already exist. +1. **Leaderboard** — **Built; see §1.** Ranked on the merged battle record, not on + `PetRoster.winCount`/`lossCount` as this line originally assumed: those froze when + battles left the chain. 2. **Social chat** — reuses the existing WebSocket channel and JWT auth; v1 scope is gated by the marriage feature that's already shipped. @@ -228,6 +230,35 @@ Reading the graph: ## 1. Leaderboard feature +> **Built.** This section is kept as the original proposal; `backend/API.md` +> (Leaderboards) is authoritative for the shipped surface. What shipped diverges +> from the sketch below in three ways, recorded here so they are not mistaken for +> drift: +> +> - **`PetRoster.winCount`/`lossCount` were the wrong source.** The sketch's whole +> claim to cheapness was that those columns already exist. They do, and they have +> been frozen since §L Phase 6 — the live record accumulates in +> `pet_battle_progress`. This was not a theoretical concern: run the roster-only +> ranking against the live Base Sepolia data and it returns **zero rows**, while +> the merged ranking returns four pets and two players. Every leaderboard query +> merges the two the way `findReadyOpponents` does, in the query that orders the +> rows, because the ordering *is* the merge and a post-sort cannot fix it. +> - **No ELO, and no `PetRating` table.** Ranking is wins DESC then losses ASC. That +> second key is the win-rate tiebreak without the division: on equal wins, fewer +> losses is a strictly higher rate, so nothing is ranked on a ratio drawn from a +> handful of fights. The `PetRating` model below was not created — see the +> paragraph after it, which is still the standing decision: if rating ever lands it +> belongs in the versioned ruleset computed from receipts, not at this layer. +> - **A player board and a self-rank came with it.** Owners are ranked by their pets' +> combined record, grouped case-folded on EVM and unfolded on Solana (folding base58 +> would merge two distinct pubkeys into one player). `playerRank` answers "where am +> I" in one query rather than having a client page the board looking for itself, and +> returns null for an unranked player rather than a zeroed row. +> +> Surfaces: `/leaderboard` in the web app, plus the sidebar rank footer, which until +> now hardcoded "RANK #3 GLOBAL / 649 Total Wins" for every visitor. Mobile was +> deliberately left out; the hooks live in `@shared/core` so it can pick them up. + **Goal.** Ranked pets and/or players by battle performance. **Design.** The cheapest feature on this list to ship: `PetRoster.winCount`/`lossCount` already From 04af54c5beaffc9a45e19a80ca31009b1c712072 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 08:40:52 -0400 Subject: [PATCH 10/61] feat(backend): add married-pair private chat --- backend/API.md | 25 +++ .../migration.sql | 36 ++++ backend/prisma/schema.prisma | 46 +++++ backend/src/app.ts | 3 + backend/src/features/chat/chat.controller.ts | 107 +++++++++++ backend/src/features/chat/chat.schema.ts | 31 +++ backend/src/features/chat/chat.service.ts | 139 ++++++++++++++ backend/src/features/chat/index.ts | 6 + backend/src/middleware/rateLimit.ts | 28 +++ backend/src/repositories/chat.repository.ts | 177 ++++++++++++++++++ backend/src/routes/chat.ts | 15 ++ .../tests/features/chat.controller.test.ts | 162 ++++++++++++++++ backend/tests/features/chat.service.test.ts | 127 +++++++++++++ 13 files changed, 902 insertions(+) create mode 100644 backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql create mode 100644 backend/src/features/chat/chat.controller.ts create mode 100644 backend/src/features/chat/chat.schema.ts create mode 100644 backend/src/features/chat/chat.service.ts create mode 100644 backend/src/features/chat/index.ts create mode 100644 backend/src/repositories/chat.repository.ts create mode 100644 backend/src/routes/chat.ts create mode 100644 backend/tests/features/chat.controller.test.ts create mode 100644 backend/tests/features/chat.service.test.ts diff --git a/backend/API.md b/backend/API.md index ddc162e8..df04439a 100644 --- a/backend/API.md +++ b/backend/API.md @@ -316,6 +316,31 @@ switching the mode off stops new battles, it does not retract receipts already i | GET | `/api/battle/rulesets/:rulesetHash` | none | One ruleset's full bundle, for replaying against it. | | POST | `/api/battle/verify-receipt` | none | Body `{ receiptHash }`. Checks the stored signature against a published key and that the payload is well-formed — §A's "operator signature, verified against a published key" row, nothing more. It does **not** re-run the fight, check the drand BLS signature, or recompute progression; that is the standalone verifier's job (§H), which runs with no backend access so its answer cannot depend on this process telling the truth. Passing this check is necessary, not sufficient. | +### Private chat (roadmap §2, v1) + +| Method | Path | Auth | Purpose | +| --- | --- | --- | --- | +| GET | `/api/chat/threads` | JWT | The caller's currently-usable threads, one per married counterpart, with the pet pairs behind each. Creates a thread on first listing — a married pair always ends up with exactly one, so an explicit open call would add a round trip and a null state that resolves one way. | +| GET | `/api/chat/threads/:id/messages` | JWT | A page, oldest first within the page. `before=` pages backwards (a chat is read from its end); `limit` defaults to 50, capped at 100. | +| POST | `/api/chat/threads/:id/messages` | JWT | Body `{ text }`, trimmed, 1-2000 characters. The author is the session wallet; a `sender` in the body is ignored. | + +Access is **derived, never stored**: a thread answers only while the two wallets have a +married pet pair in `pet_roster.spouse_id`, rechecked on every request. A divorce closes +the conversation the moment the indexer sees it, with nothing to revoke. The thread row +survives — deleting it would destroy the history — it just stops answering. + +Status codes carry a deliberate asymmetry. A non-participant gets **404**, the same as a +thread that does not exist, because 403 would confirm the id to anyone probing. A +participant whose marriage has ended gets **403** with a reason, since they already know +the thread exists. + +**What v1 does not have**, each a product call flagged in the roadmap rather than an +oversight: no block or report, no profanity filtering, no read receipts or presence, no +edit or delete, and no retention policy. The abuse controls are a length cap and a rate +limit (20 sends/min per wallet, 120 reads) — volume controls, not content ones. This is +the first endpoint in the API that stores genuine user-authored text, which is what makes +moderation a real question here and not elsewhere. + ### Battle room WebSocket (v2) ``` diff --git a/backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql b/backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql new file mode 100644 index 00000000..ce0eb2dd --- /dev/null +++ b/backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql @@ -0,0 +1,36 @@ +-- CreateTable +CREATE TABLE "chat_thread" ( + "id" TEXT NOT NULL, + "participant_a" TEXT NOT NULL, + "participant_b" TEXT NOT NULL, + "scope" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "chat_thread_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "chat_message" ( + "id" SERIAL NOT NULL, + "thread_id" TEXT NOT NULL, + "sender" TEXT NOT NULL, + "text" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "chat_message_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "chat_thread_participant_a_participant_b_key" ON "chat_thread"("participant_a", "participant_b"); + +-- CreateIndex +CREATE INDEX "chat_thread_participant_a_idx" ON "chat_thread"("participant_a"); + +-- CreateIndex +CREATE INDEX "chat_thread_participant_b_idx" ON "chat_thread"("participant_b"); + +-- CreateIndex +CREATE INDEX "chat_message_thread_id_created_at_idx" ON "chat_message"("thread_id", "created_at"); + +-- AddForeignKey +ALTER TABLE "chat_message" ADD CONSTRAINT "chat_message_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "chat_thread"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index d7965b45..4be88761 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -146,6 +146,52 @@ model BattleConversation { @@map("battle_conversation") } +/// A private thread between two wallets (roadmap §2 v1). +/// +/// No `chain` column, deliberately: the relationship is between wallets, and a wallet +/// address only exists on one chain anyway (0x-hex on EVM, base58 on Solana), so the +/// pair is implicitly single-chain without saying so. +/// +/// The marriage that grants access is NOT stored here. Access is checked against +/// `pet_roster.spouse_id` every time the thread is read or written, the same +/// "derive from indexed state, don't duplicate it" rule the roster reads follow. A +/// copied `marriedPetIds` here would keep granting access after a divorce. +/// +/// `participantA` is the lexicographically smaller address, which is what makes the +/// unique constraint mean "one thread per pair" rather than "one per direction". +model ChatThread { + id String @id @default(cuid()) + participantA String @map("participant_a") + participantB String @map("participant_b") + /// 'marriage' in v1. Present so a later 'direct' scope does not need a migration. + scope String + + createdAt DateTime @default(now()) @map("created_at") + messages ChatMessage[] + + @@unique([participantA, participantB], name: "chat_thread_pair") + @@index([participantA]) + @@index([participantB]) + @@map("chat_thread") +} + +/// One message. Unlike every other generated text in this schema, this is real +/// user-authored content, which is what makes moderation a live product question +/// rather than a prompt-layer one (roadmap §2). +model ChatMessage { + id Int @id @default(autoincrement()) + threadId String @map("thread_id") + thread ChatThread @relation(fields: [threadId], references: [id], onDelete: Cascade) + /// Wallet address of the author, normalized the way the JWT normalizes it. + sender String + text String + + createdAt DateTime @default(now()) @map("created_at") + + @@index([threadId, createdAt]) + @@map("chat_message") +} + // ─── Backend-authoritative battles ──────────────────────────────────────────── // Models for the design in docs/battle-protocol.md. The existing // pet_roster / battle_history tables stay exactly as they are: they are projections diff --git a/backend/src/app.ts b/backend/src/app.ts index fa22b559..e143d26c 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -11,6 +11,7 @@ import battleRoomRoutes from '@routes/battle-room'; import battleRoutes from '@routes/battle'; import receiptRoutes from '@routes/receipts'; import rewardRoutes from '@routes/rewards'; +import chatRoutes from '@routes/chat'; const app = express(); @@ -38,6 +39,7 @@ app.use('/api/battle-room', battleRoomRoutes); app.use('/api/battle', battleRoutes); app.use('/api/receipts', receiptRoutes); app.use('/api/rewards', rewardRoutes); +app.use('/api/chat', chatRoutes); app.get('/', (_req: Request, res: Response) => { res.json({ @@ -50,6 +52,7 @@ app.get('/', (_req: Request, res: Response) => { graphql: '/graphql', battleDialogue: '/api/battle-dialogue', battleRoom: '/api/battle-room', + chat: '/api/chat', }, }); }); diff --git a/backend/src/features/chat/chat.controller.ts b/backend/src/features/chat/chat.controller.ts new file mode 100644 index 00000000..8abef92f --- /dev/null +++ b/backend/src/features/chat/chat.controller.ts @@ -0,0 +1,107 @@ +import type { Request, Response } from 'express'; + +import type { AuthenticatedRequest } from '@middleware/auth'; +import { authorizeThread, listThreads, readMessages, sendMessage, type ChatDenial } from './chat.service'; +import { ListMessagesSchema, SendMessageSchema } from './chat.schema'; + +/** + * HTTP surface for private chat (roadmap §2 v1). Every route is JWT-gated at the + * router; the caller is always the session wallet and never a request field. + */ + +/** GET /api/chat/threads — the caller's currently-usable threads. */ +export async function getThreads(req: Request, res: Response): Promise { + const caller = callerOf(req); + if (!caller) { + res.status(401).json({ error: 'No token provided' }); + return; + } + + try { + res.json({ threads: await listThreads(caller) }); + } catch (err) { + console.error('[chat] failed to list threads:', err); + res.status(500).json({ error: 'Failed to list chat threads' }); + } +} + +/** GET /api/chat/threads/:id/messages — a page, oldest first, newest page by default. */ +export async function getMessages(req: Request, res: Response): Promise { + const caller = callerOf(req); + if (!caller) { + res.status(401).json({ error: 'No token provided' }); + return; + } + + const query = ListMessagesSchema.safeParse(req.query); + if (!query.success) { + res.status(400).json({ error: 'Invalid pagination' }); + return; + } + + const threadId = req.params.id ?? ''; + const auth = await authorizeThread(threadId, caller); + if (auth.denial) { + respondToDenial(res, auth.denial); + return; + } + + try { + const messages = await readMessages(threadId, query.data.limit, query.data.before); + res.json({ messages }); + } catch (err) { + console.error('[chat] failed to read messages:', err); + res.status(500).json({ error: 'Failed to read messages' }); + } +} + +/** POST /api/chat/threads/:id/messages — append one message. */ +export async function postMessage(req: Request, res: Response): Promise { + const caller = callerOf(req); + if (!caller) { + res.status(401).json({ error: 'No token provided' }); + return; + } + + const body = SendMessageSchema.safeParse(req.body); + if (!body.success) { + res.status(400).json({ error: 'Message must be between 1 and 2000 characters' }); + return; + } + + const threadId = req.params.id ?? ''; + const auth = await authorizeThread(threadId, caller); + if (auth.denial) { + respondToDenial(res, auth.denial); + return; + } + + try { + res.status(201).json({ message: await sendMessage(threadId, caller, body.data.text) }); + } catch (err) { + console.error('[chat] failed to send message:', err); + res.status(500).json({ error: 'Failed to send message' }); + } +} + +function callerOf(req: Request): string | undefined { + return (req as AuthenticatedRequest).user?.address; +} + +/** + * A non-participant gets 404, not 403. + * + * 403 would confirm that a thread with that id exists, which is exactly what someone + * probing ids wants to learn. "Not yours" and "not there" are the same answer to + * anyone who is not a participant. An ended marriage does get its own status, because + * that caller is a participant and has already been told the thread exists. + */ +function respondToDenial(res: Response, denial: ChatDenial): void { + if (denial === 'not-married') { + res.status(403).json({ + error: 'This conversation is open only while your pets are married', + }); + return; + } + res.status(404).json({ error: 'Thread not found' }); +} diff --git a/backend/src/features/chat/chat.schema.ts b/backend/src/features/chat/chat.schema.ts new file mode 100644 index 00000000..d4eec61f --- /dev/null +++ b/backend/src/features/chat/chat.schema.ts @@ -0,0 +1,31 @@ +import { z } from 'zod'; + +/** + * Longest message accepted. + * + * A cap is the one content rule v1 has, and it exists for storage and render sanity + * rather than moderation — see the feature's README note. 2000 characters is far above + * anything a chat message needs and far below anything worth storing as a document. + */ +export const MAX_MESSAGE_LENGTH = 2000; + +/** Default and maximum messages returned per page. */ +export const DEFAULT_MESSAGE_PAGE = 50; +export const MAX_MESSAGE_PAGE = 100; + +/** + * Body of POST /api/chat/threads/:id/messages. + * + * Trimmed before the length check, so a message of nothing but whitespace is rejected + * rather than stored as a blank line. + */ +export const SendMessageSchema = z.object({ + text: z.string().transform((value) => value.trim()).pipe(z.string().min(1).max(MAX_MESSAGE_LENGTH)), +}); + +/** Query of GET /api/chat/threads/:id/messages. */ +export const ListMessagesSchema = z.object({ + /** Exclusive message id to page backwards from; omit for the newest page. */ + before: z.coerce.number().int().positive().optional(), + limit: z.coerce.number().int().positive().max(MAX_MESSAGE_PAGE).default(DEFAULT_MESSAGE_PAGE), +}); diff --git a/backend/src/features/chat/chat.service.ts b/backend/src/features/chat/chat.service.ts new file mode 100644 index 00000000..6412393e --- /dev/null +++ b/backend/src/features/chat/chat.service.ts @@ -0,0 +1,139 @@ +import { normalizeAccount } from '@cryptopets/protocol'; + +import { + findMarriedCounterparts, + findMessages, + findThreadById, + insertMessage, + openThread, + type ChatMessageRow, +} from '@repositories/chat.repository'; + +/** + * Private player-to-player chat, v1 (roadmap §2). + * + * Access is the whole feature. A thread is readable and writable only while the two + * wallets have a married pet pair, checked against `pet_roster.spouse_id` on **every** + * request rather than recorded on the thread. That is the difference between "these two + * are married" and "these two were married once": a divorce closes the thread the moment + * the indexer sees it, with no revocation step to forget. + * + * The scope is deliberately the narrowest thing that is still a chat feature. There is + * no discovery surface, no way to name a counterpart, and no way to start a thread with + * anyone the game has not already connected you to — so the v2 question (open DMs) + * arrives with moderation as a prerequisite rather than as a retrofit. + * + * What v1 does NOT have, all of it flagged in the roadmap as a product call rather than + * an oversight: no block/report, no profanity filtering, no read receipts, no presence, + * no edit or delete, and no retention policy. Messages are kept until someone decides + * what the policy is. Rate limiting and a length cap are the only abuse controls, and + * they are volume controls, not content ones. + */ + +const MARRIAGE_SCOPE = 'marriage'; + +/** A thread as the caller sees it, with the marriage that justifies it. */ +export interface ChatThreadView { + threadId: string; + counterpart: string; + /** The married pair behind this thread, for a UI that wants to say why it exists. */ + pets: { petId: string; petName: string; spousePetId: string; spouseName: string }[]; + chain: string; +} + +/** + * Every thread the caller may currently use, derived from live marriage state. + * + * Threads are created here rather than by an explicit "open chat" call: a married pair + * always ends up with exactly one thread, so making the client ask for it first would + * add a round trip and a null state that only ever resolves one way. The insert is + * idempotent. + * + * A pair with two married pet couples collapses to one thread carrying both pairs, + * because the conversation is between the owners, not the pets. + */ +export async function listThreads(caller: string): Promise { + const marriages = await findMarriedCounterparts(caller); + if (marriages.length === 0) { + return []; + } + + const byCounterpart = new Map(); + for (const marriage of marriages) { + const counterpart = normalizeAccount(marriage.counterpart); + const pets = { + petId: marriage.petId, + petName: marriage.petName, + spousePetId: marriage.spousePetId, + spouseName: marriage.spouseName, + }; + + const seen = byCounterpart.get(counterpart); + if (seen) { + seen.pets.push(pets); + continue; + } + + const thread = await openThread(caller, counterpart, MARRIAGE_SCOPE); + byCounterpart.set(counterpart, { + threadId: thread.id, + counterpart, + pets: [pets], + chain: marriage.chain, + }); + } + + return [...byCounterpart.values()]; +} + +/** Why a thread request was refused. `null` means it was not. */ +export type ChatDenial = 'not-found' | 'not-a-participant' | 'not-married'; + +/** + * Authorizes one request against one thread. + * + * Both checks are needed and neither implies the other. Participation says the thread is + * yours; the marriage says it is still live. A thread whose marriage has ended stays in + * the database — deleting it would destroy the history — but stops answering, which is + * why this returns a reason a caller can distinguish rather than a bare boolean. + */ +export async function authorizeThread( + threadId: string, + caller: string +): Promise<{ denial: ChatDenial } | { denial: null; counterpart: string }> { + const thread = await findThreadById(threadId); + if (!thread) { + return { denial: 'not-found' }; + } + + const isParticipant = thread.participantA === caller || thread.participantB === caller; + if (!isParticipant) { + return { denial: 'not-a-participant' }; + } + + const counterpart = thread.participantA === caller ? thread.participantB : thread.participantA; + const marriages = await findMarriedCounterparts(caller); + const stillMarried = marriages.some( + (marriage) => normalizeAccount(marriage.counterpart) === counterpart + ); + + return stillMarried ? { denial: null, counterpart } : { denial: 'not-married' }; +} + +/** A page of messages. Authorization is the caller's job — see `authorizeThread`. */ +export function readMessages( + threadId: string, + limit: number, + before?: number +): Promise { + return findMessages(threadId, limit, before); +} + +/** Appends the caller's message. Authorization is the caller's job. */ +export function sendMessage( + threadId: string, + sender: string, + text: string +): Promise { + return insertMessage(threadId, sender, text); +} diff --git a/backend/src/features/chat/index.ts b/backend/src/features/chat/index.ts new file mode 100644 index 00000000..0cd2abf6 --- /dev/null +++ b/backend/src/features/chat/index.ts @@ -0,0 +1,6 @@ +/** + * Public surface of the chat feature. External code imports from `@features/chat` so + * the internal layout can change without touching call sites. + */ +export { getMessages, getThreads, postMessage } from './chat.controller'; +export { authorizeThread, listThreads, type ChatDenial, type ChatThreadView } from './chat.service'; diff --git a/backend/src/middleware/rateLimit.ts b/backend/src/middleware/rateLimit.ts index 4e04ea2b..24f1d8d6 100644 --- a/backend/src/middleware/rateLimit.ts +++ b/backend/src/middleware/rateLimit.ts @@ -41,6 +41,34 @@ export const dialogueRateLimit = rateLimit({ message: { error: 'Too many dialogue requests, try again shortly' }, }); +/** + * Chat sending is the only endpoint in the API that produces content another player + * receives, so its budget is a moderation control as much as a cost one: 20/min is + * conversational speed and well short of flooding someone's thread. It is also the + * *only* such control in v1 — there is no block, report, or filter yet (roadmap §2). + */ +export const chatSendRateLimit = rateLimit({ + windowMs: 60_000, + limit: 20, + standardHeaders: 'draft-8', + legacyHeaders: false, + keyGenerator: walletKey, + message: { error: 'Sending too fast, try again shortly' }, +}); + +/** + * Reading is indexed queries against the caller's own threads, so it only needs to be + * loose enough for a client that polls between socket updates and re-reads on focus. + */ +export const chatReadRateLimit = rateLimit({ + windowMs: 60_000, + limit: 120, + standardHeaders: 'draft-8', + legacyHeaders: false, + keyGenerator: walletKey, + message: { error: 'Too many chat requests, try again shortly' }, +}); + /** * Room creation is a single cheap insert (no LLM), so it gets a much looser * budget than dialogue — just enough to stop room-spam from repeated diff --git a/backend/src/repositories/chat.repository.ts b/backend/src/repositories/chat.repository.ts new file mode 100644 index 00000000..b5f64950 --- /dev/null +++ b/backend/src/repositories/chat.repository.ts @@ -0,0 +1,177 @@ +import { Prisma } from '@generated/prisma/client'; + +import { prisma } from '@config/prisma'; +import type { Chain } from '@typings/chain'; + +/** + * Read/write access for private chat (roadmap §2 v1), plus the marriage lookup that + * gates it. + * + * The gate lives here rather than in `roster.repository.ts` because it is a chat + * question asked of roster data, and `roster.repository.ts` is deliberately kept as the + * unmerged projection two battle callers depend on. + */ + +/** One current marriage involving the caller, from the caller's side. */ +export interface MarriedCounterpart { + chain: Chain; + /** The caller's married pet. */ + petId: string; + petName: string; + /** The spouse pet, and the wallet that owns it. */ + spousePetId: string; + spouseName: string; + counterpart: string; +} + +/** + * Every wallet the caller is currently married to, one row per married pet pair. + * + * Two normalization details, both of which decide whether a real marriage is found: + * + * - `owner` in `pet_roster` is written by indexer-go, which is not guaranteed to + * match the JWT's case. The caller arrives normalized (EVM lowercased, base58 + * untouched), so EVM rows are matched folded and Solana rows exactly. Folding + * base58 could match a different pubkey, which here would open someone else's + * marriage. + * - The chain comes from the address shape rather than a parameter. A wallet only + * exists on one chain, so asking the caller which chain they meant would let them + * ask the wrong one. + * + * A pet marries a pet, so an owner pair can appear more than once (two of their pets + * married to each other's). The caller collapses that into one thread per pair. + */ +export async function findMarriedCounterparts(caller: string): Promise { + if (!caller) { + return []; + } + + const isEvm = /^0x[0-9a-f]{40}$/.test(caller); + const ownerMatch = isEvm + ? Prisma.sql`LOWER(p.owner) = ${caller}` + : Prisma.sql`p.owner = ${caller}`; + const chain: Chain = isEvm ? 'evm' : 'solana'; + + return prisma.$queryRaw` + SELECT p.chain, + p.pet_id AS "petId", + p.name AS "petName", + s.pet_id AS "spousePetId", + s.name AS "spouseName", + s.owner AS counterpart + FROM pet_roster p + JOIN pet_roster s + ON s.chain = p.chain + AND s.pet_id = p.spouse_id + WHERE p.chain = ${chain} + AND ${ownerMatch} + AND p.spouse_id <> '0' + -- A pet married to another pet of the caller's own is a marriage, but not a + -- conversation: there is no second person to talk to. + AND s.owner <> p.owner + ORDER BY p.pet_id ASC + `; +} + +/** A thread plus the counterpart, as one participant sees it. */ +export interface ThreadRow { + id: string; + counterpart: string; + createdAt: Date; +} + +/** + * The thread for a pair, creating it if this is their first. + * + * Participants are stored in lexicographic order, which is what makes the unique + * constraint mean "one thread per pair" instead of "one per direction" — without it + * A→B and B→A would be two threads holding half a conversation each. + * + * Concurrent first-opens race, so a unique-constraint violation is resolved by reading + * the winner's row rather than failing: both callers are entitled to the same thread. + */ +export async function openThread( + walletX: string, + walletY: string, + scope: string +): Promise { + const [participantA, participantB] = walletX < walletY ? [walletX, walletY] : [walletY, walletX]; + const where = { chat_thread_pair: { participantA, participantB } }; + + const existing = await prisma.chatThread.findUnique({ where }); + if (existing) { + return toThreadRow(existing, walletX); + } + + try { + const created = await prisma.chatThread.create({ + data: { participantA, participantB, scope }, + }); + return toThreadRow(created, walletX); + } catch (err) { + if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === 'P2002') { + const winner = await prisma.chatThread.findUniqueOrThrow({ where }); + return toThreadRow(winner, walletX); + } + throw err; + } +} + +/** The thread by id, or null. Returns participants so the caller can authorize. */ +export function findThreadById(id: string) { + return prisma.chatThread.findUnique({ + where: { id }, + select: { id: true, participantA: true, participantB: true, scope: true }, + }); +} + +export interface ChatMessageRow { + id: number; + sender: string; + text: string; + createdAt: Date; +} + +/** + * A page of messages, oldest first within the page. + * + * Paged backwards from `before` (an exclusive message id) because a chat is read from + * its end: the first page is the newest messages, and older ones load as the reader + * scrolls up. + */ +export async function findMessages( + threadId: string, + limit: number, + before?: number +): Promise { + const rows = await prisma.chatMessage.findMany({ + where: { threadId, ...(before != null ? { id: { lt: before } } : {}) }, + orderBy: { id: 'desc' }, + take: limit, + select: { id: true, sender: true, text: true, createdAt: true }, + }); + return rows.reverse(); +} + +/** Appends a message. */ +export function insertMessage( + threadId: string, + sender: string, + text: string +): Promise { + return prisma.chatMessage.create({ + data: { threadId, sender, text }, + select: { id: true, sender: true, text: true, createdAt: true }, + }); +} + +function toThreadRow( + thread: { id: string; participantA: string; participantB: string; createdAt: Date }, + viewer: string +): ThreadRow { + return { + id: thread.id, + counterpart: thread.participantA === viewer ? thread.participantB : thread.participantA, + createdAt: thread.createdAt, + }; +} diff --git a/backend/src/routes/chat.ts b/backend/src/routes/chat.ts new file mode 100644 index 00000000..0224c120 --- /dev/null +++ b/backend/src/routes/chat.ts @@ -0,0 +1,15 @@ +import express, { Router } from 'express'; +import { verifyToken } from '@middleware/auth'; +import { chatReadRateLimit, chatSendRateLimit } from '@middleware/rateLimit'; +import { getMessages, getThreads, postMessage } from '@features/chat'; + +const router: Router = express.Router(); + +// Rate limits run after verifyToken so the budget is per wallet, not per IP. Sending is +// held to a much tighter budget than reading: a read is one indexed query, while a send +// is the one endpoint in this feature that creates content someone else has to receive. +router.get('/threads', verifyToken, chatReadRateLimit, getThreads); +router.get('/threads/:id/messages', verifyToken, chatReadRateLimit, getMessages); +router.post('/threads/:id/messages', verifyToken, chatSendRateLimit, postMessage); + +export default router; diff --git a/backend/tests/features/chat.controller.test.ts b/backend/tests/features/chat.controller.test.ts new file mode 100644 index 00000000..70b8092a --- /dev/null +++ b/backend/tests/features/chat.controller.test.ts @@ -0,0 +1,162 @@ +import { describe, expect, it, vi, beforeEach } from 'vitest'; +import type { Request, Response } from 'express'; + +vi.mock('../../src/features/chat/chat.service', () => ({ + listThreads: vi.fn(), + authorizeThread: vi.fn(), + readMessages: vi.fn(), + sendMessage: vi.fn(), +})); + +import { getMessages, getThreads, postMessage } from '../../src/features/chat/chat.controller'; +import { + authorizeThread, + listThreads, + readMessages, + sendMessage, +} from '../../src/features/chat/chat.service'; + +function makeRes() { + const res = { status: vi.fn().mockReturnThis(), json: vi.fn().mockReturnThis() }; + return res as unknown as Response; +} + +const ME = '0x1111111111111111111111111111111111111111'; + +/** An authenticated request for thread `t1`. */ +function req(over: Record = {}): Request { + return { + params: { id: 't1' }, + query: {}, + body: {}, + user: { address: ME, userId: 'u1' }, + ...over, + } as unknown as Request; +} + +beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(authorizeThread).mockResolvedValue({ denial: null, counterpart: '0xthem' }); +}); + +describe('getThreads', () => { + it('lists threads for the session wallet', async () => { + vi.mocked(listThreads).mockResolvedValue([]); + const res = makeRes(); + + await getThreads(req(), res); + + expect(listThreads).toHaveBeenCalledWith(ME); + expect(res.json).toHaveBeenCalledWith({ threads: [] }); + }); + + it('returns 401 without an authenticated user', async () => { + const res = makeRes(); + await getThreads(req({ user: undefined }), res); + expect(res.status).toHaveBeenCalledWith(401); + expect(listThreads).not.toHaveBeenCalled(); + }); +}); + +describe('thread authorization', () => { + // A non-participant must not be able to tell an existing thread id from a made-up + // one; 403 here would confirm the id for anyone probing. + it('answers 404, not 403, for a wallet that is not a participant', async () => { + vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-a-participant' }); + const res = makeRes(); + + await getMessages(req(), res); + + expect(res.status).toHaveBeenCalledWith(404); + expect(readMessages).not.toHaveBeenCalled(); + }); + + it('answers 404 for a thread that does not exist', async () => { + vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-found' }); + const res = makeRes(); + + await getMessages(req(), res); + + expect(res.status).toHaveBeenCalledWith(404); + }); + + // A participant already knows the thread exists, so an ended marriage can say so. + it('answers 403 with a reason when the marriage has ended', async () => { + vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-married' }); + const res = makeRes(); + + await postMessage(req({ body: { text: 'hi' } }), res); + + expect(res.status).toHaveBeenCalledWith(403); + expect(sendMessage).not.toHaveBeenCalled(); + }); +}); + +describe('getMessages', () => { + it('passes the page through after authorizing', async () => { + vi.mocked(readMessages).mockResolvedValue([]); + const res = makeRes(); + + await getMessages(req({ query: { limit: '10', before: '99' } }), res); + + expect(readMessages).toHaveBeenCalledWith('t1', 10, 99); + }); + + it('rejects a bad page size before touching the database', async () => { + const res = makeRes(); + + await getMessages(req({ query: { limit: '5000' } }), res); + + expect(res.status).toHaveBeenCalledWith(400); + expect(readMessages).not.toHaveBeenCalled(); + }); +}); + +describe('postMessage', () => { + it('stores the trimmed text under the session wallet', async () => { + vi.mocked(sendMessage).mockResolvedValue({ + id: 1, + sender: ME, + text: 'hello', + createdAt: new Date(0), + }); + const res = makeRes(); + + await postMessage(req({ body: { text: ' hello ' } }), res); + + expect(sendMessage).toHaveBeenCalledWith('t1', ME, 'hello'); + expect(res.status).toHaveBeenCalledWith(201); + }); + + it('rejects a message that is only whitespace', async () => { + const res = makeRes(); + + await postMessage(req({ body: { text: ' ' } }), res); + + expect(res.status).toHaveBeenCalledWith(400); + expect(sendMessage).not.toHaveBeenCalled(); + }); + + it('rejects a message past the length cap', async () => { + const res = makeRes(); + + await postMessage(req({ body: { text: 'x'.repeat(2001) } }), res); + + expect(res.status).toHaveBeenCalledWith(400); + expect(sendMessage).not.toHaveBeenCalled(); + }); + + it('cannot send as another wallet by putting one in the body', async () => { + vi.mocked(sendMessage).mockResolvedValue({ + id: 1, + sender: ME, + text: 'hi', + createdAt: new Date(0), + }); + const res = makeRes(); + + await postMessage(req({ body: { text: 'hi', sender: '0xsomeone-else' } }), res); + + expect(sendMessage).toHaveBeenCalledWith('t1', ME, 'hi'); + }); +}); diff --git a/backend/tests/features/chat.service.test.ts b/backend/tests/features/chat.service.test.ts new file mode 100644 index 00000000..77cf7d1f --- /dev/null +++ b/backend/tests/features/chat.service.test.ts @@ -0,0 +1,127 @@ +import { describe, expect, it, vi, beforeEach } from 'vitest'; + +const findMarriedCounterparts = vi.fn(); +const openThread = vi.fn(); +const findThreadById = vi.fn(); + +vi.mock('@repositories/chat.repository', () => ({ + findMarriedCounterparts: (caller: string) => findMarriedCounterparts(caller), + openThread: (x: string, y: string, scope: string) => openThread(x, y, scope), + findThreadById: (id: string) => findThreadById(id), + findMessages: vi.fn(), + insertMessage: vi.fn(), +})); + +import { authorizeThread, listThreads } from '../../src/features/chat/chat.service'; + +const ME = '0x1111111111111111111111111111111111111111'; +const THEM = '0x2222222222222222222222222222222222222222'; + +const marriage = (over: Record = {}) => ({ + chain: 'evm', + petId: '1', + petName: 'Mine', + spousePetId: '2', + spouseName: 'Theirs', + counterpart: THEM, + ...over, +}); + +beforeEach(() => { + vi.clearAllMocks(); + openThread.mockImplementation(async (x: string, y: string) => ({ + id: `thread-${x}-${y}`, + counterpart: y, + createdAt: new Date(0), + })); +}); + +describe('listThreads', () => { + it('opens one thread per married counterpart', async () => { + findMarriedCounterparts.mockResolvedValue([marriage()]); + + const threads = await listThreads(ME); + + expect(threads).toHaveLength(1); + expect(threads[0].counterpart).toBe(THEM); + expect(openThread).toHaveBeenCalledWith(ME, THEM, 'marriage'); + }); + + it('collapses two married pet couples between the same owners into one thread', async () => { + // The conversation is between the owners, not the pets. Two threads here would + // split one relationship across two inboxes. + findMarriedCounterparts.mockResolvedValue([ + marriage(), + marriage({ petId: '3', petName: 'Second', spousePetId: '4', spouseName: 'Fourth' }), + ]); + + const threads = await listThreads(ME); + + expect(threads).toHaveLength(1); + expect(threads[0].pets).toHaveLength(2); + expect(openThread).toHaveBeenCalledTimes(1); + }); + + it('returns nothing, and opens nothing, for an unmarried caller', async () => { + findMarriedCounterparts.mockResolvedValue([]); + + expect(await listThreads(ME)).toEqual([]); + expect(openThread).not.toHaveBeenCalled(); + }); + + it('normalizes the counterpart, so a mixed-case roster owner is one participant', async () => { + // indexer-go is not guaranteed to write the roster in the JWT's case; an + // unnormalized counterpart would open a second thread for the same wallet. + findMarriedCounterparts.mockResolvedValue([marriage({ counterpart: THEM.toUpperCase().replace('0X', '0x') })]); + + const threads = await listThreads(ME); + + expect(threads[0].counterpart).toBe(THEM); + expect(openThread).toHaveBeenCalledWith(ME, THEM, 'marriage'); + }); +}); + +describe('authorizeThread', () => { + const thread = { id: 't1', participantA: ME, participantB: THEM, scope: 'marriage' }; + + it('allows a participant whose marriage is live', async () => { + findThreadById.mockResolvedValue(thread); + findMarriedCounterparts.mockResolvedValue([marriage()]); + + expect(await authorizeThread('t1', ME)).toEqual({ denial: null, counterpart: THEM }); + }); + + it('refuses a wallet that is not a participant', async () => { + findThreadById.mockResolvedValue(thread); + + const result = await authorizeThread('t1', '0x9999999999999999999999999999999999999999'); + + expect(result.denial).toBe('not-a-participant'); + // The marriage is not even consulted: not being in the thread settles it. + expect(findMarriedCounterparts).not.toHaveBeenCalled(); + }); + + // The point of checking live state per request instead of recording it on the + // thread: a divorce closes the conversation with nothing to revoke. + it('refuses a participant whose marriage has ended', async () => { + findThreadById.mockResolvedValue(thread); + findMarriedCounterparts.mockResolvedValue([]); + + expect((await authorizeThread('t1', ME)).denial).toBe('not-married'); + }); + + it('refuses a participant now married to somebody else', async () => { + findThreadById.mockResolvedValue(thread); + findMarriedCounterparts.mockResolvedValue([ + marriage({ counterpart: '0x3333333333333333333333333333333333333333' }), + ]); + + expect((await authorizeThread('t1', ME)).denial).toBe('not-married'); + }); + + it('reports a missing thread', async () => { + findThreadById.mockResolvedValue(null); + + expect((await authorizeThread('nope', ME)).denial).toBe('not-found'); + }); +}); From cd78ee82a58024c25999e671282ca61b2dbc737c Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 08:50:10 -0400 Subject: [PATCH 11/61] feat(backend): push chat updates over a notification-only socket --- backend/API.md | 26 ++++ backend/src/features/chat/chat.controller.ts | 12 +- backend/src/server.ts | 6 + backend/src/ws/chatSocket.ts | 107 +++++++++++++++ .../tests/features/chat.controller.test.ts | 27 ++++ backend/tests/ws/chatSocket.test.ts | 125 ++++++++++++++++++ 6 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 backend/src/ws/chatSocket.ts create mode 100644 backend/tests/ws/chatSocket.test.ts diff --git a/backend/API.md b/backend/API.md index df04439a..d7ea8b9a 100644 --- a/backend/API.md +++ b/backend/API.md @@ -371,6 +371,32 @@ client-side by `(chainId, requestId)`. That socket was removed once battles stopped being resolved from chain state, so there is no longer a second channel and nothing left to filter. +### Chat WebSocket (roadmap §2) + +``` +ws(s):///ws/chat?threadId= +``` + +Notification-only, per-thread. Connecting without a `threadId` closes the socket +immediately (code `1008`). Every message is the same shape, and carries **no message +text**: + +```json +{ "type": "thread-updated", "threadId": "c...", "messageId": 42 } +``` + +The roadmap assumed chat could reuse an authenticated socket. There isn't one — the +battle-room channel above joins whoever presents a room id, which is safe there because +its payload is not content. This channel keeps that posture and gets its safety from the +same place: it says a thread changed, and the text comes from +`GET /api/chat/threads/:id/messages`, which authenticates the caller and rechecks the +marriage. Missing a notification costs latency, never access. + +What a listener does learn is timing — that a thread whose id they hold saw activity. +Thread ids are cuids handed out only by an authenticated read. If v2 opens direct +messages to strangers, this channel should be authenticated first, with the token in a +subprotocol rather than the query string, where proxies and access logs would record it. + ### Public receipt corpus (v2) `backend/src/routes/receipts.ts` — the paginated export §H item 3 calls for. diff --git a/backend/src/features/chat/chat.controller.ts b/backend/src/features/chat/chat.controller.ts index 8abef92f..20f73235 100644 --- a/backend/src/features/chat/chat.controller.ts +++ b/backend/src/features/chat/chat.controller.ts @@ -1,6 +1,7 @@ import type { Request, Response } from 'express'; import type { AuthenticatedRequest } from '@middleware/auth'; +import { notifyChatThread } from '@ws/chatSocket'; import { authorizeThread, listThreads, readMessages, sendMessage, type ChatDenial } from './chat.service'; import { ListMessagesSchema, SendMessageSchema } from './chat.schema'; @@ -77,7 +78,16 @@ export async function postMessage(req: Request, res: Response): Promise { } try { - res.status(201).json({ message: await sendMessage(threadId, caller, body.data.text) }); + const message = await sendMessage(threadId, caller, body.data.text); + // After the write, never instead of it: the message is already durable, so a + // failure to notify costs liveness, not the message. Carries no text — see + // `chatSocket`. + notifyChatThread(threadId, { + type: 'thread-updated', + threadId, + messageId: message.id, + }); + res.status(201).json({ message }); } catch (err) { console.error('[chat] failed to send message:', err); res.status(500).json({ error: 'Failed to send message' }); diff --git a/backend/src/server.ts b/backend/src/server.ts index c6e10a49..9a3e2d36 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -7,6 +7,7 @@ import { startSettleKeeper, stopSettleKeeper } from '@features/settle-keeper'; import { type BattleWorkerHandle, startBattleWorker } from '@features/battle-worker'; import { startBatchAnchor, stopBatchAnchor } from '@features/battle-anchor'; import { startBattleRoomSocket, stopBattleRoomSocket } from '@ws/battleRoomSocket'; +import { startChatSocket, stopChatSocket } from '@ws/chatSocket'; let battleWorker: BattleWorkerHandle | undefined; @@ -23,6 +24,10 @@ const server = app.listen(env.port, '0.0.0.0', () => { // Notification-only per-room channel for backend-authoritative battles (§J). Always on; // a client only gets pushed to if it connected with a roomId it already knows about. startBattleRoomSocket(server); + // Per-thread notification channel for private chat. Same posture as the battle room: + // it says a thread changed and nothing more, so the authenticated read stays the only + // thing that decides who sees a message. + startChatSocket(server); // Settles GameLogic battle/breed/mint requests once entropy reveals. No-op unless // KEEPER_ENABLED is set. startSettleKeeper(); @@ -77,6 +82,7 @@ async function shutdown(signal: NodeJS.Signals): Promise { battleWorker?.stop(); stopBatchAnchor(); stopBattleRoomSocket(); + stopChatSocket(); await new Promise((resolve) => server.close(() => resolve())); await prisma.$disconnect(); diff --git a/backend/src/ws/chatSocket.ts b/backend/src/ws/chatSocket.ts new file mode 100644 index 00000000..a8d5771e --- /dev/null +++ b/backend/src/ws/chatSocket.ts @@ -0,0 +1,107 @@ +import type { Server } from 'node:http'; +import { URL } from 'node:url'; + +// Named import for the same reason `battleRoomSocket` uses one: `ws`'s ESM entry exposes +// the server class only as `WebSocketServer`, with no `.Server` static. +import WebSocket, { WebSocketServer } from 'ws'; + +/** + * The per-thread notification channel for private chat (roadmap §2 v1). + * + * **Carries no message content, deliberately.** The roadmap assumed chat could reuse an + * authenticated socket; there isn't one. `battleRoomSocket` — the channel §2 pointed at, + * under its old name — takes an id from the query string and joins whoever asks, which + * is fine for battle updates because those carry nothing a client could not re-fetch + * anyway. Pushing message text down a channel like that would hand private conversations + * to anyone holding a thread id. + * + * So this keeps the same posture and inherits its safety from it: the socket only ever + * says "thread X changed", and the content comes from `GET /api/chat/threads/:id/messages`, + * which authenticates the caller and rechecks the marriage. A client that missed a + * notification, or never connected at all, learns exactly the same thing by re-reading. + * This makes chat feel live; it is never the thing that decides who may read it. + * + * What a listener does learn is *timing* — that a thread they know the id of had activity. + * Thread ids are cuids handed out only by an authenticated read, so that requires already + * having been told one. If v2 opens direct messages to strangers, this channel should gain + * real authentication before it does, and the token belongs in a subprotocol rather than + * the query string, where proxies and access logs would record it. + * + * Deliberately a separate file from `battleRoomSocket` rather than a shared abstraction + * over the two. The membership bookkeeping is the same today, but the two channels are + * heading different places — this one needs per-listener authorization the moment its + * scope widens, and that is exactly the seam a premature shared helper would fuse shut. + */ + +export interface ChatThreadNotification { + type: 'thread-updated'; + threadId: string; + /** Id of the message that caused it, so a client can skip a re-read it already has. */ + messageId: number; +} + +let wss: WebSocketServer | null = null; +const threadListeners = new Map>(); + +export function startChatSocket(server: Server): void { + wss = new WebSocketServer({ server, path: '/ws/chat' }); + wss.on('connection', (socket, request) => { + const threadId = threadIdFromUrl(request.url); + if (!threadId) { + socket.close(1008, 'threadId query parameter is required'); + return; + } + join(threadId, socket); + socket.on('close', () => leave(threadId, socket)); + }); + console.log('[chat-ws] listening on /ws/chat'); +} + +export function stopChatSocket(): void { + wss?.close(); + wss = null; + threadListeners.clear(); +} + +/** + * Tells everyone watching `threadId` that it changed. + * + * A no-op when nobody is listening, which is the normal case: most messages are sent to + * someone who is not looking at the app. Delivery here is an optimization, so a missed + * notification is not a failure worth surfacing — the recipient sees the message on their + * next read either way. + */ +export function notifyChatThread(threadId: string, message: ChatThreadNotification): void { + const listeners = threadListeners.get(threadId); + if (!listeners || listeners.size === 0) return; + const payload = JSON.stringify(message); + for (const client of listeners) { + if (client.readyState === WebSocket.OPEN) client.send(payload); + } +} + +function join(threadId: string, socket: WebSocket): void { + let listeners = threadListeners.get(threadId); + if (!listeners) { + listeners = new Set(); + threadListeners.set(threadId, listeners); + } + listeners.add(socket); +} + +function leave(threadId: string, socket: WebSocket): void { + const listeners = threadListeners.get(threadId); + if (!listeners) return; + listeners.delete(socket); + if (listeners.size === 0) threadListeners.delete(threadId); +} + +function threadIdFromUrl(url: string | undefined): string | null { + if (!url) return null; + try { + // The base is discarded; WHATWG URL just needs an absolute one to parse against. + return new URL(url, 'http://internal').searchParams.get('threadId'); + } catch { + return null; + } +} diff --git a/backend/tests/features/chat.controller.test.ts b/backend/tests/features/chat.controller.test.ts index 70b8092a..1c114ec7 100644 --- a/backend/tests/features/chat.controller.test.ts +++ b/backend/tests/features/chat.controller.test.ts @@ -7,6 +7,7 @@ vi.mock('../../src/features/chat/chat.service', () => ({ readMessages: vi.fn(), sendMessage: vi.fn(), })); +vi.mock('@ws/chatSocket', () => ({ notifyChatThread: vi.fn() })); import { getMessages, getThreads, postMessage } from '../../src/features/chat/chat.controller'; import { @@ -15,6 +16,7 @@ import { readMessages, sendMessage, } from '../../src/features/chat/chat.service'; +import { notifyChatThread } from '@ws/chatSocket'; function makeRes() { const res = { status: vi.fn().mockReturnThis(), json: vi.fn().mockReturnThis() }; @@ -146,6 +148,31 @@ describe('postMessage', () => { expect(sendMessage).not.toHaveBeenCalled(); }); + it('notifies the thread after the write, carrying the id and no text', async () => { + vi.mocked(sendMessage).mockResolvedValue({ + id: 42, + sender: ME, + text: 'hello', + createdAt: new Date(0), + }); + + await postMessage(req({ body: { text: 'hello' } }), makeRes()); + + expect(notifyChatThread).toHaveBeenCalledWith('t1', { + type: 'thread-updated', + threadId: 't1', + messageId: 42, + }); + }); + + it('does not notify when the write was refused', async () => { + vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-married' }); + + await postMessage(req({ body: { text: 'hello' } }), makeRes()); + + expect(notifyChatThread).not.toHaveBeenCalled(); + }); + it('cannot send as another wallet by putting one in the body', async () => { vi.mocked(sendMessage).mockResolvedValue({ id: 1, diff --git a/backend/tests/ws/chatSocket.test.ts b/backend/tests/ws/chatSocket.test.ts new file mode 100644 index 00000000..c271cfcc --- /dev/null +++ b/backend/tests/ws/chatSocket.test.ts @@ -0,0 +1,125 @@ +import { createServer, type Server } from 'node:http'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import WebSocket from 'ws'; + +import { notifyChatThread, startChatSocket, stopChatSocket } from '@ws/chatSocket'; + +/** + * Real server and real clients, because the property under test is delivery over the + * wire: a listener on thread A must never receive thread B's notification, and what + * arrives must contain no message text — the socket exists to prompt an authenticated + * re-read, never to be one. + */ + +let server: Server; +let baseUrl: string; + +beforeEach(async () => { + server = createServer(); + startChatSocket(server); + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); + const address = server.address(); + if (address === null || typeof address === 'string') { + throw new Error('expected a bound TCP address'); + } + baseUrl = `ws://127.0.0.1:${address.port}/ws/chat`; +}); + +afterEach(async () => { + stopChatSocket(); + await new Promise((resolve) => server.close(() => resolve())); +}); + +function connect(threadId: string | null): Promise { + return new Promise((resolve, reject) => { + const url = threadId === null ? baseUrl : `${baseUrl}?threadId=${threadId}`; + const socket = new WebSocket(url); + socket.once('open', () => resolve(socket)); + socket.once('error', reject); + }); +} + +function nextMessage(socket: WebSocket): Promise { + return new Promise((resolve, reject) => { + socket.once('message', (data) => resolve(JSON.parse(data.toString()))); + socket.once('close', (code) => reject(new Error(`closed before a message arrived: ${code}`))); + }); +} + +function nextClose(socket: WebSocket): Promise { + return new Promise((resolve) => socket.once('close', (code) => resolve(code))); +} + +const update = { type: 'thread-updated', threadId: 'thread_1', messageId: 7 } as const; + +describe('thread scoping', () => { + it('delivers only to listeners on that thread', async () => { + const onThread = await connect('thread_1'); + const onOther = await connect('thread_2'); + const otherMessage = nextMessage(onOther); + + const received = nextMessage(onThread); + notifyChatThread('thread_1', update); + await expect(received).resolves.toEqual(update); + + // Prove the negative without a timeout: race the other listener against a + // notification for its own thread, which must be the first thing it sees. + const ownUpdate = { type: 'thread-updated', threadId: 'thread_2', messageId: 9 } as const; + notifyChatThread('thread_2', ownUpdate); + await expect(otherMessage).resolves.toEqual(ownUpdate); + + onThread.close(); + onOther.close(); + }); + + it('delivers to both participants watching the same thread', async () => { + const first = await connect('thread_1'); + const second = await connect('thread_1'); + const firstMessage = nextMessage(first); + const secondMessage = nextMessage(second); + + notifyChatThread('thread_1', update); + + await expect(firstMessage).resolves.toEqual(update); + await expect(secondMessage).resolves.toEqual(update); + + first.close(); + second.close(); + }); + + // The whole safety argument for an unauthenticated channel: what it pushes is not + // readable content, so a listener still has to pass the authenticated read. + it('carries no message text', async () => { + const socket = await connect('thread_1'); + const received = nextMessage(socket); + + notifyChatThread('thread_1', update); + + expect(Object.keys((await received) as object).sort()).toEqual([ + 'messageId', + 'threadId', + 'type', + ]); + socket.close(); + }); + + it('does not throw when nobody is listening', () => { + // The normal case: most messages arrive while the recipient has the app closed. + expect(() => notifyChatThread('quiet', update)).not.toThrow(); + }); + + it('stops delivering to a client after it disconnects', async () => { + const socket = await connect('thread_1'); + socket.close(); + await nextClose(socket); + + expect(() => notifyChatThread('thread_1', update)).not.toThrow(); + }); +}); + +describe('connection requirements', () => { + it('closes a connection that names no thread', async () => { + const socket = new WebSocket(baseUrl); + expect(await nextClose(socket)).toBe(1008); + }); +}); From 75e0a54a11c5ad6e32905a819ea4fc47ee4fd774 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 09:00:04 -0400 Subject: [PATCH 12/61] feat(frontend): add private chat for married-pet counterparts --- frontend/src/components/chat/index.module.css | 191 ++++++++++++++ frontend/src/components/chat/index.tsx | 233 ++++++++++++++++++ .../components/layout/sidebar/nav-items.ts | 10 + frontend/src/config.ts | 8 + frontend/src/constants/interactionRoutes.ts | 3 + frontend/src/pages/chat/index.tsx | 7 + frontend/src/router/app-routes/index.tsx | 2 + frontend/tests/components/chat.test.tsx | 188 ++++++++++++++ frontend/tests/setup.ts | 8 + shared/src/hooks/chat/useChatMessages.ts | 110 +++++++++ shared/src/hooks/chat/useChatThreadSocket.ts | 118 +++++++++ shared/src/hooks/chat/useChatThreads.ts | 57 +++++ shared/src/hooks/index.ts | 21 ++ 13 files changed, 956 insertions(+) create mode 100644 frontend/src/components/chat/index.module.css create mode 100644 frontend/src/components/chat/index.tsx create mode 100644 frontend/src/pages/chat/index.tsx create mode 100644 frontend/tests/components/chat.test.tsx create mode 100644 shared/src/hooks/chat/useChatMessages.ts create mode 100644 shared/src/hooks/chat/useChatThreadSocket.ts create mode 100644 shared/src/hooks/chat/useChatThreads.ts diff --git a/frontend/src/components/chat/index.module.css b/frontend/src/components/chat/index.module.css new file mode 100644 index 00000000..0aa0368e --- /dev/null +++ b/frontend/src/components/chat/index.module.css @@ -0,0 +1,191 @@ +/* CSS Module — class names are local; reference via `import styles from './index.module.css'`. + Private chat: thread rail plus one conversation, magenta accent to match marriage. */ +.layout { + display: grid; + grid-template-columns: minmax(0, 240px) minmax(0, 1fr); + gap: 14px; + align-items: start; +} + +.threadList { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + gap: 6px; +} + +.threadButton { + width: 100%; + display: flex; + flex-direction: column; + gap: 2px; + padding: 10px 12px; + border-radius: 10px; + border: 1px solid rgb(148 163 184 / 14%); + background: var(--cp-surface); + color: inherit; + font: inherit; + text-align: left; + cursor: pointer; +} + +.threadButton.isActive { + border-color: rgb(255 123 203 / 55%); + background: rgb(255 123 203 / 8%); +} + +.threadName { + font-size: 0.9rem; + font-variant-numeric: tabular-nums; +} + +.threadSub, +.conversationSub { + font-size: 0.75rem; + opacity: 0.6; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.conversation { + display: flex; + flex-direction: column; + min-width: 0; + height: 460px; + border-radius: 10px; + border: 1px solid rgb(148 163 184 / 14%); + background: var(--cp-surface); +} + +.conversationHeader { + display: flex; + align-items: baseline; + gap: 10px; + padding: 10px 14px; + border-bottom: 1px solid rgb(148 163 184 / 12%); +} + +.conversationTitle { + font-size: 0.95rem; +} + +/* Stated plainly rather than blocking the composer: sending still works while the + notification channel is down, it just will not update on its own. */ +.offline { + margin-left: auto; + font-size: 0.7rem; + text-transform: uppercase; + letter-spacing: 0.5px; + opacity: 0.5; +} + +.messages { + list-style: none; + margin: 0; + padding: 12px 14px; + flex: 1; + min-height: 0; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 8px; +} + +.message { + max-width: 78%; + align-self: flex-start; + display: flex; + align-items: baseline; + gap: 8px; + padding: 7px 11px; + border-radius: 12px; + background: rgb(148 163 184 / 12%); +} + +.message.isMine { + align-self: flex-end; + background: rgb(255 123 203 / 16%); +} + +.messageText { + /* User-authored text: wrap anywhere rather than let one long token stretch the row. */ + min-width: 0; + overflow-wrap: anywhere; + font-size: 0.9rem; +} + +.messageTime { + flex-shrink: 0; + font-size: 0.7rem; + opacity: 0.5; + font-variant-numeric: tabular-nums; +} + +.composer { + display: flex; + gap: 8px; + padding: 10px 12px; + border-top: 1px solid rgb(148 163 184 / 12%); +} + +.composer input { + flex: 1; + min-width: 0; + padding: 8px 12px; + border-radius: 8px; + border: 1px solid rgb(148 163 184 / 22%); + background: transparent; + color: inherit; + font: inherit; + font-size: 0.9rem; +} + +.composer button { + padding: 8px 16px; + border-radius: 8px; + border: 1px solid rgb(255 123 203 / 45%); + background: rgb(255 123 203 / 12%); + color: inherit; + font: inherit; + font-size: 0.85rem; + cursor: pointer; +} + +.composer button:disabled { + opacity: 0.4; + cursor: default; +} + +.empty, +.error { + margin: 20px 14px; + font-size: 0.9rem; +} + +.empty { + opacity: 0.7; +} + +.error { + color: rgb(251 113 133); +} + +@media (width <= 720px) { + /* The rail becomes a strip above the conversation; two columns leave neither usable. */ + .layout { + grid-template-columns: minmax(0, 1fr); + } + + .threadList { + flex-direction: row; + overflow-x: auto; + } + + .threadButton { + width: auto; + flex-shrink: 0; + } +} diff --git a/frontend/src/components/chat/index.tsx b/frontend/src/components/chat/index.tsx new file mode 100644 index 00000000..89376453 --- /dev/null +++ b/frontend/src/components/chat/index.tsx @@ -0,0 +1,233 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { + useChainCapabilities, + useChatMessages, + useChatThreads, + type ChatThread, +} from '@shared/core'; + +import DashboardPanel from '@components/common/dashboard-panel'; +import StateCard from '@components/pet/interactions/state-card'; +import Icon, { MarriageIcon } from '@components/ui/icon'; +import { CHAT_WS_URL } from '../../config'; +import { DASHBOARD_HOME } from '@constants/interactionRoutes'; +import { Tones } from '@constants/tones'; +import styles from './index.module.css'; + +/** `0x1234…abcd` — a full address does not fit the thread list. */ +function shortAddress(address: string): string { + return address.length > 12 ? `${address.slice(0, 6)}…${address.slice(-4)}` : address; +} + +/** The married pets behind a thread, as a one-line reason it exists. */ +function marriageLine(thread: ChatThread): string { + return thread.pets.map((pair) => `${pair.petName} ♥ ${pair.spouseName}`).join(', '); +} + +function timeOf(createdAt: string): string { + const at = new Date(createdAt); + return Number.isNaN(at.getTime()) + ? '' + : at.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); +} + +const ThreadList: React.FC<{ + threads: ChatThread[]; + selectedId: string | null; + onSelect: (threadId: string) => void; +}> = ({ threads, selectedId, onSelect }) => ( +
      + {threads.map((thread) => ( +
    • + +
    • + ))} +
    +); + +const Conversation: React.FC<{ thread: ChatThread; me: string }> = ({ thread, me }) => { + const { messages, isLoading, error, isLive, send, isSending, sendError } = useChatMessages({ + threadId: thread.threadId, + socketUrl: CHAT_WS_URL, + }); + const [draft, setDraft] = useState(''); + const endRef = useRef(null); + + // Chats are read from the bottom. Keyed on the newest id rather than length so a + // re-read that changes nothing does not yank the view while someone scrolls up. + const newestId = messages[messages.length - 1]?.id; + useEffect(() => { + endRef.current?.scrollIntoView({ block: 'end' }); + }, [newestId]); + + const submit = async (event: React.FormEvent) => { + event.preventDefault(); + const text = draft.trim(); + if (!text || isSending) return; + try { + // Cleared only after the server accepts it: a send refused because the + // marriage ended must leave the text where the player can see it. + await send(text); + setDraft(''); + } catch { + // Already surfaced through `sendError`. Caught rather than left to reject, + // which in an onSubmit handler becomes an unhandled rejection nobody sees. + } + }; + + return ( +
    +
    + {shortAddress(thread.counterpart)} + {marriageLine(thread)} + {!isLive && ( + + offline + + )} +
    + + {error ? ( +

    {error.message}

    + ) : isLoading ? ( +
    +
    +
    + ) : messages.length === 0 ? ( +

    No messages yet. Say hello.

    + ) : ( +
      + {messages.map((message) => ( +
    1. + {message.text} + {timeOf(message.createdAt)} +
    2. + ))} +
      +
    + )} + +
    + setDraft(event.target.value)} + placeholder="Write a message" + maxLength={2000} + aria-label="Message" + /> + +
    + {sendError &&

    {sendError.message}

    } +
    + ); +}; + +/** + * Private chat between owners whose pets are married (roadmap §2 v1). + * + * The thread list is whatever the backend says it is. There is no way to start a + * conversation from here, by design: v1 has no discovery surface at all, so the only + * people a player can message are ones the game already connected them to. That is what + * lets v1 ship without block/report — a protection that ends the moment open DMs land. + * + * An empty list is the normal state for most players and says so, rather than looking + * like a failed load. + */ +const Chat: React.FC = () => { + const navigate = useNavigate(); + const { isConnected, walletAddress } = useChainCapabilities(); + const { threads, isLoading, error } = useChatThreads(); + const [selectedId, setSelectedId] = useState(null); + + const selected = useMemo( + () => threads.find((thread) => thread.threadId === selectedId) ?? threads[0] ?? null, + [threads, selectedId], + ); + + const goBack = () => navigate(DASHBOARD_HOME); + + if (!isConnected) { + return ( + + + Messages + + } + description="Connect your wallet to see your conversations" + back={goBack} + /> + ); + } + + return ( + + + Messages + + } + description="Private threads with the owners your pets are married to" + back={goBack} + > + {error ? ( +

    {error.message}

    + ) : isLoading ? ( +
    +
    +
    + ) : threads.length === 0 ? ( +

    + No conversations yet. Marry one of your pets to another player's to open + a thread with them. +

    + ) : ( +
    + + {selected && ( + + )} +
    + )} + + ); +}; + +export default Chat; diff --git a/frontend/src/components/layout/sidebar/nav-items.ts b/frontend/src/components/layout/sidebar/nav-items.ts index db17a367..b7735781 100644 --- a/frontend/src/components/layout/sidebar/nav-items.ts +++ b/frontend/src/components/layout/sidebar/nav-items.ts @@ -5,6 +5,7 @@ import { DASHBOARD_HOME, LEADERBOARD_PATH, LEVELUP_PATH, + MESSAGES_PATH, MARRIAGE_PATH, RENAME_PATH, TRAIN_PATH, @@ -50,6 +51,15 @@ export const NAV_ITEMS: readonly NavItem[] = [ { id: 'shard', label: 'Shard Forge', iconSrc: shardIcon, tone: 'cyan', deferred: true }, { id: 'marriage', label: 'Marriage', iconSrc: marriageIcon, tone: 'magenta', path: MARRIAGE_PATH }, { id: 'rename', label: 'Rename Pet', iconSrc: renameIcon, tone: 'cyan', path: RENAME_PATH }, + { + id: 'messages', + label: 'Messages', + // Reuses the marriage icon rather than inventing one: in v1 a thread exists + // only because two pets are married, so it is the same relationship. + iconSrc: marriageIcon, + tone: 'magenta', + path: MESSAGES_PATH, + }, { id: 'leaderboard', label: 'Leaderboard', diff --git a/frontend/src/config.ts b/frontend/src/config.ts index f5942c21..2a6f2f96 100644 --- a/frontend/src/config.ts +++ b/frontend/src/config.ts @@ -15,6 +15,14 @@ export const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001'; */ export const BATTLE_ROOM_WS_URL = `${API_URL.replace(/^http/, 'ws')}/ws/battle-room`; +/** + * Per-thread notification channel for private chat (roadmap §2). + * + * Carries no message text, only "this thread changed" — the authenticated read is what + * returns messages, so an unreachable socket costs liveness, never access. + */ +export const CHAT_WS_URL = `${API_URL.replace(/^http/, 'ws')}/ws/chat`; + const AUTH_TOKEN_KEY = 'authToken'; // localStorage-backed token persistence — the single source of truth for the key. diff --git a/frontend/src/constants/interactionRoutes.ts b/frontend/src/constants/interactionRoutes.ts index 528d1312..5da0a45d 100644 --- a/frontend/src/constants/interactionRoutes.ts +++ b/frontend/src/constants/interactionRoutes.ts @@ -66,3 +66,6 @@ export const DEFENSE_PATH = '/defense'; /** Read-only view, not an interaction — no pet selection, nothing to sign. */ export const LEADERBOARD_PATH = '/leaderboard'; + +/** Private chat with married-pet counterparts. Also not an interaction. */ +export const MESSAGES_PATH = '/messages'; diff --git a/frontend/src/pages/chat/index.tsx b/frontend/src/pages/chat/index.tsx new file mode 100644 index 00000000..7b1adc28 --- /dev/null +++ b/frontend/src/pages/chat/index.tsx @@ -0,0 +1,7 @@ +import React from 'react'; +import Chat from '@components/chat'; + +/** Top-level `/messages` page — private threads with married-pet counterparts. */ +const ChatPage: React.FC = () => ; + +export default ChatPage; diff --git a/frontend/src/router/app-routes/index.tsx b/frontend/src/router/app-routes/index.tsx index b31b065f..b4f7b7cd 100644 --- a/frontend/src/router/app-routes/index.tsx +++ b/frontend/src/router/app-routes/index.tsx @@ -15,6 +15,7 @@ const MarriagePage = lazy(() => import('@pages/marriage')); const RenamePage = lazy(() => import('@pages/rename')); const DefensePage = lazy(() => import('@pages/defense')); const LeaderboardPage = lazy(() => import('@pages/leaderboard')); +const ChatPage = lazy(() => import('@pages/chat')); // SCRATCH — remove after visual verification. const BattleOverlayPreview = lazy(() => import('@pages/__preview/battle-overlay-preview')); @@ -42,6 +43,7 @@ const AppRoutes: React.FC = () => { } /> } /> } /> + } /> } /> } /> diff --git a/frontend/tests/components/chat.test.tsx b/frontend/tests/components/chat.test.tsx new file mode 100644 index 00000000..8f98a0ff --- /dev/null +++ b/frontend/tests/components/chat.test.tsx @@ -0,0 +1,188 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { render, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { MemoryRouter } from 'react-router-dom'; + +const useChainCapabilities = vi.fn(); +const useChatThreads = vi.fn(); +const useChatMessages = vi.fn(); + +vi.mock('@shared/core', () => ({ + useChainCapabilities: () => useChainCapabilities(), + useChatThreads: () => useChatThreads(), + useChatMessages: (opts: unknown) => useChatMessages(opts), +})); + +// `config.ts` registers the storage adapter with @shared/core at module scope, which the +// mock above does not provide. Only the socket URL is needed here, so stub the module +// rather than reconstructing the app's bootstrap. +vi.mock('../../src/config', () => ({ + API_URL: 'http://test', + BATTLE_ROOM_WS_URL: 'ws://test/ws/battle-room', + CHAT_WS_URL: 'ws://test/ws/chat', +})); + +import Chat from '@components/chat'; + +const ME = '0xAAAAbbbbCCCCddddEEEEffff0000111122223333'; +const THEM = '0x2222222222222222222222222222222222222222'; + +const thread = (over: Record = {}) => ({ + threadId: 't1', + counterpart: THEM, + pets: [{ petId: '1', petName: 'Mine', spousePetId: '2', spouseName: 'Theirs' }], + chain: 'evm', + ...over, +}); + +const message = (over: Record = {}) => ({ + id: 1, + sender: THEM, + text: 'hello there', + createdAt: new Date(0).toISOString(), + ...over, +}); + +const send = vi.fn(); + +const messagesResult = (over: Record = {}) => ({ + messages: [], + isLoading: false, + error: null, + isLive: true, + send, + isSending: false, + sendError: null, + ...over, +}); + +const renderChat = () => + render( + + + , + ); + +beforeEach(() => { + vi.clearAllMocks(); + send.mockResolvedValue(undefined); + useChainCapabilities.mockReturnValue({ isConnected: true, walletAddress: ME }); + useChatThreads.mockReturnValue({ threads: [], isLoading: false, error: null }); + useChatMessages.mockReturnValue(messagesResult()); +}); + +describe('Chat', () => { + it('asks for a wallet before showing conversations', () => { + useChainCapabilities.mockReturnValue({ isConnected: false, walletAddress: null }); + + renderChat(); + + expect(screen.getByText(/Connect your wallet/i)).toBeInTheDocument(); + }); + + // The normal state for most players, and it must not read as a failed load. + it('explains how to get a thread when there are none', () => { + renderChat(); + + expect(screen.getByText(/Marry one of your pets/i)).toBeInTheDocument(); + }); + + it('shows the counterpart and the marriage behind each thread', () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + + renderChat(); + + expect(screen.getAllByText(/0x2222…2222/).length).toBeGreaterThan(0); + expect(screen.getAllByText('Mine ♥ Theirs').length).toBeGreaterThan(0); + }); + + it('separates my messages from theirs', () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + useChatMessages.mockReturnValue( + messagesResult({ + messages: [message(), message({ id: 2, sender: ME.toLowerCase(), text: 'hi back' })], + }), + ); + + renderChat(); + + const theirs = screen.getByText('hello there').closest('li') as HTMLElement; + const mine = screen.getByText('hi back').closest('li') as HTMLElement; + // Case differs between the wallet and the stored sender, so the sides must not + // be decided by an exact string match. + expect(mine.className).not.toEqual(theirs.className); + }); + + it('sends the trimmed draft and clears the box', async () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + + renderChat(); + const box = screen.getByLabelText('Message'); + await userEvent.type(box, ' hello '); + await userEvent.click(screen.getByRole('button', { name: 'Send' })); + + expect(send).toHaveBeenCalledWith('hello'); + expect(box).toHaveValue(''); + }); + + // A refused send must leave the text where the player can see it, not swallow it. + it('keeps the draft when sending fails', async () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + send.mockRejectedValue(new Error('marriage ended')); + + renderChat(); + const box = screen.getByLabelText('Message'); + await userEvent.type(box, 'still here'); + await userEvent.click(screen.getByRole('button', { name: 'Send' })); + + expect(box).toHaveValue('still here'); + }); + + it('will not send an empty draft', async () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + + renderChat(); + await userEvent.type(screen.getByLabelText('Message'), ' '); + + expect(screen.getByRole('button', { name: 'Send' })).toBeDisabled(); + expect(send).not.toHaveBeenCalled(); + }); + + it('says when the live channel is down without blocking sending', () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + useChatMessages.mockReturnValue(messagesResult({ isLive: false })); + + renderChat(); + + expect(screen.getByText('offline')).toBeInTheDocument(); + expect(screen.getByLabelText('Message')).toBeEnabled(); + }); + + it('switches conversations when another thread is picked', async () => { + useChatThreads.mockReturnValue({ + threads: [thread(), thread({ threadId: 't2', counterpart: '0x3333333333333333333333333333333333333333' })], + isLoading: false, + error: null, + }); + + renderChat(); + const list = screen.getByRole('list'); + await userEvent.click(within(list).getByText(/0x3333…3333/)); + + expect(useChatMessages).toHaveBeenLastCalledWith( + expect.objectContaining({ threadId: 't2' }), + ); + }); + + it('surfaces a thread-list failure', () => { + useChatThreads.mockReturnValue({ + threads: [], + isLoading: false, + error: new Error('backend unreachable'), + }); + + renderChat(); + + expect(screen.getByText('backend unreachable')).toBeInTheDocument(); + }); +}); diff --git a/frontend/tests/setup.ts b/frontend/tests/setup.ts index 8344430b..e4a71208 100644 --- a/frontend/tests/setup.ts +++ b/frontend/tests/setup.ts @@ -15,6 +15,14 @@ if (!document.getElementById('root')) { document.body.appendChild(root); } +// jsdom implements no layout, so it has no scrollIntoView at all. Components that keep a +// view pinned to its newest content (the chat transcript) call it on every update, and +// without this every such render throws. A no-op is the right stub: there is nothing to +// scroll in a headless DOM, and the behaviour under test is what gets rendered. +if (!Element.prototype.scrollIntoView) { + Element.prototype.scrollIntoView = function scrollIntoView() {}; +} + // Unmount React trees between tests so renderHook/render don't leak state. afterEach(() => { cleanup(); diff --git a/shared/src/hooks/chat/useChatMessages.ts b/shared/src/hooks/chat/useChatMessages.ts new file mode 100644 index 00000000..8a28e5d0 --- /dev/null +++ b/shared/src/hooks/chat/useChatMessages.ts @@ -0,0 +1,110 @@ +import { useCallback } from 'react'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { useApiClient } from '../../contexts/ApiClientContext'; +import { useAuth } from '../../contexts/AuthContext'; +import { useChatThreadSocket } from './useChatThreadSocket'; + +export interface ChatMessage { + id: number; + /** Author's wallet address. Compare against your own to decide which side to render. */ + sender: string; + text: string; + createdAt: string; +} + +export interface UseChatMessagesOptions { + threadId: string | null; + /** `/ws/chat` endpoint. Undefined leaves the thread poll-free but not live. */ + socketUrl?: string; +} + +export interface UseChatMessagesResult { + messages: ChatMessage[]; + isLoading: boolean; + error: Error | null; + /** True while the notification channel is connected; false means reads are on demand only. */ + isLive: boolean; + send: (text: string) => Promise; + isSending: boolean; + sendError: Error | null; +} + +export const chatMessagesQueryKey = (baseURL: string, threadId: string | null) => [ + 'chatMessages', + baseURL, + threadId, +]; + +/** + * One thread's messages, kept current by the notification channel. + * + * The socket never delivers content — it says the thread changed, and this re-reads. That + * is why a dropped connection degrades to "not live" rather than "wrong": the read is + * always the source, and a reconnect triggers one because anything sent while the socket + * was down was never announced. + * + * Sending invalidates rather than appending optimistically. A message the server refused + * (the marriage ended between opening the thread and hitting send) must not sit in the + * transcript looking delivered — and unlike a like button, the whole point of a message + * is that the other person actually received it. + */ +export const useChatMessages = ({ + threadId, + socketUrl, +}: UseChatMessagesOptions): UseChatMessagesResult => { + const apiClient = useApiClient(); + const { isAuthenticated } = useAuth(); + const queryClient = useQueryClient(); + const baseURL = apiClient.defaults.baseURL ?? ''; + const queryKey = chatMessagesQueryKey(baseURL, threadId); + + const query = useQuery({ + queryKey, + enabled: isAuthenticated && threadId != null, + queryFn: async () => { + const { data } = await apiClient.get<{ messages: ChatMessage[] }>( + `/api/chat/threads/${threadId}/messages`, + ); + return data.messages ?? []; + }, + }); + + const refresh = useCallback(() => { + void queryClient.invalidateQueries({ queryKey }); + // `queryKey` is rebuilt each render; its contents are what identify the query. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [queryClient, baseURL, threadId]); + + const { connected } = useChatThreadSocket({ + url: socketUrl, + threadId, + onNotification: refresh, + onReconnect: refresh, + }); + + const mutation = useMutation({ + mutationFn: async (text: string) => { + await apiClient.post(`/api/chat/threads/${threadId}/messages`, { text }); + }, + onSuccess: refresh, + }); + + const send = useCallback( + async (text: string) => { + const trimmed = text.trim(); + if (!trimmed || !threadId) return; + await mutation.mutateAsync(trimmed); + }, + [mutation, threadId], + ); + + return { + messages: query.data ?? [], + isLoading: query.isLoading, + error: query.error as Error | null, + isLive: connected, + send, + isSending: mutation.isPending, + sendError: mutation.error as Error | null, + }; +}; diff --git a/shared/src/hooks/chat/useChatThreadSocket.ts b/shared/src/hooks/chat/useChatThreadSocket.ts new file mode 100644 index 00000000..ab4c33e4 --- /dev/null +++ b/shared/src/hooks/chat/useChatThreadSocket.ts @@ -0,0 +1,118 @@ +import { useEffect, useRef, useState } from 'react'; + +/** + * Subscribes to one thread's notification channel (`/ws/chat`). + * + * Notification only, by construction: a frame carries `{ threadId, messageId }` and no + * text, so there is nothing here that could be rendered as a message even by mistake. + * Every frame means one thing — re-read the thread. + * + * Same shape as `useBattleRoomSocket`, including the reconnect callback, which matters + * for the same reason: anything sent while the socket was down was never delivered, so a + * reconnect is as much a reason to re-read as a frame is. Kept separate rather than + * generalized because the two channels differ in what they will need next — this one + * gains authentication when chat widens past married pairs. + */ + +export interface ChatThreadNotification { + type: 'thread-updated'; + threadId: string; + messageId: number; +} + +export interface UseChatThreadSocketOptions { + /** Socket endpoint. Undefined disables the subscription entirely. */ + url: string | undefined; + /** Thread to watch. Null disables the subscription. */ + threadId: string | null; + onNotification?: (message: ChatThreadNotification) => void; + /** Fired after a reconnect, never on the first connect. */ + onReconnect?: () => void; +} + +const INITIAL_RETRY_MS = 1000; +const MAX_RETRY_MS = 30_000; + +export function useChatThreadSocket(options: UseChatThreadSocketOptions): { connected: boolean } { + const { url, threadId } = options; + const [connected, setConnected] = useState(false); + + // Refs so inline callbacks do not rebuild the socket every render: its lifetime should + // depend on the url and thread, and nothing else. + const onNotification = useRef(options.onNotification); + const onReconnect = useRef(options.onReconnect); + onNotification.current = options.onNotification; + onReconnect.current = options.onReconnect; + + useEffect(() => { + setConnected(false); + if (!url || !threadId) return; + + let disposed = false; + let socket: WebSocket | null = null; + let retryTimer: ReturnType | null = null; + let retryDelay = INITIAL_RETRY_MS; + let hasConnectedBefore = false; + + const connect = (): void => { + if (disposed) return; + + socket = new WebSocket(`${url}?threadId=${encodeURIComponent(threadId)}`); + + socket.onopen = () => { + if (disposed) return; + setConnected(true); + retryDelay = INITIAL_RETRY_MS; + if (hasConnectedBefore) { + onReconnect.current?.(); + } + hasConnectedBefore = true; + }; + + socket.onmessage = (event) => { + if (disposed) return; + try { + const message = JSON.parse(event.data as string) as ChatThreadNotification; + if (message?.type === 'thread-updated' && typeof message.threadId === 'string') { + onNotification.current?.(message); + } + } catch { + // A malformed frame is not worth surfacing: the read endpoint is the + // truth, and the next read picks up whatever this would have announced. + } + }; + + socket.onclose = () => { + if (disposed) return; + setConnected(false); + retryTimer = setTimeout(connect, retryDelay); + retryDelay = Math.min(retryDelay * 2, MAX_RETRY_MS); + }; + + socket.onerror = () => { + // `onclose` always follows and owns reconnection; retrying here too would + // open two sockets for one failure. + socket?.close(); + }; + }; + + connect(); + + return () => { + disposed = true; + if (retryTimer) clearTimeout(retryTimer); + // Detached before closing so this teardown cannot schedule a retry for a + // subscription that is going away. + if (socket) { + socket.onopen = null; + socket.onmessage = null; + socket.onclose = null; + socket.onerror = null; + socket.close(); + } + setConnected(false); + }; + }, [url, threadId]); + + return { connected }; +} diff --git a/shared/src/hooks/chat/useChatThreads.ts b/shared/src/hooks/chat/useChatThreads.ts new file mode 100644 index 00000000..eab3cffd --- /dev/null +++ b/shared/src/hooks/chat/useChatThreads.ts @@ -0,0 +1,57 @@ +import { useQuery } from '@tanstack/react-query'; +import { useApiClient } from '../../contexts/ApiClientContext'; +import { useAuth } from '../../contexts/AuthContext'; + +/** The married pet pair a thread exists because of. */ +export interface ChatThreadPets { + petId: string; + petName: string; + spousePetId: string; + spouseName: string; +} + +export interface ChatThread { + threadId: string; + /** The other participant's wallet address. */ + counterpart: string; + /** Every married pet pair between the two owners; at least one, or the thread would not exist. */ + pets: ChatThreadPets[]; + chain: string; +} + +export interface UseChatThreadsResult { + threads: ChatThread[]; + isLoading: boolean; + error: Error | null; +} + +export const chatThreadsQueryKey = (baseURL: string) => ['chatThreads', baseURL]; + +/** + * The threads the player may currently use — one per wallet they are married to. + * + * The list is derived by the backend from live marriage state, so a thread appearing or + * disappearing here is the feature working, not a bug: a divorce closes the conversation. + * The client does not decide who it may talk to and should not try to; every read and + * send is authorized again server-side. + */ +export const useChatThreads = (): UseChatThreadsResult => { + const apiClient = useApiClient(); + const { isAuthenticated } = useAuth(); + const baseURL = apiClient.defaults.baseURL ?? ''; + + const query = useQuery({ + queryKey: chatThreadsQueryKey(baseURL), + enabled: isAuthenticated, + queryFn: async () => { + const { data } = await apiClient.get<{ threads: ChatThread[] }>('/api/chat/threads'); + return data.threads ?? []; + }, + }); + + return { + threads: query.data ?? [], + isLoading: query.isLoading, + error: query.error as Error | null, + }; +}; diff --git a/shared/src/hooks/index.ts b/shared/src/hooks/index.ts index d52fe1ab..54ddd86c 100644 --- a/shared/src/hooks/index.ts +++ b/shared/src/hooks/index.ts @@ -72,6 +72,27 @@ export { type UsePlayerLeaderboardResult, } from './leaderboard/usePlayerLeaderboard'; export { usePlayerRank, type UsePlayerRankResult } from './leaderboard/usePlayerRank'; +// Private chat (roadmap §2 v1). Access is decided server-side from live marriage state; +// these hooks render what they are given and never gate anything themselves. +export { + useChatThreads, + chatThreadsQueryKey, + type ChatThread, + type ChatThreadPets, + type UseChatThreadsResult, +} from './chat/useChatThreads'; +export { + useChatMessages, + chatMessagesQueryKey, + type ChatMessage, + type UseChatMessagesOptions, + type UseChatMessagesResult, +} from './chat/useChatMessages'; +export { + useChatThreadSocket, + type ChatThreadNotification, + type UseChatThreadSocketOptions, +} from './chat/useChatThreadSocket'; export { useBattleDialogue, type UseBattleDialogueOptions, From 390807af28824a0ef0199c8b1207f96a62abe517 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 09:09:54 -0400 Subject: [PATCH 13/61] fix(indexer-go): index Solana at finalized, not confirmed --- docs/plan-future-features-roadmap.md | 25 +++++ services/indexer-go/README.md | 36 +++++- services/indexer-go/cmd/indexer/adapters.go | 1 + services/indexer-go/internal/config/config.go | 21 ++++ .../indexer-go/internal/config/config_test.go | 39 +++++++ .../indexer-go/internal/solana/indexer.go | 18 ++- .../internal/solana/indexer_test.go | 103 ++++++++++++++++++ services/indexer-go/internal/solana/rpc.go | 10 +- .../indexer-go/internal/solana/session.go | 2 +- 9 files changed, 245 insertions(+), 10 deletions(-) diff --git a/docs/plan-future-features-roadmap.md b/docs/plan-future-features-roadmap.md index c77a98e7..1a41afed 100644 --- a/docs/plan-future-features-roadmap.md +++ b/docs/plan-future-features-roadmap.md @@ -367,6 +367,31 @@ bare as possible for a first version. ## 3. "Perfect" indexing with realtime blockchain sync +> **Partly built, and partly obsolete.** Two of this section's four items no longer +> describe the repo, and one has shipped: +> +> - **There is no dual-indexer setup left.** The backend's Node `RosterIndexer` was +> deleted; `indexer-go` is the only thing that writes `pet_roster`. So "shadow mode", +> "the Node indexers stay the source of truth until promotion", and the proposed +> reconciliation job that *diffs Node-indexer state against indexer-go state* have +> nothing left to compare against. What survives of that item is a plain freshness +> check, not a cross-indexer diff. `ROSTER_CACHE_ENABLED`'s "only coherent while +> indexer-go is the sole writer" caveat is likewise satisfied by default now. +> - **Reorg handling shipped for Solana.** Every read and the program subscription ran +> at `confirmed`, which is exactly the phantom-row exposure this section names. +> `SOLANA_COMMITMENT` now defaults to `finalized`, with reads and the subscription +> pinned to the same value; see `services/indexer-go/README.md`. This mattered more +> than "display freshness" suggests, because the roster is what battle snapshots are +> frozen from (threat T10). +> - **EVM confirmation depth is still open**, and is subtler than the Solana case. The +> subgraph is the parsing layer and rolls back reorged blocks itself, but the writer +> here is version-guarded on `updatedAt` (`WHERE last_version <= EXCLUDED.last_version`), +> so a rollback that re-emits a pet at a *lower* version is discarded rather than +> applied — leaving the pre-reorg row in place. Fixing that means either querying the +> subgraph at a confirmation depth or letting a rollback override the guard, and it +> should be designed deliberately rather than bolted on. +> - **The log-subscription path is still open** and unchanged in motivation. + **Goal.** Tighten the existing dual-indexer setup (Node `RosterIndexer` + optional `indexer-go`) so both chains reflect on-chain state with minimal lag and no missed events. diff --git a/services/indexer-go/README.md b/services/indexer-go/README.md index 74a367f8..e6e1b716 100644 --- a/services/indexer-go/README.md +++ b/services/indexer-go/README.md @@ -38,6 +38,7 @@ connection settings is skipped, so adapters roll out independently. | `DATABASE_URL` | Postgres (schema owned by `backend/prisma` — run migrations there first) | | `EVM_SUBGRAPH_URL` | The Graph query endpoint (needs the `Pet` entity deployed) | | `SOLANA_WS_URL` / `SOLANA_RPC_URL` / `SOLANA_PROGRAM_ID` | Helius endpoints + program id | +| `SOLANA_COMMITMENT` | `finalized` (default) or `confirmed`. See below before changing it. | | `GRPC_ADDR` | GameDataService bind address (default `localhost:50051`) | | `EVM_POLL_INTERVAL` / `RECONCILE_INTERVAL` | pull tick / reconciliation scan | @@ -67,16 +68,43 @@ schema bump deploys, those fields decode to their zero values. Deployment: `render.yaml` at the repo root defines `do-not-stop-indexer` as a free-plan Go web service (`/healthz` checked, `/metrics` on the same port). Free web services sleep when idle — the reconnect/backfill machinery recovers -the gap on wake, and the Node indexers stay the source of truth until -promotion. Connection env vars are set in the Render dashboard. +the gap on wake. Connection env vars are set in the Render dashboard. + +Note this service is now the **only** roster indexer: the backend's Node +`RosterIndexer` was deleted, so nothing else writes `pet_roster` and there is no +longer a shadow mode or a second source of truth to fall back on. A stalled +indexer-go means a stale roster, not a slower one. + +## Solana commitment + +`SOLANA_COMMITMENT` sets the commitment for every Solana read *and* the program +subscription, defaulting to `finalized`. + +It used to be `confirmed` everywhere, which is the reorg exposure the roadmap's +indexing-hardening section names. A confirmed slot has a supermajority vote but can +still be dropped, and this roster is what backend battle snapshots are frozen from — +so indexing unfinalized state can freeze a value that never happened into a signed, +permanently replayable receipt (`docs/battle-protocol.md` Appendix A, threat T10). +That is a different class of problem from a stale opponent list. + +The cost is roughly a dozen extra seconds of lag on pet updates. A local validator +finalizes almost immediately, so local development is unaffected. `confirmed` remains +available for an operator who has weighed the trade; anything else is refused at +startup rather than silently defaulted, and `processed` is refused outright because one +node having seen a slot is not an indexable claim about the chain. + +Reads and the subscription always use the same value — a scan at one commitment and a +live stream at another would disagree about what is real, and the roster would flip +between them. ## Read cache (milestone 8) `ROSTER_CACHE_ENABLED=true` serves `GetPetState` / `EstimateWin` from a write-through RAM copy of `pet_roster`: warmed from the table at startup, updated commit-then-cache by the single writer, version-guarded like the SQL. -**Coherent only while indexer-go is the sole writer of the table** — enable at -promotion, never during shadow mode. Reads return `UNAVAILABLE` until warm. +**Coherent only while indexer-go is the sole writer of the table** — which it now +is, the Node indexer having been deleted, so the shadow-mode caveat this +originally carried no longer applies. Reads return `UNAVAILABLE` until warm. Node side: `ROSTER_READ_SOURCE=grpc` routes the matchmaking query through the cache with a 50ms deadline, a 3-failure/30s circuit breaker, and automatic diff --git a/services/indexer-go/cmd/indexer/adapters.go b/services/indexer-go/cmd/indexer/adapters.go index 3deee458..a7c0bb71 100644 --- a/services/indexer-go/cmd/indexer/adapters.go +++ b/services/indexer-go/cmd/indexer/adapters.go @@ -34,6 +34,7 @@ func buildAdapters(cfg *config.Config) ([]indexer.ChainIndexer, error) { RPCURL: cfg.SolanaRPCURL, ProgramID: cfg.SolanaProgramID, ReconcileInterval: cfg.ReconcileInterval, + Commitment: cfg.SolanaCommitment, }) if err != nil { return nil, err diff --git a/services/indexer-go/internal/config/config.go b/services/indexer-go/internal/config/config.go index ad1cf0f3..d57ea8de 100644 --- a/services/indexer-go/internal/config/config.go +++ b/services/indexer-go/internal/config/config.go @@ -18,6 +18,16 @@ type Config struct { SolanaWSURL string SolanaRPCURL string SolanaProgramID string + // Commitment every Solana read and the program subscription run at. + // + // Defaults to "finalized" rather than "confirmed". A confirmed slot can still be + // dropped, and this roster is what battle snapshots are frozen from, so indexing + // unfinalized state can freeze a value that never happened into a signed receipt + // (docs/battle-protocol.md Appendix A, T10). The cost is roughly a dozen seconds of + // extra lag on pet updates, which matters to an opponent list far less than a + // phantom row does. A local validator finalizes almost immediately, so dev is + // unaffected; "confirmed" stays available for an operator who has weighed this. + SolanaCommitment string // EVM adapter (milestone 2). EVMSubgraphURL string @@ -46,8 +56,13 @@ const ( defaultHealthAddr = "localhost:8090" defaultEVMPollInterval = 15 * time.Second defaultReconcileInterval = 10 * time.Minute + defaultSolanaCommitment = "finalized" ) +// Commitments a Solana RPC accepts. "processed" is deliberately absent: it means "one +// node has seen it", which is not an indexable claim about the chain. +var validSolanaCommitments = map[string]bool{"confirmed": true, "finalized": true} + // Load reads the environment. It errors only on malformed values (bad // durations); missing connection settings are reported by the consuming // component at startup instead. @@ -61,10 +76,16 @@ func Load() (*Config, error) { return nil, err } + commitment := stringEnv("SOLANA_COMMITMENT", defaultSolanaCommitment) + if !validSolanaCommitments[commitment] { + return nil, fmt.Errorf(`SOLANA_COMMITMENT: must be "confirmed" or "finalized", got %q`, commitment) + } + return &Config{ SolanaWSURL: os.Getenv("SOLANA_WS_URL"), SolanaRPCURL: os.Getenv("SOLANA_RPC_URL"), SolanaProgramID: os.Getenv("SOLANA_PROGRAM_ID"), + SolanaCommitment: commitment, EVMSubgraphURL: os.Getenv("EVM_SUBGRAPH_URL"), EVMPollInterval: evmPoll, DatabaseURL: os.Getenv("DATABASE_URL"), diff --git a/services/indexer-go/internal/config/config_test.go b/services/indexer-go/internal/config/config_test.go index 84a9a0db..de126ca2 100644 --- a/services/indexer-go/internal/config/config_test.go +++ b/services/indexer-go/internal/config/config_test.go @@ -80,3 +80,42 @@ func TestHealthAddrHonorsExplicitLocalOverride(t *testing.T) { t.Errorf("HealthAddr = %q, want 127.0.0.1:9090", cfg.HealthAddr) } } + +// The default is the safe end of the trade-off, and it is load-bearing: this roster is +// what battle snapshots are frozen from, so indexing a slot that can still be dropped +// can freeze a value that never happened into a signed receipt. +func TestSolanaCommitmentDefaultsToFinalized(t *testing.T) { + cfg, err := Load() + if err != nil { + t.Fatalf("Load(): %v", err) + } + if cfg.SolanaCommitment != "finalized" { + t.Errorf("SolanaCommitment = %q, want %q", cfg.SolanaCommitment, "finalized") + } +} + +func TestSolanaCommitmentAcceptsConfirmed(t *testing.T) { + t.Setenv("SOLANA_COMMITMENT", "confirmed") + + cfg, err := Load() + if err != nil { + t.Fatalf("Load(): %v", err) + } + if cfg.SolanaCommitment != "confirmed" { + t.Errorf("SolanaCommitment = %q, want %q", cfg.SolanaCommitment, "confirmed") + } +} + +// A typo must not silently fall back to a default the operator did not choose, and +// "processed" is refused outright: one node having seen a slot is not an indexable +// claim about the chain. +func TestSolanaCommitmentRejectsUnknownValues(t *testing.T) { + for _, value := range []string{"processed", "final", "FINALIZED", "42"} { + t.Run(value, func(t *testing.T) { + t.Setenv("SOLANA_COMMITMENT", value) + if _, err := Load(); err == nil { + t.Errorf("Load() accepted SOLANA_COMMITMENT=%q, want an error", value) + } + }) + } +} diff --git a/services/indexer-go/internal/solana/indexer.go b/services/indexer-go/internal/solana/indexer.go index 1cfe8b37..94a485dc 100644 --- a/services/indexer-go/internal/solana/indexer.go +++ b/services/indexer-go/internal/solana/indexer.go @@ -24,8 +24,15 @@ type Config struct { RPCURL string ProgramID string ReconcileInterval time.Duration + // Commitment for every read and the subscription. Empty means "finalized" — the + // safe reading, so a caller that forgets to set it does not silently index + // unfinalized state. + Commitment string } +// defaultCommitment is the safe end of the trade-off; see Config.Commitment. +const defaultCommitment = "finalized" + type Indexer struct { cfg Config layout *accountLayout @@ -46,11 +53,18 @@ func New(cfg Config) (*Indexer, error) { if err != nil { return nil, err } + if cfg.Commitment == "" { + cfg.Commitment = defaultCommitment + } return &Indexer{ cfg: cfg, layout: layout, - rpc: &rpcClient{url: cfg.RPCURL, http: &http.Client{Timeout: 30 * time.Second}}, - dial: dialGorilla, + rpc: &rpcClient{ + url: cfg.RPCURL, + http: &http.Client{Timeout: 30 * time.Second}, + commitment: cfg.Commitment, + }, + dial: dialGorilla, }, nil } diff --git a/services/indexer-go/internal/solana/indexer_test.go b/services/indexer-go/internal/solana/indexer_test.go index e050af7b..647985f2 100644 --- a/services/indexer-go/internal/solana/indexer_test.go +++ b/services/indexer-go/internal/solana/indexer_test.go @@ -275,3 +275,106 @@ func TestRunRedialsAfterConnectionLoss(t *testing.T) { } } + +// --- commitment --- + +// capturingRPC records the commitment each call asked for, so the test can assert what +// went on the wire rather than what the config held. +type capturingRPC struct { + mu sync.Mutex + commitments map[string]string // rpc method -> commitment +} + +func (c *capturingRPC) RoundTrip(req *http.Request) (*http.Response, error) { + var rpcReq rpcRequest + if err := json.NewDecoder(req.Body).Decode(&rpcReq); err != nil { + return nil, err + } + + params, _ := rpcReq.Params.([]any) + for _, p := range params { + if opts, ok := p.(map[string]any); ok { + if commitment, ok := opts["commitment"].(string); ok { + c.mu.Lock() + if c.commitments == nil { + c.commitments = map[string]string{} + } + c.commitments[rpcReq.Method] = commitment + c.mu.Unlock() + } + } + } + + rec := httptest.NewRecorder() + _ = json.NewEncoder(rec).Encode(map[string]any{ + "jsonrpc": "2.0", "id": 1, + "result": map[string]any{"context": map[string]any{"slot": 1}, "value": []programAccount{}}, + }) + return rec.Result(), nil +} + +func (c *capturingRPC) commitmentFor(method string) string { + c.mu.Lock() + defer c.mu.Unlock() + return c.commitments[method] +} + +// A Config that names no commitment must not fall through to the RPC default, which is +// "finalized" for some methods and "confirmed" for others. Indexing unfinalized state is +// what freezes a value that never happened into a battle snapshot. +func TestEmptyCommitmentDefaultsToFinalized(t *testing.T) { + ix, err := New(Config{ + WSURL: "ws://test", RPCURL: "http://rpc.test", + ProgramID: "Prog1111111111111111111111111111111111111111", + }) + if err != nil { + t.Fatalf("New: %v", err) + } + if ix.cfg.Commitment != "finalized" { + t.Errorf("Commitment = %q, want %q", ix.cfg.Commitment, "finalized") + } + if ix.rpc.commitment != "finalized" { + t.Errorf("rpc commitment = %q, want %q", ix.rpc.commitment, "finalized") + } +} + +// The reads and the subscription must agree: a scan at one commitment and a live stream +// at another would disagree about what is real, and the roster would flip between them. +func TestScanAndSubscribeUseTheSameConfiguredCommitment(t *testing.T) { + for _, commitment := range []string{"finalized", "confirmed"} { + t.Run(commitment, func(t *testing.T) { + rpc := &capturingRPC{} + ix, err := New(Config{ + WSURL: "ws://test", RPCURL: "http://rpc.test", + ProgramID: "Prog1111111111111111111111111111111111111111", + Commitment: commitment, + }) + if err != nil { + t.Fatalf("New: %v", err) + } + ix.rpc.http = &http.Client{Transport: rpc} + + if _, err := ix.Scan(t.Context(), make(chan indexer.RosterUpdate, 1)); err != nil { + t.Fatalf("Scan: %v", err) + } + if got := rpc.commitmentFor("getProgramAccounts"); got != commitment { + t.Errorf("getProgramAccounts commitment = %q, want %q", got, commitment) + } + + conn := newFakeConn() + if err := ix.subscribe(conn); err != nil { + t.Fatalf("subscribe: %v", err) + } + conn.mu.Lock() + defer conn.mu.Unlock() + if len(conn.writes) == 0 { + t.Fatal("subscribe wrote nothing") + } + params := conn.writes[0]["params"].([]any) + opts := params[1].(map[string]any) + if got := opts["commitment"]; got != commitment { + t.Errorf("programSubscribe commitment = %v, want %q", got, commitment) + } + }) + } +} diff --git a/services/indexer-go/internal/solana/rpc.go b/services/indexer-go/internal/solana/rpc.go index c6e2e560..2a7eee4d 100644 --- a/services/indexer-go/internal/solana/rpc.go +++ b/services/indexer-go/internal/solana/rpc.go @@ -16,6 +16,10 @@ import ( type rpcClient struct { url string http *http.Client + // commitment every call here runs at; see config.Config.SolanaCommitment for why + // it defaults to "finalized". Carried on the client so no call site can quietly + // disagree with the subscription about what counts as real. + commitment string } type rpcRequest struct { @@ -104,7 +108,7 @@ func (c *rpcClient) getProgramPetAccounts( var result programAccountsResult params := []any{programID, map[string]any{ "encoding": "base64", - "commitment": "confirmed", + "commitment": c.commitment, "withContext": true, "filters": []any{ map[string]any{"dataSize": layout.totalLen()}, @@ -131,7 +135,7 @@ func (c *rpcClient) getSignaturesForAddress( address, until string, limit int, ) ([]signatureInfo, error) { - opts := map[string]any{"commitment": "confirmed", "limit": limit} + opts := map[string]any{"commitment": c.commitment, "limit": limit} if until != "" { opts["until"] = until } @@ -153,7 +157,7 @@ func (c *rpcClient) getTransaction(ctx context.Context, signature string) (trans var result transactionResult params := []any{signature, map[string]any{ "encoding": "json", - "commitment": "confirmed", + "commitment": c.commitment, "maxSupportedTransactionVersion": 0, }} err := c.call(ctx, "getTransaction", params, &result) diff --git a/services/indexer-go/internal/solana/session.go b/services/indexer-go/internal/solana/session.go index 978649bc..a3e9ac1c 100644 --- a/services/indexer-go/internal/solana/session.go +++ b/services/indexer-go/internal/solana/session.go @@ -126,7 +126,7 @@ func (ix *Indexer) subscribe(conn wsConn) error { "jsonrpc": "2.0", "id": 1, "method": "programSubscribe", "params": []any{ix.cfg.ProgramID, map[string]any{ "encoding": "base64", - "commitment": "confirmed", + "commitment": ix.cfg.Commitment, "filters": []any{ map[string]any{"dataSize": ix.layout.totalLen()}, map[string]any{"memcmp": map[string]any{"offset": 0, "bytes": ix.layout.discriminatorB58}}, From d9428b340f66185e62a40578b407cedf56f441a7 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 09:16:06 -0400 Subject: [PATCH 14/61] feat(indexer-go): expose indexing freshness separately from liveness --- docs/plan-future-features-roadmap.md | 6 +- services/indexer-go/README.md | 24 +++++++ services/indexer-go/cmd/indexer/app.go | 47 +++++++++++-- services/indexer-go/cmd/indexer/app_test.go | 67 +++++++++++++++++++ services/indexer-go/internal/evm/indexer.go | 7 ++ .../indexer-go/internal/metrics/metrics.go | 16 +++++ .../internal/metrics/metrics_test.go | 16 +++++ .../indexer-go/internal/solana/indexer.go | 4 ++ .../internal/solana/notifications.go | 6 ++ 9 files changed, 185 insertions(+), 8 deletions(-) create mode 100644 services/indexer-go/cmd/indexer/app_test.go diff --git a/docs/plan-future-features-roadmap.md b/docs/plan-future-features-roadmap.md index 1a41afed..d585de01 100644 --- a/docs/plan-future-features-roadmap.md +++ b/docs/plan-future-features-roadmap.md @@ -374,8 +374,10 @@ bare as possible for a first version. > deleted; `indexer-go` is the only thing that writes `pet_roster`. So "shadow mode", > "the Node indexers stay the source of truth until promotion", and the proposed > reconciliation job that *diffs Node-indexer state against indexer-go state* have -> nothing left to compare against. What survives of that item is a plain freshness -> check, not a cross-indexer diff. `ROSTER_CACHE_ENABLED`'s "only coherent while +> nothing left to compare against. What survives of that item shipped as a plain +> freshness signal rather than a cross-indexer diff: `indexer_last_poll_unixtime{chain}` +> is stamped on every error-free round trip, and `/readyz` (separate from `/healthz`, +> which stays pure liveness) refuses until every chain has been reached once. `ROSTER_CACHE_ENABLED`'s "only coherent while > indexer-go is the sole writer" caveat is likewise satisfied by default now. > - **Reorg handling shipped for Solana.** Every read and the program subscription ran > at `confirmed`, which is exactly the phantom-row exposure this section names. diff --git a/services/indexer-go/README.md b/services/indexer-go/README.md index e6e1b716..d47c17bc 100644 --- a/services/indexer-go/README.md +++ b/services/indexer-go/README.md @@ -75,6 +75,30 @@ Note this service is now the **only** roster indexer: the backend's Node longer a shadow mode or a second source of truth to fall back on. A stalled indexer-go means a stale roster, not a slower one. +## Liveness vs freshness + +Three endpoints on the health port, answering different questions: + +| Path | Meaning | +| --- | --- | +| `/healthz` | The process is up. Nothing more — this is what the platform restarts on. | +| `/readyz` | Every configured chain has been reached at least once since start. 503 names the chains still pending. | +| `/metrics` | `indexer_last_poll_unixtime{chain}` carries continuous staleness: alert on `time() - indexer_last_poll_unixtime`. | + +`/healthz` deliberately ignores indexing freshness. Restarting cannot fix an unreachable +subgraph or RPC, so failing liveness on staleness would turn a provider outage into a +restart loop that outlives it. + +The split matters more than it used to. This is the only writer of `pet_roster`, and +under backend-authoritative battles indexer-go is also the independent pre-signing +verifier, so "the process is up" and "its view of the chain is current" stopped being +the same claim. + +`indexer_last_poll_unixtime` is stamped on every error-free round trip — including a +quiet tick that returns no pets, and every live Solana notification. That is the point: +`indexer_last_version` only moves when something on chain changes, so through it a quiet +chain and a stalled adapter look identical. + ## Solana commitment `SOLANA_COMMITMENT` sets the commitment for every Solana read *and* the program diff --git a/services/indexer-go/cmd/indexer/app.go b/services/indexer-go/cmd/indexer/app.go index 6e416f36..787228e1 100644 --- a/services/indexer-go/cmd/indexer/app.go +++ b/services/indexer-go/cmd/indexer/app.go @@ -3,10 +3,12 @@ package main import ( "context" "errors" + "fmt" "log/slog" "net/http" "os" "os/signal" + "strings" "sync" "syscall" "time" @@ -66,7 +68,12 @@ func run() error { }(adapter) } - health := &http.Server{Addr: cfg.HealthAddr, Handler: healthMux()} + chains := make([]string, len(adapters)) + for i, a := range adapters { + chains[i] = a.Chain() + } + + health := &http.Server{Addr: cfg.HealthAddr, Handler: healthMux(chains)} serveErr := make(chan error, 1) go func() { if err := health.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) { @@ -74,10 +81,6 @@ func run() error { } }() - chains := make([]string, len(adapters)) - for i, a := range adapters { - chains[i] = a.Chain() - } slog.Info("indexer-go started", "chains", chains, "health_addr", cfg.HealthAddr, @@ -113,12 +116,44 @@ func run() error { return nil } -func healthMux() *http.ServeMux { +// healthMux serves liveness and readiness as two different questions, because they have +// two different consequences. +// +// `/healthz` stays a bare liveness probe: it is what the platform restarts the process +// on, and restarting cannot fix an unreachable subgraph or RPC. Tying it to indexing +// freshness would turn a provider outage into a restart loop that guarantees the outage +// outlasts it. +// +// `/readyz` is the freshness question, and it is the one that matters to callers rather +// than to the supervisor: this service is the only writer of `pet_roster`, and under +// backend-authoritative battles it is also the independent pre-signing verifier, so +// "the process is up" and "its view of the chain is current" stopped being the same +// claim. Continuous staleness lives in `indexer_last_poll_unixtime`; this endpoint +// answers the coarser question a caller can act on. +func healthMux(chains []string) *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("ok")) }) + mux.HandleFunc("GET /readyz", func(w http.ResponseWriter, _ *http.Request) { + var pending []string + for _, chain := range chains { + if !metrics.HasPolled(chain) { + pending = append(pending, chain) + } + } + if len(pending) > 0 { + // 503 until every configured chain has been reached once. Before that the + // roster is not merely stale, it is absent, and a caller that treats an + // empty answer as "no such pet" would be wrong rather than late. + w.WriteHeader(http.StatusServiceUnavailable) + _, _ = fmt.Fprintf(w, "awaiting first successful poll: %s\n", strings.Join(pending, ", ")) + return + } + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("ready")) + }) mux.HandleFunc("GET /metrics", metrics.Handler()) return mux } diff --git a/services/indexer-go/cmd/indexer/app_test.go b/services/indexer-go/cmd/indexer/app_test.go new file mode 100644 index 00000000..75c4d9ff --- /dev/null +++ b/services/indexer-go/cmd/indexer/app_test.go @@ -0,0 +1,67 @@ +package main + +import ( + "net/http/httptest" + "strings" + "testing" + + "github.com/radcrew/do-not-stop/services/indexer-go/internal/metrics" +) + +// get issues a request against the health mux and returns status + body. +func get(t *testing.T, chains []string, path string) (int, string) { + t.Helper() + rec := httptest.NewRecorder() + healthMux(chains).ServeHTTP(rec, httptest.NewRequest("GET", path, nil)) + return rec.Code, rec.Body.String() +} + +// Liveness must not depend on reaching a chain. It is what the platform restarts on, and +// a restart cannot fix an unreachable subgraph — tying the two together turns a provider +// outage into a restart loop. +func TestHealthzIgnoresIndexingFreshness(t *testing.T) { + code, body := get(t, []string{"chain-that-never-polls"}, "/healthz") + + if code != 200 { + t.Errorf("status = %d, want 200 even with no successful poll", code) + } + if strings.TrimSpace(body) != "ok" { + t.Errorf("body = %q, want %q", body, "ok") + } +} + +func TestReadyzRefusesUntilEveryChainHasBeenReached(t *testing.T) { + // Names are unique per test: the metrics registry is package-level, so a shared name + // would let one test's poll satisfy another's readiness check. + polled, unpolled := "readyz-polled", "readyz-unpolled" + metrics.SetLastPoll(polled, 1700000000) + + code, body := get(t, []string{polled, unpolled}, "/readyz") + + if code != 503 { + t.Errorf("status = %d, want 503 while a chain has never been reached", code) + } + // The body names which chain is missing, because "not ready" alone sends an operator + // looking at both adapters. + if !strings.Contains(body, unpolled) { + t.Errorf("body = %q, want it to name %q", body, unpolled) + } + if strings.Contains(body, polled) { + t.Errorf("body = %q named a chain that had polled", body) + } +} + +func TestReadyzPassesOnceEveryChainHasBeenReached(t *testing.T) { + first, second := "readyz-first", "readyz-second" + metrics.SetLastPoll(first, 1700000000) + metrics.SetLastPoll(second, 1700000001) + + code, body := get(t, []string{first, second}, "/readyz") + + if code != 200 { + t.Errorf("status = %d, want 200 once both chains have polled", code) + } + if strings.TrimSpace(body) != "ready" { + t.Errorf("body = %q, want %q", body, "ready") + } +} diff --git a/services/indexer-go/internal/evm/indexer.go b/services/indexer-go/internal/evm/indexer.go index 206ba10c..dbed5a2b 100644 --- a/services/indexer-go/internal/evm/indexer.go +++ b/services/indexer-go/internal/evm/indexer.go @@ -17,6 +17,7 @@ import ( "time" "github.com/radcrew/do-not-stop/services/indexer-go/internal/indexer" + "github.com/radcrew/do-not-stop/services/indexer-go/internal/metrics" ) const defaultPageSize = 1000 // The Graph caps `first` at 1000 @@ -77,6 +78,9 @@ func (ix *Indexer) Scan(ctx context.Context, roster chan<- indexer.RosterUpdate) if err != nil { return 0, err } + // Stamped on the round trip rather than on the rows: an empty roster is still proof + // the subgraph answered. + metrics.SetLastPoll(ix.chain, time.Now().Unix()) return ix.emit(ctx, roster, pets) } @@ -90,6 +94,9 @@ func (ix *Indexer) sync(ctx context.Context, roster chan<- indexer.RosterUpdate) if err != nil { return 0, err } + // A quiet tick returns no pets and still counts: the point of this signal is that + // the subgraph was reachable, not that anything happened. + metrics.SetLastPoll(ix.chain, time.Now().Unix()) return ix.emit(ctx, roster, pets) } diff --git a/services/indexer-go/internal/metrics/metrics.go b/services/indexer-go/internal/metrics/metrics.go index d4b1f70d..f4fe2e39 100644 --- a/services/indexer-go/internal/metrics/metrics.go +++ b/services/indexer-go/internal/metrics/metrics.go @@ -50,6 +50,13 @@ var ( flushErrors = newSeries() wsReconnects = newSeries() lastVersion = newSeries() // by chain; gauge semantics (set, not add) + // lastPoll is unix seconds of the last round trip to a chain that came back without + // an error, by chain. Distinct from lastVersion on purpose: a version only moves when + // something on chain changed, so a quiet chain and a stalled adapter look identical + // through it. This moves on every healthy tick, which is what makes staleness + // (`time() - indexer_last_poll_unixtime`) mean "we have lost contact" rather than + // "nobody has played today". + lastPoll = newSeries() // by chain cacheSize atomic.Int64 cacheWarm atomic.Int64 @@ -60,6 +67,7 @@ func Flush(rows int) { flushes.get("").Add(1); flushRows. func FlushError() { flushErrors.get("").Add(1) } func WSReconnect() { wsReconnects.get("").Add(1) } func SetLastVersion(chain string, v uint64) { lastVersion.get(chain).Store(int64(v)) } +func SetLastPoll(chain string, unix int64) { lastPoll.get(chain).Store(unix) } func SetCacheSize(n int) { cacheSize.Store(int64(n)) } func SetCacheWarm(warm bool) { cacheWarm.Store(b2i(warm)) } @@ -70,6 +78,11 @@ func b2i(b bool) int64 { return 0 } +// HasPolled reports whether this chain has completed at least one error-free round trip +// since start. Readiness, not health: a process that is up but has never reached a chain +// is not yet serving anything anyone should trust. +func HasPolled(chain string) bool { return lastPoll.get(chain).Load() > 0 } + // Handler serves the Prometheus text exposition format. func Handler() http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { @@ -88,6 +101,9 @@ func Handler() http.HandlerFunc { writeLabelled(w, "indexer_last_version", "gauge", "Last indexed source version per chain (slot / updatedAt)", lastVersion) + writeLabelled(w, "indexer_last_poll_unixtime", "gauge", + "Unix seconds of the last error-free round trip per chain", lastPoll) + writeGauge(w, "indexer_cache_pets", "Pets held in the roster read cache", cacheSize.Load()) writeGauge(w, "indexer_cache_warm", "1 when the read cache serves traffic", cacheWarm.Load()) } diff --git a/services/indexer-go/internal/metrics/metrics_test.go b/services/indexer-go/internal/metrics/metrics_test.go index bcb47011..f78fb9fb 100644 --- a/services/indexer-go/internal/metrics/metrics_test.go +++ b/services/indexer-go/internal/metrics/metrics_test.go @@ -18,6 +18,7 @@ func TestHandlerExposesAllSeries(t *testing.T) { SetLastVersion("solana", 12345) SetCacheSize(7) SetCacheWarm(true) + SetLastPoll("evm", 1700000000) rec := httptest.NewRecorder() Handler()(rec, httptest.NewRequest("GET", "/metrics", nil)) @@ -33,6 +34,7 @@ func TestHandlerExposesAllSeries(t *testing.T) { `indexer_last_version{chain="solana"} 12345`, "indexer_cache_pets 7", "indexer_cache_warm 1", + `indexer_last_poll_unixtime{chain="evm"} 1700000000`, } { if !strings.Contains(body, want) { t.Errorf("missing series %q in:\n%s", want, body) @@ -43,3 +45,17 @@ func TestHandlerExposesAllSeries(t *testing.T) { t.Errorf("Content-Type = %q", ct) } } + +// Readiness turns on this, so "never polled" must be distinguishable from "polled". +// A chain that has never been reached reads 0, which is what /readyz refuses on. +func TestHasPolledOnlyAfterASuccessfulPoll(t *testing.T) { + if HasPolled("chain-never-polled") { + t.Error("HasPolled = true for a chain that was never polled") + } + + SetLastPoll("chain-polled", 1700000001) + + if !HasPolled("chain-polled") { + t.Error("HasPolled = false after a successful poll") + } +} diff --git a/services/indexer-go/internal/solana/indexer.go b/services/indexer-go/internal/solana/indexer.go index 94a485dc..bb4edb5b 100644 --- a/services/indexer-go/internal/solana/indexer.go +++ b/services/indexer-go/internal/solana/indexer.go @@ -17,6 +17,7 @@ import ( "time" "github.com/radcrew/do-not-stop/services/indexer-go/internal/indexer" + "github.com/radcrew/do-not-stop/services/indexer-go/internal/metrics" ) type Config struct { @@ -78,6 +79,9 @@ func (ix *Indexer) Scan(ctx context.Context, roster chan<- indexer.RosterUpdate) if err != nil { return 0, err } + // Stamped on the round trip rather than on the pets: an empty program is still + // proof the RPC answered, and this is a liveness signal, not an activity one. + metrics.SetLastPoll("solana", time.Now().Unix()) emitted := 0 for _, acc := range res.Value { diff --git a/services/indexer-go/internal/solana/notifications.go b/services/indexer-go/internal/solana/notifications.go index 4f9b0542..3b82d67e 100644 --- a/services/indexer-go/internal/solana/notifications.go +++ b/services/indexer-go/internal/solana/notifications.go @@ -4,8 +4,10 @@ import ( "context" "encoding/json" "log/slog" + "time" "github.com/radcrew/do-not-stop/services/indexer-go/internal/indexer" + "github.com/radcrew/do-not-stop/services/indexer-go/internal/metrics" ) type wsNotification struct { @@ -48,6 +50,10 @@ func (ix *Indexer) handleMessage( switch note.Method { case "programNotification": + // A live frame is the freshest possible evidence of contact, so it counts the + // same as a poll. Without this the signal would go stale on a healthy stream + // between reconcile scans and read as an outage. + metrics.SetLastPoll("solana", time.Now().Unix()) ix.handleProgramNotification(ctx, note.Params.Result, roster) } } From 7d8a452188c4adf6c04cd72754435c73009fbee7 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 09:58:00 -0400 Subject: [PATCH 15/61] feat(indexer-go): reconcile the EVM roster on an interval --- docs/plan-future-features-roadmap.md | 96 +++++++++++++++++-- services/indexer-go/README.md | 36 +++++-- services/indexer-go/cmd/indexer/adapters.go | 2 + services/indexer-go/internal/evm/indexer.go | 55 +++++++++-- .../indexer-go/internal/evm/indexer_test.go | 83 ++++++++++++++++ 5 files changed, 247 insertions(+), 25 deletions(-) diff --git a/docs/plan-future-features-roadmap.md b/docs/plan-future-features-roadmap.md index d585de01..e0809945 100644 --- a/docs/plan-future-features-roadmap.md +++ b/docs/plan-future-features-roadmap.md @@ -20,6 +20,26 @@ half-built. Two doc comments in `schema.prisma` reference `PVP_BATTLE.md` and `AI_BATTLE_DIALOGUE.md` as design docs; neither file exists in the repo today, so treat those names as historical pointers, not sources to read. +> **The paragraph above has aged out in five specific ways.** It is kept as written, since +> the sections below were reasoned from it, but check each of these before building on it: +> +> - **`CombatSim.sol` is deleted.** It had no on-chain caller left once battles moved to the +> backend. `contracts/ethereum/src/` now holds `PetCore`, `GameLogic`, `GameConfig`, +> `DnaLib`, `TestDeployer`, plus `BattleBatchRegistry`, `SeasonRewardDistributor`, +> `CryptoPetsToken` and `MockERC20`. +> - **`liveBattleSocket.ts` is gone, and it is no longer "the one channel".** There are two: +> `battleRoomSocket.ts` (§J battle notifications) and `chatSocket.ts` (§2 chat). Neither is +> authenticated — both are notification-only by construction, which is what makes that +> safe. §2's assumption that an authenticated socket already existed to reuse was wrong. +> - **A chat surface now exists** (§2 v1, built). So does a **token**: `CryptoPetsToken.sol` +> is a deployed-ready fixed-supply ERC20 (CPET) that funds `SeasonRewardDistributor` under +> the battle protocol's §I. That materially narrows §11 — see the note there. +> - **The Node `RosterIndexer` is deleted.** `indexer-go` is the only writer of `pet_roster`, +> so the "mirror path in the backend's Node `RosterIndexer`" in the indexer-extension +> pattern below no longer exists and a new asset type needs one adapter, not two. +> - **Two of the eleven features are built** (§1 leaderboard, §2 chat) and a third is partly +> built (§3), on top of §9 which was always out of order. Each carries its own banner. + ## Cross-cutting architecture, established once so each feature section doesn't repeat it **Licensing.** Any new Solidity or Anchor program is MIT (`contracts/ethereum`, @@ -65,6 +85,15 @@ backend's Node `RosterIndexer`. Items, marketplace listings, and token transfers types — each needs a new Prisma table shaped this way and a new case in both indexers, not a bolt-on to `PetRoster`. +> Correction: **there is no second indexer to mirror into.** The Node `RosterIndexer` was +> deleted and `indexer-go` is the sole writer of `pet_roster`, so a new asset type needs one +> adapter, not two. `BattleHistory` is also no longer an indexed type — the backend writes it +> from its own signed receipts — so `PetRoster` is the only live example of this pattern. +> Two things about it are worth copying deliberately rather than by habit: the version guard +> discards a *lower*-versioned write, which is what makes a chain rollback leave a stale row +> in place (see §3), and on Solana the source version is a slot read at the configured +> commitment, which is why that setting is `finalized` rather than `confirmed`. + **`ChainAdapter` stays pet-action-only.** Per `AGENTS.md`, `shared/src/hooks/adapters/types.ts` is a real, narrow interface (`createPet`, `levelUpPet`, `trainPet`, `renamePet`, `transferPet`, `battlePets`, `breedPets`). Marketplace, inventory, and quest actions are new domains — give them @@ -81,8 +110,8 @@ nothing else in this doc needs to exist first. 1. **Leaderboard** — **Built; see §1.** Ranked on the merged battle record, not on `PetRoster.winCount`/`lossCount` as this line originally assumed: those froze when battles left the chain. -2. **Social chat** — reuses the existing WebSocket channel and JWT auth; v1 scope is gated by the - marriage feature that's already shipped. +2. **Social chat** — **Built (v1); see §2.** It did not reuse an authenticated socket, because + there was none to reuse; the channel it added is notification-only for that reason. *Tier 2 — foundation.* Harden what's shipped and build the systems everything else leans on. 3. **Indexing hardening** — everything downstream trusts the indexer more once this lands. @@ -298,6 +327,30 @@ rank. The ranking computation itself is unaffected. ## 2. Social features: player-to-player chat +> **Built (v1).** The married-pet private thread shipped: `chat_thread` / `chat_message`, +> `/api/chat/threads` and its message routes, `/ws/chat`, and a `/messages` screen. See +> `backend/API.md` (Private chat) for the authoritative surface. Three divergences from the +> sketch below, recorded so they are not mistaken for drift: +> +> - **There was no authenticated WebSocket to reuse.** This section's cost argument rested +> on one. `liveBattleSocket.ts` is gone, and its replacement joins whoever presents a room +> id — safe there only because battle notifications carry nothing a client could not +> re-fetch. So `/ws/chat` carries **no message text**: it says a thread changed, and the +> authenticated read returns the content. Chat still cost less than anything else here, +> just not for the stated reason. +> - **Access is checked per request, not stored.** As sketched, `ChatThread` does not record +> the marriage — but the check runs on every read and send, not only at open time, so a +> divorce closes the conversation with nothing to revoke. The thread row survives, since +> deleting it would destroy the history; it just stops answering. +> - **Threads are created on listing, not by an explicit open call.** A married pair always +> ends up with exactly one thread, so a separate open step would add a round trip and a +> null state that only ever resolves one way. +> +> The open decisions below are **unresolved and now carry a shipped surface**: there is no +> block, report, filter, read receipt, presence, edit, delete, or retention policy. The only +> abuse controls are a length cap and a send rate limit. v1's lack of any discovery surface +> is what contains the risk today, and that containment ends with v2's open DMs. + **Goal.** Real player-to-player messaging, not another AI-generated conversation. The natural starting point is the marriage feature: two owners whose pets are married already have an established relationship in the game — a private chat thread between them is the smallest, @@ -385,13 +438,20 @@ bare as possible for a first version. > pinned to the same value; see `services/indexer-go/README.md`. This mattered more > than "display freshness" suggests, because the roster is what battle snapshots are > frozen from (threat T10). -> - **EVM confirmation depth is still open**, and is subtler than the Solana case. The -> subgraph is the parsing layer and rolls back reorged blocks itself, but the writer -> here is version-guarded on `updatedAt` (`WHERE last_version <= EXCLUDED.last_version`), -> so a rollback that re-emits a pet at a *lower* version is discarded rather than -> applied — leaving the pre-reorg row in place. Fixing that means either querying the -> subgraph at a confirmation depth or letting a rollback override the guard, and it -> should be designed deliberately rather than bolted on. +> - **A periodic EVM reconcile scan shipped.** `RECONCILE_INTERVAL` was documented as a +> full-scan safety net but only the Solana adapter used it, so an EVM row the +> incremental path missed stayed wrong indefinitely: that query asks for +> `updatedAt_gt: watermark`, which cannot see anything the watermark has passed. +> - **EVM confirmation depth is still open**, and is subtler than the Solana case, in a +> way worth stating precisely because it defeats the obvious fix. The subgraph rolls +> back reorged blocks itself, but a rollback *lowers* a pet's `updatedAt`, and two +> independent things then block recovery: the incremental query never re-fetches the +> row (it is below the watermark), and the writer discards a lower version anyway +> (`WHERE last_version <= EXCLUDED.last_version`). So the reconcile sweep above fixes +> the first and not the second — it re-reads the row and the correction is rejected. +> Closing it needs either a confirmation depth on the read or a `Version` that never +> moves backwards, which changes what that column means for both chains and should be +> designed rather than bolted on. > - **The log-subscription path is still open** and unchanged in motivation. **Goal.** Tighten the existing dual-indexer setup (Node `RosterIndexer` + optional `indexer-go`) @@ -975,6 +1035,24 @@ decision. ## 11. ERC20 tokenomics +> **An EVM token already exists, and its design constrains this section.** +> `contracts/ethereum/src/CryptoPetsToken.sol` is CPET: a standard OpenZeppelin ERC20 with +> **fixed supply, no mint function, and no owner**, minted once at deployment to fund +> `SeasonRewardDistributor` under the battle protocol's §I. That is this section's +> "independently minted token per chain" recommendation, already taken for EVM. +> +> What it rules out is the part worth noticing before designing anything here: **there is no +> emission schedule to design.** A token that cannot be minted cannot emit. Rewards come out +> of a supply that already exists, so "running out means running out" — which is deliberate, +> because §I's safety argument is that a bad Merkle root is bounded by real supply rather +> than by whoever holds a minting key. Any tokenomics plan that assumes new issuance is +> either proposing a second token or proposing to give that argument up, and should say +> which. +> +> Still genuinely open, and still a human call: sinks, fee denomination, whether Solana gets +> its own SPL mint, and how much of the fixed supply is committed to seasons versus held +> back. The note below about not planning a sink around the retired battle fee still stands. + **Goal.** A utility/governance token usable for battle fees, training fees, marketplace fees, quest rewards, and breeding stud fees. diff --git a/services/indexer-go/README.md b/services/indexer-go/README.md index d47c17bc..0ecb5d49 100644 --- a/services/indexer-go/README.md +++ b/services/indexer-go/README.md @@ -40,15 +40,16 @@ connection settings is skipped, so adapters roll out independently. | `SOLANA_WS_URL` / `SOLANA_RPC_URL` / `SOLANA_PROGRAM_ID` | Helius endpoints + program id | | `SOLANA_COMMITMENT` | `finalized` (default) or `confirmed`. See below before changing it. | | `GRPC_ADDR` | GameDataService bind address (default `localhost:50051`) | -| `EVM_POLL_INTERVAL` / `RECONCILE_INTERVAL` | pull tick / reconciliation scan | +| `EVM_POLL_INTERVAL` / `RECONCILE_INTERVAL` | pull tick / reconciliation scan (both adapters; see below) | Prereq migrations (from `backend/`): `npx prisma migrate dev`. Beyond `pet_roster.last_version` / `battle_history.version`, the v2 schema adds the roster fields (`xp`, `generation`, `parent1_id`/`parent2_id`, `breed_count`, `species_id`, `spouse_id`, `breed_ready_at`, `train_ready_at`, `asset`) and the combat-sim battle fields (`loser_pet_id`, `seed`, `rounds`, -`winner_hp_remaining`, `xp_win`, `xp_loss`). All are defaulted, so the v1 Node -indexer keeps writing during shadow mode. **The writer is DML-only — run the +`winner_hp_remaining`, `xp_win`, `xp_loss`). All are defaulted, which is what let +the (since-deleted) v1 Node indexer keep writing alongside this one during the +migration. **The writer is DML-only — run the migration before pointing indexer-go at the database.** The EVM adapter also expects the subgraph to expose the matching v2 Pet/Battle fields; until that schema bump deploys, those fields decode to their zero values. @@ -59,11 +60,15 @@ schema bump deploys, those fields decode to their zero values. write, exit. The Go counterpart of the backend's `index:once`. - `GET /healthz` on `HEALTH_ADDR` (default `localhost:8090`; when `PORT` is set — Render's convention — it binds `0.0.0.0:$PORT` instead). -- `GET /metrics` (same port) — Prometheus text format: roster updates and - battles per chain, flush count/rows/errors, WS reconnects, per-chain last - version (lag), cache size/warm, stream subscriber count. The runbook - signals: rising `indexer_flush_errors_total`, a flat `indexer_last_version` - under traffic, or runaway `indexer_ws_reconnects_total`. +- `GET /readyz` (same port) — 503 until every configured chain has been reached + once. Deliberately not `/healthz`; see "Liveness vs freshness" below. +- `GET /metrics` (same port) — Prometheus text format: roster updates per chain, + flush count/rows/errors, WS reconnects, per-chain last version and last poll + time, cache size/warm. (No battle or stream series any more — that pipeline + went with §L Phase 6.) The runbook signals: rising + `indexer_flush_errors_total`, a growing `time() - indexer_last_poll_unixtime`, + or runaway `indexer_ws_reconnects_total`. A flat `indexer_last_version` is + *not* a signal on its own — it also means nobody has played. Deployment: `render.yaml` at the repo root defines `do-not-stop-indexer` as a free-plan Go web service (`/healthz` checked, `/metrics` on the same port). @@ -75,6 +80,21 @@ Note this service is now the **only** roster indexer: the backend's Node longer a shadow mode or a second source of truth to fall back on. A stalled indexer-go means a stale roster, not a slower one. +## Reconciliation + +`RECONCILE_INTERVAL` (default 10m) is a periodic full re-read of the roster, on top of +the incremental path. Both adapters use it now; until recently only Solana did, which +mattered because the EVM incremental query asks for `updatedAt_gt: watermark` — anything +the watermark has already passed is invisible to it by construction, so a row that +drifted stayed wrong until the pet changed again. + +It is not a reorg fix, and should not be read as one. A subgraph reorg can *lower* a +pet's `updatedAt`, and the writer discards a lower version +(`WHERE last_version <= EXCLUDED.last_version`), so a sweep re-reads the row and the +correction is then rejected. Closing that needs either a confirmation depth on the read +or a version that never moves backwards — a change to what `Version` means, and an open +item in the roadmap's §3. + ## Liveness vs freshness Three endpoints on the health port, answering different questions: diff --git a/services/indexer-go/cmd/indexer/adapters.go b/services/indexer-go/cmd/indexer/adapters.go index a7c0bb71..dfee2666 100644 --- a/services/indexer-go/cmd/indexer/adapters.go +++ b/services/indexer-go/cmd/indexer/adapters.go @@ -19,6 +19,8 @@ func buildAdapters(cfg *config.Config) ([]indexer.ChainIndexer, error) { evmIx, err := evm.New(evm.Config{ URL: cfg.EVMSubgraphURL, PollInterval: cfg.EVMPollInterval, + // Same safety net Solana has had all along; see evm.Indexer.Run. + ReconcileInterval: cfg.ReconcileInterval, }) if err != nil { return nil, err diff --git a/services/indexer-go/internal/evm/indexer.go b/services/indexer-go/internal/evm/indexer.go index dbed5a2b..20fa0e86 100644 --- a/services/indexer-go/internal/evm/indexer.go +++ b/services/indexer-go/internal/evm/indexer.go @@ -27,12 +27,17 @@ type Config struct { URL string // subgraph HTTP query endpoint PollInterval time.Duration PageSize int // tests use small pages to exercise pagination + // ReconcileInterval is how often to re-read the whole roster instead of only what + // changed. Zero disables it, which is what the tests that assert on incremental + // behaviour want. See Run for what it is and is not a safety net against. + ReconcileInterval time.Duration } type Indexer struct { - chain string - poll time.Duration - client *client + chain string + poll time.Duration + reconcile time.Duration + client *client // watermark is the highest updatedAt seen. Owned by Scan/Run, which are // never called concurrently (Run performs its own scans). If the initial // scan failed it stays 0, so the first successful sync recovers by @@ -58,8 +63,9 @@ func New(cfg Config) (*Indexer, error) { chain = "evm" } return &Indexer{ - chain: chain, - poll: cfg.PollInterval, + chain: chain, + poll: cfg.PollInterval, + reconcile: cfg.ReconcileInterval, client: &client{ url: cfg.URL, pageSize: pageSize, @@ -100,8 +106,22 @@ func (ix *Indexer) sync(ctx context.Context, roster chan<- indexer.RosterUpdate) return ix.emit(ctx, roster, pets) } -// Run scans once to prime the watermark, then polls incrementally. Transient -// subgraph errors are logged and retried on the next tick. +// Run scans once to prime the watermark, then polls incrementally, with a periodic full +// re-read as a safety net. Transient subgraph errors are logged and retried next tick. +// +// The reconcile sweep matches what the Solana adapter has always done, and closes a real +// asymmetry: `RECONCILE_INTERVAL` is documented as a full-scan safety net, but until now +// only one of the two adapters used it, so an EVM row that the incremental path missed +// stayed wrong until the pet changed again. The incremental query asks for +// `updatedAt_gt: watermark`, so anything the watermark has already passed is invisible +// to it, forever, by construction. +// +// Be precise about what this does *not* fix: a subgraph reorg can lower a pet's +// `updatedAt`, and the store's write guard discards a lower version +// (`WHERE last_version <= EXCLUDED.last_version`). A full sweep re-reads such a row but +// the corrected value is then rejected, so the stale row survives. Fixing that needs +// either a confirmation depth on the read or a version that does not move backwards — +// a change to what `Version` means, deliberately not made here. See the roadmap's §3. // // Battles are no longer ingested (§L Phase 6): GameLogic has no requestBattle / // settleBattle and the subgraph no longer emits a Battle entity, so there is nothing on @@ -120,6 +140,15 @@ func (ix *Indexer) Run(ctx context.Context, roster chan<- indexer.RosterUpdate) ticker := time.NewTicker(ix.poll) defer ticker.Stop() + // A disabled reconcile still needs a channel to select on; a nil one blocks forever, + // which is exactly the "never fires" behaviour wanted. + var reconcileC <-chan time.Time + if ix.reconcile > 0 { + reconcileTicker := time.NewTicker(ix.reconcile) + defer reconcileTicker.Stop() + reconcileC = reconcileTicker.C + } + for { select { case <-ctx.Done(): @@ -134,7 +163,17 @@ func (ix *Indexer) Run(ctx context.Context, roster chan<- indexer.RosterUpdate) case synced > 0: slog.Info("evm sync", "synced", synced, "watermark", ix.watermark) } - } + case <-reconcileC: + scanned, err := ix.Scan(ctx, roster) + switch { + case err != nil && ctx.Err() != nil: + return nil + case err != nil: + slog.Error("evm reconcile scan failed", "err", err) + default: + slog.Info("evm reconcile scan", "scanned", scanned, "watermark", ix.watermark) + } + } } } diff --git a/services/indexer-go/internal/evm/indexer_test.go b/services/indexer-go/internal/evm/indexer_test.go index b3800b2e..f0880375 100644 --- a/services/indexer-go/internal/evm/indexer_test.go +++ b/services/indexer-go/internal/evm/indexer_test.go @@ -1,8 +1,10 @@ package evm import ( + "bytes" "context" "encoding/json" + "io" "net/http" "net/http/httptest" "sort" @@ -285,3 +287,84 @@ func TestNewRequiresURL(t *testing.T) { } } + +// The incremental query asks for updatedAt_gt: watermark, so a row the watermark has +// already passed can never be re-read by it. Without a periodic full sweep an EVM row +// that drifted stayed wrong until the pet changed again — the safety net RECONCILE_INTERVAL +// advertises, which only the Solana adapter actually had. +func TestRunReconcilesWithAFullSweep(t *testing.T) { + fake := &fakeSubgraph{pets: []subgraphPet{pet("1", "0xA", 5, "100")}} + + fullSweeps := &atomic.Int32{} + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + if !strings.Contains(string(body), "updatedAt_gt") { + fullSweeps.Add(1) + } + r.Body = io.NopCloser(bytes.NewReader(body)) + fake.handler(t)(w, r) + }) + + ix, err := New(Config{ + URL: "http://subgraph.test/query", PageSize: 100, + PollInterval: time.Hour, // incremental ticks must not fire; only the sweep may + ReconcileInterval: 10 * time.Millisecond, + }) + if err != nil { + t.Fatalf("New: %v", err) + } + ix.client.http = &http.Client{Transport: handlerTransport{handler}} + + ch := make(chan indexer.RosterUpdate, 32) + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan error, 1) + go func() { done <- ix.Run(ctx, ch) }() + + deadline := time.After(2 * time.Second) + for fullSweeps.Load() < 2 { // one at startup, then at least one from the ticker + select { + case <-deadline: + cancel() + t.Fatalf("only %d full sweeps; reconcile never fired", fullSweeps.Load()) + case <-time.After(2 * time.Millisecond): + } + } + + cancel() + if err := <-done; err != nil { + t.Errorf("Run returned %v on clean shutdown, want nil", err) + } +} + +// Zero means off, and off must not mean "every zero seconds": a nil ticker channel here +// would spin, and a zero-duration one panics. +func TestRunWithoutReconcileIntervalOnlySyncsIncrementally(t *testing.T) { + fake := &fakeSubgraph{pets: []subgraphPet{pet("1", "0xA", 5, "100")}} + + fullSweeps := &atomic.Int32{} + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + if !strings.Contains(string(body), "updatedAt_gt") { + fullSweeps.Add(1) + } + r.Body = io.NopCloser(bytes.NewReader(body)) + fake.handler(t)(w, r) + }) + + ix := newTestIndexer(t, handler, 100) // no ReconcileInterval + ch := make(chan indexer.RosterUpdate, 32) + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan error, 1) + go func() { done <- ix.Run(ctx, ch) }() + + time.Sleep(60 * time.Millisecond) // several 10ms poll ticks + cancel() + if err := <-done; err != nil { + t.Errorf("Run returned %v on clean shutdown, want nil", err) + } + + // Exactly the startup scan, no more. + if got := fullSweeps.Load(); got != 1 { + t.Errorf("full sweeps = %d, want 1 (startup only) when reconcile is disabled", got) + } +} From 7cbceae9ad639385447e1078d6a749965c35cb5c Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 10:36:20 -0400 Subject: [PATCH 16/61] fix(backend): enable RLS on the chat tables in their migration --- CLAUDE.md | 13 +++ .../migration.sql | 15 +++ docs/plan-future-features-roadmap.md | 7 +- services/indexer-go/README.md | 5 +- .../indexer-go/plan-evm-reorg-recovery.md | 108 ++++++++++++++++++ 5 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 services/indexer-go/plan-evm-reorg-recovery.md diff --git a/CLAUDE.md b/CLAUDE.md index 739ddacb..08c260d6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -221,6 +221,19 @@ Backend auth is nonce, then wallet-signature, then JWT (`backend/README.md`), gu ### Testing conventions See `docs/testing.md` for the full per-package suite table. Test work is expected to land on dedicated branches per test type/area (e.g. `test/frontend-modules`), not mixed into feature branches, with coverage reported after each change. +### Every new Prisma migration must enable RLS on the tables it creates +The database is Supabase, and `ALTER DEFAULT PRIVILEGES` in `public` grants **every newly created table** to `anon` and `authenticated` with ALL privileges — SELECT, INSERT, UPDATE, DELETE, TRUNCATE. Prisma emits no RLS statements, so a migration that only does `CREATE TABLE` ships a table that anyone holding the project's public anon key can read *and* delete through PostgREST. + +All existing tables have RLS enabled with **zero policies**, which is the correct posture here rather than an unfinished one: with no policy, RLS denies the PostgREST roles everything, while the backend connects as the table owner (`postgres`) and owners bypass RLS unless `FORCE ROW LEVEL SECURITY` is set. So the backend is unaffected and the public roles get nothing. Verified by experiment: as `anon`, a `SELECT` against an RLS-enabled table returns zero rows, while the same query against an identical table without RLS returns the data and a follow-up `DELETE` removes it. + +So every migration that creates a table **MUST** end with: + +```sql +ALTER TABLE "new_table" ENABLE ROW LEVEL SECURITY; +``` + +Do **not** add `FORCE ROW LEVEL SECURITY`: it applies policy-less RLS to the owner too, which denies the backend its own tables. Note the existing tables got RLS out of band (dashboard or manual SQL) rather than from their migrations, so each of them was exposed between deploy and the fix — putting the statement in the migration is what closes that window. + ## Licensing This monorepo has split licensing; see the table in `README.md`. `contracts/ethereum`, `contracts/solana`, `indexer-go`, `proto`, `protocol`, and `verifier` are MIT; everything else (`frontend`, `backend`, `mobile`, `website`, `shared`, `image-generator`) is PolyForm Noncommercial 1.0.0 (root `LICENSE`). Match the license of whichever package you're editing when adding new files. diff --git a/backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql b/backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql index ce0eb2dd..70c53c08 100644 --- a/backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql +++ b/backend/prisma/migrations/20260806100000_add_chat_threads/migration.sql @@ -34,3 +34,18 @@ CREATE INDEX "chat_message_thread_id_created_at_idx" ON "chat_message"("thread_i -- AddForeignKey ALTER TABLE "chat_message" ADD CONSTRAINT "chat_message_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "chat_thread"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- EnableRowLevelSecurity +-- +-- Prisma emits no RLS statements, and on Supabase `ALTER DEFAULT PRIVILEGES` grants every +-- newly created table in `public` to `anon` and `authenticated` with ALL privileges — +-- including DELETE and TRUNCATE. So a table shipped without this line is readable and +-- writable by anyone holding the project's public anon key. For private messages that is +-- not a hardening gap, it is the whole confidentiality of the feature. +-- +-- Enabled with no policies, matching every other table in this database: that denies all +-- access to the PostgREST roles, while the backend connects as the table owner +-- (`postgres`) and owners bypass RLS unless FORCE is set. Do NOT add FORCE here — it +-- would apply these policy-less tables to the owner too and deny the backend everything. +ALTER TABLE "chat_thread" ENABLE ROW LEVEL SECURITY; +ALTER TABLE "chat_message" ENABLE ROW LEVEL SECURITY; diff --git a/docs/plan-future-features-roadmap.md b/docs/plan-future-features-roadmap.md index e0809945..c66ab8f3 100644 --- a/docs/plan-future-features-roadmap.md +++ b/docs/plan-future-features-roadmap.md @@ -450,8 +450,11 @@ bare as possible for a first version. > (`WHERE last_version <= EXCLUDED.last_version`). So the reconcile sweep above fixes > the first and not the second — it re-reads the row and the correction is rejected. > Closing it needs either a confirmation depth on the read or a `Version` that never -> moves backwards, which changes what that column means for both chains and should be -> designed rather than bolted on. +> moves backwards. Written up with a recommendation in +> `services/indexer-go/plan-evm-reorg-recovery.md`, which also records the trap in the +> obvious fix: EVM versions are block *timestamps* (~1.79e9 in the live table) while +> block numbers are ~3e7, so switching to a block number rejects every subsequent write +> while the service still looks healthy. > - **The log-subscription path is still open** and unchanged in motivation. **Goal.** Tighten the existing dual-indexer setup (Node `RosterIndexer` + optional `indexer-go`) diff --git a/services/indexer-go/README.md b/services/indexer-go/README.md index 0ecb5d49..05acfb04 100644 --- a/services/indexer-go/README.md +++ b/services/indexer-go/README.md @@ -92,8 +92,9 @@ It is not a reorg fix, and should not be read as one. A subgraph reorg can *lowe pet's `updatedAt`, and the writer discards a lower version (`WHERE last_version <= EXCLUDED.last_version`), so a sweep re-reads the row and the correction is then rejected. Closing that needs either a confirmation depth on the read -or a version that never moves backwards — a change to what `Version` means, and an open -item in the roadmap's §3. +or a version that never moves backwards; both options, the recommendation, and the +migration trap in the obvious one are written up in +[`plan-evm-reorg-recovery.md`](./plan-evm-reorg-recovery.md). ## Liveness vs freshness diff --git a/services/indexer-go/plan-evm-reorg-recovery.md b/services/indexer-go/plan-evm-reorg-recovery.md new file mode 100644 index 00000000..6a03f994 --- /dev/null +++ b/services/indexer-go/plan-evm-reorg-recovery.md @@ -0,0 +1,108 @@ +# EVM reorg recovery: the open item, and the trap in the obvious fix + +Design note for the last open piece of the roadmap's §3. Not implemented; written so the +decision can be made from facts rather than from a sketch. The Solana half of this +shipped (`SOLANA_COMMITMENT=finalized`), and the periodic EVM reconcile scan shipped, but +neither closes what follows. + +## The failure + +The Graph is the parsing layer and rolls back reorged blocks itself. When it does, a +pet's `updatedAt` **decreases**: it is `event.block.timestamp` (see +`contracts/ethereum/subgraph/src/mapping.ts`), so a rolled-back update leaves the entity +stamped with an earlier block's time. + +Two independent things then stop us from ever correcting the row: + +1. **The incremental query cannot see it.** `sync` asks for `updatedAt_gt: watermark`. + The watermark is already above the corrected value, so the row is never returned + again — not on the next tick, not ever, until some later on-chain change pushes it + back above the watermark. +2. **The writer would reject it anyway.** The upsert guard is + `WHERE last_version <= EXCLUDED.last_version`, and the corrected version is lower. + +The periodic reconcile scan fixes (1) and not (2): the sweep re-reads the row, hands it +to the writer, and the writer discards it. So the stale value survives, and the only +thing that clears it is an unrelated future update to the same pet. + +Impact is not cosmetic. `pet_roster` is what backend battle snapshots are frozen from, so +a stale row can be frozen into a signed receipt that replays forever +(`docs/battle-protocol.md` Appendix A, threat T10) — the same argument that moved Solana +to `finalized`. + +## The trap: do not switch `Version` to a block number + +The tempting fix for (2) is a version that never moves backwards, and the obvious +candidate is the subgraph head block number. **This would silently break all EVM +indexing.** + +Measured against the live database: + +| chain | `pet_roster.last_version` | what it is | +| --- | --- | --- | +| `evm` | ~1.786 × 10⁹ | Unix seconds (`block.timestamp`) | +| `solana` | ~4.76 × 10⁸ | slot number | + +Base Sepolia block numbers are around 3 × 10⁷ — roughly sixty times smaller than the +timestamps already stored. Every subsequent write would carry a version far below +`last_version`, the guard would reject all of them, and **the service would look +perfectly healthy while writing nothing**: polls succeed, `indexer_last_poll_unixtime` +advances, `/readyz` passes, `indexer_flush_errors_total` stays flat, because a +guard-rejected upsert is not an error. + +Any change to what `Version` means for EVM therefore requires a coordinated reset of +`pet_roster.last_version` for EVM rows, on a live deployment, in the same change. That is +the part that makes this a decision rather than a patch. + +## Option A (recommended): refuse to ingest entities that are too new + +Add a lower bound in time to the existing queries: ignore any pet whose `updatedAt` is +within the last N seconds. + +```graphql +pets(where: { updatedAt_gt: $since, updatedAt_lte: $safeUntil }, ...) +``` + +with `safeUntil = now - reorgDepth`. + +Why this one: + +- **It prevents the bad write instead of recovering from it**, which is what we chose for + Solana. A row that never enters the table cannot be frozen into a snapshot. +- **`Version` keeps its meaning**, so there is no migration and no trap above. +- It is a filter on the query already being issued — no `_meta` lookup, no Graph + time-travel queries (`block: { number: X }`), and so no dependence on the subgraph + retaining history, which a pruned deployment does not. +- `updatedAt` is already a timestamp, so "confirmation depth" expresses naturally in + seconds. Block-depth would have to be converted anyway. + +Costs, stated plainly: + +- Every EVM pet update is delayed by `reorgDepth`. This is the same trade accepted on + Solana, and matters less to an opponent list than a phantom row does — but it is a real + latency regression for anything reading the roster right after a transaction. +- Clock dependence: `now` is the indexer's clock against the chain's block timestamps. + Skew eats into the margin, so the depth should comfortably exceed plausible skew. +- It does not repair rows already stale from a past reorg. Those need one full sweep with + the guard bypassed, or a targeted reset — a one-off, not part of the steady state. + +Suggested shape: `EVM_REORG_DEPTH`, default something like 120s for Base, validated at +startup like `SOLANA_COMMITMENT`, and applied to both `sync` and `Scan` so a reconcile +sweep cannot reintroduce what the incremental path refused. + +## Option B: make `Version` monotonic + +Use the subgraph head block number (via `_meta { block { number } }`) as the version for +every row in a fetch, so a later fetch always outranks an earlier one and corrections +apply. + +This does close the loop when paired with the reconcile scan — but it carries the +migration hazard above, weakens the guard's protection against genuinely stale writes +(all rows in a batch share a version), and leaves the window open in which a bad value is +written and then corrected, which is precisely the window a snapshot can be taken in. + +## Recommendation + +Option A, with the depth configurable and defaulted conservatively; leave `Version` alone. +Treat the historical-stale-row cleanup as a separate one-off. Do not adopt Option B +without a `last_version` reset in the same deployment. From bdf220943f4e0198d0e6fe1b00437c1bda5a9c3f Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 11:28:55 -0400 Subject: [PATCH 17/61] refactor: apply code-quality review to leaderboard and chat --- .../migration.sql | 7 + backend/prisma/schema.prisma | 6 +- backend/src/features/chat/chat.controller.ts | 12 +- backend/src/features/chat/chat.service.ts | 46 ++- backend/src/repositories/chat.repository.ts | 145 ++++---- .../repositories/leaderboard.repository.ts | 337 +++++------------- backend/src/repositories/owner.sql.ts | 25 ++ backend/src/repositories/roster.repository.ts | 13 +- backend/src/types/chain.ts | 13 + .../tests/features/chat.controller.test.ts | 10 +- backend/tests/features/chat.service.test.ts | 31 +- .../leaderboard.repository.test.ts | 115 +++--- frontend/src/components/chat/index.tsx | 8 +- frontend/src/components/leaderboard/index.tsx | 112 +++--- .../panels/battle/battle-utils.ts | 3 - .../panels/battle/parts/battle-setup.tsx | 3 +- frontend/src/utils/address.ts | 21 ++ frontend/tests/components/chat.test.tsx | 3 + .../tests/components/leaderboard.test.tsx | 3 + .../panels/battle/battle-utils.test.ts | 11 - frontend/tests/utils/address.test.ts | 46 +++ frontend/tsconfig.app.json | 3 +- frontend/vite.config.ts | 1 + services/indexer-go/internal/evm/indexer.go | 31 +- shared/src/hooks/chat/useChatMessages.ts | 45 ++- shared/src/utils/pets/index.ts | 10 + 26 files changed, 523 insertions(+), 537 deletions(-) create mode 100644 backend/prisma/migrations/20260806120000_chat_message_index_by_id/migration.sql create mode 100644 backend/src/repositories/owner.sql.ts create mode 100644 frontend/src/utils/address.ts create mode 100644 frontend/tests/utils/address.test.ts diff --git a/backend/prisma/migrations/20260806120000_chat_message_index_by_id/migration.sql b/backend/prisma/migrations/20260806120000_chat_message_index_by_id/migration.sql new file mode 100644 index 00000000..fbc9dab1 --- /dev/null +++ b/backend/prisma/migrations/20260806120000_chat_message_index_by_id/migration.sql @@ -0,0 +1,7 @@ +-- The message page reads `WHERE thread_id = ? [AND id < ?] ORDER BY id DESC LIMIT n`. +-- The (thread_id, created_at) index could locate a thread's rows but not satisfy that +-- ordering, so every read sorted the whole thread to return one page. `id` is a SERIAL +-- and is already the ordering key the code uses, so this is a swap, not an addition. +DROP INDEX IF EXISTS "chat_message_thread_id_created_at_idx"; + +CREATE INDEX "chat_message_thread_id_id_idx" ON "chat_message"("thread_id", "id"); diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 4be88761..546d0741 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -188,7 +188,11 @@ model ChatMessage { createdAt DateTime @default(now()) @map("created_at") - @@index([threadId, createdAt]) + /// Indexed on `id`, not `createdAt`, because that is what the read orders by: a page is + /// `WHERE thread_id = ? [AND id < ?] ORDER BY id DESC LIMIT n`. Indexing `created_at` + /// instead let Postgres find the thread's rows but not satisfy the ordering, so it + /// sorted every message in the thread to return fifty of them, on every read. + @@index([threadId, id]) @@map("chat_message") } diff --git a/backend/src/features/chat/chat.controller.ts b/backend/src/features/chat/chat.controller.ts index 20f73235..d678e568 100644 --- a/backend/src/features/chat/chat.controller.ts +++ b/backend/src/features/chat/chat.controller.ts @@ -41,9 +41,9 @@ export async function getMessages(req: Request, res: Response): Promise { } const threadId = req.params.id ?? ''; - const auth = await authorizeThread(threadId, caller); - if (auth.denial) { - respondToDenial(res, auth.denial); + const denial = await authorizeThread(threadId, caller); + if (denial) { + respondToDenial(res, denial); return; } @@ -71,9 +71,9 @@ export async function postMessage(req: Request, res: Response): Promise { } const threadId = req.params.id ?? ''; - const auth = await authorizeThread(threadId, caller); - if (auth.denial) { - respondToDenial(res, auth.denial); + const denial = await authorizeThread(threadId, caller); + if (denial) { + respondToDenial(res, denial); return; } diff --git a/backend/src/features/chat/chat.service.ts b/backend/src/features/chat/chat.service.ts index 6412393e..de2b1c7f 100644 --- a/backend/src/features/chat/chat.service.ts +++ b/backend/src/features/chat/chat.service.ts @@ -5,6 +5,7 @@ import { findMessages, findThreadById, insertMessage, + isMarriedTo, openThread, type ChatMessageRow, } from '@repositories/chat.repository'; @@ -52,13 +53,20 @@ export interface ChatThreadView { * A pair with two married pet couples collapses to one thread carrying both pairs, * because the conversation is between the owners, not the pets. */ -export async function listThreads(caller: string): Promise { +export async function listThreads(rawCaller: string): Promise { + // Normalized once, here, because the caller is also the thread's participant key: an + // unnormalized spelling of the same wallet would open a second thread beside the + // first and split the conversation. Production callers arrive normalized from the + // JWT; this makes that an invariant of the feature rather than of its callers. + const caller = normalizeAccount(rawCaller); const marriages = await findMarriedCounterparts(caller); if (marriages.length === 0) { return []; } - const byCounterpart = new Map(); + // Group first, then open every thread at once. Opening inside the loop made this one + // sequential round trip per counterpart on a screen that loads them all together. + const byCounterpart = new Map>(); for (const marriage of marriages) { const counterpart = normalizeAccount(marriage.counterpart); const pets = { @@ -71,19 +79,16 @@ export async function listThreads(caller: string): Promise { const seen = byCounterpart.get(counterpart); if (seen) { seen.pets.push(pets); - continue; + } else { + byCounterpart.set(counterpart, { counterpart, pets: [pets], chain: marriage.chain }); } - - const thread = await openThread(caller, counterpart, MARRIAGE_SCOPE); - byCounterpart.set(counterpart, { - threadId: thread.id, - counterpart, - pets: [pets], - chain: marriage.chain, - }); } - return [...byCounterpart.values()]; + const views = [...byCounterpart.values()]; + const threadIds = await Promise.all( + views.map((view) => openThread(caller, view.counterpart, MARRIAGE_SCOPE)) + ); + return views.map((view, index) => ({ ...view, threadId: threadIds[index] as string })); } /** Why a thread request was refused. `null` means it was not. */ @@ -97,27 +102,20 @@ export type ChatDenial = 'not-found' | 'not-a-participant' | 'not-married'; * the database — deleting it would destroy the history — but stops answering, which is * why this returns a reason a caller can distinguish rather than a bare boolean. */ -export async function authorizeThread( - threadId: string, - caller: string -): Promise<{ denial: ChatDenial } | { denial: null; counterpart: string }> { +export async function authorizeThread(threadId: string, rawCaller: string): Promise { + const caller = normalizeAccount(rawCaller); const thread = await findThreadById(threadId); if (!thread) { - return { denial: 'not-found' }; + return 'not-found'; } const isParticipant = thread.participantA === caller || thread.participantB === caller; if (!isParticipant) { - return { denial: 'not-a-participant' }; + return 'not-a-participant'; } const counterpart = thread.participantA === caller ? thread.participantB : thread.participantA; - const marriages = await findMarriedCounterparts(caller); - const stillMarried = marriages.some( - (marriage) => normalizeAccount(marriage.counterpart) === counterpart - ); - - return stillMarried ? { denial: null, counterpart } : { denial: 'not-married' }; + return (await isMarriedTo(caller, counterpart)) ? null : 'not-married'; } /** A page of messages. Authorization is the caller's job — see `authorizeThread`. */ diff --git a/backend/src/repositories/chat.repository.ts b/backend/src/repositories/chat.repository.ts index b5f64950..3b74b543 100644 --- a/backend/src/repositories/chat.repository.ts +++ b/backend/src/repositories/chat.repository.ts @@ -1,7 +1,9 @@ +import { normalizeAccount } from '@cryptopets/protocol'; import { Prisma } from '@generated/prisma/client'; import { prisma } from '@config/prisma'; -import type { Chain } from '@typings/chain'; +import { ownerKey } from './owner.sql'; +import { chainOfAccount, type Chain } from '@typings/chain'; /** * Read/write access for private chat (roadmap §2 v1), plus the marriage lookup that @@ -25,32 +27,42 @@ export interface MarriedCounterpart { } /** - * Every wallet the caller is currently married to, one row per married pet pair. - * - * Two normalization details, both of which decide whether a real marriage is found: + * The roster-side marriage predicate for one caller: their pets, joined to each spouse + * pet, excluding pairs they own both sides of. * - * - `owner` in `pet_roster` is written by indexer-go, which is not guaranteed to - * match the JWT's case. The caller arrives normalized (EVM lowercased, base58 - * untouched), so EVM rows are matched folded and Solana rows exactly. Folding - * base58 could match a different pubkey, which here would open someone else's - * marriage. - * - The chain comes from the address shape rather than a parameter. A wallet only - * exists on one chain, so asking the caller which chain they meant would let them - * ask the wrong one. + * A pet married to another of the caller's own pets is a marriage but not a + * conversation — there is no second person to talk to. + */ +function marriedPairs(caller: string): { chain: Chain; where: Prisma.Sql } { + const chain = chainOfAccount(caller); + return { + chain, + where: Prisma.sql` + FROM pet_roster p + JOIN pet_roster s + ON s.chain = p.chain + AND s.pet_id = p.spouse_id + WHERE p.chain = ${chain} + AND ${ownerKey(chain, 'p')} = ${normalizeAccount(caller)} + AND p.spouse_id <> '0' + AND s.owner <> p.owner + `, + }; +} + +/** + * Every wallet the caller is currently married to, one row per married pet pair. * - * A pet marries a pet, so an owner pair can appear more than once (two of their pets - * married to each other's). The caller collapses that into one thread per pair. + * The caller is normalized and the chain derived from its shape, so the comparison + * matches how indexer-go wrote the roster regardless of the case it used. An owner pair + * can appear more than once (two of their pets married to each other's); the caller + * collapses that into one thread per pair. */ export async function findMarriedCounterparts(caller: string): Promise { if (!caller) { return []; } - - const isEvm = /^0x[0-9a-f]{40}$/.test(caller); - const ownerMatch = isEvm - ? Prisma.sql`LOWER(p.owner) = ${caller}` - : Prisma.sql`p.owner = ${caller}`; - const chain: Chain = isEvm ? 'evm' : 'solana'; + const { where } = marriedPairs(caller); return prisma.$queryRaw` SELECT p.chain, @@ -59,69 +71,65 @@ export async function findMarriedCounterparts(caller: string): Promise '0' - -- A pet married to another pet of the caller's own is a marriage, but not a - -- conversation: there is no second person to talk to. - AND s.owner <> p.owner + ${where} ORDER BY p.pet_id ASC `; } -/** A thread plus the counterpart, as one participant sees it. */ -export interface ThreadRow { - id: string; - counterpart: string; - createdAt: Date; +/** + * Whether these two wallets currently have a married pet pair. + * + * The binary form of `findMarriedCounterparts`, for the authorization check that runs on + * every message read and send: that path only needs a yes or no, and fetching every + * counterpart to filter one out in JavaScript reads more rows the busier a player is. + */ +export async function isMarriedTo(caller: string, counterpart: string): Promise { + if (!caller || !counterpart) { + return false; + } + const { chain, where } = marriedPairs(caller); + + const rows = await prisma.$queryRaw<{ ok: number }[]>` + SELECT 1 AS ok + ${where} + AND ${ownerKey(chain, 's')} = ${normalizeAccount(counterpart)} + LIMIT 1 + `; + return rows.length > 0; } /** - * The thread for a pair, creating it if this is their first. + * The thread id for a pair, creating it if this is their first. * * Participants are stored in lexicographic order, which is what makes the unique - * constraint mean "one thread per pair" instead of "one per direction" — without it - * A→B and B→A would be two threads holding half a conversation each. + * constraint mean "one thread per pair" instead of "one per direction" — without it A→B + * and B→A would be two threads holding half a conversation each. * - * Concurrent first-opens race, so a unique-constraint violation is resolved by reading - * the winner's row rather than failing: both callers are entitled to the same thread. + * An upsert rather than find-then-create: it is one round trip whether or not the thread + * exists, and two callers opening the same thread at once resolve to the same row instead + * of racing to a unique-constraint violation. */ export async function openThread( walletX: string, walletY: string, scope: string -): Promise { +): Promise { const [participantA, participantB] = walletX < walletY ? [walletX, walletY] : [walletY, walletX]; - const where = { chat_thread_pair: { participantA, participantB } }; - - const existing = await prisma.chatThread.findUnique({ where }); - if (existing) { - return toThreadRow(existing, walletX); - } - try { - const created = await prisma.chatThread.create({ - data: { participantA, participantB, scope }, - }); - return toThreadRow(created, walletX); - } catch (err) { - if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === 'P2002') { - const winner = await prisma.chatThread.findUniqueOrThrow({ where }); - return toThreadRow(winner, walletX); - } - throw err; - } + const thread = await prisma.chatThread.upsert({ + where: { chat_thread_pair: { participantA, participantB } }, + create: { participantA, participantB, scope }, + update: {}, + select: { id: true }, + }); + return thread.id; } /** The thread by id, or null. Returns participants so the caller can authorize. */ export function findThreadById(id: string) { return prisma.chatThread.findUnique({ where: { id }, - select: { id: true, participantA: true, participantB: true, scope: true }, + select: { id: true, participantA: true, participantB: true }, }); } @@ -135,9 +143,9 @@ export interface ChatMessageRow { /** * A page of messages, oldest first within the page. * - * Paged backwards from `before` (an exclusive message id) because a chat is read from - * its end: the first page is the newest messages, and older ones load as the reader - * scrolls up. + * Paged backwards from `before` (an exclusive message id) because a chat is read from its + * end: the first page is the newest messages, and older ones load as the reader scrolls + * up. */ export async function findMessages( threadId: string, @@ -164,14 +172,3 @@ export function insertMessage( select: { id: true, sender: true, text: true, createdAt: true }, }); } - -function toThreadRow( - thread: { id: string; participantA: string; participantB: string; createdAt: Date }, - viewer: string -): ThreadRow { - return { - id: thread.id, - counterpart: thread.participantA === viewer ? thread.participantB : thread.participantA, - createdAt: thread.createdAt, - }; -} diff --git a/backend/src/repositories/leaderboard.repository.ts b/backend/src/repositories/leaderboard.repository.ts index 2869e8cc..99f0d20c 100644 --- a/backend/src/repositories/leaderboard.repository.ts +++ b/backend/src/repositories/leaderboard.repository.ts @@ -2,6 +2,7 @@ import { Prisma } from '@generated/prisma/client'; import { prisma } from '@config/prisma'; import { servedChainIdForFamily } from './battleProgress.overlay'; +import { ownerKey } from './owner.sql'; import { servedDeploymentId } from '@features/battle-ledger/domain'; import type { Chain } from '@typings/chain'; @@ -20,13 +21,18 @@ import type { Chain } from '@typings/chain'; * ordering *is* the merge here, and a post-sort can only reorder rows a page already * holds. Same consequence, too — no gRPC fast path, because indexer-go's cache holds * chain state and has no view of `pet_battle_progress`. + * + * Every query below is built from the fragments beneath: the merge, the "has fought" + * filter and the ordering each exist once. That matters beyond tidiness — `findPlayerRank` + * must order identically to `findPlayerLeaderboard` or a player's stated rank stops + * matching where they appear on the board, and nothing but shared text enforces that. */ /** One ranked owner: their pets' battle records, summed. */ export interface PlayerLeaderboardEntry { /** 1-based position in the full ranking, not within the page. */ rank: number; - /** Wallet address / pubkey. EVM addresses are folded to lowercase; see `ownerKey`. */ + /** Wallet address / pubkey, as grouped — see `ownerKey`. */ owner: string; winCount: number; lossCount: number; @@ -58,182 +64,130 @@ export interface FindLeaderboardParams { } /** The projected columns, before the rank is attached. */ -interface RankedRow { - chain: string; - petId: string; - owner: string; - name: string; - level: number; - rarity: number; - dna: string; - winCount: number; - lossCount: number; - asset: string; -} +type RankedRow = Omit & { chain: string }; +type PlayerRow = Omit; /** - * A page of the pet leaderboard, ordered by wins and its win-rate tiebreak. + * The join onto backend progression. * - * Ordering is wins DESC, then losses ASC, then level DESC, then pet id ASC. The losses - * tiebreak *is* the win-rate tiebreak: among pets on equal wins, fewer losses is a - * strictly higher win rate, so no division is needed and pets are never ranked on a - * ratio computed from a handful of fights. + * A null `chainId` — this deployment serves no chain of the family — is not a special + * case needing its own query. `p.chain_id = NULL` is never true, so the LEFT JOIN matches + * nothing, every `COALESCE` below falls through to the roster column, and the result is + * exactly the chain-state-only ranking. Verified against live data on both chains. + */ +const progressJoin = (chainId: string | null): Prisma.Sql => Prisma.sql` + LEFT JOIN pet_battle_progress p + ON p.pet_id = r.pet_id + AND p.chain_id = ${chainId} + AND p.deployment_id = ${servedDeploymentId()} +`; + +// COALESCE for win/loss, GREATEST for level, matching `overlayRosterPet` and +// `findReadyOpponents`: a progress row supplies the battle record wholesale (nothing on +// chain writes it any more), while level keeps two live writers — backend battles raise +// the row, paid on-chain train()/levelUp() raise the roster. +const WINS = Prisma.sql`COALESCE(p.win_count, r.win_count)`; +const LOSSES = Prisma.sql`COALESCE(p.loss_count, r.loss_count)`; +const LEVEL = Prisma.sql`GREATEST(r.level, COALESCE(p.level, 0))`; + +/** + * Pets and owners with no record at all are excluded. A board of never-fought pets would + * be a roster dump with a rank column, and on this ordering they would all tie last. + */ +const HAS_FOUGHT = Prisma.sql`${WINS} + ${LOSSES} > 0`; + +/** + * Wins descending, then losses ascending, then a stable tiebreak. * - * Pets that have never fought are excluded. A leaderboard of pets with no record would - * be a roster dump with a rank column, and on the current ordering they would all tie - * at the bottom anyway. + * The losses key *is* the win-rate tiebreak: among rows on equal wins, fewer losses is a + * strictly higher rate, so no division is needed and nothing is ranked on a ratio drawn + * from a handful of fights. */ +const petOrder = Prisma.sql`${WINS} DESC, ${LOSSES} ASC, ${LEVEL} DESC, r.pet_id ASC`; +const playerOrder = (owner: Prisma.Sql) => + Prisma.sql`SUM(${WINS}) DESC, SUM(${LOSSES}) ASC, ${owner} ASC`; + +/** A page of the pet leaderboard. */ export async function findPetLeaderboard( params: FindLeaderboardParams ): Promise<{ entries: LeaderboardEntry[]; total: number }> { - const chainId = servedChainIdForFamily(params.chain); - const { rows, total } = chainId - ? await queryMerged(params, chainId) - : await queryChainStateOnly(params); - - const offset = params.page * params.pageSize; - return { - entries: rows.map((row, index) => ({ ...row, chain: row.chain as Chain, rank: offset + index + 1 })), - total, - }; -} - -/** The join against `pet_battle_progress`, for a chain family this deployment serves. */ -async function queryMerged( - params: FindLeaderboardParams, - chainId: string -): Promise<{ rows: RankedRow[]; total: number }> { - const deploymentId = servedDeploymentId(); + const join = progressJoin(servedChainIdForFamily(params.chain)); const skip = params.page * params.pageSize; - // COALESCE for win/loss, GREATEST for level, matching `overlayRosterPet` and - // `findReadyOpponents`: a progress row supplies the battle record wholesale (nothing - // on chain writes it any more), while level keeps two live writers — backend battles - // raise the row, paid on-chain train()/levelUp() raise the roster. const [rows, counted] = await Promise.all([ prisma.$queryRaw` SELECT r.chain, r.pet_id AS "petId", r.owner, r.name, r.rarity, r.dna, r.asset, - GREATEST(r.level, COALESCE(p.level, 0)) AS level, - COALESCE(p.win_count, r.win_count) AS "winCount", - COALESCE(p.loss_count, r.loss_count) AS "lossCount" + ${LEVEL} AS level, ${WINS} AS "winCount", ${LOSSES} AS "lossCount" FROM pet_roster r - LEFT JOIN pet_battle_progress p - ON p.pet_id = r.pet_id - AND p.chain_id = ${chainId} - AND p.deployment_id = ${deploymentId} - WHERE r.chain = ${params.chain} - AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 - ORDER BY COALESCE(p.win_count, r.win_count) DESC, - COALESCE(p.loss_count, r.loss_count) ASC, - GREATEST(r.level, COALESCE(p.level, 0)) DESC, - r.pet_id ASC + ${join} + WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} + ORDER BY ${petOrder} LIMIT ${params.pageSize} OFFSET ${skip} `, prisma.$queryRaw<{ total: bigint }[]>` SELECT COUNT(*) AS total FROM pet_roster r - LEFT JOIN pet_battle_progress p - ON p.pet_id = r.pet_id - AND p.chain_id = ${chainId} - AND p.deployment_id = ${deploymentId} - WHERE r.chain = ${params.chain} - AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + ${join} + WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} `, ]); - return { rows, total: Number(counted[0]?.total ?? 0) }; -} - -/** - * What one owner is grouped by. - * - * EVM addresses are folded, base58 Solana pubkeys are not — the same split - * `normalizeAccount` makes, and the same one `findReadyOpponents` applies to its consent - * match. It matters more here than there: indexer-go is not guaranteed to write the - * roster in one case, and an unfolded EVM group would list a single wallet twice with its - * record split between the rows. Folding base58 would do the opposite damage, merging two - * distinct pubkeys into one player. - */ -function ownerKey(chain: Chain): Prisma.Sql { - return chain === 'evm' ? Prisma.sql`LOWER(r.owner)` : Prisma.sql`r.owner`; + return { + entries: rows.map((row, index) => ({ + ...row, + chain: row.chain as Chain, + rank: skip + index + 1, + })), + total: Number(counted[0]?.total ?? 0), + }; } /** * A page of the player leaderboard: owners ranked by their pets' combined record. * - * Same ordering rule as the pet board — wins DESC, then losses ASC as the win-rate - * tiebreak — with the owner key as the stable final tiebreak. Only pets that have fought - * are summed, so `petCount` reads as "pets with a record" rather than "pets owned", and - * an owner with no battled pets does not appear at all. + * Only pets that have fought are summed, so `petCount` reads as "pets with a record" + * rather than "pets owned", and an owner with no battled pets does not appear at all. */ export async function findPlayerLeaderboard( params: FindLeaderboardParams ): Promise<{ entries: PlayerLeaderboardEntry[]; total: number }> { - const chainId = servedChainIdForFamily(params.chain); - const { rows, total } = chainId - ? await queryPlayersMerged(params, chainId) - : await queryPlayersFromChainState(params); - - const offset = params.page * params.pageSize; - return { - entries: rows.map((row, index) => ({ ...row, rank: offset + index + 1 })), - total, - }; -} - -/** The aggregate before its rank is attached. */ -interface PlayerRow { - owner: string; - winCount: number; - lossCount: number; - petCount: number; -} - -/** The owner aggregate over merged records, for a chain family this deployment serves. */ -async function queryPlayersMerged( - params: FindLeaderboardParams, - chainId: string -): Promise<{ rows: PlayerRow[]; total: number }> { - const deploymentId = servedDeploymentId(); + const join = progressJoin(servedChainIdForFamily(params.chain)); + const owner = ownerKey(params.chain, 'r'); const skip = params.page * params.pageSize; - const owner = ownerKey(params.chain); // The SUMs are cast because Postgres widens them to bigint, which Prisma would hand - // back as a BigInt the GraphQL Int serializer cannot take. A player's battle count - // has no way to approach the int range. + // back as a BigInt the GraphQL Int serializer cannot take. A player's battle count has + // no way to approach the int range. const [rows, counted] = await Promise.all([ prisma.$queryRaw` SELECT ${owner} AS owner, - SUM(COALESCE(p.win_count, r.win_count))::int AS "winCount", - SUM(COALESCE(p.loss_count, r.loss_count))::int AS "lossCount", + SUM(${WINS})::int AS "winCount", + SUM(${LOSSES})::int AS "lossCount", COUNT(*)::int AS "petCount" FROM pet_roster r - LEFT JOIN pet_battle_progress p - ON p.pet_id = r.pet_id - AND p.chain_id = ${chainId} - AND p.deployment_id = ${deploymentId} - WHERE r.chain = ${params.chain} - AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + ${join} + WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} GROUP BY ${owner} - ORDER BY "winCount" DESC, "lossCount" ASC, ${owner} ASC + ORDER BY ${playerOrder(owner)} LIMIT ${params.pageSize} OFFSET ${skip} `, + // Counts grouped owners, not joined pet rows: COUNT(*) over the ungrouped join + // would count pets and page the client past the last owner. prisma.$queryRaw<{ total: bigint }[]>` SELECT COUNT(*) AS total FROM ( SELECT 1 FROM pet_roster r - LEFT JOIN pet_battle_progress p - ON p.pet_id = r.pet_id - AND p.chain_id = ${chainId} - AND p.deployment_id = ${deploymentId} - WHERE r.chain = ${params.chain} - AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 + ${join} + WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} GROUP BY ${owner} ) owners `, ]); - return { rows, total: Number(counted[0]?.total ?? 0) }; + return { + entries: rows.map((row, index) => ({ ...row, rank: skip + index + 1 })), + total: Number(counted[0]?.total ?? 0), + }; } /** @@ -242,15 +196,14 @@ async function queryPlayersMerged( * Exists so a player can be told their rank without the client paging the board looking * for itself, which costs one request per page and gets worse as the game grows. * - * `ROW_NUMBER` over the same ORDER BY the paged query uses, so the number here is the - * number that row would carry on its page — the page arithmetic (`offset + index + 1`) - * is the same function. Ties cannot diverge either, since the owner key makes the - * ordering strict. + * `ROW_NUMBER` over `playerOrder` — the same ordering the paged query uses, from the same + * fragment — so this number is the one that row carries on its page. The page arithmetic + * (`skip + index + 1`) is the same function, and ties cannot diverge because the owner key + * makes the ordering strict. * - * `owner` must already be normalized the way the JWT normalizes it (EVM lowercased, - * Solana base58 as-is), which is exactly how `ownerKey` groups. An unnormalized EVM - * address matches nothing and reads as "unranked", which is why the caller passes the - * authenticated address rather than anything user-supplied. + * `owner` must already be normalized the way the JWT normalizes it, which is how + * `ownerKey` groups. An unnormalized EVM address matches nothing and reads as "unranked", + * which is why callers pass the authenticated address rather than anything user-supplied. */ export async function findPlayerRank( chain: Chain, @@ -260,119 +213,23 @@ export async function findPlayerRank( return null; } - const chainId = servedChainIdForFamily(chain); - const key = ownerKey(chain); + const join = progressJoin(servedChainIdForFamily(chain)); + const key = ownerKey(chain, 'r'); - // The two branches differ only in whether progression is joined, matching the two - // paged queries above. - const ranked = chainId - ? Prisma.sql` - SELECT ${key} AS owner, - SUM(COALESCE(p.win_count, r.win_count))::int AS "winCount", - SUM(COALESCE(p.loss_count, r.loss_count))::int AS "lossCount", - COUNT(*)::int AS "petCount", - ROW_NUMBER() OVER ( - ORDER BY SUM(COALESCE(p.win_count, r.win_count)) DESC, - SUM(COALESCE(p.loss_count, r.loss_count)) ASC, - ${key} ASC - )::int AS rank - FROM pet_roster r - LEFT JOIN pet_battle_progress p - ON p.pet_id = r.pet_id - AND p.chain_id = ${chainId} - AND p.deployment_id = ${servedDeploymentId()} - WHERE r.chain = ${chain} - AND COALESCE(p.win_count, r.win_count) + COALESCE(p.loss_count, r.loss_count) > 0 - GROUP BY ${key} - ` - : Prisma.sql` + const rows = await prisma.$queryRaw` + SELECT owner, "winCount", "lossCount", "petCount", rank FROM ( SELECT ${key} AS owner, - SUM(r.win_count)::int AS "winCount", - SUM(r.loss_count)::int AS "lossCount", + SUM(${WINS})::int AS "winCount", + SUM(${LOSSES})::int AS "lossCount", COUNT(*)::int AS "petCount", - ROW_NUMBER() OVER ( - ORDER BY SUM(r.win_count) DESC, SUM(r.loss_count) ASC, ${key} ASC - )::int AS rank + ROW_NUMBER() OVER (ORDER BY ${playerOrder(key)})::int AS rank FROM pet_roster r - WHERE r.chain = ${chain} AND r.win_count + r.loss_count > 0 + ${join} + WHERE r.chain = ${chain} AND ${HAS_FOUGHT} GROUP BY ${key} - `; - - const rows = await prisma.$queryRaw` - SELECT owner, "winCount", "lossCount", "petCount", rank - FROM (${ranked}) ranked + ) ranked WHERE owner = ${owner} `; return rows[0] ?? null; } - -/** The same aggregate without progression, for a chain family this deployment does not serve. */ -async function queryPlayersFromChainState( - params: FindLeaderboardParams -): Promise<{ rows: PlayerRow[]; total: number }> { - const skip = params.page * params.pageSize; - const owner = ownerKey(params.chain); - - const [rows, counted] = await Promise.all([ - prisma.$queryRaw` - SELECT ${owner} AS owner, - SUM(r.win_count)::int AS "winCount", - SUM(r.loss_count)::int AS "lossCount", - COUNT(*)::int AS "petCount" - FROM pet_roster r - WHERE r.chain = ${params.chain} - AND r.win_count + r.loss_count > 0 - GROUP BY ${owner} - ORDER BY "winCount" DESC, "lossCount" ASC, ${owner} ASC - LIMIT ${params.pageSize} OFFSET ${skip} - `, - prisma.$queryRaw<{ total: bigint }[]>` - SELECT COUNT(DISTINCT ${owner}) AS total - FROM pet_roster r - WHERE r.chain = ${params.chain} - AND r.win_count + r.loss_count > 0 - `, - ]); - - return { rows, total: Number(counted[0]?.total ?? 0) }; -} - -/** The same ranking without progression, for a chain family this deployment does not serve. */ -async function queryChainStateOnly( - params: FindLeaderboardParams -): Promise<{ rows: RankedRow[]; total: number }> { - const where = { - chain: params.chain, - OR: [{ winCount: { gt: 0 } }, { lossCount: { gt: 0 } }], - }; - - const [rows, total] = await Promise.all([ - prisma.petRoster.findMany({ - where, - select: { - chain: true, - petId: true, - owner: true, - name: true, - level: true, - rarity: true, - dna: true, - winCount: true, - lossCount: true, - asset: true, - }, - orderBy: [ - { winCount: 'desc' }, - { lossCount: 'asc' }, - { level: 'desc' }, - { petId: 'asc' }, - ], - skip: params.page * params.pageSize, - take: params.pageSize, - }), - prisma.petRoster.count({ where }), - ]); - - return { rows, total }; -} diff --git a/backend/src/repositories/owner.sql.ts b/backend/src/repositories/owner.sql.ts new file mode 100644 index 00000000..81861712 --- /dev/null +++ b/backend/src/repositories/owner.sql.ts @@ -0,0 +1,25 @@ +import { Prisma } from '@generated/prisma/client'; + +import type { Chain } from '@typings/chain'; + +/** + * The SQL expression that identifies a `pet_roster` owner, per chain. + * + * EVM addresses are folded to lowercase and base58 Solana pubkeys are left alone — the + * same split `normalizeAccount` makes. Stated once here because it is security-relevant + * in more than one place and was previously restated at three call sites: matchmaking's + * consent match, the leaderboard's owner grouping, and chat's marriage gate. + * + * Both directions of getting it wrong are real. `owner` is written by indexer-go, which + * is not guaranteed to match the case the JWT normalizes to, so an unfolded EVM + * comparison misses rows that should match — listing one wallet twice on the player + * board, or finding no marriage for someone who has one. Folding base58 does the + * opposite damage: two distinct Solana pubkeys can differ only in case, so it can match + * an account that is not the caller's. + * + * `alias` is the table alias the caller gave `pet_roster` in its own query. + */ +export function ownerKey(chain: Chain, alias: string): Prisma.Sql { + const column = Prisma.raw(`${alias}.owner`); + return chain === 'evm' ? Prisma.sql`LOWER(${column})` : Prisma.sql`${column}`; +} diff --git a/backend/src/repositories/roster.repository.ts b/backend/src/repositories/roster.repository.ts index f42d1ee8..ffeaf420 100644 --- a/backend/src/repositories/roster.repository.ts +++ b/backend/src/repositories/roster.repository.ts @@ -5,6 +5,7 @@ import { prisma } from '@config/prisma'; import { tryGrpcGetPetState } from '@grpc-client/rosterReads'; import { mapRosterRowToRosterPet, type PetRosterRow } from './roster.mapping'; import { servedChainIdForFamily } from './battleProgress.overlay'; +import { ownerKey } from './owner.sql'; import { servedDeploymentId } from '@features/battle-ledger/domain'; import type { Chain } from '@typings/chain'; @@ -101,14 +102,10 @@ export async function findReadyOpponents( const rulesetHash = hashRuleset(SOURCE_DEFAULT_RULESET); const skip = params.page * params.pageSize; - // `normalizeAccount` lowercases EVM addresses and leaves base58 Solana pubkeys - // alone, so only the EVM side is folded — indexer-go is not guaranteed to write - // the roster in the same case. Folding base58 too could match two distinct - // pubkeys and list a pet whose owner never consented. - const ownerMatch = - params.chain === 'evm' - ? Prisma.sql`LOWER(r.owner) = a.defender_owner` - : Prisma.sql`r.owner = a.defender_owner`; + // Folded for EVM, exact for base58 — see `ownerKey`, which states the rule once for + // the three places that need it (here, the leaderboard's grouping, chat's marriage + // gate). Getting it wrong here would list a pet whose owner never consented. + const ownerMatch = Prisma.sql`${ownerKey(params.chain, 'r')} = a.defender_owner`; // A live grant covering this pet, under the ruleset battles are currently settled // under. Level band and daily cap are not here on purpose — see the header. diff --git a/backend/src/types/chain.ts b/backend/src/types/chain.ts index fa87a420..c6d4a495 100644 --- a/backend/src/types/chain.ts +++ b/backend/src/types/chain.ts @@ -1,3 +1,5 @@ +import { isEvmAddress } from '@utils'; + /** Chains the app indexes and matches pets across. Single source of truth. */ export const SUPPORTED_CHAINS = ['evm', 'solana'] as const; @@ -6,3 +8,14 @@ export type Chain = (typeof SUPPORTED_CHAINS)[number]; export function isSupportedChain(value: string): value is Chain { return (SUPPORTED_CHAINS as readonly string[]).includes(value); } + +/** + * Which chain a wallet address belongs to, by its shape. + * + * A wallet only exists on one chain, so this is derivable rather than something a caller + * should be asked for — asking would let them name the wrong one. Uses the same + * case-insensitive EVM test as auth, so a checksummed address is not misread as Solana. + */ +export function chainOfAccount(address: string): Chain { + return isEvmAddress(address) ? 'evm' : 'solana'; +} diff --git a/backend/tests/features/chat.controller.test.ts b/backend/tests/features/chat.controller.test.ts index 1c114ec7..f74a8c72 100644 --- a/backend/tests/features/chat.controller.test.ts +++ b/backend/tests/features/chat.controller.test.ts @@ -38,7 +38,7 @@ function req(over: Record = {}): Request { beforeEach(() => { vi.clearAllMocks(); - vi.mocked(authorizeThread).mockResolvedValue({ denial: null, counterpart: '0xthem' }); + vi.mocked(authorizeThread).mockResolvedValue(null); }); describe('getThreads', () => { @@ -64,7 +64,7 @@ describe('thread authorization', () => { // A non-participant must not be able to tell an existing thread id from a made-up // one; 403 here would confirm the id for anyone probing. it('answers 404, not 403, for a wallet that is not a participant', async () => { - vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-a-participant' }); + vi.mocked(authorizeThread).mockResolvedValue('not-a-participant'); const res = makeRes(); await getMessages(req(), res); @@ -74,7 +74,7 @@ describe('thread authorization', () => { }); it('answers 404 for a thread that does not exist', async () => { - vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-found' }); + vi.mocked(authorizeThread).mockResolvedValue('not-found'); const res = makeRes(); await getMessages(req(), res); @@ -84,7 +84,7 @@ describe('thread authorization', () => { // A participant already knows the thread exists, so an ended marriage can say so. it('answers 403 with a reason when the marriage has ended', async () => { - vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-married' }); + vi.mocked(authorizeThread).mockResolvedValue('not-married'); const res = makeRes(); await postMessage(req({ body: { text: 'hi' } }), res); @@ -166,7 +166,7 @@ describe('postMessage', () => { }); it('does not notify when the write was refused', async () => { - vi.mocked(authorizeThread).mockResolvedValue({ denial: 'not-married' }); + vi.mocked(authorizeThread).mockResolvedValue('not-married'); await postMessage(req({ body: { text: 'hello' } }), makeRes()); diff --git a/backend/tests/features/chat.service.test.ts b/backend/tests/features/chat.service.test.ts index 77cf7d1f..52ab786b 100644 --- a/backend/tests/features/chat.service.test.ts +++ b/backend/tests/features/chat.service.test.ts @@ -3,11 +3,13 @@ import { describe, expect, it, vi, beforeEach } from 'vitest'; const findMarriedCounterparts = vi.fn(); const openThread = vi.fn(); const findThreadById = vi.fn(); +const isMarriedTo = vi.fn(); vi.mock('@repositories/chat.repository', () => ({ findMarriedCounterparts: (caller: string) => findMarriedCounterparts(caller), openThread: (x: string, y: string, scope: string) => openThread(x, y, scope), findThreadById: (id: string) => findThreadById(id), + isMarriedTo: (a: string, b: string) => isMarriedTo(a, b), findMessages: vi.fn(), insertMessage: vi.fn(), })); @@ -29,11 +31,8 @@ const marriage = (over: Record = {}) => ({ beforeEach(() => { vi.clearAllMocks(); - openThread.mockImplementation(async (x: string, y: string) => ({ - id: `thread-${x}-${y}`, - counterpart: y, - createdAt: new Date(0), - })); + openThread.mockImplementation(async (x: string, y: string) => `thread-${x}-${y}`); + isMarriedTo.mockResolvedValue(true); }); describe('listThreads', () => { @@ -88,7 +87,8 @@ describe('authorizeThread', () => { findThreadById.mockResolvedValue(thread); findMarriedCounterparts.mockResolvedValue([marriage()]); - expect(await authorizeThread('t1', ME)).toEqual({ denial: null, counterpart: THEM }); + expect(await authorizeThread('t1', ME)).toBeNull(); + expect(isMarriedTo).toHaveBeenCalledWith(ME, THEM); }); it('refuses a wallet that is not a participant', async () => { @@ -96,32 +96,23 @@ describe('authorizeThread', () => { const result = await authorizeThread('t1', '0x9999999999999999999999999999999999999999'); - expect(result.denial).toBe('not-a-participant'); + expect(result).toBe('not-a-participant'); // The marriage is not even consulted: not being in the thread settles it. - expect(findMarriedCounterparts).not.toHaveBeenCalled(); + expect(isMarriedTo).not.toHaveBeenCalled(); }); // The point of checking live state per request instead of recording it on the // thread: a divorce closes the conversation with nothing to revoke. it('refuses a participant whose marriage has ended', async () => { findThreadById.mockResolvedValue(thread); - findMarriedCounterparts.mockResolvedValue([]); - - expect((await authorizeThread('t1', ME)).denial).toBe('not-married'); - }); - - it('refuses a participant now married to somebody else', async () => { - findThreadById.mockResolvedValue(thread); - findMarriedCounterparts.mockResolvedValue([ - marriage({ counterpart: '0x3333333333333333333333333333333333333333' }), - ]); + isMarriedTo.mockResolvedValue(false); - expect((await authorizeThread('t1', ME)).denial).toBe('not-married'); + expect(await authorizeThread('t1', ME)).toBe('not-married'); }); it('reports a missing thread', async () => { findThreadById.mockResolvedValue(null); - expect((await authorizeThread('nope', ME)).denial).toBe('not-found'); + expect(await authorizeThread('nope', ME)).toBe('not-found'); }); }); diff --git a/backend/tests/repositories/leaderboard.repository.test.ts b/backend/tests/repositories/leaderboard.repository.test.ts index e78d754f..f877d806 100644 --- a/backend/tests/repositories/leaderboard.repository.test.ts +++ b/backend/tests/repositories/leaderboard.repository.test.ts @@ -42,27 +42,42 @@ function mockJoinQuery(rows: unknown[], total: number) { .mockResolvedValueOnce([{ total: BigInt(total) }] as never); } -/** The SQL text of the nth `$queryRaw` call, whitespace-collapsed for matching. */ -function sqlOfCall(index: number): string { - const [template] = vi.mocked(prisma.$queryRaw).mock.calls[index] as unknown as [string[]]; - return template.join(' ? ').replace(/\s+/g, ' '); +function callOf(index: number): [string[], ...unknown[]] { + return vi.mocked(prisma.$queryRaw).mock.calls[index] as unknown as [string[], ...unknown[]]; } /** - * The SQL of any `Prisma.Sql` fragments interpolated into the nth call. + * The full SQL of the nth `$queryRaw` call: literal chunks with any interpolated + * `Prisma.Sql` fragment spliced back in. * - * `sqlOfCall` only sees the literal chunks, so the owner key — a nested fragment — is - * invisible to it. `$queryRaw` is mocked, so the nesting is never flattened. + * The queries are assembled from shared fragments (the merge, the filter, the ordering), + * and `$queryRaw` is mocked so nothing ever flattens them — a helper that read only the + * literal chunks would see none of the logic under test. */ -function fragmentsOfCall(index: number): string { - const [, ...values] = vi.mocked(prisma.$queryRaw).mock.calls[index] as unknown as [string[], ...unknown[]]; - return values - .filter((value): value is { sql: string } => typeof (value as { sql?: unknown })?.sql === 'string') - .map((fragment) => fragment.sql) - .join(' ') +function sqlOfCall(index: number): string { + const [template, ...values] = callOf(index); + return template + .map((chunk, i) => { + const value = values[i] as { sql?: unknown } | undefined; + return chunk + (typeof value?.sql === 'string' ? value.sql : i < values.length ? ' ? ' : ''); + }) + .join('') .replace(/\s+/g, ' '); } +/** + * Every bound parameter of the nth call, including those carried by interpolated + * fragments — the join's `chain_id` is one of those, so a helper that only looked at the + * outer values would miss it. + */ +function paramsOfCall(index: number): unknown[] { + const [, ...values] = callOf(index); + return values.flatMap((value) => { + const fragment = value as { sql?: unknown; values?: unknown[] }; + return typeof fragment?.sql === 'string' ? (fragment.values ?? []) : [value]; + }); +} + beforeEach(() => { vi.clearAllMocks(); servedChainIdForFamily.mockReturnValue('eip155:31337'); @@ -114,24 +129,20 @@ describe('findPetLeaderboard', () => { expect(sqlOfCall(1)).toContain(battled); }); - it('falls back to chain state for a chain family this deployment does not serve', async () => { + // A chain family this deployment does not serve needs no second query: `chain_id = NULL` + // never matches, so the join contributes nothing and every COALESCE falls back to the + // roster column — which is the chain-state-only ranking, exactly. + it('joins on a null chain id for an unserved chain family, falling back to roster values', async () => { servedChainIdForFamily.mockReturnValue(null); - vi.mocked(prisma.petRoster.findMany).mockResolvedValue([rankedRow] as never); - vi.mocked(prisma.petRoster.count).mockResolvedValue(1 as never); + mockJoinQuery([rankedRow], 1); const result = await findPetLeaderboard({ chain: 'solana', page: 0, pageSize: 20 }); - expect(prisma.$queryRaw).not.toHaveBeenCalled(); expect(result.entries[0].rank).toBe(1); - - const args = vi.mocked(prisma.petRoster.findMany).mock.calls[0][0]; - expect(args?.orderBy).toEqual([ - { winCount: 'desc' }, - { lossCount: 'asc' }, - { level: 'desc' }, - { petId: 'asc' }, - ]); - expect(args?.where?.OR).toEqual([{ winCount: { gt: 0 } }, { lossCount: { gt: 0 } }]); + expect(sqlOfCall(0)).toContain('LEFT JOIN pet_battle_progress p'); + expect(paramsOfCall(0)).toContain(null); + // No separate roster-only code path exists any more. + expect(prisma.petRoster.findMany).not.toHaveBeenCalled(); }); }); @@ -162,7 +173,7 @@ describe('findPlayerLeaderboard', () => { await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); - expect(fragmentsOfCall(0)).toContain('LOWER(r.owner)'); + expect(sqlOfCall(0)).toContain('LOWER(r.owner)'); }); it('leaves Solana pubkeys unfolded, since base58 is case-significant', async () => { @@ -171,9 +182,9 @@ describe('findPlayerLeaderboard', () => { await findPlayerLeaderboard({ chain: 'solana', page: 0, pageSize: 20 }); - const fragments = fragmentsOfCall(0); - expect(fragments).toContain('r.owner'); - expect(fragments).not.toContain('LOWER('); + const sql = sqlOfCall(0); + expect(sql).toContain('r.owner'); + expect(sql).not.toContain('LOWER('); }); it('sums the merged record and counts owners, not pets', async () => { @@ -184,25 +195,12 @@ describe('findPlayerLeaderboard', () => { const sql = sqlOfCall(0); expect(sql).toContain('SUM(COALESCE(p.win_count, r.win_count))::int'); expect(sql).toContain('SUM(COALESCE(p.loss_count, r.loss_count))::int'); - expect(sql).toContain('ORDER BY "winCount" DESC, "lossCount" ASC'); + expect(sql).toContain('ORDER BY SUM(COALESCE(p.win_count, r.win_count)) DESC'); // The total counts grouped owners: COUNT(*) over the ungrouped join would count // pets, and page the client past the last owner. expect(sqlOfCall(1)).toContain('SELECT COUNT(*) AS total FROM ('); expect(sqlOfCall(1)).toContain('GROUP BY'); }); - - it('sums frozen roster counters for a chain family this deployment does not serve', async () => { - servedChainIdForFamily.mockReturnValue(null); - mockJoinQuery([playerRow], 1); - - const result = await findPlayerLeaderboard({ chain: 'solana', page: 0, pageSize: 20 }); - - expect(result.entries[0].rank).toBe(1); - const sql = sqlOfCall(0); - expect(sql).toContain('SUM(r.win_count)::int'); - expect(sql).not.toContain('pet_battle_progress'); - expect(sqlOfCall(1)).toContain('COUNT(DISTINCT'); - }); }); describe('findPlayerRank', () => { @@ -227,18 +225,21 @@ describe('findPlayerRank', () => { expect(prisma.$queryRaw).not.toHaveBeenCalled(); }); - it('ranks with ROW_NUMBER over the ordering the paged board uses', async () => { - // The paged board numbers rows `offset + index + 1`; this has to be the same - // function, or a player's stated rank would not match where they appear. + // The board and the rank are ordered by one shared fragment. If they ever diverged, a + // player's stated rank would stop matching where they actually appear. + it('ranks with ROW_NUMBER over the same ordering the paged board uses', async () => { vi.mocked(prisma.$queryRaw).mockResolvedValueOnce([] as never); - await findPlayerRank('evm', '0xowner'); + const rankSql = sqlOfCall(0); + + vi.mocked(prisma.$queryRaw).mockClear(); + mockJoinQuery([], 0); + await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + const boardSql = sqlOfCall(0); - const fragments = fragmentsOfCall(0); - expect(fragments).toContain('ROW_NUMBER() OVER ('); - expect(fragments).toContain('SUM(COALESCE(p.win_count, r.win_count)) DESC'); - expect(fragments).toContain('SUM(COALESCE(p.loss_count, r.loss_count)) ASC'); - expect(fragments).toContain('LOWER(r.owner)'); + const ordering = 'SUM(COALESCE(p.win_count, r.win_count)) DESC, SUM(COALESCE(p.loss_count, r.loss_count)) ASC, LOWER(r.owner) ASC'; + expect(rankSql).toContain(`ROW_NUMBER() OVER (ORDER BY ${ordering})`); + expect(boardSql).toContain(`ORDER BY ${ordering}`); }); it('ranks on frozen counters for a chain family this deployment does not serve', async () => { @@ -247,10 +248,10 @@ describe('findPlayerRank', () => { await findPlayerRank('solana', 'SoLpubkey'); - const fragments = fragmentsOfCall(0); - expect(fragments).toContain('SUM(r.win_count) DESC'); - expect(fragments).not.toContain('pet_battle_progress'); + const sql = sqlOfCall(0); + expect(sql).toContain('ROW_NUMBER() OVER ('); + expect(paramsOfCall(0)).toContain(null); // base58 stays unfolded here too, for the reason the board folds only EVM. - expect(fragments).not.toContain('LOWER('); + expect(sql).not.toContain('LOWER('); }); }); diff --git a/frontend/src/components/chat/index.tsx b/frontend/src/components/chat/index.tsx index 89376453..5e848d74 100644 --- a/frontend/src/components/chat/index.tsx +++ b/frontend/src/components/chat/index.tsx @@ -11,15 +11,11 @@ import DashboardPanel from '@components/common/dashboard-panel'; import StateCard from '@components/pet/interactions/state-card'; import Icon, { MarriageIcon } from '@components/ui/icon'; import { CHAT_WS_URL } from '../../config'; +import { sameAccount, shortAddress } from '@utils/address'; import { DASHBOARD_HOME } from '@constants/interactionRoutes'; import { Tones } from '@constants/tones'; import styles from './index.module.css'; -/** `0x1234…abcd` — a full address does not fit the thread list. */ -function shortAddress(address: string): string { - return address.length > 12 ? `${address.slice(0, 6)}…${address.slice(-4)}` : address; -} - /** The married pets behind a thread, as a one-line reason it exists. */ function marriageLine(thread: ChatThread): string { return thread.pets.map((pair) => `${pair.petName} ♥ ${pair.spouseName}`).join(', '); @@ -114,7 +110,7 @@ const Conversation: React.FC<{ thread: ChatThread; me: string }> = ({ thread, me
  • 12 ? `${address.slice(0, 6)}…${address.slice(-4)}` : address; -} - /** Medal for the top three, plain number below. Rank is absolute, so this holds on page 2+. */ function rankBadge(rank: number): string { return rank === 1 ? '🥇' : rank === 2 ? '🥈' : rank === 3 ? '🥉' : `#${rank}`; } -const PetRow: React.FC<{ entry: LeaderboardEntry; isYou: boolean }> = ({ entry, isYou }) => { - const rate = winRate(entry.winCount, entry.lossCount); - return ( -
  • - {rankBadge(entry.rank)} - - - - - {entry.name} - Lv {entry.level} - - - {entry.winCount}W - {entry.lossCount}L - - {rate == null ? '—' : `${rate}%`} -
  • - ); -}; - -const PlayerRow: React.FC<{ entry: PlayerLeaderboardEntry; isYou: boolean }> = ({ - entry, - isYou, -}) => { - const rate = winRate(entry.winCount, entry.lossCount); +/** + * One ranked row. Both boards render the same five tracks — only the avatar, the title + * and the sub-line differ — so they share this rather than two near-identical components + * that would drift the first time the record column is edited. + */ +const Row: React.FC<{ + rank: number; + avatar: ReactNode; + title: ReactNode; + sub: ReactNode; + winCount: number; + lossCount: number; + isYou: boolean; +}> = ({ rank, avatar, title, sub, winCount, lossCount, isYou }) => { + const rate = winRate(winCount, lossCount); return (
  • - {rankBadge(entry.rank)} + {rankBadge(rank)} - 👤 + {avatar} - {shortAddress(entry.owner)} - - {entry.petCount} pet{entry.petCount === 1 ? '' : 's'} - + {title} + {sub} - {entry.winCount}W - {entry.lossCount}L + {winCount}W + {lossCount}L {rate == null ? '—' : `${rate}%`}
  • @@ -138,12 +111,9 @@ const Leaderboard: React.FC = () => { ); } - // The owner strings the backend grouped by are lowercased on EVM and untouched on - // Solana, so compare the same way rather than assuming either case. - const you = - activeKind === 'evm' ? (walletAddress ?? '').toLowerCase() : (walletAddress ?? ''); - /** Folding base58 would let two distinct Solana pubkeys read as the same player. */ - const isYou = (owner: string) => (activeKind === 'evm' ? owner.toLowerCase() === you : owner === you); + // `sameAccount` normalizes by address shape, so this needs no chain branch and cannot + // merge two Solana pubkeys that differ only in case. + const isYou = (owner: string) => sameAccount(owner, walletAddress ?? ''); const showBoard = (next: Board) => { setBoard(next); @@ -195,12 +165,36 @@ const Leaderboard: React.FC = () => {
      {board === 'pets' ? pets.entries.map((entry) => ( - + + } + title={entry.name} + sub={`Lv ${entry.level}`} + winCount={entry.winCount} + lossCount={entry.lossCount} + isYou={isYou(entry.owner)} + /> )) : players.entries.map((entry) => ( - ))} diff --git a/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts b/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts index 517f324d..65f9efaa 100644 --- a/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts +++ b/frontend/src/components/pet/interactions/panels/battle/battle-utils.ts @@ -14,9 +14,6 @@ export const toDialoguePet = (pet: Pet | OpponentPet): DialoguePetInput => ({ /** Stable select value for an opponent (pet ids are not globally unique on Solana). */ export const opponentKey = (owner: string, id: string) => `${owner}::${id}`; -export const shortAddress = (addr: string) => - addr.length > 12 ? `${addr.slice(0, 6)}…${addr.slice(-4)}` : addr; - export const VALIDATION_MESSAGE = 'Please select your pet and an opponent'; export const BATTLE_FAIL_MESSAGE = 'Failed to start battle. Please try again.'; /** Shown briefly when the client-side live-replay disagrees with the on-chain diff --git a/frontend/src/components/pet/interactions/panels/battle/parts/battle-setup.tsx b/frontend/src/components/pet/interactions/panels/battle/parts/battle-setup.tsx index 87d1a91e..b5fdced6 100644 --- a/frontend/src/components/pet/interactions/panels/battle/parts/battle-setup.tsx +++ b/frontend/src/components/pet/interactions/panels/battle/parts/battle-setup.tsx @@ -14,7 +14,8 @@ import { import { Tones } from '@constants/tones'; import { AuthActionButton } from '@components/common'; import Icon, { BattleIcon } from '@components/ui/icon'; -import { opponentKey, shortAddress } from '../battle-utils'; +import { opponentKey } from '../battle-utils'; +import { shortAddress } from '@utils/address'; import styles from '../index.module.css'; import PetArt from '@components/pet/pet-art'; diff --git a/frontend/src/utils/address.ts b/frontend/src/utils/address.ts new file mode 100644 index 00000000..3d4a38be --- /dev/null +++ b/frontend/src/utils/address.ts @@ -0,0 +1,21 @@ +import { normalizeAccount } from '@shared/core'; + +/** + * `0x1234…abcd` — a full address does not fit the columns it is displayed in. + * + * One definition because the app should not show two address formats; it was previously + * copied into the battle panel, the leaderboard and the chat thread list. + */ +export const shortAddress = (address: string): string => + address.length > 12 ? `${address.slice(0, 6)}…${address.slice(-4)}` : address; + +/** + * Whether two wallet addresses are the same account. + * + * Uses the protocol's own normalization rather than `toLowerCase()`, so it needs no chain + * argument and cannot merge accounts: EVM addresses are case-insensitive and fold, while + * base58 Solana pubkeys are case-*sensitive* and must not — two distinct pubkeys can + * differ only in case. + */ +export const sameAccount = (a: string, b: string): boolean => + Boolean(a) && Boolean(b) && normalizeAccount(a) === normalizeAccount(b); diff --git a/frontend/tests/components/chat.test.tsx b/frontend/tests/components/chat.test.tsx index 8f98a0ff..cfc70a0b 100644 --- a/frontend/tests/components/chat.test.tsx +++ b/frontend/tests/components/chat.test.tsx @@ -8,6 +8,9 @@ const useChatThreads = vi.fn(); const useChatMessages = vi.fn(); vi.mock('@shared/core', () => ({ + // `@utils/address` normalizes through the protocol helper; the real one, since the + // EVM-folds/base58-doesn't rule is what several of these assertions are about. + normalizeAccount: (value: string) => (/^0x[0-9a-fA-F]{40}$/.test(value) ? value.toLowerCase() : value), useChainCapabilities: () => useChainCapabilities(), useChatThreads: () => useChatThreads(), useChatMessages: (opts: unknown) => useChatMessages(opts), diff --git a/frontend/tests/components/leaderboard.test.tsx b/frontend/tests/components/leaderboard.test.tsx index d9f6ebe2..f24ebf8a 100644 --- a/frontend/tests/components/leaderboard.test.tsx +++ b/frontend/tests/components/leaderboard.test.tsx @@ -8,6 +8,9 @@ const useLeaderboard = vi.fn(); const usePlayerLeaderboard = vi.fn(); vi.mock('@shared/core', () => ({ + // `@utils/address` normalizes through the protocol helper; the real one, since the + // EVM-folds/base58-doesn't rule is what several of these assertions are about. + normalizeAccount: (value: string) => (/^0x[0-9a-fA-F]{40}$/.test(value) ? value.toLowerCase() : value), useChainCapabilities: () => useChainCapabilities(), useLeaderboard: (opts: unknown) => useLeaderboard(opts), usePlayerLeaderboard: (opts: unknown) => usePlayerLeaderboard(opts), diff --git a/frontend/tests/components/pet/interactions/panels/battle/battle-utils.test.ts b/frontend/tests/components/pet/interactions/panels/battle/battle-utils.test.ts index 2aac2cb7..f8e74456 100644 --- a/frontend/tests/components/pet/interactions/panels/battle/battle-utils.test.ts +++ b/frontend/tests/components/pet/interactions/panels/battle/battle-utils.test.ts @@ -3,7 +3,6 @@ import type { OpponentPet, Pet } from '@shared/core'; import { opponentKey, - shortAddress, toDialoguePet, } from '@components/pet/interactions/panels/battle/battle-utils'; @@ -52,13 +51,3 @@ describe('opponentKey', () => { }); }); -describe('shortAddress', () => { - it('truncates long addresses to head…tail', () => { - expect(shortAddress('0x1234567890abcdef')).toBe('0x1234…cdef'); - }); - - it('returns short strings unchanged', () => { - expect(shortAddress('0x1234')).toBe('0x1234'); - expect(shortAddress('0x1234567890')).toBe('0x1234567890'); - }); -}); diff --git a/frontend/tests/utils/address.test.ts b/frontend/tests/utils/address.test.ts new file mode 100644 index 00000000..5d3ec0e0 --- /dev/null +++ b/frontend/tests/utils/address.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest'; + +import { sameAccount, shortAddress } from '@utils/address'; + +describe('shortAddress', () => { + it('truncates long addresses to head…tail', () => { + expect(shortAddress('0x1234567890abcdef')).toBe('0x1234…cdef'); + }); + + it('returns short strings unchanged', () => { + expect(shortAddress('0x1234')).toBe('0x1234'); + expect(shortAddress('0x1234567890')).toBe('0x1234567890'); + }); +}); + +describe('sameAccount', () => { + const EVM = '0xAAAAbbbbCCCCddddEEEEffff0000111122223333'; + + // EVM addresses are case-insensitive, and the backend stores them folded while a + // wallet reports them checksummed — so an exact comparison would never match. + it('treats EVM addresses as equal regardless of case', () => { + expect(sameAccount(EVM, EVM.toLowerCase())).toBe(true); + expect(sameAccount(EVM.toLowerCase(), EVM.toUpperCase().replace('0X', '0x'))).toBe(true); + }); + + it('separates different EVM addresses', () => { + expect(sameAccount(EVM, '0x0000000000000000000000000000000000000000')).toBe(false); + }); + + // The reason this is not `toLowerCase()`: base58 is case-*significant*, so two + // distinct Solana pubkeys can differ only in case and must not read as one player. + it('does not fold base58 pubkeys', () => { + expect(sameAccount('SoLpubkey11111111111111111111111111111111111', 'solpubkey11111111111111111111111111111111111')).toBe(false); + }); + + it('matches an identical Solana pubkey', () => { + const key = 'SoLpubkey11111111111111111111111111111111111'; + expect(sameAccount(key, key)).toBe(true); + }); + + // A disconnected wallet is the empty string; nothing should light up as "you". + it('never matches an empty address', () => { + expect(sameAccount('', '')).toBe(false); + expect(sameAccount(EVM, '')).toBe(false); + }); +}); diff --git a/frontend/tsconfig.app.json b/frontend/tsconfig.app.json index 13fd250b..cf67d2b5 100644 --- a/frontend/tsconfig.app.json +++ b/frontend/tsconfig.app.json @@ -27,7 +27,8 @@ "@router": ["./src/router/index.ts"], "@router/*": ["./src/router/*"], "@shared/core": ["../shared/src/index.ts"], - "@styles/*": ["./src/styles/*"] + "@styles/*": ["./src/styles/*"], + "@utils/*": ["./src/utils/*"] }, /* Linting */ diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 9144c9c4..564bf4fd 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -14,6 +14,7 @@ const aliases = { '@pages': 'src/pages', '@router': 'src/router', '@styles': 'src/styles', + '@utils': 'src/utils', } as const; // https://vite.dev/config/ diff --git a/services/indexer-go/internal/evm/indexer.go b/services/indexer-go/internal/evm/indexer.go index 20fa0e86..f6b0490d 100644 --- a/services/indexer-go/internal/evm/indexer.go +++ b/services/indexer-go/internal/evm/indexer.go @@ -149,29 +149,32 @@ func (ix *Indexer) Run(ctx context.Context, roster chan<- indexer.RosterUpdate) reconcileC = reconcileTicker.C } + // Shared so the clean-shutdown discrimination lives in one place: a cancelled context + // surfaces as an error from the in-flight request, and treating that as a failure logs + // a spurious error on every shutdown that races a poll. Reports false to stop. + report := func(label string, count int, err error) bool { + switch { + case err != nil && ctx.Err() != nil: + return false + case err != nil: + slog.Error(label+" failed", "err", err) + case count > 0: + slog.Info(label, "count", count, "watermark", ix.watermark) + } + return true + } + for { select { case <-ctx.Done(): return nil case <-ticker.C: - synced, err := ix.sync(ctx, roster) - switch { - case err != nil && ctx.Err() != nil: + if synced, err := ix.sync(ctx, roster); !report("evm sync", synced, err) { return nil - case err != nil: - slog.Error("evm sync failed", "err", err) - case synced > 0: - slog.Info("evm sync", "synced", synced, "watermark", ix.watermark) } case <-reconcileC: - scanned, err := ix.Scan(ctx, roster) - switch { - case err != nil && ctx.Err() != nil: + if scanned, err := ix.Scan(ctx, roster); !report("evm reconcile scan", scanned, err) { return nil - case err != nil: - slog.Error("evm reconcile scan failed", "err", err) - default: - slog.Info("evm reconcile scan", "scanned", scanned, "watermark", ix.watermark) } } } diff --git a/shared/src/hooks/chat/useChatMessages.ts b/shared/src/hooks/chat/useChatMessages.ts index 8a28e5d0..124df193 100644 --- a/shared/src/hooks/chat/useChatMessages.ts +++ b/shared/src/hooks/chat/useChatMessages.ts @@ -2,7 +2,7 @@ import { useCallback } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useApiClient } from '../../contexts/ApiClientContext'; import { useAuth } from '../../contexts/AuthContext'; -import { useChatThreadSocket } from './useChatThreadSocket'; +import { useChatThreadSocket, type ChatThreadNotification } from './useChatThreadSocket'; export interface ChatMessage { id: number; @@ -69,24 +69,55 @@ export const useChatMessages = ({ }, }); + // Rebuilds the key inside rather than closing over the outer array, whose identity + // changes every render — that is what previously needed an exhaustive-deps + // suppression, and a suppression here would be permanent: this callback is wired to + // the socket, the reconnect path and mutation success. const refresh = useCallback(() => { - void queryClient.invalidateQueries({ queryKey }); - // `queryKey` is rebuilt each render; its contents are what identify the query. - // eslint-disable-next-line react-hooks/exhaustive-deps + void queryClient.invalidateQueries({ queryKey: chatMessagesQueryKey(baseURL, threadId) }); }, [queryClient, baseURL, threadId]); + // A frame naming a message already in the cache is the echo of our own send, which + // `onSuccess` has already applied — re-reading fifty messages to learn nothing. + const onNotification = useCallback( + (message: ChatThreadNotification) => { + const cached = queryClient.getQueryData( + chatMessagesQueryKey(baseURL, threadId), + ); + if (cached?.some((entry) => entry.id === message.messageId)) return; + refresh(); + }, + [queryClient, baseURL, threadId, refresh], + ); + const { connected } = useChatThreadSocket({ url: socketUrl, threadId, - onNotification: refresh, + onNotification, onReconnect: refresh, }); const mutation = useMutation({ mutationFn: async (text: string) => { - await apiClient.post(`/api/chat/threads/${threadId}/messages`, { text }); + const { data } = await apiClient.post<{ message: ChatMessage }>( + `/api/chat/threads/${threadId}/messages`, + { text }, + ); + return data.message; + }, + // Appends the row the server just confirmed rather than invalidating. This is not + // an optimistic update — the message exists — so the objection to optimism (a + // refused send must not look delivered) does not apply, and it saves a full page + // re-read per message sent. + onSuccess: (message) => { + queryClient.setQueryData( + chatMessagesQueryKey(baseURL, threadId), + (previous) => + previous?.some((entry) => entry.id === message.id) + ? previous + : [...(previous ?? []), message], + ); }, - onSuccess: refresh, }); const send = useCallback( diff --git a/shared/src/utils/pets/index.ts b/shared/src/utils/pets/index.ts index 5af877c3..4f40774d 100644 --- a/shared/src/utils/pets/index.ts +++ b/shared/src/utils/pets/index.ts @@ -5,3 +5,13 @@ export { getPetSkill, type PetSkill } from './skills'; export { petArtUrl, type PetArtIdentity } from './petArtUrl'; export { getReadyPets as getReadyPetsUnified, type ReadyPet } from './readyPets'; export { NoActiveChainError } from './errors'; + +/** + * Canonical wallet-address normalization, re-exported from the MIT protocol package so + * clients compare accounts the same way the backend groups and hashes them. + * + * Shape-based, so it needs no chain argument: EVM addresses fold to lowercase, base58 + * Solana pubkeys pass through untouched. Comparing two accounts with `toLowerCase()` + * instead would let two distinct Solana pubkeys read as the same player. + */ +export { normalizeAccount } from '@cryptopets/protocol'; From 9050accc56b517507e0a8e42cd3a202727902270 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 12:11:13 -0400 Subject: [PATCH 18/61] fix(web): repair the app favicon and give the website one at all --- frontend/public/favicon.svg | 9 +++++-- website/src/app/icon.svg | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 website/src/app/icon.svg diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg index 886f4c99..9cd9b6f1 100644 --- a/frontend/public/favicon.svg +++ b/frontend/public/favicon.svg @@ -35,8 +35,13 @@ + "strong" ends of each token (cp-cyan-strong, cp-violet-strong, + cp-magenta-strong), which is what holds up unbacked on a light tab. + + Those token names are written without their leading dashes on purpose: + an XML comment may not contain a double hyphen anywhere, so spelling + them out as CSS custom properties makes the whole file malformed and + every browser silently falls back to the default icon. --> diff --git a/website/src/app/icon.svg b/website/src/app/icon.svg new file mode 100644 index 00000000..9cd9b6f1 --- /dev/null +++ b/website/src/app/icon.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + From 074d584b623f17b2f0610e94348dcdc3fc646296 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 13:02:38 -0400 Subject: [PATCH 19/61] fix(backend): serve both WebSocket channels from one upgrade listener --- backend/src/server.ts | 17 +- backend/src/ws/battleRoomSocket.ts | 103 +++--------- backend/src/ws/channel.ts | 153 ++++++++++++++++++ backend/src/ws/chatSocket.ts | 105 +++--------- backend/tests/ws/battleRoomSocket.test.ts | 26 +-- backend/tests/ws/channel.test.ts | 94 +++++++++++ backend/tests/ws/chatSocket.test.ts | 21 ++- frontend/src/components/chat/index.module.css | 21 ++- 8 files changed, 341 insertions(+), 199 deletions(-) create mode 100644 backend/src/ws/channel.ts create mode 100644 backend/tests/ws/channel.test.ts diff --git a/backend/src/server.ts b/backend/src/server.ts index 9a3e2d36..b5cef047 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -6,8 +6,7 @@ import { configureSigner, loadPersistedSigningKeys } from '@features/battle-sign import { startSettleKeeper, stopSettleKeeper } from '@features/settle-keeper'; import { type BattleWorkerHandle, startBattleWorker } from '@features/battle-worker'; import { startBatchAnchor, stopBatchAnchor } from '@features/battle-anchor'; -import { startBattleRoomSocket, stopBattleRoomSocket } from '@ws/battleRoomSocket'; -import { startChatSocket, stopChatSocket } from '@ws/chatSocket'; +import { startWsChannels, stopWsChannels } from '@ws/channel'; let battleWorker: BattleWorkerHandle | undefined; @@ -21,13 +20,10 @@ const server = app.listen(env.port, '0.0.0.0', () => { console.log(`🛡️ Protected endpoints: http://localhost:${port}/api/protected`); console.log(`⚔️ GraphQL endpoint: http://localhost:${port}/graphql`); - // Notification-only per-room channel for backend-authoritative battles (§J). Always on; - // a client only gets pushed to if it connected with a roomId it already knows about. - startBattleRoomSocket(server); - // Per-thread notification channel for private chat. Same posture as the battle room: - // it says a thread changed and nothing more, so the authenticated read stays the only - // thing that decides who sees a message. - startChatSocket(server); + // Every notification-only channel (battle rooms §J, chat §2) behind one upgrade + // listener. They cannot each attach their own: Node would call all of them per + // upgrade and every connection would be handled twice — see @ws/channel. + startWsChannels(server); // Settles GameLogic battle/breed/mint requests once entropy reveals. No-op unless // KEEPER_ENABLED is set. startSettleKeeper(); @@ -81,8 +77,7 @@ async function shutdown(signal: NodeJS.Signals): Promise { stopSettleKeeper(); battleWorker?.stop(); stopBatchAnchor(); - stopBattleRoomSocket(); - stopChatSocket(); + stopWsChannels(); await new Promise((resolve) => server.close(() => resolve())); await prisma.$disconnect(); diff --git a/backend/src/ws/battleRoomSocket.ts b/backend/src/ws/battleRoomSocket.ts index b38af8dc..64fb79a3 100644 --- a/backend/src/ws/battleRoomSocket.ts +++ b/backend/src/ws/battleRoomSocket.ts @@ -1,27 +1,23 @@ -import type { Server } from 'node:http'; -import { URL } from 'node:url'; - -// `WebSocket.Server` is only attached to the default export under `ws`'s CJS entry point; -// its ESM entry (`wrapper.mjs`, what Vitest resolves) exports the server class only as the -// named `WebSocketServer`, with no `.Server` static property. The named form resolves -// correctly under both, so it's used here instead. -import WebSocket, { WebSocketServer } from 'ws'; +import { defineChannel } from './channel'; /** * The per-room, notification-only channel for backend-authoritative battles * (docs/battle-protocol.md §J). * - * It replaced a global-broadcast socket that pushed chain-derived data for the - * on-chain flow, filtered client-side by `(chainId, requestId)`. Broadcasting was - * acceptable there because anyone could read the same data straight off the chain - * anyway. Backend-resolved battles carry full combat logs, which is not chain-derived - * data — a global broadcast would tell every connected client the outcome of every - * battle as it resolves. So this channel scopes delivery to one room, and carries - * no battle content at all: - * only "battleId X changed to state Y, go re-fetch it" (§J's read APIs, Step - * 27). A client that missed a notification, or was never connected, gets the - * exact same information by polling those same endpoints — this socket makes - * that faster, never more authoritative. + * It replaced a global-broadcast socket that pushed chain-derived data for the on-chain + * flow, filtered client-side by `(chainId, requestId)`. Broadcasting was acceptable there + * because anyone could read the same data straight off the chain anyway. + * Backend-resolved battles carry full combat logs, which is not chain-derived data — a + * global broadcast would tell every connected client the outcome of every battle as it + * resolves. So this channel scopes delivery to one room, and carries no battle content at + * all: only "battleId X changed to state Y, go re-fetch it" (§J's read APIs, Step 27). A + * client that missed a notification, or was never connected, gets the exact same + * information by polling those same endpoints — this socket makes that faster, never more + * authoritative. + * + * Membership and the HTTP upgrade are handled by `channel.ts`, which owns the single + * upgrade listener the process may have; see the note there for why one per channel is + * not an option. */ export interface BattleRoomNotification { @@ -30,72 +26,17 @@ export interface BattleRoomNotification { state: string; } -let wss: WebSocketServer | null = null; -const roomMembers = new Map>(); - -export function startBattleRoomSocket(server: Server): void { - wss = new WebSocketServer({ server, path: '/ws/battle-room' }); - wss.on('connection', (socket, request) => { - const roomId = roomIdFromUrl(request.url); - if (!roomId) { - socket.close(1008, 'roomId query parameter is required'); - return; - } - joinRoom(roomId, socket); - socket.on('close', () => leaveRoom(roomId, socket)); - }); - console.log('[battle-room-ws] listening on /ws/battle-room'); -} +const channel = defineChannel('/ws/battle-room', 'roomId'); -export function stopBattleRoomSocket(): void { - wss?.close(); - wss = null; - roomMembers.clear(); -} - -/** - * Notifies every client watching `roomId`. A no-op, not an error, when nobody - * is connected — most battles are never watched live at all, and that is an - * entirely normal outcome, not a delivery failure worth surfacing. - */ +/** Notifies every client watching `roomId`. */ export function notifyBattleRoom(roomId: string, message: BattleRoomNotification): void { - const members = roomMembers.get(roomId); - if (!members || members.size === 0) return; - const payload = JSON.stringify(message); - for (const client of members) { - if (client.readyState === WebSocket.OPEN) client.send(payload); - } + channel.notify(roomId, message); } /** Same as `notifyBattleRoom`, but a no-op when there is no room to notify at all. */ -export function notifyBattleRoomIfPresent(roomId: string | null, message: BattleRoomNotification): void { +export function notifyBattleRoomIfPresent( + roomId: string | null, + message: BattleRoomNotification +): void { if (roomId) notifyBattleRoom(roomId, message); } - -function joinRoom(roomId: string, socket: WebSocket): void { - let members = roomMembers.get(roomId); - if (!members) { - members = new Set(); - roomMembers.set(roomId, members); - } - members.add(socket); -} - -function leaveRoom(roomId: string, socket: WebSocket): void { - const members = roomMembers.get(roomId); - if (!members) return; - members.delete(socket); - if (members.size === 0) roomMembers.delete(roomId); -} - -function roomIdFromUrl(url: string | undefined): string | null { - if (!url) return null; - try { - // The base is irrelevant and discarded — only used because WHATWG URL requires - // an absolute URL to parse a relative one against. - const parsed = new URL(url, 'http://internal'); - return parsed.searchParams.get('roomId'); - } catch { - return null; - } -} diff --git a/backend/src/ws/channel.ts b/backend/src/ws/channel.ts new file mode 100644 index 00000000..e69fd824 --- /dev/null +++ b/backend/src/ws/channel.ts @@ -0,0 +1,153 @@ +import type { IncomingMessage, Server } from 'node:http'; +import type { Duplex } from 'node:stream'; +import { URL } from 'node:url'; + +// Named import for the same reason the channels use one: `ws`'s ESM entry exposes the +// server class only as `WebSocketServer`, with no `.Server` static. +import WebSocket, { WebSocketServer } from 'ws'; + +/** + * One upgrade listener for every WebSocket channel this process serves. + * + * This exists because the obvious arrangement is broken. Constructing a + * `WebSocketServer({ server, path })` per channel attaches *one upgrade listener per + * instance* to the same HTTP server, and Node calls all of them for every upgrade — so + * with two channels each connection is handled twice, the client receives two HTTP 101 + * responses, and the second one is parsed as a WebSocket frame. The visible symptom is + * `RangeError: Invalid WebSocket frame: RSV1 must be clear`, and it takes down *both* + * channels, not just the one added second. + * + * So the servers are constructed with `noServer: true` and this module owns the single + * listener, dispatching on path. That is what the `ws` documentation recommends for + * exactly this case. + * + * Every channel is notification-only by construction (see the two that use it): a frame + * says "this thing changed, re-read it" and carries no content, which is what makes an + * unauthenticated socket acceptable. A channel that ever wants to push content needs + * authentication in `handleUpgrade` first. + */ + +interface Channel { + /** Path this channel answers on, e.g. `/ws/chat`. */ + path: string; + /** Query parameter naming the topic a client subscribes to, e.g. `threadId`. */ + param: string; + /** topic → connected sockets. */ + members: Map>; + wss: WebSocketServer | null; +} + +const channels: Channel[] = []; + +/** A channel handle: register once at module load, start with the HTTP server later. */ +export interface ChannelHandle { + /** + * Sends a message to everyone subscribed to `topic`. + * + * A no-op when nobody is listening, which is the normal case rather than a failure: + * most notifications concern someone who does not have the app open. Delivery here is + * an optimization over re-reading, never the authority for it. + */ + notify(topic: string, message: unknown): void; +} + +export function defineChannel(path: string, param: string): ChannelHandle { + const channel: Channel = { path, param, members: new Map(), wss: null }; + channels.push(channel); + + return { + notify(topic, message) { + const listeners = channel.members.get(topic); + if (!listeners || listeners.size === 0) return; + const payload = JSON.stringify(message); + for (const client of listeners) { + if (client.readyState === WebSocket.OPEN) client.send(payload); + } + }, + }; +} + +/** The server and listener currently attached, so `stop` can detach precisely. */ +let attached: { server: Server; onUpgrade: UpgradeListener } | null = null; + +type UpgradeListener = (request: IncomingMessage, socket: Duplex, head: Buffer) => void; + +/** Starts every defined channel against one HTTP server. */ +export function startWsChannels(server: Server): void { + // Starting twice would attach a second listener and reintroduce the double-handled + // upgrade this module exists to prevent, so the previous one is always detached first. + stopWsChannels(); + + for (const channel of channels) { + channel.wss = new WebSocketServer({ noServer: true }); + channel.wss.on('connection', (socket: WebSocket, _req: IncomingMessage, topic: string) => { + join(channel, topic, socket); + socket.on('close', () => leave(channel, topic, socket)); + }); + } + + const onUpgrade: UpgradeListener = (request, socket, head) => { + const url = parseUrl(request.url); + const channel = url ? channels.find((candidate) => candidate.path === url.pathname) : undefined; + if (!url || !channel?.wss) { + // Not ours. Destroying rather than ignoring, because with a single listener + // there is nobody else to answer and a hanging socket would leak. + socket.destroy(); + return; + } + + const topic = url.searchParams.get(channel.param); + if (!topic) { + // Refused before the handshake: a client that names no topic would otherwise + // sit connected receiving nothing, which reads as a silent failure. + socket.destroy(); + return; + } + + channel.wss.handleUpgrade(request, socket, head, (ws) => { + channel.wss?.emit('connection', ws, request, topic); + }); + }; + + server.on('upgrade', onUpgrade); + attached = { server, onUpgrade }; + + console.log(`[ws] listening on ${channels.map((c) => c.path).join(', ')}`); +} + +export function stopWsChannels(): void { + attached?.server.off('upgrade', attached.onUpgrade); + attached = null; + + for (const channel of channels) { + channel.wss?.close(); + channel.wss = null; + channel.members.clear(); + } +} + +function join(channel: Channel, topic: string, socket: WebSocket): void { + let listeners = channel.members.get(topic); + if (!listeners) { + listeners = new Set(); + channel.members.set(topic, listeners); + } + listeners.add(socket); +} + +function leave(channel: Channel, topic: string, socket: WebSocket): void { + const listeners = channel.members.get(topic); + if (!listeners) return; + listeners.delete(socket); + if (listeners.size === 0) channel.members.delete(topic); +} + +function parseUrl(url: string | undefined): URL | null { + if (!url) return null; + try { + // The base is discarded; WHATWG URL just needs an absolute one to parse against. + return new URL(url, 'http://internal'); + } catch { + return null; + } +} diff --git a/backend/src/ws/chatSocket.ts b/backend/src/ws/chatSocket.ts index a8d5771e..446d46bd 100644 --- a/backend/src/ws/chatSocket.ts +++ b/backend/src/ws/chatSocket.ts @@ -1,36 +1,26 @@ -import type { Server } from 'node:http'; -import { URL } from 'node:url'; - -// Named import for the same reason `battleRoomSocket` uses one: `ws`'s ESM entry exposes -// the server class only as `WebSocketServer`, with no `.Server` static. -import WebSocket, { WebSocketServer } from 'ws'; +import { defineChannel } from './channel'; /** * The per-thread notification channel for private chat (roadmap §2 v1). * * **Carries no message content, deliberately.** The roadmap assumed chat could reuse an - * authenticated socket; there isn't one. `battleRoomSocket` — the channel §2 pointed at, - * under its old name — takes an id from the query string and joins whoever asks, which - * is fine for battle updates because those carry nothing a client could not re-fetch - * anyway. Pushing message text down a channel like that would hand private conversations - * to anyone holding a thread id. + * authenticated socket; there isn't one. The battle-room channel takes an id from the + * query string and joins whoever asks, which is fine there because those notifications + * carry nothing a client could not re-fetch anyway. Pushing message text down a channel + * like that would hand private conversations to anyone holding a thread id. * * So this keeps the same posture and inherits its safety from it: the socket only ever - * says "thread X changed", and the content comes from `GET /api/chat/threads/:id/messages`, - * which authenticates the caller and rechecks the marriage. A client that missed a - * notification, or never connected at all, learns exactly the same thing by re-reading. - * This makes chat feel live; it is never the thing that decides who may read it. - * - * What a listener does learn is *timing* — that a thread they know the id of had activity. - * Thread ids are cuids handed out only by an authenticated read, so that requires already - * having been told one. If v2 opens direct messages to strangers, this channel should gain - * real authentication before it does, and the token belongs in a subprotocol rather than - * the query string, where proxies and access logs would record it. + * says "thread X changed", and the content comes from + * `GET /api/chat/threads/:id/messages`, which authenticates the caller and rechecks the + * marriage. A client that missed a notification, or never connected at all, learns + * exactly the same thing by re-reading. This makes chat feel live; it is never the thing + * that decides who may read it. * - * Deliberately a separate file from `battleRoomSocket` rather than a shared abstraction - * over the two. The membership bookkeeping is the same today, but the two channels are - * heading different places — this one needs per-listener authorization the moment its - * scope widens, and that is exactly the seam a premature shared helper would fuse shut. + * What a listener does learn is *timing* — that a thread they know the id of had + * activity. Thread ids are cuids handed out only by an authenticated read, so that + * requires already having been told one. If v2 opens direct messages to strangers, this + * channel should gain real authentication before it does, and the token belongs in a + * subprotocol rather than the query string, where proxies and access logs would record it. */ export interface ChatThreadNotification { @@ -40,68 +30,9 @@ export interface ChatThreadNotification { messageId: number; } -let wss: WebSocketServer | null = null; -const threadListeners = new Map>(); - -export function startChatSocket(server: Server): void { - wss = new WebSocketServer({ server, path: '/ws/chat' }); - wss.on('connection', (socket, request) => { - const threadId = threadIdFromUrl(request.url); - if (!threadId) { - socket.close(1008, 'threadId query parameter is required'); - return; - } - join(threadId, socket); - socket.on('close', () => leave(threadId, socket)); - }); - console.log('[chat-ws] listening on /ws/chat'); -} - -export function stopChatSocket(): void { - wss?.close(); - wss = null; - threadListeners.clear(); -} +const channel = defineChannel('/ws/chat', 'threadId'); -/** - * Tells everyone watching `threadId` that it changed. - * - * A no-op when nobody is listening, which is the normal case: most messages are sent to - * someone who is not looking at the app. Delivery here is an optimization, so a missed - * notification is not a failure worth surfacing — the recipient sees the message on their - * next read either way. - */ +/** Tells everyone watching `threadId` that it changed. */ export function notifyChatThread(threadId: string, message: ChatThreadNotification): void { - const listeners = threadListeners.get(threadId); - if (!listeners || listeners.size === 0) return; - const payload = JSON.stringify(message); - for (const client of listeners) { - if (client.readyState === WebSocket.OPEN) client.send(payload); - } -} - -function join(threadId: string, socket: WebSocket): void { - let listeners = threadListeners.get(threadId); - if (!listeners) { - listeners = new Set(); - threadListeners.set(threadId, listeners); - } - listeners.add(socket); -} - -function leave(threadId: string, socket: WebSocket): void { - const listeners = threadListeners.get(threadId); - if (!listeners) return; - listeners.delete(socket); - if (listeners.size === 0) threadListeners.delete(threadId); -} - -function threadIdFromUrl(url: string | undefined): string | null { - if (!url) return null; - try { - // The base is discarded; WHATWG URL just needs an absolute one to parse against. - return new URL(url, 'http://internal').searchParams.get('threadId'); - } catch { - return null; - } + channel.notify(threadId, message); } diff --git a/backend/tests/ws/battleRoomSocket.test.ts b/backend/tests/ws/battleRoomSocket.test.ts index c5f85024..1f0b7680 100644 --- a/backend/tests/ws/battleRoomSocket.test.ts +++ b/backend/tests/ws/battleRoomSocket.test.ts @@ -2,12 +2,9 @@ import { createServer, type Server } from 'node:http'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import WebSocket from 'ws'; -import { - notifyBattleRoom, - notifyBattleRoomIfPresent, - startBattleRoomSocket, - stopBattleRoomSocket, -} from '@ws/battleRoomSocket'; +import '@ws/chatSocket'; // registers the other channel, as the real server does +import { notifyBattleRoom, notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; +import { startWsChannels, stopWsChannels } from '@ws/channel'; /** * Real HTTP server + real `ws` clients, not mocks: the property under test is @@ -21,7 +18,7 @@ let baseUrl: string; beforeEach(async () => { server = createServer(); - startBattleRoomSocket(server); + startWsChannels(server); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); const address = server.address(); if (address === null || typeof address === 'string') { @@ -31,7 +28,7 @@ beforeEach(async () => { }); afterEach(async () => { - stopBattleRoomSocket(); + stopWsChannels(); await new Promise((resolve) => server.close(() => resolve())); }); @@ -113,10 +110,15 @@ describe('room scoping', () => { }); describe('connection requirements', () => { - it('closes the connection when roomId is missing', async () => { + it('refuses the connection when roomId is missing', async () => { + // Refused at the upgrade now, so this is a transport error rather than a close + // code — see the equivalent note in chatSocket.test.ts. const socket = new WebSocket(baseUrl); - const closed = nextClose(socket); - const { code } = await closed; - expect(code).toBe(1008); + const outcome = await new Promise((resolve) => { + socket.once('open', () => resolve('open')); + socket.once('error', () => resolve('refused')); + socket.once('close', () => resolve('refused')); + }); + expect(outcome).toBe('refused'); }); }); diff --git a/backend/tests/ws/channel.test.ts b/backend/tests/ws/channel.test.ts new file mode 100644 index 00000000..9a8d2130 --- /dev/null +++ b/backend/tests/ws/channel.test.ts @@ -0,0 +1,94 @@ +import { createServer, type Server } from 'node:http'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import WebSocket from 'ws'; + +import { notifyBattleRoom } from '@ws/battleRoomSocket'; +import { notifyChatThread } from '@ws/chatSocket'; +import { startWsChannels, stopWsChannels } from '@ws/channel'; + +/** + * The case the per-channel tests cannot see: both channels on **one** HTTP server, which + * is what the real process runs. + * + * Each channel used to construct its own `WebSocketServer({ server, path })`, which + * attaches one upgrade listener per instance. Node calls every listener for every + * upgrade, so with two channels each connection was handled twice, the client received + * two HTTP 101 responses, and the second was parsed as a frame — + * `RangeError: Invalid WebSocket frame: RSV1 must be clear`. It broke *both* channels, + * and every existing test passed because each gave its socket a private server. + */ + +let server: Server; +let base: string; + +beforeEach(async () => { + server = createServer(); + startWsChannels(server); + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); + const address = server.address(); + if (address === null || typeof address === 'string') { + throw new Error('expected a bound TCP address'); + } + base = `ws://127.0.0.1:${address.port}`; +}); + +afterEach(async () => { + stopWsChannels(); + await new Promise((resolve) => server.close(() => resolve())); +}); + +function open(url: string): Promise { + return new Promise((resolve, reject) => { + const socket = new WebSocket(url); + socket.once('open', () => resolve(socket)); + socket.once('error', reject); + }); +} + +function nextMessage(socket: WebSocket): Promise { + return new Promise((resolve, reject) => { + socket.once('message', (data) => resolve(JSON.parse(data.toString()))); + socket.once('error', reject); + socket.once('close', (code) => reject(new Error(`closed before a message: ${code}`))); + }); +} + +describe('two channels on one server', () => { + it('accepts a connection on each path', async () => { + const room = await open(`${base}/ws/battle-room?roomId=r1`); + const chat = await open(`${base}/ws/chat?threadId=t1`); + + expect(room.readyState).toBe(WebSocket.OPEN); + expect(chat.readyState).toBe(WebSocket.OPEN); + + room.close(); + chat.close(); + }); + + it('delivers each channel its own traffic and never the other channel traffic', async () => { + const room = await open(`${base}/ws/battle-room?roomId=r1`); + const chat = await open(`${base}/ws/chat?threadId=t1`); + const roomMessage = nextMessage(room); + const chatMessage = nextMessage(chat); + + notifyChatThread('t1', { type: 'thread-updated', threadId: 't1', messageId: 1 }); + notifyBattleRoom('r1', { type: 'battle-updated', battleId: 'b1', state: 'signed' }); + + // Each listener's first frame must be its own channel's: if the chat notification + // reached the room listener, this resolves to the wrong shape rather than timing + // out, so the assertion catches cross-talk directly. + await expect(chatMessage).resolves.toMatchObject({ type: 'thread-updated' }); + await expect(roomMessage).resolves.toMatchObject({ type: 'battle-updated' }); + + room.close(); + chat.close(); + }); + + it('refuses an unknown path without disturbing the known ones', async () => { + await expect(open(`${base}/ws/nope?roomId=r1`)).rejects.toThrow(); + + const chat = await open(`${base}/ws/chat?threadId=t1`); + expect(chat.readyState).toBe(WebSocket.OPEN); + chat.close(); + }); +}); diff --git a/backend/tests/ws/chatSocket.test.ts b/backend/tests/ws/chatSocket.test.ts index c271cfcc..0dbb4574 100644 --- a/backend/tests/ws/chatSocket.test.ts +++ b/backend/tests/ws/chatSocket.test.ts @@ -2,7 +2,9 @@ import { createServer, type Server } from 'node:http'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import WebSocket from 'ws'; -import { notifyChatThread, startChatSocket, stopChatSocket } from '@ws/chatSocket'; +import '@ws/battleRoomSocket'; // registers the other channel, as the real server does +import { notifyChatThread } from '@ws/chatSocket'; +import { startWsChannels, stopWsChannels } from '@ws/channel'; /** * Real server and real clients, because the property under test is delivery over the @@ -16,7 +18,7 @@ let baseUrl: string; beforeEach(async () => { server = createServer(); - startChatSocket(server); + startWsChannels(server); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); const address = server.address(); if (address === null || typeof address === 'string') { @@ -26,7 +28,7 @@ beforeEach(async () => { }); afterEach(async () => { - stopChatSocket(); + stopWsChannels(); await new Promise((resolve) => server.close(() => resolve())); }); @@ -118,8 +120,17 @@ describe('thread scoping', () => { }); describe('connection requirements', () => { - it('closes a connection that names no thread', async () => { + it('refuses a connection that names no thread', async () => { + // Refused at the upgrade, before a WebSocket exists, so this surfaces as a + // transport error rather than a close code. Failing here rather than accepting a + // subscriber to nothing is the point: the latter looks connected and never + // delivers. const socket = new WebSocket(baseUrl); - expect(await nextClose(socket)).toBe(1008); + const outcome = await new Promise((resolve) => { + socket.once('open', () => resolve('open')); + socket.once('error', () => resolve('refused')); + socket.once('close', () => resolve('refused')); + }); + expect(outcome).toBe('refused'); }); }); diff --git a/frontend/src/components/chat/index.module.css b/frontend/src/components/chat/index.module.css index 0aa0368e..f90bb9be 100644 --- a/frontend/src/components/chat/index.module.css +++ b/frontend/src/components/chat/index.module.css @@ -1,10 +1,17 @@ /* CSS Module — class names are local; reference via `import styles from './index.module.css'`. Private chat: thread rail plus one conversation, magenta accent to match marriage. */ +/* Fills the panel body instead of sizing to its content. Every ancestor from the app + shell down is already a flex column that owns the viewport height, so the conversation + should end at the bottom of the panel's padding rather than at a fixed height with + dead space beneath it. `min-height: 0` is what lets the transcript scroll inside + rather than pushing the composer past the bottom edge. */ .layout { display: grid; grid-template-columns: minmax(0, 240px) minmax(0, 1fr); gap: 14px; - align-items: start; + flex: 1; + min-height: 0; + align-items: stretch; } .threadList { @@ -14,6 +21,10 @@ display: flex; flex-direction: column; gap: 6px; + /* Scrolls on its own so a long thread list cannot stretch the row and push the + conversation off the bottom. */ + min-height: 0; + overflow-y: auto; } .threadButton { @@ -54,7 +65,7 @@ display: flex; flex-direction: column; min-width: 0; - height: 460px; + min-height: 0; border-radius: 10px; border: 1px solid rgb(148 163 184 / 14%); background: var(--cp-surface); @@ -174,14 +185,18 @@ } @media (width <= 720px) { - /* The rail becomes a strip above the conversation; two columns leave neither usable. */ + /* The rail becomes a strip above the conversation; two columns leave neither usable. + Rows are declared so the conversation still takes the remaining height rather than + splitting it evenly with the strip. */ .layout { grid-template-columns: minmax(0, 1fr); + grid-template-rows: auto minmax(0, 1fr); } .threadList { flex-direction: row; overflow-x: auto; + overflow-y: visible; } .threadButton { From c264d58386237fbcf266f15bad51d5941340f49c Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 13:10:52 -0400 Subject: [PATCH 20/61] fix(frontend): give the messaging panel real full-screen height --- frontend/src/components/chat/index.module.css | 15 +++++++++++++++ frontend/src/components/chat/index.tsx | 1 + 2 files changed, 16 insertions(+) diff --git a/frontend/src/components/chat/index.module.css b/frontend/src/components/chat/index.module.css index f90bb9be..b76fcc7a 100644 --- a/frontend/src/components/chat/index.module.css +++ b/frontend/src/components/chat/index.module.css @@ -1,5 +1,20 @@ /* CSS Module — class names are local; reference via `import styles from './index.module.css'`. Private chat: thread rail plus one conversation, magenta accent to match marriage. */ + +/* The messaging panel is the one screen that should end at the bottom of the window + rather than at the bottom of its content. + + `height: 100%` and not a flex rule: the shell's content slot is a scrollable *block* + (`overflow: auto`, no `display: flex`), so a `flex` declaration on the panel is inert + and it just sizes to its children. The slot does have a definite height — it is a + flex item of the shell's column — so a percentage resolves against it, and it resolves + against the slot's *content box*, which is why the panel lands inside the shell's + padding instead of overflowing it. Everything below here is a flex column already, so + the height flows down to the transcript on its own. */ +.page { + height: 100%; +} + /* Fills the panel body instead of sizing to its content. Every ancestor from the app shell down is already a flex column that owns the viewport height, so the conversation should end at the bottom of the panel's padding rather than at a fixed height with diff --git a/frontend/src/components/chat/index.tsx b/frontend/src/components/chat/index.tsx index 5e848d74..2dc216b7 100644 --- a/frontend/src/components/chat/index.tsx +++ b/frontend/src/components/chat/index.tsx @@ -183,6 +183,7 @@ const Chat: React.FC = () => { return ( From 233aba71e1ade1ab43ce8ad88b17facda0597941 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 13:23:40 -0400 Subject: [PATCH 21/61] fix(frontend): give the leaderboard panel full-screen height --- .../components/leaderboard/index.module.css | 20 +++++++++++++++++++ frontend/src/components/leaderboard/index.tsx | 1 + 2 files changed, 21 insertions(+) diff --git a/frontend/src/components/leaderboard/index.module.css b/frontend/src/components/leaderboard/index.module.css index cd53e4bc..5a30f08e 100644 --- a/frontend/src/components/leaderboard/index.module.css +++ b/frontend/src/components/leaderboard/index.module.css @@ -1,9 +1,23 @@ /* CSS Module — class names are local; reference via `import styles from './index.module.css'`. Leaderboard: a read-only ranking table, amber accent to match the trophy. */ + +/* Ends at the bottom of the window rather than at the bottom of its rows, so the pager + stays reachable without scrolling the page and short pages leave no dead space. + + `height: 100%` rather than a flex rule, for the reason spelled out in the chat panel's + stylesheet: the shell's content slot is a scrollable *block*, so a `flex` declaration + on the panel is inert. The percentage resolves against the slot's content box, which + is what keeps the panel inside the shell's padding. */ +.page { + height: 100%; +} + .tabs { display: flex; gap: 8px; margin-bottom: 14px; + /* Header-ish: never absorbs the space the list should get. */ + flex-shrink: 0; } .tab { @@ -29,6 +43,8 @@ background: rgb(251 191 36 / 12%); } +/* The one part that scrolls. Everything else in the panel keeps its natural height, so + the pager stays pinned below the rows instead of being pushed off the bottom. */ .list { list-style: none; margin: 0; @@ -36,6 +52,9 @@ display: flex; flex-direction: column; gap: 6px; + flex: 1; + min-height: 0; + overflow-y: auto; } /* Fixed track widths so ranks, records and rates line up down the column; only the @@ -112,6 +131,7 @@ justify-content: center; gap: 14px; margin-top: 16px; + flex-shrink: 0; } .pager button { diff --git a/frontend/src/components/leaderboard/index.tsx b/frontend/src/components/leaderboard/index.tsx index 6b0bf75f..78984046 100644 --- a/frontend/src/components/leaderboard/index.tsx +++ b/frontend/src/components/leaderboard/index.tsx @@ -126,6 +126,7 @@ const Leaderboard: React.FC = () => { return ( From 6220aafc82a873b3358ed13d10abaeb3cc022c1f Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 13:41:41 -0400 Subject: [PATCH 22/61] feat(chat): show whether the counterpart is connected --- backend/src/ws/channel.ts | 175 ++++++++++++++++-- backend/src/ws/chatSocket.ts | 88 +++++++-- backend/tests/ws/channel.test.ts | 32 +++- backend/tests/ws/chatSocket.test.ts | 171 +++++++++++++---- frontend/src/components/chat/index.module.css | 19 ++ frontend/src/components/chat/index.tsx | 32 +++- frontend/tests/components/chat.test.tsx | 36 +++- shared/src/hooks/chat/useChatMessages.ts | 5 +- shared/src/hooks/chat/useChatThreadSocket.ts | 83 +++++++-- 9 files changed, 539 insertions(+), 102 deletions(-) diff --git a/backend/src/ws/channel.ts b/backend/src/ws/channel.ts index e69fd824..964789b3 100644 --- a/backend/src/ws/channel.ts +++ b/backend/src/ws/channel.ts @@ -21,19 +21,44 @@ import WebSocket, { WebSocketServer } from 'ws'; * listener, dispatching on path. That is what the `ws` documentation recommends for * exactly this case. * - * Every channel is notification-only by construction (see the two that use it): a frame - * says "this thing changed, re-read it" and carries no content, which is what makes an - * unauthenticated socket acceptable. A channel that ever wants to push content needs - * authentication in `handleUpgrade` first. + * A channel may declare an authorizer. Without one it stays open to anyone who knows a + * topic id, which is acceptable only while its frames carry nothing readable — the + * battle-room channel's position. Chat has one, because presence is a claim about + * *identities* and an anonymous socket has none. */ +/** Marker subprotocol; the token rides alongside it as the second offered value. */ +export const AUTH_PROTOCOL = 'cryptopets-auth'; + +/** + * Decides whether a connection may subscribe, and who it belongs to. + * + * Returns the subscriber's identity (a wallet address) to accept, or null to refuse + * before the handshake, so a rejected client never becomes a subscriber at all — not + * even to the fact that the topic changed. + */ +export type ChannelAuthorizer = ( + request: IncomingMessage, + topic: string +) => Promise; + +export interface ChannelOptions { + authorize?: ChannelAuthorizer; + /** Broadcast who is connected to a topic. Requires `authorize`. */ + presence?: boolean; +} + interface Channel { /** Path this channel answers on, e.g. `/ws/chat`. */ path: string; /** Query parameter naming the topic a client subscribes to, e.g. `threadId`. */ param: string; + authorize?: ChannelAuthorizer; + presence: boolean; /** topic → connected sockets. */ members: Map>; + /** topic → identity → open connection count, so two tabs are one person. */ + present: Map>; wss: WebSocketServer | null; } @@ -51,8 +76,27 @@ export interface ChannelHandle { notify(topic: string, message: unknown): void; } -export function defineChannel(path: string, param: string): ChannelHandle { - const channel: Channel = { path, param, members: new Map(), wss: null }; +export function defineChannel( + path: string, + param: string, + options: ChannelOptions = {} +): ChannelHandle { + if (options.presence && !options.authorize) { + // A guard rather than a silent degradation: presence over anonymous sockets can + // only say "somebody is here", and one person with two tabs open would read as + // their counterpart being online. + throw new Error(`channel ${path}: presence requires an authorizer`); + } + + const channel: Channel = { + path, + param, + members: new Map(), + present: new Map(), + wss: null, + presence: options.presence ?? false, + ...(options.authorize ? { authorize: options.authorize } : {}), + }; channels.push(channel); return { @@ -79,16 +123,27 @@ export function startWsChannels(server: Server): void { stopWsChannels(); for (const channel of channels) { - channel.wss = new WebSocketServer({ noServer: true }); - channel.wss.on('connection', (socket: WebSocket, _req: IncomingMessage, topic: string) => { - join(channel, topic, socket); - socket.on('close', () => leave(channel, topic, socket)); + channel.wss = new WebSocketServer({ + noServer: true, + // Browsers cannot set headers on a WebSocket, so a token travels as a + // subprotocol. The marker is echoed back, never the token; a query parameter + // would put the JWT into proxy and access logs. + handleProtocols: (protocols) => (protocols.has(AUTH_PROTOCOL) ? AUTH_PROTOCOL : false), }); + channel.wss.on( + 'connection', + (socket: WebSocket, _req: IncomingMessage, topic: string, identity: string | null) => { + join(channel, topic, socket, identity); + socket.on('close', () => leave(channel, topic, socket, identity)); + } + ); } const onUpgrade: UpgradeListener = (request, socket, head) => { const url = parseUrl(request.url); - const channel = url ? channels.find((candidate) => candidate.path === url.pathname) : undefined; + const channel = url + ? channels.find((candidate) => candidate.path === url.pathname) + : undefined; if (!url || !channel?.wss) { // Not ours. Destroying rather than ignoring, because with a single listener // there is nobody else to answer and a hanging socket would leak. @@ -104,9 +159,30 @@ export function startWsChannels(server: Server): void { return; } - channel.wss.handleUpgrade(request, socket, head, (ws) => { - channel.wss?.emit('connection', ws, request, topic); - }); + const wss = channel.wss; + const authorize = channel.authorize; + if (!authorize) { + wss.handleUpgrade(request, socket, head, (ws) => { + wss.emit('connection', ws, request, topic, null); + }); + return; + } + + void (async () => { + let identity: string | null = null; + try { + identity = await authorize(request, topic); + } catch (err) { + console.error(`[ws] authorize threw for ${channel.path}:`, err); + } + if (!identity) { + socket.destroy(); + return; + } + wss.handleUpgrade(request, socket, head, (ws) => { + wss.emit('connection', ws, request, topic, identity); + }); + })(); }; server.on('upgrade', onUpgrade); @@ -123,23 +199,84 @@ export function stopWsChannels(): void { channel.wss?.close(); channel.wss = null; channel.members.clear(); + channel.present.clear(); } } -function join(channel: Channel, topic: string, socket: WebSocket): void { +function join( + channel: Channel, + topic: string, + socket: WebSocket, + identity: string | null +): void { let listeners = channel.members.get(topic); if (!listeners) { listeners = new Set(); channel.members.set(topic, listeners); } listeners.add(socket); + + if (channel.presence && identity) { + const counts = channel.present.get(topic) ?? new Map(); + counts.set(identity, (counts.get(identity) ?? 0) + 1); + channel.present.set(topic, counts); + broadcastPresence(channel, topic); + } else if (channel.presence) { + // Still tell the newcomer who is already here; the broadcast above only fires for + // an identified join, and a client that connected to silence would show everyone + // offline until the next arrival. + sendPresence(channel, topic, socket); + } } -function leave(channel: Channel, topic: string, socket: WebSocket): void { +function leave( + channel: Channel, + topic: string, + socket: WebSocket, + identity: string | null +): void { const listeners = channel.members.get(topic); - if (!listeners) return; - listeners.delete(socket); - if (listeners.size === 0) channel.members.delete(topic); + if (listeners) { + listeners.delete(socket); + if (listeners.size === 0) channel.members.delete(topic); + } + + if (channel.presence && identity) { + const counts = channel.present.get(topic); + if (counts) { + // Counted, not a set: closing one of two tabs must not report someone as gone. + const remaining = (counts.get(identity) ?? 1) - 1; + if (remaining > 0) counts.set(identity, remaining); + else counts.delete(identity); + if (counts.size === 0) channel.present.delete(topic); + } + broadcastPresence(channel, topic); + } +} + +/** The current roster of a topic, as a frame. */ +function presenceFrame(channel: Channel, topic: string): string { + const online = [...(channel.present.get(topic)?.keys() ?? [])]; + return JSON.stringify({ type: 'presence', topic, online }); +} + +/** + * Tells everyone on a topic who is currently connected. + * + * Only participants can be connected at all (presence requires an authorizer), so these + * identities are already known to everyone receiving them. + */ +function broadcastPresence(channel: Channel, topic: string): void { + const listeners = channel.members.get(topic); + if (!listeners || listeners.size === 0) return; + const payload = presenceFrame(channel, topic); + for (const client of listeners) { + if (client.readyState === WebSocket.OPEN) client.send(payload); + } +} + +function sendPresence(channel: Channel, topic: string, socket: WebSocket): void { + if (socket.readyState === WebSocket.OPEN) socket.send(presenceFrame(channel, topic)); } function parseUrl(url: string | undefined): URL | null { diff --git a/backend/src/ws/chatSocket.ts b/backend/src/ws/chatSocket.ts index 446d46bd..00c813df 100644 --- a/backend/src/ws/chatSocket.ts +++ b/backend/src/ws/chatSocket.ts @@ -1,26 +1,34 @@ -import { defineChannel } from './channel'; +import type { IncomingMessage } from 'node:http'; +import jwt from 'jsonwebtoken'; + +import { env } from '@config/env'; +// Imported from the module, not the feature barrel: the barrel also exports the +// controller, which imports this file, and that would be a cycle. +import { authorizeThread } from '@features/chat/chat.service'; +import { AUTH_PROTOCOL, defineChannel } from './channel'; /** - * The per-thread notification channel for private chat (roadmap §2 v1). + * The per-thread channel for private chat (roadmap §2 v1). + * + * **Carries no message content.** The socket only ever says "thread X changed" plus who + * is currently connected; the text comes from `GET /api/chat/threads/:id/messages`, which + * authenticates the caller and rechecks the marriage. A client that missed a notification, + * or never connected, learns the same thing by re-reading. This makes chat feel live; it + * is never the thing that decides who may read it. * - * **Carries no message content, deliberately.** The roadmap assumed chat could reuse an - * authenticated socket; there isn't one. The battle-room channel takes an id from the - * query string and joins whoever asks, which is fine there because those notifications - * carry nothing a client could not re-fetch anyway. Pushing message text down a channel - * like that would hand private conversations to anyone holding a thread id. + * Unlike the battle-room channel, this one **authenticates the upgrade**. Presence forced + * it: "is my counterpart online" is a question about identities, and an anonymous socket + * has none — counting connections would report one person with two tabs open as two + * people. Authenticating also closes the timing leak the earlier version accepted, where + * anyone holding a thread id could watch a conversation's activity without being in it. * - * So this keeps the same posture and inherits its safety from it: the socket only ever - * says "thread X changed", and the content comes from - * `GET /api/chat/threads/:id/messages`, which authenticates the caller and rechecks the - * marriage. A client that missed a notification, or never connected at all, learns - * exactly the same thing by re-reading. This makes chat feel live; it is never the thing - * that decides who may read it. + * The token arrives as a WebSocket subprotocol rather than a query parameter, because + * browsers cannot set headers on a WebSocket and a URL-borne JWT ends up in proxy and + * access logs. * - * What a listener does learn is *timing* — that a thread they know the id of had - * activity. Thread ids are cuids handed out only by an authenticated read, so that - * requires already having been told one. If v2 opens direct messages to strangers, this - * channel should gain real authentication before it does, and the token belongs in a - * subprotocol rather than the query string, where proxies and access logs would record it. + * Authorization is checked at connect only. A marriage that ends mid-session leaves the + * socket open until it drops, which costs nothing: every frame is contentless, and the + * read endpoint it prompts refuses immediately. */ export interface ChatThreadNotification { @@ -30,7 +38,49 @@ export interface ChatThreadNotification { messageId: number; } -const channel = defineChannel('/ws/chat', 'threadId'); +/** Who is connected to a thread right now. */ +export interface ChatPresenceNotification { + type: 'presence'; + topic: string; + /** Wallet addresses currently connected, normalized as the thread stores them. */ + online: string[]; +} + +/** + * Reads the token from the offered subprotocols. + * + * The client offers `[AUTH_PROTOCOL, ]`; the server echoes only the marker back. + */ +function tokenFromRequest(request: IncomingMessage): string | null { + const offered = request.headers['sec-websocket-protocol']; + if (!offered) return null; + const values = (Array.isArray(offered) ? offered.join(',') : offered) + .split(',') + .map((value) => value.trim()) + .filter(Boolean); + const marker = values.indexOf(AUTH_PROTOCOL); + return marker === -1 ? null : (values[marker + 1] ?? null); +} + +const channel = defineChannel('/ws/chat', 'threadId', { + presence: true, + async authorize(request, threadId) { + const token = tokenFromRequest(request); + if (!token) return null; + + let address: string; + try { + ({ address } = jwt.verify(token, env.jwtSecret) as { address: string }); + } catch { + return null; + } + if (!address) return null; + + // The same gate the HTTP routes apply, so a socket can never be subscribed to a + // thread its holder could not read. + return (await authorizeThread(threadId, address)) === null ? address : null; + }, +}); /** Tells everyone watching `threadId` that it changed. */ export function notifyChatThread(threadId: string, message: ChatThreadNotification): void { diff --git a/backend/tests/ws/channel.test.ts b/backend/tests/ws/channel.test.ts index 9a8d2130..14dd782b 100644 --- a/backend/tests/ws/channel.test.ts +++ b/backend/tests/ws/channel.test.ts @@ -1,7 +1,14 @@ import { createServer, type Server } from 'node:http'; -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import jwt from 'jsonwebtoken'; import WebSocket from 'ws'; +// Chat authorizes its upgrades now; the battle room does not. Stubbing the marriage gate +// keeps this file about channel routing rather than about chat's rules. +vi.mock('@features/chat/chat.service', () => ({ + authorizeThread: vi.fn(async () => null), +})); + import { notifyBattleRoom } from '@ws/battleRoomSocket'; import { notifyChatThread } from '@ws/chatSocket'; import { startWsChannels, stopWsChannels } from '@ws/channel'; @@ -37,17 +44,34 @@ afterEach(async () => { await new Promise((resolve) => server.close(() => resolve())); }); +const AUTH_PROTOCOL = 'cryptopets-auth'; +const token = () => + jwt.sign( + { address: '0x1111111111111111111111111111111111111111', userId: 'u' }, + process.env.JWT_SECRET as string, + { expiresIn: '5m' }, + ); + function open(url: string): Promise { return new Promise((resolve, reject) => { - const socket = new WebSocket(url); + // The token is ignored by the unauthenticated channel and required by chat, so + // both connections are opened the same way. + const socket = new WebSocket(url, [AUTH_PROTOCOL, token()]); socket.once('open', () => resolve(socket)); socket.once('error', reject); }); } -function nextMessage(socket: WebSocket): Promise { +/** Skips presence frames, which chat emits unprompted on join. */ +function nextMessage(socket: WebSocket): Promise> { return new Promise((resolve, reject) => { - socket.once('message', (data) => resolve(JSON.parse(data.toString()))); + const onMessage = (data: Buffer) => { + const message = JSON.parse(data.toString()) as Record; + if (message.type === 'presence') return; + socket.off('message', onMessage); + resolve(message); + }; + socket.on('message', onMessage); socket.once('error', reject); socket.once('close', (code) => reject(new Error(`closed before a message: ${code}`))); }); diff --git a/backend/tests/ws/chatSocket.test.ts b/backend/tests/ws/chatSocket.test.ts index 0dbb4574..cc9f02db 100644 --- a/backend/tests/ws/chatSocket.test.ts +++ b/backend/tests/ws/chatSocket.test.ts @@ -1,22 +1,38 @@ import { createServer, type Server } from 'node:http'; -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import jwt from 'jsonwebtoken'; import WebSocket from 'ws'; +// The channel authorizes against the real service, so the marriage gate is stubbed while +// the JWT stays genuine — the token path is part of what these tests cover. +const authorizeThread = vi.fn(); +vi.mock('@features/chat/chat.service', () => ({ + authorizeThread: (threadId: string, caller: string) => authorizeThread(threadId, caller), +})); + import '@ws/battleRoomSocket'; // registers the other channel, as the real server does import { notifyChatThread } from '@ws/chatSocket'; import { startWsChannels, stopWsChannels } from '@ws/channel'; /** * Real server and real clients, because the property under test is delivery over the - * wire: a listener on thread A must never receive thread B's notification, and what - * arrives must contain no message text — the socket exists to prompt an authenticated - * re-read, never to be one. + * wire: a listener on thread A must never receive thread B's notification, what arrives + * must contain no message text, and an unauthorized client must not connect at all. */ +const ME = '0x1111111111111111111111111111111111111111'; +const THEM = '0x2222222222222222222222222222222222222222'; +const AUTH_PROTOCOL = 'cryptopets-auth'; + let server: Server; let baseUrl: string; +const tokenFor = (address: string) => + jwt.sign({ address, userId: address }, process.env.JWT_SECRET as string, { expiresIn: '5m' }); + beforeEach(async () => { + vi.clearAllMocks(); + authorizeThread.mockResolvedValue(null); // a null denial means allowed server = createServer(); startWsChannels(server); await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); @@ -32,19 +48,26 @@ afterEach(async () => { await new Promise((resolve) => server.close(() => resolve())); }); -function connect(threadId: string | null): Promise { +function connect(threadId: string | null, address = ME): Promise { return new Promise((resolve, reject) => { const url = threadId === null ? baseUrl : `${baseUrl}?threadId=${threadId}`; - const socket = new WebSocket(url); + const socket = new WebSocket(url, [AUTH_PROTOCOL, tokenFor(address)]); socket.once('open', () => resolve(socket)); socket.once('error', reject); }); } -function nextMessage(socket: WebSocket): Promise { +/** The next frame that is not presence — presence arrives unprompted on join and leave. */ +function nextUpdate(socket: WebSocket): Promise> { return new Promise((resolve, reject) => { - socket.once('message', (data) => resolve(JSON.parse(data.toString()))); - socket.once('close', (code) => reject(new Error(`closed before a message arrived: ${code}`))); + const onMessage = (data: Buffer) => { + const message = JSON.parse(data.toString()) as Record; + if (message.type === 'presence') return; + socket.off('message', onMessage); + resolve(message); + }; + socket.on('message', onMessage); + socket.once('close', (code) => reject(new Error(`closed before a message: ${code}`))); }); } @@ -52,15 +75,24 @@ function nextClose(socket: WebSocket): Promise { return new Promise((resolve) => socket.once('close', (code) => resolve(code))); } +/** Refusals happen at the upgrade, so they surface as an error rather than a close code. */ +function outcomeOf(socket: WebSocket): Promise { + return new Promise((resolve) => { + socket.once('open', () => resolve('open')); + socket.once('error', () => resolve('refused')); + socket.once('close', () => resolve('refused')); + }); +} + const update = { type: 'thread-updated', threadId: 'thread_1', messageId: 7 } as const; describe('thread scoping', () => { it('delivers only to listeners on that thread', async () => { const onThread = await connect('thread_1'); const onOther = await connect('thread_2'); - const otherMessage = nextMessage(onOther); + const otherMessage = nextUpdate(onOther); - const received = nextMessage(onThread); + const received = nextUpdate(onThread); notifyChatThread('thread_1', update); await expect(received).resolves.toEqual(update); @@ -75,10 +107,10 @@ describe('thread scoping', () => { }); it('delivers to both participants watching the same thread', async () => { - const first = await connect('thread_1'); - const second = await connect('thread_1'); - const firstMessage = nextMessage(first); - const secondMessage = nextMessage(second); + const first = await connect('thread_1', ME); + const second = await connect('thread_1', THEM); + const firstMessage = nextUpdate(first); + const secondMessage = nextUpdate(second); notifyChatThread('thread_1', update); @@ -89,19 +121,15 @@ describe('thread scoping', () => { second.close(); }); - // The whole safety argument for an unauthenticated channel: what it pushes is not - // readable content, so a listener still has to pass the authenticated read. + // The safety argument for the channel: what it pushes is not readable content, so a + // listener still has to pass the authenticated read. it('carries no message text', async () => { const socket = await connect('thread_1'); - const received = nextMessage(socket); + const received = nextUpdate(socket); notifyChatThread('thread_1', update); - expect(Object.keys((await received) as object).sort()).toEqual([ - 'messageId', - 'threadId', - 'type', - ]); + expect(Object.keys(await received).sort()).toEqual(['messageId', 'threadId', 'type']); socket.close(); }); @@ -119,18 +147,93 @@ describe('thread scoping', () => { }); }); +describe('presence', () => { + /** Records presence rosters as they arrive. */ + function presenceLog(socket: WebSocket): string[][] { + const seen: string[][] = []; + socket.on('message', (data: Buffer) => { + const message = JSON.parse(data.toString()) as { type: string; online?: string[] }; + if (message.type === 'presence' && message.online) seen.push(message.online); + }); + return seen; + } + + const settle = () => new Promise((resolve) => setTimeout(resolve, 80)); + + it('announces an arrival to whoever is already there', async () => { + const first = await connect('thread_1', ME); + const seen = presenceLog(first); + await settle(); + + const second = await connect('thread_1', THEM); + await settle(); + + // This is what turns the dot green without a reload. + expect(seen.at(-1)).toEqual(expect.arrayContaining([ME, THEM])); + + first.close(); + second.close(); + }); + + it('drops someone from the roster when they disconnect', async () => { + const first = await connect('thread_1', ME); + const second = await connect('thread_1', THEM); + const seen = presenceLog(first); + await settle(); + + second.close(); + await settle(); + + expect(seen.at(-1)).toEqual([ME]); + first.close(); + }); + + // Why presence counts identities rather than sockets: one person with two tabs open + // must not look like two people, and closing one tab must not report them as gone. + it('treats two connections from one wallet as one person', async () => { + const first = await connect('thread_1', ME); + const seen = presenceLog(first); + const secondTab = await connect('thread_1', ME); + await settle(); + + expect(seen.at(-1)).toEqual([ME]); + + secondTab.close(); + await settle(); + expect(seen.at(-1)).toEqual([ME]); + + first.close(); + }); +}); + describe('connection requirements', () => { it('refuses a connection that names no thread', async () => { - // Refused at the upgrade, before a WebSocket exists, so this surfaces as a - // transport error rather than a close code. Failing here rather than accepting a - // subscriber to nothing is the point: the latter looks connected and never - // delivers. - const socket = new WebSocket(baseUrl); - const outcome = await new Promise((resolve) => { - socket.once('open', () => resolve('open')); - socket.once('error', () => resolve('refused')); - socket.once('close', () => resolve('refused')); - }); - expect(outcome).toBe('refused'); + expect(await outcomeOf(new WebSocket(baseUrl, [AUTH_PROTOCOL, tokenFor(ME)]))).toBe( + 'refused' + ); + }); + + it('refuses a connection with no token', async () => { + expect(await outcomeOf(new WebSocket(`${baseUrl}?threadId=thread_1`))).toBe('refused'); + expect(authorizeThread).not.toHaveBeenCalled(); + }); + + it('refuses a connection with a forged token', async () => { + const forged = jwt.sign({ address: ME, userId: ME }, 'not-the-secret'); + const socket = new WebSocket(`${baseUrl}?threadId=thread_1`, [AUTH_PROTOCOL, forged]); + + expect(await outcomeOf(socket)).toBe('refused'); + // Rejected on the signature, before the marriage gate is even consulted. + expect(authorizeThread).not.toHaveBeenCalled(); + }); + + // Authenticated but not a participant: the same gate the HTTP routes apply, so a + // socket can never subscribe to a thread its holder could not read. + it('refuses a valid token for a thread the caller is not in', async () => { + authorizeThread.mockResolvedValue('not-a-participant'); + const socket = new WebSocket(`${baseUrl}?threadId=thread_1`, [AUTH_PROTOCOL, tokenFor(ME)]); + + expect(await outcomeOf(socket)).toBe('refused'); + expect(authorizeThread).toHaveBeenCalledWith('thread_1', ME); }); }); diff --git a/frontend/src/components/chat/index.module.css b/frontend/src/components/chat/index.module.css index b76fcc7a..cfa7ec04 100644 --- a/frontend/src/components/chat/index.module.css +++ b/frontend/src/components/chat/index.module.css @@ -95,9 +95,28 @@ } .conversationTitle { + display: flex; + align-items: center; + gap: 8px; font-size: 0.95rem; } +/* Presence. Grey is the resting state and green is the exception, so a thread that is + simply quiet does not look like an error. Sized in em so it tracks the title. */ +.dot { + width: 0.55em; + height: 0.55em; + flex-shrink: 0; + border-radius: 50%; + background: rgb(148 163 184 / 55%); +} + +.dot.isOnline { + background: rgb(52 211 153); + /* A faint halo so it reads as "lit" at this size rather than as a dark speck. */ + box-shadow: 0 0 0 3px rgb(52 211 153 / 18%); +} + /* Stated plainly rather than blocking the composer: sending still works while the notification channel is down, it just will not update on its own. */ .offline { diff --git a/frontend/src/components/chat/index.tsx b/frontend/src/components/chat/index.tsx index 2dc216b7..fa065d63 100644 --- a/frontend/src/components/chat/index.tsx +++ b/frontend/src/components/chat/index.tsx @@ -55,10 +55,17 @@ const ThreadList: React.FC<{ ); const Conversation: React.FC<{ thread: ChatThread; me: string }> = ({ thread, me }) => { - const { messages, isLoading, error, isLive, send, isSending, sendError } = useChatMessages({ - threadId: thread.threadId, - socketUrl: CHAT_WS_URL, - }); + const { messages, isLoading, error, isLive, online, send, isSending, sendError } = + useChatMessages({ + threadId: thread.threadId, + socketUrl: CHAT_WS_URL, + }); + + // Only a live channel can say anyone is present. While it is down every dot would + // otherwise read grey, which is indistinguishable from "they left" — so the header + // says the channel is offline instead of asserting anything about the other person. + const counterpartOnline = + isLive && online.some((address) => sameAccount(address, thread.counterpart)); const [draft, setDraft] = useState(''); const endRef = useRef(null); @@ -87,11 +94,24 @@ const Conversation: React.FC<{ thread: ChatThread; me: string }> = ({ thread, me return (
      - {shortAddress(thread.counterpart)} + + + {shortAddress(thread.counterpart)} + {marriageLine(thread)} {!isLive && ( - offline + reconnecting )}
      diff --git a/frontend/tests/components/chat.test.tsx b/frontend/tests/components/chat.test.tsx index cfc70a0b..9bc6e03a 100644 --- a/frontend/tests/components/chat.test.tsx +++ b/frontend/tests/components/chat.test.tsx @@ -53,6 +53,7 @@ const messagesResult = (over: Record = {}) => ({ isLoading: false, error: null, isLive: true, + online: [], send, isSending: false, sendError: null, @@ -151,13 +152,46 @@ describe('Chat', () => { expect(send).not.toHaveBeenCalled(); }); + it('shows the counterpart as online when they are connected', () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + // Deliberately a different case from the stored address: presence is matched on + // accounts, not strings. + useChatMessages.mockReturnValue( + messagesResult({ online: [THEM.toUpperCase().replace('0X', '0x')] }), + ); + + renderChat(); + + expect(screen.getByLabelText('Online')).toBeInTheDocument(); + }); + + it('shows the counterpart as offline when only you are connected', () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + useChatMessages.mockReturnValue(messagesResult({ online: [ME] })); + + renderChat(); + + expect(screen.getByLabelText('Offline')).toBeInTheDocument(); + }); + + // A dropped channel cannot report presence. Showing grey would be indistinguishable + // from "they left", so the dot must not claim anything while the socket is down. + it('does not claim the counterpart is online while the channel is down', () => { + useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); + useChatMessages.mockReturnValue(messagesResult({ isLive: false, online: [ME, THEM] })); + + renderChat(); + + expect(screen.getByLabelText('Offline')).toBeInTheDocument(); + }); + it('says when the live channel is down without blocking sending', () => { useChatThreads.mockReturnValue({ threads: [thread()], isLoading: false, error: null }); useChatMessages.mockReturnValue(messagesResult({ isLive: false })); renderChat(); - expect(screen.getByText('offline')).toBeInTheDocument(); + expect(screen.getByText('reconnecting')).toBeInTheDocument(); expect(screen.getByLabelText('Message')).toBeEnabled(); }); diff --git a/shared/src/hooks/chat/useChatMessages.ts b/shared/src/hooks/chat/useChatMessages.ts index 124df193..5d0850ce 100644 --- a/shared/src/hooks/chat/useChatMessages.ts +++ b/shared/src/hooks/chat/useChatMessages.ts @@ -24,6 +24,8 @@ export interface UseChatMessagesResult { error: Error | null; /** True while the notification channel is connected; false means reads are on demand only. */ isLive: boolean; + /** Wallet addresses currently connected to this thread, including your own. */ + online: string[]; send: (text: string) => Promise; isSending: boolean; sendError: Error | null; @@ -90,7 +92,7 @@ export const useChatMessages = ({ [queryClient, baseURL, threadId, refresh], ); - const { connected } = useChatThreadSocket({ + const { connected, online } = useChatThreadSocket({ url: socketUrl, threadId, onNotification, @@ -134,6 +136,7 @@ export const useChatMessages = ({ isLoading: query.isLoading, error: query.error as Error | null, isLive: connected, + online, send, isSending: mutation.isPending, sendError: mutation.error as Error | null, diff --git a/shared/src/hooks/chat/useChatThreadSocket.ts b/shared/src/hooks/chat/useChatThreadSocket.ts index ab4c33e4..e53cf22c 100644 --- a/shared/src/hooks/chat/useChatThreadSocket.ts +++ b/shared/src/hooks/chat/useChatThreadSocket.ts @@ -1,17 +1,21 @@ import { useEffect, useRef, useState } from 'react'; +import { getStorageAdapter } from '../../api'; /** - * Subscribes to one thread's notification channel (`/ws/chat`). + * Subscribes to one thread's channel (`/ws/chat`). * - * Notification only, by construction: a frame carries `{ threadId, messageId }` and no - * text, so there is nothing here that could be rendered as a message even by mistake. - * Every frame means one thing — re-read the thread. + * Carries no message text: a frame says the thread changed, or who is currently + * connected. Every notification means one thing — re-read the thread. * - * Same shape as `useBattleRoomSocket`, including the reconnect callback, which matters - * for the same reason: anything sent while the socket was down was never delivered, so a - * reconnect is as much a reason to re-read as a frame is. Kept separate rather than - * generalized because the two channels differ in what they will need next — this one - * gains authentication when chat widens past married pairs. + * The connection is authenticated. The token is offered as a WebSocket subprotocol + * because browsers cannot set headers on a WebSocket and a token in the query string + * would be recorded by proxies and access logs. Without a valid token for a thread the + * caller participates in, the server refuses the upgrade, so this reports "not live" + * rather than silently subscribing to nothing. + * + * Same reconnect shape as `useBattleRoomSocket`, including the reconnect callback: + * anything sent while the socket was down was never delivered, so a reconnect is as much + * a reason to re-read as a frame is. */ export interface ChatThreadNotification { @@ -20,6 +24,12 @@ export interface ChatThreadNotification { messageId: number; } +export interface ChatPresence { + type: 'presence'; + topic: string; + online: string[]; +} + export interface UseChatThreadSocketOptions { /** Socket endpoint. Undefined disables the subscription entirely. */ url: string | undefined; @@ -30,12 +40,24 @@ export interface UseChatThreadSocketOptions { onReconnect?: () => void; } +export interface UseChatThreadSocketResult { + connected: boolean; + /** Wallet addresses currently connected to this thread, including your own. */ + online: string[]; +} + const INITIAL_RETRY_MS = 1000; const MAX_RETRY_MS = 30_000; -export function useChatThreadSocket(options: UseChatThreadSocketOptions): { connected: boolean } { +/** Marker subprotocol the server echoes back; the token follows it. */ +const AUTH_PROTOCOL = 'cryptopets-auth'; + +export function useChatThreadSocket( + options: UseChatThreadSocketOptions +): UseChatThreadSocketResult { const { url, threadId } = options; const [connected, setConnected] = useState(false); + const [online, setOnline] = useState([]); // Refs so inline callbacks do not rebuild the socket every render: its lifetime should // depend on the url and thread, and nothing else. @@ -46,6 +68,7 @@ export function useChatThreadSocket(options: UseChatThreadSocketOptions): { conn useEffect(() => { setConnected(false); + setOnline([]); if (!url || !threadId) return; let disposed = false; @@ -54,10 +77,25 @@ export function useChatThreadSocket(options: UseChatThreadSocketOptions): { conn let retryDelay = INITIAL_RETRY_MS; let hasConnectedBefore = false; - const connect = (): void => { + const connect = async (): Promise => { + if (disposed) return; + + // Read per attempt rather than once: a reconnect after a token refresh must + // use the new one, or it authenticates with a token the server has retired. + const token = await getStorageAdapter()?.getToken(); if (disposed) return; + if (!token) { + // Nothing to authenticate with. Retry rather than give up: this happens + // during sign-in, and the thread becomes live once a token exists. + retryTimer = setTimeout(() => void connect(), retryDelay); + retryDelay = Math.min(retryDelay * 2, MAX_RETRY_MS); + return; + } - socket = new WebSocket(`${url}?threadId=${encodeURIComponent(threadId)}`); + socket = new WebSocket(`${url}?threadId=${encodeURIComponent(threadId)}`, [ + AUTH_PROTOCOL, + token, + ]); socket.onopen = () => { if (disposed) return; @@ -72,9 +110,16 @@ export function useChatThreadSocket(options: UseChatThreadSocketOptions): { conn socket.onmessage = (event) => { if (disposed) return; try { - const message = JSON.parse(event.data as string) as ChatThreadNotification; - if (message?.type === 'thread-updated' && typeof message.threadId === 'string') { - onNotification.current?.(message); + const message = JSON.parse(event.data as string) as + | ChatThreadNotification + | ChatPresence; + if (message?.type === 'presence' && Array.isArray(message.online)) { + setOnline(message.online); + } else if ( + message?.type === 'thread-updated' && + typeof message.threadId === 'string' + ) { + onNotification.current?.(message as ChatThreadNotification); } } catch { // A malformed frame is not worth surfacing: the read endpoint is the @@ -85,7 +130,8 @@ export function useChatThreadSocket(options: UseChatThreadSocketOptions): { conn socket.onclose = () => { if (disposed) return; setConnected(false); - retryTimer = setTimeout(connect, retryDelay); + setOnline([]); + retryTimer = setTimeout(() => void connect(), retryDelay); retryDelay = Math.min(retryDelay * 2, MAX_RETRY_MS); }; @@ -96,7 +142,7 @@ export function useChatThreadSocket(options: UseChatThreadSocketOptions): { conn }; }; - connect(); + void connect(); return () => { disposed = true; @@ -111,8 +157,9 @@ export function useChatThreadSocket(options: UseChatThreadSocketOptions): { conn socket.close(); } setConnected(false); + setOnline([]); }; }, [url, threadId]); - return { connected }; + return { connected, online }; } From 73548b2b9197888b19e44dba20d8ecbd0a8499f2 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 13:49:41 -0400 Subject: [PATCH 23/61] feat(frontend): give Messages its own chat icon --- frontend/src/assets/nav-icons/messages.svg | 1 + frontend/src/components/layout/sidebar/nav-items.ts | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 frontend/src/assets/nav-icons/messages.svg diff --git a/frontend/src/assets/nav-icons/messages.svg b/frontend/src/assets/nav-icons/messages.svg new file mode 100644 index 00000000..a758ef21 --- /dev/null +++ b/frontend/src/assets/nav-icons/messages.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/components/layout/sidebar/nav-items.ts b/frontend/src/components/layout/sidebar/nav-items.ts index b7735781..f49b22cb 100644 --- a/frontend/src/components/layout/sidebar/nav-items.ts +++ b/frontend/src/components/layout/sidebar/nav-items.ts @@ -19,6 +19,7 @@ import itemsIcon from '@assets/nav-icons/items.svg'; import shardIcon from '@assets/nav-icons/shard.svg'; import marriageIcon from '@assets/nav-icons/marriage.svg'; import renameIcon from '@assets/nav-icons/rename.svg'; +import messagesIcon from '@assets/nav-icons/messages.svg'; import leaderboardIcon from '@assets/nav-icons/leaderboard.svg'; export type NavItem = { @@ -54,9 +55,7 @@ export const NAV_ITEMS: readonly NavItem[] = [ { id: 'messages', label: 'Messages', - // Reuses the marriage icon rather than inventing one: in v1 a thread exists - // only because two pets are married, so it is the same relationship. - iconSrc: marriageIcon, + iconSrc: messagesIcon, tone: 'magenta', path: MESSAGES_PATH, }, From a532e07dccc232307a0b042f8c49cd67136379e4 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 13:54:40 -0400 Subject: [PATCH 24/61] docs: bring the chat socket docs in line --- CLAUDE.md | 10 +++++++ backend/API.md | 41 +++++++++++++++++++--------- docs/plan-future-features-roadmap.md | 29 ++++++++++++++------ 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 08c260d6..23b0b77c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -200,6 +200,16 @@ The dialogue endpoint's anti-forgery guard still exists but now compares the cli Consequently `src/grpc/battleStream.ts` is deleted: nothing published to it after indexer-go stopped ingesting battles, and nothing read from it after this. `INDEXER_GRPC_ADDR` still matters for pet-state reads and win estimates. `StreamLiveBattles` and `ListReadyOpponents` are gone from `proto/cryptopets.proto` too, along with indexer-go's whole `BattleEvent` pipeline — no adapter had published one since battles left the chain. +### Every WebSocket channel goes through one upgrade listener +`backend/src/ws/channel.ts` owns the process's single `upgrade` handler and dispatches on path; `battleRoomSocket.ts` and `chatSocket.ts` are thin registrations on top of it. Do **not** add a channel by constructing `new WebSocketServer({ server, path })`. That attaches one upgrade listener *per instance* to the same HTTP server, Node calls every listener on every upgrade, so each connection is handled twice, the client gets two HTTP 101 responses, and the second is parsed as a frame — `RangeError: Invalid WebSocket frame: RSV1 must be clear`. It breaks **every** channel, not just the new one, and per-channel tests will not catch it because each builds its own HTTP server with a single channel attached (`tests/ws/channel.test.ts` is the regression test that does). + +A channel may declare an authorizer, which runs before the handshake so a refused client never becomes a subscriber at all. The battle room has none: its frames carry nothing a client could not re-fetch, which is the only thing that makes an anonymous socket acceptable. Chat has one, and needed it for presence — "is my counterpart online" is a claim about identities, and an anonymous socket has none, so counting connections would report one person with two tabs as two people. Presence therefore counts identities, not sockets. The JWT arrives as a WebSocket subprotocol rather than a query parameter: browsers cannot set headers on a WebSocket, and a URL-borne token is recorded by proxies and access logs. + +### Private chat (roadmap §2 v1): access is derived per request, never stored +`chat_thread` deliberately does not record the marriage that justifies it. Every read, send, and socket upgrade rechecks `pet_roster.spouse_id` through `chat.service.authorizeThread`, so a divorce closes the conversation the moment the indexer sees it, with no revocation step that could be forgotten. The thread row survives — deleting it would destroy the history — it just stops answering. + +Two consequences worth keeping: a non-participant gets **404, not 403**, identical to a thread that does not exist, because 403 would confirm a thread id to anyone probing; and the caller is normalized (`normalizeAccount`) at the service boundary, since the caller doubles as the thread's participant key and an unnormalized spelling would open a second thread beside the first and split the conversation. + ### Known v1 contract limitations (design context, not regressions to "fix") `contracts/plan-contract-upgrade.md` documents intentional v1 gaps that v2 is designed around: no battle authorization (anyone can call `battle()`/`attack()` on anyone's pets), an EVM `changeDna` cheat that lets a level-20 pet set arbitrary DNA, and a Solana `create_starter_pet` that accepts client-supplied dna/rarity. v2 plan: EVM moves to UUPS proxies (`PetCoreProxy` + `GameLogicProxy`, with `CombatSimV1` deployed as a separate contract to stay under the 24KB bytecode ceiling); Solana adds versioned/reserved-space accounts and migrates pets to Metaplex Core NFTs. This is a plan doc; check current contract source before assuming any of it is implemented. diff --git a/backend/API.md b/backend/API.md index d7ea8b9a..d10bbd46 100644 --- a/backend/API.md +++ b/backend/API.md @@ -377,25 +377,40 @@ and nothing left to filter. ws(s):///ws/chat?threadId= ``` -Notification-only, per-thread. Connecting without a `threadId` closes the socket -immediately (code `1008`). Every message is the same shape, and carries **no message -text**: +Per-thread, and **authenticated**. Two frame shapes, neither carrying message text: ```json { "type": "thread-updated", "threadId": "c...", "messageId": 42 } +{ "type": "presence", "topic": "c...", "online": ["0xabc…"] } ``` -The roadmap assumed chat could reuse an authenticated socket. There isn't one — the -battle-room channel above joins whoever presents a room id, which is safe there because -its payload is not content. This channel keeps that posture and gets its safety from the -same place: it says a thread changed, and the text comes from +`thread-updated` means "re-read this thread"; the text comes from `GET /api/chat/threads/:id/messages`, which authenticates the caller and rechecks the -marriage. Missing a notification costs latency, never access. - -What a listener does learn is timing — that a thread whose id they hold saw activity. -Thread ids are cuids handed out only by an authenticated read. If v2 opens direct -messages to strangers, this channel should be authenticated first, with the token in a -subprotocol rather than the query string, where proxies and access logs would record it. +marriage. Missing a notification costs latency, never access. `presence` is the roster of +participants currently connected, which is what drives the online dot. + +**Authentication.** The client offers two subprotocols, `cryptopets-auth` followed by the +JWT; the server echoes back only the marker. A subprotocol rather than a query parameter +because browsers cannot set headers on a WebSocket and a URL-borne token is recorded by +proxies and access logs. The upgrade then applies the same participation and live-marriage +gate as the HTTP routes, so a socket can never subscribe to a thread its holder could not +read. A connection with no token, a forged token, or a thread the caller is not in is +refused at the upgrade — it never becomes a subscriber, not even to the fact that the +thread changed. + +This is stricter than the channel shipped with. It was unauthenticated at first, on the +argument that contentless frames made it safe; presence forced the change, because "is my +counterpart online" is a claim about identities and an anonymous socket has none. Counting +connections would have reported one person with two tabs open as two people. Closing the +activity-timing leak came along with it. + +Presence counts identities, not sockets, so a second tab does not double a person and +closing one does not report them as gone. Authorization is checked at connect only: a +marriage that ends mid-session leaves the socket open until it drops, which costs nothing +because every frame is contentless and the read it prompts refuses immediately. + +The battle-room channel above remains unauthenticated. It carries no content and has no +presence, so it has nothing an identity would protect. ### Public receipt corpus (v2) diff --git a/docs/plan-future-features-roadmap.md b/docs/plan-future-features-roadmap.md index c66ab8f3..b8fbe555 100644 --- a/docs/plan-future-features-roadmap.md +++ b/docs/plan-future-features-roadmap.md @@ -28,9 +28,12 @@ names as historical pointers, not sources to read. > `DnaLib`, `TestDeployer`, plus `BattleBatchRegistry`, `SeasonRewardDistributor`, > `CryptoPetsToken` and `MockERC20`. > - **`liveBattleSocket.ts` is gone, and it is no longer "the one channel".** There are two: -> `battleRoomSocket.ts` (§J battle notifications) and `chatSocket.ts` (§2 chat). Neither is -> authenticated — both are notification-only by construction, which is what makes that -> safe. §2's assumption that an authenticated socket already existed to reuse was wrong. +> `battleRoomSocket.ts` (§J battle notifications) and `chatSocket.ts` (§2 chat), both +> behind one upgrade listener (`ws/channel.ts`) — a `WebSocketServer` per channel on the +> same HTTP server handles every connection twice. The battle room is unauthenticated, +> which is safe only because its frames carry nothing readable; chat is authenticated. +> §2's assumption that an authenticated socket already existed to reuse was wrong, so one +> had to be built. > - **A chat surface now exists** (§2 v1, built). So does a **token**: `CryptoPetsToken.sol` > is a deployed-ready fixed-supply ERC20 (CPET) that funds `SeasonRewardDistributor` under > the battle protocol's §I. That materially narrows §11 — see the note there. @@ -335,9 +338,16 @@ rank. The ranking computation itself is unaffected. > - **There was no authenticated WebSocket to reuse.** This section's cost argument rested > on one. `liveBattleSocket.ts` is gone, and its replacement joins whoever presents a room > id — safe there only because battle notifications carry nothing a client could not -> re-fetch. So `/ws/chat` carries **no message text**: it says a thread changed, and the -> authenticated read returns the content. Chat still cost less than anything else here, -> just not for the stated reason. +> re-fetch. `/ws/chat` still carries **no message text**: it says a thread changed, and +> the authenticated read returns the content. Chat still cost less than anything else +> here, just not for the stated reason. +> - **Presence shipped, and it is what made the socket authenticated.** The open decision +> below asked whether v1 should have online presence. It does: a green dot for the +> counterpart. That forced the auth this section assumed existed — presence is a claim +> about identities, and an anonymous socket has none, so counting connections would +> report one person with two tabs open as two people. The JWT travels as a subprotocol +> rather than a query parameter, and the upgrade applies the same participation and +> live-marriage gate as the HTTP routes. Read receipts are still absent. > - **Access is checked per request, not stored.** As sketched, `ChatThread` does not record > the marriage — but the check runs on every read and send, not only at open time, so a > divorce closes the conversation with nothing to revoke. The thread row survives, since @@ -347,9 +357,10 @@ rank. The ranking computation itself is unaffected. > null state that only ever resolves one way. > > The open decisions below are **unresolved and now carry a shipped surface**: there is no -> block, report, filter, read receipt, presence, edit, delete, or retention policy. The only -> abuse controls are a length cap and a send rate limit. v1's lack of any discovery surface -> is what contains the risk today, and that containment ends with v2's open DMs. +> block, report, filter, read receipt, edit, delete, or retention policy. (Presence is the +> one that got answered — see above.) The only abuse controls are a length cap and a send +> rate limit. v1's lack of any discovery surface is what contains the risk today, and that +> containment ends with v2's open DMs. **Goal.** Real player-to-player messaging, not another AI-generated conversation. The natural starting point is the marriage feature: two owners whose pets are married already have an From 7255664682c219619a58fdb6d777159a34277ade Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 14:05:35 -0400 Subject: [PATCH 25/61] fix(frontend): centre the loading spinner in the space it is given --- frontend/src/styles/messages.css | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/frontend/src/styles/messages.css b/frontend/src/styles/messages.css index 6254706c..7b5ccb87 100644 --- a/frontend/src/styles/messages.css +++ b/frontend/src/styles/messages.css @@ -25,15 +25,32 @@ } /* Loading / error states — shared across views (gallery, interaction panels). */ + +/* Centring the *contents* is not enough: this box only ever grew to fit its spinner, so + it sat at the top of whatever contained it and the spinner appeared near the header + rather than in the middle of the screen. + + Two rules, because the parents differ. Panel bodies are flex columns and honour `flex`, + which takes the leftover space below any header or tab row. The shell's content slot, + where the router's Suspense fallback renders, is a scrollable *block* — `flex` is inert + there and only a percentage resolves. The percentage is scoped to `:only-child` so it + cannot stack its own full height beside a sibling (the leaderboard's tabs) and overflow + the panel. */ .loading-container { display: flex; flex-direction: column; align-items: center; justify-content: center; + flex: 1 1 auto; padding: var(--cp-spacing-2xl); color: var(--cp-color-text-muted); } +.loading-container:only-child { + min-height: 100%; + box-sizing: border-box; +} + .loading-spinner { width: 40px; height: 40px; From b56489538285b39f61b568b85d165296c2200b4f Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 14:26:40 -0400 Subject: [PATCH 26/61] feat(frontend): ask for sign-in instead of failing with 401 --- frontend/src/components/chat/index.tsx | 107 ++++----- frontend/src/components/common/index.ts | 1 + .../components/common/session-gate/index.tsx | 75 ++++++ frontend/src/components/leaderboard/index.tsx | 223 +++++++++--------- frontend/tests/components/chat.test.tsx | 26 ++ .../tests/components/leaderboard.test.tsx | 15 ++ 6 files changed, 274 insertions(+), 173 deletions(-) create mode 100644 frontend/src/components/common/session-gate/index.tsx diff --git a/frontend/src/components/chat/index.tsx b/frontend/src/components/chat/index.tsx index fa065d63..792fb900 100644 --- a/frontend/src/components/chat/index.tsx +++ b/frontend/src/components/chat/index.tsx @@ -8,7 +8,7 @@ import { } from '@shared/core'; import DashboardPanel from '@components/common/dashboard-panel'; -import StateCard from '@components/pet/interactions/state-card'; +import SessionGate from '@components/common/session-gate'; import Icon, { MarriageIcon } from '@components/ui/icon'; import { CHAT_WS_URL } from '../../config'; import { sameAccount, shortAddress } from '@utils/address'; @@ -174,7 +174,7 @@ const Conversation: React.FC<{ thread: ChatThread; me: string }> = ({ thread, me */ const Chat: React.FC = () => { const navigate = useNavigate(); - const { isConnected, walletAddress } = useChainCapabilities(); + const { walletAddress } = useChainCapabilities(); const { threads, isLoading, error } = useChatThreads(); const [selectedId, setSelectedId] = useState(null); @@ -184,66 +184,59 @@ const Chat: React.FC = () => { ); const goBack = () => navigate(DASHBOARD_HOME); - - if (!isConnected) { - return ( - - - Messages - - } - description="Connect your wallet to see your conversations" - back={goBack} - /> - ); - } + const heading = ( + <> + + Messages + + ); return ( - - - Messages - - } - description="Private threads with the owners your pets are married to" + - {error ? ( -

      {error.message}

      - ) : isLoading ? ( -
      -
      -
      - ) : threads.length === 0 ? ( -

      - No conversations yet. Marry one of your pets to another player's to open - a thread with them. -

      - ) : ( -
      - - {selected && ( - + {error ? ( +

      {error.message}

      + ) : isLoading ? ( +
      +
      +
      + ) : threads.length === 0 ? ( +

      + No conversations yet. Marry one of your pets to another player's to open + a thread with them. +

      + ) : ( +
      + - )} -
      - )} - + {selected && ( + + )} +
      + )} + + ); }; diff --git a/frontend/src/components/common/index.ts b/frontend/src/components/common/index.ts index a665bd91..cb4f6e78 100644 --- a/frontend/src/components/common/index.ts +++ b/frontend/src/components/common/index.ts @@ -1,5 +1,6 @@ export { default as AuthActionButton } from './auth-action-button'; export { default as TransactionStatus } from './transaction-status'; export { default as DashboardPanel } from './dashboard-panel'; +export { default as SessionGate } from './session-gate'; // ui primitives re-exported for convenience export { NeonButton, NeonCard, NeonModal } from '@components/ui'; diff --git a/frontend/src/components/common/session-gate/index.tsx b/frontend/src/components/common/session-gate/index.tsx new file mode 100644 index 00000000..816aab1a --- /dev/null +++ b/frontend/src/components/common/session-gate/index.tsx @@ -0,0 +1,75 @@ +import React, { type ReactNode } from 'react'; +import { useAuth, useChainCapabilities } from '@shared/core'; + +import AuthActionButton from '@components/common/auth-action-button'; +import StateCard from '@components/pet/interactions/state-card'; +import type { NeonButtonTone } from '@components/ui/neon-button'; + +export type SessionGateProps = { + /** Panel heading, shown in every state so the screen keeps its identity. */ + title: ReactNode; + /** Shown when no wallet is connected. */ + connectPrompt: string; + /** Shown when a wallet is connected but the session is not signed in. */ + signInPrompt: string; + /** Accent for the sign-in button, matching the screen. */ + tone?: NeonButtonTone; + back: () => void; + children: ReactNode; +}; + +/** + * Gates a screen that cannot render without an authenticated session, and asks for + * whichever step is actually missing. + * + * These are two different states and were previously treated as one. A connected wallet + * is not a session: `/graphql` and `/api/chat` are JWT-gated, so a player who has + * connected but not signed the login message gets 401s. Screens that only checked + * `isConnected` rendered anyway and surfaced that as a raw error, or worse as an empty + * state — "No conversations yet" and "No battles on record yet" are both *wrong* when + * the real answer is "we have not asked who you are yet", and neither tells the player + * what to do about it. + * + * Signing in is one click, so this offers the button rather than an explanation. It is + * the same `AuthActionButton` the battle, breed and marriage panels already use, so the + * prompt reads the same wherever a player meets it. + */ +const SessionGate: React.FC = ({ + title, + connectPrompt, + signInPrompt, + tone = 'cyan', + back, + children, +}) => { + const { isConnected } = useChainCapabilities(); + const { isAuthenticated } = useAuth(); + + if (!isConnected) { + return ( + + ); + } + + if (!isAuthenticated) { + // Deliberately not the `wallet-disconnected` variant: that one routes the + // description into a centered slot and drops children, so the button would + // vanish. + return ( + + Sign in + + ); + } + + return <>{children}; +}; + +export default SessionGate; diff --git a/frontend/src/components/leaderboard/index.tsx b/frontend/src/components/leaderboard/index.tsx index 78984046..2442e2fc 100644 --- a/frontend/src/components/leaderboard/index.tsx +++ b/frontend/src/components/leaderboard/index.tsx @@ -7,7 +7,7 @@ import { } from '@shared/core'; import DashboardPanel from '@components/common/dashboard-panel'; -import StateCard from '@components/pet/interactions/state-card'; +import SessionGate from '@components/common/session-gate'; import PetArt from '@components/pet/pet-art'; import Icon, { TrophyIcon } from '@components/ui/icon'; import { DASHBOARD_HOME } from '@constants/interactionRoutes'; @@ -79,7 +79,7 @@ const Row: React.FC<{ */ const Leaderboard: React.FC = () => { const navigate = useNavigate(); - const { isConnected, activeKind, walletAddress } = useChainCapabilities(); + const { activeKind, walletAddress } = useChainCapabilities(); const [board, setBoard] = useState('pets'); const [page, setPage] = useState(0); @@ -92,24 +92,12 @@ const Leaderboard: React.FC = () => { const active = board === 'pets' ? pets : players; const goBack = () => navigate(DASHBOARD_HOME); - - if (!isConnected) { - return ( - - - Leaderboard - - } - description="Connect your wallet to see the rankings" - back={goBack} - /> - ); - } + const heading = ( + <> + + Leaderboard + + ); // `sameAccount` normalizes by address shape, so this needs no chain branch and cannot // merge two Solana pubkeys that differ only in case. @@ -125,106 +113,109 @@ const Leaderboard: React.FC = () => { const lastPage = Math.max(0, Math.ceil(active.total / active.pageSize) - 1); return ( - - - Leaderboard - - } - description="Ranked by wins, then by fewest losses" + -
      - {(['pets', 'players'] as const).map((tab) => ( - - ))} -
      - - {active.error ? ( -

      {active.error.message}

      - ) : active.isLoading ? ( -
      -
      + +
      + {(['pets', 'players'] as const).map((tab) => ( + + ))}
      - ) : active.total === 0 ? ( -

      - No battles on record yet. Win one and the board fills up. -

      - ) : ( - <> -
        - {board === 'pets' - ? pets.entries.map((entry) => ( - - } - title={entry.name} - sub={`Lv ${entry.level}`} - winCount={entry.winCount} - lossCount={entry.lossCount} - isYou={isYou(entry.owner)} - /> - )) - : players.entries.map((entry) => ( - - ))} -
      - {lastPage > 0 && ( -
      - - - Page {page + 1} of {lastPage + 1} - - -
      - )} - - )} -
      + {active.error ? ( +

      {active.error.message}

      + ) : active.isLoading ? ( +
      +
      +
      + ) : active.total === 0 ? ( +

      + No battles on record yet. Win one and the board fills up. +

      + ) : ( + <> +
        + {board === 'pets' + ? pets.entries.map((entry) => ( + + } + title={entry.name} + sub={`Lv ${entry.level}`} + winCount={entry.winCount} + lossCount={entry.lossCount} + isYou={isYou(entry.owner)} + /> + )) + : players.entries.map((entry) => ( + + ))} +
      + + {lastPage > 0 && ( +
      + + + Page {page + 1} of {lastPage + 1} + + +
      + )} + + )} + + ); }; diff --git a/frontend/tests/components/chat.test.tsx b/frontend/tests/components/chat.test.tsx index 9bc6e03a..823cc5d6 100644 --- a/frontend/tests/components/chat.test.tsx +++ b/frontend/tests/components/chat.test.tsx @@ -7,7 +7,10 @@ const useChainCapabilities = vi.fn(); const useChatThreads = vi.fn(); const useChatMessages = vi.fn(); +const useAuth = vi.fn(); + vi.mock('@shared/core', () => ({ + useAuth: () => useAuth(), // `@utils/address` normalizes through the protocol helper; the real one, since the // EVM-folds/base58-doesn't rule is what several of these assertions are about. normalizeAccount: (value: string) => (/^0x[0-9a-fA-F]{40}$/.test(value) ? value.toLowerCase() : value), @@ -69,6 +72,7 @@ const renderChat = () => beforeEach(() => { vi.clearAllMocks(); + useAuth.mockReturnValue({ isAuthenticated: true, signAndLogin: vi.fn() }); send.mockResolvedValue(undefined); useChainCapabilities.mockReturnValue({ isConnected: true, walletAddress: ME }); useChatThreads.mockReturnValue({ threads: [], isLoading: false, error: null }); @@ -85,6 +89,28 @@ describe('Chat', () => { }); // The normal state for most players, and it must not read as a failed load. + // A connected wallet is not a session: the API is JWT-gated, so rendering the panel + // here produced 401s surfaced as a raw error, or an empty state claiming there were + // no conversations when the truth was that nobody had signed in. + it('offers sign-in when the wallet is connected but the session is not', () => { + useAuth.mockReturnValue({ isAuthenticated: false, signAndLogin: vi.fn() }); + + renderChat(); + + expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument(); + expect(screen.queryByText(/Marry one of your pets/i)).toBeNull(); + }); + + it('starts the sign-in flow when the button is pressed', async () => { + const signAndLogin = vi.fn(); + useAuth.mockReturnValue({ isAuthenticated: false, signAndLogin }); + + renderChat(); + await userEvent.click(screen.getByRole('button', { name: /sign in/i })); + + expect(signAndLogin).toHaveBeenCalled(); + }); + it('explains how to get a thread when there are none', () => { renderChat(); diff --git a/frontend/tests/components/leaderboard.test.tsx b/frontend/tests/components/leaderboard.test.tsx index f24ebf8a..28fa5600 100644 --- a/frontend/tests/components/leaderboard.test.tsx +++ b/frontend/tests/components/leaderboard.test.tsx @@ -7,7 +7,10 @@ const useChainCapabilities = vi.fn(); const useLeaderboard = vi.fn(); const usePlayerLeaderboard = vi.fn(); +const useAuth = vi.fn(); + vi.mock('@shared/core', () => ({ + useAuth: () => useAuth(), // `@utils/address` normalizes through the protocol helper; the real one, since the // EVM-folds/base58-doesn't rule is what several of these assertions are about. normalizeAccount: (value: string) => (/^0x[0-9a-fA-F]{40}$/.test(value) ? value.toLowerCase() : value), @@ -50,6 +53,7 @@ const renderBoard = () => beforeEach(() => { vi.clearAllMocks(); + useAuth.mockReturnValue({ isAuthenticated: true, signAndLogin: vi.fn() }); useChainCapabilities.mockReturnValue({ isConnected: true, activeKind: 'evm', @@ -72,6 +76,17 @@ describe('Leaderboard', () => { expect(screen.getByText(/Connect your wallet/i)).toBeInTheDocument(); }); + // The empty state said "No battles on record yet", which is a claim about the game + // rather than about the session — wrong, and it left the player with nothing to do. + it('offers sign-in when the wallet is connected but the session is not', () => { + useAuth.mockReturnValue({ isAuthenticated: false, signAndLogin: vi.fn() }); + + renderBoard(); + + expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument(); + expect(screen.queryByText(/No battles on record yet/i)).toBeNull(); + }); + it('renders a pet row with its record and win rate', () => { useLeaderboard.mockReturnValue({ ...emptyResult, entries: [petEntry()], total: 1 }); From 5f6df12d555721de64d541b2e0379cb7dadd4007 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 14:34:00 -0400 Subject: [PATCH 27/61] feat: sync chatbot knowledge base with the expanded site content --- .../interactions/panels/_shared/pet-showcase.module.css | 9 ++++++--- .../pet/interactions/panels/train/index.module.css | 5 +++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css b/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css index 6e822a94..39ac5450 100644 --- a/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css +++ b/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css @@ -18,15 +18,18 @@ flex-shrink: 0; } +/* `font-size` is the real lever, not the box: PetArt renders generated art as a 1em + square, so the image tracks the type size and the box is only the frame around it. + The box grows with it to keep the float animation and the drop-shadow from clipping. */ .avatar { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; - width: 98px; - height: 98px; - font-size: 3.5rem; + width: 140px; + height: 140px; + font-size: 5.5rem; line-height: 1; border-radius: 18px; animation: cp-float 3.6s ease-in-out infinite; diff --git a/frontend/src/components/pet/interactions/panels/train/index.module.css b/frontend/src/components/pet/interactions/panels/train/index.module.css index 27eb9052..bdc7f595 100644 --- a/frontend/src/components/pet/interactions/panels/train/index.module.css +++ b/frontend/src/components/pet/interactions/panels/train/index.module.css @@ -16,7 +16,7 @@ .visual { position: relative; flex-shrink: 0; - width: 96px; + width: 128px; display: flex; align-items: center; justify-content: center; @@ -39,8 +39,9 @@ font-weight: 700; } +/* See the note in _shared/pet-showcase.module.css: the art is 1em, so this sizes it. */ .avatar { - font-size: 2.6rem; + font-size: 4rem; line-height: 1; animation: cp-float 3.5s ease-in-out infinite; filter: drop-shadow(0 0 18px rgb(125 214 255 / 60%)); From 76337ff6edc227ed70ec68c4111d0421e81c747d Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 14:39:56 -0400 Subject: [PATCH 28/61] ui: round the pet art on rename, level-up and train --- .../interactions/panels/_shared/pet-showcase.module.css | 8 ++++++++ .../pet/interactions/panels/train/index.module.css | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css b/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css index 39ac5450..b0d27d30 100644 --- a/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css +++ b/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css @@ -36,6 +36,14 @@ filter: drop-shadow(0 0 28px rgb(var(--sc-accent) / 80%)); } +/* Rounds the generated art itself, not just the frame around it. The frame's own + radius never showed, because the image is smaller than its box and so never reaches + the corners. Targets the `img` specifically: the emoji fallback is text, where a + radius would do nothing, and rounding it would be meaningless anyway. */ +.avatar img { + border-radius: 18px; +} + /* Local copy of the shared float keyframe (kept in-module so the scoped animation-name resolves). */ @keyframes cp-float { diff --git a/frontend/src/components/pet/interactions/panels/train/index.module.css b/frontend/src/components/pet/interactions/panels/train/index.module.css index bdc7f595..077a2290 100644 --- a/frontend/src/components/pet/interactions/panels/train/index.module.css +++ b/frontend/src/components/pet/interactions/panels/train/index.module.css @@ -47,6 +47,12 @@ filter: drop-shadow(0 0 18px rgb(125 214 255 / 60%)); } +/* Matches `.visual`'s radius so the art echoes the frame it sits in. `.visual` already + clips, but the art is smaller than the panel and never touches those corners. */ +.avatar img { + border-radius: 10px; +} + .body { flex: 1; min-width: 0; From f9ad2d5a250fc2e48329b1ed4c6db6ce4d5c6ee9 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 14:44:41 -0400 Subject: [PATCH 29/61] fix(frontend): keep the message composer on the bottom edge in every state --- frontend/src/components/chat/index.module.css | 20 +++++++++++++++++++ frontend/src/components/chat/index.tsx | 6 ++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/chat/index.module.css b/frontend/src/components/chat/index.module.css index cfa7ec04..674256ce 100644 --- a/frontend/src/components/chat/index.module.css +++ b/frontend/src/components/chat/index.module.css @@ -169,11 +169,19 @@ font-variant-numeric: tabular-nums; } +/* Pinned to the bottom of the card by the region above it filling, not by absolute + positioning. An absolutely positioned bar sits on top of the transcript unless the + scroll area reserves exactly its height, and that reservation has to be re-tuned by + hand every time the composer's padding, font or error line changes — it silently + covers the newest message when it drifts. `flex-shrink: 0` is the part that matters: + it keeps the bar at its natural height instead of being squeezed by a long + transcript. */ .composer { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid rgb(148 163 184 / 12%); + flex-shrink: 0; } .composer input { @@ -204,6 +212,18 @@ cursor: default; } +/* The transcript's stand-in states. They take the same space the message list would, so + the composer stays on the bottom edge whether the thread is loading, empty, or broken + — previously these hugged their one line of text and the composer rode up with them. */ +.placeholder { + flex: 1; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + text-align: center; +} + .empty, .error { margin: 20px 14px; diff --git a/frontend/src/components/chat/index.tsx b/frontend/src/components/chat/index.tsx index 792fb900..a0e6c44f 100644 --- a/frontend/src/components/chat/index.tsx +++ b/frontend/src/components/chat/index.tsx @@ -117,13 +117,15 @@ const Conversation: React.FC<{ thread: ChatThread; me: string }> = ({ thread, me {error ? ( -

      {error.message}

      +

      {error.message}

      ) : isLoading ? (
      ) : messages.length === 0 ? ( -

      No messages yet. Say hello.

      +

      + No messages yet. Say hello. +

      ) : (
        {messages.map((message) => ( From 750cbeb61574dd786ec99dedab1e6b4975dfcf47 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 14:52:36 -0400 Subject: [PATCH 30/61] feat(frontend): show a spinner while pet art is still loading --- .../src/components/pet/pet-art.module.css | 30 +++++++++++ frontend/src/components/pet/pet-art.tsx | 24 +++++++-- .../tests/components/pet/pet-art.test.tsx | 54 +++++++++++++++---- 3 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 frontend/src/components/pet/pet-art.module.css diff --git a/frontend/src/components/pet/pet-art.module.css b/frontend/src/components/pet/pet-art.module.css new file mode 100644 index 00000000..dae29c7a --- /dev/null +++ b/frontend/src/components/pet/pet-art.module.css @@ -0,0 +1,30 @@ +/* CSS Module — class names are local; reference via `import styles from './pet-art.module.css'`. + Placeholder shown while a pet's generated art is still on its way. */ + +/* Sized in em, like the art itself, so it tracks whatever font-size the caller set — + PetArt is rendered at 1em in a leaderboard row, at 5.5rem in the rename hero, and + filling a card in the gallery. A fixed pixel size would be a speck in one and a slab + in another. */ +.spinner { + width: 0.45em; + height: 0.45em; + box-sizing: border-box; + border: 0.07em solid rgb(125 214 255 / 22%); + border-block-start-color: var(--cp-cyan, #7dd6ff); + border-radius: 50%; + animation: cp-art-spin 0.9s linear infinite; +} + +@keyframes cp-art-spin { + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: reduce) { + /* A still ring still reads as "something belongs here and has not arrived", which is + the whole job. */ + .spinner { + animation: none; + } +} diff --git a/frontend/src/components/pet/pet-art.tsx b/frontend/src/components/pet/pet-art.tsx index 4daf73cc..8587a972 100644 --- a/frontend/src/components/pet/pet-art.tsx +++ b/frontend/src/components/pet/pet-art.tsx @@ -1,6 +1,8 @@ import React, { useEffect, useRef, useState } from 'react'; import { getPetAvatar, petArtUrl as buildPetArtUrl, type Pet } from '@shared/core'; +import styles from './pet-art.module.css'; + /** * A pet's generated art, falling back to its emoji avatar. * @@ -10,9 +12,13 @@ import { getPetAvatar, petArtUrl as buildPetArtUrl, type Pet } from '@shared/cor * can resolve, and the image actually loads. Any of those failing leaves the UI * exactly as it was rather than showing a broken frame. * - * The emoji also covers the first-ever request for a pet, which is slow: art is - * generated on demand and the response can take seconds. Showing the emoji until - * the image arrives beats an empty box. + * While art is *on its way*, a spinner holds the space rather than the emoji. The + * two cases look the same to a viewer but are not: an emoji is a final answer for + * a pet with no art, whereas a pet whose first-ever request is still generating — + * which takes seconds — has art coming. Showing the emoji there presented a + * placeholder as the finished thing and then swapped it out under the reader. + * The emoji still covers every case where nothing is coming: no service + * configured, no identifier to resolve, or the image gave up after its retry. * * Sizing is inherited, not declared: the image is 1em square, so it matches * whatever font-size the surrounding avatar style already sets, and no CSS @@ -96,7 +102,15 @@ const PetArt: React.FC = ({ pet, fill = false, emojiClassName }) => if (!url || failed) return <>{emojiNode}; - // The emoji and the image share one grid cell, so they stack without a + // Deliberately not given `emojiClassName`: that class carries glyph decoration + // (size, glow, float) meant for text, and a spinner wearing it reads as a bug. + const pending = ( + + + + ); + + // The placeholder and the image share one grid cell, so they stack without a // wrapper that reserves its own space, and swapping them causes no layout // shift. The image is hidden with opacity rather than `display: none` // specifically because it must keep a layout box: `loading="lazy"` defers @@ -104,7 +118,7 @@ const PetArt: React.FC = ({ pet, fill = false, emojiClassName }) => // nothing to intersect, so hiding it that way risks never loading it at all. return ( - {loaded ? null : {emojiNode}} + {loaded ? null : pending} { expect(screen.queryByRole('img')).toBeNull(); }); - // Art is generated on demand, so the first request for a pet can take - // seconds. The emoji covers that rather than leaving an empty frame. - it('keeps showing the emoji until the image has loaded', async () => { + // Art is generated on demand, so the first request for a pet can take seconds. A + // spinner holds the frame for that wait rather than the emoji: the emoji is the + // final answer for a pet with no art, and showing it here presented a placeholder + // as the finished thing and then swapped it under the reader. + it('shows a spinner, not the emoji, until the image has loaded', async () => { const PetArt = await loadPetArt(); - render(); + const { container } = render(); - expect(screen.getByText('🦉')).toBeInTheDocument(); + expect(container.querySelector('[class*="spinner"]')).not.toBeNull(); + expect(screen.queryByText('🦉')).toBeNull(); expect(screen.getByRole('img')).toHaveStyle({ opacity: '0' }); fireEvent.load(screen.getByRole('img')); - expect(screen.queryByText('🦉')).toBeNull(); + expect(container.querySelector('[class*="spinner"]')).toBeNull(); expect(screen.getByRole('img')).toHaveStyle({ opacity: '1' }); }); + // The spinner is scenery, and the image already carries the pet's name as alt text. + it('hides the spinner from assistive technology', async () => { + const PetArt = await loadPetArt(); + const { container } = render(); + + expect(container.querySelector('[class*="spinner"]')?.closest('[aria-hidden]')).not.toBeNull(); + }); + // loading="lazy" defers until the element nears the viewport, so the image // must keep a layout box while hidden. display:none would leave nothing to // intersect, and the image could never load at all. @@ -174,11 +185,36 @@ describe('PetArt', () => { // absolutely positioned descendants, so wrapping PetArt in it // trapped the filling image at emoji size and the art never reached // the frame. The class has to land on the glyph. + // + // Checked on the failed path, because that is when the emoji renders now. + vi.useFakeTimers(); + try { + const PetArt = await loadPetArt(); + const { container } = render( + , + ); + + fireEvent.error(screen.getByRole('img')); + act(() => { vi.advanceTimersByTime(30_000); }); + fireEvent.error(screen.getByRole('img')); + + expect(screen.getByText('🦉')).toHaveClass('avatar-cls'); + expect(container.querySelector('.avatar-cls img')).toBeNull(); + } finally { + vi.useRealTimers(); + } + }); + + it('does not put the caller glyph class on the loading spinner', async () => { + // That class carries glyph decoration (size, glow, float); a spinner + // wearing it reads as a rendering bug rather than as progress. const PetArt = await loadPetArt(); - render(); + const { container } = render( + , + ); - expect(screen.getByText('🦉')).toHaveClass('avatar-cls'); - expect(screen.getByRole('img').closest('.avatar-cls')).toBeNull(); + expect(container.querySelector('.avatar-cls')).toBeNull(); + expect(container.querySelector('[class*="spinner"]')).not.toBeNull(); }); it('still falls back to the emoji when filling and the image fails', async () => { From 8eb77f436a23c44228b5504b9f3f53f3caf9e2be Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 15:22:03 -0400 Subject: [PATCH 31/61] fix(frontend): give the signed-out message and leaderboard panels full height --- .../common/session-gate/index.module.css | 19 +++++++++++++++++++ .../components/common/session-gate/index.tsx | 15 +++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/common/session-gate/index.module.css diff --git a/frontend/src/components/common/session-gate/index.module.css b/frontend/src/components/common/session-gate/index.module.css new file mode 100644 index 00000000..5580efeb --- /dev/null +++ b/frontend/src/components/common/session-gate/index.module.css @@ -0,0 +1,19 @@ +/* CSS Module — class names are local; reference via `import styles from './index.module.css'`. */ + +/* The gate's cards stand in for a full screen, so they take the same height the screen + would. Without this they sized to their own text and left a short card floating in an + otherwise empty panel — the same "flex is inert in the shell's block content slot" + reason the panels themselves carry `height: 100%` rather than a flex rule. */ +.fill { + height: 100%; +} + +/* The connect-wallet variant routes its description into DashboardPanel's `.state-body`, + which already centres. The sign-in variant renders into `.panel-body`, which does not, + so a full-height card would strand the prompt and its button against the top edge. */ +.signIn :global(.panel-body) { + align-items: center; + justify-content: center; + gap: 14px; + text-align: center; +} diff --git a/frontend/src/components/common/session-gate/index.tsx b/frontend/src/components/common/session-gate/index.tsx index 816aab1a..2cd66968 100644 --- a/frontend/src/components/common/session-gate/index.tsx +++ b/frontend/src/components/common/session-gate/index.tsx @@ -4,6 +4,7 @@ import { useAuth, useChainCapabilities } from '@shared/core'; import AuthActionButton from '@components/common/auth-action-button'; import StateCard from '@components/pet/interactions/state-card'; import type { NeonButtonTone } from '@components/ui/neon-button'; +import styles from './index.module.css'; export type SessionGateProps = { /** Panel heading, shown in every state so the screen keeps its identity. */ @@ -48,9 +49,10 @@ const SessionGate: React.FC = ({ if (!isConnected) { return ( = ({ // description into a centered slot and drops children, so the button would // vanish. return ( - + Sign in ); From 85c28bbfb38e0ef16ef02055a5fafcbf7e4aa5b4 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 15:29:16 -0400 Subject: [PATCH 32/61] fix(frontend): give the standalone interaction panels full height --- .../src/components/pet/interactions/interactions.css | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/pet/interactions/interactions.css b/frontend/src/components/pet/interactions/interactions.css index 9c804793..3aa026ee 100644 --- a/frontend/src/components/pet/interactions/interactions.css +++ b/frontend/src/components/pet/interactions/interactions.css @@ -16,9 +16,17 @@ as the battle showdown), so every panel shares the uniform slot padding rather than a narrow centered cap. `max-height: 100%` bounds the panel to the slot so its body scrolls internally instead of the whole panel growing - past the header. */ + past the header. + + `height: 100%` is what makes it *reach* that bound. The panel already declares + `flex: 1 1 auto`, but the shell's content slot is a scrollable block rather than + a flex container, so that rule is inert and the panel used to size to its + content — short screens like rename left a small card stranded in an empty slot, + and the height jumped between screens. The percentage resolves against the + slot's content box, which lands the panel inside the shell's padding. */ &.interaction-standalone { max-width: 100%; + height: 100%; max-height: 100%; } From e1020edb35d294210bced04fd112df51febf9d67 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 15:52:19 -0400 Subject: [PATCH 33/61] feat(frontend): two-column layout for the level-up, train and breed panels --- .../pet/interactions/interactions.css | 83 +++++++++++++++++++ .../panels/breed/index.module.css | 11 ++- .../interactions/panels/level-up/index.tsx | 4 + .../pet/interactions/panels/train/index.tsx | 2 +- 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/pet/interactions/interactions.css b/frontend/src/components/pet/interactions/interactions.css index 3aa026ee..d19a57f0 100644 --- a/frontend/src/components/pet/interactions/interactions.css +++ b/frontend/src/components/pet/interactions/interactions.css @@ -186,6 +186,89 @@ `interaction-standalone--` sets a wash + accent; the shared chrome below left-aligns the title bar to match the redesign mock. ============================================================================= */ +/* Breed lays its own tabs and parent columns out, so it takes only the pinned action: + on the spouse tab the button lives here rather than in the DNA centre. */ +.dashboard-panel.pet-interactions.interaction-standalone--breed .action-controls { + margin-top: auto; + padding-top: 18px; + border-top: 1px solid var(--zi-border); +} + +/* ========================================================================== + Single-pet action screens (level-up, train): pet column beside the controls, + primary action across the bottom. + + These panels are one short form in a very wide slot, so a single stacked column + left most of the panel empty. The pet block becomes a fixed-width left column, + the picker takes the rest, and the action sits on the bottom edge under a rule — + `margin-top: auto` rather than absolute positioning, so it is pushed down by the + free space instead of overlapping content when there is none. + + Scoped with `:has(.interaction-visual)`: with no pet selected there is nothing to + put in the left column, and the form stays a single column. + ========================================================================== */ +.dashboard-panel.pet-interactions.interaction-standalone--levelup .interface, +.dashboard-panel.pet-interactions.interaction-standalone--train .interface { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; +} + +.dashboard-panel.pet-interactions.interaction-standalone--levelup .interface .action-controls, +.dashboard-panel.pet-interactions.interaction-standalone--train .interface .action-controls { + margin-top: auto; + padding-top: 18px; + border-top: 1px solid var(--zi-border); +} + +@media (min-width: 900px) { + .dashboard-panel.pet-interactions.interaction-standalone--levelup + .interface:has(.interaction-visual), + .dashboard-panel.pet-interactions.interaction-standalone--train + .interface:has(.interaction-visual) { + display: grid; + grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); + grid-template-rows: 1fr auto; + column-gap: 32px; + /* Both columns ride in the middle of the free row rather than hugging the top, + so the leftover height is shared above and below instead of pooling under + the form. */ + align-items: center; + } + + .interaction-standalone--levelup .interface .interaction-visual, + .interaction-standalone--train .interface .interaction-visual { + grid-column: 1; + grid-row: 1; + } + + /* Roomy enough for the pet column not to feel cramped, but the panel can be very + wide and a lone select stretched across it reads as a mistake. */ + .interaction-standalone--levelup .interface .picker, + .interaction-standalone--train .interface .picker { + max-width: 460px; + } + + .interaction-standalone--levelup .interface .picker, + .interaction-standalone--train .interface .picker { + grid-column: 2; + grid-row: 1; + /* One column of its own: the outer grid already splits the panel, so the + picker's own two-up grid would put the select and the cost side by side in + half the width. */ + grid-template-columns: minmax(0, 1fr); + margin-bottom: 0; + } + + .interaction-standalone--levelup .interface .action-controls, + .interaction-standalone--train .interface .action-controls { + grid-column: 1 / -1; + grid-row: 2; + align-self: end; + } +} + .interaction-standalone--battle { --view-wash: var(--cp-wash-battle); --view-accent: 255 123 203; diff --git a/frontend/src/components/pet/interactions/panels/breed/index.module.css b/frontend/src/components/pet/interactions/panels/breed/index.module.css index b325abe4..88923d9d 100644 --- a/frontend/src/components/pet/interactions/panels/breed/index.module.css +++ b/frontend/src/components/pet/interactions/panels/breed/index.module.css @@ -65,11 +65,15 @@ color: #ffd07b; } +/* Fills the panel rather than sitting at the top of it, so the two parents and the DNA + centre between them use the height instead of leaving it empty below. */ .tabPanel { padding-top: 18px; display: flex; flex-direction: column; gap: 14px; + flex: 1; + min-height: 0; } .tabHint { @@ -142,12 +146,17 @@ } /* ── Parent A · egg · Parent B preview (real stats) ─────────────────────────── */ +/* Takes the slack inside the tab panel and centres the pair in it. `align-items: center` + also keeps the DNA centre — which carries the breed action on this tab — level with the + two parent cards rather than riding at their top edge. */ .parents { display: grid; grid-template-columns: 1fr auto 1fr; - align-items: start; + align-items: center; gap: 12px; margin-bottom: 10px; + flex: 1; + min-height: 0; } /* Parent column = card + Prev/Next cycle row (mock-style selection) */ diff --git a/frontend/src/components/pet/interactions/panels/level-up/index.tsx b/frontend/src/components/pet/interactions/panels/level-up/index.tsx index 4b8a5158..b22996dd 100644 --- a/frontend/src/components/pet/interactions/panels/level-up/index.tsx +++ b/frontend/src/components/pet/interactions/panels/level-up/index.tsx @@ -110,6 +110,9 @@ const LevelUpPanel: React.FC = ({ isStandaloneView = true }) )} {selectedPetObj && ( + // `interaction-visual` is the layout hook: it marks the pet column + // for the two-column rule in interactions.css. +
        } accent="violet">
        {selectedPetObj.name}
        {getPetClass(selectedPetObj.dna)}
        @@ -139,6 +142,7 @@ const LevelUpPanel: React.FC = ({ isStandaloneView = true })
      +
      )}
      diff --git a/frontend/src/components/pet/interactions/panels/train/index.tsx b/frontend/src/components/pet/interactions/panels/train/index.tsx index f34eb148..82254e29 100644 --- a/frontend/src/components/pet/interactions/panels/train/index.tsx +++ b/frontend/src/components/pet/interactions/panels/train/index.tsx @@ -93,7 +93,7 @@ const TrainPanel: React.FC = ({ isStandaloneView = true }) => { )} {selectedPetObj && ( -
      +
      Lv.{selectedPetObj.level} From c535dc1f74ea29f913f9764b2f88aabd41c2a5fb Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 16:05:55 -0400 Subject: [PATCH 34/61] fix(frontend): keep the level-up and train layout fixed as a pet is selected --- .../pet/interactions/interactions.css | 79 +++++++++++++++++-- .../interactions/panels/level-up/index.tsx | 36 ++++++++- .../pet/interactions/panels/train/index.tsx | 69 ++++++++++------ 3 files changed, 152 insertions(+), 32 deletions(-) diff --git a/frontend/src/components/pet/interactions/interactions.css b/frontend/src/components/pet/interactions/interactions.css index d19a57f0..3da9f02b 100644 --- a/frontend/src/components/pet/interactions/interactions.css +++ b/frontend/src/components/pet/interactions/interactions.css @@ -186,6 +186,75 @@ `interaction-standalone--` sets a wash + accent; the shared chrome below left-aligns the title bar to match the redesign mock. ============================================================================= */ +/* Placeholder for the pet slot before a pet is chosen. + * + * Built from the filled state's own classes in each panel, so the empty and filled + * cards are the same height by construction. Only the bars and the glyph are new. + * + * It occupies exactly the space the real pet block will, which is the point: the slot is + * never empty, so the panel does not reshape when a pet is picked and nothing around it + * moves. That also lets the two-column rule below apply unconditionally rather than + * switching layouts on selection. + */ +.pet-slot-glyph { + font-weight: 700; + color: rgb(195 210 255 / 45%); +} + +.skeleton-bar { + /* Inline-block so it can sit inside the same text rows the filled state uses and + still take a width and height. */ + display: inline-block; + vertical-align: middle; + height: 12px; + border-radius: 999px; + background: linear-gradient( + 90deg, + rgb(125 214 255 / 8%), + rgb(125 214 255 / 18%), + rgb(125 214 255 / 8%) + ); + background-size: 200% 100%; + animation: cp-skeleton 1.6s ease-in-out infinite; +} + +/* Fixed widths, not percentages: these sit inside shrink-to-fit rows (the showcase is a + centred flex column), where a percentage resolves against a zero-width parent and the + bar disappears. */ +.skeleton-bar.wide { + width: 132px; +} + +.skeleton-bar.narrow { + width: 84px; +} + +.skeleton-bar.full { + width: 100%; + min-width: 120px; +} + +.pet-slot-hint { + margin: 4px 0 0; + font-size: 12px; + color: rgb(195 210 255 / 55%); +} + +@keyframes cp-skeleton { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} + +@media (prefers-reduced-motion: reduce) { + .skeleton-bar { + animation: none; + } +} + /* Breed lays its own tabs and parent columns out, so it takes only the pinned action: on the spouse tab the button lives here rather than in the DNA centre. */ .dashboard-panel.pet-interactions.interaction-standalone--breed .action-controls { @@ -204,8 +273,8 @@ `margin-top: auto` rather than absolute positioning, so it is pushed down by the free space instead of overlapping content when there is none. - Scoped with `:has(.interaction-visual)`: with no pet selected there is nothing to - put in the left column, and the form stays a single column. + The pet column is always rendered — a placeholder stands in before a pet is chosen — + so this layout does not switch on selection and nothing moves when a pet is picked. ========================================================================== */ .dashboard-panel.pet-interactions.interaction-standalone--levelup .interface, .dashboard-panel.pet-interactions.interaction-standalone--train .interface { @@ -223,10 +292,8 @@ } @media (min-width: 900px) { - .dashboard-panel.pet-interactions.interaction-standalone--levelup - .interface:has(.interaction-visual), - .dashboard-panel.pet-interactions.interaction-standalone--train - .interface:has(.interaction-visual) { + .dashboard-panel.pet-interactions.interaction-standalone--levelup .interface, + .dashboard-panel.pet-interactions.interaction-standalone--train .interface { display: grid; grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); grid-template-rows: 1fr auto; diff --git a/frontend/src/components/pet/interactions/panels/level-up/index.tsx b/frontend/src/components/pet/interactions/panels/level-up/index.tsx index b22996dd..8956228d 100644 --- a/frontend/src/components/pet/interactions/panels/level-up/index.tsx +++ b/frontend/src/components/pet/interactions/panels/level-up/index.tsx @@ -109,10 +109,38 @@ const LevelUpPanel: React.FC = ({ isStandaloneView = true }) )} + {/* The slot is always rendered, with a placeholder standing in before a + pet is chosen, so picking one swaps content into a box that is + already the right size and nothing on the panel shifts. */} +
      + {!selectedPetObj && ( + // Built from the same classes as the filled state rather than from + // its own skeleton layout, so the two are the same height by + // construction instead of by hand-matched numbers that drift. + ?} accent="violet"> +
      + +
      +
      + +
      +
      + Lv.? + + → + + Lv.? +
      +
      +
      + XP + +
      +
      +
      + + )} {selectedPetObj && ( - // `interaction-visual` is the layout hook: it marks the pet column - // for the two-column rule in interactions.css. -
      } accent="violet">
      {selectedPetObj.name}
      {getPetClass(selectedPetObj.dna)}
      @@ -142,8 +170,8 @@ const LevelUpPanel: React.FC = ({ isStandaloneView = true })
      -
      )} +
      diff --git a/frontend/src/components/pet/interactions/panels/train/index.tsx b/frontend/src/components/pet/interactions/panels/train/index.tsx index 82254e29..001825eb 100644 --- a/frontend/src/components/pet/interactions/panels/train/index.tsx +++ b/frontend/src/components/pet/interactions/panels/train/index.tsx @@ -92,31 +92,56 @@ const TrainPanel: React.FC = ({ isStandaloneView = true }) => { )} - {selectedPetObj && ( -
      -
      - Lv.{selectedPetObj.level} + {/* Always rendered, with a placeholder before a pet is chosen: the card + keeps its size either way, so selecting a pet moves nothing. */} +
      +
      + {selectedPetObj ? ( + <> + Lv.{selectedPetObj.level} + + + + + ) : ( - + ? -
      -
      -
      {selectedPetObj.name}
      -
      - {getPetClass(selectedPetObj.dna)} -
      -
      -
      -
      -
      - {selectedXp?.xpCurrent}/{selectedXp?.xpMax} XP -
      -
      + )}
      - )} +
      + {selectedPetObj ? ( + <> +
      {selectedPetObj.name}
      +
      + {getPetClass(selectedPetObj.dna)} +
      +
      +
      +
      +
      + {selectedXp?.xpCurrent}/{selectedXp?.xpMax} XP +
      + + ) : ( + // Same classes as the filled state, so both are the same + // height by construction rather than by matched numbers. + <> +
      + +
      +
      + +
      +
      +
      Select a pet to see its XP
      + + )} +
      +
      From 877c17b4f5544fc86a29d201674912e5593510e8 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 16:15:29 -0400 Subject: [PATCH 35/61] feat(frontend): enlarge the pet art in the level-up and train columns --- .../components/pet/interactions/interactions.css | 16 ++++++++++++++++ .../panels/_shared/pet-showcase.module.css | 14 ++++++++------ .../interactions/panels/train/index.module.css | 9 +++++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/pet/interactions/interactions.css b/frontend/src/components/pet/interactions/interactions.css index 3da9f02b..24677225 100644 --- a/frontend/src/components/pet/interactions/interactions.css +++ b/frontend/src/components/pet/interactions/interactions.css @@ -310,6 +310,22 @@ grid-row: 1; } + /* The pet gets its own column here, so the art can be far larger than in the + single-column layout these panels fall back to. This is the space the screen was + wasting. */ + .interaction-standalone--levelup .interface .interaction-visual { + --sc-size: 260px; + } + + /* Train's card stacks in a narrow column: side by side, the art could never be more + than half the column wide. */ + .interaction-standalone--train .interface .interaction-visual { + --tr-dir: column; + --tr-visual: 100%; + --tr-visual-ratio: 1; + --tr-art: 10rem; + } + /* Roomy enough for the pet column not to feel cramped, but the panel can be very wide and a lone select stretched across it reads as a mistake. */ .interaction-standalone--levelup .interface .picker, diff --git a/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css b/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css index b0d27d30..f2bafc4c 100644 --- a/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css +++ b/frontend/src/components/pet/interactions/panels/_shared/pet-showcase.module.css @@ -18,18 +18,20 @@ flex-shrink: 0; } -/* `font-size` is the real lever, not the box: PetArt renders generated art as a 1em - square, so the image tracks the type size and the box is only the frame around it. - The box grows with it to keep the float animation and the drop-shadow from clipping. */ +/* One knob, `--sc-size`, sizes the frame; the art follows from it. + `font-size` is the real lever for the art, not the box: PetArt renders generated art as + a 1em square, so the image tracks the type size. Deriving it keeps the two in step, and + leaves the frame enough margin that the float animation and drop-shadow do not clip. + Callers that want a larger hero set `--sc-size` on an ancestor. */ .avatar { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; - width: 140px; - height: 140px; - font-size: 5.5rem; + width: var(--sc-size, 140px); + height: var(--sc-size, 140px); + font-size: calc(var(--sc-size, 140px) * 0.62); line-height: 1; border-radius: 18px; animation: cp-float 3.6s ease-in-out infinite; diff --git a/frontend/src/components/pet/interactions/panels/train/index.module.css b/frontend/src/components/pet/interactions/panels/train/index.module.css index 077a2290..a08fb6cb 100644 --- a/frontend/src/components/pet/interactions/panels/train/index.module.css +++ b/frontend/src/components/pet/interactions/panels/train/index.module.css @@ -1,8 +1,12 @@ /* CSS Module — class names are local; reference via `import styles from './index.module.css'`. Train pet-status card — avatar + name/class + XP (cyan accent). Shared chrome (.interface/.picker/.field/.action-controls) stays global in interactions.css. */ +/* `--tr-*` are the knobs the two-column layout turns (see interactions.css): in a narrow + pet column the card stacks and the art grows, while the default stays the wide + avatar-beside-stats card this panel uses on its own. */ .status { display: flex; + flex-direction: var(--tr-dir, row); align-items: stretch; gap: 14px; margin-bottom: 18px; @@ -16,7 +20,8 @@ .visual { position: relative; flex-shrink: 0; - width: 128px; + width: var(--tr-visual, 128px); + aspect-ratio: var(--tr-visual-ratio, auto); display: flex; align-items: center; justify-content: center; @@ -41,7 +46,7 @@ /* See the note in _shared/pet-showcase.module.css: the art is 1em, so this sizes it. */ .avatar { - font-size: 4rem; + font-size: var(--tr-art, 4rem); line-height: 1; animation: cp-float 3.5s ease-in-out infinite; filter: drop-shadow(0 0 18px rgb(125 214 255 / 60%)); From 875c27c35534027fdcb3d180f17343fd8ae0f98e Mon Sep 17 00:00:00 2001 From: heyradcode Date: Thu, 6 Aug 2026 16:38:48 -0400 Subject: [PATCH 36/61] feat(frontend): replace the pet select with a neon pet picker --- .../interactions/panels/level-up/index.tsx | 16 +- .../pet/interactions/panels/train/index.tsx | 16 +- frontend/src/components/ui/index.ts | 2 + .../components/ui/pet-select/index.module.css | 160 ++++++++++++ .../src/components/ui/pet-select/index.tsx | 235 ++++++++++++++++++ .../pet/interactions/panels/level-up.test.tsx | 26 +- .../pet/interactions/panels/train.test.tsx | 20 +- 7 files changed, 446 insertions(+), 29 deletions(-) create mode 100644 frontend/src/components/ui/pet-select/index.module.css create mode 100644 frontend/src/components/ui/pet-select/index.tsx diff --git a/frontend/src/components/pet/interactions/panels/level-up/index.tsx b/frontend/src/components/pet/interactions/panels/level-up/index.tsx index 8956228d..fa84705b 100644 --- a/frontend/src/components/pet/interactions/panels/level-up/index.tsx +++ b/frontend/src/components/pet/interactions/panels/level-up/index.tsx @@ -2,6 +2,7 @@ import React, { useMemo, useState } from 'react'; import clsx from 'clsx'; import TransactionStatus from '@components/common/transaction-status'; import NeonButton from '@components/ui/neon-button'; +import PetSelect from '@components/ui/pet-select'; import { getPetClass, getReadyPetsUnified, @@ -176,18 +177,13 @@ const LevelUpPanel: React.FC = ({ isStandaloneView = true })
      - + onChange={setSelectedPet} + placeholder="Select a pet to level up" + />
      {levelUpCost &&

      Cost: {levelUpCost}

      }
      diff --git a/frontend/src/components/pet/interactions/panels/train/index.tsx b/frontend/src/components/pet/interactions/panels/train/index.tsx index 001825eb..7dc5a4e5 100644 --- a/frontend/src/components/pet/interactions/panels/train/index.tsx +++ b/frontend/src/components/pet/interactions/panels/train/index.tsx @@ -1,6 +1,7 @@ import React, { useMemo, useState } from 'react'; import TransactionStatus from '@components/common/transaction-status'; import NeonButton from '@components/ui/neon-button'; +import PetSelect from '@components/ui/pet-select'; import { getPetClass, getReadyPetsUnified, @@ -146,18 +147,13 @@ const TrainPanel: React.FC = ({ isStandaloneView = true }) => {
      - + onChange={setSelectedPet} + placeholder="Select a pet to train" + />
      {trainCost &&

      Cost: {trainCost}

      }
      diff --git a/frontend/src/components/ui/index.ts b/frontend/src/components/ui/index.ts index 9256d925..73233cf1 100644 --- a/frontend/src/components/ui/index.ts +++ b/frontend/src/components/ui/index.ts @@ -5,3 +5,5 @@ export { default as Icon } from './icon'; export { ToastProvider, useToast } from './toast'; export { default as PetSearchDropdown } from './pet-search-dropdown'; export type { PetSearchDropdownProps } from './pet-search-dropdown'; +export { default as PetSelect } from './pet-select'; +export type { PetSelectOption, PetSelectProps } from './pet-select'; diff --git a/frontend/src/components/ui/pet-select/index.module.css b/frontend/src/components/ui/pet-select/index.module.css new file mode 100644 index 00000000..c1d312c0 --- /dev/null +++ b/frontend/src/components/ui/pet-select/index.module.css @@ -0,0 +1,160 @@ +/* CSS Module — class names are local; reference via `import styles from './index.module.css'`. + Pet picker, styled to match the neon chrome the rest of the interaction panels use + (see ui/pet-search-dropdown, which this deliberately echoes so the two read as one + control rather than two different widgets). */ + +.trigger { + display: flex; + align-items: center; + gap: 10px; + width: 100%; + min-height: 46px; + padding: 6px 38px 6px 8px; + border: 1px solid rgb(125 214 255 / 28%); + border-radius: 4px; + background: rgb(4 10 26 / 96%); + box-shadow: inset 0 0 20px rgb(125 214 255 / 4%), inset 0 1px 0 rgb(125 214 255 / 8%); + color: #f6f3ff; + font: inherit; + text-align: left; + cursor: pointer; + position: relative; + transition: border-color 0.2s ease, box-shadow 0.2s ease; +} + +.trigger:hover:not(.disabled) { + border-color: rgb(125 214 255 / 55%); + box-shadow: inset 0 0 20px rgb(125 214 255 / 7%), 0 0 10px rgb(125 214 255 / 14%); +} + +.trigger:focus-visible, +.trigger.isOpen { + outline: none; + border-color: var(--cp-cyan); + box-shadow: 0 0 0 2px var(--cp-cyan), 0 0 12px rgb(125 214 255 / 32%); +} + +.trigger.disabled { + opacity: 0.5; + cursor: not-allowed; +} + +/* The pet is the point of the control, so it leads. Square frame, art at 1em inside it — + see PetArt for why font-size is what sizes the image. */ +.triggerArt, +.rowArt { + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + font-size: 1.8rem; + line-height: 1; + border-radius: 6px; + overflow: hidden; + background: radial-gradient(circle at 50% 45%, rgb(125 214 255 / 16%), transparent 68%); +} + +.triggerArt img, +.rowArt img { + border-radius: 6px; +} + +.triggerName, +.rowName { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 13px; + font-weight: 600; + letter-spacing: 0.25px; +} + +.placeholder { + flex: 1; + padding-inline-start: 6px; + color: rgb(125 214 255 / 40%); + font-size: 13px; + font-style: italic; +} + +.rowLevel { + flex-shrink: 0; + padding: 2px 9px; + border: 1px solid rgb(125 214 255 / 32%); + border-radius: 999px; + background: rgb(5 13 30 / 88%); + color: var(--cp-cyan); + font-size: 10px; + font-weight: 700; + letter-spacing: 0.4px; +} + +/* Drawn rather than a background image so it can pick up the accent on open. */ +.chevron { + position: absolute; + right: 14px; + top: 50%; + width: 7px; + height: 7px; + border-right: 2px solid rgb(125 214 255 / 65%); + border-bottom: 2px solid rgb(125 214 255 / 65%); + transform: translateY(-70%) rotate(45deg); + transition: transform 0.18s ease, border-color 0.18s ease; +} + +.trigger.isOpen .chevron { + border-color: var(--cp-cyan); + transform: translateY(-30%) rotate(225deg); +} + +/* ── Popup ──────────────────────────────────────────────────────────────────── + Portalled to the body, so it is positioned in the viewport rather than inside the + panel that would otherwise clip it. */ +.popup { + max-height: 320px; + overflow-y: auto; + padding: 6px; + border: 1px solid rgb(125 214 255 / 45%); + border-radius: 6px; + background: rgb(4 10 26 / 98%); + box-shadow: 0 18px 40px rgb(0 0 0 / 55%), 0 0 18px rgb(125 214 255 / 18%); + scrollbar-width: thin; + scrollbar-color: rgb(125 214 255 / 35%) transparent; +} + +.row { + display: flex; + align-items: center; + gap: 10px; + width: 100%; + padding: 7px 8px; + border: 1px solid transparent; + border-radius: 4px; + background: transparent; + color: #f6f3ff; + font: inherit; + text-align: left; + cursor: pointer; +} + +/* Keyboard and pointer share one highlight: two different "current row" cues in one + list is how a keyboard user loses track of where they are. */ +.row.isActive { + border-color: rgb(125 214 255 / 45%); + background: rgb(125 214 255 / 10%); +} + +.row.isSelected .rowName { + color: var(--cp-cyan); +} + +.emptyRow { + padding: 12px 10px; + color: rgb(195 210 255 / 55%); + font-size: 12px; + font-style: italic; +} diff --git a/frontend/src/components/ui/pet-select/index.tsx b/frontend/src/components/ui/pet-select/index.tsx new file mode 100644 index 00000000..8a1ef4b8 --- /dev/null +++ b/frontend/src/components/ui/pet-select/index.tsx @@ -0,0 +1,235 @@ +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { createPortal } from 'react-dom'; +import clsx from 'clsx'; +import type { Pet } from '@shared/core'; + +import PetArt from '@components/pet/pet-art'; +import styles from './index.module.css'; + +export type PetSelectOption = { + id: string; + pet: Pet; +}; + +export type PetSelectProps = { + /** Pets to choose from, in display order. */ + pets: PetSelectOption[]; + /** Selected pet id, or '' for none. */ + value: string; + onChange: (petId: string) => void; + placeholder?: string; + disabled?: boolean; + /** Forwarded to the trigger so an external `
    - {lastPage > 0 && ( -
    - - - Page {page + 1} of {lastPage + 1} - - -
    - )} + )} diff --git a/frontend/tests/components/leaderboard.test.tsx b/frontend/tests/components/leaderboard.test.tsx index 28fa5600..82f40ba8 100644 --- a/frontend/tests/components/leaderboard.test.tsx +++ b/frontend/tests/components/leaderboard.test.tsx @@ -164,3 +164,60 @@ describe('Leaderboard', () => { expect(screen.getByText('backend unreachable')).toBeInTheDocument(); }); }); + + +describe('Leaderboard pagination', () => { + const board = (total: number, page = 0) => ({ + entries: [petEntry({ rank: page * 20 + 1 })], + total, + pageSize: 20, + isLoading: false, + error: null, + }); + + // The old pager hid itself whenever everything fit, which left a reader unable to + // tell a short board from a truncated one. + it('states the range even when there is only one page', () => { + useLeaderboard.mockReturnValue(board(4)); + usePlayerLeaderboard.mockReturnValue(emptyResult); + + renderBoard(); + + expect(screen.getByText('1–4 of 4')).toBeInTheDocument(); + expect(screen.queryByRole('navigation', { name: 'Leaderboard pages' })).toBeNull(); + }); + + it('offers a numbered page per page and jumps straight to one', async () => { + useLeaderboard.mockReturnValue(board(65)); + usePlayerLeaderboard.mockReturnValue(emptyResult); + + renderBoard(); + const nav = screen.getByRole('navigation', { name: 'Leaderboard pages' }); + + // 65 rows at 20 a page is four pages, and the first is the one you are on. + expect(within(nav).getByRole('button', { name: 'Page 1' })).toHaveAttribute( + 'aria-current', + 'page', + ); + expect(within(nav).getByRole('button', { name: 'Page 4' })).toBeInTheDocument(); + + await userEvent.click(within(nav).getByRole('button', { name: 'Page 3' })); + + // The hook is asked for the page that was pressed, not the next one along. + expect(useLeaderboard).toHaveBeenLastCalledWith(expect.objectContaining({ page: 2 })); + }); + + it('keeps both ends reachable on a long board', () => { + useLeaderboard.mockReturnValue(board(1000)); + usePlayerLeaderboard.mockReturnValue(emptyResult); + + renderBoard(); + const nav = screen.getByRole('navigation', { name: 'Leaderboard pages' }); + + // Fifty pages, but a fixed-width strip: the ends, the neighbours, and a gap. + expect(within(nav).getByRole('button', { name: 'Page 1' })).toBeInTheDocument(); + expect(within(nav).getByRole('button', { name: 'Page 50' })).toBeInTheDocument(); + expect(within(nav).queryByRole('button', { name: 'Page 25' })).toBeNull(); + expect(within(nav).getAllByRole('button').length).toBeLessThan(10); + }); +}); From f348169bd8bbd4dcd233333b7b7fe71632c6f0a7 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Fri, 7 Aug 2026 13:47:33 -0400 Subject: [PATCH 57/61] feat(leaderboard): search pets by name and players by address --- backend/src/graphql/resolvers.ts | 16 ++- backend/src/graphql/schema.ts | 4 + .../repositories/leaderboard.repository.ts | 101 ++++++++++++------ .../leaderboard.repository.test.ts | 56 ++++++++-- .../components/leaderboard/index.module.css | 36 +++++++ frontend/src/components/leaderboard/index.tsx | 42 +++++++- .../tests/components/leaderboard.test.tsx | 71 +++++++++++- .../src/hooks/leaderboard/useLeaderboard.ts | 15 ++- .../hooks/leaderboard/usePlayerLeaderboard.ts | 15 ++- 9 files changed, 301 insertions(+), 55 deletions(-) diff --git a/backend/src/graphql/resolvers.ts b/backend/src/graphql/resolvers.ts index cde4bd40..1f5bace3 100644 --- a/backend/src/graphql/resolvers.ts +++ b/backend/src/graphql/resolvers.ts @@ -26,6 +26,8 @@ interface LeaderboardArgs { chain: string; page?: number | null; pageSize?: number | null; + /** Substring filter; ranks stay absolute, so it narrows the board without renumbering it. */ + search?: string | null; } interface BattleProgressArgs { @@ -115,7 +117,12 @@ export const rootValue = { // No overlay here, for the same reason as `opponents`: the ranking is the merge, // so `findPetLeaderboard` does it in the query. - const { entries, total } = await findPetLeaderboard({ chain: args.chain, page, pageSize }); + const { entries, total } = await findPetLeaderboard({ + chain: args.chain, + page, + pageSize, + search: args.search ?? undefined, + }); return { entries: entries.map(({ petId: id, ...rest }) => ({ id, ...rest })), @@ -132,7 +139,12 @@ export const rootValue = { const page = Math.max(0, args.page ?? 0); const pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, args.pageSize ?? DEFAULT_PAGE_SIZE)); - const { entries, total } = await findPlayerLeaderboard({ chain: args.chain, page, pageSize }); + const { entries, total } = await findPlayerLeaderboard({ + chain: args.chain, + page, + pageSize, + search: args.search ?? undefined, + }); return { entries, total, page, pageSize }; }, diff --git a/backend/src/graphql/schema.ts b/backend/src/graphql/schema.ts index c373ad1a..c408c050 100644 --- a/backend/src/graphql/schema.ts +++ b/backend/src/graphql/schema.ts @@ -137,6 +137,8 @@ export const schema = buildSchema(` chain: String! page: Int pageSize: Int + "Case-insensitive substring of the pet's name. Ranks stay absolute: a match keeps its position on the full board rather than being renumbered within the results." + search: String ): LeaderboardPage! """ @@ -148,6 +150,8 @@ export const schema = buildSchema(` chain: String! page: Int pageSize: Int + "Case-insensitive substring of the owner's address. Ranks stay absolute, as on the pet board." + search: String ): PlayerLeaderboardPage! """ diff --git a/backend/src/repositories/leaderboard.repository.ts b/backend/src/repositories/leaderboard.repository.ts index 99f0d20c..19c866b9 100644 --- a/backend/src/repositories/leaderboard.repository.ts +++ b/backend/src/repositories/leaderboard.repository.ts @@ -61,6 +61,8 @@ export interface FindLeaderboardParams { chain: Chain; page: number; pageSize: number; + /** Filters the board without renumbering it; see `contains`. */ + search?: string | undefined; } /** The projected columns, before the rank is attached. */ @@ -104,6 +106,22 @@ const HAS_FOUGHT = Prisma.sql`${WINS} + ${LOSSES} > 0`; * from a handful of fights. */ const petOrder = Prisma.sql`${WINS} DESC, ${LOSSES} ASC, ${LEVEL} DESC, r.pet_id ASC`; + +/** + * A search term as a case-insensitive contains-match, or nothing at all. + * + * `TRUE` for a blank term rather than a second query: an unfiltered board is the same + * shape as a filtered one, and branching would double every query below. + * + * `%` and `_` are escaped because they are wildcards to `ILIKE` — a player searching for + * a pet actually named `100%` should not match every pet on the board. + */ +function contains(column: Prisma.Sql, term: string | undefined): Prisma.Sql { + const needle = term?.trim(); + if (!needle) return Prisma.sql`TRUE`; + const escaped = needle.replace(/[\\%_]/g, (char) => `\\${char}`); + return Prisma.sql`${column} ILIKE ${`%${escaped}%`} ESCAPE '\\'`; +} const playerOrder = (owner: Prisma.Sql) => Prisma.sql`SUM(${WINS}) DESC, SUM(${LOSSES}) ASC, ${owner} ASC`; @@ -113,31 +131,42 @@ export async function findPetLeaderboard( ): Promise<{ entries: LeaderboardEntry[]; total: number }> { const join = progressJoin(servedChainIdForFamily(params.chain)); const skip = params.page * params.pageSize; + const match = contains(Prisma.sql`r.name`, params.search); + + /** + * Ranked first, filtered second. + * + * The rank is a position on the whole board, so it has to be assigned before any + * search narrows the rows — otherwise a pet's rank would change depending on what + * someone typed, and "where does Yasu sit" is the question a search here is asked. + * That is why it comes from `ROW_NUMBER` rather than from the offset, which only ever + * described an unfiltered page. + */ + const ranked = Prisma.sql` + SELECT r.chain, r.pet_id AS "petId", r.owner, r.name, r.rarity, r.dna, r.asset, + ${LEVEL} AS level, ${WINS} AS "winCount", ${LOSSES} AS "lossCount", + ROW_NUMBER() OVER (ORDER BY ${petOrder})::int AS rank + FROM pet_roster r + ${join} + WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} + `; const [rows, counted] = await Promise.all([ - prisma.$queryRaw` - SELECT r.chain, r.pet_id AS "petId", r.owner, r.name, r.rarity, r.dna, r.asset, - ${LEVEL} AS level, ${WINS} AS "winCount", ${LOSSES} AS "lossCount" - FROM pet_roster r - ${join} - WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} - ORDER BY ${petOrder} + prisma.$queryRaw<(RankedRow & { rank: number })[]>` + SELECT * FROM (${ranked}) ranked + WHERE ${match} + ORDER BY rank LIMIT ${params.pageSize} OFFSET ${skip} `, + // Counted after the filter, since it drives the pager over the matches rather + // than over the board. prisma.$queryRaw<{ total: bigint }[]>` - SELECT COUNT(*) AS total - FROM pet_roster r - ${join} - WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} + SELECT COUNT(*) AS total FROM (${ranked}) ranked WHERE ${match} `, ]); return { - entries: rows.map((row, index) => ({ - ...row, - chain: row.chain as Chain, - rank: skip + index + 1, - })), + entries: rows.map((row) => ({ ...row, chain: row.chain as Chain })), total: Number(counted[0]?.total ?? 0), }; } @@ -154,38 +183,42 @@ export async function findPlayerLeaderboard( const join = progressJoin(servedChainIdForFamily(params.chain)); const owner = ownerKey(params.chain, 'r'); const skip = params.page * params.pageSize; + const match = contains(Prisma.sql`ranked.owner`, params.search); // The SUMs are cast because Postgres widens them to bigint, which Prisma would hand // back as a BigInt the GraphQL Int serializer cannot take. A player's battle count has // no way to approach the int range. + // + // Ranked before filtered, for the same reason as the pet board: a rank describes a + // position on the whole board, not within someone's search. + const ranked = Prisma.sql` + SELECT ${owner} AS owner, + SUM(${WINS})::int AS "winCount", + SUM(${LOSSES})::int AS "lossCount", + COUNT(*)::int AS "petCount", + ROW_NUMBER() OVER (ORDER BY ${playerOrder(owner)})::int AS rank + FROM pet_roster r + ${join} + WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} + GROUP BY ${owner} + `; + const [rows, counted] = await Promise.all([ - prisma.$queryRaw` - SELECT ${owner} AS owner, - SUM(${WINS})::int AS "winCount", - SUM(${LOSSES})::int AS "lossCount", - COUNT(*)::int AS "petCount" - FROM pet_roster r - ${join} - WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} - GROUP BY ${owner} - ORDER BY ${playerOrder(owner)} + prisma.$queryRaw<(PlayerRow & { rank: number })[]>` + SELECT * FROM (${ranked}) ranked + WHERE ${match} + ORDER BY rank LIMIT ${params.pageSize} OFFSET ${skip} `, // Counts grouped owners, not joined pet rows: COUNT(*) over the ungrouped join // would count pets and page the client past the last owner. prisma.$queryRaw<{ total: bigint }[]>` - SELECT COUNT(*) AS total FROM ( - SELECT 1 - FROM pet_roster r - ${join} - WHERE r.chain = ${params.chain} AND ${HAS_FOUGHT} - GROUP BY ${owner} - ) owners + SELECT COUNT(*) AS total FROM (${ranked}) ranked WHERE ${match} `, ]); return { - entries: rows.map((row, index) => ({ ...row, rank: skip + index + 1 })), + entries: rows, total: Number(counted[0]?.total ?? 0), }; } diff --git a/backend/tests/repositories/leaderboard.repository.test.ts b/backend/tests/repositories/leaderboard.repository.test.ts index f877d806..82cfe35b 100644 --- a/backend/tests/repositories/leaderboard.repository.test.ts +++ b/backend/tests/repositories/leaderboard.repository.test.ts @@ -23,6 +23,7 @@ import { import { prisma } from '@config/prisma'; const rankedRow = { + rank: 1, chain: 'evm', petId: '7', owner: '0xowner', @@ -94,15 +95,49 @@ describe('findPetLeaderboard', () => { expect(result.entries[0].rank).toBe(1); }); - it('numbers ranks absolutely, continuing across pages', async () => { - // A rank that restarted at 1 on every page would say the 21st pet is the best one. - mockJoinQuery([rankedRow, { ...rankedRow, petId: '8' }], 42); + // The rank moved into the query when search arrived: it has to be assigned over the + // whole board *before* a filter narrows it, which an offset cannot do. These two say + // the repository reports what the query ranked and never recomputes it. + it('reports the rank the query assigned', async () => { + mockJoinQuery([{ ...rankedRow, rank: 41 }, { ...rankedRow, petId: '8', rank: 42 }], 42); const result = await findPetLeaderboard({ chain: 'evm', page: 2, pageSize: 20 }); expect(result.entries.map((entry) => entry.rank)).toEqual([41, 42]); }); + it('ranks over the whole board before any search narrows it', async () => { + mockJoinQuery([], 0); + + await findPetLeaderboard({ chain: 'evm', page: 0, pageSize: 20, search: 'Rex' }); + + const sql = sqlOfCall(0); + // The window sits inside the subquery, the filter outside it. The other way round + // would renumber the matches from one and a pet's rank would depend on what + // somebody typed. + const ranking = sql.indexOf('ROW_NUMBER() OVER'); + const filtering = sql.indexOf('ILIKE'); + expect(ranking).toBeGreaterThan(-1); + expect(filtering).toBeGreaterThan(ranking); + }); + + it('counts the matches, not the board, so the pager fits the search', async () => { + mockJoinQuery([], 0); + + await findPetLeaderboard({ chain: 'evm', page: 0, pageSize: 20, search: 'Rex' }); + + expect(sqlOfCall(1)).toContain('ILIKE'); + }); + + it('leaves the board unfiltered when nothing is searched for', async () => { + mockJoinQuery([], 0); + + await findPetLeaderboard({ chain: 'evm', page: 0, pageSize: 20, search: ' ' }); + + // A blank term is `TRUE`, not a second query shape. + expect(sqlOfCall(0)).not.toContain('ILIKE'); + }); + it('ranks on the merged battle record, not the frozen roster counters', async () => { // The roster's win/loss stopped moving when battles left the chain, so ordering on // r.win_count alone would freeze the leaderboard at the retired path's last state. @@ -147,7 +182,7 @@ describe('findPetLeaderboard', () => { }); describe('findPlayerLeaderboard', () => { - const playerRow = { owner: '0xowner', winCount: 20, lossCount: 4, petCount: 3 }; + const playerRow = { rank: 1, owner: '0xowner', winCount: 20, lossCount: 4, petCount: 3 }; it('returns the ranked owners and their total', async () => { mockJoinQuery([playerRow], 1); @@ -158,14 +193,23 @@ describe('findPlayerLeaderboard', () => { expect(result.entries[0]).toMatchObject({ owner: '0xowner', rank: 1, petCount: 3 }); }); - it('numbers ranks absolutely, continuing across pages', async () => { - mockJoinQuery([playerRow, { ...playerRow, owner: '0xother' }], 30); + it('reports the rank the query assigned', async () => { + mockJoinQuery([{ ...playerRow, rank: 21 }, { ...playerRow, owner: '0xother', rank: 22 }], 30); const result = await findPlayerLeaderboard({ chain: 'evm', page: 1, pageSize: 20 }); expect(result.entries.map((entry) => entry.rank)).toEqual([21, 22]); }); + it('ranks over the whole board before a search narrows it', async () => { + mockJoinQuery([], 0); + + await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20, search: '0xowner' }); + + const sql = sqlOfCall(0); + expect(sql.indexOf('ILIKE')).toBeGreaterThan(sql.indexOf('ROW_NUMBER() OVER')); + }); + it('folds EVM owners to one group so a wallet is not listed twice', async () => { // indexer-go is not guaranteed to write the roster in one case, and an unfolded // group would split a single wallet's record across two rows. diff --git a/frontend/src/components/leaderboard/index.module.css b/frontend/src/components/leaderboard/index.module.css index 23416bab..022689ac 100644 --- a/frontend/src/components/leaderboard/index.module.css +++ b/frontend/src/components/leaderboard/index.module.css @@ -209,3 +209,39 @@ display: none; } } + +/* Search. One box for whichever board is showing — the two search different things, so + the placeholder says which, and switching boards clears it. */ +.search { + margin-bottom: 12px; + flex-shrink: 0; +} + +.search input { + box-sizing: border-box; + width: 100%; + min-height: 40px; + padding: 8px 14px; + border: 1px solid rgb(148 163 184 / 25%); + border-radius: 8px; + background: rgb(4 10 26 / 96%); + color: inherit; + font: inherit; + font-size: 0.9rem; + caret-color: var(--cp-amber); +} + +.search input::placeholder { + color: rgb(195 210 255 / 35%); + font-style: italic; +} + +.search input:hover { + border-color: rgb(255 207 112 / 40%); +} + +.search input:focus { + outline: none; + border-color: var(--cp-amber); + box-shadow: 0 0 0 2px rgb(255 207 112 / 30%); +} diff --git a/frontend/src/components/leaderboard/index.tsx b/frontend/src/components/leaderboard/index.tsx index 0edbf554..b1b257d5 100644 --- a/frontend/src/components/leaderboard/index.tsx +++ b/frontend/src/components/leaderboard/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, type ReactNode } from 'react'; +import React, { useEffect, useState, type ReactNode } from 'react'; import { useNavigate } from 'react-router-dom'; import { useChainCapabilities, @@ -163,11 +163,25 @@ const Leaderboard: React.FC = () => { const { activeKind, walletAddress } = useChainCapabilities(); const [board, setBoard] = useState('pets'); const [page, setPage] = useState(0); + const [term, setTerm] = useState(''); - const pets = useLeaderboard({ chain: activeKind, page, enabled: board === 'pets' }); + // 300 ms, matching `useSearchPets`: a round trip per keystroke against a ranked query + // is a lot of work to throw away, and the board is not a typeahead. + const [search, setSearch] = useState(''); + useEffect(() => { + const id = setTimeout(() => setSearch(term.trim()), 300); + return () => clearTimeout(id); + }, [term]); + + // A term that narrows the board also renumbers which page anything is on, so the + // reader has to be put back at the first one or a search can land on an empty page. + useEffect(() => setPage(0), [search]); + + const pets = useLeaderboard({ chain: activeKind, page, search, enabled: board === 'pets' }); const players = usePlayerLeaderboard({ chain: activeKind, page, + search, enabled: board === 'players', }); @@ -187,8 +201,12 @@ const Leaderboard: React.FC = () => { const showBoard = (next: Board) => { setBoard(next); // Page 3 of the pet board says nothing about where a player sits, and the two - // boards have different lengths. + // boards have different lengths. The term goes too: the boards search different + // things — a pet's name and an owner's address — so carrying one across would + // hand the other board a query that cannot match. setPage(0); + setTerm(''); + setSearch(''); }; const lastPage = Math.max(0, Math.ceil(active.total / active.pageSize) - 1); @@ -222,6 +240,20 @@ const Leaderboard: React.FC = () => { ))}
    +
    + setTerm(event.target.value)} + placeholder={ + board === 'pets' ? 'Search pets by name' : 'Search players by address' + } + aria-label={ + board === 'pets' ? 'Search pets by name' : 'Search players by address' + } + /> +
    + {active.error ? (

    {active.error.message}

    ) : active.isLoading ? ( @@ -230,7 +262,9 @@ const Leaderboard: React.FC = () => {
    ) : active.total === 0 ? (

    - No battles on record yet. Win one and the board fills up. + {search + ? `Nothing on the board matches "${search}".` + : 'No battles on record yet. Win one and the board fills up.'}

    ) : ( <> diff --git a/frontend/tests/components/leaderboard.test.tsx b/frontend/tests/components/leaderboard.test.tsx index 82f40ba8..5d9ec926 100644 --- a/frontend/tests/components/leaderboard.test.tsx +++ b/frontend/tests/components/leaderboard.test.tsx @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, within } from '@testing-library/react'; +import { act, fireEvent, render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; @@ -221,3 +221,72 @@ describe('Leaderboard pagination', () => { expect(within(nav).getAllByRole('button').length).toBeLessThan(10); }); }); + + +describe('Leaderboard search', () => { + const board = (over: Record = {}) => ({ + entries: [petEntry()], + total: 1, + pageSize: 20, + isLoading: false, + error: null, + ...over, + }); + + it('passes the typed term to the board, debounced', async () => { + vi.useFakeTimers({ shouldAdvanceTime: true }); + useLeaderboard.mockReturnValue(board()); + usePlayerLeaderboard.mockReturnValue(emptyResult); + + renderBoard(); + await userEvent.type(screen.getByRole('searchbox', { name: /search pets/i }), 'Yas'); + + // Nothing yet: a round trip per keystroke is what the debounce exists to avoid. + expect(useLeaderboard).not.toHaveBeenCalledWith(expect.objectContaining({ search: 'Yas' })); + + await act(async () => { + vi.advanceTimersByTime(300); + }); + expect(useLeaderboard).toHaveBeenLastCalledWith(expect.objectContaining({ search: 'Yas' })); + vi.useRealTimers(); + }); + + it('says nothing matched, rather than that the board is empty', () => { + vi.useFakeTimers({ shouldAdvanceTime: true }); + useLeaderboard.mockReturnValue(board({ entries: [], total: 0 })); + usePlayerLeaderboard.mockReturnValue(emptyResult); + + renderBoard(); + fireEvent.change(screen.getByRole('searchbox'), { target: { value: 'nobody' } }); + act(() => { + vi.advanceTimersByTime(300); + }); + + expect(screen.getByText('Nothing on the board matches "nobody".')).toBeInTheDocument(); + expect(screen.queryByText(/No battles on record yet/)).toBeNull(); + vi.useRealTimers(); + }); + + // The boards search different things, so a pet name handed to the player board could + // only ever match nothing. + it('clears the term when the other board is opened', async () => { + vi.useFakeTimers({ shouldAdvanceTime: true }); + useLeaderboard.mockReturnValue(board()); + usePlayerLeaderboard.mockReturnValue(board()); + + renderBoard(); + const box = screen.getByRole('searchbox'); + fireEvent.change(box, { target: { value: 'Yasu' } }); + act(() => { + vi.advanceTimersByTime(300); + }); + + await userEvent.click(screen.getByRole('tab', { name: 'Players' })); + + expect(screen.getByRole('searchbox')).toHaveValue(''); + expect(usePlayerLeaderboard).toHaveBeenLastCalledWith( + expect.objectContaining({ search: '' }), + ); + vi.useRealTimers(); + }); +}); diff --git a/shared/src/hooks/leaderboard/useLeaderboard.ts b/shared/src/hooks/leaderboard/useLeaderboard.ts index 76938b12..b4af6f2b 100644 --- a/shared/src/hooks/leaderboard/useLeaderboard.ts +++ b/shared/src/hooks/leaderboard/useLeaderboard.ts @@ -4,8 +4,8 @@ import { useAuth } from '../../contexts/AuthContext'; import type { PetChain } from '../../types/pet'; const LEADERBOARD_QUERY = ` - query Leaderboard($chain: String!, $page: Int, $pageSize: Int) { - leaderboard(chain: $chain, page: $page, pageSize: $pageSize) { + query Leaderboard($chain: String!, $page: Int, $pageSize: Int, $search: String) { + leaderboard(chain: $chain, page: $page, pageSize: $pageSize, search: $search) { entries { rank id chain owner name dna level rarity winCount lossCount asset @@ -49,6 +49,12 @@ export interface UseLeaderboardOptions { chain: PetChain | null; /** Zero-based page index. */ page?: number; + /** + * Narrows the board to matching rows. Ranks are unaffected: a match keeps its place + * on the full board, so searching answers "where does this sit" rather than + * renumbering the results from one. + */ + search?: string; enabled?: boolean; } @@ -73,6 +79,7 @@ export interface UseLeaderboardResult { export const useLeaderboard = ({ chain, page = 0, + search, enabled = true, }: UseLeaderboardOptions): UseLeaderboardResult => { const apiClient = useApiClient(); @@ -80,12 +87,12 @@ export const useLeaderboard = ({ const baseURL = apiClient.defaults.baseURL ?? ''; const query = useQuery({ - queryKey: ['leaderboard', baseURL, chain, page], + queryKey: ['leaderboard', baseURL, chain, page, search ?? ''], enabled: enabled && chain != null && isAuthenticated, queryFn: async () => { const { data } = await apiClient.post('/graphql', { query: LEADERBOARD_QUERY, - variables: { chain, page }, + variables: { chain, page, search }, }); if (data.errors?.length) { diff --git a/shared/src/hooks/leaderboard/usePlayerLeaderboard.ts b/shared/src/hooks/leaderboard/usePlayerLeaderboard.ts index 68ea23af..1185cd59 100644 --- a/shared/src/hooks/leaderboard/usePlayerLeaderboard.ts +++ b/shared/src/hooks/leaderboard/usePlayerLeaderboard.ts @@ -4,8 +4,8 @@ import { useAuth } from '../../contexts/AuthContext'; import type { PetChain } from '../../types/pet'; const PLAYER_LEADERBOARD_QUERY = ` - query PlayerLeaderboard($chain: String!, $page: Int, $pageSize: Int) { - playerLeaderboard(chain: $chain, page: $page, pageSize: $pageSize) { + query PlayerLeaderboard($chain: String!, $page: Int, $pageSize: Int, $search: String) { + playerLeaderboard(chain: $chain, page: $page, pageSize: $pageSize, search: $search) { entries { rank owner winCount lossCount petCount } total page pageSize } @@ -41,6 +41,12 @@ export interface UsePlayerLeaderboardOptions { chain: PetChain | null; /** Zero-based page index. */ page?: number; + /** + * Narrows the board to matching rows. Ranks are unaffected: a match keeps its place + * on the full board, so searching answers "where does this sit" rather than + * renumbering the results from one. + */ + search?: string; enabled?: boolean; } @@ -63,6 +69,7 @@ export interface UsePlayerLeaderboardResult { export const usePlayerLeaderboard = ({ chain, page = 0, + search, enabled = true, }: UsePlayerLeaderboardOptions): UsePlayerLeaderboardResult => { const apiClient = useApiClient(); @@ -70,12 +77,12 @@ export const usePlayerLeaderboard = ({ const baseURL = apiClient.defaults.baseURL ?? ''; const query = useQuery({ - queryKey: ['playerLeaderboard', baseURL, chain, page], + queryKey: ['playerLeaderboard', baseURL, chain, page, search ?? ''], enabled: enabled && chain != null && isAuthenticated, queryFn: async () => { const { data } = await apiClient.post('/graphql', { query: PLAYER_LEADERBOARD_QUERY, - variables: { chain, page }, + variables: { chain, page, search }, }); if (data.errors?.length) { From b0c9aaa3f8b494aa7b2fce51358d98499fbcc72e Mon Sep 17 00:00:00 2001 From: heyradcode Date: Fri, 7 Aug 2026 13:58:27 -0400 Subject: [PATCH 58/61] feat(leaderboard): podium over ledger --- .../components/leaderboard/index.module.css | 212 +++++++++++++++++- frontend/src/components/leaderboard/index.tsx | 201 ++++++++++++----- .../tests/components/leaderboard.test.tsx | 43 +++- 3 files changed, 378 insertions(+), 78 deletions(-) diff --git a/frontend/src/components/leaderboard/index.module.css b/frontend/src/components/leaderboard/index.module.css index 022689ac..c52f23d3 100644 --- a/frontend/src/components/leaderboard/index.module.css +++ b/frontend/src/components/leaderboard/index.module.css @@ -1,5 +1,17 @@ /* CSS Module — class names are local; reference via `import styles from './index.module.css'`. - Leaderboard: a read-only ranking table, amber accent to match the trophy. */ + + Leaderboard: a podium over a ledger. + + The split is the design, and it is true of the content rather than imposed on it — the + top three are a *result* and everything below is a *record*, which is why medals exist + at all. So the top three get cards at the size their placing earns, with the pet art as + the hero; everywhere else in the app that art is an identifier, here being looked at is + the whole point. Below them the rows go tighter and more typographic, with the rank at + display size because the rank is what a reader came for. + + Gold, silver and bronze are the real metals rather than three tints of the page accent: + the colour then encodes the placing instead of decorating it. Amber stays the page's + own accent — the trophy, the tabs, the search — and gold belongs to first place alone. */ /* Ends at the bottom of the window rather than at the bottom of its rows, so the pager stays reachable without scrolling the page and short pages leave no dead space. @@ -45,6 +57,17 @@ /* The one part that scrolls. Everything else in the panel keeps its natural height, so the pager stays pinned below the rows instead of being pushed off the bottom. */ +/* Podium and ledger scroll together: with a podium on screen the rows below are a + remainder, and scrolling only the remainder would strand it in a sliver. */ +.board { + display: flex; + flex-direction: column; + gap: 18px; + flex: 1; + min-height: 0; + overflow-y: auto; +} + .list { list-style: none; margin: 0; @@ -52,19 +75,162 @@ display: flex; flex-direction: column; gap: 6px; - flex: 1; - min-height: 0; - overflow-y: auto; } -/* Fixed track widths so ranks, records and rates line up down the column; only the - name track flexes. */ +/* ── Podium ──────────────────────────────────────────────────────────────────── + Second, first, third across, the way a podium is actually arranged: the winner in the + middle and taller. `order` does it, so the DOM keeps rank order for a screen reader + and for anyone tabbing through. */ +.podium { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + align-items: end; + gap: 12px; + flex-shrink: 0; +} + +.podiumCard { + --medal: var(--cp-amber); + --art: 78px; + + position: relative; + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + padding: 18px 12px 14px; + border: 1px solid rgb(from var(--medal) r g b / 32%); + border-radius: 14px; + background: + radial-gradient( + 120% 90% at 50% 0%, + rgb(from var(--accent, var(--medal)) r g b / 14%), + transparent 62% + ), + var(--cp-surface); + text-align: center; + overflow: hidden; +} + +/* The lit edge along the top: the placing, drawn rather than described. */ +.podiumCard::before { + content: ''; + position: absolute; + inset: 0 0 auto; + height: 2px; + background: linear-gradient(90deg, transparent, var(--medal), transparent); +} + +.podiumCard.gold { + --medal: #ffcf70; +} + +.podiumCard.silver { + --medal: #c9d4e8; +} + +.podiumCard.bronze { + --medal: #e0955f; +} + +/* First place stands taller and shows its pet bigger. On a board of four that means the + page is mostly podium, which is the honest shape of a four-entry ranking: a result, + not a spreadsheet with thirty-six empty rows. */ +.podiumCard.isLeader { + --art: 104px; + + order: 2; + padding-block: 26px 18px; + box-shadow: 0 0 26px rgb(from var(--medal) r g b / 14%); +} + +.podiumCard:first-child { + order: 1; +} + +.podiumCard:last-child { + order: 3; +} + +.podiumRank { + font-family: var(--cp-title-font); + font-size: 0.85rem; + font-weight: 700; + letter-spacing: 1.5px; + color: var(--medal); + font-variant-numeric: tabular-nums; +} + +/* PetArt draws at 1em, so font-size is the lever; see PetArt. */ +.podiumArt { + display: flex; + align-items: center; + justify-content: center; + width: var(--art); + height: var(--art); + font-size: calc(var(--art) * 0.86); + line-height: 1; +} + +.podiumArt img { + border-radius: 14px; +} + +.podiumName { + margin: 6px 0 0; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-family: var(--cp-title-font); + font-size: 1rem; + font-weight: 700; + letter-spacing: 0.3px; +} + +.podiumSub, +.podiumRate { + margin: 0; + font-size: 0.72rem; + opacity: 0.55; +} + +.podiumRecord { + margin: 2px 0 0; + display: flex; + align-items: baseline; + gap: 6px; + font-size: 0.95rem; + font-variant-numeric: tabular-nums; +} + +.dash { + opacity: 0.35; +} + +@media (max-width: 620px) { + /* Three cards side by side stop being a podium and start being three slivers. */ + .podium { + grid-template-columns: minmax(0, 1fr); + } + + .podiumCard, + .podiumCard.isLeader { + order: 0; + --art: 72px; + } +} + +/* ── Ledger ──────────────────────────────────────────────────────────────────── + Fixed track widths so ranks, records and rates line up down the column; only the name + track flexes. The meter spans the full width on its own row beneath. */ .row { + position: relative; display: grid; - grid-template-columns: 3rem 2.2rem minmax(0, 1fr) 6.5rem 3.5rem; + grid-template-columns: 2.6rem 2.2rem minmax(0, 1fr) 6.5rem 3.2rem; align-items: center; gap: 10px; - padding: 8px 12px; + padding: 9px 12px 11px; border-radius: 10px; border: 1px solid rgb(148 163 184 / 14%); background: var(--cp-surface); @@ -77,12 +243,37 @@ background: rgb(251 191 36 / 8%); } +/* The rank at display size: it is what the reader came for, so the row text is quieter + than it rather than the other way round. */ .rank { - font-size: 1.05rem; + font-family: var(--cp-title-font); + font-size: 1.35rem; + font-weight: 700; + line-height: 1; + color: rgb(255 207 112 / 55%); font-variant-numeric: tabular-nums; text-align: center; } +/* Win rate as a hairline under the row. A column of percentages has to be read one at a + time; a column of bars shows the shape of the board at a glance. Kept faint on purpose + — the podium is where this page spends its boldness. */ +.meter { + position: absolute; + inset: auto 12px 5px; + height: 2px; + border-radius: 2px; + background: rgb(148 163 184 / 14%); + overflow: hidden; +} + +.meterFill { + display: block; + height: 100%; + border-radius: 2px; + background: linear-gradient(90deg, rgb(52 211 153 / 55%), rgb(255 207 112 / 75%)); +} + .avatar { font-size: 1.4rem; line-height: 1; @@ -96,6 +287,9 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + /* `#root` in App.css centres the whole app, so a left-aligned column has to say so. + The podium cards want the centring and keep it. */ + text-align: left; } .sub { diff --git a/frontend/src/components/leaderboard/index.tsx b/frontend/src/components/leaderboard/index.tsx index b1b257d5..9a60d65b 100644 --- a/frontend/src/components/leaderboard/index.tsx +++ b/frontend/src/components/leaderboard/index.tsx @@ -1,6 +1,8 @@ -import React, { useEffect, useState, type ReactNode } from 'react'; +import React, { useEffect, useMemo, useState, type ReactNode } from 'react'; +import clsx from 'clsx'; import { useNavigate } from 'react-router-dom'; import { + getRarityColor, useChainCapabilities, useLeaderboard, usePlayerLeaderboard, @@ -24,41 +26,96 @@ function winRate(wins: number, losses: number): number | null { return fought === 0 ? null : Math.round((wins / fought) * 100); } -/** Medal for the top three, plain number below. Rank is absolute, so this holds on page 2+. */ -function rankBadge(rank: number): string { - return rank === 1 ? '🥇' : rank === 2 ? '🥈' : rank === 3 ? '🥉' : `#${rank}`; -} +/** Metal for each of the top three, and nothing below. Drives `--medal` on the card. */ +const MEDALS = ['gold', 'silver', 'bronze'] as const; -/** - * One ranked row. Both boards render the same five tracks — only the avatar, the title - * and the sub-line differ — so they share this rather than two near-identical components - * that would drift the first time the record column is edited. - */ -const Row: React.FC<{ +/** How many places get a card rather than a row. */ +const PODIUM_PLACES = MEDALS.length; + +/** What one row shows, whichever board produced it. */ +type Standing = { + key: string; rank: number; avatar: ReactNode; - title: ReactNode; - sub: ReactNode; + title: string; + sub: string; + /** Tints the podium card behind the pet; null on the player board. */ + accent: string | null; winCount: number; lossCount: number; isYou: boolean; -}> = ({ rank, avatar, title, sub, winCount, lossCount, isYou }) => { - const rate = winRate(winCount, lossCount); +}; + +/** + * A place on the podium: the top three, at the size their result earns. + * + * The pet art is the hero here rather than a 20px avatar in a table cell. It is the most + * distinctive thing the product owns and the leaderboard is where being looked at is the + * whole point — everywhere else it is an identifier, here it is a trophy. + * + * The wash behind it is the pet's own rarity colour, so a card says something about the + * pet and not only about its position. + */ +const PodiumCard: React.FC<{ standing: Standing; place: number }> = ({ standing, place }) => { + const rate = winRate(standing.winCount, standing.lossCount); + return ( +
    + {standing.rank} + + {standing.avatar} + +

    {standing.title}

    +

    {standing.sub}

    +

    + {standing.winCount}W + + · + + {standing.lossCount}L +

    +

    {rate == null ? 'no record' : `${rate}% win rate`}

    +
    + ); +}; + +/** + * One line of the ledger, below the podium. + * + * The rank leads at display size because the rank is what the reader came for; the row + * text is deliberately quieter than it. The win rate is drawn as a bar under the row + * rather than printed as a fifth column — a column of percentages has to be read one at a + * time, where a column of bars shows the shape of the board at a glance. + */ +const Row: React.FC<{ standing: Standing }> = ({ standing }) => { + const rate = winRate(standing.winCount, standing.lossCount); return ( -
  • - {rankBadge(rank)} +
  • + {standing.rank} - {avatar} + {standing.avatar} - {title} - {sub} + {standing.title} + {standing.sub} - {winCount}W - {lossCount}L + {standing.winCount}W + {standing.lossCount}L {rate == null ? '—' : `${rate}%`} + {/* Presentational: the same number is written beside it for anyone who cannot + see the bar. */} + + +
  • ); }; @@ -211,6 +268,52 @@ const Leaderboard: React.FC = () => { const lastPage = Math.max(0, Math.ceil(active.total / active.pageSize) - 1); + /** Both boards flattened to the same shape, so the podium and ledger take either. */ + const standings: Standing[] = useMemo( + () => + board === 'pets' + ? pets.entries.map((entry) => ({ + key: entry.id, + rank: entry.rank, + avatar: ( + + ), + title: entry.name, + sub: `Lv ${entry.level}`, + accent: getRarityColor(entry.rarity), + winCount: entry.winCount, + lossCount: entry.lossCount, + isYou: isYou(entry.owner), + })) + : players.entries.map((entry) => ({ + key: entry.owner, + rank: entry.rank, + avatar: '👤', + title: shortAddress(entry.owner), + sub: `${entry.petCount} pet${entry.petCount === 1 ? '' : 's'}`, + accent: null, + winCount: entry.winCount, + lossCount: entry.lossCount, + isYou: isYou(entry.owner), + })), + // eslint-disable-next-line react-hooks/exhaustive-deps + [board, pets.entries, players.entries, walletAddress], + ); + + // Decided by the rank itself, not by which page is showing: a medal belongs to third + // place, so page 2 grows no podium and a search that turns up the leader still shows + // it as the leader. Ranks are absolute for exactly this reason. + const podium = standings.filter((standing) => standing.rank <= PODIUM_PLACES); + const ledger = standings.filter((standing) => standing.rank > PODIUM_PLACES); + return ( { : 'No battles on record yet. Win one and the board fills up.'}

    ) : ( - <> +
    + {podium.length > 0 && ( +
    + {podium.map((standing) => ( + + ))} +
    + )} +
      - {board === 'pets' - ? pets.entries.map((entry) => ( - - } - title={entry.name} - sub={`Lv ${entry.level}`} - winCount={entry.winCount} - lossCount={entry.lossCount} - isYou={isYou(entry.owner)} - /> - )) - : players.entries.map((entry) => ( - - ))} + {ledger.map((standing) => ( + + ))}
    { total={active.total} onGo={setPage} /> - +
    )}
    diff --git a/frontend/tests/components/leaderboard.test.tsx b/frontend/tests/components/leaderboard.test.tsx index 5d9ec926..49f9115c 100644 --- a/frontend/tests/components/leaderboard.test.tsx +++ b/frontend/tests/components/leaderboard.test.tsx @@ -21,6 +21,8 @@ vi.mock('@shared/core', () => ({ // since VITE_IMAGE_SERVICE_URL is unset in tests. getPetAvatar: () => '🐾', petArtUrl: () => null, + // Tints the podium card behind the pet; any colour will do here. + getRarityColor: () => '#b58cff', })); import Leaderboard from '@components/leaderboard'; @@ -87,19 +89,21 @@ describe('Leaderboard', () => { expect(screen.queryByText(/No battles on record yet/i)).toBeNull(); }); - it('renders a pet row with its record and win rate', () => { + // The top three are cards, not rows: a ranking's first three are a result and the + // rest are a record, and the page says so. + it('puts the leader on the podium with its record and win rate', () => { useLeaderboard.mockReturnValue({ ...emptyResult, entries: [petEntry()], total: 1 }); renderBoard(); - const row = screen.getByText('Yasu').closest('li') as HTMLElement; - expect(within(row).getByText('5W')).toBeInTheDocument(); - expect(within(row).getByText('2L')).toBeInTheDocument(); + const card = screen.getByText('Yasu').closest('article') as HTMLElement; + expect(within(card).getByText('5W')).toBeInTheDocument(); + expect(within(card).getByText('2L')).toBeInTheDocument(); // 5 of 7 fights, rounded. - expect(within(row).getByText('71%')).toBeInTheDocument(); + expect(within(card).getByText('71% win rate')).toBeInTheDocument(); }); - it('medals the top three and numbers the rest, using the absolute rank', () => { + it('has no podium beyond the first page, where "top three" is not true', () => { useLeaderboard.mockReturnValue({ ...emptyResult, entries: [ @@ -110,12 +114,31 @@ describe('Leaderboard', () => { }); renderBoard(); + // Rendered by the pager as page 1 of 2, so this *is* the first page of a longer + // board; the ranks are what say these are not the top three. + const row = screen.getByText('Twenty-first').closest('li') as HTMLElement; - // Page 2 rows are not medalled: rank is absolute, not per-page. - expect(screen.getByText('#21')).toBeInTheDocument(); + expect(within(row).getByText('21')).toBeInTheDocument(); expect(screen.queryByText('🥇')).toBeNull(); }); + // The card follows the rank, not the page or the query: searching up the leader + // should still show it as the leader. + it('keeps a medal on a rank-1 pet found by search', async () => { + vi.useFakeTimers({ shouldAdvanceTime: true }); + useLeaderboard.mockReturnValue({ ...emptyResult, entries: [petEntry()], total: 1 }); + + renderBoard(); + fireEvent.change(screen.getByRole('searchbox'), { target: { value: 'Yas' } }); + act(() => { + vi.advanceTimersByTime(300); + }); + + expect(screen.getByRole('region', { name: 'Top three' })).toBeInTheDocument(); + expect(screen.getByText('Yasu').closest('article')).not.toBeNull(); + vi.useRealTimers(); + }); + it('highlights the connected wallet regardless of address case', () => { // The backend groups EVM owners lowercased; the wallet reports mixed case. useLeaderboard.mockReturnValue({ @@ -126,8 +149,8 @@ describe('Leaderboard', () => { renderBoard(); - const mine = screen.getByText('Yasu').closest('li') as HTMLElement; - const theirs = screen.getByText('Someone else').closest('li') as HTMLElement; + const mine = screen.getByText('Yasu').closest('article') as HTMLElement; + const theirs = screen.getByText('Someone else').closest('article') as HTMLElement; expect(mine.className).not.toEqual(theirs.className); }); From 29f5cdfdf0c3a72edd5d2ca91d889472dbb1f982 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Fri, 7 Aug 2026 14:09:39 -0400 Subject: [PATCH 59/61] feat(leaderboard): search by pet name or wallet address on both boards --- .../repositories/leaderboard.repository.ts | 37 +++++++++++++++---- .../leaderboard.repository.test.ts | 31 ++++++++++++++++ frontend/src/components/leaderboard/index.tsx | 18 +++------ .../tests/components/leaderboard.test.tsx | 12 +++--- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/backend/src/repositories/leaderboard.repository.ts b/backend/src/repositories/leaderboard.repository.ts index 19c866b9..ef46489e 100644 --- a/backend/src/repositories/leaderboard.repository.ts +++ b/backend/src/repositories/leaderboard.repository.ts @@ -108,7 +108,11 @@ const HAS_FOUGHT = Prisma.sql`${WINS} + ${LOSSES} > 0`; const petOrder = Prisma.sql`${WINS} DESC, ${LOSSES} ASC, ${LEVEL} DESC, r.pet_id ASC`; /** - * A search term as a case-insensitive contains-match, or nothing at all. + * A search term as a case-insensitive contains-match against any of several columns. + * + * Several, because one box has to answer both questions people bring here — "how is my + * pet doing" and "how is that player doing" — and nobody should have to know which board + * indexes which. A wallet address typed into the pet board finds that wallet's pets. * * `TRUE` for a blank term rather than a second query: an unfiltered board is the same * shape as a filtered one, and branching would double every query below. @@ -116,12 +120,17 @@ const petOrder = Prisma.sql`${WINS} DESC, ${LOSSES} ASC, ${LEVEL} DESC, r.pet_id * `%` and `_` are escaped because they are wildcards to `ILIKE` — a player searching for * a pet actually named `100%` should not match every pet on the board. */ -function contains(column: Prisma.Sql, term: string | undefined): Prisma.Sql { +function matchesAny(columns: Prisma.Sql[], term: string | undefined): Prisma.Sql { const needle = term?.trim(); if (!needle) return Prisma.sql`TRUE`; const escaped = needle.replace(/[\\%_]/g, (char) => `\\${char}`); - return Prisma.sql`${column} ILIKE ${`%${escaped}%`} ESCAPE '\\'`; + const pattern = `%${escaped}%`; + return Prisma.sql`(${Prisma.join( + columns.map((column) => Prisma.sql`${column} ILIKE ${pattern} ESCAPE '\\'`), + ' OR ' + )})`; } + const playerOrder = (owner: Prisma.Sql) => Prisma.sql`SUM(${WINS}) DESC, SUM(${LOSSES}) ASC, ${owner} ASC`; @@ -131,7 +140,12 @@ export async function findPetLeaderboard( ): Promise<{ entries: LeaderboardEntry[]; total: number }> { const join = progressJoin(servedChainIdForFamily(params.chain)); const skip = params.page * params.pageSize; - const match = contains(Prisma.sql`r.name`, params.search); + // Name or owner: the pet board is where someone pastes an address to see a rival's + // pets, and where they type a name to find their own. + const match = matchesAny( + [Prisma.sql`ranked.name`, Prisma.sql`ranked.owner`], + params.search + ); /** * Ranked first, filtered second. @@ -183,7 +197,13 @@ export async function findPlayerLeaderboard( const join = progressJoin(servedChainIdForFamily(params.chain)); const owner = ownerKey(params.chain, 'r'); const skip = params.page * params.pageSize; - const match = contains(Prisma.sql`ranked.owner`, params.search); + // Address or any of the owner's pet names, so looking up the player behind a pet + // works without knowing whose it is. The names are aggregated in the subquery below + // because the filter runs outside it, after the grouping. + const match = matchesAny( + [Prisma.sql`ranked.owner`, Prisma.sql`ranked."petNames"`], + params.search + ); // The SUMs are cast because Postgres widens them to bigint, which Prisma would hand // back as a BigInt the GraphQL Int serializer cannot take. A player's battle count has @@ -196,6 +216,7 @@ export async function findPlayerLeaderboard( SUM(${WINS})::int AS "winCount", SUM(${LOSSES})::int AS "lossCount", COUNT(*)::int AS "petCount", + STRING_AGG(r.name, ' ') AS "petNames", ROW_NUMBER() OVER (ORDER BY ${playerOrder(owner)})::int AS rank FROM pet_roster r ${join} @@ -204,7 +225,7 @@ export async function findPlayerLeaderboard( `; const [rows, counted] = await Promise.all([ - prisma.$queryRaw<(PlayerRow & { rank: number })[]>` + prisma.$queryRaw<(PlayerRow & { rank: number; petNames: string })[]>` SELECT * FROM (${ranked}) ranked WHERE ${match} ORDER BY rank @@ -218,7 +239,9 @@ export async function findPlayerLeaderboard( ]); return { - entries: rows, + // `petNames` exists to be searched, not shown: dropped here so it never reaches a + // client that would have to know to ignore it. + entries: rows.map(({ petNames: _petNames, ...entry }) => entry), total: Number(counted[0]?.total ?? 0), }; } diff --git a/backend/tests/repositories/leaderboard.repository.test.ts b/backend/tests/repositories/leaderboard.repository.test.ts index 82cfe35b..46f9e223 100644 --- a/backend/tests/repositories/leaderboard.repository.test.ts +++ b/backend/tests/repositories/leaderboard.repository.test.ts @@ -129,6 +129,17 @@ describe('findPetLeaderboard', () => { expect(sqlOfCall(1)).toContain('ILIKE'); }); + // One box, both questions: a name finds a pet, an address finds that wallet's pets. + it('matches a term against the pet name or its owner', async () => { + mockJoinQuery([], 0); + + await findPetLeaderboard({ chain: 'evm', page: 0, pageSize: 20, search: '0xf00d' }); + + const sql = sqlOfCall(0); + expect(sql).toContain('ranked.name ILIKE'); + expect(sql).toContain('ranked.owner ILIKE'); + }); + it('leaves the board unfiltered when nothing is searched for', async () => { mockJoinQuery([], 0); @@ -210,6 +221,26 @@ describe('findPlayerLeaderboard', () => { expect(sql.indexOf('ILIKE')).toBeGreaterThan(sql.indexOf('ROW_NUMBER() OVER')); }); + // Aggregated in the subquery because the filter runs outside it, after the grouping: + // looking up the player behind a pet should not require knowing whose it is. + it("matches a term against the address or the owner's pet names", async () => { + mockJoinQuery([], 0); + + await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20, search: 'Rex' }); + + const sql = sqlOfCall(0); + expect(sql).toContain('STRING_AGG(r.name'); + expect(sql).toContain('ranked."petNames" ILIKE'); + }); + + it('keeps the searchable pet names out of what it returns', async () => { + mockJoinQuery([{ ...playerRow, petNames: 'Rex Bramble' }], 1); + + const result = await findPlayerLeaderboard({ chain: 'evm', page: 0, pageSize: 20 }); + + expect(result.entries[0]).not.toHaveProperty('petNames'); + }); + it('folds EVM owners to one group so a wallet is not listed twice', async () => { // indexer-go is not guaranteed to write the roster in one case, and an unfolded // group would split a single wallet's record across two rows. diff --git a/frontend/src/components/leaderboard/index.tsx b/frontend/src/components/leaderboard/index.tsx index 9a60d65b..6f080bcf 100644 --- a/frontend/src/components/leaderboard/index.tsx +++ b/frontend/src/components/leaderboard/index.tsx @@ -257,13 +257,11 @@ const Leaderboard: React.FC = () => { const showBoard = (next: Board) => { setBoard(next); - // Page 3 of the pet board says nothing about where a player sits, and the two - // boards have different lengths. The term goes too: the boards search different - // things — a pet's name and an owner's address — so carrying one across would - // hand the other board a query that cannot match. + // Only the page resets. Page 3 of the pet board says nothing about where a player + // sits, and the two boards are different lengths. The search term carries over on + // purpose now that both boards match a name *or* an address: looking a pet up and + // then switching boards is how you find out who owns it. setPage(0); - setTerm(''); - setSearch(''); }; const lastPage = Math.max(0, Math.ceil(active.total / active.pageSize) - 1); @@ -348,12 +346,8 @@ const Leaderboard: React.FC = () => { type="search" value={term} onChange={(event) => setTerm(event.target.value)} - placeholder={ - board === 'pets' ? 'Search pets by name' : 'Search players by address' - } - aria-label={ - board === 'pets' ? 'Search pets by name' : 'Search players by address' - } + placeholder="Search by pet name or wallet address" + aria-label="Search by pet name or wallet address" /> diff --git a/frontend/tests/components/leaderboard.test.tsx b/frontend/tests/components/leaderboard.test.tsx index 49f9115c..0613b453 100644 --- a/frontend/tests/components/leaderboard.test.tsx +++ b/frontend/tests/components/leaderboard.test.tsx @@ -262,7 +262,7 @@ describe('Leaderboard search', () => { usePlayerLeaderboard.mockReturnValue(emptyResult); renderBoard(); - await userEvent.type(screen.getByRole('searchbox', { name: /search pets/i }), 'Yas'); + await userEvent.type(screen.getByRole('searchbox', { name: /pet name or wallet/i }), 'Yas'); // Nothing yet: a round trip per keystroke is what the debounce exists to avoid. expect(useLeaderboard).not.toHaveBeenCalledWith(expect.objectContaining({ search: 'Yas' })); @@ -290,9 +290,9 @@ describe('Leaderboard search', () => { vi.useRealTimers(); }); - // The boards search different things, so a pet name handed to the player board could - // only ever match nothing. - it('clears the term when the other board is opened', async () => { + // Both boards match a name or an address, so the term is worth keeping: looking a pet + // up and switching boards is how you find out who owns it. + it('carries the term to the other board', async () => { vi.useFakeTimers({ shouldAdvanceTime: true }); useLeaderboard.mockReturnValue(board()); usePlayerLeaderboard.mockReturnValue(board()); @@ -306,9 +306,9 @@ describe('Leaderboard search', () => { await userEvent.click(screen.getByRole('tab', { name: 'Players' })); - expect(screen.getByRole('searchbox')).toHaveValue(''); + expect(screen.getByRole('searchbox')).toHaveValue('Yasu'); expect(usePlayerLeaderboard).toHaveBeenLastCalledWith( - expect.objectContaining({ search: '' }), + expect.objectContaining({ search: 'Yasu' }), ); vi.useRealTimers(); }); From e784d695ec68d02706939ceee7267fd1614ad2a2 Mon Sep 17 00:00:00 2001 From: heyradcode Date: Fri, 7 Aug 2026 14:28:46 -0400 Subject: [PATCH 60/61] refactor(backend): group the battle features under one directory --- .../{battle-anchor => battle/anchor}/abi.ts | 0 .../anchor}/anchor.service.ts | 0 .../{battle-anchor => battle/anchor}/index.ts | 2 +- .../batcher}/batch.builder.ts | 0 .../batcher}/batcher.controller.ts | 0 .../batcher}/batcher.service.ts | 0 .../batcher}/index.ts | 0 .../ledger}/accept.controller.ts | 0 .../ledger}/accept.service.ts | 4 ++-- .../ledger}/consent.controller.ts | 0 .../ledger}/consent.service.ts | 0 .../ledger}/corpus.controller.ts | 0 .../ledger}/corpus.service.ts | 0 .../ledger}/domain.ts | 0 .../{battle-ledger => battle/ledger}/index.ts | 0 .../ledger}/intent.controller.ts | 0 .../ledger}/intent.service.ts | 0 .../{battle-ledger => battle/ledger}/mode.ts | 0 .../ledger}/outbox.ts | 0 .../ledger}/reads.controller.ts | 0 .../ledger}/reads.service.ts | 2 +- .../ledger}/snapshot.builder.ts | 0 .../{battle-ledger => battle/ledger}/state.ts | 0 .../ledger}/transitions.ts | 0 .../randomness}/drand.client.ts | 0 .../randomness}/index.ts | 0 .../rewards}/entitlements.ts | 0 .../rewards}/index.ts | 0 .../rewards}/season.controller.ts | 0 .../rewards}/season.open.ts | 0 .../rewards}/season.service.ts | 0 .../room}/battle-room.controller.ts | 0 .../room}/battle-room.schema.ts | 0 .../room}/battle-room.service.ts | 0 .../{battle-room => battle/room}/index.ts | 2 +- .../{battle-signer => battle/signer}/index.ts | 0 .../signer}/signer.kms.ts | 0 .../signer}/signer.local.ts | 0 .../signer}/signer.registry.ts | 0 .../signer}/signer.service.ts | 0 .../signer}/signer.types.ts | 0 .../worker}/beacon.worker.ts | 4 ++-- .../worker}/compute.worker.ts | 2 +- .../{battle-worker => battle/worker}/index.ts | 0 .../worker}/publish.worker.ts | 2 +- .../worker}/runner.ts | 2 +- .../worker}/sign.worker.ts | 4 ++-- .../worker}/verify.worker.ts | 2 +- .../repositories/battleProgress.overlay.ts | 2 +- .../repositories/leaderboard.repository.ts | 2 +- backend/src/repositories/roster.repository.ts | 2 +- backend/src/routes/battle-room.ts | 2 +- backend/src/routes/battle.ts | 2 +- backend/src/routes/receipts.ts | 4 ++-- backend/src/routes/rewards.ts | 2 +- backend/src/server.ts | 8 +++---- .../anchor}/anchor.service.test.ts | 2 +- .../batcher}/batch.builder.test.ts | 2 +- .../batcher}/batcher.service.test.ts | 2 +- .../ledger}/accept.service.test.ts | 22 +++++++++---------- .../ledger}/config.service.test.ts | 4 ++-- .../ledger}/consent.service.test.ts | 2 +- .../ledger}/corpus.controller.test.ts | 6 ++--- .../ledger}/corpus.service.test.ts | 2 +- .../ledger}/drills.test.ts | 6 ++--- .../ledger}/intent.service.test.ts | 2 +- .../ledger}/mode.test.ts | 2 +- .../ledger}/outbox.reschedule.test.ts | 2 +- .../ledger}/outbox.test.ts | 2 +- .../ledger}/reads.controller.test.ts | 6 ++--- .../ledger}/reads.service.test.ts | 6 ++--- .../ledger}/snapshot.builder.test.ts | 2 +- .../ledger}/state.test.ts | 2 +- .../ledger}/transitions.test.ts | 2 +- .../randomness}/drand.client.test.ts | 4 ++-- .../rewards}/entitlements.test.ts | 2 +- .../rewards}/season.open.test.ts | 2 +- .../rewards}/season.service.test.ts | 2 +- .../room}/battle-room.controller.test.ts | 6 ++--- .../signer}/signer.persistence.test.ts | 2 +- .../signer}/signer.registry.test.ts | 4 ++-- .../signer}/signer.service.test.ts | 2 +- .../worker}/beacon.worker.test.ts | 10 ++++----- .../worker}/compute.worker.test.ts | 6 ++--- .../worker}/publish.worker.test.ts | 6 ++--- .../worker}/runner.test.ts | 20 ++++++++--------- .../worker}/sign.worker.test.ts | 12 +++++----- .../worker}/verify.worker.test.ts | 6 ++--- bash.exe.stackdump | 9 ++++++++ docs/battle-protocol.md | 2 +- services/indexer-go/README.md | 2 +- 91 files changed, 115 insertions(+), 106 deletions(-) rename backend/src/features/{battle-anchor => battle/anchor}/abi.ts (100%) rename backend/src/features/{battle-anchor => battle/anchor}/anchor.service.ts (100%) rename backend/src/features/{battle-anchor => battle/anchor}/index.ts (98%) rename backend/src/features/{battle-batcher => battle/batcher}/batch.builder.ts (100%) rename backend/src/features/{battle-batcher => battle/batcher}/batcher.controller.ts (100%) rename backend/src/features/{battle-batcher => battle/batcher}/batcher.service.ts (100%) rename backend/src/features/{battle-batcher => battle/batcher}/index.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/accept.controller.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/accept.service.ts (98%) rename backend/src/features/{battle-ledger => battle/ledger}/consent.controller.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/consent.service.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/corpus.controller.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/corpus.service.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/domain.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/index.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/intent.controller.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/intent.service.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/mode.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/outbox.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/reads.controller.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/reads.service.ts (99%) rename backend/src/features/{battle-ledger => battle/ledger}/snapshot.builder.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/state.ts (100%) rename backend/src/features/{battle-ledger => battle/ledger}/transitions.ts (100%) rename backend/src/features/{battle-randomness => battle/randomness}/drand.client.ts (100%) rename backend/src/features/{battle-randomness => battle/randomness}/index.ts (100%) rename backend/src/features/{battle-rewards => battle/rewards}/entitlements.ts (100%) rename backend/src/features/{battle-rewards => battle/rewards}/index.ts (100%) rename backend/src/features/{battle-rewards => battle/rewards}/season.controller.ts (100%) rename backend/src/features/{battle-rewards => battle/rewards}/season.open.ts (100%) rename backend/src/features/{battle-rewards => battle/rewards}/season.service.ts (100%) rename backend/src/features/{battle-room => battle/room}/battle-room.controller.ts (100%) rename backend/src/features/{battle-room => battle/room}/battle-room.schema.ts (100%) rename backend/src/features/{battle-room => battle/room}/battle-room.service.ts (100%) rename backend/src/features/{battle-room => battle/room}/index.ts (78%) rename backend/src/features/{battle-signer => battle/signer}/index.ts (100%) rename backend/src/features/{battle-signer => battle/signer}/signer.kms.ts (100%) rename backend/src/features/{battle-signer => battle/signer}/signer.local.ts (100%) rename backend/src/features/{battle-signer => battle/signer}/signer.registry.ts (100%) rename backend/src/features/{battle-signer => battle/signer}/signer.service.ts (100%) rename backend/src/features/{battle-signer => battle/signer}/signer.types.ts (100%) rename backend/src/features/{battle-worker => battle/worker}/beacon.worker.ts (98%) rename backend/src/features/{battle-worker => battle/worker}/compute.worker.ts (99%) rename backend/src/features/{battle-worker => battle/worker}/index.ts (100%) rename backend/src/features/{battle-worker => battle/worker}/publish.worker.ts (99%) rename backend/src/features/{battle-worker => battle/worker}/runner.ts (98%) rename backend/src/features/{battle-worker => battle/worker}/sign.worker.ts (99%) rename backend/src/features/{battle-worker => battle/worker}/verify.worker.ts (99%) rename backend/tests/features/{battle-anchor => battle/anchor}/anchor.service.test.ts (99%) rename backend/tests/features/{battle-batcher => battle/batcher}/batch.builder.test.ts (99%) rename backend/tests/features/{battle-batcher => battle/batcher}/batcher.service.test.ts (99%) rename backend/tests/features/{battle-ledger => battle/ledger}/accept.service.test.ts (95%) rename backend/tests/features/{battle-ledger => battle/ledger}/config.service.test.ts (96%) rename backend/tests/features/{battle-ledger => battle/ledger}/consent.service.test.ts (99%) rename backend/tests/features/{battle-ledger => battle/ledger}/corpus.controller.test.ts (93%) rename backend/tests/features/{battle-ledger => battle/ledger}/corpus.service.test.ts (99%) rename backend/tests/features/{battle-ledger => battle/ledger}/drills.test.ts (98%) rename backend/tests/features/{battle-ledger => battle/ledger}/intent.service.test.ts (99%) rename backend/tests/features/{battle-ledger => battle/ledger}/mode.test.ts (98%) rename backend/tests/features/{battle-ledger => battle/ledger}/outbox.reschedule.test.ts (94%) rename backend/tests/features/{battle-ledger => battle/ledger}/outbox.test.ts (99%) rename backend/tests/features/{battle-ledger => battle/ledger}/reads.controller.test.ts (96%) rename backend/tests/features/{battle-ledger => battle/ledger}/reads.service.test.ts (98%) rename backend/tests/features/{battle-ledger => battle/ledger}/snapshot.builder.test.ts (99%) rename backend/tests/features/{battle-ledger => battle/ledger}/state.test.ts (99%) rename backend/tests/features/{battle-ledger => battle/ledger}/transitions.test.ts (99%) rename backend/tests/features/{battle-randomness => battle/randomness}/drand.client.test.ts (98%) rename backend/tests/features/{battle-rewards => battle/rewards}/entitlements.test.ts (99%) rename backend/tests/features/{battle-rewards => battle/rewards}/season.open.test.ts (99%) rename backend/tests/features/{battle-rewards => battle/rewards}/season.service.test.ts (99%) rename backend/tests/features/{battle-room => battle/room}/battle-room.controller.test.ts (87%) rename backend/tests/features/{battle-signer => battle/signer}/signer.persistence.test.ts (99%) rename backend/tests/features/{battle-signer => battle/signer}/signer.registry.test.ts (98%) rename backend/tests/features/{battle-signer => battle/signer}/signer.service.test.ts (99%) rename backend/tests/features/{battle-worker => battle/worker}/beacon.worker.test.ts (96%) rename backend/tests/features/{battle-worker => battle/worker}/compute.worker.test.ts (98%) rename backend/tests/features/{battle-worker => battle/worker}/publish.worker.test.ts (98%) rename backend/tests/features/{battle-worker => battle/worker}/runner.test.ts (86%) rename backend/tests/features/{battle-worker => battle/worker}/sign.worker.test.ts (98%) rename backend/tests/features/{battle-worker => battle/worker}/verify.worker.test.ts (98%) create mode 100644 bash.exe.stackdump diff --git a/backend/src/features/battle-anchor/abi.ts b/backend/src/features/battle/anchor/abi.ts similarity index 100% rename from backend/src/features/battle-anchor/abi.ts rename to backend/src/features/battle/anchor/abi.ts diff --git a/backend/src/features/battle-anchor/anchor.service.ts b/backend/src/features/battle/anchor/anchor.service.ts similarity index 100% rename from backend/src/features/battle-anchor/anchor.service.ts rename to backend/src/features/battle/anchor/anchor.service.ts diff --git a/backend/src/features/battle-anchor/index.ts b/backend/src/features/battle/anchor/index.ts similarity index 98% rename from backend/src/features/battle-anchor/index.ts rename to backend/src/features/battle/anchor/index.ts index 5d8307de..bbbb8bc1 100644 --- a/backend/src/features/battle-anchor/index.ts +++ b/backend/src/features/battle/anchor/index.ts @@ -2,7 +2,7 @@ import { createPublicClient, createWalletClient, http, type Address, type Chain import { privateKeyToAccount } from 'viem/accounts'; import { env } from '@config/env'; -import { buildNextBatch } from '@features/battle-batcher'; +import { buildNextBatch } from '@features/battle/batcher'; import { anchorNextBatch, type AnchorContext } from './anchor.service'; diff --git a/backend/src/features/battle-batcher/batch.builder.ts b/backend/src/features/battle/batcher/batch.builder.ts similarity index 100% rename from backend/src/features/battle-batcher/batch.builder.ts rename to backend/src/features/battle/batcher/batch.builder.ts diff --git a/backend/src/features/battle-batcher/batcher.controller.ts b/backend/src/features/battle/batcher/batcher.controller.ts similarity index 100% rename from backend/src/features/battle-batcher/batcher.controller.ts rename to backend/src/features/battle/batcher/batcher.controller.ts diff --git a/backend/src/features/battle-batcher/batcher.service.ts b/backend/src/features/battle/batcher/batcher.service.ts similarity index 100% rename from backend/src/features/battle-batcher/batcher.service.ts rename to backend/src/features/battle/batcher/batcher.service.ts diff --git a/backend/src/features/battle-batcher/index.ts b/backend/src/features/battle/batcher/index.ts similarity index 100% rename from backend/src/features/battle-batcher/index.ts rename to backend/src/features/battle/batcher/index.ts diff --git a/backend/src/features/battle-ledger/accept.controller.ts b/backend/src/features/battle/ledger/accept.controller.ts similarity index 100% rename from backend/src/features/battle-ledger/accept.controller.ts rename to backend/src/features/battle/ledger/accept.controller.ts diff --git a/backend/src/features/battle-ledger/accept.service.ts b/backend/src/features/battle/ledger/accept.service.ts similarity index 98% rename from backend/src/features/battle-ledger/accept.service.ts rename to backend/src/features/battle/ledger/accept.service.ts index 11e81936..3340c7de 100644 --- a/backend/src/features/battle-ledger/accept.service.ts +++ b/backend/src/features/battle/ledger/accept.service.ts @@ -18,8 +18,8 @@ import { BattleState } from '@generated/prisma/enums'; import { prisma } from '@config/prisma'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; -import { activeSigningKey, sign, SignerRefusedError } from '../battle-signer'; -import { chooseCommitmentRound, roundPublishTime } from '../battle-randomness'; +import { activeSigningKey, sign, SignerRefusedError } from '../signer'; +import { chooseCommitmentRound, roundPublishTime } from '../randomness'; import { type ConsentFailure, consumeDailyBudget, findCoveringAuthorization } from './consent.service'; import { servedDeploymentId } from './domain'; diff --git a/backend/src/features/battle-ledger/consent.controller.ts b/backend/src/features/battle/ledger/consent.controller.ts similarity index 100% rename from backend/src/features/battle-ledger/consent.controller.ts rename to backend/src/features/battle/ledger/consent.controller.ts diff --git a/backend/src/features/battle-ledger/consent.service.ts b/backend/src/features/battle/ledger/consent.service.ts similarity index 100% rename from backend/src/features/battle-ledger/consent.service.ts rename to backend/src/features/battle/ledger/consent.service.ts diff --git a/backend/src/features/battle-ledger/corpus.controller.ts b/backend/src/features/battle/ledger/corpus.controller.ts similarity index 100% rename from backend/src/features/battle-ledger/corpus.controller.ts rename to backend/src/features/battle/ledger/corpus.controller.ts diff --git a/backend/src/features/battle-ledger/corpus.service.ts b/backend/src/features/battle/ledger/corpus.service.ts similarity index 100% rename from backend/src/features/battle-ledger/corpus.service.ts rename to backend/src/features/battle/ledger/corpus.service.ts diff --git a/backend/src/features/battle-ledger/domain.ts b/backend/src/features/battle/ledger/domain.ts similarity index 100% rename from backend/src/features/battle-ledger/domain.ts rename to backend/src/features/battle/ledger/domain.ts diff --git a/backend/src/features/battle-ledger/index.ts b/backend/src/features/battle/ledger/index.ts similarity index 100% rename from backend/src/features/battle-ledger/index.ts rename to backend/src/features/battle/ledger/index.ts diff --git a/backend/src/features/battle-ledger/intent.controller.ts b/backend/src/features/battle/ledger/intent.controller.ts similarity index 100% rename from backend/src/features/battle-ledger/intent.controller.ts rename to backend/src/features/battle/ledger/intent.controller.ts diff --git a/backend/src/features/battle-ledger/intent.service.ts b/backend/src/features/battle/ledger/intent.service.ts similarity index 100% rename from backend/src/features/battle-ledger/intent.service.ts rename to backend/src/features/battle/ledger/intent.service.ts diff --git a/backend/src/features/battle-ledger/mode.ts b/backend/src/features/battle/ledger/mode.ts similarity index 100% rename from backend/src/features/battle-ledger/mode.ts rename to backend/src/features/battle/ledger/mode.ts diff --git a/backend/src/features/battle-ledger/outbox.ts b/backend/src/features/battle/ledger/outbox.ts similarity index 100% rename from backend/src/features/battle-ledger/outbox.ts rename to backend/src/features/battle/ledger/outbox.ts diff --git a/backend/src/features/battle-ledger/reads.controller.ts b/backend/src/features/battle/ledger/reads.controller.ts similarity index 100% rename from backend/src/features/battle-ledger/reads.controller.ts rename to backend/src/features/battle/ledger/reads.controller.ts diff --git a/backend/src/features/battle-ledger/reads.service.ts b/backend/src/features/battle/ledger/reads.service.ts similarity index 99% rename from backend/src/features/battle-ledger/reads.service.ts rename to backend/src/features/battle/ledger/reads.service.ts index 744e5f32..041bfd74 100644 --- a/backend/src/features/battle-ledger/reads.service.ts +++ b/backend/src/features/battle/ledger/reads.service.ts @@ -2,7 +2,7 @@ import { hashRuleset, SOURCE_DEFAULT_RULESET, type Hex } from '@cryptopets/proto import { ethers } from 'ethers'; import { prisma } from '@config/prisma'; -import { listSigningKeys } from '@features/battle-signer'; +import { listSigningKeys } from '@features/battle/signer'; import { servedChainIds, servedDeploymentId } from './domain'; import { backendBattleModeEnabled } from './mode'; diff --git a/backend/src/features/battle-ledger/snapshot.builder.ts b/backend/src/features/battle/ledger/snapshot.builder.ts similarity index 100% rename from backend/src/features/battle-ledger/snapshot.builder.ts rename to backend/src/features/battle/ledger/snapshot.builder.ts diff --git a/backend/src/features/battle-ledger/state.ts b/backend/src/features/battle/ledger/state.ts similarity index 100% rename from backend/src/features/battle-ledger/state.ts rename to backend/src/features/battle/ledger/state.ts diff --git a/backend/src/features/battle-ledger/transitions.ts b/backend/src/features/battle/ledger/transitions.ts similarity index 100% rename from backend/src/features/battle-ledger/transitions.ts rename to backend/src/features/battle/ledger/transitions.ts diff --git a/backend/src/features/battle-randomness/drand.client.ts b/backend/src/features/battle/randomness/drand.client.ts similarity index 100% rename from backend/src/features/battle-randomness/drand.client.ts rename to backend/src/features/battle/randomness/drand.client.ts diff --git a/backend/src/features/battle-randomness/index.ts b/backend/src/features/battle/randomness/index.ts similarity index 100% rename from backend/src/features/battle-randomness/index.ts rename to backend/src/features/battle/randomness/index.ts diff --git a/backend/src/features/battle-rewards/entitlements.ts b/backend/src/features/battle/rewards/entitlements.ts similarity index 100% rename from backend/src/features/battle-rewards/entitlements.ts rename to backend/src/features/battle/rewards/entitlements.ts diff --git a/backend/src/features/battle-rewards/index.ts b/backend/src/features/battle/rewards/index.ts similarity index 100% rename from backend/src/features/battle-rewards/index.ts rename to backend/src/features/battle/rewards/index.ts diff --git a/backend/src/features/battle-rewards/season.controller.ts b/backend/src/features/battle/rewards/season.controller.ts similarity index 100% rename from backend/src/features/battle-rewards/season.controller.ts rename to backend/src/features/battle/rewards/season.controller.ts diff --git a/backend/src/features/battle-rewards/season.open.ts b/backend/src/features/battle/rewards/season.open.ts similarity index 100% rename from backend/src/features/battle-rewards/season.open.ts rename to backend/src/features/battle/rewards/season.open.ts diff --git a/backend/src/features/battle-rewards/season.service.ts b/backend/src/features/battle/rewards/season.service.ts similarity index 100% rename from backend/src/features/battle-rewards/season.service.ts rename to backend/src/features/battle/rewards/season.service.ts diff --git a/backend/src/features/battle-room/battle-room.controller.ts b/backend/src/features/battle/room/battle-room.controller.ts similarity index 100% rename from backend/src/features/battle-room/battle-room.controller.ts rename to backend/src/features/battle/room/battle-room.controller.ts diff --git a/backend/src/features/battle-room/battle-room.schema.ts b/backend/src/features/battle/room/battle-room.schema.ts similarity index 100% rename from backend/src/features/battle-room/battle-room.schema.ts rename to backend/src/features/battle/room/battle-room.schema.ts diff --git a/backend/src/features/battle-room/battle-room.service.ts b/backend/src/features/battle/room/battle-room.service.ts similarity index 100% rename from backend/src/features/battle-room/battle-room.service.ts rename to backend/src/features/battle/room/battle-room.service.ts diff --git a/backend/src/features/battle-room/index.ts b/backend/src/features/battle/room/index.ts similarity index 78% rename from backend/src/features/battle-room/index.ts rename to backend/src/features/battle/room/index.ts index 5ffcb4a2..41c661b6 100644 --- a/backend/src/features/battle-room/index.ts +++ b/backend/src/features/battle/room/index.ts @@ -1,6 +1,6 @@ /** * Public surface of the battle-room feature. External code imports from - * `@features/battle-room` so the internal layout can change without touching + * `@features/battle/room` so the internal layout can change without touching * call sites. */ export { createBattleRoom } from './battle-room.controller'; diff --git a/backend/src/features/battle-signer/index.ts b/backend/src/features/battle/signer/index.ts similarity index 100% rename from backend/src/features/battle-signer/index.ts rename to backend/src/features/battle/signer/index.ts diff --git a/backend/src/features/battle-signer/signer.kms.ts b/backend/src/features/battle/signer/signer.kms.ts similarity index 100% rename from backend/src/features/battle-signer/signer.kms.ts rename to backend/src/features/battle/signer/signer.kms.ts diff --git a/backend/src/features/battle-signer/signer.local.ts b/backend/src/features/battle/signer/signer.local.ts similarity index 100% rename from backend/src/features/battle-signer/signer.local.ts rename to backend/src/features/battle/signer/signer.local.ts diff --git a/backend/src/features/battle-signer/signer.registry.ts b/backend/src/features/battle/signer/signer.registry.ts similarity index 100% rename from backend/src/features/battle-signer/signer.registry.ts rename to backend/src/features/battle/signer/signer.registry.ts diff --git a/backend/src/features/battle-signer/signer.service.ts b/backend/src/features/battle/signer/signer.service.ts similarity index 100% rename from backend/src/features/battle-signer/signer.service.ts rename to backend/src/features/battle/signer/signer.service.ts diff --git a/backend/src/features/battle-signer/signer.types.ts b/backend/src/features/battle/signer/signer.types.ts similarity index 100% rename from backend/src/features/battle-signer/signer.types.ts rename to backend/src/features/battle/signer/signer.types.ts diff --git a/backend/src/features/battle-worker/beacon.worker.ts b/backend/src/features/battle/worker/beacon.worker.ts similarity index 98% rename from backend/src/features/battle-worker/beacon.worker.ts rename to backend/src/features/battle/worker/beacon.worker.ts index 91c974bc..42827724 100644 --- a/backend/src/features/battle-worker/beacon.worker.ts +++ b/backend/src/features/battle/worker/beacon.worker.ts @@ -10,8 +10,8 @@ import { completeOutbox, OUTBOX_TOPICS, rescheduleOutbox, -} from '@features/battle-ledger'; -import { fetchVerifiedRound, roundPublishTime } from '@features/battle-randomness'; +} from '@features/battle/ledger'; +import { fetchVerifiedRound, roundPublishTime } from '@features/battle/randomness'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; /** diff --git a/backend/src/features/battle-worker/compute.worker.ts b/backend/src/features/battle/worker/compute.worker.ts similarity index 99% rename from backend/src/features/battle-worker/compute.worker.ts rename to backend/src/features/battle/worker/compute.worker.ts index ff6b8f13..dbc74be5 100644 --- a/backend/src/features/battle-worker/compute.worker.ts +++ b/backend/src/features/battle/worker/compute.worker.ts @@ -10,7 +10,7 @@ import { BattleState } from '@generated/prisma/enums'; import type { Prisma } from '@generated/prisma/client'; import { prisma } from '@config/prisma'; -import { applyTransition, type ClaimedMessage, completeOutbox, OUTBOX_TOPICS } from '@features/battle-ledger'; +import { applyTransition, type ClaimedMessage, completeOutbox, OUTBOX_TOPICS } from '@features/battle/ledger'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; /** diff --git a/backend/src/features/battle-worker/index.ts b/backend/src/features/battle/worker/index.ts similarity index 100% rename from backend/src/features/battle-worker/index.ts rename to backend/src/features/battle/worker/index.ts diff --git a/backend/src/features/battle-worker/publish.worker.ts b/backend/src/features/battle/worker/publish.worker.ts similarity index 99% rename from backend/src/features/battle-worker/publish.worker.ts rename to backend/src/features/battle/worker/publish.worker.ts index 6eeff6e6..ad5a7a0c 100644 --- a/backend/src/features/battle-worker/publish.worker.ts +++ b/backend/src/features/battle/worker/publish.worker.ts @@ -2,7 +2,7 @@ import { assertBattleReceipt, hashBattleReceipt, receiptFromWire, type WireBattl import { BattleState } from '@generated/prisma/enums'; import { prisma } from '@config/prisma'; -import { applyTransition, type ClaimedMessage, completeOutbox } from '@features/battle-ledger'; +import { applyTransition, type ClaimedMessage, completeOutbox } from '@features/battle/ledger'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; /** diff --git a/backend/src/features/battle-worker/runner.ts b/backend/src/features/battle/worker/runner.ts similarity index 98% rename from backend/src/features/battle-worker/runner.ts rename to backend/src/features/battle/worker/runner.ts index 7383a700..ac86833c 100644 --- a/backend/src/features/battle-worker/runner.ts +++ b/backend/src/features/battle/worker/runner.ts @@ -1,5 +1,5 @@ import { env } from '@config/env'; -import { type ClaimedMessage, claimOutbox, failOutbox, OUTBOX_TOPICS } from '@features/battle-ledger'; +import { type ClaimedMessage, claimOutbox, failOutbox, OUTBOX_TOPICS } from '@features/battle/ledger'; import { processAwaitBeaconMessage } from './beacon.worker'; import { processComputeMessage } from './compute.worker'; diff --git a/backend/src/features/battle-worker/sign.worker.ts b/backend/src/features/battle/worker/sign.worker.ts similarity index 99% rename from backend/src/features/battle-worker/sign.worker.ts rename to backend/src/features/battle/worker/sign.worker.ts index 3e783c6a..13c4b6ca 100644 --- a/backend/src/features/battle-worker/sign.worker.ts +++ b/backend/src/features/battle/worker/sign.worker.ts @@ -11,8 +11,8 @@ import type { Prisma } from '@generated/prisma/client'; import { env } from '@config/env'; import { prisma } from '@config/prisma'; -import { applyTransition, type ClaimedMessage, completeOutbox, OUTBOX_TOPICS } from '@features/battle-ledger'; -import { activeSigningKey, type EngineAttestation, sign, SignerRefusedError } from '@features/battle-signer'; +import { applyTransition, type ClaimedMessage, completeOutbox, OUTBOX_TOPICS } from '@features/battle/ledger'; +import { activeSigningKey, type EngineAttestation, sign, SignerRefusedError } from '@features/battle/signer'; import { recordBattleFromReceipt } from '@repositories/history.repository'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; diff --git a/backend/src/features/battle-worker/verify.worker.ts b/backend/src/features/battle/worker/verify.worker.ts similarity index 99% rename from backend/src/features/battle-worker/verify.worker.ts rename to backend/src/features/battle/worker/verify.worker.ts index 0e2a4608..e311efa2 100644 --- a/backend/src/features/battle-worker/verify.worker.ts +++ b/backend/src/features/battle/worker/verify.worker.ts @@ -11,7 +11,7 @@ import { BattleState } from '@generated/prisma/enums'; import type { Prisma } from '@generated/prisma/client'; import { prisma } from '@config/prisma'; -import { applyTransition, type ClaimedMessage, completeOutbox, OUTBOX_TOPICS } from '@features/battle-ledger'; +import { applyTransition, type ClaimedMessage, completeOutbox, OUTBOX_TOPICS } from '@features/battle/ledger'; import { callVerifyBattle, type VerifyBattleWire, type VerifyPetProgressionWire } from '@grpc-client/verifyBattle'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; diff --git a/backend/src/repositories/battleProgress.overlay.ts b/backend/src/repositories/battleProgress.overlay.ts index 9c1f2318..0d7270fa 100644 --- a/backend/src/repositories/battleProgress.overlay.ts +++ b/backend/src/repositories/battleProgress.overlay.ts @@ -1,7 +1,7 @@ import { chainFamily, type ChainId } from '@cryptopets/protocol'; import { prisma } from '@config/prisma'; -import { servedChainIds, servedDeploymentId } from '@features/battle-ledger/domain'; +import { servedChainIds, servedDeploymentId } from '@features/battle/ledger/domain'; import type { RosterPet } from './roster.repository'; import type { Chain } from '@typings/chain'; diff --git a/backend/src/repositories/leaderboard.repository.ts b/backend/src/repositories/leaderboard.repository.ts index ef46489e..8021966f 100644 --- a/backend/src/repositories/leaderboard.repository.ts +++ b/backend/src/repositories/leaderboard.repository.ts @@ -3,7 +3,7 @@ import { Prisma } from '@generated/prisma/client'; import { prisma } from '@config/prisma'; import { servedChainIdForFamily } from './battleProgress.overlay'; import { ownerKey } from './owner.sql'; -import { servedDeploymentId } from '@features/battle-ledger/domain'; +import { servedDeploymentId } from '@features/battle/ledger/domain'; import type { Chain } from '@typings/chain'; /** diff --git a/backend/src/repositories/roster.repository.ts b/backend/src/repositories/roster.repository.ts index ffeaf420..f8d24abf 100644 --- a/backend/src/repositories/roster.repository.ts +++ b/backend/src/repositories/roster.repository.ts @@ -6,7 +6,7 @@ import { tryGrpcGetPetState } from '@grpc-client/rosterReads'; import { mapRosterRowToRosterPet, type PetRosterRow } from './roster.mapping'; import { servedChainIdForFamily } from './battleProgress.overlay'; import { ownerKey } from './owner.sql'; -import { servedDeploymentId } from '@features/battle-ledger/domain'; +import { servedDeploymentId } from '@features/battle/ledger/domain'; import type { Chain } from '@typings/chain'; /** diff --git a/backend/src/routes/battle-room.ts b/backend/src/routes/battle-room.ts index 3b2b97eb..d98469d6 100644 --- a/backend/src/routes/battle-room.ts +++ b/backend/src/routes/battle-room.ts @@ -1,7 +1,7 @@ import express, { Router } from 'express'; import { verifyToken } from '@middleware/auth'; import { battleRoomRateLimit } from '@middleware/rateLimit'; -import { createBattleRoom } from '@features/battle-room'; +import { createBattleRoom } from '@features/battle/room'; const router: Router = express.Router(); diff --git a/backend/src/routes/battle.ts b/backend/src/routes/battle.ts index 47e23ee5..b88d8f04 100644 --- a/backend/src/routes/battle.ts +++ b/backend/src/routes/battle.ts @@ -15,7 +15,7 @@ import { postDefenseAuthorization, postVerifyReceipt, requireBackendBattleMode, -} from '@features/battle-ledger'; +} from '@features/battle/ledger'; import { verifyToken } from '@middleware/auth'; import { battleRoomRateLimit } from '@middleware/rateLimit'; diff --git a/backend/src/routes/receipts.ts b/backend/src/routes/receipts.ts index 918aac37..112f846b 100644 --- a/backend/src/routes/receipts.ts +++ b/backend/src/routes/receipts.ts @@ -1,7 +1,7 @@ import express, { Router } from 'express'; -import { getReceiptInclusionProof } from '@features/battle-batcher'; -import { getReceiptsByPet, getReceiptsBySequence, getReceiptsByWallet } from '@features/battle-ledger'; +import { getReceiptInclusionProof } from '@features/battle/batcher'; +import { getReceiptsByPet, getReceiptsBySequence, getReceiptsByWallet } from '@features/battle/ledger'; /** * The public receipt corpus (§H item 3): paginated export by pet, by wallet, and diff --git a/backend/src/routes/rewards.ts b/backend/src/routes/rewards.ts index 274df354..d12b1892 100644 --- a/backend/src/routes/rewards.ts +++ b/backend/src/routes/rewards.ts @@ -1,6 +1,6 @@ import express, { Router } from 'express'; -import { getSeason, getSeasonClaim } from '@features/battle-rewards'; +import { getSeason, getSeasonClaim } from '@features/battle/rewards'; /** * Reward seasons and claim proofs (§I). diff --git a/backend/src/server.ts b/backend/src/server.ts index b5cef047..4aff4aa0 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -2,10 +2,10 @@ import './register-path-aliases'; import { env } from '@config/env'; import { prisma } from '@config/prisma'; import app from './app'; -import { configureSigner, loadPersistedSigningKeys } from '@features/battle-signer'; +import { configureSigner, loadPersistedSigningKeys } from '@features/battle/signer'; import { startSettleKeeper, stopSettleKeeper } from '@features/settle-keeper'; -import { type BattleWorkerHandle, startBattleWorker } from '@features/battle-worker'; -import { startBatchAnchor, stopBatchAnchor } from '@features/battle-anchor'; +import { type BattleWorkerHandle, startBattleWorker } from '@features/battle/worker'; +import { startBatchAnchor, stopBatchAnchor } from '@features/battle/anchor'; import { startWsChannels, stopWsChannels } from '@ws/channel'; let battleWorker: BattleWorkerHandle | undefined; @@ -30,7 +30,7 @@ const server = app.listen(env.port, '0.0.0.0', () => { // Backend-authoritative battles (docs/battle-protocol.md §L Phase 3). // Selects the signing backend (refuses an in-process key in production; see - // @features/battle-signer) and starts the outbox worker that carries accepted battles + // @features/battle/signer) and starts the outbox worker that carries accepted battles // through to a signed receipt. // // Both are gated on the mode, so a deployment running only the on-chain path needs no diff --git a/backend/tests/features/battle-anchor/anchor.service.test.ts b/backend/tests/features/battle/anchor/anchor.service.test.ts similarity index 99% rename from backend/tests/features/battle-anchor/anchor.service.test.ts rename to backend/tests/features/battle/anchor/anchor.service.test.ts index 38ffdcdc..639325fd 100644 --- a/backend/tests/features/battle-anchor/anchor.service.test.ts +++ b/backend/tests/features/battle/anchor/anchor.service.test.ts @@ -5,7 +5,7 @@ vi.mock('@config/prisma', () => ({ })); import { prisma } from '@config/prisma'; -import { anchorNextBatch, ZERO_ROOT, type AnchorContext } from '@features/battle-anchor'; +import { anchorNextBatch, ZERO_ROOT, type AnchorContext } from '@features/battle/anchor'; const ROOT_1 = `0x${'11'.repeat(32)}`; const ROOT_2 = `0x${'22'.repeat(32)}`; diff --git a/backend/tests/features/battle-batcher/batch.builder.test.ts b/backend/tests/features/battle/batcher/batch.builder.test.ts similarity index 99% rename from backend/tests/features/battle-batcher/batch.builder.test.ts rename to backend/tests/features/battle/batcher/batch.builder.test.ts index e775d26a..1aef70bc 100644 --- a/backend/tests/features/battle-batcher/batch.builder.test.ts +++ b/backend/tests/features/battle/batcher/batch.builder.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'; import { merkleLeaf, verifyReceiptInclusion, type Hex } from '@cryptopets/protocol'; -import { buildBatch, hashRulesetSet, type BatchableReceipt } from '@features/battle-batcher'; +import { buildBatch, hashRulesetSet, type BatchableReceipt } from '@features/battle/batcher'; const RULESET_A = `0x${'aa'.repeat(32)}`; const RULESET_B = `0x${'bb'.repeat(32)}`; diff --git a/backend/tests/features/battle-batcher/batcher.service.test.ts b/backend/tests/features/battle/batcher/batcher.service.test.ts similarity index 99% rename from backend/tests/features/battle-batcher/batcher.service.test.ts rename to backend/tests/features/battle/batcher/batcher.service.test.ts index 627877be..0f37e1a6 100644 --- a/backend/tests/features/battle-batcher/batcher.service.test.ts +++ b/backend/tests/features/battle/batcher/batcher.service.test.ts @@ -19,7 +19,7 @@ vi.mock('@config/prisma', () => { }); import { prisma } from '@config/prisma'; -import { buildBatch, buildNextBatch, getInclusionProof } from '@features/battle-batcher'; +import { buildBatch, buildNextBatch, getInclusionProof } from '@features/battle/batcher'; const RULESET = `0x${'aa'.repeat(32)}`; const SCOPE = { chainId: 'eip155:84532', deploymentId: 'base-sepolia-live' }; diff --git a/backend/tests/features/battle-ledger/accept.service.test.ts b/backend/tests/features/battle/ledger/accept.service.test.ts similarity index 95% rename from backend/tests/features/battle-ledger/accept.service.test.ts rename to backend/tests/features/battle/ledger/accept.service.test.ts index 5cc6d6d7..d0487446 100644 --- a/backend/tests/features/battle-ledger/accept.service.test.ts +++ b/backend/tests/features/battle/ledger/accept.service.test.ts @@ -14,21 +14,21 @@ vi.mock('@config/prisma', () => ({ }, })); -vi.mock('../../../src/features/battle-ledger/snapshot.builder', () => ({ +vi.mock('../../../../src/features/battle/ledger/snapshot.builder', () => ({ buildPetSnapshot: vi.fn(), })); -vi.mock('../../../src/features/battle-ledger/consent.service', () => ({ +vi.mock('../../../../src/features/battle/ledger/consent.service', () => ({ findCoveringAuthorization: vi.fn(), consumeDailyBudget: vi.fn(), })); -vi.mock('../../../src/features/battle-randomness', () => ({ +vi.mock('../../../../src/features/battle/randomness', () => ({ chooseCommitmentRound: vi.fn(), roundPublishTime: vi.fn((round: number) => new Date(roundTime(QUICKNET, round) * 1000)), })); -vi.mock('../../../src/features/battle-signer', () => ({ +vi.mock('../../../../src/features/battle/signer', () => ({ activeSigningKey: vi.fn(), sign: vi.fn(), SignerRefusedError: class SignerRefusedError extends Error { @@ -41,18 +41,18 @@ vi.mock('../../../src/features/battle-signer', () => ({ }, })); -vi.mock('../../../src/features/battle-ledger/transitions', () => ({ +vi.mock('../../../../src/features/battle/ledger/transitions', () => ({ openBattle: vi.fn(), applyTransition: vi.fn(), })); import { prisma } from '@config/prisma'; -import { acceptBattle } from '@features/battle-ledger'; -import { chooseCommitmentRound, roundPublishTime } from '@features/battle-randomness'; -import { activeSigningKey, sign, SignerRefusedError } from '@features/battle-signer'; -import { consumeDailyBudget, findCoveringAuthorization } from '../../../src/features/battle-ledger/consent.service'; -import { buildPetSnapshot } from '../../../src/features/battle-ledger/snapshot.builder'; -import { applyTransition, openBattle } from '../../../src/features/battle-ledger/transitions'; +import { acceptBattle } from '@features/battle/ledger'; +import { chooseCommitmentRound, roundPublishTime } from '@features/battle/randomness'; +import { activeSigningKey, sign, SignerRefusedError } from '@features/battle/signer'; +import { consumeDailyBudget, findCoveringAuthorization } from '../../../../src/features/battle/ledger/consent.service'; +import { buildPetSnapshot } from '../../../../src/features/battle/ledger/snapshot.builder'; +import { applyTransition, openBattle } from '../../../../src/features/battle/ledger/transitions'; const ROUND_1000_TIME = roundTime(QUICKNET, 1000); const NOW = ROUND_1000_TIME + 1; diff --git a/backend/tests/features/battle-ledger/config.service.test.ts b/backend/tests/features/battle/ledger/config.service.test.ts similarity index 96% rename from backend/tests/features/battle-ledger/config.service.test.ts rename to backend/tests/features/battle/ledger/config.service.test.ts index ebe42a2e..eb421886 100644 --- a/backend/tests/features/battle-ledger/config.service.test.ts +++ b/backend/tests/features/battle/ledger/config.service.test.ts @@ -17,9 +17,9 @@ vi.mock('@config/prisma', () => ({ battleRuleset: { findMany: vi.fn(), findUnique: vi.fn() }, }, })); -vi.mock('@features/battle-signer', () => ({ listSigningKeys: vi.fn() })); +vi.mock('@features/battle/signer', () => ({ listSigningKeys: vi.fn() })); -import { getBattleConfig } from '@features/battle-ledger'; +import { getBattleConfig } from '@features/battle/ledger'; beforeEach(() => { battleEnv.enabled = true; diff --git a/backend/tests/features/battle-ledger/consent.service.test.ts b/backend/tests/features/battle/ledger/consent.service.test.ts similarity index 99% rename from backend/tests/features/battle-ledger/consent.service.test.ts rename to backend/tests/features/battle/ledger/consent.service.test.ts index 3c5ce136..93c02c20 100644 --- a/backend/tests/features/battle-ledger/consent.service.test.ts +++ b/backend/tests/features/battle/ledger/consent.service.test.ts @@ -25,7 +25,7 @@ import { revokeDefenseAuthorizations, submitDefenseAuthorization, toProtocolAuthorization, -} from '@features/battle-ledger'; +} from '@features/battle/ledger'; const wallet = new ethers.Wallet('0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'); const DEFENDER = wallet.address.toLowerCase(); diff --git a/backend/tests/features/battle-ledger/corpus.controller.test.ts b/backend/tests/features/battle/ledger/corpus.controller.test.ts similarity index 93% rename from backend/tests/features/battle-ledger/corpus.controller.test.ts rename to backend/tests/features/battle/ledger/corpus.controller.test.ts index 0d96b039..c3d91f22 100644 --- a/backend/tests/features/battle-ledger/corpus.controller.test.ts +++ b/backend/tests/features/battle/ledger/corpus.controller.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@features/battle-ledger/corpus.service', () => ({ +vi.mock('@features/battle/ledger/corpus.service', () => ({ listReceiptsByPet: vi.fn(), listReceiptsByWallet: vi.fn(), listReceiptsBySequence: vi.fn(), @@ -10,12 +10,12 @@ import { listReceiptsByPet, listReceiptsBySequence, listReceiptsByWallet, -} from '../../../src/features/battle-ledger/corpus.service'; +} from '../../../../src/features/battle/ledger/corpus.service'; import { getReceiptsByPet, getReceiptsBySequence, getReceiptsByWallet, -} from '../../../src/features/battle-ledger/corpus.controller'; +} from '../../../../src/features/battle/ledger/corpus.controller'; function mockRes() { const res = { status: vi.fn(), json: vi.fn() }; diff --git a/backend/tests/features/battle-ledger/corpus.service.test.ts b/backend/tests/features/battle/ledger/corpus.service.test.ts similarity index 99% rename from backend/tests/features/battle-ledger/corpus.service.test.ts rename to backend/tests/features/battle/ledger/corpus.service.test.ts index 09f45752..9b62d729 100644 --- a/backend/tests/features/battle-ledger/corpus.service.test.ts +++ b/backend/tests/features/battle/ledger/corpus.service.test.ts @@ -5,7 +5,7 @@ vi.mock('@config/prisma', () => ({ })); import { prisma } from '@config/prisma'; -import { listReceiptsByPet, listReceiptsBySequence, listReceiptsByWallet } from '@features/battle-ledger'; +import { listReceiptsByPet, listReceiptsBySequence, listReceiptsByWallet } from '@features/battle/ledger'; function row(overrides: Partial> = {}) { return { diff --git a/backend/tests/features/battle-ledger/drills.test.ts b/backend/tests/features/battle/ledger/drills.test.ts similarity index 98% rename from backend/tests/features/battle-ledger/drills.test.ts rename to backend/tests/features/battle/ledger/drills.test.ts index b9bfbfd9..ad9bcf83 100644 --- a/backend/tests/features/battle-ledger/drills.test.ts +++ b/backend/tests/features/battle/ledger/drills.test.ts @@ -25,9 +25,9 @@ vi.mock('@config/prisma', () => ({ import { env } from '@config/env'; import { prisma } from '@config/prisma'; -import { listDeadLetters, requeueDeadLetter } from '@features/battle-ledger'; -import { backendBattleModeEnabled } from '@features/battle-ledger'; -import { listSigningKeys, registerRotatedKey, resetSigner } from '@features/battle-signer'; +import { listDeadLetters, requeueDeadLetter } from '@features/battle/ledger'; +import { backendBattleModeEnabled } from '@features/battle/ledger'; +import { listSigningKeys, registerRotatedKey, resetSigner } from '@features/battle/signer'; const NOW = new Date('2026-07-26T12:00:00.000Z'); diff --git a/backend/tests/features/battle-ledger/intent.service.test.ts b/backend/tests/features/battle/ledger/intent.service.test.ts similarity index 99% rename from backend/tests/features/battle-ledger/intent.service.test.ts rename to backend/tests/features/battle/ledger/intent.service.test.ts index 20484eea..1cc132e1 100644 --- a/backend/tests/features/battle-ledger/intent.service.test.ts +++ b/backend/tests/features/battle/ledger/intent.service.test.ts @@ -19,7 +19,7 @@ vi.mock('@repositories/roster.repository', () => ({ })); import { prisma } from '@config/prisma'; -import { submitBattleIntent, toProtocolIntent, verifyIntentSignature } from '@features/battle-ledger'; +import { submitBattleIntent, toProtocolIntent, verifyIntentSignature } from '@features/battle/ledger'; import { getPetById } from '@repositories/roster.repository'; /** diff --git a/backend/tests/features/battle-ledger/mode.test.ts b/backend/tests/features/battle/ledger/mode.test.ts similarity index 98% rename from backend/tests/features/battle-ledger/mode.test.ts rename to backend/tests/features/battle/ledger/mode.test.ts index 2ed55b9a..86224afc 100644 --- a/backend/tests/features/battle-ledger/mode.test.ts +++ b/backend/tests/features/battle/ledger/mode.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; vi.mock('@config/env', () => ({ env: { battle: { enabled: false } } })); import { env } from '@config/env'; -import { backendBattleModeEnabled, requireBackendBattleMode } from '@features/battle-ledger'; +import { backendBattleModeEnabled, requireBackendBattleMode } from '@features/battle/ledger'; function res() { const json = vi.fn(); diff --git a/backend/tests/features/battle-ledger/outbox.reschedule.test.ts b/backend/tests/features/battle/ledger/outbox.reschedule.test.ts similarity index 94% rename from backend/tests/features/battle-ledger/outbox.reschedule.test.ts rename to backend/tests/features/battle/ledger/outbox.reschedule.test.ts index b5fbb6e8..d4918540 100644 --- a/backend/tests/features/battle-ledger/outbox.reschedule.test.ts +++ b/backend/tests/features/battle/ledger/outbox.reschedule.test.ts @@ -5,7 +5,7 @@ vi.mock('@config/prisma', () => ({ })); import { prisma } from '@config/prisma'; -import { rescheduleOutbox } from '@features/battle-ledger'; +import { rescheduleOutbox } from '@features/battle/ledger'; beforeEach(() => { vi.clearAllMocks(); diff --git a/backend/tests/features/battle-ledger/outbox.test.ts b/backend/tests/features/battle/ledger/outbox.test.ts similarity index 99% rename from backend/tests/features/battle-ledger/outbox.test.ts rename to backend/tests/features/battle/ledger/outbox.test.ts index fb2b2a5d..a77ec75c 100644 --- a/backend/tests/features/battle-ledger/outbox.test.ts +++ b/backend/tests/features/battle/ledger/outbox.test.ts @@ -22,7 +22,7 @@ import { MAX_OUTBOX_ATTEMPTS, OUTBOX_TOPICS, retryDelaySeconds, -} from '@features/battle-ledger'; +} from '@features/battle/ledger'; const NOW = new Date('2026-07-26T09:00:00.000Z'); diff --git a/backend/tests/features/battle-ledger/reads.controller.test.ts b/backend/tests/features/battle/ledger/reads.controller.test.ts similarity index 96% rename from backend/tests/features/battle-ledger/reads.controller.test.ts rename to backend/tests/features/battle/ledger/reads.controller.test.ts index caf7616d..bbb59f12 100644 --- a/backend/tests/features/battle-ledger/reads.controller.test.ts +++ b/backend/tests/features/battle/ledger/reads.controller.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@features/battle-ledger/reads.service', () => ({ +vi.mock('@features/battle/ledger/reads.service', () => ({ getBattleStateSummary: vi.fn(), getSignedCommitment: vi.fn(), getSignedReceipt: vi.fn(), @@ -20,7 +20,7 @@ import { listActiveSigningKeys, listRulesets, verifyReceiptSignature, -} from '../../../src/features/battle-ledger/reads.service'; +} from '../../../../src/features/battle/ledger/reads.service'; import { getBattleCombatLog, getBattleCommitment, @@ -30,7 +30,7 @@ import { getRulesets, getSigningKeys, postVerifyReceipt, -} from '../../../src/features/battle-ledger/reads.controller'; +} from '../../../../src/features/battle/ledger/reads.controller'; function mockRes() { const res = { status: vi.fn(), json: vi.fn() }; diff --git a/backend/tests/features/battle-ledger/reads.service.test.ts b/backend/tests/features/battle/ledger/reads.service.test.ts similarity index 98% rename from backend/tests/features/battle-ledger/reads.service.test.ts rename to backend/tests/features/battle/ledger/reads.service.test.ts index b849231e..49ddd235 100644 --- a/backend/tests/features/battle-ledger/reads.service.test.ts +++ b/backend/tests/features/battle/ledger/reads.service.test.ts @@ -11,7 +11,7 @@ vi.mock('@config/prisma', () => ({ }, })); -vi.mock('@features/battle-signer', () => ({ +vi.mock('@features/battle/signer', () => ({ listSigningKeys: vi.fn(), })); @@ -25,8 +25,8 @@ import { listActiveSigningKeys, listRulesets, verifyReceiptSignature, -} from '@features/battle-ledger'; -import { listSigningKeys } from '@features/battle-signer'; +} from '@features/battle/ledger'; +import { listSigningKeys } from '@features/battle/signer'; beforeEach(() => { vi.clearAllMocks(); diff --git a/backend/tests/features/battle-ledger/snapshot.builder.test.ts b/backend/tests/features/battle/ledger/snapshot.builder.test.ts similarity index 99% rename from backend/tests/features/battle-ledger/snapshot.builder.test.ts rename to backend/tests/features/battle/ledger/snapshot.builder.test.ts index cc156496..bbfd3476 100644 --- a/backend/tests/features/battle-ledger/snapshot.builder.test.ts +++ b/backend/tests/features/battle/ledger/snapshot.builder.test.ts @@ -12,7 +12,7 @@ vi.mock('@config/prisma', () => ({ })); import { prisma } from '@config/prisma'; -import { buildPetSnapshot } from '@features/battle-ledger'; +import { buildPetSnapshot } from '@features/battle/ledger'; const ROSTER_ROW = { chain: 'evm', diff --git a/backend/tests/features/battle-ledger/state.test.ts b/backend/tests/features/battle/ledger/state.test.ts similarity index 99% rename from backend/tests/features/battle-ledger/state.test.ts rename to backend/tests/features/battle/ledger/state.test.ts index 666c8b71..5590f6c0 100644 --- a/backend/tests/features/battle-ledger/state.test.ts +++ b/backend/tests/features/battle/ledger/state.test.ts @@ -10,7 +10,7 @@ import { isTerminal, shouldReleaseLocks, TERMINAL_STATES, -} from '@features/battle-ledger'; +} from '@features/battle/ledger'; describe('happy path', () => { it('is walkable end to end', () => { diff --git a/backend/tests/features/battle-ledger/transitions.test.ts b/backend/tests/features/battle/ledger/transitions.test.ts similarity index 99% rename from backend/tests/features/battle-ledger/transitions.test.ts rename to backend/tests/features/battle/ledger/transitions.test.ts index 23867c3b..6f10a349 100644 --- a/backend/tests/features/battle-ledger/transitions.test.ts +++ b/backend/tests/features/battle/ledger/transitions.test.ts @@ -30,7 +30,7 @@ import { openBattle, OUTBOX_TOPICS, sortPetIds, -} from '@features/battle-ledger'; +} from '@features/battle/ledger'; beforeEach(() => { vi.clearAllMocks(); diff --git a/backend/tests/features/battle-randomness/drand.client.test.ts b/backend/tests/features/battle/randomness/drand.client.test.ts similarity index 98% rename from backend/tests/features/battle-randomness/drand.client.test.ts rename to backend/tests/features/battle/randomness/drand.client.test.ts index fd00e286..b7bb0645 100644 --- a/backend/tests/features/battle-randomness/drand.client.test.ts +++ b/backend/tests/features/battle/randomness/drand.client.test.ts @@ -25,7 +25,7 @@ import { resetDrandTransport, roundPublishTime, setDrandTransport, -} from '@features/battle-randomness'; +} from '@features/battle/randomness'; /** * Real quicknet beacons, from the same fixtures the protocol tests use. The whole point of @@ -37,7 +37,7 @@ interface Fixture { } const here = dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, '$1')); const fixture = JSON.parse( - readFileSync(join(here, '../../../../protocol/tests/fixtures/drand.json'), 'utf8'), + readFileSync(join(here, '../../../../../protocol/tests/fixtures/drand.json'), 'utf8'), ) as Fixture; const ROUND_1000 = fixture.quicknet.rounds.find((r) => r.round === 1000)!; diff --git a/backend/tests/features/battle-rewards/entitlements.test.ts b/backend/tests/features/battle/rewards/entitlements.test.ts similarity index 99% rename from backend/tests/features/battle-rewards/entitlements.test.ts rename to backend/tests/features/battle/rewards/entitlements.test.ts index 46a600d1..bfdb38dc 100644 --- a/backend/tests/features/battle-rewards/entitlements.test.ts +++ b/backend/tests/features/battle/rewards/entitlements.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { computeEntitlements, totalEntitled, type BattleContribution, type RewardRates } from '@features/battle-rewards'; +import { computeEntitlements, totalEntitled, type BattleContribution, type RewardRates } from '@features/battle/rewards'; const ALICE = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; const BOB = '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; diff --git a/backend/tests/features/battle-rewards/season.open.test.ts b/backend/tests/features/battle/rewards/season.open.test.ts similarity index 99% rename from backend/tests/features/battle-rewards/season.open.test.ts rename to backend/tests/features/battle/rewards/season.open.test.ts index bf82873a..05710f23 100644 --- a/backend/tests/features/battle-rewards/season.open.test.ts +++ b/backend/tests/features/battle/rewards/season.open.test.ts @@ -5,7 +5,7 @@ vi.mock('@config/prisma', () => ({ })); import { prisma } from '@config/prisma'; -import { boundsViolations, openSeasonOnChain, type OpenSeasonContext } from '@features/battle-rewards'; +import { boundsViolations, openSeasonOnChain, type OpenSeasonContext } from '@features/battle/rewards'; const ALICE = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; const BOB = '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; diff --git a/backend/tests/features/battle-rewards/season.service.test.ts b/backend/tests/features/battle/rewards/season.service.test.ts similarity index 99% rename from backend/tests/features/battle-rewards/season.service.test.ts rename to backend/tests/features/battle/rewards/season.service.test.ts index 8dbad228..6001cc36 100644 --- a/backend/tests/features/battle-rewards/season.service.test.ts +++ b/backend/tests/features/battle/rewards/season.service.test.ts @@ -18,7 +18,7 @@ vi.mock('@config/prisma', () => { }); import { prisma } from '@config/prisma'; -import { buildSeason, getClaimProof, type SeasonInputs } from '@features/battle-rewards'; +import { buildSeason, getClaimProof, type SeasonInputs } from '@features/battle/rewards'; const ALICE = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; const BOB = '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; diff --git a/backend/tests/features/battle-room/battle-room.controller.test.ts b/backend/tests/features/battle/room/battle-room.controller.test.ts similarity index 87% rename from backend/tests/features/battle-room/battle-room.controller.test.ts rename to backend/tests/features/battle/room/battle-room.controller.test.ts index e3700d0e..18ee7987 100644 --- a/backend/tests/features/battle-room/battle-room.controller.test.ts +++ b/backend/tests/features/battle/room/battle-room.controller.test.ts @@ -1,12 +1,12 @@ import { describe, expect, it, vi, beforeEach } from 'vitest'; import type { Request, Response } from 'express'; -vi.mock('../../../src/features/battle-room/battle-room.service', () => ({ +vi.mock('../../../../src/features/battle/room/battle-room.service', () => ({ mintRoom: vi.fn(), })); -import { createBattleRoom } from '../../../src/features/battle-room/battle-room.controller'; -import { mintRoom } from '../../../src/features/battle-room/battle-room.service'; +import { createBattleRoom } from '../../../../src/features/battle/room/battle-room.controller'; +import { mintRoom } from '../../../../src/features/battle/room/battle-room.service'; function makeRes() { const res = { diff --git a/backend/tests/features/battle-signer/signer.persistence.test.ts b/backend/tests/features/battle/signer/signer.persistence.test.ts similarity index 99% rename from backend/tests/features/battle-signer/signer.persistence.test.ts rename to backend/tests/features/battle/signer/signer.persistence.test.ts index 36b18f99..908451a8 100644 --- a/backend/tests/features/battle-signer/signer.persistence.test.ts +++ b/backend/tests/features/battle/signer/signer.persistence.test.ts @@ -22,7 +22,7 @@ import { listSigningKeys, loadPersistedSigningKeys, resetSigner, -} from '@features/battle-signer'; +} from '@features/battle/signer'; /** When this deployment first started signing — well before any of the restarts below. */ const FIRST_BOOT = 1_700_000_000; diff --git a/backend/tests/features/battle-signer/signer.registry.test.ts b/backend/tests/features/battle/signer/signer.registry.test.ts similarity index 98% rename from backend/tests/features/battle-signer/signer.registry.test.ts rename to backend/tests/features/battle/signer/signer.registry.test.ts index d6967284..1746fac1 100644 --- a/backend/tests/features/battle-signer/signer.registry.test.ts +++ b/backend/tests/features/battle/signer/signer.registry.test.ts @@ -5,8 +5,8 @@ vi.mock('@config/prisma', () => ({ })); import { prisma } from '@config/prisma'; -import { loadSigningKeys, persistSigningKey } from '@features/battle-signer'; -import type { SigningKeyDescriptor } from '@features/battle-signer'; +import { loadSigningKeys, persistSigningKey } from '@features/battle/signer'; +import type { SigningKeyDescriptor } from '@features/battle/signer'; function key(overrides: Partial = {}): SigningKeyDescriptor { return { diff --git a/backend/tests/features/battle-signer/signer.service.test.ts b/backend/tests/features/battle/signer/signer.service.test.ts similarity index 99% rename from backend/tests/features/battle-signer/signer.service.test.ts rename to backend/tests/features/battle/signer/signer.service.test.ts index e2b0ac87..68d4c6a4 100644 --- a/backend/tests/features/battle-signer/signer.service.test.ts +++ b/backend/tests/features/battle/signer/signer.service.test.ts @@ -46,7 +46,7 @@ import { sign, signerAuditLog, SignerRefusedError, -} from '@features/battle-signer'; +} from '@features/battle/signer'; const NOW = roundTime(QUICKNET, 1000) + 1; const DOMAIN = { chainId: 'eip155:84532' as const, deploymentId: 'base-sepolia-live' }; diff --git a/backend/tests/features/battle-worker/beacon.worker.test.ts b/backend/tests/features/battle/worker/beacon.worker.test.ts similarity index 96% rename from backend/tests/features/battle-worker/beacon.worker.test.ts rename to backend/tests/features/battle/worker/beacon.worker.test.ts index 88051416..765289b3 100644 --- a/backend/tests/features/battle-worker/beacon.worker.test.ts +++ b/backend/tests/features/battle/worker/beacon.worker.test.ts @@ -10,14 +10,14 @@ vi.mock('@config/prisma', () => ({ prisma: { battleLedger: { findUnique: vi.fn() } }, })); -vi.mock('@features/battle-ledger', () => ({ +vi.mock('@features/battle/ledger', () => ({ applyTransition: vi.fn(), completeOutbox: vi.fn(), rescheduleOutbox: vi.fn(), OUTBOX_TOPICS: { compute: 'compute' }, })); -vi.mock('@features/battle-randomness', () => ({ +vi.mock('@features/battle/randomness', () => ({ fetchVerifiedRound: vi.fn(), roundPublishTime: vi.fn((round: number) => new Date(roundTime(QUICKNET, round) * 1000)), })); @@ -27,9 +27,9 @@ vi.mock('@ws/battleRoomSocket', () => ({ })); import { prisma } from '@config/prisma'; -import { applyTransition, completeOutbox, rescheduleOutbox } from '@features/battle-ledger'; -import { fetchVerifiedRound } from '@features/battle-randomness'; -import { processAwaitBeaconMessage } from '@features/battle-worker'; +import { applyTransition, completeOutbox, rescheduleOutbox } from '@features/battle/ledger'; +import { fetchVerifiedRound } from '@features/battle/randomness'; +import { processAwaitBeaconMessage } from '@features/battle/worker'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; const ROUND = 1000; diff --git a/backend/tests/features/battle-worker/compute.worker.test.ts b/backend/tests/features/battle/worker/compute.worker.test.ts similarity index 98% rename from backend/tests/features/battle-worker/compute.worker.test.ts rename to backend/tests/features/battle/worker/compute.worker.test.ts index 4c6a2324..87e22d56 100644 --- a/backend/tests/features/battle-worker/compute.worker.test.ts +++ b/backend/tests/features/battle/worker/compute.worker.test.ts @@ -9,7 +9,7 @@ vi.mock('@config/prisma', () => ({ }, })); -vi.mock('@features/battle-ledger', () => ({ +vi.mock('@features/battle/ledger', () => ({ applyTransition: vi.fn(), completeOutbox: vi.fn(), OUTBOX_TOPICS: { verify: 'verify' }, @@ -20,8 +20,8 @@ vi.mock('@ws/battleRoomSocket', () => ({ })); import { prisma } from '@config/prisma'; -import { applyTransition, completeOutbox } from '@features/battle-ledger'; -import { processComputeMessage } from '@features/battle-worker'; +import { applyTransition, completeOutbox } from '@features/battle/ledger'; +import { processComputeMessage } from '@features/battle/worker'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; const RULESET_HASH = hashRuleset(SOURCE_DEFAULT_RULESET); diff --git a/backend/tests/features/battle-worker/publish.worker.test.ts b/backend/tests/features/battle/worker/publish.worker.test.ts similarity index 98% rename from backend/tests/features/battle-worker/publish.worker.test.ts rename to backend/tests/features/battle/worker/publish.worker.test.ts index c7bfd7be..bb12db53 100644 --- a/backend/tests/features/battle-worker/publish.worker.test.ts +++ b/backend/tests/features/battle/worker/publish.worker.test.ts @@ -19,7 +19,7 @@ import { vi.mock('@config/prisma', () => ({ prisma: { battleLedger: { findUnique: vi.fn() }, battleReceipt: { findUnique: vi.fn() } }, })); -vi.mock('@features/battle-ledger', () => ({ +vi.mock('@features/battle/ledger', () => ({ applyTransition: vi.fn(), completeOutbox: vi.fn(), claimOutbox: vi.fn(), @@ -38,8 +38,8 @@ vi.mock('@features/battle-ledger', () => ({ vi.mock('@ws/battleRoomSocket', () => ({ notifyBattleRoomIfPresent: vi.fn() })); import { prisma } from '@config/prisma'; -import { applyTransition, completeOutbox } from '@features/battle-ledger'; -import { processPublishMessage } from '@features/battle-worker'; +import { applyTransition, completeOutbox } from '@features/battle/ledger'; +import { processPublishMessage } from '@features/battle/worker'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; const BEACON = { diff --git a/backend/tests/features/battle-worker/runner.test.ts b/backend/tests/features/battle/worker/runner.test.ts similarity index 86% rename from backend/tests/features/battle-worker/runner.test.ts rename to backend/tests/features/battle/worker/runner.test.ts index 379e0e70..eb6a3fd2 100644 --- a/backend/tests/features/battle-worker/runner.test.ts +++ b/backend/tests/features/battle/worker/runner.test.ts @@ -4,7 +4,7 @@ vi.mock('@config/env', () => ({ env: { battle: { workerBatchSize: 10, workerPollIntervalMs: 2000 } }, })); -vi.mock('@features/battle-ledger', () => ({ +vi.mock('@features/battle/ledger', () => ({ claimOutbox: vi.fn(), failOutbox: vi.fn(), // Must list every real topic. A missing one is not a smaller map — it registers as an @@ -19,26 +19,26 @@ vi.mock('@features/battle-ledger', () => ({ }, })); -vi.mock('@features/battle-worker/beacon.worker', () => ({ +vi.mock('@features/battle/worker/beacon.worker', () => ({ processAwaitBeaconMessage: vi.fn(), })); -vi.mock('@features/battle-worker/compute.worker', () => ({ +vi.mock('@features/battle/worker/compute.worker', () => ({ processComputeMessage: vi.fn(), })); -vi.mock('@features/battle-worker/verify.worker', () => ({ +vi.mock('@features/battle/worker/verify.worker', () => ({ processVerifyMessage: vi.fn(), })); -vi.mock('@features/battle-worker/sign.worker', () => ({ +vi.mock('@features/battle/worker/sign.worker', () => ({ processSignMessage: vi.fn(), })); -vi.mock('@features/battle-worker/publish.worker', () => ({ +vi.mock('@features/battle/worker/publish.worker', () => ({ processPublishMessage: vi.fn(), })); -import { claimOutbox, failOutbox } from '@features/battle-ledger'; -import { processAwaitBeaconMessage } from '@features/battle-worker/beacon.worker'; -import { processComputeMessage } from '@features/battle-worker/compute.worker'; -import { runBattleWorkerOnce } from '@features/battle-worker/runner'; +import { claimOutbox, failOutbox } from '@features/battle/ledger'; +import { processAwaitBeaconMessage } from '@features/battle/worker/beacon.worker'; +import { processComputeMessage } from '@features/battle/worker/compute.worker'; +import { runBattleWorkerOnce } from '@features/battle/worker/runner'; const NOW = new Date('2026-07-26T12:00:00.000Z'); diff --git a/backend/tests/features/battle-worker/sign.worker.test.ts b/backend/tests/features/battle/worker/sign.worker.test.ts similarity index 98% rename from backend/tests/features/battle-worker/sign.worker.test.ts rename to backend/tests/features/battle/worker/sign.worker.test.ts index 768d8ea0..0f075f72 100644 --- a/backend/tests/features/battle-worker/sign.worker.test.ts +++ b/backend/tests/features/battle/worker/sign.worker.test.ts @@ -26,14 +26,14 @@ vi.mock('@config/prisma', () => ({ }, })); -vi.mock('@features/battle-ledger', () => ({ +vi.mock('@features/battle/ledger', () => ({ applyTransition: vi.fn(), completeOutbox: vi.fn(), OUTBOX_TOPICS: { publish: 'publish' }, })); -vi.mock('@features/battle-signer', async () => { - const actual = await vi.importActual('@features/battle-signer'); +vi.mock('@features/battle/signer', async () => { + const actual = await vi.importActual('@features/battle/signer'); return { activeSigningKey: vi.fn(), sign: vi.fn(), @@ -46,9 +46,9 @@ vi.mock('@ws/battleRoomSocket', () => ({ })); import { prisma } from '@config/prisma'; -import { applyTransition, completeOutbox } from '@features/battle-ledger'; -import { activeSigningKey, sign, SignerRefusedError } from '@features/battle-signer'; -import { processSignMessage } from '@features/battle-worker'; +import { applyTransition, completeOutbox } from '@features/battle/ledger'; +import { activeSigningKey, sign, SignerRefusedError } from '@features/battle/signer'; +import { processSignMessage } from '@features/battle/worker'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; const RULESET_HASH = hashRuleset(SOURCE_DEFAULT_RULESET); diff --git a/backend/tests/features/battle-worker/verify.worker.test.ts b/backend/tests/features/battle/worker/verify.worker.test.ts similarity index 98% rename from backend/tests/features/battle-worker/verify.worker.test.ts rename to backend/tests/features/battle/worker/verify.worker.test.ts index 0dee9dad..2877c1ff 100644 --- a/backend/tests/features/battle-worker/verify.worker.test.ts +++ b/backend/tests/features/battle/worker/verify.worker.test.ts @@ -19,7 +19,7 @@ vi.mock('@config/prisma', () => ({ }, })); -vi.mock('@features/battle-ledger', () => ({ +vi.mock('@features/battle/ledger', () => ({ applyTransition: vi.fn(), completeOutbox: vi.fn(), OUTBOX_TOPICS: { sign: 'sign' }, @@ -34,8 +34,8 @@ vi.mock('@ws/battleRoomSocket', () => ({ })); import { prisma } from '@config/prisma'; -import { applyTransition, completeOutbox } from '@features/battle-ledger'; -import { processVerifyMessage } from '@features/battle-worker'; +import { applyTransition, completeOutbox } from '@features/battle/ledger'; +import { processVerifyMessage } from '@features/battle/worker'; import { callVerifyBattle } from '@grpc-client/verifyBattle'; import { notifyBattleRoomIfPresent } from '@ws/battleRoomSocket'; diff --git a/bash.exe.stackdump b/bash.exe.stackdump new file mode 100644 index 00000000..e15c61ae --- /dev/null +++ b/bash.exe.stackdump @@ -0,0 +1,9 @@ +Stack trace: +Frame Function Args +000FFFFA3C0 00210062B0E (00210297158, 00210275E3E, 000FFFFA3C0, 000FFFF92C0) +000FFFFA3C0 0021004846A (00000000000, 00000000000, 00000000000, 00000000004) +000FFFFA3C0 002100484A2 (00210297209, 000FFFFA278, 000FFFFA3C0, 00000000000) +000FFFFA3C0 002100D2FFE (00000000000, 00000000000, 00000000000, 00000000000) +000FFFFA3C0 002100D3125 (000FFFFA3D0, 00000000000, 00000000000, 00000000000) +001004F84B7 002100D46E5 (000FFFFA3D0, 00000000000, 00000000000, 00000000000) +End of stack trace diff --git a/docs/battle-protocol.md b/docs/battle-protocol.md index 7afbce09..6ffbbd13 100644 --- a/docs/battle-protocol.md +++ b/docs/battle-protocol.md @@ -1170,7 +1170,7 @@ short of that. ## The drills are tests, not a checklist -Each drill below is executed by `backend/tests/features/battle-ledger/drills.test.ts`, so it +Each drill below is executed by `backend/tests/features/battle/ledger/drills.test.ts`, so it runs on every CI pass rather than being performed once and slowly becoming untrue. A drill that only ever lived in this file would describe a system nobody had checked in months. diff --git a/services/indexer-go/README.md b/services/indexer-go/README.md index 05acfb04..c2f1ea26 100644 --- a/services/indexer-go/README.md +++ b/services/indexer-go/README.md @@ -184,7 +184,7 @@ the whole delta, not just the XP formula `xp.go` already covered). This is release safety, not a trust boundary — see `docs/battle-protocol.md` §F's "what the Go verifier is for" before reusing it as anything stronger. The backend -(`backend/src/features/battle-worker/verify.worker.ts`) calls it, converts the +(`backend/src/features/battle/worker/verify.worker.ts`) calls it, converts the structured log back into `@cryptopets/protocol`'s `SimOutcome` shape, and hashes it with the *real* canonical encoder — Go never reimplements that encoding itself, so the only question this check answers is whether the two engines From 2858c291cdf2b976ddbbfaadb7247d9b40f991bb Mon Sep 17 00:00:00 2001 From: heyradcode Date: Fri, 7 Aug 2026 14:49:20 -0400 Subject: [PATCH 61/61] fix(battle): end a battle whose pipeline dead-letters, freeing its pets --- backend/src/features/battle/ledger/index.ts | 2 + backend/src/features/battle/ledger/state.ts | 21 +++++-- .../src/features/battle/ledger/transitions.ts | 53 ++++++++++++++++- backend/src/features/battle/worker/runner.ts | 35 +++++++++++- .../features/battle/ledger/state.test.ts | 15 +++-- .../battle/ledger/transitions.test.ts | 57 +++++++++++++++++++ .../features/battle/worker/runner.test.ts | 52 ++++++++++++++++- 7 files changed, 221 insertions(+), 14 deletions(-) diff --git a/backend/src/features/battle/ledger/index.ts b/backend/src/features/battle/ledger/index.ts index c8b28c97..5dc27798 100644 --- a/backend/src/features/battle/ledger/index.ts +++ b/backend/src/features/battle/ledger/index.ts @@ -92,6 +92,7 @@ export { export { ALLOWED_TRANSITIONS, BATTLE_HAPPY_PATH, + canForfeitFrom, classifyTransition, IllegalTransitionError, isCommitted, @@ -101,6 +102,7 @@ export { type TransitionKind, } from './state'; export { + abandonBattle, applyTransition, type BattleLedgerPatch, failBattle, diff --git a/backend/src/features/battle/ledger/state.ts b/backend/src/features/battle/ledger/state.ts index 14e16d37..238febf7 100644 --- a/backend/src/features/battle/ledger/state.ts +++ b/backend/src/features/battle/ledger/state.ts @@ -40,19 +40,27 @@ export const TERMINAL_STATES: readonly BattleState[] = [ /** * Legal moves out of each state. * - * `forfeited` is reachable from `committed` and `seeded` because a permanent beacon + * `forfeited` is reachable from `committed`, `seeded` and `computed` because a permanent * outage has to end the battle somehow, and ending it with no progression change plus a - * cooldown is the option that does not reward manufacturing an outage (§E). + * cooldown is the option that does not reward manufacturing an outage (§E). From + * `computed` it covers the verifier being unreachable until the outbox gives up — which + * is an outage like any other, and must not be confused with the next paragraph. * * `verification_failed` is reachable only from `computed`: it means the TypeScript * engine and the Go verifier disagreed, which stops signing for that ruleset rather - * than silently preferring one implementation (§F). + * than silently preferring one implementation (§F). A verifier that never answered has + * disagreed with nothing, so it forfeits instead; marking it failed would trip a + * ruleset-wide circuit breaker over a service being down. */ export const ALLOWED_TRANSITIONS: Readonly> = { [BattleState.accepted]: [BattleState.committed, BattleState.rejected, BattleState.expired], [BattleState.committed]: [BattleState.seeded, BattleState.forfeited], [BattleState.seeded]: [BattleState.computed, BattleState.forfeited], - [BattleState.computed]: [BattleState.verified, BattleState.verification_failed], + [BattleState.computed]: [ + BattleState.verified, + BattleState.verification_failed, + BattleState.forfeited, + ], [BattleState.verified]: [BattleState.signed, BattleState.signing_failed], [BattleState.signed]: [BattleState.published], [BattleState.published]: [BattleState.batched], @@ -82,6 +90,11 @@ export function classifyTransition(from: BattleState, to: BattleState): Transiti return ALLOWED_TRANSITIONS[from].includes(to) ? 'advance' : 'illegal'; } +/** Whether `forfeited` is a legal move from here; see `abandonBattle`. */ +export function canForfeitFrom(state: BattleState): boolean { + return (ALLOWED_TRANSITIONS[state] ?? []).includes(BattleState.forfeited); +} + /** Whether a battle has reached a state it never leaves. */ export function isTerminal(state: BattleState): boolean { return TERMINAL_STATES.includes(state); diff --git a/backend/src/features/battle/ledger/transitions.ts b/backend/src/features/battle/ledger/transitions.ts index 53b46589..8780620b 100644 --- a/backend/src/features/battle/ledger/transitions.ts +++ b/backend/src/features/battle/ledger/transitions.ts @@ -1,10 +1,15 @@ -import type { BattleState } from '@generated/prisma/enums'; +import { BattleState } from '@generated/prisma/enums'; import type { Prisma } from '@generated/prisma/client'; import { prisma } from '@config/prisma'; import { enqueueOutbox, type OutboxMessage } from './outbox'; -import { classifyTransition, IllegalTransitionError, shouldReleaseLocks } from './state'; +import { + canForfeitFrom, + classifyTransition, + IllegalTransitionError, + shouldReleaseLocks, +} from './state'; /** * Transactional state transitions for the battle ledger (§J). @@ -220,3 +225,47 @@ export async function failBattle( ): Promise { return applyTransition({ battleId, from, to, patch: { failureReason: reason } }); } + +/** + * Ends a battle whose pipeline can no longer make progress, freeing both pets. + * + * Called when an outbox message dead-letters. Until this existed, a battle whose step ran + * out of retries stayed in a non-terminal state forever, and because locks are released by + * reaching a terminal state, both its pets were unable to battle again — permanently, with + * nothing surfacing why. That is how one unreachable verifier took two pets out of the + * game for days. + * + * `forfeited` and deliberately not `verification_failed`: that state means the two engines + * disagreed and is a ruleset-wide circuit breaker (§F). A verifier that never answered has + * disagreed with nothing, and marking it failed would stop signing for every battle on + * that ruleset because one service was down. + * + * States with no legal move to `forfeited` — `verified` awaiting a signature, say — are + * left exactly as they are. Freeing the pets is not worth inventing a transition the state + * machine does not allow, and the dead letter is still listed for a human either way. + */ +export async function abandonBattle( + battleId: string, + reason: string, +): Promise<{ abandoned: boolean; state: BattleState | null }> { + const current = await prisma.battleLedger.findUnique({ + where: { battleId }, + select: { state: true }, + }); + if (!current) { + return { abandoned: false, state: null }; + } + + const from = current.state as BattleState; + if (!canForfeitFrom(from)) { + return { abandoned: false, state: from }; + } + + const result = await applyTransition({ + battleId, + from, + to: BattleState.forfeited, + patch: { failureReason: reason }, + }); + return { abandoned: result.applied, state: result.state }; +} diff --git a/backend/src/features/battle/worker/runner.ts b/backend/src/features/battle/worker/runner.ts index ac86833c..c0609031 100644 --- a/backend/src/features/battle/worker/runner.ts +++ b/backend/src/features/battle/worker/runner.ts @@ -1,5 +1,11 @@ import { env } from '@config/env'; -import { type ClaimedMessage, claimOutbox, failOutbox, OUTBOX_TOPICS } from '@features/battle/ledger'; +import { + abandonBattle, + type ClaimedMessage, + claimOutbox, + failOutbox, + OUTBOX_TOPICS, +} from '@features/battle/ledger'; import { processAwaitBeaconMessage } from './beacon.worker'; import { processComputeMessage } from './compute.worker'; @@ -37,19 +43,42 @@ export async function runBattleWorkerOnce(workerId: string, now: Date = new Date // Claimed a topic this process does not know how to run. That is a deployment or // routing bug, not a transient failure, but dead-lettering it immediately is safer // than leaving it claimed forever with nothing to process it. - await failOutbox(message, `no handler for topic ${message.topic}`, now); + await giveUp(message, `no handler for topic ${message.topic}`, now); continue; } try { await handler(message, nowSeconds); } catch (error) { - await failOutbox(message, (error as Error).message, now); + await giveUp(message, (error as Error).message, now); } } return { processed: messages.length }; } +/** + * Records the failure, and ends the battle if that was the last attempt. + * + * A dead letter used to stop at the message: the battle stayed in whatever non-terminal + * state it was in, and since locks are freed by reaching a terminal state, both its pets + * were left unable to battle again with nothing saying why. `abandonBattle` closes that, + * and declines where the state machine has no legal way to forfeit — the dead letter is + * still listed for a human in either case. + */ +async function giveUp(message: ClaimedMessage, error: string, now: Date): Promise { + const { deadLettered } = await failOutbox(message, error, now); + if (!deadLettered) return; + + const { abandoned, state } = await abandonBattle( + message.battleId, + `${message.topic} gave up after ${message.attempts} attempts: ${error}`, + ); + console.error( + `[battle-worker] ${message.topic} dead-lettered for ${message.battleId}` + + (abandoned ? ' — battle forfeited, pets released' : ` — left in ${state ?? 'unknown'}`), + ); +} + export interface BattleWorkerHandle { stop(): void; } diff --git a/backend/tests/features/battle/ledger/state.test.ts b/backend/tests/features/battle/ledger/state.test.ts index 5590f6c0..757b659b 100644 --- a/backend/tests/features/battle/ledger/state.test.ts +++ b/backend/tests/features/battle/ledger/state.test.ts @@ -53,12 +53,19 @@ describe('no cancellation after commitment', () => { expect(isCommitted(BattleState.seeded)).toBe(true); }); - it('offers forfeit instead, but only where a beacon can actually stall', () => { - // A permanent beacon outage has to end the battle somehow. Forfeit does it with no - // progression change, so manufacturing an outage gains nothing. + it('offers forfeit instead, but only where the pipeline can actually stall', () => { + // A permanent outage has to end the battle somehow. Forfeit does it with no + // progression change, so manufacturing an outage gains nothing. `computed` is here + // because the verifier can be unreachable until the outbox gives up, which strands + // the battle and its pets' locks exactly as a beacon outage would. expect(classifyTransition(BattleState.committed, BattleState.forfeited)).toBe('advance'); expect(classifyTransition(BattleState.seeded, BattleState.forfeited)).toBe('advance'); - expect(classifyTransition(BattleState.computed, BattleState.forfeited)).toBe('illegal'); + expect(classifyTransition(BattleState.computed, BattleState.forfeited)).toBe('advance'); + + // Not from everywhere: past signing there is a signed receipt, and a battle with one + // is resolved rather than abandonable. + expect(classifyTransition(BattleState.verified, BattleState.forfeited)).toBe('illegal'); + expect(classifyTransition(BattleState.signed, BattleState.forfeited)).toBe('illegal'); }); }); diff --git a/backend/tests/features/battle/ledger/transitions.test.ts b/backend/tests/features/battle/ledger/transitions.test.ts index 6f10a349..edc5e1c0 100644 --- a/backend/tests/features/battle/ledger/transitions.test.ts +++ b/backend/tests/features/battle/ledger/transitions.test.ts @@ -24,6 +24,7 @@ vi.mock('@config/prisma', () => ({ import { prisma } from '@config/prisma'; import { + abandonBattle, applyTransition, failBattle, IllegalTransitionError, @@ -236,3 +237,59 @@ describe('sortPetIds', () => { expect(input).toEqual(['10', '9']); }); }); + +describe('abandonBattle', () => { + /** The state `prisma.battleLedger.findUnique` reports for the battle under test. */ + const currently = (state: BattleState | null) => + vi.mocked(prisma.battleLedger.findUnique).mockResolvedValue( + (state === null ? null : { state }) as never, + ); + + // The gap this closes: a dead-lettered step left the battle non-terminal, and locks are + // released by reaching a terminal state, so both its pets were stuck for good. + it('forfeits a battle stuck in computed and releases its locks', async () => { + currently(BattleState.computed); + + const result = await abandonBattle('btl_1', 'verify gave up'); + + expect(result).toEqual({ abandoned: true, state: BattleState.forfeited }); + expect(tx.battleLedger.updateMany).toHaveBeenCalledWith({ + where: { battleId: 'btl_1', state: BattleState.computed }, + data: { failureReason: 'verify gave up', state: BattleState.forfeited }, + }); + // Terminal, so the locks go with it — in the same transaction. + expect(tx.petBattleLock.deleteMany).toHaveBeenCalledWith({ where: { battleId: 'btl_1' } }); + }); + + // `verification_failed` means the two engines disagreed and is a ruleset-wide circuit + // breaker (§F). A verifier that never answered has disagreed with nothing. + it('does not mark an unreachable verifier as a verification failure', async () => { + currently(BattleState.computed); + + await abandonBattle('btl_1', 'indexer-go unavailable'); + + const data = tx.battleLedger.updateMany.mock.calls[0]![0].data; + expect(data.state).toBe(BattleState.forfeited); + expect(data.state).not.toBe(BattleState.verification_failed); + }); + + it('leaves a state with no legal forfeit exactly as it is', async () => { + currently(BattleState.verified); + + const result = await abandonBattle('btl_1', 'sign gave up'); + + expect(result).toEqual({ abandoned: false, state: BattleState.verified }); + // Untouched: the battle is still live and may yet be signed, so its pets stay locked. + expect(tx.battleLedger.updateMany).not.toHaveBeenCalled(); + expect(tx.petBattleLock.deleteMany).not.toHaveBeenCalled(); + }); + + it('reports nothing to do for a battle that does not exist', async () => { + currently(null); + + await expect(abandonBattle('btl_missing', 'whatever')).resolves.toEqual({ + abandoned: false, + state: null, + }); + }); +}); diff --git a/backend/tests/features/battle/worker/runner.test.ts b/backend/tests/features/battle/worker/runner.test.ts index eb6a3fd2..99f49427 100644 --- a/backend/tests/features/battle/worker/runner.test.ts +++ b/backend/tests/features/battle/worker/runner.test.ts @@ -7,6 +7,7 @@ vi.mock('@config/env', () => ({ vi.mock('@features/battle/ledger', () => ({ claimOutbox: vi.fn(), failOutbox: vi.fn(), + abandonBattle: vi.fn(), // Must list every real topic. A missing one is not a smaller map — it registers as an // `undefined` key and the dispatcher claims a topic called "undefined". OUTBOX_TOPICS: { @@ -35,15 +36,20 @@ vi.mock('@features/battle/worker/publish.worker', () => ({ processPublishMessage: vi.fn(), })); -import { claimOutbox, failOutbox } from '@features/battle/ledger'; +import { abandonBattle, claimOutbox, failOutbox } from '@features/battle/ledger'; import { processAwaitBeaconMessage } from '@features/battle/worker/beacon.worker'; import { processComputeMessage } from '@features/battle/worker/compute.worker'; +import { processVerifyMessage } from '@features/battle/worker/verify.worker'; import { runBattleWorkerOnce } from '@features/battle/worker/runner'; const NOW = new Date('2026-07-26T12:00:00.000Z'); beforeEach(() => { vi.clearAllMocks(); + // The default: a failure that still has retries left. Tests wanting the last attempt + // override this. + vi.mocked(failOutbox).mockResolvedValue({ deadLettered: false, retryAt: new Date(0) }); + vi.mocked(abandonBattle).mockResolvedValue({ abandoned: true, state: 'forfeited' as never }); }); describe('dispatch', () => { @@ -113,3 +119,47 @@ describe('dispatch', () => { expect(await runBattleWorkerOnce('worker-a', NOW)).toEqual({ processed: 0 }); }); }); + + +describe('the end of the retry road', () => { + const dying = (topic: string) => { + vi.mocked(claimOutbox).mockResolvedValue([ + { id: 'm1', battleId: 'btl_1', topic, payload: {}, attempts: 8 }, + ]); + vi.mocked(failOutbox).mockResolvedValue({ deadLettered: true, retryAt: null }); + }; + + // Locks are released by reaching a terminal state, so a battle left non-terminal keeps + // both its pets out of the game for good. This is what closes that. + it('ends the battle when a message dead-letters, freeing its pets', async () => { + dying('verify'); + vi.mocked(processVerifyMessage).mockRejectedValue(new Error('indexer-go unavailable')); + + await runBattleWorkerOnce('w1'); + + expect(abandonBattle).toHaveBeenCalledWith( + 'btl_1', + expect.stringContaining('verify gave up after 8 attempts'), + ); + }); + + it('leaves the battle alone while retries remain', async () => { + vi.mocked(claimOutbox).mockResolvedValue([ + { id: 'm1', battleId: 'btl_1', topic: 'verify', payload: {}, attempts: 2 }, + ]); + vi.mocked(processVerifyMessage).mockRejectedValue(new Error('transient')); + + await runBattleWorkerOnce('w1'); + + expect(failOutbox).toHaveBeenCalled(); + expect(abandonBattle).not.toHaveBeenCalled(); + }); + + it('also ends one dead-lettered for having no handler at all', async () => { + dying('nonsense'); + + await runBattleWorkerOnce('w1'); + + expect(abandonBattle).toHaveBeenCalledWith('btl_1', expect.stringContaining('no handler')); + }); +});

    rWnR=#VF062x2zK_dkU(g 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

    `fqMp2Mc%SzT`_7ei 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∨toY}Ak(J!0%R2VU3py`TGj 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≪etJ;V-%u|5l>8X@*x=&_b%lxt&)8 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