From 51a235fbade25797a79d889616c98d5c32e15429 Mon Sep 17 00:00:00 2001 From: Ben Razon Date: Tue, 5 Dec 2023 17:13:45 -0800 Subject: [PATCH] Version 0.1.17 --- examples/basic_transfer.py | 2 +- examples/basic_withdraw.py | 21 +++++++++++++++++++++ hyperliquid/exchange.py | 22 +++++++++++++++++++++- hyperliquid/utils/signing.py | 27 +++++++++++++++++++++++++++ pyproject.toml | 2 +- tests/signing_test.py | 14 ++++++++++++++ 6 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 examples/basic_withdraw.py diff --git a/examples/basic_transfer.py b/examples/basic_transfer.py index f0e16da..ecfaa8a 100644 --- a/examples/basic_transfer.py +++ b/examples/basic_transfer.py @@ -13,7 +13,7 @@ def main(): # Transfer 1 usd to the zero address for demonstration purposes exchange = Exchange(account, constants.TESTNET_API_URL) - transfer_result = exchange.usd_tranfer(1, "0x0000000000000000000000000000000000000000") + transfer_result = exchange.usd_transfer(1, "0x0000000000000000000000000000000000000000") print(transfer_result) diff --git a/examples/basic_withdraw.py b/examples/basic_withdraw.py new file mode 100644 index 0000000..81f1c65 --- /dev/null +++ b/examples/basic_withdraw.py @@ -0,0 +1,21 @@ +import eth_account +import utils +from eth_account.signers.local import LocalAccount + +from hyperliquid.exchange import Exchange +from hyperliquid.utils import constants + + +def main(): + config = utils.get_config() + account: LocalAccount = eth_account.Account.from_key(config["secret_key"]) + print("Running with account address:", account.address) + + # Withdraw 1 usd + exchange = Exchange(account, constants.TESTNET_API_URL) + withdraw_result = exchange.withdraw_from_bridge(1, account.address) + print(withdraw_result) + + +if __name__ == "__main__": + main() diff --git a/hyperliquid/exchange.py b/hyperliquid/exchange.py index 5cff636..87c5c50 100644 --- a/hyperliquid/exchange.py +++ b/hyperliquid/exchange.py @@ -24,6 +24,7 @@ order_spec_to_order_wire, sign_l1_action, sign_usd_transfer_action, + sign_withdraw_from_bridge_action, sign_agent, str_to_bytes16, ) @@ -335,7 +336,7 @@ def update_isolated_margin(self, amount: float, coin: str) -> Any: timestamp, ) - def usd_tranfer(self, amount: float, destination: str) -> Any: + def usd_transfer(self, amount: float, destination: str) -> Any: timestamp = get_timestamp_ms() payload = { "destination": destination, @@ -354,6 +355,25 @@ def usd_tranfer(self, amount: float, destination: str) -> Any: timestamp, ) + def withdraw_from_bridge(self, usd: float, destination: str) -> Any: + timestamp = get_timestamp_ms() + payload = { + "destination": destination, + "usd": str(usd), + "time": timestamp, + } + is_mainnet = self.base_url == MAINNET_API_URL + signature = sign_withdraw_from_bridge_action(self.wallet, payload, is_mainnet) + return self._post_action( + { + "chain": "Arbitrum" if is_mainnet else "ArbitrumTestnet", + "payload": payload, + "type": "withdraw2", + }, + signature, + timestamp, + ) + def approve_agent(self, name: Optional[str] = None) -> Tuple[Any, str]: agent_key = "0x" + secrets.token_hex(32) account = eth_account.Account.from_key(agent_key) diff --git a/hyperliquid/utils/signing.py b/hyperliquid/utils/signing.py index e47873a..adf9611 100644 --- a/hyperliquid/utils/signing.py +++ b/hyperliquid/utils/signing.py @@ -203,6 +203,33 @@ def sign_usd_transfer_action(wallet, message, is_mainnet): return sign_inner(wallet, data) +def sign_withdraw_from_bridge_action(wallet, message, is_mainnet): + data = { + "domain": { + "name": "Exchange", + "version": "1", + "chainId": 42161 if is_mainnet else 421614, + "verifyingContract": "0x0000000000000000000000000000000000000000", + }, + "types": { + "WithdrawFromBridge2SignPayload": [ + {"name": "destination", "type": "string"}, + {"name": "usd", "type": "string"}, + {"name": "time", "type": "uint64"}, + ], + "EIP712Domain": [ + {"name": "name", "type": "string"}, + {"name": "version", "type": "string"}, + {"name": "chainId", "type": "uint256"}, + {"name": "verifyingContract", "type": "address"}, + ], + }, + "primaryType": "WithdrawFromBridge2SignPayload", + "message": message, + } + return sign_inner(wallet, data) + + def sign_agent(wallet, agent, is_mainnet): data = { "domain": { diff --git a/pyproject.toml b/pyproject.toml index ccc49c5..be6fbcf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "hyperliquid-python-sdk" -version = "0.1.16" +version = "0.1.17" description = "SDK for Hyperliquid API trading with Python." readme = "README.md" authors = ["Hyperliquid "] diff --git a/tests/signing_test.py b/tests/signing_test.py index 5f7d543..aaac21c 100644 --- a/tests/signing_test.py +++ b/tests/signing_test.py @@ -13,6 +13,7 @@ order_spec_preprocessing, sign_l1_action, sign_usd_transfer_action, + sign_withdraw_from_bridge_action, ) from hyperliquid.utils.types import Cloid @@ -210,3 +211,16 @@ def test_sign_usd_transfer_action(): assert signature["r"] == "0x283ca602ac69be536bd2272f050eddf8d250ed3eef083d1fc26989e57f891759" assert signature["s"] == "0x9bc743cf95042269236bc7f48c06ab8a6a9ee53e04f3336c6cfd1b22783aa74" assert signature["v"] == 28 + + +def test_sign_withdraw_from_bridge_action(): + wallet = eth_account.Account.from_key("0x0123456789012345678901234567890123456789012345678901234567890123") + message = { + "destination": "0x5e9ee1089755c3435139848e47e6635505d5a13a", + "usd": "1", + "time": 1687816341423, + } + signature = sign_withdraw_from_bridge_action(wallet, message, False) + assert signature["r"] == "0xd60816bf99a00645aa81b9ade23f03bf15994cd2c6d06fc3740a4c74530e36d9" + assert signature["s"] == "0x4552f30419166a6e9d8dbd49b14aeef1e7606fe9e0caec8c0211608d79ce43a3" + assert signature["v"] == 28