Skip to content

Latest commit

Β 

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Surge Gaming ⚑

Decentralized Pay-Before-Queue Gaming Platform with Multichain Support

License Solidity Next.js

Surge is a trustless gaming platform where players stake ETH/MNT to compete, with winners taking 75% of the pot while the platform collects 25% as fees. Built with smart contract escrow and real-time Socket.io matchmaking.


πŸ“¦ Live Contract Addresses

Network Chain ID Contract Address Explorer
Arbitrum Sepolia 421614 0x8fD3A16F905dF98907B3739bCD0E31a7949cd2D2 View on Arbiscan
Mantle Sepolia 5003 0x6bFe0C83f7924d54A0780F80d2B4561CfbC0B2B1 View on MantleScan

Platform Wallet: 0xFE13B060897b5daBbC866C312A6839C007d181fB


πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              FRONTEND                                    β”‚
β”‚                          (Next.js + Wagmi)                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Wallet Connect β”‚  β”‚  Chain Switcher β”‚  β”‚    Game Components      β”‚  β”‚
β”‚  β”‚  (RainbowKit)   β”‚  β”‚  (ARB ↔ MNT)   β”‚  β”‚  (Lobby/Waiting/Games)  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚           β”‚                    β”‚                       β”‚                 β”‚
β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β”‚
β”‚                                β”‚                                         β”‚
β”‚                       Smart Contract Calls                               β”‚
β”‚                   (depositStake, withdraw, etc.)                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                         β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚       SMART CONTRACTS          β”‚   β”‚      BACKEND SERVER       β”‚
    β”‚       (SurgeGaming.sol)        β”‚   β”‚    (Node.js + Socket.io)  β”‚
    β”‚                                β”‚   β”‚                           β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
    β”‚  β”‚  Arbitrum Sepolia        β”‚  β”‚   β”‚  β”‚ MatchmakingManager  β”‚  β”‚
    β”‚  β”‚  0x8fD3A16F905d...cd2D2  β”‚  β”‚   β”‚  β”‚ - Queue Management  β”‚  β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚  β”‚ - Chain-aware Match β”‚  β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
    β”‚  β”‚  Mantle Sepolia          β”‚  β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
    β”‚  β”‚  0x6bFe0C83f7...b0B2B1   β”‚  β”‚   β”‚  β”‚    GameManager      β”‚  β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚  β”‚ - Score Tracking    β”‚  β”‚
    β”‚                                β”‚   β”‚  β”‚ - Winner Declarationβ”‚  β”‚
    β”‚  Escrow Functions:             β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
    β”‚  β€’ depositStake()              β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
    β”‚  β€’ refundStake()               β”‚   β”‚  β”‚  ContractService    β”‚  β”‚
    β”‚  β€’ createMatchFromDeposits()   β”‚   β”‚  β”‚ - Multi-chain calls β”‚  β”‚
    β”‚  β€’ declareWinner()             β”‚   β”‚  β”‚ - Match creation    β”‚  β”‚
    β”‚  β€’ withdraw() / withdrawDraw() β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”„ Game Flow

sequenceDiagram
    participant P1 as Player 1
    participant P2 as Player 2
    participant FE as Frontend
    participant SC as Smart Contract
    participant BE as Backend Server

    Note over P1,BE: 1️⃣ STAKE DEPOSIT PHASE
    P1->>FE: Select game + stake amount
    FE->>SC: depositStake(depositId) + ETH/MNT
    SC-->>FE: StakeDeposited event
    FE->>BE: join_queue(address, stake, txSignature, chainId)
    BE-->>FE: queue_joined

    P2->>FE: Select same game + stake
    FE->>SC: depositStake(depositId) + ETH/MNT
    SC-->>FE: StakeDeposited event
    FE->>BE: join_queue(address, stake, txSignature, chainId)

    Note over P1,BE: 2️⃣ MATCHMAKING PHASE
    BE->>BE: Match players (same stake + chain)
    BE->>SC: createMatchFromDeposits(matchId, dep1, dep2)
    SC-->>BE: MatchCreated event
    BE->>FE: match_found (both players)
    FE-->>P1: Navigate to game room
    FE-->>P2: Navigate to game room

    Note over P1,BE: 3️⃣ GAMEPLAY PHASE
    P1->>BE: game_ready
    P2->>BE: game_ready
    BE-->>FE: game_started
    loop Game Rounds
        P1->>BE: game_action (submit score)
        P2->>BE: game_action (submit score)
        BE-->>FE: game_update (scores)
    end

    Note over P1,BE: 4️⃣ WINNER DECLARATION & PAYOUT
    BE->>SC: submitScore(matchId, player, score)
    BE->>SC: declareWinner(matchId, winnerAddress)
    SC-->>BE: WinnerDeclared event
    BE-->>FE: game_over (winner info)
    P1->>SC: withdraw(matchId)
    SC->>P1: 75% payout
    SC->>SC: 25% to Platform Wallet
Loading

πŸ’° Payout Structure

Outcome Winner Gets Platform Gets
Win 75% of total pot 25% platform fee
Draw Original stake returned 0%
Cancel (pre-match) Full refund via refundStake() 0%

