DexterDexter

DexterArchitecture

How PokeDexter's components fit together.

Architecture

PokeDexter is built on a fork of Pokémon Showdown with custom wagering infrastructure layered on top. This page explains how all the pieces connect.

High-Level Overview

┌─────────────────────────────────────────────────────────────────────────┐
│                         POKEDEXTER ARCHITECTURE                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────┐                      ┌──────────────────┐             │
│  │   Browser    │◄────── WebSocket ───►│   Game Server    │             │
│  │   Client     │      (SockJS)        │   Port 8000      │             │
│  │              │                      │                  │             │
│  │ poke.dexter  │                      │ Pokemon Showdown │             │
│  │   .cash      │                      │ + Wager Plugin   │             │
│  └──────┬───────┘                      └────────┬─────────┘             │
│         │                                       │                        │
│         │                                       ▼                        │
│         │                              ┌──────────────────┐             │
│         │                              │ Fake Login Server│             │
│         │                              │   Port 8001      │             │
│         │                              └──────────────────┘             │
│         │                                       │                        │
│         │         ┌─────────────────────────────┘                        │
│         │         │                                                      │
│         ▼         ▼                                                      │
│  ┌─────────────────────┐          ┌─────────────────────┐              │
│  │  Solana Blockchain  │◄────────►│  Dexter Facilitator │              │
│  │  (USDC Transfers)   │          │  x402.dexter.cash   │              │
│  └─────────────────────┘          └─────────────────────┘              │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Components

Game Server (Port 8000)

The core Pokémon Showdown server, responsible for:

  • User connections via SockJS (WebSocket abstraction)
  • Chat rooms and private messages
  • Matchmaking for ladder and challenges
  • Battle simulation (Generations 1-9)
  • Wager plugin for escrow and settlement

Key directories:

pokedexter/
├── server/           # Server code
│   ├── chat.ts       # Chat command routing
│   ├── rooms.ts      # Room management
│   ├── users.ts      # User management
│   ├── sockets.ts    # WebSocket handling
│   └── chat-plugins/
│       └── wager/    # Custom wagering system
├── sim/              # Battle simulation engine
├── data/             # Pokemon data (moves, abilities, etc.)
└── config/           # Server configuration

Fake Login Server (Port 8001)

A lightweight mock authentication server that:

  • Allows instant username selection (no registration)
  • Returns valid assertions for any username
  • Bypasses the official Pokémon Showdown login server

Why fake? The official PS login server requires account creation. For PokeDexter, we want frictionless access - pick a name and play.

// Returns assertion for any requested username
if (act === 'getassertion') {
  const userid = params.userid || 'Guest';
  res.end(userid + ',0,');
}

Browser Client

The web interface users interact with:

  • Static files served via nginx
  • SockJS client for real-time communication
  • Battle renderer with animations
  • Team builder (for non-random formats)

Configuration:

Config.defaultserver = {
  id: 'pokedexter',
  host: 'poke.dexter.cash',
  port: 443,
  prefix: '/showdown',
};

Wager Plugin

Custom chat plugin that adds wagering functionality:

server/chat-plugins/wager/
├── index.ts           # Plugin entry point
├── escrow.ts          # Escrow wallet management
├── wallet-registry.ts # User wallet mappings
├── challenges.ts      # Pending wager challenges
├── settlement.ts      # Battle-end settlement
├── cmd-wallet.ts      # /connectwallet, /mywallet
├── cmd-wager.ts       # /wager command
├── cmd-accept.ts      # /acceptwager command
├── cmd-cancel.ts      # /cancelwager command
└── cmd-list.ts        # /wagers, /allwagers

Dexter Facilitator

External service (x402.dexter.cash) that:

  • Sponsors transaction fees (users don't need SOL)
  • Verifies payment signatures
  • Settles transactions on-chain
  • Tracks all payments for marketplace stats

Solana Blockchain

Where the money actually moves:

  • USDC (SPL token) for all wagers
  • Escrow wallets hold funds during battles
  • Settlement transactions pay winners
  • All transactions publicly verifiable

Data Flow: Wagered Battle

1. Challenge Phase

Player A                     Server                      Player B
    │                           │                            │
    │ /wager PlayerB, 10        │                            │
    ├──────────────────────────►│                            │
    │                           │  Challenge notification    │
    │                           ├───────────────────────────►│
    │                           │                            │
    │                           │  /acceptwager PlayerA      │
    │                           │◄───────────────────────────┤
    │                           │                            │
    │  Escrow created           │  Escrow created            │
    │◄──────────────────────────┼───────────────────────────►│

2. Deposit Phase

Player A                     Server                      Solana
    │                           │                            │
    │  Send USDC to escrow      │                            │
    ├───────────────────────────┼───────────────────────────►│
    │                           │                            │
    │                           │  Check escrow balance      │
    │                           ├───────────────────────────►│
    │                           │◄───────────────────────────┤
    │                           │                            │
    │  Deposit confirmed        │                            │
    │◄──────────────────────────┤                            │

3. Battle Phase

Player A                     Server                      Player B
    │                           │                            │
    │  Battle created           │  Battle created            │
    │◄──────────────────────────┼───────────────────────────►│
    │                           │                            │
    │  Move: Thunderbolt        │                            │
    ├──────────────────────────►│                            │
    │                           │  Move: Earthquake          │
    │                           │◄───────────────────────────┤
    │                           │                            │
    │  Battle updates           │  Battle updates            │
    │◄──────────────────────────┼───────────────────────────►│

4. Settlement Phase

Server                      Solana                   Facilitator
    │                           │                            │
    │  Battle ends              │                            │
    │  Winner: Player A         │                            │
    │                           │                            │
    │  Build settlement TX      │                            │
    ├──────────────────────────►│                            │
    │                           │                            │
    │  Sign with escrow key     │                            │
    ├──────────────────────────►│                            │
    │                           │                            │
    │  Transfer to winner       │                            │
    │  (minus house fee)        │                            │
    │◄──────────────────────────┤                            │
    │                           │                            │
    │  Register x402 event      │                            │
    ├───────────────────────────┼───────────────────────────►│

Configuration Files

Server Config (config/config.js)

exports.port = 8000;
exports.bindaddress = '0.0.0.0';
exports.noguestsecurity = true;  // Allow login without real auth
exports.noipchecks = true;       // Allow same-IP matchmaking

Client Config (config/config.js)

Config.defaultserver = {
  id: 'pokedexter',
  host: 'poke.dexter.cash',
  port: 443,
  httpport: 443,
  prefix: '/showdown',
  registered: true
};

Environment Variables

# Solana
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
USDC_MINT=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
 
# Wagering
HOUSE_CUT_PERCENT=5
HOUSE_WALLET_ADDRESS=<your-wallet>
MIN_WAGER_USD=1
MAX_WAGER_USD=100
 
# Facilitator
FACILITATOR_URL=https://x402.dexter.cash

Security Model

Escrow Isolation

Each wager creates a fresh Keypair. Even if one escrow is compromised, others are unaffected.

Server-Side Keys

Escrow private keys exist only on the server. Users never see them, only the public address for deposits.

No Password Storage

The fake login server doesn't store passwords - there are no passwords. Usernames are ephemeral.

On-Chain Verification

All settlements are Solana transactions. Anyone can verify a payout happened.


Next Steps