Skip to content

Refactor is_mainnet, add multisig validation, and update readme for local dev #105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ python examples/basic_order.py
make install
```

4. Run your local code with poetry

```bash
poetry run python examples/basic_order
```

### Makefile usage

CLI commands for faster development.
Expand Down
51 changes: 26 additions & 25 deletions hyperliquid/exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ def __init__(
self.account_address = account_address
self.info = Info(base_url, True, meta, spot_meta)

@property
def is_mainnet(self) -> bool:
return self.base_url == MAINNET_API_URL

def _post_action(self, action, signature, nonce):
payload = {
"action": action,
Expand Down Expand Up @@ -121,7 +125,7 @@ def bulk_orders(self, order_requests: List[OrderRequest], builder: Optional[Buil
order_action,
self.vault_address,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)

return self._post_action(
Expand Down Expand Up @@ -175,7 +179,7 @@ def bulk_modify_orders_new(self, modify_requests: List[ModifyRequest]) -> Any:
modify_action,
self.vault_address,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)

return self._post_action(
Expand Down Expand Up @@ -261,7 +265,7 @@ def bulk_cancel(self, cancel_requests: List[CancelRequest]) -> Any:
cancel_action,
self.vault_address,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)

return self._post_action(
Expand All @@ -288,7 +292,7 @@ def bulk_cancel_by_cloid(self, cancel_requests: List[CancelByCloidRequest]) -> A
cancel_action,
self.vault_address,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)

return self._post_action(
Expand Down Expand Up @@ -316,7 +320,7 @@ def schedule_cancel(self, time: Optional[int]) -> Any:
schedule_cancel_action,
self.vault_address,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)
return self._post_action(
schedule_cancel_action,
Expand All @@ -337,7 +341,7 @@ def update_leverage(self, leverage: int, name: str, is_cross: bool = True) -> An
update_leverage_action,
self.vault_address,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)
return self._post_action(
update_leverage_action,
Expand All @@ -359,7 +363,7 @@ def update_isolated_margin(self, amount: float, name: str) -> Any:
update_isolated_margin_action,
self.vault_address,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)
return self._post_action(
update_isolated_margin_action,
Expand All @@ -378,7 +382,7 @@ def set_referrer(self, code: str) -> Any:
set_referrer_action,
None,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)
return self._post_action(
set_referrer_action,
Expand All @@ -397,7 +401,7 @@ def create_sub_account(self, name: str) -> Any:
create_sub_account_action,
None,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)
return self._post_action(
create_sub_account_action,
Expand All @@ -417,7 +421,7 @@ def usd_class_transfer(self, amount: float, to_perp: bool) -> Any:
"toPerp": to_perp,
"nonce": timestamp,
}
signature = sign_usd_class_transfer_action(self.wallet, action, self.base_url == MAINNET_API_URL)
signature = sign_usd_class_transfer_action(self.wallet, action, self.is_mainnet)
return self._post_action(
action,
signature,
Expand All @@ -437,7 +441,7 @@ def sub_account_transfer(self, sub_account_user: str, is_deposit: bool, usd: int
sub_account_transfer_action,
None,
timestamp,
self.base_url == MAINNET_API_URL,
self.is_mainnet,
)
return self._post_action(
sub_account_transfer_action,
Expand All @@ -453,8 +457,7 @@ def vault_usd_transfer(self, vault_address: str, is_deposit: bool, usd: int) ->
"isDeposit": is_deposit,
"usd": usd,
}
is_mainnet = self.base_url == MAINNET_API_URL
signature = sign_l1_action(self.wallet, vault_transfer_action, None, timestamp, is_mainnet)
signature = sign_l1_action(self.wallet, vault_transfer_action, None, timestamp, self.is_mainnet)
return self._post_action(
vault_transfer_action,
signature,
Expand All @@ -464,8 +467,7 @@ def vault_usd_transfer(self, vault_address: str, is_deposit: bool, usd: int) ->
def usd_transfer(self, amount: float, destination: str) -> Any:
timestamp = get_timestamp_ms()
action = {"destination": destination, "amount": str(amount), "time": timestamp, "type": "usdSend"}
is_mainnet = self.base_url == MAINNET_API_URL
signature = sign_usd_transfer_action(self.wallet, action, is_mainnet)
signature = sign_usd_transfer_action(self.wallet, action, self.is_mainnet)
return self._post_action(
action,
signature,
Expand All @@ -481,8 +483,7 @@ def spot_transfer(self, amount: float, destination: str, token: str) -> Any:
"time": timestamp,
"type": "spotSend",
}
is_mainnet = self.base_url == MAINNET_API_URL
signature = sign_spot_transfer_action(self.wallet, action, is_mainnet)
signature = sign_spot_transfer_action(self.wallet, action, self.is_mainnet)
return self._post_action(
action,
signature,
Expand All @@ -492,8 +493,7 @@ def spot_transfer(self, amount: float, destination: str, token: str) -> Any:
def withdraw_from_bridge(self, amount: float, destination: str) -> Any:
timestamp = get_timestamp_ms()
action = {"destination": destination, "amount": str(amount), "time": timestamp, "type": "withdraw3"}
is_mainnet = self.base_url == MAINNET_API_URL
signature = sign_withdraw_from_bridge_action(self.wallet, action, is_mainnet)
signature = sign_withdraw_from_bridge_action(self.wallet, action, self.is_mainnet)
return self._post_action(
action,
signature,
Expand All @@ -504,14 +504,13 @@ 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)
timestamp = get_timestamp_ms()
is_mainnet = self.base_url == MAINNET_API_URL
action = {
"type": "approveAgent",
"agentAddress": account.address,
"agentName": name or "",
"nonce": timestamp,
}
signature = sign_agent(self.wallet, action, is_mainnet)
signature = sign_agent(self.wallet, action, self.is_mainnet)
if name is None:
del action["agentName"]

Expand All @@ -528,7 +527,7 @@ def approve_builder_fee(self, builder: str, max_fee_rate: str) -> Any:
timestamp = get_timestamp_ms()

action = {"maxFeeRate": max_fee_rate, "builder": builder, "nonce": timestamp, "type": "approveBuilderFee"}
signature = sign_approve_builder_fee(self.wallet, action, self.base_url == MAINNET_API_URL)
signature = sign_approve_builder_fee(self.wallet, action, self.is_mainnet)
return self._post_action(action, signature, timestamp)

def convert_to_multi_sig_user(self, authorized_users: List[str], threshold: int) -> Any:
Expand All @@ -543,14 +542,17 @@ def convert_to_multi_sig_user(self, authorized_users: List[str], threshold: int)
"signers": json.dumps(signers),
"nonce": timestamp,
}
signature = sign_convert_to_multi_sig_user_action(self.wallet, action, self.base_url == MAINNET_API_URL)
signature = sign_convert_to_multi_sig_user_action(self.wallet, action, self.is_mainnet)
return self._post_action(
action,
signature,
timestamp,
)

def multi_sig(self, multi_sig_user, inner_action, signatures, nonce, vault_address=None):
# Currently, we only support up to 10 authorized users for multi-sig
assert len(signatures) <= 10, "Only up to 10 authorized users are supported for multi-sig"

multi_sig_user = multi_sig_user.lower()
multi_sig_action = {
"type": "multiSig",
Expand All @@ -562,11 +564,10 @@ def multi_sig(self, multi_sig_user, inner_action, signatures, nonce, vault_addre
"action": inner_action,
},
}
is_mainnet = self.base_url == MAINNET_API_URL
signature = sign_multi_sig_action(
self.wallet,
multi_sig_action,
is_mainnet,
self.is_mainnet,
vault_address,
nonce,
)
Expand Down