Product definition and locked scope for unified player/house custody on the pad (Dice first, anvil). Companion to FLYWHEEL-v1-brief-2026-10-12.md.
One-paragraph product
Flywheel uses one shared multi-token, multi-game custody vault (Suited-faithful). Players must deposit a pad-launched token that allocated to the game before real play. The pad WalletBar shows Game Wallet (on-chain checkpointed balance) vs wallet balances, grouped by game → tokens. Fast withdraw needs a settler signature; if the gateway is dead, players use requestExit → claimExit. Launch house % credits house[game][token] in this same vault. Dice-only on anvil this pass, with a minimal settler/gateway.
Locked architecture choices
| ID | Choice |
|---|---|
| Vault | One contract for all games × all pad tokens |
| House | Explicit house[game][token] (not “excess only”) |
| House + players | Same vault; launch 50% credits house |
| Checkpoints | Entries (gameId, token, player, delta); Dice-only batches until BJ |
| Ops | One shared owner + settler across games |
| Game Wallet | On-chain checkpointed balance; in-session ≠ Game Wallet |
| Play gate | Must deposit before real play |
| Withdraw | Settler EIP-712 auth (fast path); unilateral exit hatch if gateway dead |
| Exit delay | 1h anvil / 24h prod intent |
| minDeposit | 1e18 (1 whole token) |
| Pause | Suited parity (blocks deposit/checkpoint; never withdraw/exit) |
| Allowlist | Pad-launched tokens that allocated to that game |
| WalletBar | Everywhere; Deposit + Withdraw; Exit when needed |
| List | Group by game → tokens; default Supported only |
| Empty Game Wallet | Grayed row + Deposit CTA if wallet balance > 0 |
| In play | Block fast withdraw only; explain why |
| Scope | Dice + anvil; BJ play / RH deploy later |
In scope for v1
- Unified vault contract (multi-token + multi-game), full Suited surface adapted for
(gameId, token, player)checkpoints and per-token solvency. - Launch path credits
house[game][token]; LP TOKEN fee share → house for that game/token. - Minimal anvil settler/gateway: checkpoint + sign withdraw auths; hot key in
.dev. - Pad WalletBar Game Wallet dropdown (deposit / withdraw / exit messaging).
- Dice real play gated on Game Wallet balance for the selected token.
Out of scope for v1
- Blackjack play wiring / BJ checkpoint batches
- Robinhood testnet/mainnet deploy
- Rake sweep UI, Creator NFT changes
- Betting from the external wallet without deposit
Domain model
- Vault — single contract; allowlisted
(gameId, token);players[gameId][token][wallet];house[gameId][token];liabilities[token]; settler; exit hatch; pause. - Checkpoint — strict seq; per-token zero-sum including house moves + rake; Dice-only until BJ ships.
- Game Wallet — on-chain checkpointed balance for
(game, token, wallet). - Deposit / Withdraw / Exit — Suited semantics.
Flow
- Creator launches → 50% TOKEN →
house[game][token]in FlywheelVault; token allowlisted. - Player buys TOKEN on pool → Deposit via WalletBar into Game Wallet.
- Dice plays against house using off-chain session balance; settler checkpoints nets.
- Withdraw (settler auth) or requestExit / claimExit if gateway is down.
Settlement model (Dice v1 — locked 2026-10-14)
One live Game Wallet number everywhere (display option 1, locked 2026-10-14): Canonical store liveGameWallet.ts (pad + Dice share one singleton via Vite alias): liveWei = settledWei + pendingWei + unackedWei (optimistic rolls ahead of settler). Dice YOUR BALANCE / TokenPicker and WalletBar Game all read that store. On-chain balances still move only on checkpoint / settleAndWithdraw.
WalletBar deposit/withdraw/exit emits flywheel:game-wallet-changed; Dice re-reads chain + pending so YOUR BALANCE updates without remount. Dice also emits on successful roll report / flush; WalletBar listens and refreshes live Game.
TokenPicker dropdown You must use the same live figure as the button / YOUR BALANCE (not chain-only playerBalance).
| Trigger | Action |
|---|---|
| Every 60s | Settler flushes pending nets → checkpoint tx (settler pays gas) |
Idle (no roll for game idleMs, default 30s) | Same flush |
| Every N rolls (Dice default 10) | Same flush |
| Tab close / page hide | Beacon flush |
| Withdraw | Player submits one tx: settleAndWithdraw (settler one EIP-712 sig covers pending checkpoint + withdraw; player pays gas). Max / amount use live balance. |
Pending lifecycle (2026-10-14): Settler clears playerDeltaWei only after checkpoint receipt success, or after POST /api/settler/withdraw-complete following a confirmed settleAndWithdraw. withdraw-auth reserves the session (flush skipped) until complete / withdraw-cancel / auth deadline — does not clear pending on auth issue. Flush and withdraw-auth are mutually exclusive per session key.
Per-game knobs: launcher-pad/src/lib/gameSettleSettings.ts. Pending merge: launcher-pad/src/lib/gameWallet.ts. Document when adding BJ.
Empty pending + withdraw still uses settleAndWithdraw with empty entries bound to current checkpointSeq.
Open questions (follow-up)
- Exact rake encoding in multi-token checkpoints (per-token rake array).
- Whether legacy
HouseVault/VaultFactoryremain for anything after cutover.