Example:

  • Player A stakes 0.01 ETH, Player B stakes 0.01 ETH
  • Total Pot = 0.02 ETH
  • Winner receives: 0.015 ETH (75%)
  • Platform receives: 0.005 ETH (25%)

πŸ› οΈ Tech Stack

Frontend

Technology Purpose
Next.js 15 React framework with App Router
Wagmi + Viem Ethereum interactions
RainbowKit Wallet connection
Socket.io Client Real-time game updates
shadcn/ui UI component library
Firebase Authentication & data storage

Backend

Technology Purpose
Node.js + TypeScript Server runtime
Socket.io WebSocket server for real-time matchmaking
Ethers.js v6 Blockchain interactions
Render Cloud deployment

Smart Contracts

Technology Purpose
Solidity ^0.8.20 Smart contract language
OpenZeppelin ReentrancyGuard, Pausable, Ownable
Hardhat Development & deployment framework

πŸ“ Project Structure

Surge/
β”œβ”€β”€ frontend/                    # Next.js application
β”‚   β”œβ”€β”€ app/                     # App router pages
β”‚   β”œβ”€β”€ components/              # React components
β”‚   β”‚   β”œβ”€β”€ games/               # Game-specific UIs
β”‚   β”‚   β”œβ”€β”€ ui/                  # shadcn components
β”‚   β”‚   β”œβ”€β”€ chain-switcher.tsx   # Network selector
β”‚   β”‚   β”œβ”€β”€ game-lobby.tsx       # Main lobby
β”‚   β”‚   β”œβ”€β”€ stake-selector.tsx   # Bet amount picker
β”‚   β”‚   β”œβ”€β”€ waiting-room.tsx     # Matchmaking queue
β”‚   β”‚   └── wallet-connect.tsx   # Wallet integration
β”‚   β”œβ”€β”€ hooks/                   # Custom React hooks
β”‚   └── lib/
β”‚       β”œβ”€β”€ chains.ts            # Multichain config
β”‚       β”œβ”€β”€ wagmi.ts             # Web3 setup
β”‚       └── firebase.ts          # Firebase config
β”‚
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ server.ts            # Socket.io entry point
β”‚   β”‚   └── services/
β”‚   β”‚       β”œβ”€β”€ matchmaking.ts   # Queue & matching logic
β”‚   β”‚       β”œβ”€β”€ game-manager.ts  # Game state & scoring
β”‚   β”‚       └── contract.ts      # Blockchain interactions
β”‚   └── contracts/
β”‚       β”œβ”€β”€ contracts/
β”‚       β”‚   └── SurgeGaming.sol  # Main smart contract
β”‚       └── scripts/
β”‚           β”œβ”€β”€ deploy_arbitrum.js
β”‚           └── deploy_mantle.js
β”‚
└── render.yaml                  # Deployment config

πŸš€ Getting Started

Prerequisites

  • Node.js 18+
  • pnpm or npm
  • MetaMask or compatible wallet
  • Testnet ETH (Arbitrum Sepolia) or MNT (Mantle Sepolia)

Installation

# Clone repository
git clone https://github.com/your-username/surge.git
cd surge

# Install frontend dependencies
cd frontend
pnpm install

# Install backend dependencies
cd ../backend
pnpm install

# Install contract dependencies
cd contracts
npm install

Environment Setup

Frontend (frontend/.env.local):

NEXT_PUBLIC_SOCKET_URL=http://localhost:8080
NEXT_PUBLIC_FIREBASE_API_KEY=your_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_domain
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project

Backend (backend/.env):

PORT=8080
BACKEND_PRIVATE_KEY=0x_your_oracle_wallet_private_key
FRONTEND_URL=http://localhost:3000

Contracts (backend/contracts/.env.local):

PRIVATE_KEY=0x_your_deployer_wallet_private_key

Running Locally

# Terminal 1: Backend
cd backend
npm run dev

# Terminal 2: Frontend
cd frontend
npm run dev

πŸ“œ Smart Contract Functions

Player Functions

Function Description
depositStake(depositId) Deposit ETH/MNT to escrow before joining queue
refundStake(depositId) Get full refund if not yet matched
withdraw(matchId) Winner claims payout (75%)
withdrawDraw(matchId) Both players claim refund on draw

Backend-Only Functions (Oracle)

Function Description
createMatchFromDeposits(...) Link two deposits into a match
submitScore(matchId, player, score) Record player's game score
declareWinner(matchId, winner) Finalize match result

Admin Functions (Owner)

Function Description
setBackendOracle(address) Update backend oracle address
pause() / unpause() Emergency controls

πŸ”— Useful Links

Faucets (Get Testnet Tokens)

Block Explorers

RPC Endpoints

Network RPC URL
Arbitrum Sepolia https://sepolia-rollup.arbitrum.io/rpc
Mantle Sepolia https://rpc.sepolia.mantle.xyz

πŸ” Security Features

  • ReentrancyGuard: Prevents reentrancy attacks on all fund transfers
  • Pausable: Emergency stop mechanism for the platform
  • Ownable: Admin controls for critical functions
  • Backend Oracle: Only authorized backend can submit scores and declare winners
  • Deposit Validation: Stakes must match before match creation

πŸ“„ License

This project is licensed under the MIT License.


🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Built with ⚑ for competitive gamers

About

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages