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,439 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from eth_account.signers.local import LocalAccount
|
|
5
|
+
from web3 import Web3
|
|
6
|
+
from web3.types import TxReceipt
|
|
7
|
+
from zero_ex.contract_wrappers import TxParams
|
|
8
|
+
from eth_abi.utils.padding import zpad32_right
|
|
9
|
+
|
|
10
|
+
from ddx._rust.decimal import Decimal
|
|
11
|
+
from ddx._rust.common.state.keys import StrategyKey
|
|
12
|
+
from ddx.common.utils import to_base_unit_amount_list, to_base_unit_amount
|
|
13
|
+
from ddx.rest_client.clients.base_client import BaseClient
|
|
14
|
+
from ddx.rest_client.contracts.i_collateral import ICollateral
|
|
15
|
+
from ddx.rest_client.contracts.ddx import DDX
|
|
16
|
+
from ddx.rest_client.contracts.dummy_token import DummyToken
|
|
17
|
+
from ddx.rest_client.contracts.checkpoint import Checkpoint
|
|
18
|
+
from ddx.rest_client.contracts.i_stake import IStake
|
|
19
|
+
from ddx.rest_client.constants.endpoints import OnChain
|
|
20
|
+
from ddx.rest_client.http.http_client import HTTPClient
|
|
21
|
+
|
|
22
|
+
COLLATERAL_DECIMALS = 6
|
|
23
|
+
DDX_DECIMALS = 18
|
|
24
|
+
DEFAULT_GAS_LIMIT = 500_000
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class OnChainClient(BaseClient):
|
|
28
|
+
"""
|
|
29
|
+
On-chain operations for depositing, withdrawing, and other activities.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
http : HTTPClient
|
|
34
|
+
The HTTP client instance to use for requests
|
|
35
|
+
base_url : str
|
|
36
|
+
The base URL for trading endpoints
|
|
37
|
+
web3_account : Any
|
|
38
|
+
The web3 account for signing requests
|
|
39
|
+
verifying_contract : str
|
|
40
|
+
The contract address
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
http: HTTPClient,
|
|
46
|
+
base_url: str,
|
|
47
|
+
web3_account: LocalAccount,
|
|
48
|
+
web3: Web3,
|
|
49
|
+
verifying_contract: str,
|
|
50
|
+
):
|
|
51
|
+
super().__init__(http, base_url)
|
|
52
|
+
self._web3_account = web3_account
|
|
53
|
+
self._web3 = web3
|
|
54
|
+
self._verifying_contract = verifying_contract
|
|
55
|
+
self._logger = logging.getLogger(__name__)
|
|
56
|
+
|
|
57
|
+
def _send_transaction(
|
|
58
|
+
self,
|
|
59
|
+
contract_method,
|
|
60
|
+
method_params: list,
|
|
61
|
+
nonce: Optional[int] = None,
|
|
62
|
+
gas: int = 500_000,
|
|
63
|
+
local_account: Optional[LocalAccount] = None,
|
|
64
|
+
) -> TxReceipt:
|
|
65
|
+
"""
|
|
66
|
+
Helper to build, sign and send a transaction.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
contract_method : ContractMethod
|
|
71
|
+
The contract method object
|
|
72
|
+
method_params : list
|
|
73
|
+
Parameters to pass to the contract method
|
|
74
|
+
nonce : Optional[int]
|
|
75
|
+
Custom nonce or None for auto
|
|
76
|
+
gas : int
|
|
77
|
+
Gas limit for transaction
|
|
78
|
+
local_account : Optional[LocalAccount]
|
|
79
|
+
Local account to sign with, defaults to client's account
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
TxReceipt
|
|
84
|
+
Transaction receipt
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
account = local_account or self._web3_account
|
|
88
|
+
|
|
89
|
+
if nonce is None:
|
|
90
|
+
nonce = self._web3.eth.get_transaction_count(account.address)
|
|
91
|
+
|
|
92
|
+
tx = contract_method.build_transaction(
|
|
93
|
+
*method_params,
|
|
94
|
+
tx_params=TxParams(from_=account.address, nonce=nonce, gas=gas),
|
|
95
|
+
)
|
|
96
|
+
signed_tx = self._web3.eth.account.sign_transaction(tx, private_key=account.key)
|
|
97
|
+
tx_hash = self._web3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
|
98
|
+
receipt = self._web3.eth.wait_for_transaction_receipt(tx_hash, poll_latency=0.5)
|
|
99
|
+
|
|
100
|
+
return receipt
|
|
101
|
+
|
|
102
|
+
def approve(
|
|
103
|
+
self,
|
|
104
|
+
collateral_address: str,
|
|
105
|
+
amount: Decimal,
|
|
106
|
+
nonce: Optional[int] = None,
|
|
107
|
+
local_account: Optional[LocalAccount] = None,
|
|
108
|
+
) -> TxReceipt:
|
|
109
|
+
"""
|
|
110
|
+
Approve ERC-20 collateral for transfer to the DerivaDEX contract.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
collateral_address : str
|
|
115
|
+
The token contract address to approve
|
|
116
|
+
amount : Decimal
|
|
117
|
+
Amount to approve for transfer
|
|
118
|
+
nonce : Optional[int]
|
|
119
|
+
Custom nonce for the transaction, if None uses next available
|
|
120
|
+
local_account : Optional[LocalAccount]
|
|
121
|
+
Local account to sign with, defaults to client's account
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
TxReceipt
|
|
126
|
+
Transaction receipt
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
if not self._verifying_contract:
|
|
130
|
+
raise TypeError("Verifying contract address is not set")
|
|
131
|
+
dummy_token = DummyToken(self._web3, collateral_address)
|
|
132
|
+
approve_amount = to_base_unit_amount(amount, COLLATERAL_DECIMALS)
|
|
133
|
+
|
|
134
|
+
return self._send_transaction(
|
|
135
|
+
dummy_token.approve,
|
|
136
|
+
method_params=[self._verifying_contract, approve_amount],
|
|
137
|
+
nonce=nonce,
|
|
138
|
+
local_account=local_account,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
async def deposit(
|
|
142
|
+
self,
|
|
143
|
+
collateral_address: str,
|
|
144
|
+
strategy_id: str,
|
|
145
|
+
amount: Decimal,
|
|
146
|
+
nonce: Optional[int] = None,
|
|
147
|
+
local_account: Optional[LocalAccount] = None,
|
|
148
|
+
) -> TxReceipt:
|
|
149
|
+
"""
|
|
150
|
+
Deposit ERC-20 collateral into a strategy.
|
|
151
|
+
|
|
152
|
+
Parameters
|
|
153
|
+
----------
|
|
154
|
+
collateral_address : str
|
|
155
|
+
The token contract address to deposit
|
|
156
|
+
strategy_id : str
|
|
157
|
+
Strategy identifier to deposit into
|
|
158
|
+
amount : Decimal
|
|
159
|
+
Amount to deposit
|
|
160
|
+
nonce : Optional[int]
|
|
161
|
+
Custom nonce for the transaction, if None uses next available
|
|
162
|
+
local_account : Optional[LocalAccount]
|
|
163
|
+
Local account to sign with, defaults to client's account
|
|
164
|
+
|
|
165
|
+
Returns
|
|
166
|
+
-------
|
|
167
|
+
TxReceipt
|
|
168
|
+
Transaction receipt
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
account = local_account or self._web3_account
|
|
172
|
+
kyc_auth = await self._http.get(
|
|
173
|
+
self._build_url(OnChain.KYC_AUTH), params={"trader": account.address}
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
encoded_strategy = zpad32_right(
|
|
177
|
+
len(strategy_id).to_bytes(1, byteorder="little")
|
|
178
|
+
+ strategy_id.encode("utf8")
|
|
179
|
+
)
|
|
180
|
+
deposit_amount = to_base_unit_amount(amount, COLLATERAL_DECIMALS)
|
|
181
|
+
i_collateral_contract = ICollateral(self._web3, self._verifying_contract)
|
|
182
|
+
|
|
183
|
+
return self._send_transaction(
|
|
184
|
+
i_collateral_contract.deposit,
|
|
185
|
+
method_params=[
|
|
186
|
+
collateral_address,
|
|
187
|
+
encoded_strategy,
|
|
188
|
+
deposit_amount,
|
|
189
|
+
kyc_auth["kycAuth"]["expiryBlock"],
|
|
190
|
+
kyc_auth["signature"],
|
|
191
|
+
],
|
|
192
|
+
nonce=nonce,
|
|
193
|
+
gas=DEFAULT_GAS_LIMIT,
|
|
194
|
+
local_account=local_account,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def approve_ddx(
|
|
198
|
+
self,
|
|
199
|
+
ddx_address: str,
|
|
200
|
+
amount: Decimal,
|
|
201
|
+
nonce: Optional[int] = None,
|
|
202
|
+
local_account: Optional[LocalAccount] = None,
|
|
203
|
+
) -> TxReceipt:
|
|
204
|
+
"""
|
|
205
|
+
Approve DDX for transfer to the DerivaDEX contract.
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
ddx_address : str
|
|
210
|
+
The DDX token contract address
|
|
211
|
+
amount : Decimal
|
|
212
|
+
Amount to approve for transfer
|
|
213
|
+
nonce : Optional[int]
|
|
214
|
+
Custom nonce for the transaction, if None uses next available
|
|
215
|
+
local_account : Optional[LocalAccount]
|
|
216
|
+
Local account to sign with, defaults to client's account
|
|
217
|
+
|
|
218
|
+
Returns
|
|
219
|
+
-------
|
|
220
|
+
TxReceipt
|
|
221
|
+
Transaction receipt
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
if not self._verifying_contract:
|
|
225
|
+
raise TypeError("Verifying contract address is not set")
|
|
226
|
+
ddx_contract = DDX(self._web3, ddx_address)
|
|
227
|
+
approve_amount = to_base_unit_amount(amount, DDX_DECIMALS)
|
|
228
|
+
|
|
229
|
+
return self._send_transaction(
|
|
230
|
+
ddx_contract.approve,
|
|
231
|
+
method_params=[self._verifying_contract, approve_amount],
|
|
232
|
+
nonce=nonce,
|
|
233
|
+
local_account=local_account,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
async def deposit_ddx(
|
|
237
|
+
self,
|
|
238
|
+
amount: Decimal,
|
|
239
|
+
nonce: Optional[int] = None,
|
|
240
|
+
local_account: Optional[LocalAccount] = None,
|
|
241
|
+
) -> TxReceipt:
|
|
242
|
+
"""
|
|
243
|
+
Deposit DDX to exchange.
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
----------
|
|
247
|
+
amount : Decimal
|
|
248
|
+
Amount of DDX to deposit
|
|
249
|
+
nonce : Optional[int]
|
|
250
|
+
Custom nonce for the transaction, if None uses next available
|
|
251
|
+
local_account : Optional[LocalAccount]
|
|
252
|
+
Local account to sign with, defaults to client's account
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
TxReceipt
|
|
257
|
+
Transaction receipt
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
account = local_account or self._web3_account
|
|
261
|
+
kyc_auth = await self._http.get(
|
|
262
|
+
self._build_url(OnChain.KYC_AUTH), params={"trader": account.address}
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
deposit_amount = to_base_unit_amount(amount, DDX_DECIMALS)
|
|
266
|
+
i_stake_contract = IStake(self._web3, self._verifying_contract)
|
|
267
|
+
|
|
268
|
+
return self._send_transaction(
|
|
269
|
+
i_stake_contract.deposit_ddx,
|
|
270
|
+
method_params=[
|
|
271
|
+
deposit_amount,
|
|
272
|
+
kyc_auth["kycAuth"]["expiryBlock"],
|
|
273
|
+
kyc_auth["signature"],
|
|
274
|
+
],
|
|
275
|
+
nonce=nonce,
|
|
276
|
+
gas=DEFAULT_GAS_LIMIT,
|
|
277
|
+
local_account=local_account,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
async def withdraw(
|
|
281
|
+
self,
|
|
282
|
+
collateral_address: str,
|
|
283
|
+
strategy_id: str,
|
|
284
|
+
amount: Decimal,
|
|
285
|
+
nonce: Optional[int] = None,
|
|
286
|
+
local_account: Optional[LocalAccount] = None,
|
|
287
|
+
) -> TxReceipt:
|
|
288
|
+
"""
|
|
289
|
+
Withdraw collateral from a strategy.
|
|
290
|
+
|
|
291
|
+
Parameters
|
|
292
|
+
----------
|
|
293
|
+
collateral_address : str
|
|
294
|
+
The token contract address to withdraw
|
|
295
|
+
strategy_id : str
|
|
296
|
+
Strategy identifier to withdraw from
|
|
297
|
+
amount : Decimal
|
|
298
|
+
Amount to deposit
|
|
299
|
+
nonce : Optional[int]
|
|
300
|
+
Custom nonce for the transaction, if None uses next available
|
|
301
|
+
local_account : Optional[LocalAccount]
|
|
302
|
+
Local account to sign with, defaults to client's account
|
|
303
|
+
|
|
304
|
+
Returns
|
|
305
|
+
-------
|
|
306
|
+
TxReceipt
|
|
307
|
+
Transaction receipt
|
|
308
|
+
"""
|
|
309
|
+
|
|
310
|
+
account = local_account or self._web3_account
|
|
311
|
+
|
|
312
|
+
# Get checkpointed epoch id
|
|
313
|
+
checkpoint_contract = Checkpoint(self._web3, self._verifying_contract)
|
|
314
|
+
checkpointed_epoch_id = checkpoint_contract.get_latest_checkpoint.call()[3]
|
|
315
|
+
|
|
316
|
+
# Get withdrawal proof
|
|
317
|
+
strategy_key = StrategyKey(
|
|
318
|
+
f"0x00{account.address[2:]}",
|
|
319
|
+
StrategyKey.generate_strategy_id_hash(strategy_id),
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
proof_response = await self._http.get(
|
|
323
|
+
self._build_url(OnChain.PROOF),
|
|
324
|
+
params={
|
|
325
|
+
"key": str(strategy_key.encode_key()),
|
|
326
|
+
"epochId": checkpointed_epoch_id,
|
|
327
|
+
},
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
collateral_address = self._web3.to_checksum_address(collateral_address)
|
|
331
|
+
|
|
332
|
+
# Prepare strategy data
|
|
333
|
+
checkpointed_strategy = {
|
|
334
|
+
"maxLeverage": 3,
|
|
335
|
+
"frozen": False,
|
|
336
|
+
"availCollateral": {
|
|
337
|
+
"tokens": [
|
|
338
|
+
self._web3.to_checksum_address(key)
|
|
339
|
+
for key in list(
|
|
340
|
+
proof_response["item"]["Strategy"]["availCollateral"].keys()
|
|
341
|
+
)
|
|
342
|
+
],
|
|
343
|
+
"amounts": to_base_unit_amount_list(
|
|
344
|
+
[
|
|
345
|
+
Decimal(val)
|
|
346
|
+
for val in list(
|
|
347
|
+
proof_response["item"]["Strategy"][
|
|
348
|
+
"availCollateral"
|
|
349
|
+
].values()
|
|
350
|
+
)
|
|
351
|
+
],
|
|
352
|
+
6,
|
|
353
|
+
),
|
|
354
|
+
},
|
|
355
|
+
"lockedCollateral": {
|
|
356
|
+
"tokens": [
|
|
357
|
+
self._web3.to_checksum_address(key)
|
|
358
|
+
for key in list(
|
|
359
|
+
proof_response["item"]["Strategy"]["lockedCollateral"].keys()
|
|
360
|
+
)
|
|
361
|
+
],
|
|
362
|
+
"amounts": to_base_unit_amount_list(
|
|
363
|
+
[
|
|
364
|
+
Decimal(val)
|
|
365
|
+
for val in list(
|
|
366
|
+
proof_response["item"]["Strategy"][
|
|
367
|
+
"lockedCollateral"
|
|
368
|
+
].values()
|
|
369
|
+
)
|
|
370
|
+
],
|
|
371
|
+
6,
|
|
372
|
+
),
|
|
373
|
+
},
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
withdraw_data = {
|
|
377
|
+
"tokens": [collateral_address],
|
|
378
|
+
"amounts": [int(amount * Decimal("1e6"))],
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
# Execute withdrawal
|
|
382
|
+
i_collateral_contract = ICollateral(self._web3, self._verifying_contract)
|
|
383
|
+
return self._send_transaction(
|
|
384
|
+
i_collateral_contract.withdraw,
|
|
385
|
+
method_params=[
|
|
386
|
+
StrategyKey.generate_strategy_id_hash(strategy_id),
|
|
387
|
+
withdraw_data,
|
|
388
|
+
checkpointed_strategy,
|
|
389
|
+
f'0x{bytes(proof_response["proof"]).hex()}',
|
|
390
|
+
],
|
|
391
|
+
nonce=nonce,
|
|
392
|
+
local_account=local_account,
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# TODO: Add and fuzz withdraw_ddx method
|
|
396
|
+
# TODO: Add and fuzz checkpoint method
|
|
397
|
+
|
|
398
|
+
async def wait_for_confirmations(
|
|
399
|
+
self,
|
|
400
|
+
tx_receipt: TxReceipt,
|
|
401
|
+
confirmations: int = 6,
|
|
402
|
+
check_interval: float = 1.0,
|
|
403
|
+
) -> None:
|
|
404
|
+
"""
|
|
405
|
+
Wait for required number of block confirmations.
|
|
406
|
+
|
|
407
|
+
Parameters
|
|
408
|
+
----------
|
|
409
|
+
tx_receipt : TxReceipt
|
|
410
|
+
Transaction receipt containing block number
|
|
411
|
+
confirmations : int, default=6
|
|
412
|
+
Number of block confirmations to wait for
|
|
413
|
+
check_interval : float, default=1.0
|
|
414
|
+
How often to check for new blocks in seconds
|
|
415
|
+
|
|
416
|
+
Raises
|
|
417
|
+
------
|
|
418
|
+
TimeoutError
|
|
419
|
+
If confirmations don't arrive within reasonable time
|
|
420
|
+
"""
|
|
421
|
+
|
|
422
|
+
tx_block_number = tx_receipt.blockNumber
|
|
423
|
+
timeout = (confirmations * 2) * 12
|
|
424
|
+
start_time = asyncio.get_event_loop().time()
|
|
425
|
+
|
|
426
|
+
while True:
|
|
427
|
+
current_block = self._web3.eth.block_number
|
|
428
|
+
confirmed_blocks = current_block - tx_block_number
|
|
429
|
+
|
|
430
|
+
if confirmed_blocks >= confirmations:
|
|
431
|
+
return
|
|
432
|
+
|
|
433
|
+
if asyncio.get_event_loop().time() - start_time > timeout:
|
|
434
|
+
raise TimeoutError(
|
|
435
|
+
f"Timeout waiting for {confirmations} confirmations. "
|
|
436
|
+
f"Got {confirmed_blocks} after {timeout} seconds"
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
await asyncio.sleep(check_interval)
|