A production-ready, highly secure, and provably fair gambling platform baseline.
Built exclusively on Next.js 15, React 19, Tailwind CSS v4, Prisma (PostgreSQL), and Redis (Upstash) with a heavy emphasis on auditability, transactional integrity, and race-condition prevention.
- Executive Overview & Philosophy
- Deep System Design & Architecture
- Provably Fair Cryptography
- Real-Time WebSocket Infrastructure
- Anti-Cheat, Security & Compliance
- UI/UX & Frontend Architecture
- In-Depth Project Structure
- Comprehensive Local Setup Guide
- Deployment & Production Readiness
This project is not a simple "website." It is a financial engine wrapped in a gaming interface. The core philosophy of this platform is zero trust in the client.
- The Frontend (Next.js App Router): Is treated purely as a reactive display and user-intent collector. It holds no authority over money, odds, or game results.
- The Backend (Next.js API + Services): Acts as the absolute source of truth. It validates every single request mathematically and cryptographically before interacting with the database.
The platform comes pre-built with full mathematical models and React components for:
Baccarat, Blackjack, CoinFlip, Crash, DiceRoll, HiLo, Keno, Limbo, Mines, Plinko, Roulette, Slots, Video Poker, and Wheel.
Every critical request (like placing a bet or withdrawing funds) follows a strict pipeline:
sequenceDiagram
participant User as Client (Next.js UI)
participant API as /app/api/route
participant Redis as Redis (Upstash)
participant PF as Provably Fair Service
participant Wallet as Ledger Service
participant DB as PostgreSQL (Prisma)
User->>API: POST /api/games/dice/bet {wager, clientSeed, target}
API->>Redis: Lock request (Idempotency Key) + Rate Limit Check
Redis-->>API: Allow / Deny
API->>Wallet: Validate Balance (wager) & Deduct
Wallet->>DB: ATOMIC Row Lock + Create Transaction (BET)
API->>PF: Resolve Game Outcome (serverSeed + clientSeed + nonce)
PF-->>API: Outcome Result (Win/Loss, Payout)
alt isWin == true
API->>Wallet: Add Funds
Wallet->>DB: ATOMIC Row Lock + Create Transaction (WIN)
end
API->>DB: Record 'Bet' with seeds used (for audit)
API-->>User: Response {payout, profit, result}
Most platforms fail because they store user balances like this: [User.balance = 500] -> [User.balance = 600]. If a request is duplicated, money is printed from nowhere.
This platform strictly implements an Immutable Ledger Model.
- The
Transactiontable is the sole source of truth. - The literal formula for a user's wallet balance is:
SUM(All DEPOSITS + WINS) - SUM(All WITHDRAWALS + BETS). - Whenever a user places a bet:
- A
Transactionis logged with typeBETand thebalanceBeforeandbalanceAfterare recorded. - If the user wins, a second separate
Transactionof typeWINis logged instantly.
- A
- No financial row is ever deleted. "Reversals" are handled by issuing opposing transactions (e.g.,
ADJUSTMENT).
Operating on PostgreSQL via Prisma ORM, the primary entities are tightly constrained:
User: Core identity. Stores Auth credentials, 2FA keys, unified KYC state, VIP Wagered amounts, and the activeServerSeed/ClientSeedrequired for the next bet.Transaction: The holy grail of the platform. Enums defineDEPOSIT,WITHDRAWAL,BET,WIN, andBONUS.Bet: Connects to the User and Game. Stores the exact cryptographic seeds utilized at the millisecond the bet was processed. It holds a JSONresultcolumn for game-specific data (e.g., exactly what cards were drawn in Blackjack).Withdrawal/Deposit: Handles fiat and cryptocurency lifecycle states (PENDING,PROCESSING,COMPLETED,REJECTED).
To prevent users from exploiting the platform by spamming buttons, refreshing rapidly, or manipulating network latency:
- Idempotency Keys (
src/services/idempotency.service.ts): Every request generates a unique hash based on User ID + Action. This hash is temporarily stored in Redis/DB. If another request with the same hash arrives withinXmilliseconds, it is violently rejected. - Atomic Locks: Prisma
updatequeries use native database row-locks preventing parallel balance reads/writes from overlapping.
The fundamental requirement of a cryptographic casino is proving the house did not cheat. This is handled by src/services/provably-fair.service.ts.
The Math:
- Server Seed Generation: Server generates a massive random string (
serverSeed). The server hashes this string using SHA-256 (serverSeedHash) and displays the hash to the player. The player now knows the outcome is set, but cannot decipher it. - Client Seed Generation: The player provides their own string (
clientSeed), acting as entropy the server cannot predict. - Nonce: Starts at
0. Increases by1for every bet placed with the current seed pair. - Resolution Hash:
HMAC_SHA256(clientSeed + ":" + nonce, serverSeed). - Number Generation: The first few bytes of that hexadecimal hash are converted into a float between
0and1. This uniform float is then multiplied by game logic (e.g., multiplying by 10,000 for a Crash multiplier).
When the player rotates their seed, the previous serverSeed is revealed in plaintext, allowing the player to verify every past bet mathematically entirely offline.
Standard serverless Next.js functions cannot handle the persistent polling required for a live multiplayer Crash game or global chatting.
This project utilizes a Custom Server Base (server.ts):
- Next.js is injected into a standard Node.js
httpserver. - Socket.io is attached to the same port.
- Authentication Flow: Clients emit an
authenticatepacket with their NextAuth JWT. The server verifies the JWT using theNEXTAUTH_SECRETbefore allowing the socket to emit to protected chat channels or receive personalized WebSocket events. - Use Cases:
- The Crash curve rising (emitting multiplier every 100ms to all clients).
- Global "Live Bets" feed broadcasting large wins.
src/services/fraud-detection.service.ts actively monitors transaction velocities.
- Win-Rate Monitoring: Identifies mathematically impossible win streaks based on established standard deviations.
- Bet Velocity: Flags users hitting API endpoints faster than humanly possible (bypassing normal frontend UI limitations).
- Withdrawal Cooldowns: The system strictly prohibits instant withdrawals immediately following deposits + bonuses, circumventing free-money washing exploits.
- Identity Gates: The admin panel requires manual approval of uploaded ID formats before the
kycStatusflips toAPPROVED, unlocking the Withdrawal tier. - Deep Audit Logging:
src/services/audit.service.tslogs everything. Example: "Admin 'Dave' approved KYC for User 'X' at 11:42 PM".
The frontend is built to feel like an immersive, extremely premium modern gaming application.
- Responsive Mobile-First constraints: Using strict Tailwind CSS v4 breakpoints (
sm,md,lg,xl). The UI collapses cleanly on smartphones without horizontal scroll breakage. - Headless Accessibility: Radix UI enables keyboard-navigable dialogs, tooltips, toasts, and dropdowns. Screen readers easily interpret the states.
- Fluid Animations:
framer-motiondictates page transitions, chip placements in Roulette, and smooth ticker numbers. The UI must wow the user while gracefully handling asynchronous loading states to prevent "button lag" panic. - Component Structure: Heavily modularized.
components/ui/contains reusable buttons, inputs, and layout wrappers.components/games/contains the distinct rendering canvas/SVG configurations for the various game boards.
gambling-platform/
├── .env.example # Crucial environment variable templates (DB, Redis, Auth)
├── package.json # Script definitions (build, dev, lint)
├── prisma/
│ └── schema.prisma # The absolute backbone: 500+ lines defining the relational DB
├── server.ts # Custom Node Wrapper for Next.js + Socket.io Server
├── public/ # Static assets, branding, and game vector SVGs
└── src/
├── app/ # Next.js App Router
│ ├── (public)/ # Unauthenticated marketing & login interfaces
│ ├── (dashboard)/ # Authenticated wallet, profiles, and game grids
│ └── api/ # Serverless execution routes
│ ├── admin/ # Protected endpoints regulating Users, KYC, and Settings
│ ├── auth/ # NextAuth callback providers
│ ├── games/ # [GAME_NAME]/bet REST execution endpoints
│ └── webhooks/ # Incoming server-to-server Razorpay/Gateway confirmations
├── components/ # React Components
│ ├── admin/ # Dashboards, tables, graphs, and audit-logs UI
│ ├── games/ # Highly complex Game Client components (Crash curve, Roulette wheel)
│ └── ui/ # Core design system primitives (Tailwind integrated)
├── lib/ # Singletons (PrismaClient, RedisClient, NextAuth Config)
├── services/ # Core Backend Services (MUST REMAIN ISOLATED FROM API ROUTES)
│ ├── audit.service.ts
│ ├── betting.service.ts
│ ├── fraud-detection.service.ts
│ ├── idempotency.service.ts
│ ├── provably-fair.service.ts
│ └── wallet.service.ts
└── types/ # Global TypeScript Definitions
-
System Prerequisites:
- Node.js
v18+orv20+is mandatory for Next.js 15 features. - Access to a PostgreSQL instance (Local Docker or cloud provider like Supabase/Neon).
- Redis Database (Local Docker or Upstash).
- Node.js
-
Clone & Install:
git clone <repository_url> cd gambling-platform npm install
-
Environment Setup: Duplicate the
.env.examplefile and rename it to.env. Configure the following critical vars:# Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE DATABASE_URL="mongodb+srv://... or postgresql://..." # Required for Rate Limiting & NextAuth sessions REDIS_URL="redis://..." # Execute `openssl rand -base64 32` to generate a secure secret NEXTAUTH_SECRET="..." NEXTAUTH_URL="http://localhost:3000"
-
Initialize the Database Ledger: Synchronize the Prisma schema to construct the strict transaction columns.
npx prisma generate npx prisma db push
-
Start Development Server: Launch the comprehensive
server.tsbuild (Next.js + WebSockets).npm run dev
Navigate to
http://localhost:3000.
Vercel / Next.js Serverless deployments DO NOT SUPPORT standard Socket.io connections natively within the same build.
To deploy this application correctly into a production environment:
- The Next.js Frontend & API: Can be hosted uniformly on Vercel.
- The Socket.io Server: Needs to be decoupled and hosted on a long-running instance (like an AWS EC2, DigitalOcean Droplet, Railway, or Render service). Configure the frontend's Socket.io client to connect to this detached live URL.
- Database Connectivity: When deploying Serverless APIs interacting with Prisma, utilize Prisma Accelerate or PgBouncer connection pooling to avoid exhausting PostgreSQL instances upon high traffic loads. You cannot allow 1000 simultaneous users to open direct single DB connections on every refresh.
- Build command overriding: As programmed in
package.json, ensureprisma generateexecutes during the build process to inject the ORM correctly.
Strictly Confidential & Proprietary Software. Do not distribute. Audit trailing is perpetually active.