ddx-python 1.0.4__cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- ddx/.gitignore +1 -0
- ddx/__init__.py +58 -0
- ddx/_rust/__init__.pyi +2685 -0
- ddx/_rust/common/__init__.pyi +17 -0
- ddx/_rust/common/accounting.pyi +6 -0
- ddx/_rust/common/enums.pyi +3 -0
- ddx/_rust/common/requests/__init__.pyi +23 -0
- ddx/_rust/common/requests/intents.pyi +19 -0
- ddx/_rust/common/specs.pyi +17 -0
- ddx/_rust/common/state/__init__.pyi +41 -0
- ddx/_rust/common/state/keys.pyi +29 -0
- ddx/_rust/common/transactions.pyi +7 -0
- ddx/_rust/decimal.pyi +3 -0
- ddx/_rust/h256.pyi +3 -0
- ddx/_rust.abi3.so +0 -0
- ddx/app_config/ethereum/addresses.json +526 -0
- ddx/auditor/README.md +32 -0
- ddx/auditor/__init__.py +0 -0
- ddx/auditor/auditor_driver.py +1043 -0
- ddx/auditor/websocket_message.py +54 -0
- ddx/common/__init__.py +0 -0
- ddx/common/epoch_params.py +28 -0
- ddx/common/fill_context.py +141 -0
- ddx/common/logging.py +184 -0
- ddx/common/market_aware_account.py +259 -0
- ddx/common/market_specs.py +64 -0
- ddx/common/trade_mining_params.py +19 -0
- ddx/common/transaction_utils.py +85 -0
- ddx/common/transactions/__init__.py +0 -0
- ddx/common/transactions/advance_epoch.py +91 -0
- ddx/common/transactions/advance_settlement_epoch.py +63 -0
- ddx/common/transactions/all_price_checkpoints.py +84 -0
- ddx/common/transactions/cancel.py +76 -0
- ddx/common/transactions/cancel_all.py +88 -0
- ddx/common/transactions/complete_fill.py +103 -0
- ddx/common/transactions/disaster_recovery.py +96 -0
- ddx/common/transactions/event.py +48 -0
- ddx/common/transactions/fee_distribution.py +119 -0
- ddx/common/transactions/funding.py +292 -0
- ddx/common/transactions/futures_expiry.py +123 -0
- ddx/common/transactions/genesis.py +108 -0
- ddx/common/transactions/inner/__init__.py +0 -0
- ddx/common/transactions/inner/adl_outcome.py +25 -0
- ddx/common/transactions/inner/fill.py +232 -0
- ddx/common/transactions/inner/liquidated_position.py +41 -0
- ddx/common/transactions/inner/liquidation_entry.py +41 -0
- ddx/common/transactions/inner/liquidation_fill.py +118 -0
- ddx/common/transactions/inner/outcome.py +32 -0
- ddx/common/transactions/inner/trade_fill.py +292 -0
- ddx/common/transactions/insurance_fund_update.py +138 -0
- ddx/common/transactions/insurance_fund_withdraw.py +100 -0
- ddx/common/transactions/liquidation.py +353 -0
- ddx/common/transactions/partial_fill.py +125 -0
- ddx/common/transactions/pnl_realization.py +120 -0
- ddx/common/transactions/post.py +72 -0
- ddx/common/transactions/post_order.py +95 -0
- ddx/common/transactions/price_checkpoint.py +97 -0
- ddx/common/transactions/signer_registered.py +62 -0
- ddx/common/transactions/specs_update.py +61 -0
- ddx/common/transactions/strategy_update.py +158 -0
- ddx/common/transactions/tradable_product_update.py +98 -0
- ddx/common/transactions/trade_mining.py +147 -0
- ddx/common/transactions/trader_update.py +131 -0
- ddx/common/transactions/withdraw.py +90 -0
- ddx/common/transactions/withdraw_ddx.py +74 -0
- ddx/common/utils.py +176 -0
- ddx/config.py +17 -0
- ddx/derivadex_client.py +270 -0
- ddx/models/__init__.py +0 -0
- ddx/models/base.py +132 -0
- ddx/py.typed +0 -0
- ddx/realtime_client/__init__.py +2 -0
- ddx/realtime_client/config.py +2 -0
- ddx/realtime_client/models/__init__.py +611 -0
- ddx/realtime_client/realtime_client.py +646 -0
- ddx/rest_client/__init__.py +0 -0
- ddx/rest_client/clients/__init__.py +0 -0
- ddx/rest_client/clients/base_client.py +60 -0
- ddx/rest_client/clients/market_client.py +1243 -0
- ddx/rest_client/clients/on_chain_client.py +439 -0
- ddx/rest_client/clients/signed_client.py +292 -0
- ddx/rest_client/clients/system_client.py +843 -0
- ddx/rest_client/clients/trade_client.py +357 -0
- ddx/rest_client/constants/__init__.py +0 -0
- ddx/rest_client/constants/endpoints.py +66 -0
- ddx/rest_client/contracts/__init__.py +0 -0
- ddx/rest_client/contracts/checkpoint/__init__.py +560 -0
- ddx/rest_client/contracts/ddx/__init__.py +1949 -0
- ddx/rest_client/contracts/dummy_token/__init__.py +1014 -0
- ddx/rest_client/contracts/i_collateral/__init__.py +1414 -0
- ddx/rest_client/contracts/i_stake/__init__.py +696 -0
- ddx/rest_client/exceptions/__init__.py +0 -0
- ddx/rest_client/exceptions/exceptions.py +32 -0
- ddx/rest_client/http/__init__.py +0 -0
- ddx/rest_client/http/http_client.py +336 -0
- ddx/rest_client/models/__init__.py +0 -0
- ddx/rest_client/models/market.py +693 -0
- ddx/rest_client/models/signed.py +61 -0
- ddx/rest_client/models/system.py +311 -0
- ddx/rest_client/models/trade.py +185 -0
- ddx/rest_client/utils/__init__.py +0 -0
- ddx/rest_client/utils/encryption_utils.py +26 -0
- ddx/utils/__init__.py +0 -0
- ddx_python-1.0.4.dist-info/METADATA +63 -0
- ddx_python-1.0.4.dist-info/RECORD +106 -0
- ddx_python-1.0.4.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import time
|
|
3
|
+
from typing import Union, List, Optional
|
|
4
|
+
from eth_account.signers.local import LocalAccount
|
|
5
|
+
from eth_abi import encode
|
|
6
|
+
from decimal import Decimal as PyDecimal
|
|
7
|
+
|
|
8
|
+
from ddx._rust.decimal import Decimal
|
|
9
|
+
from ddx._rust.common.requests.intents import (
|
|
10
|
+
OrderIntent,
|
|
11
|
+
CancelOrderIntent,
|
|
12
|
+
CancelAllIntent,
|
|
13
|
+
ProfileUpdateIntent,
|
|
14
|
+
WithdrawIntent,
|
|
15
|
+
)
|
|
16
|
+
from ddx.rest_client.clients.base_client import BaseClient
|
|
17
|
+
from ddx.rest_client.constants.endpoints import Signed
|
|
18
|
+
from ddx.rest_client.models.signed import TradeReceipt
|
|
19
|
+
from ddx.rest_client.utils.encryption_utils import encrypt_with_nonce
|
|
20
|
+
from ddx.rest_client.http.http_client import HTTPClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TradingJSONEncoder(json.JSONEncoder):
|
|
24
|
+
"""JSON encoder for trading request data"""
|
|
25
|
+
|
|
26
|
+
def default(self, o):
|
|
27
|
+
if hasattr(o, "repr_json"):
|
|
28
|
+
return o.repr_json()
|
|
29
|
+
elif type(o) == Decimal:
|
|
30
|
+
return PyDecimal(str(o))
|
|
31
|
+
return super().default(o)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SignedClient(BaseClient):
|
|
35
|
+
"""
|
|
36
|
+
Trading operations for executing orders and other trading actions.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
http : HTTPClient
|
|
41
|
+
The HTTP client instance to use for requests
|
|
42
|
+
base_url : str
|
|
43
|
+
The base URL for trading endpoints
|
|
44
|
+
web3_account : Any
|
|
45
|
+
The web3 account for signing requests
|
|
46
|
+
chain_id : int
|
|
47
|
+
The blockchain chain ID
|
|
48
|
+
verifying_contract : str
|
|
49
|
+
The contract address for EIP-712 signing
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self,
|
|
54
|
+
http: HTTPClient,
|
|
55
|
+
base_url: str,
|
|
56
|
+
web3_account: LocalAccount,
|
|
57
|
+
chain_id: int,
|
|
58
|
+
verifying_contract: str,
|
|
59
|
+
):
|
|
60
|
+
super().__init__(http, base_url)
|
|
61
|
+
self._web3_account = web3_account
|
|
62
|
+
self._chain_id = chain_id
|
|
63
|
+
self._verifying_contract = verifying_contract
|
|
64
|
+
self._encryption_key = None
|
|
65
|
+
|
|
66
|
+
async def _get_or_fetch_encryption_key(self) -> str:
|
|
67
|
+
"""Get cached encryption key or fetch if not available"""
|
|
68
|
+
|
|
69
|
+
if self._encryption_key is None:
|
|
70
|
+
response = await self._http.get(self._build_url(Signed.ENCRYPTION_KEY))
|
|
71
|
+
self._encryption_key = response
|
|
72
|
+
|
|
73
|
+
return self._encryption_key
|
|
74
|
+
|
|
75
|
+
async def _encrypt_and_submit_request(
|
|
76
|
+
self,
|
|
77
|
+
intent: Union[
|
|
78
|
+
OrderIntent,
|
|
79
|
+
CancelOrderIntent,
|
|
80
|
+
CancelAllIntent,
|
|
81
|
+
ProfileUpdateIntent,
|
|
82
|
+
WithdrawIntent,
|
|
83
|
+
],
|
|
84
|
+
local_account: Optional[LocalAccount] = None,
|
|
85
|
+
) -> TradeReceipt:
|
|
86
|
+
"""
|
|
87
|
+
Helper method to encrypt and submit trading requests.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
intent : Union[OrderIntent, CancelOrderIntent, CancelAllIntent, ProfileUpdateIntent, WithdrawIntent]
|
|
92
|
+
The trading intent to encrypt and submit
|
|
93
|
+
local_account : Optional[LocalAccount]
|
|
94
|
+
Local account to sign with, defaults to client's account
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
TradeReceipt
|
|
99
|
+
The parsed receipt response
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
account = local_account or self._web3_account
|
|
103
|
+
|
|
104
|
+
intent.signature = account.signHash(
|
|
105
|
+
intent.hash_eip712((self._chain_id, self._verifying_contract))
|
|
106
|
+
).signature.hex()
|
|
107
|
+
|
|
108
|
+
encryption_key = await self._get_or_fetch_encryption_key()
|
|
109
|
+
encrypted_contents = encrypt_with_nonce(
|
|
110
|
+
encryption_key, TradingJSONEncoder().encode(intent.json)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Submit the encrypted request
|
|
114
|
+
response = await self._http.post(
|
|
115
|
+
self._build_url(Signed.SUBMIT_REQUEST), data=encrypted_contents
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
return TradeReceipt.model_validate(response)
|
|
119
|
+
|
|
120
|
+
def get_nonce(self) -> str:
|
|
121
|
+
"""
|
|
122
|
+
Get nonce to be used as the unique nonce in various commands.
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
str
|
|
127
|
+
32-byte hex-encoded nonce string, encoded using eth_abi
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
# Retrieve current UNIX time in nanoseconds to derive a unique, monotonically-increasing nonce
|
|
131
|
+
nonce = str(time.time_ns())
|
|
132
|
+
|
|
133
|
+
# abi.encode(['bytes32'], [nonce])
|
|
134
|
+
return f'0x{encode(["bytes32"], [nonce.encode("utf8")]).hex()}'
|
|
135
|
+
|
|
136
|
+
async def place_order(
|
|
137
|
+
self,
|
|
138
|
+
order: OrderIntent,
|
|
139
|
+
local_account: Optional[LocalAccount] = None,
|
|
140
|
+
) -> TradeReceipt:
|
|
141
|
+
"""
|
|
142
|
+
Place a single order on the exchange.
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
order : OrderIntent
|
|
147
|
+
The order intent to submit, containing symbol, strategy, side,
|
|
148
|
+
order type, quantity, and price information
|
|
149
|
+
local_account : Optional[LocalAccount]
|
|
150
|
+
Local account to sign with, defaults to client's account
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
TradeReceipt
|
|
155
|
+
The response containing order submission details including
|
|
156
|
+
nonce, request hash, and request index
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
return await self._encrypt_and_submit_request(
|
|
160
|
+
order, local_account=local_account
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
async def place_orders(
|
|
164
|
+
self,
|
|
165
|
+
orders: List[OrderIntent],
|
|
166
|
+
local_account: Optional[LocalAccount] = None,
|
|
167
|
+
) -> List[TradeReceipt]:
|
|
168
|
+
"""
|
|
169
|
+
Place multiple orders efficiently.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
orders : List[OrderIntent]
|
|
174
|
+
List of order intents to submit
|
|
175
|
+
local_account : Optional[LocalAccount]
|
|
176
|
+
Local account to sign with, defaults to client's account
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
-------
|
|
180
|
+
List[TradeReceipt]
|
|
181
|
+
List of responses for each order containing submission details
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
results = []
|
|
185
|
+
for order in orders:
|
|
186
|
+
result = await self.place_order(order, local_account=local_account)
|
|
187
|
+
results.append(result)
|
|
188
|
+
|
|
189
|
+
return results
|
|
190
|
+
|
|
191
|
+
async def cancel_order(
|
|
192
|
+
self,
|
|
193
|
+
cancel_intent: CancelOrderIntent,
|
|
194
|
+
local_account: Optional[LocalAccount] = None,
|
|
195
|
+
) -> TradeReceipt:
|
|
196
|
+
"""
|
|
197
|
+
Cancel a specific order.
|
|
198
|
+
|
|
199
|
+
Parameters
|
|
200
|
+
----------
|
|
201
|
+
cancel_intent : CancelOrderIntent
|
|
202
|
+
The cancel intent containing order details to cancel
|
|
203
|
+
local_account : Optional[LocalAccount]
|
|
204
|
+
Local account to sign with, defaults to client's account
|
|
205
|
+
|
|
206
|
+
Returns
|
|
207
|
+
-------
|
|
208
|
+
TradeReceipt
|
|
209
|
+
Response containing cancellation details
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
return await self._encrypt_and_submit_request(
|
|
213
|
+
cancel_intent, local_account=local_account
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
async def cancel_all(
|
|
217
|
+
self,
|
|
218
|
+
cancel_all_intent: CancelAllIntent,
|
|
219
|
+
local_account: Optional[LocalAccount] = None,
|
|
220
|
+
) -> TradeReceipt:
|
|
221
|
+
"""
|
|
222
|
+
Cancel all orders for a strategy.
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
cancel_all_intent : CancelAllIntent
|
|
227
|
+
The cancel all intent containing strategy details
|
|
228
|
+
local_account : Optional[LocalAccount]
|
|
229
|
+
Local account to sign with, defaults to client's account
|
|
230
|
+
|
|
231
|
+
Returns
|
|
232
|
+
-------
|
|
233
|
+
TradeReceipt
|
|
234
|
+
Response containing cancellation details for all orders
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
return await self._encrypt_and_submit_request(
|
|
238
|
+
cancel_all_intent, local_account=local_account
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
async def withdraw(
|
|
242
|
+
self,
|
|
243
|
+
withdraw_intent: WithdrawIntent,
|
|
244
|
+
local_account: Optional[LocalAccount] = None,
|
|
245
|
+
) -> TradeReceipt:
|
|
246
|
+
"""
|
|
247
|
+
Submit a withdrawal request.
|
|
248
|
+
|
|
249
|
+
Parameters
|
|
250
|
+
----------
|
|
251
|
+
withdraw_intent : WithdrawIntent
|
|
252
|
+
The withdrawal intent containing amount and strategy details
|
|
253
|
+
local_account : Optional[LocalAccount]
|
|
254
|
+
Local account to sign with, defaults to client's account
|
|
255
|
+
|
|
256
|
+
Returns
|
|
257
|
+
-------
|
|
258
|
+
TradeReceipt
|
|
259
|
+
Response containing withdrawal submission details
|
|
260
|
+
"""
|
|
261
|
+
|
|
262
|
+
return await self._encrypt_and_submit_request(
|
|
263
|
+
withdraw_intent, local_account=local_account
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
# TODO: Add and fuzz withdraw_ddx
|
|
267
|
+
# TODO: Add and fuzz modify_order
|
|
268
|
+
|
|
269
|
+
async def update_profile(
|
|
270
|
+
self,
|
|
271
|
+
profile_update_intent: ProfileUpdateIntent,
|
|
272
|
+
local_account: Optional[LocalAccount] = None,
|
|
273
|
+
) -> TradeReceipt:
|
|
274
|
+
"""
|
|
275
|
+
Submit a profile update request.
|
|
276
|
+
|
|
277
|
+
Parameters
|
|
278
|
+
----------
|
|
279
|
+
profile_update_intent : ProfileUpdateIntent
|
|
280
|
+
The profile update intent containing ddx fee election details
|
|
281
|
+
local_account : Optional[LocalAccount]
|
|
282
|
+
Local account to sign with, defaults to client's account
|
|
283
|
+
|
|
284
|
+
Returns
|
|
285
|
+
-------
|
|
286
|
+
TradeReceipt
|
|
287
|
+
Response containing profile update submission details
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
return await self._encrypt_and_submit_request(
|
|
291
|
+
profile_update_intent, local_account=local_account
|
|
292
|
+
)
|