@@ -200,13 +200,14 @@ def create_signed_order(self, params:OrderSignatureRequest):
200200 maker = order ["maker" ]
201201 )
202202
203- def create_signed_cancel_order (self ,params :OrderSignatureRequest ):
203+ def create_signed_cancel_order (self ,params :OrderSignatureRequest , parentAddress : str = "" ):
204204 """
205205 Creates a cancel order request from provided params and signs it using the private
206206 key of the account
207207
208208 Inputs:
209209 - params (OrderSignatureRequest): parameters to create cancel order with
210+ - parentAddress (str): Only provided by a sub account
210211
211212 Returns:
212213 - OrderSignatureResponse: generated cancel signature
@@ -215,30 +216,32 @@ def create_signed_cancel_order(self,params:OrderSignatureRequest):
215216 signer :OrderSigner = self ._get_order_signer (params ["symbol" ])
216217 order_to_sign = self .create_order_to_sign (params )
217218 hash = signer .get_order_hash (order_to_sign )
218- return self .create_signed_cancel_orders (params ["symbol" ],hash )
219+ return self .create_signed_cancel_orders (params ["symbol" ], hash , parentAddress )
219220 except Exception as e :
220221 return ""
221222
222- def create_signed_cancel_orders (self ,symbol :MARKET_SYMBOLS ,order_hash :list ):
223+ def create_signed_cancel_orders (self , symbol :MARKET_SYMBOLS , order_hash :list , parentAddress : str = "" ):
223224 """
224225 Creates a cancel order from provided params and sign it using the private
225226 key of the account
226227
227228 Inputs:
228- params (list): a list of order hashes
229-
229+ - params (list): a list of order hashes
230+ - parentAddress (str): only provided by a sub account
230231 Returns:
231232 OrderCancellationRequest: containing symbol, hashes and signature
232233 """
233234 if type (order_hash )!= list :
234235 order_hash = [order_hash ]
236+
235237 order_signer :OrderSigner = self ._get_order_signer (symbol )
236238 cancel_hash = order_signer .sign_cancellation_hash (order_hash )
237239 hash_sig = order_signer .sign_hash (cancel_hash ,self .account .key .hex (), "01" )
238240 return OrderCancellationRequest (
239241 symbol = symbol .value ,
240242 hashes = order_hash ,
241- signature = hash_sig
243+ signature = hash_sig ,
244+ parentAddress = parentAddress
242245 )
243246
244247 async def post_cancel_order (self ,params :OrderCancellationRequest ):
@@ -255,22 +258,25 @@ async def post_cancel_order(self,params:OrderCancellationRequest):
255258 {
256259 "symbol" : params ["symbol" ],
257260 "orderHashes" :params ["hashes" ],
258- "cancelSignature" :params ["signature" ]
261+ "cancelSignature" :params ["signature" ],
262+ "parentAddress" : params ["parentAddress" ],
259263 },
260264 auth_required = True
261265 )
262266
263- async def cancel_all_open_orders (self ,symbol :MARKET_SYMBOLS ):
267+ async def cancel_all_open_orders (self ,symbol :MARKET_SYMBOLS , parentAddress : str = "" ):
264268 """
265269 GETs all open orders for the specified symbol, creates a cancellation request
266270 for all orders and POSTs the cancel order request to Firefly
267271 Inputs:
268- - symbol(MARKET_SYMBOLS)
272+ - symbol (MARKET_SYMBOLS): Market for which orders are to be cancelled
273+ - parentAddress (str): address of parent account, only provided by sub account
269274 Returns:
270275 - dict: response from orders delete API Firefly
271276 """
272277 orders = await self .get_orders ({
273278 "symbol" :symbol ,
279+ "parentAddress" : parentAddress ,
274280 "statuses" :[ORDER_STATUS .OPEN , ORDER_STATUS .PARTIAL_FILLED ]
275281 })
276282
@@ -279,7 +285,7 @@ async def cancel_all_open_orders(self,symbol:MARKET_SYMBOLS):
279285 hashes .append (i ["hash" ])
280286
281287 if len (hashes ) > 0 :
282- req = self .create_signed_cancel_orders (symbol ,hashes )
288+ req = self .create_signed_cancel_orders (symbol , hashes , parentAddress )
283289 return await self .post_cancel_order (req )
284290
285291 return False
@@ -384,39 +390,41 @@ async def withdraw_margin_from_bank(self, amount):
384390
385391 return True ;
386392
387- async def adjust_leverage (self , symbol , leverage ):
393+ async def adjust_leverage (self , symbol , leverage , parentAddress : str = "" ):
388394 """
389395 Adjusts user leverage to the provided one for their current position on-chain and off-chain.
390396 If a user has no position for the provided symbol, leverage only recorded off-chain
391397
392398 Inputs:
393399 symbol (MARKET_SYMBOLS): market for which to adjust user leverage
394400 leverage (number): new leverage to be set. Must be in base decimals (1,2 etc.)
395-
401+ parentAddress (str): optional, if provided, the leverage of parent is
402+ being adjusted (for sub accounts only)
396403 Returns:
397404 Boolean: true if the leverage is successfully adjusted
398405 """
399406
400- user_position = await self .get_user_position ({"symbol" :symbol })
401-
407+ user_position = await self .get_user_position ({"symbol" :symbol , "parentAddress" : parentAddress })
408+
409+ account_address = Web3 .toChecksumAddress (self .account .address if parentAddress == "" else parentAddress )
410+
402411 # implies user has an open position on-chain, perform on-chain leverage update
403412 if (user_position != {}):
404413 perp_contract = self .contracts .get_contract (name = "Perpetual" , market = symbol .value );
405414 construct_txn = perp_contract .functions .adjustLeverage (
406- self . account . address ,
415+ account_address ,
407416 to_wei (leverage , "ether" )).buildTransaction ({
408417 'from' : self .account .address ,
409418 'nonce' : self .w3 .eth .getTransactionCount (self .account .address ),
410- })
411-
419+ })
412420 self ._execute_tx (construct_txn )
413421
414422 else :
415423 await self .apis .post (
416424 SERVICE_URLS ["USER" ]["ADJUST_LEVERAGE" ],
417425 {
418426 "symbol" : symbol .value ,
419- "address" : self . account . address ,
427+ "address" : account_address ,
420428 "leverage" : to_wei (leverage , "ether" ),
421429 "marginType" : MARGIN_TYPE .ISOLATED .value ,
422430 },
@@ -425,20 +433,23 @@ async def adjust_leverage(self, symbol, leverage):
425433
426434 return True
427435
428- async def adjust_margin (self , symbol , operation , amount ):
436+ async def adjust_margin (self , symbol , operation , amount , parentAddress : str = "" ):
429437 """
430438 Adjusts user's on-chain position by adding or removing the specified amount of margin.
431439 Performs on-chain contract call, the user must have gas tokens
432440 Inputs:
433441 symbol (MARKET_SYMBOLS): market for which to adjust user leverage
434442 operation (ADJUST_MARGIN): ADD/REMOVE adding or removing margin to position
435443 amount (number): amount of margin to be adjusted
436-
444+ parentAddress (str): optional, if provided, the margin of parent is
445+ being adjusted (for sub accounts only)
437446 Returns:
438447 Boolean: true if the margin is adjusted
439448 """
440449
441- user_position = await self .get_user_position ({"symbol" :symbol })
450+ user_position = await self .get_user_position ({"symbol" :symbol , "parentAddress" : parentAddress })
451+
452+ account_address = Web3 .toChecksumAddress (self .account .address if parentAddress == "" else parentAddress )
442453
443454 if (user_position == {}):
444455 raise (Exception ("User has no open position on market: {}" .format (symbol )))
@@ -447,7 +458,7 @@ async def adjust_margin(self, symbol, operation, amount):
447458 on_chain_call = perp_contract .functions .addMargin if operation == ADJUST_MARGIN .ADD else perp_contract .functions .removeMargin
448459
449460 construct_txn = on_chain_call (
450- self . account . address ,
461+ account_address ,
451462 to_wei (amount , "ether" )).buildTransaction ({
452463 'from' : self .account .address ,
453464 'nonce' : self .w3 .eth .getTransactionCount (self .account .address ),
@@ -746,24 +757,27 @@ async def get_user_trades(self,params:GetUserTradesRequest):
746757 True
747758 )
748759
749- async def get_user_account_data (self ):
760+ async def get_user_account_data (self , parentAddress : str = "" ):
750761 """
751762 Returns user account data.
763+ Inputs:
764+ - parentAddress: an optional field, used by sub accounts to fetch parent account state
752765 """
753766 return await self .apis .get (
754767 service_url = SERVICE_URLS ["USER" ]["ACCOUNT" ],
768+ query = { "parentAddress" : parentAddress },
755769 auth_required = True
756770 )
757771
758- async def get_user_leverage (self , symbol :MARKET_SYMBOLS ):
772+ async def get_user_leverage (self , symbol :MARKET_SYMBOLS , parentAddress : str = "" ):
759773 """
760774 Returns user market default leverage.
761775 Inputs:
762776 - symbol(MARKET_SYMBOLS): market symbol to get user market default leverage for.
763777 Returns:
764778 - str: user default leverage
765779 """
766- account_data_by_market = (await self .get_user_account_data ())["accountDataByMarket" ]
780+ account_data_by_market = (await self .get_user_account_data (parentAddress ))["accountDataByMarket" ]
767781
768782 for i in account_data_by_market :
769783 if symbol .value == i ["symbol" ]:
0 commit comments