0004. Venue boundary with capability interfaces
- Status: Accepted
- Date: 2026-09-30
Context
Polymarket Predictions come first, then Polymarket Combos, then a second prediction-market venue (Yeet) whose API docs are not available yet. Venues differ in what they support: Combos use RFQ quotes, and a venue may have no sports feed. The engine and UI should not change shape each time a venue is added.Decision
backend/internal/coreholds venue-agnostic types (Event, Market, Outcome, Book, Order, Fill, Position, Game) and small capability interfaces:Discovery,MarketData,Trading,Portfolio,Sports.- Each venue adapter lives in
backend/internal/venue/<name>/and implements only the capabilities it supports. The engine checks which capabilities a venue offers. - Venue wire types stay inside the adapter package and are converted to
coretypes at the adapter edge.coreimports nothing fromvenue/. - IDs that cross the boundary are namespaced:
pm:<tokenId>,yeet:<id>. - Polymarket signing and EIP-712 code exists once, in
venue/polymarket/signing, shared by the Predictions and Combos adapters. - No other helper packages are shared between adapters. Duplication between sibling adapters is accepted.
- Each adapter uses the same file names for the same concerns:
adapter.go,api.go,auth.go,types.go,ws.go,errors.go.
Consequences
- Adding Yeet means writing an adapter; the engine, API and UI gain a venue filter but no structural change.
- An adapter does not need stub methods for operations it lacks.
- Namespaced IDs cannot collide across venues and show which adapter owns an object.
- Conversion code at each adapter edge is extra work, and some fields a venue exposes
are dropped unless
coremodels them. - Duplicated code between adapters must be fixed in each copy.
Alternatives considered
- One large
Venueinterface. Every adapter would need stubs for unsupported operations, and callers could not tell a stub from a real call. - Use Polymarket types throughout. Fastest for Phase 1, but adding Yeet would touch every layer.
- A shared helper package for all adapters. Couples adapters that change for different reasons; signing is the one exception because the crypto must exist once.