Skip to main content

Documentation Index

Fetch the complete documentation index at: https://hedgeem-api.qeetoto.com/llms.txt

Use this file to discover all available pages before exploring further.

F102 — Two-Balance Wallet System

Phase5 — Platform
JiraHEDGE-187
StatusTypeScript ✅ · UMA ⬜ · V7 ⬜

Business Rule

Every registered player holds two separate balances:
BalanceLocationDescription
Account balancewallets.balance (Supabase)Money held by the platform. Shown in the lobby header and cashier page. Persists across sessions.
Seat balancegame_table_state.seat_balanceChips in front of the player at a specific table. Exists only while seated.
Flow:
  1. Player sits at a table → buy-in amount deducted from account, credited as seat chips
  2. Player tops up during a session → amount deducted from account, added to seat chips
  3. Player presses Back to Lobby → all remaining seat chips automatically credited back to account
  4. If player loses all chips mid-session → can top up from account without leaving the table
Welcome balance: New players receive a £1,000 welcome balance on first login (Google OAuth).

Technical Design

Database

-- Account balance — persists across sessions
public.wallets.balance          bigint  -- pence, non-negative
public.wallets.welcome_balance_granted  boolean  -- prevents double-crediting

-- Seat balance — per (table, player) while in a game
public.game_table_state.seat_balance   bigint  -- pence, non-negative

API endpoints

EndpointEffect on balances
GET /api/players/:playerIdReturns accountBalance from wallets.balance. Auto-creates wallet with £1,000 on first login.
POST /api/tables/:id/sitDeducts buyInAmount from wallet. Sets seat_balance. Returns NACK if wallet insufficient.
POST /api/tables/:id/topupDeducts amount from wallet. Adds to seat_balance. Returns NACK if wallet insufficient. Response always includes newAccountBalance.
POST /api/tables/:id/leaveCredits seat_balance → wallet. Resets game state to STATUS_START. Idempotent — safe if seat is already empty.

Client integration (game-shell.html)

The compliance bar’s Lobby button is intercepted:
click → POST /api/tables/:tableId/leave (auth'd only)
      → update localStorage session.balance = newAccountBalance * 100
      → navigate to /lobby.html
The tableId is extracted from the game iframe URL (?tableId=N). If the player is anonymous or no tableId is present, navigation proceeds immediately without calling leave.

localStorage session shape

{
  "playerId": "uuid",
  "displayName": "Simon",
  "balance": 100000,
  "access_token": "...",
  "role": "BASIC_USER"
}
balance is stored in pence (integer). £1,000 = 100000. Updated after leave and after fetchPlayerProfile().

Acceptance Criteria

#CriterionTest
AC1After OAuth login, lobby header shows account balance from serverGET /api/players/:id returns accountBalance: 1000.00 for new user
AC2Sitting at a table deducts buy-in from account balancewallets.balance reduced by buyInAmount * 100 after /sit
AC3Sitting with more than available balance returns NACK/sit with buyInAmount > wallet{ acknowledgement: "NACK" }
AC4Pressing Lobby button calls leave before navigatinggame-shell.html network log shows POST /leave
AC5Account balance updated in localStorage after leavelocalStorage.hedgeem_session.balance reflects newAccountBalance * 100
AC6Lobby header balance refreshes after return from gamerenderHeader() reads updated session on load
AC7Top-up deducts from account and adds to seatwallets.balance -= amount; seat_balance += amount
AC8Top-up with insufficient wallet returns NACK/topup with amount > wallet{ acknowledgement: "NACK" }
AC9New player receives £1,000 welcome balanceFirst GET /api/players/:idaccountBalance: 1000.00
AC10Leave with empty seat returns creditsReturned: 0/leave when seat_balance = 0{ creditsReturned: 0 }

Version Parity

VersionStatusNotes
TypeScript (v6)Full implementation: server endpoints + game-shell leave hook (HEDGE-187)
JavaScript (v4)N/ANo server integration; standalone client only
UMA (v5)Not implemented
V7 (Horse Racing)Not implemented

  • POST /api/tables/{tableId}/sit — buy in to a table
  • POST /api/tables/{tableId}/leave — cash out chips back to wallet
  • POST /api/tables/{tableId}/topup — top up chips during a session
  • GET /api/players/{playerId} — read account balance
  • F016 — Credits wallet — in-game chip balance display
  • HEDGE-187 · HEDGE-190 (lobby / cashier page)