Architecture
The platform consists of four main layers: smart contracts, backend API, matching engine, and frontend.
System Diagram
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ Frontend │─────▶│ Backend │─────▶│ Matcher │
│ (Vue/React)│ │ (NestJS) │ │ (Fastify) │
└─────────────┘ └──────┬───────┘ └──────┬───────┘
│ │
│ ┌────────────────┘
│ │
┌────▼─────▼────┐
│ Blockchain │
│ (EVM Chain) │
└───────────────┘Smart Contracts
| Contract | Purpose |
|---|---|
| ConditionalTokens (CTF) | Core conditional tokens engine — creates conditions, splits/merges positions |
| CTFExchange | Validates signed orders and settles matched fills on-chain |
| MockUmaAdapter | Owner-controlled oracle for market creation and resolution |
| MockCollateral | Mintable ERC-20 test collateral |
| DeterministicWallet | Signer-owned wallet for proxy/safe trading flows |
| PolyProxyFactory | Deterministic proxy wallet factory |
| PolySafeFactory | Deterministic safe wallet factory |
Backend (NestJS)
The backend is the primary API for the frontend. It handles:
- Authentication — SIWE (Sign-In with Ethereum) based auth with JWT tokens
- Market Management — CRUD for market metadata, syncs trading pairs to the matcher
- Trading BFF — Proxies order submission, cancellation, and orderbook queries to the matcher
- User Management — Profiles, usernames, wallet linking
- File Uploads — Market images via Google Cloud Storage
Auth flow: wallet signs a SIWE message → backend verifies → issues JWT access + refresh tokens.
Matcher (CLOB Engine)
The matcher is an internal service that the backend calls. It handles:
- Market Registry — Token pair registration for each market condition
- Order Intake — Validates signed orders (EOA, POLY_PROXY, POLY_GNOSIS_SAFE)
- Price-Time Matching — Matches compatible buy/sell orders
- Settlement — Submits
matchOrders(...)transactions on-chain - Reconciliation — Listens for chain events to confirm fills
WARNING
The matcher is not meant to be called directly by the frontend. All trading requests go through the backend BFF layer.
Data Flow: Placing an Order
- User signs an order in the frontend (EIP-712 typed data)
- Frontend sends the signed order to
POST /markets/:id/orderson the backend - Backend validates the market is open and forwards to the matcher's
POST /orders - Matcher validates the signature, stores the order, and attempts to match
- If a match is found, matcher submits
matchOrders(...)to the CTFExchange contract - Exchange verifies signatures, transfers collateral, and splits/transfers conditional tokens
- Matcher reconciles the fill from on-chain events
Database Architecture
Both the backend and matcher use PostgreSQL with Prisma ORM.
| Database | Service | Contains |
|---|---|---|
| Backend DB | NestJS backend | Users, markets, comments, sessions |
| Matcher DB | Fastify matcher | Token pairs, orders, fills, events |