Skip to content

Releases: pinax-network/pinax-api

v3.21.1

Choose a tag to compare

@DenisCarriere DenisCarriere released this 09 Jul 18:28
af56ff2

Performance release: pool OHLC queries no longer scan a pool's full history to return a page of candles. Responses are byte-identical to before — this is a pure query-planning change with no API, parameter, or schema changes.

Performance

Pool OHLC endpoints — bounded to the requested window (#583)

GET /v1/svm/pools/ohlc, /v1/evm/pools/ohlc, and /v1/tvm/pools/ohlc aggregate AggregateFunction state rows with a blocking GROUP BY. Without a lower time bound, ClickHouse had to merge a pool's entire history before ORDER BY … LIMIT could discard all but the requested page. On high-activity pools this read gigabytes and used gigabytes of RAM per request, producing multi-second latencies and intermittent 500s under concurrency (reported in #582).

Each query now first derives the timestamp cutoff of the most-recent limit + offset candles by scanning only the cheap timestamp column, then constrains the heavy aggregation to that window. Sparse pools (whose candles span a much wider wall-clock range than interval × limit) return exactly the same rows as before — the cutoff is derived from the data, not a fixed lookback.

Measured on production against the outlier pools from #582:

Query Before After
SVM 1m / limit 60 830–1240 ms · 210 MiB read · ~815 MiB RAM 120–200 ms · 16 MiB · ~42 MiB
SVM 5m / limit 288 980–1450 ms 160–250 ms
SVM 4h / limit 180 ~1190 ms ~260 ms
EVM 1m / limit 100 (hot pool) 3270 ms · 1.56 GiB read · ~5.1 GB RAM 155 ms · 262 MiB · ~314 MiB

~7–21× faster and ~6–16× less memory per request. The memory reduction is what removes the contention behind the reported timeouts. Coarse intervals with little history (e.g. hourly/weekly presets) may take a few tens of milliseconds longer from the extra timestamp pass, but remain well within budget.

Client tip for charting: always pass start_time/end_time for the visible window. It further bounds the scan and lets you fetch a full preset in fewer requests.

Chores

  • Bumped dbs-config.yaml.example DEX dataset versions to match production (solana:svm-dex@v0.5.2, mainnet:evm-dex@v0.5.0, tron:evm-dex@v0.5.0).
  • Made SKILL.md OKF-compatible (#581).

Full changelog: v3.21.0...v3.21.1

v3.21.0

Choose a tag to compare

@0237h 0237h released this 18 Jun 14:00
4734c32

Adds the HIP-4 outcome market family on Hyperliquid, normalizes the response shape across the new /outcomes/* endpoints, and tightens a few existing surfaces.

Breaking changes

/v1/hyperliquid/markets — volume / count semantics

buy_volume_24h / sell_volume_24h now report taker-aggressor notional only (previously combined taker + maker on the matched side). volume_24h is the true matched total and trades_24h is the true match count.

Field Before After
buy_volume_24h bid-side notional taker buys (aggressor on the ask)
sell_volume_24h ask-side notional taker sells (aggressor on the bid)
volume_24h sum of both sides (≈ 2× true) true matched volume
trades_24h row count (≈ 2× true) true match count

/v1/hyperliquid/markets/ohlc, /markets/liquidations/ohlc, /platform

Same taker-derived swap as /markets, applied to the equivalent fields on each. The redundant buys / sells columns are removed from the response — after the fix both equalled the match count, so they carried no information.

/v1/hyperliquid/markets — nullable funding fields for spot rows

open_interest, funding_rate, and funding_snapshot_time now return null for spot markets (which have no funding data), instead of the sentinels 0 / 0 / 1970-01-01 00:00:00. Perp markets are unchanged.

// before
{ "coin": "@107", "dex": "spot", "open_interest": 0, "funding_rate": 0, "funding_snapshot_time": "1970-01-01 00:00:00" }
// after
{ "coin": "@107", "dex": "spot", "open_interest": null, "funding_rate": null, "funding_snapshot_time": null }

New endpoints

Six new HIP-4 outcome endpoints under /v1/hyperliquid/outcomes/*:

Endpoint Description
GET /v1/hyperliquid/outcomes Outcome universe with per-leg price, 24h volume, and 24h price change
GET /v1/hyperliquid/outcomes/ohlc Per-leg OHLCV candles
GET /v1/hyperliquid/outcomes/trades Taker fills feed (BUY/SELL + optional composition events)
GET /v1/hyperliquid/outcomes/users Per-user-per-outcome P&L and volume rollup; leaderboard mode when filtered by outcome/question
GET /v1/hyperliquid/outcomes/users/positions Current share holdings per (user, leg) — open balances only
GET /v1/hyperliquid/outcomes/users/activity Composition-event feed (SPLIT_OUTCOME, MERGE_OUTCOME, MERGE_QUESTION, NEGATE_OUTCOME, SETTLEMENT)

Outcome coins use the #<outcome_id*10 + side_index> encoding (e.g. #1720 = outcome 172, Yes leg; #1721 = outcome 172, No leg). Outcome coins and dex=outcome are rejected on the regular /markets/* and /users/* endpoints — use the dedicated /outcomes/* family.

Response shape on /outcomes/*

Every /outcomes/* response (except /outcomes itself, which remains the canonical full-metadata source) embeds a compact outcome context object:

  • OutcomeContext on /outcomes/users (aggregates collapse legs): outcome_id, outcome_name, question_id, question_name, status, settle_fraction.
  • OutcomeLegContext on per-leg endpoints (/outcomes/ohlc, /outcomes/trades, /outcomes/users/positions, /outcomes/users/activity): the above plus coin, side_index, side_label.

settle_fraction follows the HIP-4 spec — a value in [0, 1] representing the Yes share's payout at settlement. null until status='settled'.

Additive filters and modes (non-breaking)

  • ?direction=… (CSV) on /outcomes/trades, /markets/activity, and /markets/liquidations, each with an endpoint-specific enum.
  • ?sort_by=… on /outcomes (volume_24h, last_trade, outcome_id) and /outcomes/users (total_volume, transactions, realized_pnl).
  • ?include_fallback=true on /outcomes exposes each multi-outcome question's catch-all leg (off by default).
  • ?coin is a valid scope on /outcomes/users/positions and /outcomes/users/activity, in line with outcome_id and question_id.
  • ?user is optional on /outcomes/users — when omitted, the response is a leaderboard for the given ?outcome_id / ?question_id scope, sorted by sort_by desc.

🤖 Generated with Claude Code

v3.21.0-pre2

v3.21.0-pre2 Pre-release
Pre-release

Choose a tag to compare

@0237h 0237h released this 18 Jun 13:28
464933c

Polish on top of v3.21.0-pre1

Tightens the new /outcomes/users family based on staging feedback. No infrastructure or breaking-change deltas vs. v3.21.0-pre1.

Changes

  • /outcomes/users/activity — direction enum now restricted to the five composition events (SETTLEMENT, SPLIT_OUTCOME, MERGE_OUTCOME, MERGE_QUESTION, NEGATE_OUTCOME). Passing BUY/SELL returns 400; taker fills remain on /outcomes/trades.
  • /outcomes/users/positionscoin is now a valid scope alongside user/outcome_id/question_id. Previously the param was silently ignored.
  • /outcomes/users — new sort_by parameter (total_volume default, also transactions, realized_pnl). Parity with /users leaderboard mode.
  • All three endpoint descriptions now lead with the at-least-one-of constraint in bold.

Reference


🤖 Generated with Claude Code

v3.21.0-pre1

v3.21.0-pre1 Pre-release
Pre-release

Choose a tag to compare

@0237h 0237h released this 17 Jun 21:46
3b959f9

First pre-release in the v3.21.0 cycle. Adds the HIP-4 outcome market family, unifies the response shape across /outcomes/* endpoints, and ships a few cross-family fixes.

Breaking changes

/v1/hyperliquid/markets — volume / count semantics

buy_volume_24h / sell_volume_24h now report taker-aggressor notional only (previously combined taker + maker on the matched side). volume_24h is the true matched total (was approximately 2× due to two rows per match) and trades_24h is the true match count (was approximately 2× inflated).

Field Before After
buy_volume_24h bid-side notional taker buys (aggressor on the ask)
sell_volume_24h ask-side notional taker sells (aggressor on the bid)
volume_24h sum of both sides (≈ 2× true) true matched volume
trades_24h row count (≈ 2× true) true match count

/v1/hyperliquid/markets/ohlc, /v1/hyperliquid/markets/liquidations/ohlc, /v1/hyperliquid/platform

Same taker-derived swap as /markets, applied to the equivalent fields on each. Additionally, the redundant buys / sells columns are removed from the response — after the fix both equalled the match count, so they carried no information.

/v1/hyperliquid/markets — nullable funding fields for spot rows

open_interest, funding_rate, and funding_snapshot_time now return null for spot markets (which have no funding data), instead of the sentinels 0 / 0 / 1970-01-01 00:00:00. Perp markets are unchanged.

// before
{ "coin": "@107", "dex": "spot", "open_interest": 0, "funding_rate": 0, "funding_snapshot_time": "1970-01-01 00:00:00" }
// after
{ "coin": "@107", "dex": "spot", "open_interest": null, "funding_rate": null, "funding_snapshot_time": null }

New endpoints (six)

Endpoint Description
GET /v1/hyperliquid/outcomes Outcome universe with per-leg price, 24h volume, and 24h price change
GET /v1/hyperliquid/outcomes/ohlc Per-leg OHLCV candles
GET /v1/hyperliquid/outcomes/trades Taker fills feed (BUY/SELL + optional composition events)
GET /v1/hyperliquid/outcomes/users Per-user-per-outcome P&L and volume rollup; leaderboard mode when filtered by outcome/question
GET /v1/hyperliquid/outcomes/users/positions Current share holdings per (user, leg) — open balances only
GET /v1/hyperliquid/outcomes/users/activity Composition events feed per user (SPLIT/MERGE/MERGE_QUESTION/NEGATE/SETTLEMENT)

Response shape on /outcomes/*

Every /outcomes/* response (except /outcomes itself, which remains the canonical full-metadata source) embeds a compact outcome context object:

  • OutcomeContext on /outcomes/users (aggregates collapse legs): outcome_id, outcome_name, question_id, question_name, status, settle_fraction.
  • OutcomeLegContext on per-leg endpoints (/outcomes/ohlc, /outcomes/trades, /outcomes/users/positions, /outcomes/users/activity): the above + coin, side_index, side_label.

settle_fraction follows the HIP-4 spec — a value in [0, 1] representing the Yes share's payout at settlement. Null until status='settled'.

Additive filters (non-breaking)

  • ?direction=... (CSV) on /v1/hyperliquid/outcomes/trades, /v1/hyperliquid/markets/activity, and /v1/hyperliquid/markets/liquidations, each with an endpoint-specific enum. Default behavior unchanged when omitted.
  • ?user is optional on /outcomes/users — when omitted, the response is a leaderboard for the given ?outcome_id / ?question_id scope, sorted by total_volume desc.

Performance

  • Responses are now gzip-encoded when Accept-Encoding: gzip is sent. JSON payloads typically compress 5–10× on the wire.
  • /v1/hyperliquid/outcomes is meaningfully faster — fewer source-table scans per request.

🤖 Generated with Claude Code

v3.20.6

Choose a tag to compare

@0237h 0237h released this 11 Jun 21:45
6df1595

What's Changed

  • fix(polymarket/markets): apply m.* filters before LEFT JOIN by @0237h in #560

Full Changelog: v3.20.5...v3.20.6

v3.20.5

Choose a tag to compare

@YaroShkvorets YaroShkvorets released this 01 Jun 22:24
22b4d64

What's Changed

  • fix(polymarket/ohlc): dedup market metadata join by @0237h in #557
  • perf(evm): faster /holders/native (ERC-20 reverted — see proposal) by @YaroShkvorets in #558

Full Changelog: v3.20.4...v3.20.5

v3.20.4

Choose a tag to compare

@YaroShkvorets YaroShkvorets released this 01 Jun 18:02
f505de1

What's Changed

  • perf+fix(svm): faster pools/holders/balances + pagination & determinism correctness fixes by @YaroShkvorets in #556

Full Changelog: v3.20.3...v3.20.4

v3.20.3

Choose a tag to compare

@YaroShkvorets YaroShkvorets released this 29 May 17:51
733554f

What's Changed

Full Changelog: v3.20.2...v3.20.3

v3.20.2

Choose a tag to compare

@0237h 0237h released this 28 May 18:20
65ca14f

Performance

  • /v1/evm/ohlcv, /v1/evm/balances, /v1/evm/balances/historical, /v1/tvm/tokens — faster response times by lifting the metadata.metadata lookup into a CTE so the (network, contract) primary key engages, instead of scanning the full network prefix that the previous JOIN-only condition fell back to.

PRs

  • #553 — perf(evm/ohlcv,balances,balances_historical,tvm/tokens): push metadata PK predicate

Full Changelog: v3.20.1...v3.20.2

v3.20.1

Choose a tag to compare

@0237h 0237h released this 28 May 16:06
4b9f61d

Fixes

  • /v1/evm/holders, /v1/evm/holders/native, /v1/evm/nft/collections now return null for fields that depend on contract-deployment data (is_contract, contract_creation, contract_creator) on chains where that data is unavailable (currently hyperevm and avalanche). Previously these returned misleading defaults (is_contract: false for every holder; epoch-zero timestamp and a null-byte creator on NFT collections).

Performance

  • /v1/evm/pools: faster response times via projections on the aggregating tables and PK-predicate pushdowns.
  • /v1/evm/tokens: faster response times via single-pass FINAL aggregation on erc20_balances and PK-predicate pushdown on metadata.

PRs

  • #550 — perf(evm/pools): use token-table projection and push PK predicates
  • #551 — perf(evm/tokens): use FINAL for balances and push metadata PK predicate
  • #552 — fix(evm): null-fallback for is_contract and NFT creation fields

Full Changelog: v3.20.0...v3.20.1