feat(hyperliquid): support batched filter parameters across 8 endpoints#532
Merged
Conversation
Filter params on Hyperliquid endpoints now accept a single value,
a comma-separated list, or a repeated query key — matching the
batched-parameter convention already used on EVM/SVM/TVM routes.
Batched fields per endpoint:
- `/markets` coin, dex, base_token, quote_token
- `/markets/activity` coin, dex, user
- `/markets/liquidations` coin, dex, liquidated_user
- `/markets/oi` coin, dex
- `/users` user, coin, dex
- `/users/positions` user, coin, dex
- `/vaults` vault
- `/vaults/depositors` vault
OHLC endpoints (`/markets/ohlc`, `/markets/liquidations/ohlc`) and
`/users/activity` are intentionally left scalar — the OHLC pair
mirrors the scalar-only contract on EVM/SVM/TVM `/pools/ohlc`, and
`/users/activity` is a UNION ALL fan-out that warrants separate
perf review before batching.
Side effects:
- `hyperliquidCoinSchema` and `hyperliquidTokenSchema` now reject
commas and whitespace at the scalar level so the union splitter
in `createQuerySchema` can fire on CSV input. Otherwise the
permissive scalar consumed the whole string.
- `/users` SQL aliases the source table and qualifies column
references in WHERE/GROUP BY. The literal `{coin} AS coin`
projection shadowed the source column, leaving the prior
`coin = ...` filter as a no-op — `?coin=BTC` was silently
returning all-coin totals. The filter now applies correctly,
which materially changes the numbers returned for any request
that scoped by coin or dex on `/users`. Single-value scoping
still echoes the filter back into the response.
- `/vaults/depositors` SQL drops the literal `{vault} AS vault`
projection and joins CTEs on `(vault, user)` so multi-vault
responses carry the correct vault per row.
- `hyperliquidDexIdSchema` description trimmed to keep the
OpenAPI 300-char description cap once the batched suffix is
appended.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
?coin=BTC,ETH, repeated?coin=BTC&coin=ETH, and single?coin=BTCall parse, matching the convention on/v1/{evm,svm,tvm}/*./userswhere{coin:Nullable(String)} AS coinprojection collided with the source column, silently turning thecoin/dexfilter into a no-op. The filter now applies — see the Behavior change note below./vaults/depositorsSQL rewritten to carryvaultthrough CTEs (no more literal projection) so multi-vault responses are correct.hyperliquidCoinSchema/hyperliquidTokenSchemato reject commas and whitespace so thecreateQuerySchemaunion splitter fires on CSV input.Endpoints / params
/marketscoin,dex,base_token,quote_token/markets/activitycoin,dex,user/markets/liquidationscoin,dex,liquidated_user/markets/oicoin,dex/usersuser,coin,dex/users/positionsuser,coin,dex/vaultsvault/vaults/depositorsvaultIntentionally scalar for now:
/markets/ohlcand/markets/liquidations/ohlc— mirrors the scalar-only contract on/v1/{evm,svm,tvm}/pools/ohlc./users/activity— UNION ALL fan-out across 9 ledger tables; needs a perf review before batching.Behavior change on
/usersPrior SQL had
{coin:Nullable(String)} AS coinaliased on top of the source column; the WHERE clausecoin = {coin:Nullable(String)}was being resolved against the projected literal, not the column. Net effect:?coin=BTCreturned all-coin totals on every response row. After this PR the filter applies as documented, so any client that scoped/usersby coin or dex will see different (smaller, correct) aggregate numbers. The response shape is unchanged — single-value calls still echo the filter back as before.Test plan
bun run tsc --noEmitclean?coin=BTC,ETHreturns rows for users trading either coin withcoins_tradedreflecting the per-user coin count within the filter set🤖 Generated with Claude Code