Skip to main content

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/core holds 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 core types at the adapter edge. core imports nothing from venue/.
  • 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 core models them.
  • Duplicated code between adapters must be fixed in each copy.

Alternatives considered

  • One large Venue interface. 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.