import { type ReactNode } from "react"; import type { SomniaMarketsClient } from "./createClient.js"; import type { WatchStatus } from "./liveTail.js"; import type { BinaryOrderBook, SpotOrderBook } from "./orders.js"; import type { IndexedMarketCreator, IndexedOracleAdapter, MarketCreatorFilter } from "./marketCreatorAdmin.js"; import type { IndexedOperator, OperatorFilter } from "./operatorAdmin.js"; import type { Portfolio, PortfolioOptions } from "./binary/portfolio.js"; import type { BinaryMarket, Market, MarketFees, MarketType } from "./markets.js"; import type { Candle } from "./candles.js"; import type { Address } from "viem"; import type { LendAccount, LendReserve } from "./lend/types.js"; import type { LiveFill, LiveFundingUpdate, LiveMarket, LiveOrder, TailStatus } from "./store.js"; import type { FundingRateCandle } from "./perp/history.js"; import { type FundingRateSeries } from "./funding.js"; import type { LivePrice, PriceFeedInfo, PriceFeedStatus, PricePoint } from "./priceFeed/types.js"; /** * Provide the SDK's engine tier to the hooks below. Build one exchange * (`new SomniaMarkets(...)`) and pass its `.client` here near the root of your app. * * @category React */ export declare function SomniaMarketsProvider({ client, children, }: { client: SomniaMarketsClient; children: ReactNode; }): ReactNode; /** * The SomniaMarketsClient from the nearest provider. Throws if there isn't one. * * @category React */ export declare function useSomniaMarketsClient(): SomniaMarketsClient; /** * Watch one market while mounted (ref-counted; shared with the data hooks) and * report its watch state — render loading UI off `"hydrating"`. * * @category React */ export declare function useWatchMarket(pool: string | undefined): WatchStatus; /** * Hydrate + hold `user`'s order/fill history while mounted, so the user-scoped * live reads have depth predating the market watches. * * @category React */ export declare function useWatchUser(user: string | null | undefined): void; /** * The live tail's status snapshot (mode, blocks, event counter) — drive a * connection banner off it, or use {@link useIsTailing} for the common boolean. * * @category React */ export declare function useLiveStatus(): TailStatus; /** * True when at least one watch is live (vs idle / hydrating / reconnecting). * * @category React */ export declare function useIsTailing(): boolean; /** * Live trade tape for one pool. Watches the pool while mounted. * * @category React */ export declare function useLiveFills(pool: string | undefined, limit?: number): LiveFill[]; /** * Fills `user` participated in. Watches `pool` while mounted when given; with * `pool === null` it reads across whatever markets other hooks are watching * (pair with useWatchUser for history). * * @category React */ export declare function useLiveUserFills(pool: string | null, user: string | undefined, limit?: number): LiveFill[]; /** * One market by pool address (either kind). Watches the pool while mounted. * * @category React */ export declare function useLiveMarketByPool(pool: string | undefined): LiveMarket | null; /** * One binary market by its BinaryMarket contract address. NOTE: watches are * pool-keyed, so this hook does not open one — it reads whatever a pool-keyed * hook (or explicit watchMarket) on the same page has hydrated. * * @category React */ export declare function useLiveMarketByAddress(addr: string | undefined): BinaryMarket | null; /** * `user`'s orders on one pool. Watches the pool while mounted. * * @category React */ export declare function useLiveUserOrders(pool: string | undefined, user: string | undefined, limit?: number): LiveOrder[]; /** * The locally-materialized resting book of a binary pool (4-sided), updating * the moment an order event lands — no round-trips, no refetch interval. * Watches the pool while mounted. * * @category React */ export declare function useLiveBinaryOrderBook(pool: string | undefined, depth?: number): BinaryOrderBook; /** * The locally-materialized resting book of a binary MARKET, resolved by its * `marketId` (4-sided) — mirrors {@link useLiveBinaryOrderBook} but keyed on the * market rather than the pool. Because a BinaryPool is recycled across markets, * this returns an EMPTY book once the given market is no longer the pool's * current binding, so a stale page never shows the successor market's orders. * Watches the market's pool while mounted (once the market is known to the live * store). * * @category React */ export declare function useLiveBinaryOrderBookByMarket(marketId: string | undefined, depth?: number): BinaryOrderBook; /** * The locally-materialized resting book of a spot pool, updating the moment an * order event lands — no round-trips, no refetch interval. Watches the pool * while mounted. * * @category React */ export declare function useLiveSpotOrderBook(pool: string | undefined, depth?: number): SpotOrderBook; /** * The state one {@link useIndexerQuery} exposes. * * @category React */ export interface IndexerQueryState { /** * Latest successful result — `undefined` until the first response lands; * the previous value is kept while a refetch is in flight or after it fails. */ data: T | undefined; /** True while a request is in flight (initial load and refetches alike). */ loading: boolean; /** The most recent request's failure, or null. Cleared when a new request starts. */ error: Error | null; /** Re-run the query imperatively (e.g. a manual refresh button). */ refetch: () => void; } /** * Run an async indexer read against the context client, re-running when `deps` * change. Errors are captured (not thrown) so a failed indexer read renders as * `error`, not a crash. A superseded request (deps changed, `refetch`, unmount) * is aborted via the `signal` handed to `fn`, and its response is discarded * either way. Client reads take no per-request signal (cancellation is * client-scoped, via `ClientConfig.signal`), so the signal matters when `fn` * does its own fetching — pass it to anything that accepts one. * * **Example** (Running a custom indexer query) * * ```ts * const { data: markets } = useIndexerQuery((c) => c.listBinaryMarkets({ limit: 20 }), []); * ``` * * @category React */ export declare function useIndexerQuery(fn: (client: SomniaMarketsClient, signal: AbortSignal) => Promise, deps: readonly unknown[]): IndexerQueryState; /** * A wallet's binary portfolio (indexer read). Re-runs when `account`/`opts` change. * * @category React */ export declare function usePortfolio(account: string | undefined, opts?: PortfolioOptions): IndexerQueryState; /** * Markets, newest first (indexer read). Pass `marketType` to narrow. * * @category React */ export declare function useMarkets(opts?: { marketType?: MarketType; limit?: number; offset?: number; }): IndexerQueryState; /** * OHLCV candles for one pool + interval (indexer read), oldest first. * * @category React */ export declare function useCandles(pool: string | undefined, intervalSeconds: number, opts?: { limit?: number; from?: number; to?: number; }): IndexerQueryState; /** * Funding settlements for one pool seen by the live tail, OLDEST FIRST (chart order, * matching `SomniaMarketsClient.getLiveFundingUpdates`) — not newest first like * {@link useLiveFills}. Watches the pool while mounted. * * These are the tail's counterpart to the indexed `FundingRateUpdate` series and carry * only what `FundingUpdated` puts on the wire — no `intervalsAccrued`, no covered span. * For a chart, prefer {@link useFundingRateSeries}, which uses these purely as a nudge. * * @category React */ export declare function useLiveFundingUpdates(pool: string | undefined, limit?: number): LiveFundingUpdate[]; /** * 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 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. * * @category React */ export declare function useFundingRateSeries(pool: string | undefined, intervalSeconds: number, window: { from: number; to: number; limit?: number; }): IndexerQueryState>; /** * A market's frozen fee config + running total (indexer read), or null. * * @category React */ export declare function useMarketFees(marketId: string | undefined): IndexerQueryState; /** * Operator directory (indexer read). Pass `owner`/`enabled` to filter, page with `limit`/`offset`. * * @category React */ export declare function useOperators(opts?: OperatorFilter & { limit?: number; offset?: number; }): IndexerQueryState; /** * MarketCreator directory (indexer read) — the operator machinery list. Pass * `owner`/`operatorId`/`venueId` to filter, page with `limit`/`offset`. Each * row carries its nested `series`. * * @category React */ export declare function useMarketCreators(opts?: MarketCreatorFilter & { limit?: number; offset?: number; }): IndexerQueryState; /** * Oracle-adapter directory (indexer read). Pass `owner`/`approved` to filter, * page with `limit`/`offset`. * * @category React */ export declare function useOracleAdapters(opts?: { owner?: string; approved?: boolean; limit?: number; offset?: number; }): IndexerQueryState; /** * Every market the live store knows (spot + perp + binary), from the live tail * — synchronous, memoized. Pair with {@link useWatchMarket}/`watchMarkets` to * keep it populated; unlike {@link useMarkets} this is the zero-round-trip store * view, not an indexer fetch. * * @category React */ export declare function useLiveMarkets(): LiveMarket[]; /** * Watch one asset's price feed (e.g. `"BTC"`, `"ETH"`) while mounted * (ref-counted; shared with the price data hooks) and report its watch state. * * @category React */ export declare function useWatchPrice(asset: string | undefined): PriceFeedStatus; /** * The live current price of one asset, updating the moment a new tick is pushed * — no round-trips, no refetch interval. Watches the feed while mounted. * * @category React */ export declare function useLivePrice(asset: string | undefined): LivePrice | null; /** * The live feed metadata of one asset — pair symbol, quote, decimals, and the * freshness fields (`updatedAtMs` / `sourceUpdatedAtMs` / `resynced`). Watches * the feed while mounted. * * Note this does NOT re-render as a price ages: a stalled feed pushes nothing, * so the store never notifies. Callers rendering an age must drive their own * timer (see {@link PriceFeedInfo.updatedAtMs}). * * @category React */ export declare function useLivePriceFeedInfo(asset: string | undefined): PriceFeedInfo | null; /** * The live tick tape of one asset, newest first. Watches the feed while mounted. * * @category React */ export declare function useLivePriceTicks(asset: string | undefined, limit?: number): PricePoint[]; /** * Every SomniaLend reserve — rates, caps, prices (chain read via the * UiPoolDataProvider aggregate). Errors (surfaced on `error`) when the * client's `config.addresses.lend` is unset. * * @category React */ export declare function useLendReserves(): IndexerQueryState; /** * A SomniaLend account's health factor + positions (chain read). Re-runs when * `account` changes; `undefined` account resolves to `undefined` data. * * @category React */ export declare function useLendAccount(account: Address | undefined): IndexerQueryState;