hyperliquid-python-sdk-async 0.24.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hyperliquid/__init__.py +0 -0
- hyperliquid/api.py +69 -0
- hyperliquid/exchange.py +888 -0
- hyperliquid/info.py +288 -0
- hyperliquid/utils/__init__.py +0 -0
- hyperliquid/utils/constants.py +3 -0
- hyperliquid/utils/error.py +17 -0
- hyperliquid/utils/signing.py +527 -0
- hyperliquid/utils/types.py +220 -0
- hyperliquid/websocket_manager.py +197 -0
- hyperliquid_python_sdk_async-0.24.6.dist-info/LICENSE.md +21 -0
- hyperliquid_python_sdk_async-0.24.6.dist-info/METADATA +162 -0
- hyperliquid_python_sdk_async-0.24.6.dist-info/RECORD +15 -0
- hyperliquid_python_sdk_async-0.24.6.dist-info/WHEEL +4 -0
- hyperliquid_python_sdk_async-0.24.6.dist-info/entry_points.txt +3 -0
hyperliquid/exchange.py
ADDED
|
@@ -0,0 +1,888 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
import secrets
|
|
5
|
+
|
|
6
|
+
import eth_account
|
|
7
|
+
from eth_account.signers.local import LocalAccount
|
|
8
|
+
|
|
9
|
+
from hyperliquid.api import API
|
|
10
|
+
from hyperliquid.info import Info
|
|
11
|
+
from hyperliquid.utils.constants import MAINNET_API_URL
|
|
12
|
+
from hyperliquid.utils.signing import (
|
|
13
|
+
CancelByCloidRequest,
|
|
14
|
+
CancelRequest,
|
|
15
|
+
Grouping,
|
|
16
|
+
ModifyRequest,
|
|
17
|
+
OidOrCloid,
|
|
18
|
+
OrderRequest,
|
|
19
|
+
OrderType,
|
|
20
|
+
OrderWire,
|
|
21
|
+
ScheduleCancelAction,
|
|
22
|
+
float_to_usd_int,
|
|
23
|
+
get_timestamp_ms,
|
|
24
|
+
order_request_to_order_wire,
|
|
25
|
+
order_wires_to_order_action,
|
|
26
|
+
sign_agent,
|
|
27
|
+
sign_approve_builder_fee,
|
|
28
|
+
sign_convert_to_multi_sig_user_action,
|
|
29
|
+
sign_l1_action,
|
|
30
|
+
sign_multi_sig_action,
|
|
31
|
+
sign_send_asset_action,
|
|
32
|
+
sign_spot_transfer_action,
|
|
33
|
+
sign_token_delegate_action,
|
|
34
|
+
sign_usd_class_transfer_action,
|
|
35
|
+
sign_usd_transfer_action,
|
|
36
|
+
sign_user_dex_abstraction_action,
|
|
37
|
+
sign_user_set_abstraction_action,
|
|
38
|
+
sign_withdraw_from_bridge_action,
|
|
39
|
+
)
|
|
40
|
+
from hyperliquid.utils.types import (
|
|
41
|
+
Abstraction,
|
|
42
|
+
AgentAbstraction,
|
|
43
|
+
Any,
|
|
44
|
+
BuilderInfo,
|
|
45
|
+
Cloid,
|
|
46
|
+
Dict,
|
|
47
|
+
List,
|
|
48
|
+
Meta,
|
|
49
|
+
Optional,
|
|
50
|
+
PerpDexSchemaInput,
|
|
51
|
+
SpotMeta,
|
|
52
|
+
Tuple,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _get_dex(coin: str) -> str:
|
|
57
|
+
return coin.split(":")[0] if ":" in coin else ""
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
USER_SET_ABSTRACTION_WIRE_VALUES = {
|
|
61
|
+
"disabled": "i",
|
|
62
|
+
"unifiedAccount": "u",
|
|
63
|
+
"portfolioMargin": "p",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _multi_sig_payload_action(inner_action):
|
|
68
|
+
if inner_action.get("type") != "userSetAbstraction":
|
|
69
|
+
return inner_action
|
|
70
|
+
|
|
71
|
+
abstraction = inner_action.get("abstraction")
|
|
72
|
+
if abstraction not in USER_SET_ABSTRACTION_WIRE_VALUES:
|
|
73
|
+
return inner_action
|
|
74
|
+
|
|
75
|
+
payload_action = inner_action.copy()
|
|
76
|
+
payload_action["abstraction"] = USER_SET_ABSTRACTION_WIRE_VALUES[abstraction]
|
|
77
|
+
return payload_action
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class Exchange(API):
|
|
81
|
+
DEFAULT_SLIPPAGE = 0.05
|
|
82
|
+
|
|
83
|
+
def __init__(
|
|
84
|
+
self,
|
|
85
|
+
wallet: LocalAccount,
|
|
86
|
+
base_url: Optional[str] = None,
|
|
87
|
+
meta: Optional[Meta] = None,
|
|
88
|
+
vault_address: Optional[str] = None,
|
|
89
|
+
account_address: Optional[str] = None,
|
|
90
|
+
spot_meta: Optional[SpotMeta] = None,
|
|
91
|
+
perp_dexs: Optional[List[str]] = None,
|
|
92
|
+
timeout: Optional[float] = None,
|
|
93
|
+
session=None,
|
|
94
|
+
):
|
|
95
|
+
super().__init__(base_url, timeout, session=session)
|
|
96
|
+
self.wallet = wallet
|
|
97
|
+
self.vault_address = vault_address
|
|
98
|
+
self.account_address = account_address
|
|
99
|
+
self.info = Info(base_url, True, meta, spot_meta, perp_dexs, timeout, session=session)
|
|
100
|
+
self.expires_after: Optional[int] = None
|
|
101
|
+
self._initialized = False
|
|
102
|
+
self._init_lock = asyncio.Lock()
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
async def create(cls, *args, **kwargs) -> "Exchange":
|
|
106
|
+
client = cls(*args, **kwargs)
|
|
107
|
+
await client.initialize()
|
|
108
|
+
return client
|
|
109
|
+
|
|
110
|
+
async def initialize(self) -> "Exchange":
|
|
111
|
+
if self._initialized:
|
|
112
|
+
return self
|
|
113
|
+
|
|
114
|
+
async with self._init_lock:
|
|
115
|
+
if self._initialized:
|
|
116
|
+
return self
|
|
117
|
+
session = await self._ensure_session()
|
|
118
|
+
self.info.session = session
|
|
119
|
+
self.info._owns_session = False
|
|
120
|
+
await self.info.initialize()
|
|
121
|
+
self._initialized = True
|
|
122
|
+
return self
|
|
123
|
+
|
|
124
|
+
async def _ensure_initialized(self) -> None:
|
|
125
|
+
if not self._initialized:
|
|
126
|
+
await self.initialize()
|
|
127
|
+
|
|
128
|
+
async def aclose(self) -> None:
|
|
129
|
+
await self.info.aclose()
|
|
130
|
+
await super().aclose()
|
|
131
|
+
|
|
132
|
+
async def _post_action(self, action, signature, nonce):
|
|
133
|
+
payload = {
|
|
134
|
+
"action": action,
|
|
135
|
+
"nonce": nonce,
|
|
136
|
+
"signature": signature,
|
|
137
|
+
"vaultAddress": self.vault_address if action["type"] not in ["usdClassTransfer", "sendAsset"] else None,
|
|
138
|
+
"expiresAfter": self.expires_after,
|
|
139
|
+
}
|
|
140
|
+
logging.debug(payload)
|
|
141
|
+
return await self.post("/exchange", payload)
|
|
142
|
+
|
|
143
|
+
async def _slippage_price(
|
|
144
|
+
self,
|
|
145
|
+
name: str,
|
|
146
|
+
is_buy: bool,
|
|
147
|
+
slippage: float,
|
|
148
|
+
px: Optional[float] = None,
|
|
149
|
+
) -> float:
|
|
150
|
+
await self._ensure_initialized()
|
|
151
|
+
coin = self.info.name_to_coin[name]
|
|
152
|
+
if not px:
|
|
153
|
+
dex = _get_dex(coin)
|
|
154
|
+
px = float((await self.info.all_mids(dex))[coin])
|
|
155
|
+
|
|
156
|
+
asset = self.info.coin_to_asset[coin]
|
|
157
|
+
is_spot = asset >= 10_000
|
|
158
|
+
px *= (1 + slippage) if is_buy else (1 - slippage)
|
|
159
|
+
return round(float(f"{px:.5g}"), (6 if not is_spot else 8) - self.info.asset_to_sz_decimals[asset])
|
|
160
|
+
|
|
161
|
+
def set_expires_after(self, expires_after: Optional[int]) -> None:
|
|
162
|
+
self.expires_after = expires_after
|
|
163
|
+
|
|
164
|
+
async def order(
|
|
165
|
+
self,
|
|
166
|
+
name: str,
|
|
167
|
+
is_buy: bool,
|
|
168
|
+
sz: float,
|
|
169
|
+
limit_px: float,
|
|
170
|
+
order_type: OrderType,
|
|
171
|
+
reduce_only: bool = False,
|
|
172
|
+
cloid: Optional[Cloid] = None,
|
|
173
|
+
builder: Optional[BuilderInfo] = None,
|
|
174
|
+
) -> Any:
|
|
175
|
+
order: OrderRequest = {
|
|
176
|
+
"coin": name,
|
|
177
|
+
"is_buy": is_buy,
|
|
178
|
+
"sz": sz,
|
|
179
|
+
"limit_px": limit_px,
|
|
180
|
+
"order_type": order_type,
|
|
181
|
+
"reduce_only": reduce_only,
|
|
182
|
+
}
|
|
183
|
+
if cloid:
|
|
184
|
+
order["cloid"] = cloid
|
|
185
|
+
return await self.bulk_orders([order], builder)
|
|
186
|
+
|
|
187
|
+
async def bulk_orders(
|
|
188
|
+
self, order_requests: List[OrderRequest], builder: Optional[BuilderInfo] = None, grouping: Grouping = "na"
|
|
189
|
+
) -> Any:
|
|
190
|
+
await self._ensure_initialized()
|
|
191
|
+
order_wires: List[OrderWire] = [
|
|
192
|
+
order_request_to_order_wire(order, await self.info.name_to_asset(order["coin"])) for order in order_requests
|
|
193
|
+
]
|
|
194
|
+
timestamp = get_timestamp_ms()
|
|
195
|
+
|
|
196
|
+
if builder:
|
|
197
|
+
builder["b"] = builder["b"].lower()
|
|
198
|
+
order_action = order_wires_to_order_action(order_wires, builder, grouping)
|
|
199
|
+
|
|
200
|
+
signature = sign_l1_action(
|
|
201
|
+
self.wallet,
|
|
202
|
+
order_action,
|
|
203
|
+
self.vault_address,
|
|
204
|
+
timestamp,
|
|
205
|
+
self.expires_after,
|
|
206
|
+
self.base_url == MAINNET_API_URL,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
return await self._post_action(order_action, signature, timestamp)
|
|
210
|
+
|
|
211
|
+
async def modify_order(
|
|
212
|
+
self,
|
|
213
|
+
oid: OidOrCloid,
|
|
214
|
+
name: str,
|
|
215
|
+
is_buy: bool,
|
|
216
|
+
sz: float,
|
|
217
|
+
limit_px: float,
|
|
218
|
+
order_type: OrderType,
|
|
219
|
+
reduce_only: bool = False,
|
|
220
|
+
cloid: Optional[Cloid] = None,
|
|
221
|
+
) -> Any:
|
|
222
|
+
modify: ModifyRequest = {
|
|
223
|
+
"oid": oid,
|
|
224
|
+
"order": {
|
|
225
|
+
"coin": name,
|
|
226
|
+
"is_buy": is_buy,
|
|
227
|
+
"sz": sz,
|
|
228
|
+
"limit_px": limit_px,
|
|
229
|
+
"order_type": order_type,
|
|
230
|
+
"reduce_only": reduce_only,
|
|
231
|
+
"cloid": cloid,
|
|
232
|
+
},
|
|
233
|
+
}
|
|
234
|
+
return await self.bulk_modify_orders_new([modify])
|
|
235
|
+
|
|
236
|
+
async def bulk_modify_orders_new(self, modify_requests: List[ModifyRequest]) -> Any:
|
|
237
|
+
await self._ensure_initialized()
|
|
238
|
+
timestamp = get_timestamp_ms()
|
|
239
|
+
modify_wires = [
|
|
240
|
+
{
|
|
241
|
+
"oid": modify["oid"].to_raw() if isinstance(modify["oid"], Cloid) else modify["oid"],
|
|
242
|
+
"order": order_request_to_order_wire(
|
|
243
|
+
modify["order"], await self.info.name_to_asset(modify["order"]["coin"])
|
|
244
|
+
),
|
|
245
|
+
}
|
|
246
|
+
for modify in modify_requests
|
|
247
|
+
]
|
|
248
|
+
|
|
249
|
+
modify_action = {
|
|
250
|
+
"type": "batchModify",
|
|
251
|
+
"modifies": modify_wires,
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
signature = sign_l1_action(
|
|
255
|
+
self.wallet,
|
|
256
|
+
modify_action,
|
|
257
|
+
self.vault_address,
|
|
258
|
+
timestamp,
|
|
259
|
+
self.expires_after,
|
|
260
|
+
self.base_url == MAINNET_API_URL,
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
return await self._post_action(modify_action, signature, timestamp)
|
|
264
|
+
|
|
265
|
+
async def market_open(
|
|
266
|
+
self,
|
|
267
|
+
name: str,
|
|
268
|
+
is_buy: bool,
|
|
269
|
+
sz: float,
|
|
270
|
+
px: Optional[float] = None,
|
|
271
|
+
slippage: float = DEFAULT_SLIPPAGE,
|
|
272
|
+
cloid: Optional[Cloid] = None,
|
|
273
|
+
builder: Optional[BuilderInfo] = None,
|
|
274
|
+
) -> Any:
|
|
275
|
+
px = await self._slippage_price(name, is_buy, slippage, px)
|
|
276
|
+
return await self.order(
|
|
277
|
+
name, is_buy, sz, px, order_type={"limit": {"tif": "Ioc"}}, reduce_only=False, cloid=cloid, builder=builder
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
async def market_close(
|
|
281
|
+
self,
|
|
282
|
+
coin: str,
|
|
283
|
+
sz: Optional[float] = None,
|
|
284
|
+
px: Optional[float] = None,
|
|
285
|
+
slippage: float = DEFAULT_SLIPPAGE,
|
|
286
|
+
cloid: Optional[Cloid] = None,
|
|
287
|
+
builder: Optional[BuilderInfo] = None,
|
|
288
|
+
) -> Any:
|
|
289
|
+
await self._ensure_initialized()
|
|
290
|
+
address: str = self.wallet.address
|
|
291
|
+
if self.account_address:
|
|
292
|
+
address = self.account_address
|
|
293
|
+
if self.vault_address:
|
|
294
|
+
address = self.vault_address
|
|
295
|
+
dex = _get_dex(coin)
|
|
296
|
+
positions = (await self.info.user_state(address, dex))["assetPositions"]
|
|
297
|
+
for position in positions:
|
|
298
|
+
item = position["position"]
|
|
299
|
+
if coin != item["coin"]:
|
|
300
|
+
continue
|
|
301
|
+
szi = float(item["szi"])
|
|
302
|
+
if not sz:
|
|
303
|
+
sz = abs(szi)
|
|
304
|
+
is_buy = szi < 0
|
|
305
|
+
px = await self._slippage_price(coin, is_buy, slippage, px)
|
|
306
|
+
return await self.order(
|
|
307
|
+
coin,
|
|
308
|
+
is_buy,
|
|
309
|
+
sz,
|
|
310
|
+
px,
|
|
311
|
+
order_type={"limit": {"tif": "Ioc"}},
|
|
312
|
+
reduce_only=True,
|
|
313
|
+
cloid=cloid,
|
|
314
|
+
builder=builder,
|
|
315
|
+
)
|
|
316
|
+
return None
|
|
317
|
+
|
|
318
|
+
async def cancel(self, name: str, oid: int) -> Any:
|
|
319
|
+
return await self.bulk_cancel([{"coin": name, "oid": oid}])
|
|
320
|
+
|
|
321
|
+
async def cancel_by_cloid(self, name: str, cloid: Cloid) -> Any:
|
|
322
|
+
return await self.bulk_cancel_by_cloid([{"coin": name, "cloid": cloid}])
|
|
323
|
+
|
|
324
|
+
async def bulk_cancel(self, cancel_requests: List[CancelRequest]) -> Any:
|
|
325
|
+
await self._ensure_initialized()
|
|
326
|
+
timestamp = get_timestamp_ms()
|
|
327
|
+
cancel_action = {
|
|
328
|
+
"type": "cancel",
|
|
329
|
+
"cancels": [{"a": await self.info.name_to_asset(cancel["coin"]), "o": cancel["oid"]} for cancel in cancel_requests],
|
|
330
|
+
}
|
|
331
|
+
signature = sign_l1_action(
|
|
332
|
+
self.wallet,
|
|
333
|
+
cancel_action,
|
|
334
|
+
self.vault_address,
|
|
335
|
+
timestamp,
|
|
336
|
+
self.expires_after,
|
|
337
|
+
self.base_url == MAINNET_API_URL,
|
|
338
|
+
)
|
|
339
|
+
return await self._post_action(cancel_action, signature, timestamp)
|
|
340
|
+
|
|
341
|
+
async def bulk_cancel_by_cloid(self, cancel_requests: List[CancelByCloidRequest]) -> Any:
|
|
342
|
+
await self._ensure_initialized()
|
|
343
|
+
timestamp = get_timestamp_ms()
|
|
344
|
+
cancel_action = {
|
|
345
|
+
"type": "cancelByCloid",
|
|
346
|
+
"cancels": [
|
|
347
|
+
{"asset": await self.info.name_to_asset(cancel["coin"]), "cloid": cancel["cloid"].to_raw()}
|
|
348
|
+
for cancel in cancel_requests
|
|
349
|
+
],
|
|
350
|
+
}
|
|
351
|
+
signature = sign_l1_action(
|
|
352
|
+
self.wallet,
|
|
353
|
+
cancel_action,
|
|
354
|
+
self.vault_address,
|
|
355
|
+
timestamp,
|
|
356
|
+
self.expires_after,
|
|
357
|
+
self.base_url == MAINNET_API_URL,
|
|
358
|
+
)
|
|
359
|
+
return await self._post_action(cancel_action, signature, timestamp)
|
|
360
|
+
|
|
361
|
+
async def schedule_cancel(self, time: Optional[int]) -> Any:
|
|
362
|
+
timestamp = get_timestamp_ms()
|
|
363
|
+
schedule_cancel_action: ScheduleCancelAction = {"type": "scheduleCancel"}
|
|
364
|
+
if time is not None:
|
|
365
|
+
schedule_cancel_action["time"] = time
|
|
366
|
+
signature = sign_l1_action(
|
|
367
|
+
self.wallet,
|
|
368
|
+
schedule_cancel_action,
|
|
369
|
+
self.vault_address,
|
|
370
|
+
timestamp,
|
|
371
|
+
self.expires_after,
|
|
372
|
+
self.base_url == MAINNET_API_URL,
|
|
373
|
+
)
|
|
374
|
+
return await self._post_action(schedule_cancel_action, signature, timestamp)
|
|
375
|
+
|
|
376
|
+
async def update_leverage(self, leverage: int, name: str, is_cross: bool = True) -> Any:
|
|
377
|
+
await self._ensure_initialized()
|
|
378
|
+
timestamp = get_timestamp_ms()
|
|
379
|
+
update_leverage_action = {
|
|
380
|
+
"type": "updateLeverage",
|
|
381
|
+
"asset": await self.info.name_to_asset(name),
|
|
382
|
+
"isCross": is_cross,
|
|
383
|
+
"leverage": leverage,
|
|
384
|
+
}
|
|
385
|
+
signature = sign_l1_action(
|
|
386
|
+
self.wallet,
|
|
387
|
+
update_leverage_action,
|
|
388
|
+
self.vault_address,
|
|
389
|
+
timestamp,
|
|
390
|
+
self.expires_after,
|
|
391
|
+
self.base_url == MAINNET_API_URL,
|
|
392
|
+
)
|
|
393
|
+
return await self._post_action(update_leverage_action, signature, timestamp)
|
|
394
|
+
|
|
395
|
+
async def update_isolated_margin(self, amount: float, name: str) -> Any:
|
|
396
|
+
await self._ensure_initialized()
|
|
397
|
+
timestamp = get_timestamp_ms()
|
|
398
|
+
amount = float_to_usd_int(amount)
|
|
399
|
+
update_isolated_margin_action = {
|
|
400
|
+
"type": "updateIsolatedMargin",
|
|
401
|
+
"asset": await self.info.name_to_asset(name),
|
|
402
|
+
"isBuy": True,
|
|
403
|
+
"ntli": amount,
|
|
404
|
+
}
|
|
405
|
+
signature = sign_l1_action(
|
|
406
|
+
self.wallet,
|
|
407
|
+
update_isolated_margin_action,
|
|
408
|
+
self.vault_address,
|
|
409
|
+
timestamp,
|
|
410
|
+
self.expires_after,
|
|
411
|
+
self.base_url == MAINNET_API_URL,
|
|
412
|
+
)
|
|
413
|
+
return await self._post_action(update_isolated_margin_action, signature, timestamp)
|
|
414
|
+
|
|
415
|
+
async def set_referrer(self, code: str) -> Any:
|
|
416
|
+
timestamp = get_timestamp_ms()
|
|
417
|
+
set_referrer_action = {"type": "setReferrer", "code": code}
|
|
418
|
+
signature = sign_l1_action(
|
|
419
|
+
self.wallet,
|
|
420
|
+
set_referrer_action,
|
|
421
|
+
None,
|
|
422
|
+
timestamp,
|
|
423
|
+
self.expires_after,
|
|
424
|
+
self.base_url == MAINNET_API_URL,
|
|
425
|
+
)
|
|
426
|
+
return await self._post_action(set_referrer_action, signature, timestamp)
|
|
427
|
+
|
|
428
|
+
async def create_sub_account(self, name: str) -> Any:
|
|
429
|
+
timestamp = get_timestamp_ms()
|
|
430
|
+
create_sub_account_action = {"type": "createSubAccount", "name": name}
|
|
431
|
+
signature = sign_l1_action(
|
|
432
|
+
self.wallet,
|
|
433
|
+
create_sub_account_action,
|
|
434
|
+
None,
|
|
435
|
+
timestamp,
|
|
436
|
+
self.expires_after,
|
|
437
|
+
self.base_url == MAINNET_API_URL,
|
|
438
|
+
)
|
|
439
|
+
return await self._post_action(create_sub_account_action, signature, timestamp)
|
|
440
|
+
|
|
441
|
+
async def usd_class_transfer(self, amount: float, to_perp: bool) -> Any:
|
|
442
|
+
timestamp = get_timestamp_ms()
|
|
443
|
+
str_amount = str(amount)
|
|
444
|
+
if self.vault_address:
|
|
445
|
+
str_amount += f" subaccount:{self.vault_address}"
|
|
446
|
+
|
|
447
|
+
action = {"type": "usdClassTransfer", "amount": str_amount, "toPerp": to_perp, "nonce": timestamp}
|
|
448
|
+
signature = sign_usd_class_transfer_action(self.wallet, action, self.base_url == MAINNET_API_URL)
|
|
449
|
+
return await self._post_action(action, signature, timestamp)
|
|
450
|
+
|
|
451
|
+
async def send_asset(self, destination: str, source_dex: str, destination_dex: str, token: str, amount: float) -> Any:
|
|
452
|
+
timestamp = get_timestamp_ms()
|
|
453
|
+
action = {
|
|
454
|
+
"type": "sendAsset",
|
|
455
|
+
"destination": destination,
|
|
456
|
+
"sourceDex": source_dex,
|
|
457
|
+
"destinationDex": destination_dex,
|
|
458
|
+
"token": token,
|
|
459
|
+
"amount": str(amount),
|
|
460
|
+
"fromSubAccount": self.vault_address if self.vault_address else "",
|
|
461
|
+
"nonce": timestamp,
|
|
462
|
+
}
|
|
463
|
+
signature = sign_send_asset_action(self.wallet, action, self.base_url == MAINNET_API_URL)
|
|
464
|
+
return await self._post_action(action, signature, timestamp)
|
|
465
|
+
|
|
466
|
+
async def sub_account_transfer(self, sub_account_user: str, is_deposit: bool, usd: int) -> Any:
|
|
467
|
+
timestamp = get_timestamp_ms()
|
|
468
|
+
sub_account_transfer_action = {
|
|
469
|
+
"type": "subAccountTransfer",
|
|
470
|
+
"subAccountUser": sub_account_user,
|
|
471
|
+
"isDeposit": is_deposit,
|
|
472
|
+
"usd": usd,
|
|
473
|
+
}
|
|
474
|
+
signature = sign_l1_action(
|
|
475
|
+
self.wallet,
|
|
476
|
+
sub_account_transfer_action,
|
|
477
|
+
None,
|
|
478
|
+
timestamp,
|
|
479
|
+
self.expires_after,
|
|
480
|
+
self.base_url == MAINNET_API_URL,
|
|
481
|
+
)
|
|
482
|
+
return await self._post_action(sub_account_transfer_action, signature, timestamp)
|
|
483
|
+
|
|
484
|
+
async def sub_account_spot_transfer(self, sub_account_user: str, is_deposit: bool, token: str, amount: float) -> Any:
|
|
485
|
+
timestamp = get_timestamp_ms()
|
|
486
|
+
sub_account_transfer_action = {
|
|
487
|
+
"type": "subAccountSpotTransfer",
|
|
488
|
+
"subAccountUser": sub_account_user,
|
|
489
|
+
"isDeposit": is_deposit,
|
|
490
|
+
"token": token,
|
|
491
|
+
"amount": str(amount),
|
|
492
|
+
}
|
|
493
|
+
signature = sign_l1_action(
|
|
494
|
+
self.wallet,
|
|
495
|
+
sub_account_transfer_action,
|
|
496
|
+
None,
|
|
497
|
+
timestamp,
|
|
498
|
+
self.expires_after,
|
|
499
|
+
self.base_url == MAINNET_API_URL,
|
|
500
|
+
)
|
|
501
|
+
return await self._post_action(sub_account_transfer_action, signature, timestamp)
|
|
502
|
+
|
|
503
|
+
async def vault_usd_transfer(self, vault_address: str, is_deposit: bool, usd: int) -> Any:
|
|
504
|
+
timestamp = get_timestamp_ms()
|
|
505
|
+
vault_transfer_action = {
|
|
506
|
+
"type": "vaultTransfer",
|
|
507
|
+
"vaultAddress": vault_address,
|
|
508
|
+
"isDeposit": is_deposit,
|
|
509
|
+
"usd": usd,
|
|
510
|
+
}
|
|
511
|
+
is_mainnet = self.base_url == MAINNET_API_URL
|
|
512
|
+
signature = sign_l1_action(self.wallet, vault_transfer_action, None, timestamp, self.expires_after, is_mainnet)
|
|
513
|
+
return await self._post_action(vault_transfer_action, signature, timestamp)
|
|
514
|
+
|
|
515
|
+
async def usd_transfer(self, amount: float, destination: str) -> Any:
|
|
516
|
+
timestamp = get_timestamp_ms()
|
|
517
|
+
action = {"destination": destination, "amount": str(amount), "time": timestamp, "type": "usdSend"}
|
|
518
|
+
is_mainnet = self.base_url == MAINNET_API_URL
|
|
519
|
+
signature = sign_usd_transfer_action(self.wallet, action, is_mainnet)
|
|
520
|
+
return await self._post_action(action, signature, timestamp)
|
|
521
|
+
|
|
522
|
+
async def spot_transfer(self, amount: float, destination: str, token: str) -> Any:
|
|
523
|
+
timestamp = get_timestamp_ms()
|
|
524
|
+
action = {"destination": destination, "amount": str(amount), "token": token, "time": timestamp, "type": "spotSend"}
|
|
525
|
+
is_mainnet = self.base_url == MAINNET_API_URL
|
|
526
|
+
signature = sign_spot_transfer_action(self.wallet, action, is_mainnet)
|
|
527
|
+
return await self._post_action(action, signature, timestamp)
|
|
528
|
+
|
|
529
|
+
async def token_delegate(self, validator: str, wei: int, is_undelegate: bool) -> Any:
|
|
530
|
+
timestamp = get_timestamp_ms()
|
|
531
|
+
action = {
|
|
532
|
+
"validator": validator,
|
|
533
|
+
"wei": wei,
|
|
534
|
+
"isUndelegate": is_undelegate,
|
|
535
|
+
"nonce": timestamp,
|
|
536
|
+
"type": "tokenDelegate",
|
|
537
|
+
}
|
|
538
|
+
is_mainnet = self.base_url == MAINNET_API_URL
|
|
539
|
+
signature = sign_token_delegate_action(self.wallet, action, is_mainnet)
|
|
540
|
+
return await self._post_action(action, signature, timestamp)
|
|
541
|
+
|
|
542
|
+
async def withdraw_from_bridge(self, amount: float, destination: str) -> Any:
|
|
543
|
+
timestamp = get_timestamp_ms()
|
|
544
|
+
action = {"destination": destination, "amount": str(amount), "time": timestamp, "type": "withdraw3"}
|
|
545
|
+
is_mainnet = self.base_url == MAINNET_API_URL
|
|
546
|
+
signature = sign_withdraw_from_bridge_action(self.wallet, action, is_mainnet)
|
|
547
|
+
return await self._post_action(action, signature, timestamp)
|
|
548
|
+
|
|
549
|
+
async def approve_agent(self, name: Optional[str] = None) -> Tuple[Any, str]:
|
|
550
|
+
agent_key = "0x" + secrets.token_hex(32)
|
|
551
|
+
account = eth_account.Account.from_key(agent_key)
|
|
552
|
+
timestamp = get_timestamp_ms()
|
|
553
|
+
is_mainnet = self.base_url == MAINNET_API_URL
|
|
554
|
+
action = {
|
|
555
|
+
"type": "approveAgent",
|
|
556
|
+
"agentAddress": account.address,
|
|
557
|
+
"agentName": name or "",
|
|
558
|
+
"nonce": timestamp,
|
|
559
|
+
}
|
|
560
|
+
signature = sign_agent(self.wallet, action, is_mainnet)
|
|
561
|
+
if name is None:
|
|
562
|
+
del action["agentName"]
|
|
563
|
+
return await self._post_action(action, signature, timestamp), agent_key
|
|
564
|
+
|
|
565
|
+
async def approve_builder_fee(self, builder: str, max_fee_rate: str) -> Any:
|
|
566
|
+
timestamp = get_timestamp_ms()
|
|
567
|
+
action = {"maxFeeRate": max_fee_rate, "builder": builder, "nonce": timestamp, "type": "approveBuilderFee"}
|
|
568
|
+
signature = sign_approve_builder_fee(self.wallet, action, self.base_url == MAINNET_API_URL)
|
|
569
|
+
return await self._post_action(action, signature, timestamp)
|
|
570
|
+
|
|
571
|
+
async def convert_to_multi_sig_user(self, authorized_users: List[str], threshold: int) -> Any:
|
|
572
|
+
timestamp = get_timestamp_ms()
|
|
573
|
+
signers = {"authorizedUsers": sorted(authorized_users), "threshold": threshold}
|
|
574
|
+
action = {"type": "convertToMultiSigUser", "signers": json.dumps(signers), "nonce": timestamp}
|
|
575
|
+
signature = sign_convert_to_multi_sig_user_action(self.wallet, action, self.base_url == MAINNET_API_URL)
|
|
576
|
+
return await self._post_action(action, signature, timestamp)
|
|
577
|
+
|
|
578
|
+
async def spot_deploy_register_token(
|
|
579
|
+
self, token_name: str, sz_decimals: int, wei_decimals: int, max_gas: int, full_name: str
|
|
580
|
+
) -> Any:
|
|
581
|
+
timestamp = get_timestamp_ms()
|
|
582
|
+
action = {
|
|
583
|
+
"type": "spotDeploy",
|
|
584
|
+
"registerToken2": {
|
|
585
|
+
"spec": {"name": token_name, "szDecimals": sz_decimals, "weiDecimals": wei_decimals},
|
|
586
|
+
"maxGas": max_gas,
|
|
587
|
+
"fullName": full_name,
|
|
588
|
+
},
|
|
589
|
+
}
|
|
590
|
+
signature = sign_l1_action(
|
|
591
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
592
|
+
)
|
|
593
|
+
return await self._post_action(action, signature, timestamp)
|
|
594
|
+
|
|
595
|
+
async def spot_deploy_user_genesis(
|
|
596
|
+
self, token: int, user_and_wei: List[Tuple[str, str]], existing_token_and_wei: List[Tuple[int, str]]
|
|
597
|
+
) -> Any:
|
|
598
|
+
timestamp = get_timestamp_ms()
|
|
599
|
+
action = {
|
|
600
|
+
"type": "spotDeploy",
|
|
601
|
+
"userGenesis": {
|
|
602
|
+
"token": token,
|
|
603
|
+
"userAndWei": [(user.lower(), wei) for (user, wei) in user_and_wei],
|
|
604
|
+
"existingTokenAndWei": existing_token_and_wei,
|
|
605
|
+
},
|
|
606
|
+
}
|
|
607
|
+
signature = sign_l1_action(
|
|
608
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
609
|
+
)
|
|
610
|
+
return await self._post_action(action, signature, timestamp)
|
|
611
|
+
|
|
612
|
+
async def spot_deploy_enable_freeze_privilege(self, token: int) -> Any:
|
|
613
|
+
return await self.spot_deploy_token_action_inner("enableFreezePrivilege", token)
|
|
614
|
+
|
|
615
|
+
async def spot_deploy_freeze_user(self, token: int, user: str, freeze: bool) -> Any:
|
|
616
|
+
timestamp = get_timestamp_ms()
|
|
617
|
+
action = {"type": "spotDeploy", "freezeUser": {"token": token, "user": user.lower(), "freeze": freeze}}
|
|
618
|
+
signature = sign_l1_action(
|
|
619
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
620
|
+
)
|
|
621
|
+
return await self._post_action(action, signature, timestamp)
|
|
622
|
+
|
|
623
|
+
async def spot_deploy_revoke_freeze_privilege(self, token: int) -> Any:
|
|
624
|
+
return await self.spot_deploy_token_action_inner("revokeFreezePrivilege", token)
|
|
625
|
+
|
|
626
|
+
async def spot_deploy_enable_quote_token(self, token: int) -> Any:
|
|
627
|
+
return await self.spot_deploy_token_action_inner("enableQuoteToken", token)
|
|
628
|
+
|
|
629
|
+
async def spot_deploy_token_action_inner(self, variant: str, token: int) -> Any:
|
|
630
|
+
timestamp = get_timestamp_ms()
|
|
631
|
+
action = {"type": "spotDeploy", variant: {"token": token}}
|
|
632
|
+
signature = sign_l1_action(
|
|
633
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
634
|
+
)
|
|
635
|
+
return await self._post_action(action, signature, timestamp)
|
|
636
|
+
|
|
637
|
+
async def spot_deploy_genesis(self, token: int, max_supply: str, no_hyperliquidity: bool) -> Any:
|
|
638
|
+
timestamp = get_timestamp_ms()
|
|
639
|
+
genesis = {"token": token, "maxSupply": max_supply}
|
|
640
|
+
if no_hyperliquidity:
|
|
641
|
+
genesis["noHyperliquidity"] = True
|
|
642
|
+
action = {"type": "spotDeploy", "genesis": genesis}
|
|
643
|
+
signature = sign_l1_action(
|
|
644
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
645
|
+
)
|
|
646
|
+
return await self._post_action(action, signature, timestamp)
|
|
647
|
+
|
|
648
|
+
async def spot_deploy_register_spot(self, base_token: int, quote_token: int) -> Any:
|
|
649
|
+
timestamp = get_timestamp_ms()
|
|
650
|
+
action = {"type": "spotDeploy", "registerSpot": {"tokens": [base_token, quote_token]}}
|
|
651
|
+
signature = sign_l1_action(
|
|
652
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
653
|
+
)
|
|
654
|
+
return await self._post_action(action, signature, timestamp)
|
|
655
|
+
|
|
656
|
+
async def spot_deploy_register_hyperliquidity(
|
|
657
|
+
self, spot: int, start_px: float, order_sz: float, n_orders: int, n_seeded_levels: Optional[int]
|
|
658
|
+
) -> Any:
|
|
659
|
+
timestamp = get_timestamp_ms()
|
|
660
|
+
register_hyperliquidity = {"spot": spot, "startPx": str(start_px), "orderSz": str(order_sz), "nOrders": n_orders}
|
|
661
|
+
if n_seeded_levels is not None:
|
|
662
|
+
register_hyperliquidity["nSeededLevels"] = n_seeded_levels
|
|
663
|
+
action = {"type": "spotDeploy", "registerHyperliquidity": register_hyperliquidity}
|
|
664
|
+
signature = sign_l1_action(
|
|
665
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
666
|
+
)
|
|
667
|
+
return await self._post_action(action, signature, timestamp)
|
|
668
|
+
|
|
669
|
+
async def spot_deploy_set_deployer_trading_fee_share(self, token: int, share: str) -> Any:
|
|
670
|
+
timestamp = get_timestamp_ms()
|
|
671
|
+
action = {"type": "spotDeploy", "setDeployerTradingFeeShare": {"token": token, "share": share}}
|
|
672
|
+
signature = sign_l1_action(
|
|
673
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
674
|
+
)
|
|
675
|
+
return await self._post_action(action, signature, timestamp)
|
|
676
|
+
|
|
677
|
+
async def perp_deploy_register_asset(
|
|
678
|
+
self,
|
|
679
|
+
dex: str,
|
|
680
|
+
max_gas: Optional[int],
|
|
681
|
+
coin: str,
|
|
682
|
+
sz_decimals: int,
|
|
683
|
+
oracle_px: str,
|
|
684
|
+
margin_table_id: int,
|
|
685
|
+
only_isolated: bool,
|
|
686
|
+
schema: Optional[PerpDexSchemaInput],
|
|
687
|
+
) -> Any:
|
|
688
|
+
timestamp = get_timestamp_ms()
|
|
689
|
+
schema_wire = None
|
|
690
|
+
if schema is not None:
|
|
691
|
+
schema_wire = {
|
|
692
|
+
"fullName": schema["fullName"],
|
|
693
|
+
"collateralToken": schema["collateralToken"],
|
|
694
|
+
"oracleUpdater": schema["oracleUpdater"].lower() if schema["oracleUpdater"] is not None else None,
|
|
695
|
+
}
|
|
696
|
+
action = {
|
|
697
|
+
"type": "perpDeploy",
|
|
698
|
+
"registerAsset": {
|
|
699
|
+
"maxGas": max_gas,
|
|
700
|
+
"assetRequest": {
|
|
701
|
+
"coin": coin,
|
|
702
|
+
"szDecimals": sz_decimals,
|
|
703
|
+
"oraclePx": oracle_px,
|
|
704
|
+
"marginTableId": margin_table_id,
|
|
705
|
+
"onlyIsolated": only_isolated,
|
|
706
|
+
},
|
|
707
|
+
"dex": dex,
|
|
708
|
+
"schema": schema_wire,
|
|
709
|
+
},
|
|
710
|
+
}
|
|
711
|
+
signature = sign_l1_action(
|
|
712
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
713
|
+
)
|
|
714
|
+
return await self._post_action(action, signature, timestamp)
|
|
715
|
+
|
|
716
|
+
async def perp_deploy_set_oracle(
|
|
717
|
+
self,
|
|
718
|
+
dex: str,
|
|
719
|
+
oracle_pxs: Dict[str, str],
|
|
720
|
+
all_mark_pxs: List[Dict[str, str]],
|
|
721
|
+
external_perp_pxs: Dict[str, str],
|
|
722
|
+
) -> Any:
|
|
723
|
+
timestamp = get_timestamp_ms()
|
|
724
|
+
action = {
|
|
725
|
+
"type": "perpDeploy",
|
|
726
|
+
"setOracle": {
|
|
727
|
+
"dex": dex,
|
|
728
|
+
"oraclePxs": sorted(list(oracle_pxs.items())),
|
|
729
|
+
"markPxs": [sorted(list(mark_pxs.items())) for mark_pxs in all_mark_pxs],
|
|
730
|
+
"externalPerpPxs": sorted(list(external_perp_pxs.items())),
|
|
731
|
+
},
|
|
732
|
+
}
|
|
733
|
+
signature = sign_l1_action(
|
|
734
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
735
|
+
)
|
|
736
|
+
return await self._post_action(action, signature, timestamp)
|
|
737
|
+
|
|
738
|
+
async def c_signer_unjail_self(self) -> Any:
|
|
739
|
+
return await self.c_signer_inner("unjailSelf")
|
|
740
|
+
|
|
741
|
+
async def c_signer_jail_self(self) -> Any:
|
|
742
|
+
return await self.c_signer_inner("jailSelf")
|
|
743
|
+
|
|
744
|
+
async def c_signer_inner(self, variant: str) -> Any:
|
|
745
|
+
timestamp = get_timestamp_ms()
|
|
746
|
+
action = {"type": "CSignerAction", variant: None}
|
|
747
|
+
signature = sign_l1_action(
|
|
748
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
749
|
+
)
|
|
750
|
+
return await self._post_action(action, signature, timestamp)
|
|
751
|
+
|
|
752
|
+
async def c_validator_register(
|
|
753
|
+
self,
|
|
754
|
+
node_ip: str,
|
|
755
|
+
name: str,
|
|
756
|
+
description: str,
|
|
757
|
+
delegations_disabled: bool,
|
|
758
|
+
commission_bps: int,
|
|
759
|
+
signer: str,
|
|
760
|
+
unjailed: bool,
|
|
761
|
+
initial_wei: int,
|
|
762
|
+
) -> Any:
|
|
763
|
+
timestamp = get_timestamp_ms()
|
|
764
|
+
action = {
|
|
765
|
+
"type": "CValidatorAction",
|
|
766
|
+
"register": {
|
|
767
|
+
"profile": {
|
|
768
|
+
"node_ip": {"Ip": node_ip},
|
|
769
|
+
"name": name,
|
|
770
|
+
"description": description,
|
|
771
|
+
"delegations_disabled": delegations_disabled,
|
|
772
|
+
"commission_bps": commission_bps,
|
|
773
|
+
"signer": signer,
|
|
774
|
+
},
|
|
775
|
+
"unjailed": unjailed,
|
|
776
|
+
"initial_wei": initial_wei,
|
|
777
|
+
},
|
|
778
|
+
}
|
|
779
|
+
signature = sign_l1_action(
|
|
780
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
781
|
+
)
|
|
782
|
+
return await self._post_action(action, signature, timestamp)
|
|
783
|
+
|
|
784
|
+
async def c_validator_change_profile(
|
|
785
|
+
self,
|
|
786
|
+
node_ip: Optional[str],
|
|
787
|
+
name: Optional[str],
|
|
788
|
+
description: Optional[str],
|
|
789
|
+
unjailed: bool,
|
|
790
|
+
disable_delegations: Optional[bool],
|
|
791
|
+
commission_bps: Optional[int],
|
|
792
|
+
signer: Optional[str],
|
|
793
|
+
) -> Any:
|
|
794
|
+
timestamp = get_timestamp_ms()
|
|
795
|
+
action = {
|
|
796
|
+
"type": "CValidatorAction",
|
|
797
|
+
"changeProfile": {
|
|
798
|
+
"node_ip": None if node_ip is None else {"Ip": node_ip},
|
|
799
|
+
"name": name,
|
|
800
|
+
"description": description,
|
|
801
|
+
"unjailed": unjailed,
|
|
802
|
+
"disable_delegations": disable_delegations,
|
|
803
|
+
"commission_bps": commission_bps,
|
|
804
|
+
"signer": signer,
|
|
805
|
+
},
|
|
806
|
+
}
|
|
807
|
+
signature = sign_l1_action(
|
|
808
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
809
|
+
)
|
|
810
|
+
return await self._post_action(action, signature, timestamp)
|
|
811
|
+
|
|
812
|
+
async def c_validator_unregister(self) -> Any:
|
|
813
|
+
timestamp = get_timestamp_ms()
|
|
814
|
+
action = {"type": "CValidatorAction", "unregister": None}
|
|
815
|
+
signature = sign_l1_action(
|
|
816
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
817
|
+
)
|
|
818
|
+
return await self._post_action(action, signature, timestamp)
|
|
819
|
+
|
|
820
|
+
async def multi_sig(self, multi_sig_user, inner_action, signatures, nonce, vault_address=None):
|
|
821
|
+
multi_sig_user = multi_sig_user.lower()
|
|
822
|
+
payload_action = _multi_sig_payload_action(inner_action)
|
|
823
|
+
multi_sig_action = {
|
|
824
|
+
"type": "multiSig",
|
|
825
|
+
"signatureChainId": "0x66eee",
|
|
826
|
+
"signatures": signatures,
|
|
827
|
+
"payload": {
|
|
828
|
+
"multiSigUser": multi_sig_user,
|
|
829
|
+
"outerSigner": self.wallet.address.lower(),
|
|
830
|
+
"action": payload_action,
|
|
831
|
+
},
|
|
832
|
+
}
|
|
833
|
+
is_mainnet = self.base_url == MAINNET_API_URL
|
|
834
|
+
signature = sign_multi_sig_action(
|
|
835
|
+
self.wallet, multi_sig_action, is_mainnet, vault_address, nonce, self.expires_after
|
|
836
|
+
)
|
|
837
|
+
return await self._post_action(multi_sig_action, signature, nonce)
|
|
838
|
+
|
|
839
|
+
async def use_big_blocks(self, enable: bool) -> Any:
|
|
840
|
+
timestamp = get_timestamp_ms()
|
|
841
|
+
action = {"type": "evmUserModify", "usingBigBlocks": enable}
|
|
842
|
+
signature = sign_l1_action(
|
|
843
|
+
self.wallet, action, None, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
844
|
+
)
|
|
845
|
+
return await self._post_action(action, signature, timestamp)
|
|
846
|
+
|
|
847
|
+
async def agent_enable_dex_abstraction(self) -> Any:
|
|
848
|
+
timestamp = get_timestamp_ms()
|
|
849
|
+
action = {"type": "agentEnableDexAbstraction"}
|
|
850
|
+
signature = sign_l1_action(
|
|
851
|
+
self.wallet, action, self.vault_address, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
852
|
+
)
|
|
853
|
+
return await self._post_action(action, signature, timestamp)
|
|
854
|
+
|
|
855
|
+
async def agent_set_abstraction(self, abstraction: AgentAbstraction) -> Any:
|
|
856
|
+
timestamp = get_timestamp_ms()
|
|
857
|
+
action = {"type": "agentSetAbstraction", "abstraction": abstraction}
|
|
858
|
+
signature = sign_l1_action(
|
|
859
|
+
self.wallet, action, self.vault_address, timestamp, self.expires_after, self.base_url == MAINNET_API_URL
|
|
860
|
+
)
|
|
861
|
+
return await self._post_action(action, signature, timestamp)
|
|
862
|
+
|
|
863
|
+
async def user_dex_abstraction(self, user: str, enabled: bool) -> Any:
|
|
864
|
+
timestamp = get_timestamp_ms()
|
|
865
|
+
action = {"type": "userDexAbstraction", "user": user.lower(), "enabled": enabled, "nonce": timestamp}
|
|
866
|
+
signature = sign_user_dex_abstraction_action(self.wallet, action, self.base_url == MAINNET_API_URL)
|
|
867
|
+
return await self._post_action(action, signature, timestamp)
|
|
868
|
+
|
|
869
|
+
async def user_set_abstraction(self, user: str, abstraction: Abstraction) -> Any:
|
|
870
|
+
timestamp = get_timestamp_ms()
|
|
871
|
+
action = {"type": "userSetAbstraction", "user": user.lower(), "abstraction": abstraction, "nonce": timestamp}
|
|
872
|
+
signature = sign_user_set_abstraction_action(self.wallet, action, self.base_url == MAINNET_API_URL)
|
|
873
|
+
return await self._post_action(action, signature, timestamp)
|
|
874
|
+
|
|
875
|
+
async def noop(self, nonce):
|
|
876
|
+
action = {"type": "noop"}
|
|
877
|
+
signature = sign_l1_action(
|
|
878
|
+
self.wallet, action, self.vault_address, nonce, self.expires_after, self.base_url == MAINNET_API_URL
|
|
879
|
+
)
|
|
880
|
+
return await self._post_action(action, signature, nonce)
|
|
881
|
+
|
|
882
|
+
async def gossip_priority_bid(self, slot_id, ip, max_gas):
|
|
883
|
+
nonce = get_timestamp_ms()
|
|
884
|
+
action = {"type": "gossipPriorityBid", "slotId": slot_id, "ip": ip, "maxGas": max_gas}
|
|
885
|
+
signature = sign_l1_action(
|
|
886
|
+
self.wallet, action, self.vault_address, nonce, self.expires_after, self.base_url == MAINNET_API_URL
|
|
887
|
+
)
|
|
888
|
+
return await self._post_action(action, signature, nonce)
|