Every service on this page is public: an unauthenticated PolyesterClient can call all of them.
import { PolyesterClient, POLYESTER_TESTNET_ENVIRONMENT } from "@polyester/sdk";
const client = new PolyesterClient({ environment: POLYESTER_TESTNET_ENVIRONMENT });Symbols and symbol IDs
Markets are addressed either by pair symbol ("BTC-USDC") or numeric symbolId, depending on the
endpoint. The client catalog converts between them and knows every pair's precision rules:
await client.catalog.ensureReady();
const symbolId = client.catalog.market.requireSymbolIdByPairSymbol("BTC-USDC");
const pair = client.catalog.market.requirePairBySymbol("BTC-USDC");
const listedPairs = client.catalog.market.listPairs({ listed: true });You rarely need to call ensureReady() yourself before service calls — any method that needs
reference data awaits it internally — but direct catalog reads like the above require it once.
Market overview (tickers)
One row per market: last price, 24h stats, top-of-book, and optional sparklines. Supports filtering, sorting, and pagination:
const { markets, nextPageToken } = await client.marketOverview.list({
orderBy: "volume_24h_quote",
sort: "desc",
limit: 50,
});The matching stream is snapshot-then-stream: it fetches the full set, then merges live updates and emits the merged array. It also refetches automatically on reconnect:
const unsubscribe = client.marketOverview.subscribe({
onEvent: (markets) => render(markets),
onError: (ctx) => console.error(ctx),
});Candles (OHLCV)
Row form for consumption, columnar form for charting libraries. Timeframes: 1s, 1m, 5m, 15m, 30m, 1h, 4h, 12h, 1d, 1w, 1mo.
const candles = await client.candles.list({
symbolId,
timeframe: "1h",
limit: 200,
});
// Chart-friendly parallel arrays (oldest-first)
const columns = await client.candles.listColumnar({
symbolId,
timeframe: "1h",
startTsSec: Math.floor(Date.now() / 1000) - 86_400,
});
const unsubscribe = client.candles.subscribe({
symbolId,
timeframe: "1m",
onEvent: (candle) => chart.update(candle),
});listColumnarInts / subscribeInts are variants keyed by numeric tsSec timestamps instead of
formatted times — useful when feeding chart engines directly.
Order book
Fetch a depth snapshot, or maintain a live local book:
const book = await client.orderbook.get({ symbol: "BTC-USDC", depth: 20 });
console.log(book.bids[0], book.asks[0]);For a live book, createSubscription handles the hard parts — initial snapshot, sequence-checked
deltas, and automatic refetch on gaps or reconnects:
const subscription = client.orderbook.createSubscription({
symbol: "BTC-USDC",
symbolId,
depth: 50,
onEvent: (book) => render(book),
onError: (ctx) => console.error(ctx),
});
// change local price-bucket aggregation without reconnecting
subscription.setBucket("10");
subscription.unsubscribe();Public trades
const { trades, nextPageToken } = await client.marketData.listTrades({
symbolId,
limit: 100,
});
const unsubscribe = client.marketData.subscribeTrades({
symbolId,
onEvent: (trade) => console.log(trade.price, trade.qty),
});Order book heatmap
Historical liquidity heatmaps plus a live bucket stream, for depth-over-time visualizations:
const heatmap = await client.heatmap.getOrderbookHeatmap({
symbolId,
interval: "1m", // "1s" | "1m" | "5m" | "1h"
depth: 100,
startTsSec: Math.floor(Date.now() / 1000) - 3600,
});
const unsubscribe = client.heatmap.subscribeLive({
symbolId,
interval: "1m",
onEvent: (bucket) => draw(bucket),
});Historical queries page either by time range (startTsSec / endTsSec) or by cursor
(pageToken); one of the two is required.
Chain analytics
Public chart series about the chain itself — zToken supply per route and unified asset balances:
const supply = await client.chainAnalytics.getZippedAssetSupply({ zippedAssetId });
const group = await client.chainAnalytics.getZippedAssetSupplyGroup({ groupId });
const balances = await client.chainAnalytics.getUnifiedAssetBalances({ assetId });Spot configuration
client.marketData.getSpotConfig() returns the raw reference-data snapshot (assets, pairs,
scales, statuses). You normally don't call it directly — it is the refresh source that feeds client.catalog, which exposes the same data with lookups, conversions, and validation on top.
See Catalog & precision.
pageToken and return a nextPageToken. An empty token means you have reached the end.