Skip to content

Commit eae5222

Browse files
committed
Version 0.15.0
1 parent d822d01 commit eae5222

File tree

6 files changed

+71
-7
lines changed

6 files changed

+71
-7
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import example_utils
2+
3+
from hyperliquid.utils import constants
4+
5+
DUMMY_DEX = "test"
6+
COLLATERAL_TOKEN = "USDC"
7+
8+
9+
def main():
10+
address, info, exchange = example_utils.setup(constants.TESTNET_API_URL, skip_ws=True)
11+
12+
# Transfer 1.23 USDC from perp wallet to spot wallet
13+
transfer_result = exchange.perp_dex_class_transfer(DUMMY_DEX, COLLATERAL_TOKEN, 1.23, False)
14+
print(transfer_result)
15+
16+
# Transfer 1.23 collateral token from spot wallet to perp wallet
17+
transfer_result = exchange.perp_dex_class_transfer(DUMMY_DEX, COLLATERAL_TOKEN, 1.23, True)
18+
print(transfer_result)
19+
20+
21+
if __name__ == "__main__":
22+
main()

hyperliquid/exchange.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
sign_convert_to_multi_sig_user_action,
2727
sign_l1_action,
2828
sign_multi_sig_action,
29+
sign_perp_dex_class_transfer_action,
2930
sign_spot_transfer_action,
3031
sign_token_delegate_action,
3132
sign_usd_class_transfer_action,
@@ -455,6 +456,27 @@ def usd_class_transfer(self, amount: float, to_perp: bool) -> Any:
455456
timestamp,
456457
)
457458

459+
def perp_dex_class_transfer(self, dex: str, token: str, amount: float, to_perp: bool) -> Any:
460+
timestamp = get_timestamp_ms()
461+
str_amount = str(amount)
462+
if self.vault_address:
463+
str_amount += f" subaccount:{self.vault_address}"
464+
465+
action = {
466+
"type": "PerpDexClassTransfer",
467+
"dex": dex,
468+
"token": token,
469+
"amount": str_amount,
470+
"toPerp": to_perp,
471+
"nonce": timestamp,
472+
}
473+
signature = sign_perp_dex_class_transfer_action(self.wallet, action, self.base_url == MAINNET_API_URL)
474+
return self._post_action(
475+
action,
476+
signature,
477+
timestamp,
478+
)
479+
458480
def sub_account_transfer(self, sub_account_user: str, is_deposit: bool, usd: int) -> Any:
459481
timestamp = get_timestamp_ms()
460482
sub_account_transfer_action = {

hyperliquid/info.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ def query_sub_accounts(self, user: str) -> Any:
598598
def query_user_to_multi_sig_signers(self, multi_sig_user: str) -> Any:
599599
return self.post("/info", {"type": "userToMultiSigSigners", "user": multi_sig_user})
600600

601-
def _validate_subscription(self, subscription: Subscription) -> None:
601+
def _remap_coin_subscription(self, subscription: Subscription) -> None:
602602
if (
603603
subscription["type"] == "l2Book"
604604
or subscription["type"] == "trades"
@@ -608,14 +608,14 @@ def _validate_subscription(self, subscription: Subscription) -> None:
608608
subscription["coin"] = self.name_to_coin[subscription["coin"]]
609609

610610
def subscribe(self, subscription: Subscription, callback: Callable[[Any], None]) -> int:
611-
self._validate_subscription(subscription)
611+
self._remap_coin_subscription(subscription)
612612
if self.ws_manager is None:
613613
raise RuntimeError("Cannot call subscribe since skip_ws was used")
614614
else:
615615
return self.ws_manager.subscribe(subscription, callback)
616616

617617
def unsubscribe(self, subscription: Subscription, subscription_id: int) -> bool:
618-
self._validate_subscription(subscription)
618+
self._remap_coin_subscription(subscription)
619619
if self.ws_manager is None:
620620
raise RuntimeError("Cannot call unsubscribe since skip_ws was used")
621621
else:

hyperliquid/utils/signing.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@
104104
{"name": "nonce", "type": "uint64"},
105105
]
106106

107+
PERP_DEX_CLASS_TRANSFER_SIGN_TYPES = [
108+
{"name": "hyperliquidChain", "type": "string"},
109+
{"name": "dex", "type": "string"},
110+
{"name": "token", "type": "string"},
111+
{"name": "amount", "type": "string"},
112+
{"name": "toPerp", "type": "bool"},
113+
{"name": "nonce", "type": "uint64"},
114+
]
115+
107116
TOKEN_DELEGATE_TYPES = [
108117
{"name": "hyperliquidChain", "type": "string"},
109118
{"name": "validator", "type": "address"},
@@ -341,6 +350,16 @@ def sign_usd_class_transfer_action(wallet, action, is_mainnet):
341350
)
342351

343352

353+
def sign_perp_dex_class_transfer_action(wallet, action, is_mainnet):
354+
return sign_user_signed_action(
355+
wallet,
356+
action,
357+
PERP_DEX_CLASS_TRANSFER_SIGN_TYPES,
358+
"HyperliquidTransaction:PerpDexClassTransfer",
359+
is_mainnet,
360+
)
361+
362+
344363
def sign_convert_to_multi_sig_user_action(wallet, action, is_mainnet):
345364
return sign_user_signed_action(
346365
wallet,
@@ -392,7 +411,8 @@ def sign_token_delegate_action(wallet, action, is_mainnet):
392411

393412

394413
def sign_inner(wallet, data):
395-
signed = wallet.sign_typed_data(full_message=data)
414+
structured_data = encode_typed_data(full_message=data)
415+
signed = wallet.sign_message(structured_data)
396416
return {"r": to_hex(signed["r"]), "s": to_hex(signed["s"]), "v": signed["v"]}
397417

398418

hyperliquid/utils/types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@
6767
AllMidsData = TypedDict("AllMidsData", {"mids": Dict[str, str]})
6868
AllMidsMsg = TypedDict("AllMidsMsg", {"channel": Literal["allMids"], "data": AllMidsData})
6969
L2Level = TypedDict("L2Level", {"px": str, "sz": str, "n": int})
70-
BboData = TypedDict("BboData", {"coin": str, "time": int, "bbo": Tuple[Optional[L2Level], Optional[L2Level]]})
71-
BboMsg = TypedDict("BboMsg", {"channel": Literal["bbo"], "data": BboData})
7270
L2BookData = TypedDict("L2BookData", {"coin": str, "levels": Tuple[List[L2Level], List[L2Level]], "time": int})
7371
L2BookMsg = TypedDict("L2BookMsg", {"channel": Literal["l2Book"], "data": L2BookData})
72+
BboData = TypedDict("BboData", {"coin": str, "time": int, "bbo": Tuple[Optional[L2Level], Optional[L2Level]]})
73+
BboMsg = TypedDict("BboMsg", {"channel": Literal["bbo"], "data": BboData})
7474
PongMsg = TypedDict("PongMsg", {"channel": Literal["pong"]})
7575
Trade = TypedDict("Trade", {"coin": str, "side": Side, "px": str, "sz": int, "hash": str, "time": int})
7676
TradesMsg = TypedDict("TradesMsg", {"channel": Literal["trades"], "data": List[Trade]})

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
55

66
[tool.poetry]
77
name = "hyperliquid-python-sdk"
8-
version = "0.14.1"
8+
version = "0.15.0"
99
description = "SDK for Hyperliquid API trading with Python."
1010
readme = "README.md"
1111
authors = ["Hyperliquid <hello@hyperliquid.xyz>"]

0 commit comments

Comments
 (0)