feat: add Hunch venue (parimutuel prediction market on Base, x402)#1150
feat: add Hunch venue (parimutuel prediction market on Base, x402)#1150rajkaria wants to merge 1 commit into
Conversation
Hunch (playhunch.xyz) is a parimutuel prediction market on Base, settling via x402 / EIP-3009 USDC. Adapter mirrors the Myriad pattern: reads (markets/events/ OHLCV/trades/positions/balance) normalize the live agent API; orderbook is emulated from the implied price + pool; createOrder runs the x402 402->sign EIP-3009->200 loop (viem), self-hosted via a Base private key. Market-orders only (cancel/limit/sell unsupported — parimutuel). Registered in index.ts, the server exchange factory, the ExchangeParam enum, and COMPLIANCE.md. Tests: core/test/normalizers/hunch-normalizer.test.ts (47) — binary + N-way mapping, the money-critical outcomeId<->side round-trip, position/balance/OHLCV/ emulated-orderbook. tsc --noEmit clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR Review: VERIFIEDWhat This DoesAdds Hunch as a new PMXT venue adapter for Base/x402 parimutuel prediction markets. SDK consumers can discover Hunch markets through the normal sidecar exchange route ( Blast RadiusNew Consumer VerificationBefore (base branch): POST /api/hunch/fetchMarkets {"params":{"limit":2}}
# base branch: exchange route is absent / hunch is not a supported ExchangeParamAfter (PR branch): curl -X POST http://localhost:3847/api/hunch/fetchMarkets \
-H 'Content-Type: application/json' \
-H 'x-pmxt-access-token: <local token>' \
-d '{"params":{"limit":2}}'Response snippet: {
"success": true,
"data": [
{
"marketId": "bankr-100m-mcap-2026-06-30",
"title": "Will $BNKR reach $100M market cap by June 30, 2026 at 11:59 PM UTC?",
"slug": "bankr-100m",
"outcomes": [
{ "outcomeId": "bankr-100m-mcap-2026-06-30:yes", "price": 0 },
{ "outcomeId": "bankr-100m-mcap-2026-06-30:no", "price": 0 }
],
"status": "active",
"sourceMetadata": { "headline": "$BNKR $100M by June 30 · YES 68¢ / NO 32¢ · 3 bets · $4 pool · closes June 30" }
}
]
}Test Results
FindingsNo blocking findings. PMXT Pipeline Check
Semver Impactminor -- adds a new venue and new exchange capability surface. RiskI verified public market discovery end-to-end. I did not place a real Hunch bet or exercise the x402 signing/payment loop because that would require live funds/private-key side effects; the money path remains covered only by static review and normalizer tests in this run. |
Adds Hunch (playhunch.xyz) as a pmxt venue — unique crypto-native inventory (token market-cap milestones/ladders, up/down, launchpad, date-window markets) settling in USDC on Base.
Market model
Parimutuel (pool-based) — not CLOB, not AMM. Modeled on the Myriad adapter: market-orders only,
fetchOrderBook: 'emulated'(a single level synthesized from the implied price + pool),cancelOrder/ limit / sell unsupported. Reads are keyless; trading is self-hosted via a Base private key.Surface (
core/src/exchanges/hunch/)All reads normalize Hunch's live agent API (
/api/agent/v1/*; OpenAPI at/openapi.json):fetchMarkets/fetchEvents(single-market wrap — Hunch has no event tier) /fetchOHLCV(flat candles from the odds tape) /fetchOrderBook(emulated) /fetchTrades/fetchPositions/fetchBalance.outcomeIdencodes${marketId}:${side}and round-trips back to a Hunch trade side.createOrderruns Hunch's x402 loop:POST /trade→ 402 → sign the EIP-3009TransferWithAuthorization(viem) → re-POSTwithX-PAYMENT→ 200 receipt. Orders > $10 fetch a price-locked quote first. Verified end-to-end against the live 402 challenge (no funds moved).Registration
index.ts(export + registry +Hunch),server/exchange-factory.ts(case "hunch"),server/openapi.yaml(ExchangeParamenum),COMPLIANCE.md.Tests
core/test/normalizers/hunch-normalizer.test.ts— 47 tests: binary + N-way mapping, the money-criticaloutcomeId↔sideround-trip, position/balance/OHLCV/emulated-orderbook.tsc --noEmitclean.Notes for maintainers
hunch/api.tsembeds the live/openapi.json(the 10 ops the adapter drives) — re-run yourfetch:openapito regenerate canonically; I did not rungenerate:sdk:all(maintainer toolchain).HUNCH_PRIVATE_KEY/HUNCH_WALLET_ADDRESS(Base). Hosted-mode trading (your Polygon escrow) is out of scope — Hunch settles on Base via x402 — so it lists as read-only hosted / tradeable self-hosted, like Kalshi.createOrderfrom a Base wallet is the natural live trade test.volume24his0(Hunch reports no 24h split; totalvolumeis the pool size) — a fast-follow on our side can add it.Happy to iterate on anything — thanks @Sammie for the nudge to wire this up. 🤝
🤖 Generated with Claude Code