> For the complete documentation index, see [llms.txt](https://serotolabs.gitbook.io/tradeclash/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://serotolabs.gitbook.io/tradeclash/technical-documentation/architecture.md).

# System Architecture

Trade Clash is a multiplayer auction game with real-time bidding, a 3D globe interface, and live Polymarket data. This page covers the technical systems that make it work.

***

## Stack Overview

| Layer                | Technology                               |
| -------------------- | ---------------------------------------- |
| **Frontend**         | React 18, TypeScript, Vite, Tailwind CSS |
| **3D Globe**         | Three.js, Globe.gl                       |
| **State Management** | Zustand, TanStack Query                  |
| **Animation**        | Framer Motion                            |
| **UI Components**    | Radix UI, Lucide icons                   |
| **Backend**          | FastAPI, SQLAlchemy                      |
| **Database**         | PostgreSQL                               |
| **Real-time**        | WebSocket                                |
| **Wallet** (Phase 2) | wagmi, viem (Base L2)                    |

***

## Auction Server

The auction server manages the core game loop: rooms, timers, bids, and reveals.

**Room management**: Rooms are persistent containers for 2-4 players. Players join and leave between lots. The server tracks room state, player connections, and lot rotation.

**Timer authority**: All 30-second street timers are server-authoritative. The client displays the countdown, but the server decides when a street ends. Timeout defaults to $0 bid. No client-side manipulation possible.

**Bid validation**: Bids must be non-negative. Bids are sealed — stored server-side and revealed only when the street timer expires. The server calculates first-place win checks after each street.

**Reveal calculation**: After Street 3 (or after a first-place win), the server exposes all 7 positions, calculates trueValue, determines the winner, and computes profit/loss.

***

## WebSocket Flow

Real-time communication between client and server follows this event sequence:

```
Client                          Server
  |-- join_room ----------------->|
  |<-- room_state (players, lot) -|
  |                               |
  |<-- street_start (info) -------|   Street 1
  |-- submit_bid (amount) ------->|
  |<-- bids_revealed (all bids) --|
  |                               |
  |<-- first_place_check ---------|   (if applicable)
  |                               |
  |<-- street_start (+ shared) ---|   Street 2
  |-- submit_bid (amount) ------->|
  |<-- bids_revealed (all bids) --|
  |                               |
  |<-- street_start (+ shared) ---|   Street 3
  |-- submit_bid (amount) ------->|
  |<-- bids_revealed (all bids) --|
  |                               |
  |<-- reveal (all positions, ----|   Reveal
  |    trueValue, winner, profit) |
  |                               |
  |<-- lot_cooldown --------------|   ~10s
  |<-- new_lot_dealt -------------|   Next lot
```

Connection drops are handled gracefully — if a player disconnects mid-street, their bid defaults to $0. They can rejoin the room between lots.

***

## Lot Curation Pipeline

Lots are assembled from live Polymarket data:

```
Polymarket API → Trending markets → Admin selection → Position bundling → trueValue calculation → Database storage → Lot rotation
```

1. **Pull**: Fetch active markets, prices, and resolution timers from Polymarket API
2. **Select**: Admin picks 7 positions from trending markets
3. **Bundle**: Assign category based on market type, set payout range (2-3x wider than trueValue position)
4. **Calculate**: `trueValue = sum of (currentPrice - entry) × size`
5. **Store**: Lot saved to PostgreSQL with positions, trueValue, category, payout range, creation timestamp
6. **Rotate**: Lots enter the active pool for rooms to deal

Positions are snapshot at curation time. Polymarket prices may move after curation, but the lot's trueValue is fixed.

Target: 15+ active lots in rotation.

***

## Globe Rendering

The 3D globe is rendered with Three.js via Globe.gl:

* **Low-poly Earth model** — distinctive aesthetic, consistent performance across devices
* **Region highlighting** — subtle glow in category color, not harsh overlays
* **Active auction** — pulsing orange ring on the lot's region
* **Reveal flash** — brief green (profit) or red (overpay) on the region
* **Camera** — smooth pan to lot region on street start, ambient rotation between lots

The globe also serves as the dashboard surface — Polymarket market activity visualized by region when no auction is active.

***

## Database Schema (Simplified)

```
rooms
  id, status, player_count, current_lot_id, created_at

lots
  id, category, payout_range, true_value, positions (JSONB), created_at, status

auctions
  id, room_id, lot_id, started_at, ended_at, winner_id

bids
  id, auction_id, player_id, street, amount, submitted_at

players
  id, handle, session_profit, lifetime_profit, created_at
```

***

## Phase 2 Additions

* **Wallet integration**: wagmi + viem for Base L2 wallet connection
* **USDC settlement**: Winner pays bid amount in $SIM or USDC. On-chain transaction.
* **Player-created lots**: Creator stakes $SIM/USDC. Bidders bid against the creator's lot.
* **On-chain posting**: Lot positions, bids, and results posted to Base for verifiability
* **Creator identity**: Anonymous during play, revealed at the reveal screen


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://serotolabs.gitbook.io/tradeclash/technical-documentation/architecture.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
