Skip to main content

System Architecture

Kuest is built on a modern, serverless architecture that combines Next.js App Router, Polygon blockchain, and Supabase for a scalable, production-ready prediction market platform.

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                     User Interface Layer                     │
│  Next.js 16 App Router • Server Components • React 19       │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                     Application Layer                        │
│  • Trading Logic        • Portfolio Management               │
│  • Order Execution      • Market Data                        │
│  • Authentication       • Admin Operations                   │
└─────────────────────────────────────────────────────────────┘

┌──────────────────┬──────────────────┬──────────────────────┐
│   Blockchain     │   Database       │   External APIs      │
│   (Polygon)      │   (Supabase)     │   (Kuest CLOB)       │
├──────────────────┼──────────────────┼──────────────────────┤
│ • CTF Contracts  │ • PostgreSQL     │ • Order Matching     │
│ • Exchange       │ • Events         │ • Market Data        │
│ • USDC Token     │ • Orders         │ • Price Feeds        │
│ • UMA Oracles    │ • Users          │ • Trading History    │
│ • Safe Wallets   │ • Bookmarks      │                      │
└──────────────────┴──────────────────┴──────────────────────┘

Tech Stack

Frontend Framework

Next.js 16

App Router with Server Components, Server Actions, and Parallel Routes for optimal performance

React 19

Latest React features with Suspense, Transitions, and Server Components

TypeScript

Full type safety across the entire application

Tailwind CSS 4

Utility-first CSS with custom theme configuration

Blockchain Layer (Polygon)

Kuest currently runs on Polygon Amoy testnet with mainnet deployment coming soon. All contracts and infrastructure are production-ready.

Smart Contracts

ContractAddressPurpose
Conditional Tokens0x4682...A9C7ERC-1155 tokens representing YES/NO outcomes
CTF Exchange0xB559...61cbStandard binary markets order matching
Neg Risk Exchange0xef02...24F5Negative risk markets (e.g., “Who will NOT win?”)
UMA CTF Adapter0x2008...bf8Oracle adapter for outcome resolution
UMA Neg Risk Adapter0x7242...d76Oracle adapter for negative risk markets
USDC Token0x41E9...7582 (testnet)Collateral token for trading

Blockchain Integration

// Core blockchain libraries
import { wagmi } from '@reown/appkit-adapter-wagmi'  // Wallet connection
import { viem } from 'viem'                           // Contract interactions
import { polygonAmoy } from '@reown/appkit/networks'  // Network configuration
Key Features:
  • Reown AppKit: WalletConnect v2 integration for MetaMask, Rainbow, Coinbase Wallet, etc.
  • Safe Wallet Support: Gnosis Safe integration for multi-sig wallets
  • EIP-712 Signatures: Gasless order signing with typed data
  • Contract Reads: Real-time fee rates and referral data from chain

Database Layer (Supabase)

PostgreSQL database with Drizzle ORM for type-safe queries:

Database Schema

events table stores prediction markets:
CREATE TABLE events (
  id UUID PRIMARY KEY,
  slug TEXT UNIQUE NOT NULL,
  question TEXT NOT NULL,
  description TEXT,
  condition_id TEXT NOT NULL,
  end_date TIMESTAMP,
  resolution_date TIMESTAMP,
  resolved BOOLEAN DEFAULT false,
  outcome INTEGER,
  uma_request_tx_hash TEXT,
  uma_request_log_index INTEGER,
  created_at TIMESTAMP DEFAULT NOW()
);
  • Stores market metadata, condition IDs for blockchain
  • UMA oracle tracking for resolution
  • Category tags and visibility settings

Storage

  • Supabase Storage: Market images, logos, and user avatars
  • S3-Compatible: Alternative to Supabase Storage for self-hosting

External APIs

Kuest CLOB (Central Limit Order Book)

// Trading authentication
const credentials = {
  address: process.env.KUEST_ADDRESS,
  apiKey: process.env.KUEST_API_KEY,
  apiSecret: process.env.KUEST_API_SECRET,
  passphrase: process.env.KUEST_PASSPHRASE,
}
Shared Infrastructure:
  • All forks connect to the same order book
  • Shared liquidity across all deployments
  • Real-time market data and price updates
  • Order matching and execution
  • Historical trades and volume
