Skip to Content
Symmio Trading-SDK — the SDK surface for builders on HyperEVM
ReactUnified Quotes

Unified Quotes hooks

Live, reconciled quote list — the primary abstraction UI code binds to. Composes on-chain reads, pending instant-opens, pending instant-closes, and solver notifications into one reactive stream of UnifiedQuote[].

Read-only page. Every hook here is a read. The writes that produce the pending rows (useInstantOpen*, useInstantClose*) live under Solvers.

Import

import { useManagedQuotes, useGroupedQuotes, useOptimisticQuotesStore, useQuoteUpnlAndPnl, useQuotePlatformFee, useAccountLiquidationPrice, useQuotePriceHistory, } from "@symmio/trading-react";

useManagedQuotes

The orchestrator. Handles:

  1. ReadsgetPartyAOpenPositions, getPartyAPendingQuotes, getInstantOpens, getInstantCloses on a chain-scoped poll.
  2. Notifications — subscribes via useNotifications, folds each frame through applyNotificationToQuotes.
  3. Reconciliation — merges every source via reconcileQuotes with the useOptimisticQuotesStore ledger.
  4. Polling acceleration — switches to a tighter interval (~1.5 s) while any row is mid-transition (shouldAccelerate(quotes) === true); otherwise idles at ~5 s.
  5. Invalidation on notification — debounces + invalidates the on-chain reads so the next poll returns fresh data.
const managed = useManagedQuotes({ partyA: subAccount, live: true, // subscribe to notifications (default: true) }); for (const quote of managed.quotes) { render(quote); }

Parameters

NameTypeDefaultNotes
partyAAddressrequiredSubAccount whose quotes to manage.
livebooleantrueSubscribe to the notifications WS; false for poll-only.
extraAccountsAddress[]?[]Extra addresses to include in the on-chain read set (VAs).
chainIdnumber?config defaultOptional chain override.

Return type

{ quotes: UnifiedQuote[]; isLoading: boolean; isFetching: boolean; socketStatus: SocketStatus; error: SymmioRequestError | null; }

The React hook is the recommended entry point — it wires stores, polling, and WS reconciliation you would otherwise have to compose by hand.

useGroupedQuotes

Groups a UnifiedQuote[] by market + side. Useful for a “positions grouped by symbol” table.

const grouped = useGroupedQuotes({ quotes: managed.quotes });

useOptimisticQuotesStore

Module-level Zustand store — the “pending opens the reconciler still remembers about” ledger. See Stores.

Written by mutations (useInstantOpen* push an entry) and cleared by reconciliation once the row is anchored on-chain. Consumers rarely read the store directly; useManagedQuotes composes it in for you.

Direct access via a selector when you need to render optimistic UI outside the managed list:

const pending = useOptimisticQuotesStore((state) => state.pending);

Per-quote decorators

Small derived hooks that compose reads on a specific quote:

useQuoteUpnlAndPnl

{ upnl, upnlPercent, markPrice } snapshot for a quote — composes on-chain quote + mark price + Muon UPNL.

const { upnl, upnlPercent, markPrice } = useQuoteUpnlAndPnl({ quote });

useQuotePlatformFee

Open + close fee for a quote based on useFeeForUser + quote size.

const { openFee, closeFee } = useQuotePlatformFee({ quote });

useAccountLiquidationPrice

Liquidation price for an account, computed from its balance info + open positions via calculateLiquidationPrice. Pass the position’s VA (quote.vaAddress ?? quote.partyA); lowcap isolates each position into its own single-position VA, so the account’s liq price is that position’s.

const { liquidationPrice, isLoading } = useAccountLiquidationPrice({ account: quote.vaAddress ?? quote.partyA });

liquidationPrice is 18-decimal wei bigint0n when unavailable (no balance / no positions).

useQuotePriceHistory

Subgraph-backed open-price history for a quote → { rows, hasMore }. Each row is a settle-uPnL recompute or funding tick (PRICE_HISTORY_EVENT_TYPES) with newPrice / prevPrice (wei) and a timestamp (seconds). Needs the on-chain quoteId; pass orderDirection: "asc" for an oldest-first timeline.

const { data } = useQuotePriceHistory({ quoteId: 42n, orderDirection: "asc", query: { enabled: quoteId != null } }); const priceChanges = (data?.rows ?? []).filter((r) => r.newPrice !== undefined);
Last updated on