@somnia-chain/markets-sdk


@somnia-chain/markets-sdk / react / useFundingRateSeries

Function: useFundingRateSeries()

useFundingRateSeries(pool, intervalSeconds, window, options?): IndexerQueryState<FundingRateSeries<FundingRateCandle>>

Defined in: packages/sdk/src/hooks.ts:984

A pool's funding-rate rollups over [from, to) at one resolution (3600 | 14400 | 86400), densified onto the grid and oldest-first. The read for a funding chart.

Poll plus nudge: the rollups are re-read when the live tail observes a settlement on this pool, so the tip advances at settlement time rather than on the next poll tick. Callers should not re-implement that — the whole point of this hook.

The nudge waits for the indexer. A settlement arrives on the tail as soon as its block is confirmed, which is before the indexer has processed that block. So the hook reads getSyncStatus about once a second until the indexer's latestProcessedBlock reaches the settlement's block, then re-reads the rollups once. The wait is bounded at 4 seconds in total. At the bound the hook re-reads the rollups anyway, which is a best effort and is never worse than an immediate re-read. The wait stops on unmount and on a pool change, and it makes no request after that. It survives a from/to window roll: the roll issues its own read, but that read can still be pre-settlement, so the wait continues and then re-reads the ROLLED window. A getSyncStatus failure stops the wait and appears as catchUpError; the hook never treats a failed watermark read as coverage. A caller-cancelled wait leaves catchUpError unset.

THE CALLER OWNS THE CLOCK. from/to are required and must be stable across renders: a Date.now() read inside this hook would change the query deps on every render and refetch forever. Snap your window to the grid (Math.floor(now / interval) * interval) and it will be stable between buckets.

Reading the result:

  • avgFundingRate8h is already per-8h. Convert with the helpers in funding.ts (fundingRate1h, annualizedFundingRate) — never by hand in a component.
  • coverage is a 1e18-scaled ratio in [0, 1]. A bucket at rate 0 with LOW coverage is a pause, not a measured zero — hatch it. filled: true marks a slot with no row at all; both cases are coverage: "0", and only filled separates them.
  • Cumulative funding is exact and needs none of that reasoning: realizedFundingPerBase(first.cumulativeFundingStart, last.cumulativeFundingEnd) telescopes across gaps, because the index is flat over uncovered time.

Watch acquisition failures use the configured debug/console warning channel. Use useWatchMarketResult for typed acquisition error UI. History query failures remain in state.error.

Parameters

pool

string | undefined

intervalSeconds

number

window

from

number

to

number

limit?

number

options?

HookChainOptions = {}

Returns

IndexerQueryState<FundingRateSeries<FundingRateCandle>>

Throws

No Markets provider is mounted.