Info endpoints: twapHistory, userTwapSliceFillsByTime, activeAssetData - #157
Merged
Conversation
Completes the TWAP history story (twapOrder/twapCancel/userTwapSliceFills
already existed) and adds per-asset leverage/margin data needed for
correct order sizing.
Response shapes for all three were confirmed live against mainnet (real
TWAP trader addresses discovered via hypurrscan, and the HLP vault address
for activeAssetData), not just from docs:
- twapHistory: flat array of {time, state, status, twapId}. Also
discovered two status values missing from the existing TwapHistoryStatus
enum (waitingForTrigger, stopped) alongside the previously-known
activated/terminated/finished/error, and that state carries twapId as a
sibling field rather than nested inside state.
- userTwapSliceFillsByTime: identical array-of-{fill,twapId} shape to the
existing userTwapSliceFills, just filtered by time range - same pattern
as userFills/userFillsByTime.
- activeAssetData: matches the docs (user, coin, leverage{type,value},
maxTradeSzs, availableToTrade, markPx). The isolated-margin HIP-3 dex
variant that adds "rawUsd" to the leverage object is doc-sourced only,
not independently verified live (noted in code comments and PR
description).
Adds RestApi + WebsocketApi methods (sync/async + post-over-websocket) for
all three, request-builder and response-parser tests, and marks the three
rows ✅ in README's endpoint coverage table.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Le73N2EZjGLsCqmCScAse
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #157 +/- ##
==========================================
+ Coverage 69.53% 69.72% +0.19%
==========================================
Files 53 53
Lines 8219 8404 +185
Branches 513 526 +13
==========================================
+ Hits 5715 5860 +145
- Misses 2501 2541 +40
Partials 3 3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
TuxedoFish
commented
Sep 8, 2026
|
|
||
| enum class TwapHistoryStatus { Activated, Terminated, Finished, Error, Unknown }; | ||
| // Confirmed live against mainnet (twapHistory info endpoint): activated, terminated, | ||
| // waitingForTrigger, stopped, finished, error have all been observed on real accounts. |
TuxedoFish
commented
Sep 8, 2026
| virtual void onPostResponse(const SpotClearinghouseStateResponse&, std::optional<uint64_t> = std::nullopt) {} | ||
| virtual void onPostResponse(const FrontendOpenOrdersResponse&, std::optional<uint64_t> = std::nullopt) {} | ||
| virtual void onPostResponse(const HistoricalOrdersResponse&, std::optional<uint64_t> = std::nullopt) {} | ||
| // userTwapSliceFills/userTwapSliceFillsByTime share this response shape. |
TuxedoFish
commented
Sep 8, 2026
| // crackTwapState. Only reads fields through "timestamp" - "trigger"/"stopPx" also appear on | ||
| // the wire (trigger-TWAP orders) but aren't modeled by TwapState yet, and it's safe to leave | ||
| // trailing fields unread since simdjson's ondemand only requires in-order reads, not | ||
| // exhaustive ones. |
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Le73N2EZjGLsCqmCScAse
This was referenced Sep 8, 2026
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
/infoendpoints:twapHistory,userTwapSliceFillsByTime(closes Implement twapHistory / userTwapSliceFillsByTime #124), andactiveAssetData(closes Implement activeAssetData #126).twapHistory/userTwapSliceFillsByTimecomplete the TWAP story alongside the already-existingtwapOrder/twapCancel/userTwapSliceFills.activeAssetDatareturns per-asset leverage/margin/mark-price data, needed for correct order sizing.RestApi(sync + async) andWebsocketApi(post-over-websocket) methods added for all three, per CONTRIBUTING.md.tests/rest_account_test.cpp(TWAP endpoints) andtests/rest_market_data_test.cpp(activeAssetData), plus aWebsocketApino-throw smoke test intests/websocket_api_test.cpp.rest_twap_slices.cppnow also callstwapHistory/userTwapSliceFillsByTime,rest_leverage.cppnow callsactiveAssetData.Verification against live mainnet (not just docs)
Per CONTRIBUTING.md's guidance, I ran real requests against
https://api.hyperliquid.xyz/infobefore writing the parsers, rather than trusting docs/memory alone:activeAssetData: queried the HLP vault address (0xa15099a30bbf2e68942d6f4c43d70d04faeab0a0) for ETH/BTC/HYPE. Confirmed shape:{"user":..,"coin":..,"leverage":{"type":"cross","value":20},"maxTradeSzs":["0.0","0.0"],"availableToTrade":["0.0","0.0"],"markPx":"2479.5"}. Also discovered anullresponse for a dex/coin the user has never traded on (e.g. querying a HIP-3 dex asset for an account with no isolated position there) - the parser degrades gracefully (logs and returns a default-constructed struct) rather than crashing.twapHistory: found real active TWAP trader addresses viahypurrscan.io's/twap/{coin}API (e.g.0x6973a383b202b4349d256bbf8b0187dc7b2ed6bb,0x9b3cafa1209ac61f02d7bc3b219697fb171c9c91,0x13c50dcdee4bbcba71baf578b345cdd35c7928be) and queried theirtwapHistory. Confirmed shape: a flat array of{time, state, status, twapId}(field order matters for simdjson ondemand -timefirst, thenstate, thenstatus, thentwapId). Two things this uncovered that weren't previously known to the codebase (the existingTwapHistoryStatusenum, shared with theuserTwapHistory/twapStateswebsocket channels, only hadactivated/terminated/finished/error):waitingForTriggerandstopped(both added to the enum).twapIdis a sibling field ofstate/statusat the entry level, not nested insidestate- added as a new field on the sharedTwapHistoryEntrystruct (defaults to 0 / unpopulated on the websocketuserTwapHistorychannel path, which I did not touch).statealso carriestrigger/stopPxfields (trigger-based TWAP orders) not modeled by the existingTwapStatestruct - left unread/unmodeled since they're safely skippable trailing fields and out of scope for this PR (no existingtwapOrderrequest support for trigger-TWAPs either).userTwapSliceFillsByTime: confirmed identicalarray of {fill, twapId}shape to the existinguserTwapSliceFills, just filtered bystartTime/endTime/aggregateByTime- same pattern asuserFills/userFillsByTime.Not independently verified live: the isolated-margin HIP-3 dex variant of
activeAssetData'sleverageobject, which per the official docs adds arawUsdfield alongsidetype/value. I could not find a live isolated-margin HIP-3 position to query, soActiveAssetData::leverageRawUsdand its parsing are doc-sourced only - please double-check before relying on this if it matters for your use case.Test plan
cmake -S . -B build -DHYPERLIQUID_WARNINGS_AS_ERRORS=ON -DHYPERLIQUID_BUILD_TESTS=ON -DHYPERLIQUID_BUILD_EXAMPLES=ON -DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake"- clean configurecmake --build build -j"$(nproc)"- zero warnings/errorsctest --test-dir build- 100% pass (28/28 test suites)build/removed before committing🤖 Generated with Claude Code
https://claude.ai/code/session_018Le73N2EZjGLsCqmCScAse