Solvers hooks
React hooks over @symmio/trading-core’s Solvers slice — market catalog, locked params, notional cap, open interest, plus the instant-open / instant-close mutation orchestrators.
Every hook on this landing page is a read. The writes (instant-open / instant-close) live on their own pages linked at the bottom.
Each hook takes an optional solverId and defaults to the connected chain’s solver (enigma on HyperEVM, rasa on Base). useMarkets returns the Market union — narrow on kind for solver-specific fields. Endpoints only the rasa solver serves (readiness, whitelist, uPnL, open interest, price range) are on the Rasa Solver hooks page; see Solvers & Chains for the model.
Import
import {
useMarkets,
useLockedParams,
useNotionalCapAll,
useNotionalCapBySymbolId,
useOpenInterestBySymbolId,
useFundingInfo,
useEstimatedPrice,
calculatePriceImpact,
useSolverRevenue,
useSolverErrorCodes,
useSolverErrorMessage,
useSolverCapabilities,
useSupportsLimitOrder,
useSupportsGroupClose,
useSupportsListingService,
} from "@symmio/trading-react";Reads
useMarkets
Solver-side market catalog. Prefer this over useOnchainContractMarkets for UI catalogs — the solver adds precision / tick metadata.
const markets = useMarkets(); // Market[] — the union; narrow on `kind`
const rasa = useMarkets({ solverId: "rasa" }); // RasaMarket[]Returns UseQueryResult<Market[]> — the normalized SDK market shape (camelCase fields, maxLeverage as a number). Market is a discriminated union EnigmaMarket | RasaMarket on kind; pass a literal solverId ("enigma" / "rasa") to narrow the returned market type to that solver.
useLockedParams
Fetch the solver’s LockedParams for a market + leverage — the CVA / LF percentages required to open at that leverage. Used inside useInstantOpenAuto internally; expose it to render “at this leverage you lock X collateral” UIs.
const locked = useLockedParams({ symbol: "BTCUSDT", leverage: 5 });useNotionalCapBySymbolId
Available liquidity — how much notional the solver still permits for a market. Gate order size on this.
const cap = useNotionalCapBySymbolId({ symbolId: 1n });useNotionalCapAll
Batch — every market’s cap in one call.
const caps = useNotionalCapAll();useOpenInterestBySymbolId
Used vs capped notional per market.
const oi = useOpenInterestBySymbolId({ symbolId: 1n });useFundingInfo
Next-epoch funding for every market in one call — pick a row by symbol. Each row is { symbol, nextFundingRateLong, nextFundingRateShort, nextFundingTime, epochDurationSeconds }. The rates are per-epoch decimal fractions (0.0001 = 0.01%, ×100 for a percent); a positive rate receives funding, a negative rate pays. nextFundingTime is a Unix timestamp in milliseconds (guard < 1e12 as seconds). Does not poll by default — pass query.refetchInterval.
const funding = useFundingInfo({ query: { refetchInterval: 30_000 } });
const btc = funding.data?.find((f) => f.symbol === "BTCUSDT");
const pct = (btc?.nextFundingRateLong ?? 0) * 100; // long-side funding %useEstimatedPrice
Ask the solver what price an open or close would fill at — a read-only simulation of the trade → { estimatedPrice }. Use it to preview the fill price, price impact (calculatePriceImpact) and — for a close — an estimated PnL, before the user submits. Pass the slippage-adjusted request price (what the SDK sends to the solver), not the raw mark; positionType and entry ("open" | "close") pick the direction. Disabled until quantity and price are non-empty. quantity and price are debounced internally (debounceMs, default 350) so typing an amount fires one request once the user settles — pass the raw input, no external debounce needed; set debounceMs: 0 to disable.
const { data } = useEstimatedPrice({
symbolId: Number(market.symbol_id),
quantity: tradeParams.quantity, // leveraged quantity to open / amount to close
positionType,
entry: "open",
price: tradeParams.requestedOpenPrice, // slippage-adjusted; use calculateClosePrice for a close
});
const impact = data
? calculatePriceImpact({ estimatedPrice: data.estimatedPrice, referencePrice: String(markPrice) })
: 0;useSolverRevenue
What the solver earned — protocol-wide by default. symbolId narrows the totals to a single market, and leaving it off is what makes the figure a true aggregate: the reference UI hardcodes market 1 on its overview and therefore under-reports the protocol.
const lifetime = useSolverRevenue(); // every market, lifetime
const day = useSolverRevenue({ timeRange: "24h" }); // every market, trailing 24h
const market = useSolverRevenue({ symbolId: 1, timeRange: "7d" }); // one market onlytimeRange is a closed set — "1h" | "24h" | "7d" | "30d" | "lifetime". The solver validates it and rejects anything else with TimeRange must be one of [1h 24h 7d 30d lifetime]. Omit it and the SDK sends no window at all, letting the solver apply its own default, which is lifetime.
Returns UseQueryResult<SolverRevenue, SymmioRequestError>:
| Field | Type | Notes |
|---|---|---|
totalRevenue | number | Revenue over the window. Always hedgerFeeRevenue + fundingRevenue. |
hedgerFeeRevenue | number | The share earned from hedger fees. |
fundingRevenue | number | The share earned from funding payments. |
recordCount | number | Rows behind the totals — it separates “this window earned nothing” (recordCount > 0, totals 0) from “there is no data for this window” (recordCount === 0). |
Every figure is a plain number in the dollar units the solver already reports — no decimal scaling, so 165.49 means $165.49. That is the opposite of the listing and inventory backends, whose money fields are 18-decimal fixed point; do not run these through formatUnits.
Enigma-only. A rasa-kind solver has no revenue endpoint, so the read fails before the wire with UNSUPPORTED_BY_SOLVER rather than a vendor 404 — a SymmioRequestError with kind: "sdk" and that code. A request that does go out and fails carries FETCH_SOLVER_REVENUE_FAILED, with kind: "api" when the failure came from axios — the normal case, carrying status and responseData — and kind: "sdk" for a non-axios throw. Nothing polls by default; pass query.refetchInterval for a live figure.
Revenue is one of five figures a pools overview shows, and it is not the only vendor involved — see Overview aggregates for which service serves each of them.
useSolverErrorCodes
Fetch the solver’s error-code registry. Cache once, look up by code.
const codes = useSolverErrorCodes();useSolverErrorMessage
Composed — takes an error code (positional), returns the human-readable message.
const msg = useSolverErrorMessage(42);Capabilities
Gate a flow or UI on what the resolved solver declares it supports, so an unsupported solver degrades gracefully instead of erroring. Config-driven (see Solver capabilities); unset flags default to false. All four take an optional solverId / chainId and follow the connected chain’s default solver when omitted.
useSolverCapabilities
The resolved SolverCapabilities object ({ groupClose, limitOrder, listingService }, all definite booleans). listingService is declarative metadata — the listing functions do not gate on it (see Pools listing service).
const { limitOrder, groupClose } = useSolverCapabilities();useSupportsLimitOrder
Boolean shorthand — whether the solver supports LIMIT orders. Gate the limit-order UI (and useLimitOpenAuto, which throws UNSUPPORTED_BY_SOLVER otherwise) on it.
const canLimit = useSupportsLimitOrder();
{
canLimit ? <LimitOrderTab /> : null;
}useSupportsGroupClose
Boolean shorthand — whether the solver supports closing a whole market + side group in one flow.
const canGroupClose = useSupportsGroupClose();useSupportsListingService
Boolean shorthand — whether the chain has the lowcap Pools, i.e. whether it carries a listing backend. Gate the Pools tab on it so the feature hides where it is unavailable instead of erroring at request time.
const hasPools = useSupportsListingService();It is true when the chain carries a listing block, delegating to core’s supportsListingService. Every request useListingMarkets issues resolves the backend through resolveListingService — the throwing form — which is why a read against a chain without a listing backend surfaces as LISTING_NOT_CONFIGURED rather than as a false. Today only HyperEVM has it. See Pools listing service.
Trading flows
Instant Open and Instant Close live on their own pages:
- Instant Open —
useInstantOpen,useInstantOpenAuto,useInstantOpenWithTpSl,useInstantOpens,useInstantOpenQuoteId. - Instant Close —
useInstantClose,useInstantCloseAuto,useInstantCloseBulk,useInstantCloseBulkAuto,useInstantCloses.
Related
- Core Solvers — the underlying actions.
- SYMMIO Contract — on-chain analogs where applicable.
- Pools hooks — the lowcap listing catalog
useSupportsListingServicegates. getSolverRevenue— the core actionuseSolverRevenuewraps.- Errors — solver failures surface as
SymmioRequestErrorkind: "api".