Skip to content

Commit a1fca2a

Browse files
authored
feat(info): add more missing Info API methods (#203)
Added support for additional Hyperliquid Info API endpoints: - historical_orders: Retrieve user's historical orders with status - user_non_funding_ledger_updates: Get ledger updates excluding funding - portfolio: portfolio performance across time periods - user_twap_slice_fills: TWAP order slice fills - user_vault_equities: Vault investment positions - user_role: User role and account type information - user_rate_limit: API rate limit configuration and usage - delegator_history: staking history
1 parent ad8beaf commit a1fca2a

11 files changed

+734
-0
lines changed

hyperliquid/info.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,20 @@ def user_staking_rewards(self, address: str) -> Any:
594594
"""
595595
return self.post("/info", {"type": "delegatorRewards", "user": address})
596596

597+
def delegator_history(self, user: str) -> Any:
598+
"""Retrieve comprehensive staking history for a user.
599+
600+
POST /info
601+
602+
Args:
603+
user (str): Onchain address in 42-character hexadecimal format.
604+
605+
Returns:
606+
Comprehensive staking history including delegation and undelegation
607+
events with timestamps, transaction hashes, and detailed delta information.
608+
"""
609+
return self.post("/info", {"type": "delegatorHistory", "user": user})
610+
597611
def query_order_by_oid(self, user: str, oid: int) -> Any:
598612
return self.post("/info", {"type": "orderStatus", "user": user, "oid": oid})
599613

@@ -612,6 +626,110 @@ def query_user_to_multi_sig_signers(self, multi_sig_user: str) -> Any:
612626
def query_perp_deploy_auction_status(self) -> Any:
613627
return self.post("/info", {"type": "perpDeployAuctionStatus"})
614628

629+
def historical_orders(self, user: str) -> Any:
630+
"""Retrieve a user's historical orders.
631+
632+
POST /info
633+
634+
Args:
635+
user (str): Onchain address in 42-character hexadecimal format;
636+
e.g. 0x0000000000000000000000000000000000000000.
637+
638+
Returns:
639+
Returns at most 2000 most recent historical orders with their current
640+
status and detailed order information.
641+
"""
642+
return self.post("/info", {"type": "historicalOrders", "user": user})
643+
644+
def user_non_funding_ledger_updates(self, user: str, startTime: int, endTime: Optional[int] = None) -> Any:
645+
"""Retrieve non-funding ledger updates for a user.
646+
647+
POST /info
648+
649+
Args:
650+
user (str): Onchain address in 42-character hexadecimal format.
651+
startTime (int): Start time in milliseconds (epoch timestamp).
652+
endTime (Optional[int]): End time in milliseconds (epoch timestamp).
653+
654+
Returns:
655+
Comprehensive ledger updates including deposits, withdrawals, transfers,
656+
liquidations, and other account activities excluding funding payments.
657+
"""
658+
return self.post(
659+
"/info",
660+
{"type": "userNonFundingLedgerUpdates", "user": user, "startTime": startTime, "endTime": endTime},
661+
)
662+
663+
def portfolio(self, user: str) -> Any:
664+
"""Retrieve comprehensive portfolio performance data.
665+
666+
POST /info
667+
668+
Args:
669+
user (str): Onchain address in 42-character hexadecimal format.
670+
671+
Returns:
672+
Comprehensive portfolio performance data across different time periods,
673+
including account value history, PnL history, and volume metrics.
674+
"""
675+
return self.post("/info", {"type": "portfolio", "user": user})
676+
677+
def user_twap_slice_fills(self, user: str) -> Any:
678+
"""Retrieve a user's TWAP slice fills.
679+
680+
POST /info
681+
682+
Args:
683+
user (str): Onchain address in 42-character hexadecimal format.
684+
685+
Returns:
686+
Returns at most 2000 most recent TWAP slice fills with detailed
687+
execution information.
688+
"""
689+
return self.post("/info", {"type": "userTwapSliceFills", "user": user})
690+
691+
def user_vault_equities(self, user: str) -> Any:
692+
"""Retrieve user's equity positions across all vaults.
693+
694+
POST /info
695+
696+
Args:
697+
user (str): Onchain address in 42-character hexadecimal format.
698+
699+
Returns:
700+
Detailed information about user's equity positions across all vaults
701+
including current values, profit/loss metrics, and withdrawal details.
702+
"""
703+
return self.post("/info", {"type": "userVaultEquities", "user": user})
704+
705+
def user_role(self, user: str) -> Any:
706+
"""Retrieve the role and account type information for a user.
707+
708+
POST /info
709+
710+
Args:
711+
user (str): Onchain address in 42-character hexadecimal format.
712+
713+
Returns:
714+
Role and account type information including account structure,
715+
permissions, and relationships within the Hyperliquid ecosystem.
716+
"""
717+
return self.post("/info", {"type": "userRole", "user": user})
718+
719+
def user_rate_limit(self, user: str) -> Any:
720+
"""Retrieve user's API rate limit configuration and usage.
721+
722+
POST /info
723+
724+
Args:
725+
user (str): Onchain address in 42-character hexadecimal format.
726+
727+
Returns:
728+
Detailed information about user's API rate limit configuration
729+
and current usage for managing API usage and avoiding rate limiting.
730+
"""
731+
return self.post("/info", {"type": "userRateLimit", "user": user})
732+
615733
def query_spot_deploy_auction_status(self, user: str) -> Any:
616734
return self.post("/info", {"type": "spotDeployState", "user": user})
617735

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
interactions:
2+
- request:
3+
body: '{"type": "delegatorHistory", "user": "0x2ba553d9f990a3b66b03b2dc0d030dfc1c061036"}'
4+
headers:
5+
Accept:
6+
- '*/*'
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Content-Length:
12+
- '82'
13+
Content-Type:
14+
- application/json
15+
User-Agent:
16+
- python-requests/2.32.3
17+
method: POST
18+
uri: https://api.hyperliquid.xyz/info
19+
response:
20+
body:
21+
string: '[{"time":1751382238782,"hash":"0xaea14981ae79c88826b104269e1e61020161008a69327e1bd0716a870eb0032e","delta":{"delegate":{"validator":"0xb8f45222a3246a2b0104696a1df26842007c5bc5","amount":"89968.0","isUndelegate":false}}},{"time":1751382217852,"hash":"0xa41a74f16345b8b0ba4e04269e1d5d018200756676283eee1bbc9d4e86d0d942","delta":{"cDeposit":{"amount":"89968.0"}}},{"time":1746636092325,"hash":"0x1520bf77c0dae738c8130422ff52cf01cc00f7c6f145792f2eeca62d178cd048","delta":{"delegate":{"validator":"0xb8f45222a3246a2b0104696a1df26842007c5bc5","amount":"10000.1","isUndelegate":false}}},{"time":1746636051729,"hash":"0x88f45bda40a6b572ef230422ff50cf01e20075ab01e3a48566ea9979a7ac6313","delta":{"cDeposit":{"amount":"10000.1"}}}]'
22+
headers:
23+
Connection:
24+
- keep-alive
25+
Content-Length:
26+
- '721'
27+
Content-Type:
28+
- application/json
29+
Date:
30+
- Fri, 22 Aug 2025 11:45:24 GMT
31+
Server:
32+
- nginx/1.22.1
33+
Via:
34+
- 1.1 628e5146add9b3daeb91ab8792398818.cloudfront.net (CloudFront)
35+
X-Amz-Cf-Id:
36+
- B6JLp5pY_ZwV5Maq5tZMTGwlfJSngY7VdiQZMSn9iMwnWap6HroQEg==
37+
X-Amz-Cf-Pop:
38+
- FRA60-P5
39+
X-Cache:
40+
- Miss from cloudfront
41+
access-control-allow-origin:
42+
- '*'
43+
access-control-expose-headers:
44+
- '*'
45+
vary:
46+
- origin
47+
- access-control-request-method
48+
- access-control-request-headers
49+
status:
50+
code: 200
51+
message: OK
52+
version: 1
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
interactions:
2+
- request:
3+
body: '{"type": "historicalOrders", "user": "0x31ca8395cf837de08b24da3f660e77761dfb974b"}'
4+
headers:
5+
Accept:
6+
- '*/*'
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Content-Length:
12+
- '82'
13+
Content-Type:
14+
- application/json
15+
User-Agent:
16+
- python-requests/2.32.3
17+
method: POST
18+
uri: https://api.hyperliquid.xyz/info
19+
response:
20+
body:
21+
string: '[{"order": {"coin": "TON", "side": "B", "limitPx": "3.2502", "sz":
22+
"81.7", "oid": 141682155424, "timestamp": 1755863118217, "triggerCondition":
23+
"N/A", "isTrigger": false, "triggerPx": "0.0", "children": [], "isPositionTpsl":
24+
false, "reduceOnly": false, "orderType": "Limit", "origSz": "81.7", "tif":
25+
"Ioc", "cloid": null}, "status": "iocCancelRejected", "statusTimestamp": 1755863118217},
26+
{"order": {"coin": "ORDI", "side": "B", "limitPx": "8.6328", "sz": "3.15",
27+
"oid": 141682155423, "timestamp": 1755863118217, "triggerCondition": "N/A",
28+
"isTrigger": false, "triggerPx": "0.0", "children": [], "isPositionTpsl":
29+
false, "reduceOnly": false, "orderType": "Limit", "origSz": "3.15", "tif":
30+
"Ioc", "cloid": null}, "status": "iocCancelRejected", "statusTimestamp": 1755863118217},
31+
{"order": {"coin": "GRIFFAIN", "side": "B", "limitPx": "0.035057", "sz": "529.0",
32+
"oid": 141682155422, "timestamp": 1755863118217, "triggerCondition": "N/A",
33+
"isTrigger": false, "triggerPx": "0.0", "children": [], "isPositionTpsl":
34+
false, "reduceOnly": false, "orderType": "Limit", "origSz": "529.0", "tif":
35+
"Ioc", "cloid": null}, "status": "iocCancelRejected", "statusTimestamp": 1755863118217},
36+
{"order": {"coin": "DYDX", "side": "B", "limitPx": "0.62613", "sz": "1500.3",
37+
"oid": 141682147400, "timestamp": 1755863117780, "triggerCondition": "N/A",
38+
"isTrigger": false, "triggerPx": "0.0", "children": [], "isPositionTpsl":
39+
false, "reduceOnly": false, "orderType": "Limit", "origSz": "1500.3", "tif":
40+
"Alo", "cloid": null}, "status": "canceled", "statusTimestamp": 1755863118217},
41+
{"order": {"coin": "DYDX", "side": "B", "limitPx": "0.62689", "sz": "1614.3",
42+
"oid": 141682147399, "timestamp": 1755863117780, "triggerCondition": "N/A",
43+
"isTrigger": false, "triggerPx": "0.0", "children": [], "isPositionTpsl":
44+
false, "reduceOnly": false, "orderType": "Limit", "origSz": "1614.3", "tif":
45+
"Alo", "cloid": null}, "status": "canceled", "statusTimestamp": 1755863118217}]'
46+
headers:
47+
Connection:
48+
- keep-alive
49+
Content-Length:
50+
- '689574'
51+
Content-Type:
52+
- application/json
53+
Date:
54+
- Fri, 22 Aug 2025 11:45:18 GMT
55+
Server:
56+
- nginx/1.22.1
57+
Via:
58+
- 1.1 72500140cb63ff2dee8b57e4476902e6.cloudfront.net (CloudFront)
59+
X-Amz-Cf-Id:
60+
- JXelN_TiQqwyxr7GLuIrTUgS_CQKdomVFn3rF6_0bRtf0mUiv0U1Ag==
61+
X-Amz-Cf-Pop:
62+
- FRA60-P5
63+
X-Cache:
64+
- Miss from cloudfront
65+
access-control-allow-origin:
66+
- '*'
67+
access-control-expose-headers:
68+
- '*'
69+
vary:
70+
- origin
71+
- access-control-request-method
72+
- access-control-request-headers
73+
status:
74+
code: 200
75+
message: OK
76+
version: 1

tests/cassettes/info_test/test_portfolio.yaml

Lines changed: 52 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
interactions:
2+
- request:
3+
body: '{"type": "userNonFundingLedgerUpdates", "user": "0x2ba553d9f990a3b66b03b2dc0d030dfc1c061036",
4+
"startTime": 1681923833000, "endTime": 1682010233000}'
5+
headers:
6+
Accept:
7+
- '*/*'
8+
Accept-Encoding:
9+
- gzip, deflate
10+
Connection:
11+
- keep-alive
12+
Content-Length:
13+
- '147'
14+
Content-Type:
15+
- application/json
16+
User-Agent:
17+
- python-requests/2.32.3
18+
method: POST
19+
uri: https://api.hyperliquid.xyz/info
20+
response:
21+
body:
22+
string: '[]'
23+
headers:
24+
Connection:
25+
- keep-alive
26+
Content-Length:
27+
- '2'
28+
Content-Type:
29+
- application/json
30+
Date:
31+
- Fri, 22 Aug 2025 11:45:20 GMT
32+
Server:
33+
- nginx/1.22.1
34+
Via:
35+
- 1.1 bc841916063a49c638b48e73f77a28e8.cloudfront.net (CloudFront)
36+
X-Amz-Cf-Id:
37+
- D8Oa1RQKRIe6INTVcGG14k0D09p8YP-IFdUOAeppzsojGT-ojYedOA==
38+
X-Amz-Cf-Pop:
39+
- FRA60-P5
40+
X-Cache:
41+
- Miss from cloudfront
42+
access-control-allow-origin:
43+
- '*'
44+
access-control-expose-headers:
45+
- '*'
46+
vary:
47+
- origin
48+
- access-control-request-method
49+
- access-control-request-headers
50+
status:
51+
code: 200
52+
message: OK
53+
version: 1
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
interactions:
2+
- request:
3+
body: '{"type": "userNonFundingLedgerUpdates", "user": "0x2ba553d9f990a3b66b03b2dc0d030dfc1c061036",
4+
"startTime": 1681923833000, "endTime": null}'
5+
headers:
6+
Accept:
7+
- '*/*'
8+
Accept-Encoding:
9+
- gzip, deflate
10+
Connection:
11+
- keep-alive
12+
Content-Length:
13+
- '138'
14+
Content-Type:
15+
- application/json
16+
User-Agent:
17+
- python-requests/2.32.3
18+
method: POST
19+
uri: https://api.hyperliquid.xyz/info
20+
response:
21+
body:
22+
string: '[{"time": 1731999196516, "hash": "0x09ddd9f712b5df0945af34b055bbb3329c88ca001aff41bbfd4341d80bc760ce",
23+
"delta": {"type": "deposit", "usdc": "2703997.4500000002"}}, {"time": 1732834706761,
24+
"hash": "0x1ddfe341d6a65a05392a0417f410fd014100a311417ccf11da13fcddea1429c9",
25+
"delta": {"type": "accountClassTransfer", "usdc": "12.0", "toPerp": false}},
26+
{"time": 1732834825313, "hash": "0x2ceac78e94d15a1af8660417f418400175003b84f5f2d86615b352360e4d48ac",
27+
"delta": {"type": "spotTransfer", "token": "USDC", "amount": "10.5", "usdcValue":
28+
"10.5", "user": "0x2ba553d9f990a3b66b03b2dc0d030dfc1c061036", "destination":
29+
"0xaaa0c2769cb990f4f37db951a9e48de2385c2733", "fee": "1.0", "nativeTokenFee":
30+
"0.0", "nonce": null, "feeToken": ""}}, {"time": 1732865846906, "hash": "0xb43e5536dbe1e0393ac60417fb7e2301a400281569835033a92471582fbc705a",
31+
"delta": {"type": "accountClassTransfer", "usdc": "2684105.0099999998", "toPerp":
32+
false}}, {"time": 1732867345893, "hash": "0xfba2579369bfd93f45b5ea54942e59f81aa72b422064d8969917a0feb0c68694",
33+
"delta": {"type": "deposit", "usdc": "1099994.98"}}]'
34+
headers:
35+
Connection:
36+
- keep-alive
37+
Content-Length:
38+
- '40389'
39+
Content-Type:
40+
- application/json
41+
Date:
42+
- Sat, 30 Aug 2025 19:17:29 GMT
43+
Server:
44+
- nginx/1.22.1
45+
Via:
46+
- 1.1 e505058447bf5e74cc264f4e72f27bee.cloudfront.net (CloudFront)
47+
X-Amz-Cf-Id:
48+
- MV7KMQ-PpTHyokjwV3NYgHQcJrCu9w0lFL1woFwYTBadyP8i1H5ikA==
49+
X-Amz-Cf-Pop:
50+
- FRA60-P5
51+
X-Cache:
52+
- Miss from cloudfront
53+
access-control-allow-origin:
54+
- '*'
55+
access-control-expose-headers:
56+
- '*'
57+
vary:
58+
- origin
59+
- access-control-request-method
60+
- access-control-request-headers
61+
status:
62+
code: 200
63+
message: OK
64+
version: 1

0 commit comments

Comments
 (0)