Curva Documentation

A serverless, peer-to-peer football prediction market.

Pears + QVAC + WDK · Tether Developers Cup · MIT · github.com/rajkaria/curva

Overview

Curva lets a group of fans run a real-money prediction market among themselves — no server matching bets, no oracle company calling the result, no custodian holding the money.

Everyone “knows” a prediction market needs three centralized things: a matching engine, an oracle, and a custodian. Curva removes all three. Every peer holds one append-only log of bets; the market only exists in the aggregate of the swarm. Kill any machine — including the one that created the market — and the market keeps trading.

A curva is the curved stand behind the goal where the ultras gather: thousands of fans, no assigned seats, moving as one. No single fan is the crowd; the crowd only exists in the aggregate. Curva is a market built the same way.

How it works

The end-to-end flow of a single terrace (a match market), exactly as npm run demo exercises it, headless and with no network:

  1. Derive — each fan turns a WDK seed phrase into an identity key (signs every message) and a self-custodial USDt wallet.
  2. Open a terrace — a host opens a market for tonight's match and shares an invite key. Others join the swarm.
  3. Trade — fans place bets; the parimutuel pool odds shift live on every screen. Each bet is a signed message appended to that peer's log.
  4. Kill the host — the peer that created the market goes offline. The others keep trading and still converge. There is no host.
  5. Cutoff — at kickoff the market locks. Autobase's deterministic linearization is the single ordered fence; late bets after the fence are dropped.
  6. Resolve — at full time, each device's on-device ASR hears the score from the commentary and pre-fills an attestation. The crowd signs a dual-⅔ quorum; after a dispute window the outcome is final.
  7. Net & settle — the payout manifest is netted to a minimal transfer set; each loser signs their own USDt transfer from their own wallet. Receipts land on every log — everyone's square.

The insight: a parimutuel pool is a CRDT

This is why Curva can be serverless without consensus:

Polymarket needs AWS, an oracle company, and a custodian. Curva needs two phones.

Architecture

Ports-and-adapters throughout: everything money- or consensus-related is pure and fuzz-tested; Pears/QVAC/WDK live behind adapters with in-memory fakes, so the whole protocol is testable headless in Node with no Pear, no model, no wallet, and no network.

PackageResponsibility
@curva/market-kernelPure parimutuel core — odds, payouts, refunds, void. Exact conservation via largest-remainder dust (no treasury).
@curva/terrace-baseSigned-message protocol · deterministic apply() fold · Hyperbee view · cutoff fence · Autobase multi-writer runtime.
@curva/crowd-oracleQuorum math (dual ⅔ + dispute→void) and QVAC ASR score extraction.
@curva/wdk-vaultSeed → identity + wallet · minimal-transfer netting · USDt settlement.
@curva/market-catalogueMarket factories — match-result, total-goals ladder, micro-rounds, first-scorer, correct-score.
@curva/qvac-surfacesThe Gaffer (local LLM commentator) · terrace translate · hunch suggestions.
@curva/steward-escrowTier-2 2-of-3 escrow — steward election, deposit verify, co-signing.
@curva/terrace-uiThe app's tested render layer — view-models + formatters + the single HTML-escaping choke-point.
@curva/simLamport-ordered swarm simulator + adversarial fuzzer.
@curva/e2eThe whole pipeline, headless (npm run demo).
apps/terraceThe Pear desktop app — a thin DOM shell over @curva/terrace-ui.

The three tracks

Each track is structurally load-bearing — remove any one and the product ceases to exist.

Pears — the market

Hyperswarm discovery, an Autobase multi-writer ledger with a deterministic apply fold, a Hyperbee view of market state, the cutoff fence, and pear for deployment. This is the exchange; there is no server.

QVAC — the oracle

On-device speech-to-text over the match commentary extracts the score and pre-fills attestations; a local-LLM “Gaffer” adds commentary; chat is translated locally across 32 languages. Zero cloud AI — a mic in a pub demands local inference.

WDK — the money

One seed derives the HD identity key that signs every message and the self-custodial USDt wallet. Payouts net to a minimal transfer set; each loser signs their own transfer; receipts append to the log.

Identity is a secp256k1 key derived from the WDK seed and signed with noble, which keeps the protocol pure and Bare-runnable — WDK is load-bearing only for moving USDt.

The crowd oracle

At watch-party scale the oracle problem dissolves: everyone is literally watching the answer. Curva makes that safe with a dual ⅔ quorum — an outcome resolves only when it holds two-thirds of both the stake and the writers. This makes it mathematically impossible for two outcomes to both reach quorum, so neither a whale nor a sock-puppet swarm can steer the result.

ASR is a pre-fill assist, never authority — a wrong or unheard score is always one manual tap away from correction. A dispute window (evaluated per-timestamp-batch, not per-event) lets the crowd contest a result; unresolved disputes void the market and refund every stake.

Trust & escrow

Curva is honest about its trust tiers:

What's proven, not asserted

237 tests run in CI — property, fuzz, quorum-safety, view-model, and a full headless end-to-end:

Run & build

# the whole thesis, headless, no external services
npm install
npm run demo

# typecheck + lint + 237 tests (Node ≥20.19 / 22.12 / 24)
npm run check

# the live P2P app (needs the Pear runtime: npm i -g pear)
npm run build && pear run apps/terrace

The demo uses in-memory fakes for the wallet and ASR (clearly labelled in-app), so the entire claim is verifiable without Pear, a QVAC model, a funded wallet, or a network. Swapping in the real WDK/QVAC adapters is a configuration change, not a protocol change.

FAQ

Is there really no server?

No server. Peers discover each other over Hyperswarm and each holds the full append-only ledger. The only external service in real mode is a chain RPC endpoint to broadcast USDt transfers — no backend, no cloud AI, no analytics.

What stops someone double-spending or resolving falsely?

Bets are signed and folded deterministically; the cutoff fence drops late bets; and the dual-⅔ quorum plus dispute→void protects resolution. In adversarial (non-mates) settings, the 2-of-3 escrow tier adds custody guarantees.

Can I run it in a browser?

The live app runs on the Pear runtime, not a plain browser (it uses Bare modules like Autobase and Hyperswarm). A zero-install browser demo of the UI on fake adapters is on the roadmap.