useConditionsState
The useConditionsState hook is used for maintain updated states for a conditions.
Conditions have a state field that indicates their current state. ConditionState.Active signifies the condition is available for betting, while ConditionState.Stopped indicates it is not accepting bets right now. This hook keeps those states live over the socket and returns them keyed by condition ID — compare against ConditionState.Active to know whether a bet can be placed. For a single condition, useConditionState returns a ready-made isLocked flag.
A condition never carries a result. Since toolkit v7 ConditionState is exactly Active | Stopped —
Resolved, Canceled and Removed are gone. Settlement is tracked per outcome: read
OutcomeState via useOutcomeState /
useOutcomesState, or with
isOutcomeSettled.
A condition that is absent from the feed now reports ConditionState.Stopped — it used to report the
removed ConditionState.Removed. Use the hidden field of conditionsMap to tell a condition the provider pulled off the grid
from one that is merely not taking bets.
Usage
Before utilizing useConditionsState, it is essential to initialize the FeedSocketProvider and ConditionUpdatesProvider:
import {
ChainProvider,
FeedSocketProvider,
ConditionUpdatesProvider,
} from '@azuro-org/sdk'
import { polygonAmoy } from 'viem/chains'
function Providers(props: { children: React.ReactNode }) {
const { children } = props
return (
<ChainProvider initialChainId={polygonAmoy.id}>
<FeedSocketProvider>
<ConditionUpdatesProvider>
{children}
</ConditionUpdatesProvider>
</FeedSocketProvider>
</ChainProvider>
)
}Example of usage: Game markets list (Option A).
Pass the full conditions array to get hidden state without an extra fetch.
import { useConditionsState } from '@azuro-org/sdk'
// conditions: ConditionDetailedData[] from useConditions
const { data: states, conditionsMap } = useConditionsState({ conditions })
// drop the conditions the feed isn't offering
const visibleConditions = conditions.filter(({ conditionId }) => !conditionsMap[conditionId]?.hidden)Subscribe to every condition of the game, hidden ones included, and filter afterwards, as above. The feed sends no updates for a condition that was never subscribed, so a condition you filter out before subscribing can never be shown again — however alive it turns out to be.
useActiveConditions and
useActiveMarkets already do exactly this. Do it by hand
only if you need a grid they don’t cover.
Example of usage: Betslip (Option B).
import { useConditionsState } from '@azuro-org/sdk'
import { ConditionState } from '@azuro-org/toolkit'
import { useMemo } from 'react'
const items = [{...}]
const { data: states, isFetching: isStatesFetching } = useConditionsState({
conditionIds: items.map(({ conditionId }) => conditionId),
})
const isConditionsInActiveState = useMemo(() => {
return Object.values(states).every(state => state === ConditionState.Active)
}, [ states ])Props
Two signatures are supported:
Option A — pass full condition objects (preferred for game markets):
{
conditions: Pick<ConditionDetailedData, 'conditionId' | 'state' | 'hidden'>[]
}Option B — pass IDs only (betslip / ID-only scenarios):
{
conditionIds: string[]
initialStates?: Record<string, ConditionState> // key is conditionId
}Option A is preferred when rendering game markets — it provides initial hidden state without an extra fetch.
When using Option B, initialStates is optional. If it’s not provided, the hook will automatically fetch the initial states. Either way hidden starts out undefined in this mode: neither initialStates nor the state endpoint carries condition-level visibility.
enum ConditionState {
Active = 'Active',
Stopped = 'Stopped',
}Return Value
{
data: Record<string, ConditionState> // key is conditionId
conditionsMap: Record<string, { // key is conditionId
state: ConditionState
hidden?: boolean // undefined until the feed has reported it
}>
isFetching: boolean // flag indicates initial states fetching
}state is taken from every update, so a condition locks and unlocks in real time.
How hidden behaves
hidden says whether the feed is offering this condition right now — as opposed to state, which says
whether it is taking bets. It starts from what the fetch reported and then follows two rules.
It is revealed by an update reporting hidden: false — not by an update arriving. The feed sends the
condition’s own hidden flag on every message and that flag is what the hook reads. An update arriving
proves nothing: a market the provider has parked keeps streaming odds for the rest of its life, so
treating any message as a sign of life puts dead markets back in the grid.
It is latched one way, by design. Once a condition has been reported visible it stays visible, and
nothing hides it again. A market that stops therefore stays in the list, locked, rather than vanishing and
returning as the provider suspends and re-prices it — 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.
Render the lock from state instead.
hidden is boolean | undefined, and undefined means the feed has not reported it yet — not
“visible” and 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.
!conditionsMap[conditionId]?.hidden is the right test for “show it” and treats undefined as visible,
which is what you want for a condition the fetch never flagged. Don’t write
hidden === false to mean “revealed”.
The socket message behind all of this is ConditionUpdatedData, exported from the SDK for consumers
subscribing to the raw feed. It carries the condition’s hidden flag alongside its state:
import { type ConditionOutcomeData, type ConditionUpdatedData } from '@azuro-org/sdk'
type ConditionUpdatedData = {
conditionId: string
state: ConditionState
/** whether the feed is offering this condition right now */
hidden: boolean
gameId: string
isLiveEnabled: boolean
isPrematchEnabled: boolean
isCashoutEnabled: boolean
/** per-outcome payload: outcomeId (a number here, a string in REST), title, currentOdds,
* turnover, potentialLoss, state, hidden */
outcomes: ConditionOutcomeData[]
}If you fold these messages into your own state, apply the same latch: hidden: false reveals for good,
and a message arriving is not itself a reveal.
A refetch of condition states can’t report visibility — the state endpoint carries no
condition-level hidden — so the last known value is carried forward across one. And when the watched
set changes (the feed adds conditions to a running game routinely), conditions that stayed keep what the
socket has already taught the hook; only conditions that left are dropped.