Phase 0.1 — Underpayment confirmation bug (CRITICAL):
Payment confirmation gated on `status.confirmed`, which checkPaymentStatus
sets for ANY incoming tx regardless of amount, so sending a single atomic
unit granted a full game/credits. Now gate on `status.complete` (received
>= expected). Underpayers are warned once and the payment stays pending so
a top-up can complete it. Persist `received_amount` for single-game and
credits confirmations for reconciliation. Adds an underpayment regression
test.
Phase 0.2 — Provably-fair was decorative (CRITICAL):
The committed seed had zero effect on the dungeon (created seededRNG was
unused; generation used Math.random + a globally-seeded ROT.RNG). Thread a
per-game seeded RNG derived from the committed seed through dungeon
generation (reseed the Digger via seedToInt + replace all Math.random) and
monster movement (seededShuffle). Add DungeonGenerator.regenerateFromSeed
and layoutFingerprint; /api/verify now regenerates the dungeon from the
seed and returns a fingerprint a player can independently reproduce. Adds a
determinism test suite.
Full suite: 11 suites / 113 tests passing.
Plan and progress tracked in docs/REMEDIATION_PLAN.md.
Smirk extension is migrating from SHA256 pre-hash to standard RFC 8032
Ed25519 signatures. Accept both formats during transition:
- Try raw message bytes first (new standard)
- Fall back to SHA256(message) (legacy, remove after 2026-07-01)
- Fix wallet balance always showing 'Disconnected' in admin dashboard
- Always attempt balance fetch even if isHealthy=false
- Show error state with message instead of generic 'Disconnected'
- Add POST /api/admin/alerts/test-email endpoint to verify Resend config
- Move alertService to module scope for endpoint access
When both payment modes are enabled (mixed mode) and user has no credits
or confirmed payment, the 'choose_payment' action was falling through to
the error case. Now 'choose_payment' triggers the payment options modal
just like 'make_payment' and 'purchase_credits' do.
- Replace asterisk (*) sparkles with floor tiles + bright golden color
- Remove skull emoji (☠) and death particles (% *) - use red flash effect
- Fix monster shadows causing black boxes - use red floor glow instead
- Replace 'ESCAPED!' emoji text with character-by-character transparent rendering
- Use GameTiles.getPlayerTile() instead of hardcoded '@'
- Use GameTiles.getMonsterTile() instead of hardcoded '~'
All tiles now render with proper transparency on floor tile base.
New dedicated animation while waiting for payment:
- Player runs toward BIG pulsating golden treasure
- Player always grabs the treasure (with dramatic pickup moment)
- Monster pack (4-6 monsters) spawns from multiple directions
- 60% chance: player escapes with treasure to the exit
- 40% chance: player gets devoured by monster pack (skull/death effect)
Animation features:
- Massive golden aura around treasure with sparkle ring
- Player glows gold when carrying treasure
- Death particles expand outward on devour
- Monsters converge from edges (left, right, top, bottom)
Existing 'Awaiting next block' animation preserved unchanged.
- Created SuspendedGameManager to preserve game state when users disconnect
- Games are keyed by DB userId (persistent) instead of ephemeral socketId
- handleDisconnect now suspends games for 5 minutes instead of deleting
- handleConnection restores suspended games on reconnect with session token
- Payment monitoring is restored for pending payments on reconnect
- Added hasActiveMonitoring() method to PaymentHandlers
- Queue entries preserved for users with active sessions/payments
- Updated TODO.md with reconnection feature documentation
Users in dungeon or awaiting payment can now close/refresh browser and
seamlessly resume within 5 minutes when reconnecting.
Payment Fixes:
- Prevent credits going negative with WHERE credits >= $1 check
- completeGame now uses recorded payment_mode from game record instead of global gameMode
- Add duplicate payout prevention by checking for existing payouts before processing
Dead Code Cleanup:
- Remove unused MoneroPayService (WalletRPCService is the actual service)
- Remove legacy MoneroPay references from comments
Tests:
- Add 50 comprehensive payment/payout tests (payment_payout_comprehensive.test.js)
- Expand WalletRPCService tests (4 -> 31 tests)
- Total: 106 tests passing across 10 test suites
Documentation:
- Update TODO.md with recent fixes and correct test counts
- Update migration comments to reflect actual wallet service used