getListingMarketDetail
Fetch one pool’s public detail — its aggregate stats and the inventory position behind it. This is the read a whole pool page is built on: the same response feeds the stats cards and, through toPoolPositions, the positions table, so a pool page costs one request rather than two.
import { getListingMarketDetail, ListingDepositChainId, toPoolPositions } from "@symmio/trading-core";
const detail = await getListingMarketDetail(config, {
tokenContractAddress: "0x800822d361335b4d5F352Dac293cA4128b5B605f",
depositChain: ListingDepositChainId.BASE,
});
const rows = toPoolPositions(detail);A pool is addressed by its token and its deposit chain. Neither identifies a pool alone — the same token contract can be listed from more than one chain — so both parameters are required.
Public: no bearer token. Listed pools report live inventory balances; a delisted pool returns cached remaining
token and USDC balances with tvl fixed at zero, which is the backend’s documented behavior rather than missing data.
Parameters
chainIdnumberoptionalTarget chain id. Defaults to the config’s defaultChainId. Selects which chain’s listing backend is used, and is
folded into the query key.
tokenContractAddressstringrequiredThe pool’s token contract address — its id in the listing API. An EVM 0x… address, or a Solana base58 address for
a Solana-deposited listing, which is why this is string and not viem’s Address.
depositChainListingDepositChainIdrequiredThe chain the token was deposited on. Take it from the catalog row’s chainId.
Returns
ListingMarketDetail. Money and rate fields are bigint at LISTING_VALUE_DECIMALS (18) — and recall that a descaled rate is already a percentage (1e18 = 1%) while a descaled money field is USD (1e18 = $1). null means the backend reported no value, which is not zero.
tokenContractAddressstringThe pool’s token contract address.
depositChainListingDepositChainIdChain the token lives on and its deposit was made on.
tokenNamestringToken display name.
tokenTickerstring | nullToken ticker, or null when the backend has none.
tokenDecimalnumberToken decimals.
symbolIdnumber | nullSolver market id, or null when the pool is not tradable yet.
marketStatusListingMarketStatusWhere the pool sits in the listing lifecycle.
maxLeveragenumberMaximum leverage, as a whole multiplier.
buybackRationumberShare of revenue routed to token buybacks, as a percentage (50 = 50%).
listingTimenumber | nullWhen the market went live, Unix seconds.
agenumber | nullPool age in seconds, or null before listing.
activeLpsnumberNumber of distinct LPs in the pool.
tvlbigint | nullTotal value locked, USD. 0 for a delisted pool by design.
totalUsdcInPoolbigintCollateral held by the pool, USD.
totalTokenInPoolbigintPool token held by the pool, in the token’s own units.
maintenanceFeesbigintAccrued maintenance fees, USD.
rewardsListingApyWindowsLP rewards per window, USD.
solverRevenueListingApyWindowsSolver revenue per window, USD.
apyListingApyWindowsHeadline APY per window, as a percentage.
tvlDrivenApyListingApyWindowsAPY attributed to TVL growth, per window.
priceDrivenApyListingApyWindowsAPY attributed to token price movement, per window.
longPositionPoolPosition | nullThe pool’s aggregate long side, or null when the backend reported none.
shortPositionPoolPosition | nullThe pool’s aggregate short side, or null when the backend reported none.
toPoolPositions
A pool’s inventory is not a list of trades — the backend reports one aggregate per side. toPoolPositions folds a detail into the rows a positions table renders, long first, then short. It is a pure reshape, so it costs nothing beyond the detail you already fetched.
const rows = toPoolPositions(detail);
// [{ side: PoolPositionSide.LONG, size, value, avgOpenPrice, upnl },
// { side: PoolPositionSide.SHORT, size, value, avgOpenPrice, upnl }]Sides the backend reported nothing for are omitted, so an empty array means the pool holds no inventory at all. A side reporting a genuine zero size is kept — that is a different state from an absent one, and collapsing the two would hide it.
Each row is a PoolPosition:
sidePoolPositionSideLONG or SHORT.
sizebigintTotal size held on this side, in the pool token’s units.
valuebigintNotional value of the side, USD.
avgOpenPricebigintSize-weighted average open price, USD.
upnlbigintUnrealized PnL of the side, USD. Signed — a losing side is negative.
long_position_upnl arrives from the backend with a fractional tail ("…286154.904298") and, when zero, in
scientific notation ("0E-36"). Both are handled by the shared parser; the fraction truncates toward zero.
Throws
LISTING_NOT_CONFIGURED— aSymmError(kind: "config") when the chain has no listing backend. Gate withsupportsListingServiceto hide Pools rather than error.UNSUPPORTED_CHAIN— aSymmError(kind: "config") when thechainIdis not one the config knows about.FETCH_LISTING_MARKET_DETAIL_FAILED— the request itself failed. Any axios failure becomes aSymmApiErrorcarryingstatus,statusText,responseData,urlandmethod(a failure with no response carriesstatus: 0); a non-axios throw becomes a plainSymmError(kind: "api").
Related
- Pool detail tables — how this fits with the other four reads.
- React:
useListingMarketDetail.