Skip to Content
Developer HubSDKMigration to v8

Migration Guide: SDK v8.0.0

This guide will help you migrate your application from SDK v7.x to v8.0.0.

Overview

SDK v8.0.0 depends on @azuro-org/toolkit v7.0.0 and carries its model change through the hooks: the protocol resolves outcomes, not conditions. Within one condition, outcomes can independently be Won, Lost, Canceled (voided) or still live — and the SDK now reports them that way.

  • Removed: useResolvedMarkets, BetOutcome.wonOutcomeIds, UseConditionsProps.onlyActiveOrStopped
  • Added: includeHidden on useActiveConditions and useActiveMarkets, plus their own result types UseActiveConditionsResult / UseActiveMarketsResult; the value types of the watched state maps are now exported too — ConditionsStateData, OutcomesStateData, OutcomeStateData and ConditionOutcomeData
  • Changed shape: useActiveConditions and useActiveMarkets are no longer plain UseQueryResults and require the feed providers; useActiveConditions no longer accepts query.select; OutcomesStateData.statesMap holds a different value type
  • Changed without a type error: which hooks filter hidden rows, when a hidden market is revealed, how far per-outcome state from the socket is trusted, voided combo legs, condition/outcome state fallbacks, and the key of the map useBetsSummaryBySelection returns
⚠️

Read the “Behaviour changes with no compile error” section — it is the one that will bite you.

Several of these changes type-check perfectly and silently alter what your UI renders: the “active” hooks drop hidden conditions and outcomes by default while useConditions keeps them, a hidden market is now revealed only by an update that says so, per-outcome state is no longer read from every socket message, a voided combo leg reports isWin: false instead of isWin: null, and useBetsSummaryBySelection is keyed differently. A green tsc does not mean you are done.

ℹ️

Start with the Toolkit v7 Migration Guide — it explains the underlying model (ConditionState reduced to Active | Stopped, MarketOutcome.isWon removed) that everything below builds on.

Breaking Changes

1. useResolvedMarkets removed

The hook is deleted with no stub. It existed to answer “what were this game’s results?” by fetching the conditions that had reached a Resolved state — a state that no longer exists.

Its replacement is the ordinary markets hook with includeHidden: true: once a game is finished, you want everything the game offered, including the markets and outcomes that were hidden while it ran. Each outcome then carries its own result in state.

Before (v7.x):

import { useResolvedMarkets } from '@azuro-org/sdk' const { data: markets } = useResolvedMarkets({ gameId })

After (v8.0.0):

import { useActiveMarkets } from '@azuro-org/sdk' const { data: markets } = useActiveMarkets({ gameId, includeHidden: true })

If you need the raw conditions rather than grouped markets:

import { useActiveConditions } from '@azuro-org/sdk' const { data: conditions } = useActiveConditions({ gameId, includeHidden: true })

includeHidden: true is what makes this the results view: it keeps the markets and outcomes that were hidden while the game ran, which is where the settled and refunded outcomes are.

ℹ️

There is no longer a separate “active markets” view and “resolved markets” view to switch between. One grid serves both — see The recommended integration pattern below.


2. BetOutcome.wonOutcomeIds removed

useBets no longer returns wonOutcomeIds on a bet’s outcomes. It was a condition-level field used to infer whether the bet’s leg won — which is exactly the inference that mispriced voided legs.

Before (v7.x):