API Endpoints:
  • POST /orders - Place limit/market orders
  • DELETE /orders/:id - Cancel orders
  • GET /orderbook - Real-time order book
  • GET /markets - Market data and prices
  • GET /trades - Trade history
Important: All forks must authenticate with Kuest CLOB. Running an independent order matching engine requires a commercial agreement.

Component Architecture

Application Structure

src/
├── app/                    # Next.js App Router
│   ├── [locale]/          # Internationalized routes
│   │   ├── (platform)/    # Main app pages
│   │   ├── admin/         # Admin panel
│   │   └── api/           # API routes
│   └── layout.tsx         # Root layout
├── components/            # React components
│   ├── ui/               # Base UI components
│   └── docs/             # Documentation components
├── lib/                   # Core business logic
│   ├── db/               # Database queries (Drizzle)
│   ├── orders/           # Order signing and validation
│   ├── trading-auth/     # CLOB authentication
│   └── uma.ts            # UMA oracle integration
└── providers/            # React context providers

Key Components

Order Flow:
  1. User creates order in UI (market/limit)
  2. Order parameters validated client-side
  3. EIP-712 signature generated (gasless)
  4. Order submitted to Kuest CLOB
  5. CLOB matches order against orderbook
  6. Settlement executed on-chain (CTF Exchange)
  7. Database updated with order status
Files:
  • src/lib/orders/signing.ts - EIP-712 order signing
  • src/lib/orders/validation.ts - Order validation rules
  • src/lib/exchange.ts - Exchange contract interactions
