Skip to content

Commit ef147ea

Browse files
author
Louis Tao
committed
Version 0.2.3
1 parent 84b854f commit ef147ea

File tree

5 files changed

+97
-1
lines changed

5 files changed

+97
-1
lines changed

examples/basic_schedule_cancel.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import time
2+
3+
from hyperliquid.utils import constants
4+
from hyperliquid.utils.signing import get_timestamp_ms
5+
import example_utils
6+
7+
8+
def main():
9+
address, info, exchange = example_utils.setup(base_url=constants.TESTNET_API_URL, skip_ws=True)
10+
11+
# Place an order that should rest by setting the price very low
12+
order_result = exchange.order("ETH", True, 0.2, 1100, {"limit": {"tif": "Gtc"}})
13+
print(order_result)
14+
15+
# Query the order status by oid
16+
if order_result["status"] == "ok":
17+
status = order_result["response"]["data"]["statuses"][0]
18+
if "resting" in status:
19+
order_status = info.query_order_by_oid(address, status["resting"]["oid"])
20+
print("Order status by oid:", order_status)
21+
22+
# Schedule cancel
23+
cancel_time = get_timestamp_ms() + 10000 # 10 seconds from now
24+
print(exchange.schedule_cancel(cancel_time))
25+
26+
time.sleep(10)
27+
print("open orders:", info.open_orders(address))
28+
29+
30+
if __name__ == "__main__":
31+
main()

hyperliquid/exchange.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
OrderRequest,
1717
OrderType,
1818
OrderWire,
19+
ScheduleCancelAction,
1920
float_to_usd_int,
2021
get_timestamp_ms,
2122
order_request_to_order_wire,
@@ -278,6 +279,33 @@ def bulk_cancel_by_cloid(self, cancel_requests: List[CancelByCloidRequest]) -> A
278279
timestamp,
279280
)
280281

282+
def schedule_cancel(self, time: Optional[int]) -> Any:
283+
"""Schedules a time (in UTC millis) to cancel all open orders. The time must be at least 5 seconds after the current time.
284+
Once the time comes, all open orders will be canceled and a trigger count will be incremented. The max number of triggers
285+
per day is 10. This trigger count is reset at 00:00 UTC.
286+
287+
Args:
288+
time (int): if time is not None, then set the cancel time in the future. If None, then unsets any cancel time in the future.
289+
"""
290+
timestamp = get_timestamp_ms()
291+
schedule_cancel_action: ScheduleCancelAction = {
292+
"type": "scheduleCancel",
293+
}
294+
if time is not None:
295+
schedule_cancel_action["time"] = time
296+
signature = sign_l1_action(
297+
self.wallet,
298+
schedule_cancel_action,
299+
self.vault_address,
300+
timestamp,
301+
self.base_url == MAINNET_API_URL,
302+
)
303+
return self._post_action(
304+
schedule_cancel_action,
305+
signature,
306+
timestamp,
307+
)
308+
281309
def update_leverage(self, leverage: int, coin: str, is_cross: bool = True) -> Any:
282310
timestamp = get_timestamp_ms()
283311
asset = self.coin_to_asset[coin]

hyperliquid/utils/signing.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@
6565
},
6666
)
6767

68+
ScheduleCancelAction = TypedDict(
69+
"ScheduleCancelAction",
70+
{
71+
"type": Literal["scheduleCancel"],
72+
"time": NotRequired[Optional[int]],
73+
},
74+
)
75+
6876

6977
def order_type_to_wire(order_type: OrderType) -> OrderTypeWire:
7078
if "limit" in order_type:

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.2.2"
8+
version = "0.2.3"
99
description = "SDK for Hyperliquid API trading with Python."
1010
readme = "README.md"
1111
authors = ["Hyperliquid <[email protected]>"]

tests/signing_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from hyperliquid.utils.signing import (
66
action_hash,
77
OrderRequest,
8+
ScheduleCancelAction,
89
construct_phantom_agent,
910
float_to_int_for_hashing,
1011
order_request_to_order_wire,
@@ -236,3 +237,31 @@ def test_sub_account_transfer_action():
236237
assert signature_testnet["r"] == "0xe26574013395ad55ee2f4e0575310f003c5bb3351b5425482e2969fa51543927"
237238
assert signature_testnet["s"] == "0xefb08999196366871f919fd0e138b3a7f30ee33e678df7cfaf203e25f0a4278"
238239
assert signature_testnet["v"] == 28
240+
241+
242+
def test_schedule_cancel_action():
243+
wallet = eth_account.Account.from_key("0x0123456789012345678901234567890123456789012345678901234567890123")
244+
action: ScheduleCancelAction = {
245+
"type": "scheduleCancel",
246+
}
247+
signature_mainnet = sign_l1_action(wallet, action, None, 0, True)
248+
assert signature_mainnet["r"] == "0x6cdfb286702f5917e76cd9b3b8bf678fcc49aec194c02a73e6d4f16891195df9"
249+
assert signature_mainnet["s"] == "0x6557ac307fa05d25b8d61f21fb8a938e703b3d9bf575f6717ba21ec61261b2a0"
250+
assert signature_mainnet["v"] == 27
251+
signature_testnet = sign_l1_action(wallet, action, None, 0, False)
252+
assert signature_testnet["r"] == "0xc75bb195c3f6a4e06b7d395acc20bbb224f6d23ccff7c6a26d327304e6efaeed"
253+
assert signature_testnet["s"] == "0x342f8ede109a29f2c0723bd5efb9e9100e3bbb493f8fb5164ee3d385908233df"
254+
assert signature_testnet["v"] == 28
255+
256+
action = {
257+
"type": "scheduleCancel",
258+
"time": 123456789,
259+
}
260+
signature_mainnet = sign_l1_action(wallet, action, None, 0, True)
261+
assert signature_mainnet["r"] == "0x609cb20c737945d070716dcc696ba030e9976fcf5edad87afa7d877493109d55"
262+
assert signature_mainnet["s"] == "0x16c685d63b5c7a04512d73f183b3d7a00da5406ff1f8aad33f8ae2163bab758b"
263+
assert signature_mainnet["v"] == 28
264+
signature_testnet = sign_l1_action(wallet, action, None, 0, False)
265+
assert signature_testnet["r"] == "0x4e4f2dbd4107c69783e251b7e1057d9f2b9d11cee213441ccfa2be63516dc5bc"
266+
assert signature_testnet["s"] == "0x706c656b23428c8ba356d68db207e11139ede1670481a9e01ae2dfcdb0e1a678"
267+
assert signature_testnet["v"] == 27

0 commit comments

Comments
 (0)