diff --git a/hyperliquid/info.py b/hyperliquid/info.py index 360d0588..80a0b012 100644 --- a/hyperliquid/info.py +++ b/hyperliquid/info.py @@ -1,5 +1,6 @@ from hyperliquid.api import API from hyperliquid.utils.types import ( + ActiveAssetData, Any, Callable, Cloid, @@ -127,6 +128,32 @@ def user_state(self, address: str, dex: str = "") -> Any: """ return self.post("/info", {"type": "clearinghouseState", "user": address, "dex": dex}) + def active_asset_data(self, user: str, coin: str) -> ActiveAssetData: + """Retrieve a user's active data for a specific asset. + + POST /info + + Args: + user (str): Onchain address in 42-character hexadecimal format; + e.g. 0x0000000000000000000000000000000000000000. + coin (str): Perp coin name, e.g. "ETH". + + Returns: + { + user: str, + coin: str, + leverage: { + type: "cross" | "isolated", + value: int, + rawUsd: float string # only if type is "isolated" + }, + maxTradeSzs: [float string, float string], + availableToTrade: [float string, float string], + markPx: float string, + } + """ + return cast(ActiveAssetData, self.post("/info", {"type": "activeAssetData", "user": user, "coin": coin})) + def spot_user_state(self, address: str) -> Any: return self.post("/info", {"type": "spotClearinghouseState", "user": address}) diff --git a/tests/info_test.py b/tests/info_test.py index 79e146c9..0eaeafa0 100644 --- a/tests/info_test.py +++ b/tests/info_test.py @@ -15,6 +15,32 @@ def test_get_user_state(): assert response["marginSummary"]["accountValue"] == "1182.312496" +def test_active_asset_data_posts_expected_payload(monkeypatch): + info = Info(skip_ws=True, meta=TEST_META, spot_meta=TEST_SPOT_META) + user = "0x0000000000000000000000000000000000000000" + expected_response = { + "user": user, + "coin": "ETH", + "leverage": {"type": "cross", "value": 20}, + "maxTradeSzs": ("1.0", "2.0"), + "availableToTrade": ("3.0", "4.0"), + "markPx": "2000.0", + } + posted = {} + + def fake_post(url_path, payload): + posted["url_path"] = url_path + posted["payload"] = payload + return expected_response + + monkeypatch.setattr(info, "post", fake_post) + + response = info.active_asset_data(user, "ETH") + + assert response == expected_response + assert posted == {"url_path": "/info", "payload": {"type": "activeAssetData", "user": user, "coin": "ETH"}} + + @pytest.mark.vcr() def test_get_open_orders(): info = Info(skip_ws=True, meta=TEST_META, spot_meta=TEST_SPOT_META)