Data Pipeline:
  1. Sync Jobs (/api/sync/*) run every 5 minutes
  2. Fetch market data from Kuest CLOB
  3. Update database with latest prices/volumes
  4. Generate chart data and statistics
  5. Cache results with Next.js Data Cache
Market Types:
  • Binary markets (YES/NO outcomes)
  • Negative risk markets (exclusion logic)
  • Recurring markets (crypto prices, Nasdaq, social metrics)
  • Sports markets (live events)
Files:
  • src/app/api/sync/ - Cron job endpoints
  • src/lib/db/queries/event.ts - Market queries
Auth Flow:
  1. User connects wallet (Reown AppKit)
  2. Sign-in-with-Ethereum (SIWE) challenge
  3. User signs message with wallet
  4. Better Auth creates session
  5. Session stored in database + cookie
Trading Authentication:Separate from web auth - encrypts CLOB credentials:
// Encrypt and store trading credentials
const encrypted = await encryptTradingCredentials({
  apiKey: userApiKey,
  apiSecret: userApiSecret,
  passphrase: userPassphrase,
})
Files:
  • src/lib/auth.ts - Better Auth configuration
  • src/lib/trading-auth/ - CLOB authentication
Resolution Process:
  1. Market reaches end date
  2. Admin/bot proposes outcome to UMA oracle
  3. UMA initiates challenge period (2 hours default)
  4. Anyone can dispute with bond
  5. If no dispute, outcome settles
  6. If disputed, UMA governance votes
  7. Winning outcome pushed on-chain
  8. Users redeem winning shares
Oracle Integration:
// Build UMA propose URL
const proposeUrl = buildUmaProposeUrl({
  uma_request_tx_hash: market.uma_request_tx_hash,
  uma_request_log_index: market.uma_request_log_index,
}, 'Kuest')  // Project name
Files:
  • src/lib/uma.ts - UMA URL builders
  • src/lib/contracts.ts - UMA adapter addresses

Data Flow

Trading Flow

1

Order Creation

User fills out order form (amount, price, side, outcome)
2

Client Validation

Validate sufficient balance, price bounds, amount limits
3

EIP-712 Signing

Generate typed signature (no gas required)
4

CLOB Submission

Submit signed order to Kuest CLOB API
5

Order Matching

CLOB matches against existing orders in orderbook
6

On-Chain Settlement

Execute matched trades on CTF Exchange contract
7

Database Update

Record order and fills in local database
8

UI Update

Real-time updates to portfolio, positions, and PnL

Market Sync Flow

┌──────────────┐
│ Vercel Cron  │  Every 5 minutes
└──────┬───────┘

┌──────────────────────────────────┐
│  /api/sync/markets               │  Fetch market list
│  /api/sync/prices                │  Update current prices
│  /api/sync/volume                │  Sync 24h volume
│  /api/sync/orderbooks            │  Update orderbook depth
│  /api/sync/charts                │  Generate price charts
└──────┬───────────────────────────┘

┌──────────────┐     ┌──────────────┐
│ Kuest CLOB   │────>│  Supabase    │
│  API Data    │     │   Database   │
└──────────────┘     └──────────────┘

┌──────────────────────────────────┐
│  Next.js Data Cache (ISR)        │
│  Revalidate: 60s                 │
└──────────────────────────────────┘

Infrastructure Options

Best for: Quick deployment, zero maintenance

Pros

  • One-click deployment
  • Automatic scaling
  • Built-in CDN
  • Integrated database
  • Free tier available

Cons

  • Vendor lock-in
  • Usage-based pricing
  • Limited customization
Components:
  • Vercel: Next.js hosting, serverless functions, cron jobs
  • Supabase: PostgreSQL, Storage, Auth (optional)
  • Revalidation: ISR with 60s cache

Option 2: Docker Self-Hosted

Best for: Full control, cost optimization

Pros

  • Complete control
  • Fixed costs
  • Custom infrastructure
  • No vendor lock-in

Cons

  • Manual maintenance
  • Requires DevOps knowledge
  • Scaling complexity
Requirements:
  • PostgreSQL database (self-hosted or managed)
  • S3-compatible storage (MinIO, AWS S3, Backblaze B2)
  • External cron scheduler
  • Reverse proxy (Nginx, Traefik)

Option 3: Kubernetes

Best for: Enterprise deployments, high availability

Pros

  • High availability
  • Auto-scaling
  • Multi-region support
  • Production-grade

Cons

  • Complex setup
  • Higher costs
  • K8s expertise required
Manifests provided for:
  • Deployment with replicas
  • Service and Ingress
  • ConfigMaps and Secrets
  • CronJob for sync tasks
See Deployment Options for detailed guides on each infrastructure option.

Performance Optimizations

Server-Side Rendering (SSR)

  • Market pages rendered on-demand
  • User-specific data fetched server-side
  • Parallel data loading with React Suspense

Incremental Static Regeneration (ISR)

// Revalidate market list every 60 seconds
export const revalidate = 60

const markets = await fetchMarkets()

Client-Side Caching

  • React Query for API data
  • Zustand for global state
  • LocalStorage for user preferences

Database Optimization

  • Indexed queries on high-traffic tables
  • Materialized views for complex queries
  • Connection pooling with Supabase

Security Considerations

Authentication

  • Wallet-based auth (SIWE)
  • Encrypted trading credentials
  • Session management with Better Auth
  • CSRF protection on mutations

API Security

  • Rate limiting on public endpoints
  • CRON_SECRET for scheduled jobs
  • Input validation with Zod
  • SQL injection prevention (Drizzle ORM)

Smart Contracts

  • Audited UMA oracle contracts
  • EIP-712 typed signatures
  • On-chain fee enforcement
  • Immutable condition IDs

Infrastructure

  • HTTPS only (enforced)
  • Environment variable encryption
  • Sentry error monitoring
  • Automated dependency updates

Scalability

Current Limits

  • Vercel Free Tier: 100GB bandwidth, 100 serverless function hours
  • Supabase Free Tier: 500MB database, 1GB storage, 2GB bandwidth
  • Order Rate: Limited by CLOB API rate limits

Scaling Strategies

1

Optimize Database Queries

Add indexes, use materialized views, implement pagination
2

Upgrade Infrastructure

Vercel Pro (20/mo)+SupabasePro(20/mo) + Supabase Pro (25/mo) for higher limits
3

Add Caching Layers

Redis for hot data, CDN for static assets
4

Horizontal Scaling

Move to Kubernetes with multiple replicas and load balancing

Monitoring & Observability

Built-in Monitoring

  • Vercel Analytics: Traffic, performance, errors
  • Sentry: Error tracking and alerting
  • Supabase Dashboard: Database performance, query stats

Custom Metrics

// Track trading metrics
import { track } from '@vercel/analytics'

track('order_placed', {
  market: eventId,
  side: 'buy',
  outcome: 'yes',
  amount: orderAmount,
})

Next Steps

Now that you understand the architecture:

Build docs developers (and LLMs) love