type BetOutcome = { selectionName: string odds: number marketName: string game: GameData wonOutcomeIds: string[] | null // removed isLive: boolean isWin: boolean | null isLose: boolean | null isCanceled: boolean } & Selection

After (v8.0.0):

type BetOutcome = { selectionName: string odds: number marketName: string game: GameData isLive: boolean isWin: boolean | null isLose: boolean | null isCanceled: boolean } & Selection

Read isWin / isLose / isCanceled — the SDK already derives them from the per-outcome result.


3. UseConditionsProps.onlyActiveOrStopped removed

The prop filtered conditions down to those whose state was Active or Stopped. Since ConditionState is now exactly { Active, Stopped }, that predicate matches every condition — it had become a no-op.

Before (v7.x):

const { data: conditions } = useConditions({ gameId, onlyActiveOrStopped: true, })

After (v8.0.0):

const { data: conditions } = useConditions({ gameId })

Just delete the prop. If what you actually wanted was “the markets a bettor can act on right now”, that is the default behaviour of useActiveConditions / useActiveMarkets with includeHidden left off.


4. useActiveConditions / useActiveMarkets: new result type, feed providers required, no select

These two hooks now decide visibility themselves, on the live value from the feed, after subscribing to every condition of the game. Three consequences, two of which the compiler will point at.

They are no longer plain UseQueryResults. data is produced after the query, so it is typed separately from the query’s own data:

type UseActiveConditionsResult = { data: ConditionDetailedData[] | undefined } & Omit<UseQueryResult<ConditionDetailedData[]>, 'data'> type UseActiveMarketsResult = { data: GameMarkets | undefined } & Omit<UseQueryResult<ConditionDetailedData[]>, 'data'>

isLoading, isFetching, isPlaceholderData, status, error and refetch are unchanged, and your query options are still forwarded. Only annotations naming the old type break.

useActiveConditions no longer supports query.select, and UseActiveConditionsProps is no longer generic. A select runs inside the query — before the visibility filter — so it would see exactly the hidden rows the hook exists to remove, and its output would then be filtered as if it were still a ConditionDetailedData[]. (useActiveMarkets never accepted a select: its query was already QueryParameter<ConditionDetailedData[]> in v7, and QueryParameter omits select. Nothing changes there.)

// Before (v7.x) const { data } = useActiveConditions({ gameId, query: { select: (conditions) => conditions.filter(myPredicate) }, }) // After (v8.0.0) - shape the raw data yourself const { data: conditions } = useConditions({ gameId, query: { select: (conditions) => conditions.filter(myPredicate) }, })

They require FeedSocketProvider and ConditionUpdatesProvider. Both are already inside AzuroSDKProvider, so nothing to do unless you compose the providers by hand — but if you do and one is missing, this fails at runtime, not at compile time. Check your provider tree before shipping.


5. OutcomesStateData.statesMap holds OutcomeStateData, not OutcomeUpdateData

useOutcomesState used to keep the raw socket message for each outcome. It now keeps its own view of the outcome, and that view has its own type.

Before (v7.x):

type OutcomesStateData = { states: Record<string, OutcomeState> statesMap: Record<string, OutcomeUpdateData> }

After (v8.0.0):

import { type OutcomeStateData } from '@azuro-org/sdk' type OutcomesStateData = { states: Record<string, OutcomeState> statesMap: Record<string, OutcomeStateData> } type OutcomeStateData = { odds: number turnover: string /** `undefined` until an update that can be trusted for it, or a state read, has reported it */ state?: OutcomeState /** `undefined` until the feed has reported it */ hidden?: boolean }

The entry lost conditionState, and its state and hidden became optional. conditionState says how far the message it arrived on can be trusted — the hook applies that itself rather than handing it on, which is behaviour change 4 below — and neither state nor hidden is known until something authoritative has reported it. The wire message keeps the name OutcomeUpdateData and keeps conditionState, so an annotation that meant the socket message is still correct; one that meant a map entry has to move to OutcomeStateData.

ℹ️

OutcomesStateData is the hook’s internal state shape, not its return value: useOutcomesState returns { data, outcomesMap, isFetching }, where data is that states map and outcomesMap is that statesMap. The same holds for ConditionsStateData and useConditionsState, which returns { data, conditionsMap, isFetching }.


Behaviour changes with no compile error

⚠️

Everything in this section compiles unchanged and behaves differently at runtime. Walk through each one against your own screens.

1. hidden conditions and outcomes are dropped by default — in the “active” hooks

useActiveConditions and useActiveMarkets now drop conditions flagged hidden, and hidden outcomes inside the conditions they keep. A condition left with no visible outcome is dropped entirely.

Previously the SDK returned everything and apps filtered at render time. If your app did that filtering itself, it now filters an already-filtered list — harmless, though you can delete it. The breakage is in the other direction: a view that relied on getting everything back now silently renders less.

// running game - hidden markets are not on offer, so the default is what you want const { data: markets } = useActiveMarkets({ gameId }) // finished game - you want everything the game had, including what was hidden while it ran const { data: allMarkets } = useActiveMarkets({ gameId, includeHidden: true })

2. useConditions is a pure data hook, and the conditions query key changed

useConditions filters nothing: it returns everything the feed has for the game, hidden conditions and outcomes included. Visibility can’t be decided there — the feed sends no updates for a condition that was never subscribed, so a row dropped in the fetch could never be revealed afterwards, however alive it turned out to be. That decision moved into the two “active” hooks, which subscribe first and filter second.

If you used useConditions to render a bettor-facing grid, move to useActiveConditions or useActiveMarkets:

// Before - a grid built on raw feed data const { data: conditions } = useConditions({ gameId }) // After - the conditions the game is actually offering const { data: conditions } = useActiveConditions({ gameId })
⚠️

The conditions query key changed — it lost onlyActiveOrStopped and is now [ 'conditions', chainId, gameId, extended ]. Nothing about visibility is part of it, so one cache entry serves every view of a game instead of one per flag combination. Cached entries written by v7 don’t match the new key: expect a refetch on first load after the upgrade, and update any manual queryClient.setQueryData / invalidateQueries / getQueryData call that hard-codes the old shape.

3. A hidden market is revealed by an update that says so, not by any update arriving

hidden on useConditionState / useConditionsState used to clear to false as soon as any socket message arrived for the condition. It is now taken from the condition’s own hidden flag, which the feed sends on every message.

The reason is that an update arriving proves nothing: a market the provider has parked keeps streaming odds for the rest of its life, so “it sent something” is not evidence that it is being offered. Expect fewer markets in the grid than before — deliberately.

Two related shape changes:

  • hidden is now boolean | undefined in conditionsMap, and isHidden is boolean | undefined on useConditionState. undefined means “the feed has not reported it yet” — not “visible”, and specifically not “already revealed”. Only an explicit false closes the latch; if undefined counted as revealed, the latch would close before the feed had said anything. Test !hidden, not hidden === false.
  • Visibility is latched one way, at both levels. Once revealed, a condition or outcome stays in the result and is never hidden again. A market that stops stays in the grid, locked — a grid that reflows while a bettor is reading it, moving the market under their cursor, is worse than one that keeps a market slightly longer than it had to.

4. Per-outcome state and hidden are only read from updates whose condition is Active

useOutcomeState / useOutcomesState used to take state and hidden from every socket message. They now ignore both unless the message’s condition is Active.

An update for an inactive condition reports every one of its outcomes as Stopped, whatever they had actually settled to — so trusting it un-settles won, lost and voided outcomes each time their condition is suspended. Such a message now schedules a re-read from the state endpoint, which is authoritative for per-outcome state, instead of being applied. odds and turnover are real in every message and are still taken from all of them.

⚠️

The consequence to design for: when a condition stops, there is a brief window — one state-endpoint round trip — in which its outcomes still read their previous state. Condition-level locking is unaffected and still immediate, so gate the bet on the condition’s state as well as the outcome’s, and don’t treat a per-outcome Stopped as instantaneous.

The socket message type OutcomeUpdateData carries the new conditionState field if you fold these messages into your own state — apply the same rule.

5. Outcome hidden is latched by the SDK — drop your own latch

Both outcome watch hooks now latch hidden one way themselves, on the socket path and on the state-endpoint path. If your app keeps its own one-way isHidden latch on top of them to stop outcomes flickering in and out as a condition is suspended and re-priced, delete it. Re-hiding no longer happens, by design.

6. A voided combo leg is now isCanceled, not “pending”

Before (v7.x) a voided leg came back as:

{ isWin: null, isLose: null, isCanceled: false }

— indistinguishable from a leg that simply hasn’t settled yet.

After (v8.0.0):

{ isWin: false, isLose: false, isCanceled: true }

Won, lost, voided and pending are now mutually exclusive: a settled leg never reports null, and a leg that is still pending reports isWin: null / isLose: null with isCanceled: false.

⚠️

Any UI that branches on isWin === null to mean “pending” must check isCanceled first.

// Before - a voided leg fell into the "pending" branch if (outcome.isWin === null) { return <Pending /> } // After if (outcome.isCanceled) { return <Refunded /> } if (outcome.isWin === null) { return <Pending /> } return outcome.isWin ? <Won /> : <Lost />

7. Combo totalOdds, possibleWin and payout change for every unredeemed combo

Two separate corrections land on these four figures. Neither is an API change — nothing to update — but screenshots, snapshots and any figures you cache or reconcile against will move.

A voided leg no longer multiplies into the odds. It is refunded, so useBets excludes it. If you are coming from v7.6 or later this already happened there; from earlier, combos containing a voided leg now report lower, correct figures.

A combo is re-priced, voided leg or not. This is new in v8. The feed applies its fee to every outcome’s odds, and a combo is priced by removing that fee per leg and applying it once to the product. The subgraph records the plain product instead, compounding the fee once per leg — so for an unredeemed combo the four figures now report higher, correct values, by more the more legs the bet has. See Combo pricing.

Three shapes are deliberately unchanged: a redeemed bet (its recorded payout is what was actually paid), a combo placed before MARGIN_APPLIED_AT (its leg odds are raw, so the plain product is already right), and a cashed-out bet (paid at the price the bettor took — read cashout). Singles are unaffected either way.

If you reconstruct any of these yourself, use calcComboOdds and pass the bet’s real createdAt — the same legs price differently either side of the fee’s start date.

A combo whose every leg was voided has odds of 1: the stake is simply returned. The same holds for any bet the protocol canceled outright, single or combo — totalOdds is 1 for it, and possibleWin is the stake. Before, a canceled single kept the odds it was placed at.

8. useConditionState / useConditionsState fall back to Stopped

When a condition is absent from the feed, these hooks used to report the removed ConditionState.Removed. They now report ConditionState.Stopped.

// Before const isMissing = state === ConditionState.Removed // After - "not in the feed" and "temporarily not taking bets" are the same state now const isNotBettable = state === ConditionState.Stopped

If you rendered Removed conditions differently from Stopped ones — hiding the first, greying out the second — use isHidden from the hook (fed by condition.hidden) to make that distinction instead.

9. useOutcomeState / useOutcomesState fall back to Stopped

Same change one level down: an outcome absent from the feed used to read as OutcomeState.Canceled and now reads as OutcomeState.Stopped.

⚠️

OutcomeState.Canceled now strictly means voided — with money attached.

If you treated Canceled as “this outcome isn’t in the feed” (a rendering concern), you must stop: it now means the protocol voided the outcome and refunded bets on it. Showing “Refunded” for an outcome that is merely missing, or hiding an outcome that was actually voided, are both wrong.

// Before - Canceled was overloaded if (state === OutcomeState.Canceled) { return null // "not in feed, don't render" } // After if (state === OutcomeState.Canceled) { return <Refunded /> // voided, stake returned } if (state === OutcomeState.Stopped) { return <Disabled /> // not offered right now, or not in the feed }

10. useActiveMarket skips fully settled markets

useActiveMarket — the watch hook that picks which market tab to show and moves off it when it goes inactive — no longer selects a market whose condition is Active but all of whose outcomes are settled. Such a market has nothing left to bet on, so the hook advances to the next one.

If you relied on the previously-selected tab staying put after a market finished, pin the selection yourself rather than reading it from the hook.

11. The single-item watch hooks re-seed when pointed elsewhere

useConditionState and useOutcomeState now re-seed from their props when conditionId / outcomeId change, instead of keeping what they held for the item that has gone. Reusing one component instance across conditions or outcomes is therefore safe.

It matters most for isHidden: visibility is latched, so a reveal the previous item had earned used to carry over to the new one permanently. If your app worked around that — a key to force a remount, or a reset of your own — you can drop it.

12. useBetsSummaryBySelection is keyed by condition and outcome

The map useBetsSummaryBySelection returns was keyed by outcomeId alone. It is now keyed by `${conditionId}-${outcomeId}`.

An outcome is identified by its condition and its outcomeId — that pair is what the protocol keys an outcome on. On its own an outcomeId is not unique across a game, for two independent reasons:

  • v5 markets number their outcomes per condition, from 1 up. Every v5 condition therefore carries the same low ids, so outcome 1 of one condition and outcome 1 of another are unrelated selections — and both collide with the outcome 1 a legacy market takes from the shared dictionaries namespace.
  • legacy markets draw their ids from that dictionary, so an id there always denotes the same selection. But a market that is suspended and re-offered comes back as a second condition carrying the same outcomes, so one game still shows the id twice.

Keyed by outcomeId alone, every one of these shared a single entry: their profit and loss were summed together and each of them read the total back — the wrong figure on all of them, on the results view of a finished game.

Before (v7.x):

<Outcome summary={betsSummary?.[outcome.outcomeId]} />

After (v8.0.0):

<Outcome summary={betsSummary?.[`${outcome.conditionId}-${outcome.outcomeId}`]} />
⚠️

This does not fail to compile. The map is Record<string, string> before and after, so the old lookup type-checks, misses, and yields undefined — the summary just stops rendering. Grep for every read of this hook’s result rather than waiting for tsc to find them.

This is the same key useOutcomesState and useOdds already use, so one helper can address all three maps:

import { type MarketOutcome } from '@azuro-org/toolkit' export const getOutcomeKey = ({ conditionId, outcomeId }: Pick<MarketOutcome, 'conditionId' | 'outcomeId'>) => ( `${conditionId}-${outcomeId}` )

New: includeHidden

// UseActiveConditionsProps { gameId: string | string[] includeHidden?: boolean // default: false extended?: boolean chainId?: ChainId query?: QueryParameter<UseConditionsQueryFnData> // no `select` }

Available on useActiveConditions and useActiveMarkets — the hooks that decide visibility. Defaults to false, i.e. hidden conditions and outcomes are dropped. useConditions has no such prop: it always returns everything.

The rule to apply is simple and it is the only thing in the markets grid that should depend on game state:

While a game is active, hidden conditions and outcomes stay hidden. Once the game is finished, they are shown.

import { useActiveMarkets, useGameState } from '@azuro-org/sdk' import { GameState } from '@azuro-org/toolkit' const { data: gameState } = useGameState({ gameId, initialState: game.state }) const { data: markets } = useActiveMarkets({ gameId, includeHidden: gameState === GameState.Finished, })

Do not gate the whole market grid on game state. There is no longer an “is this game over?” switch that flips the page between a betting view and a results view — because outcomes settle independently, a game can have finished markets and live markets on screen at the same time.

Render one grid, in which each outcome shows its own state:

import { useActiveMarkets, useGameState } from '@azuro-org/sdk' import { GameState, isOutcomeSettled, OutcomeState, type MarketOutcome } from '@azuro-org/toolkit' const Markets: React.FC<{ gameId: string, initialGameState: GameState }> = (props) => { const { gameId, initialGameState } = props const { data: gameState } = useGameState({ gameId, initialState: initialGameState }) // the one thing that depends on game state const { data: markets } = useActiveMarkets({ gameId, includeHidden: gameState === GameState.Finished, }) return ( <> { markets?.map(market => ( market.conditions.map(condition => ( condition.outcomes.map(outcome => ( <Outcome key={`${outcome.conditionId}-${outcome.outcomeId}`} outcome={outcome} /> )) )) )) } </> ) } const Outcome: React.FC<{ outcome: MarketOutcome }> = ({ outcome }) => { if (!isOutcomeSettled(outcome.state)) { // still bettable - disabled while Stopped return ( <button disabled={outcome.state === OutcomeState.Stopped}> {outcome.selectionName} {outcome.odds} </button> ) } if (outcome.state === OutcomeState.Won) { return <div>{outcome.selectionName} — Won</div> } if (outcome.state === OutcomeState.Canceled) { return <div>{outcome.selectionName} — Refunded</div> } return <div>{outcome.selectionName} — Lost</div> }

Use useOutcomeState or useOutcomesState to keep each outcome’s state live over the socket, so an outcome flips to Won / Lost / Refunded in place while the rest of the grid keeps taking bets.


Migration Steps

Step 1: Update dependencies

npm install @azuro-org/sdk@^8 @azuro-org/toolkit@^7 # or yarn add @azuro-org/sdk@^8 @azuro-org/toolkit@^7 # or pnpm add @azuro-org/sdk@^8 @azuro-org/toolkit@^7

Step 2: Grep your call sites

Everything above the divider produces a compile error. The rest are silent, so search for them:

# --- these fail to compile --- # removed hook and its types grep -rn "useResolvedMarkets\|UseResolvedMarketsProps\|UseResolvedMarkets\b" src/ # removed prop - now a no-op, just delete it grep -rn "onlyActiveOrStopped" src/ # removed field on BetOutcome, and removed enum members grep -rn "wonOutcomeIds\|ConditionState.Removed\|ConditionState.Resolved\|ConditionState.Canceled" src/ # a `select` passed to useActiveConditions, and annotations naming the old result type grep -rn "select:" src/ grep -rn "UseQueryResult" src/ # --- these compile fine and change behaviour --- # "pending" branches that a voided leg now falls out of grep -rn "isWin === null\|isLose === null\|isWin == null" src/ # Canceled used as "missing from the feed" grep -rn "OutcomeState.Canceled" src/ # every call that may need includeHidden: true, and every grid still built on raw feed data grep -rn "useConditions(\|useActiveConditions(\|useActiveMarkets(" src/ # your own visibility filters and latches - the SDK owns these now grep -rn "isHidden\|conditionsMap\|outcomesMap\|\.hidden" src/ # hard-coded TanStack Query keys for conditions - the shape changed grep -rn "'conditions'" src/ # a hand-composed provider tree that may be missing the feed providers grep -rn "ConditionUpdatesProvider\|FeedSocketProvider" src/ # condition-level result derivation, removed in toolkit v7 grep -rn "isWon" src/ # every read of the useBetsSummaryBySelection map - its key gained the conditionId grep -rn "useBetsSummaryBySelection" src/

Step 3: Fix the useResolvedMarkets call sites

Replace each with useActiveMarkets({ gameId, includeHidden: true }), then delete the “resolved markets” view: fold it into the single grid described above.

Step 4: Audit every useConditions / useActiveConditions / useActiveMarkets call

First, pick the right hook. A bettor-facing grid belongs on useActiveConditions / useActiveMarkets; useConditions is for raw feed data, a custom select, prefetching, or a view that deliberately wants the hidden rows.

Then, for each “active” call, decide what the screen should show:

  • a running game → leave includeHidden off (the new default)
  • a finished game, a results view, or anything that must reflect everything the game offered → pass includeHidden: true
  • unsure? Drive it off game state: includeHidden: gameState === GameState.Finished

Finally, delete the visibility filtering you were doing at render time — the hook has already done it, and on a better value: yours reads the hidden the fetch reported, the hook’s reads the live one. A row can legitimately come back with hidden: true on it after the feed has revealed it, so re-filtering will hide markets that are on offer.

Step 5: Fix the pending / voided branches

Search results from isWin === null are the dangerous ones. In every such branch, add an isCanceled check before the null check.

Step 6: Re-check anything that reconciles combo payouts

totalOdds and possibleWin returned different values for combos with a voided leg from v7.6 on. If you compare those against your own backend figures, snapshot tests, or cached values, refresh them.

Step 7: Re-key every read of useBetsSummaryBySelection

Trace the map this hook returns down through your component tree — it is usually passed as a prop several levels before anything indexes it — and replace map[outcomeId] with map[`${conditionId}-${outcomeId}`]. Nothing here fails to compile, and a missed site renders no summary at all rather than a wrong one, so the grep is the only thing that will find them.

Step 8: Test

  1. A live game’s market grid — hidden markets should be absent
  2. A finished game — with includeHidden: true, every market is back, each outcome labelled Won / Lost / Refunded
  3. A game with mixed settlement — some markets settled while others still take bets, on one screen
  4. A market that stops while you watch it — it should stay in the grid, locked, and not disappear or reflow the list
  5. A market that was hidden on load and comes back on offer — it should appear once the feed says hidden: false
  6. A settled outcome whose condition keeps sending updates — it must stay Won / Lost / Refunded and not flip back to Stopped
  7. A combo bet with a voided leg — the leg reads “Refunded”, and totalOdds / possibleWin exclude it
  8. A pending bet — still reads as pending, not as refunded
  9. A component instance reused across outcomes or conditions — it must show the new item’s lock and visibility, never the previous one’s
  10. A finished game you have settled bets on — every bet’s profit or loss appears on the selection it was placed on, and on no other. Two markets of the same game that share an outcomeId must show their own figures, not each other’s sum

Migration Checklist

  • npm install @azuro-org/sdk@^8 @azuro-org/toolkit@^7
  • Follow the Toolkit v7 Migration Guide first
  • Replace useResolvedMarkets with useActiveMarkets({ includeHidden: true })
  • Delete every onlyActiveOrStopped prop
  • Stop reading BetOutcome.wonOutcomeIds
  • Move bettor-facing grids off useConditions onto useActiveConditions / useActiveMarkets
  • Add includeHidden: true to every finished-game / results view
  • Drop query.select from useActiveConditions calls — use useConditions for that
  • Replace annotations naming the old UseQueryResult shape with UseActiveConditionsResult / UseActiveMarketsResult
  • Re-point annotations of an outcomesMap entry from OutcomeUpdateData to OutcomeStateData — the entry no longer carries conditionState
  • Confirm FeedSocketProvider + ConditionUpdatesProvider are in your provider tree (free with AzuroSDKProvider) — the active hooks fail at runtime without them
  • Update manual TanStack Query cache reads of the conditions key — its shape changed
  • Delete render-time visibility filtering on top of the active hooks, and any hand-rolled one-way isHidden latch
  • Drop any key-remount or manual reset that stopped useConditionState / useOutcomeState carrying state across items — they re-seed themselves now
  • Test !hidden rather than hidden === falseundefined means “not reported yet”
  • Stop reading per-outcome state from your own socket handling of inactive conditions
  • Check isCanceled before isWin === null everywhere
  • Stop treating OutcomeState.Canceled as “missing from feed”
  • Stop treating ConditionState.Stopped as identical to the old Removed for hiding — use isHidden
  • Re-key every read of the useBetsSummaryBySelection map to `${conditionId}-${outcomeId}`
  • Re-verify combo totalOdds / possibleWin against your own figures
  • Collapse separate “active” and “resolved” market views into one per-outcome grid

Need Help?

  1. Check the SDK Documentation
  2. Read the Toolkit v7 Migration Guide
  3. Check the SDK GitHub repository  for known issues