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.
Files changed (106) hide show
  1. ddx/.gitignore +1 -0
  2. ddx/__init__.py +58 -0
  3. ddx/_rust/__init__.pyi +2685 -0
  4. ddx/_rust/common/__init__.pyi +17 -0
  5. ddx/_rust/common/accounting.pyi +6 -0
  6. ddx/_rust/common/enums.pyi +3 -0
  7. ddx/_rust/common/requests/__init__.pyi +23 -0
  8. ddx/_rust/common/requests/intents.pyi +19 -0
  9. ddx/_rust/common/specs.pyi +17 -0
  10. ddx/_rust/common/state/__init__.pyi +41 -0
  11. ddx/_rust/common/state/keys.pyi +29 -0
  12. ddx/_rust/common/transactions.pyi +7 -0
  13. ddx/_rust/decimal.pyi +3 -0
  14. ddx/_rust/h256.pyi +3 -0
  15. ddx/_rust.abi3.so +0 -0
  16. ddx/app_config/ethereum/addresses.json +526 -0
  17. ddx/auditor/README.md +32 -0
  18. ddx/auditor/__init__.py +0 -0
  19. ddx/auditor/auditor_driver.py +1043 -0
  20. ddx/auditor/websocket_message.py +54 -0
  21. ddx/common/__init__.py +0 -0
  22. ddx/common/epoch_params.py +28 -0
  23. ddx/common/fill_context.py +141 -0
  24. ddx/common/logging.py +184 -0
  25. ddx/common/market_aware_account.py +259 -0
  26. ddx/common/market_specs.py +64 -0
  27. ddx/common/trade_mining_params.py +19 -0
  28. ddx/common/transaction_utils.py +85 -0
  29. ddx/common/transactions/__init__.py +0 -0
  30. ddx/common/transactions/advance_epoch.py +91 -0
  31. ddx/common/transactions/advance_settlement_epoch.py +63 -0
  32. ddx/common/transactions/all_price_checkpoints.py +84 -0
  33. ddx/common/transactions/cancel.py +76 -0
  34. ddx/common/transactions/cancel_all.py +88 -0
  35. ddx/common/transactions/complete_fill.py +103 -0
  36. ddx/common/transactions/disaster_recovery.py +96 -0
  37. ddx/common/transactions/event.py +48 -0
  38. ddx/common/transactions/fee_distribution.py +119 -0
  39. ddx/common/transactions/funding.py +292 -0
  40. ddx/common/transactions/futures_expiry.py +123 -0
  41. ddx/common/transactions/genesis.py +108 -0
  42. ddx/common/transactions/inner/__init__.py +0 -0
  43. ddx/common/transactions/inner/adl_outcome.py +25 -0
  44. ddx/common/transactions/inner/fill.py +232 -0
  45. ddx/common/transactions/inner/liquidated_position.py +41 -0
  46. ddx/common/transactions/inner/liquidation_entry.py +41 -0
  47. ddx/common/transactions/inner/liquidation_fill.py +118 -0
  48. ddx/common/transactions/inner/outcome.py +32 -0
  49. ddx/common/transactions/inner/trade_fill.py +292 -0
  50. ddx/common/transactions/insurance_fund_update.py +138 -0
  51. ddx/common/transactions/insurance_fund_withdraw.py +100 -0
  52. ddx/common/transactions/liquidation.py +353 -0
  53. ddx/common/transactions/partial_fill.py +125 -0
  54. ddx/common/transactions/pnl_realization.py +120 -0
  55. ddx/common/transactions/post.py +72 -0
  56. ddx/common/transactions/post_order.py +95 -0
  57. ddx/common/transactions/price_checkpoint.py +97 -0
  58. ddx/common/transactions/signer_registered.py +62 -0
  59. ddx/common/transactions/specs_update.py +61 -0
  60. ddx/common/transactions/strategy_update.py +158 -0
  61. ddx/common/transactions/tradable_product_update.py +98 -0
  62. ddx/common/transactions/trade_mining.py +147 -0
  63. ddx/common/transactions/trader_update.py +131 -0
  64. ddx/common/transactions/withdraw.py +90 -0
  65. ddx/common/transactions/withdraw_ddx.py +74 -0
  66. ddx/common/utils.py +176 -0
  67. ddx/config.py +17 -0
  68. ddx/derivadex_client.py +270 -0
  69. ddx/models/__init__.py +0 -0
  70. ddx/models/base.py +132 -0
  71. ddx/py.typed +0 -0
  72. ddx/realtime_client/__init__.py +2 -0
  73. ddx/realtime_client/config.py +2 -0
  74. ddx/realtime_client/models/__init__.py +611 -0
  75. ddx/realtime_client/realtime_client.py +646 -0
  76. ddx/rest_client/__init__.py +0 -0
  77. ddx/rest_client/clients/__init__.py +0 -0
  78. ddx/rest_client/clients/base_client.py +60 -0
  79. ddx/rest_client/clients/market_client.py +1243 -0
  80. ddx/rest_client/clients/on_chain_client.py +439 -0
  81. ddx/rest_client/clients/signed_client.py +292 -0
  82. ddx/rest_client/clients/system_client.py +843 -0
  83. ddx/rest_client/clients/trade_client.py +357 -0
  84. ddx/rest_client/constants/__init__.py +0 -0
  85. ddx/rest_client/constants/endpoints.py +66 -0
  86. ddx/rest_client/contracts/__init__.py +0 -0
  87. ddx/rest_client/contracts/checkpoint/__init__.py +560 -0
  88. ddx/rest_client/contracts/ddx/__init__.py +1949 -0
  89. ddx/rest_client/contracts/dummy_token/__init__.py +1014 -0
  90. ddx/rest_client/contracts/i_collateral/__init__.py +1414 -0
  91. ddx/rest_client/contracts/i_stake/__init__.py +696 -0
  92. ddx/rest_client/exceptions/__init__.py +0 -0
  93. ddx/rest_client/exceptions/exceptions.py +32 -0
  94. ddx/rest_client/http/__init__.py +0 -0
  95. ddx/rest_client/http/http_client.py +336 -0
  96. ddx/rest_client/models/__init__.py +0 -0
  97. ddx/rest_client/models/market.py +693 -0
  98. ddx/rest_client/models/signed.py +61 -0
  99. ddx/rest_client/models/system.py +311 -0
  100. ddx/rest_client/models/trade.py +185 -0
  101. ddx/rest_client/utils/__init__.py +0 -0
  102. ddx/rest_client/utils/encryption_utils.py +26 -0
  103. ddx/utils/__init__.py +0 -0
  104. ddx_python-1.0.4.dist-info/METADATA +63 -0
  105. ddx_python-1.0.4.dist-info/RECORD +106 -0
  106. 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
+ )