Mr. Doge
Mr. Doge SDK

Usage

Adapters mapping real Mr. Doge SDK responses onto mrdoge-ui component props.

Mr. Doge SDK

Small, pure functions from a real @mrdoge/protocol response to a component's plain props: type-checked, so a schema change fails to compile instead of silently going stale. They live in lib/mrdoge-adapters/, named for this specific integration, and are the ones used throughout every example on this site. Integrating a different data provider? Your own lib/<provider>-adapters/ directory, following the same pattern, is the way. A new page here too, PRs welcome.

See Installation for setting up @mrdoge/react, the hooks package that feeds these adapters real data.

Match Card

Maps a real matches.get() response (plus a market from odds.list()) onto Match Card's props.

pnpm dlx shadcn@latest add https://mrdoge.co/r/mrdoge-match-card-adapter.json

movementById is optional throughout: pass useOddsMovement(market)'s result to color options as prices change (green/red), or omit it and options render without any color change.

Match Highlight

matchToMatchHighlightProps maps a real matches.get()/matches.subscribe() response onto Match Highlight's props, including the minute/stoppage/elapsedSeconds/referenceTime fields that drive its live ticking clock. Cards and corners are soccer-specific; other sports get no stats row rather than misleading zeros.

matchesToCompetitionMatches is separate: a pure mapping from a matches.list({ competitionIds, date }) response onto competitionMatches, excluding the match you're already viewing and sorting by kickoff time. Running that query lazily (only once the dropdown first opens) is the caller's job, same as fetching itself; see The competition dropdown.

pnpm dlx shadcn@latest add https://mrdoge.co/r/mrdoge-match-highlight-adapter.json

Match Timeline

Maps a real matches.get()/matches.subscribe() response onto Match Timeline's entries prop, filtered to goals, cards, penalties, and half/full-time, most-recent-first. Full-time is synthesized from match.status/stats rather than a specific timeline event, since there's no single event that reliably marks a match as truly over once extra time is possible.

pnpm dlx shadcn@latest add https://mrdoge.co/r/mrdoge-match-timeline-adapter.json

Stats List

statsToStatsListEntries maps match.stats onto Stats List's entries prop. MatchStats is a discriminated union per sport, so this switches on stats.sport: soccer has the richest set (possession, shots, corners, cards, tackles, throw-ins, goal kicks, woodwork hits, penalty kicks, ...); american football, baseball, ice hockey, and handball currently have no comparable home/away stats in the protocol beyond score and clock, so those return an empty array.

matchToPlayerStatsListEntries is separate: the top player per side (soccer only) for shots, shots on target, and woodwork hits, from match.stats's per-player arrays. Returns empty unless match.timeline has at least one player-attributed event, a proxy for "this match has player-level tracking at all."

pnpm dlx shadcn@latest add https://mrdoge.co/r/mrdoge-stats-list-adapter.json

Odds Selector

SOCCER_UNDER_OVER posts one market per threshold (0.5, 1.5, 2.5, ...) instead of one market total. toOddsLines pairs each into a row, sorted by threshold, for Odds Selector's lines prop. pickMostBalancedMarket picks the closest-to-even Over/Under pair as a single representative line, e.g. for the Odds Board example, instead of an arbitrary, often lopsided, first market.

pnpm dlx shadcn@latest add https://mrdoge.co/r/mrdoge-odds-selector-adapter.json

Bet Slip

Builds a BetSlipPick directly from a real match, one of its markets, and a selected line id. A pick is basically a selected odds line. For Bet Slip's picks. Also populates home/away from the match's teams, so BetSlipPickRow can render team crests.

pnpm dlx shadcn@latest add https://mrdoge.co/r/mrdoge-bet-slip-adapter.json

Conflicts

Some selections are mutually exclusive on the same match: any Match Result pick rules out the entire Double Chance market, Over 4.5 rules out Under 1.5 in Total Goals, and so on. getConflictingIds checks a set of selections against every available candidate and returns the ids incompatible with at least one of them; getConflictingPickIds does the same directly against an existing BetSlipPick[], for consumers without live Market data on hand (e.g. picks loaded from storage).

What to do with a conflicting id is entirely up to you: feed it into Odds Selector's disabledIds to block the click before it happens, or into Bet Slip's conflictingPickIds to flag an already-added pick instead. The adapter only tells you what conflicts, never what to do about it.

pnpm dlx shadcn@latest add https://mrdoge.co/r/mrdoge-conflict-adapter.json

Three rule families, scoped to the same match:

  • Match Result ↔ Double Chance: Double Chance is just two of Match Result's three outcomes combined, so the two markets describe overlapping information about the same result rather than independent events. Any Match Result selection blocks the entire Double Chance market, and vice versa, not just the specific pairs that are outright impossible.
  • Over/Under threshold overlap: Over-at-T1 and Under-at-T2 in the same Totals market conflict once T1 >= T2 (Under 1.5 + Over 4.5 can never both be true; Over 1.5 + Under 4.5 can). Same-side pairs at different thresholds conflict too, e.g. Over 1.5 + Over 2.5: the higher threshold winning always means the lower one wins too, so it's never a genuinely new combination.
  • Both Teams to Score ↔ low Totals: BTTS "Yes" conflicts with Under 1.5 goals or lower (scoring twice needs at least 2 goals).

On this page