diff --git a/nado_protocol/engine_client/query.py b/nado_protocol/engine_client/query.py index 55c238e..b85f087 100644 --- a/nado_protocol/engine_client/query.py +++ b/nado_protocol/engine_client/query.py @@ -1,3 +1,4 @@ +import json from typing import Optional import requests @@ -182,7 +183,10 @@ def get_order(self, product_id: int, digest: str) -> OrderData: ) def get_subaccount_info( - self, subaccount: str, txs: Optional[list[QuerySubaccountInfoTx]] = None + self, + subaccount: str, + txs: Optional[list[QuerySubaccountInfoTx]] = None, + pre_state: Optional[bool] = None, ) -> SubaccountInfoData: """ Query the engine for the state of a subaccount, including balances. @@ -193,11 +197,26 @@ def get_subaccount_info( txs (list[QuerySubaccountInfoTx], optional): You can optionally provide a list of txs, to get an estimated view of what the subaccount state would look like if the transactions were applied. + pre_state (bool, optional): When True and txs are provided, returns the subaccount state before the + transactions were applied in the pre_state field. Defaults to False. + Returns: SubaccountInfoData: Information about the specified subaccount. """ + txns_str = None + if txs is not None: + txns_str = json.dumps([tx.dict() for tx in txs]) + + pre_state_str = None + if pre_state is not None: + pre_state_str = str(pre_state).lower() + return ensure_data_type( - self.query(QuerySubaccountInfoParams(subaccount=subaccount, txs=txs)).data, + self.query( + QuerySubaccountInfoParams( + subaccount=subaccount, txns=txns_str, pre_state=pre_state_str + ) + ).data, SubaccountInfoData, ) diff --git a/nado_protocol/engine_client/types/__init__.py b/nado_protocol/engine_client/types/__init__.py index 77fd199..5c60eb3 100644 --- a/nado_protocol/engine_client/types/__init__.py +++ b/nado_protocol/engine_client/types/__init__.py @@ -60,6 +60,7 @@ class EngineClientOpts(NadoClientOpts): "ContractsData", "NoncesData", "OrderData", + "PreState", "SubaccountInfoData", "SubaccountOpenOrdersData", "MarketLiquidityData", diff --git a/nado_protocol/engine_client/types/query.py b/nado_protocol/engine_client/types/query.py index bea7cb2..90e7553 100644 --- a/nado_protocol/engine_client/types/query.py +++ b/nado_protocol/engine_client/types/query.py @@ -101,7 +101,8 @@ class QuerySubaccountInfoParams(NadoBaseModel): type = EngineQueryType.SUBACCOUNT_INFO.value subaccount: str - txs: Optional[list[QuerySubaccountInfoTx]] + txns: Optional[str] + pre_state: Optional[str] class QuerySubaccountOpenOrdersParams(NadoBaseModel): @@ -299,6 +300,17 @@ class OrderData(NadoBaseModel): placed_at: str +class PreState(NadoBaseModel): + """ + Model for subaccount state before simulated transactions were applied. + """ + + healths: list[SubaccountHealth] + health_contributions: list[list[str]] + spot_balances: list[SpotProductBalance] + perp_balances: list[PerpProductBalance] + + class SubaccountInfoData(NadoBaseModel): """ Model for detailed info about a subaccount, including balances. @@ -314,6 +326,7 @@ class SubaccountInfoData(NadoBaseModel): perp_balances: list[PerpProductBalance] spot_products: list[SpotProduct] perp_products: list[PerpProduct] + pre_state: Optional[PreState] def parse_subaccount_balance( self, product_id: int diff --git a/pyproject.toml b/pyproject.toml index df25ab7..ad0386e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nado-protocol" -version = "0.2.7" +version = "0.2.8" description = "Nado Protocol SDK" authors = ["Jeury Mejia "] homepage = "https://nado.xyz" diff --git a/sanity/engine_client.py b/sanity/engine_client.py index 6be0cb8..ebf76ee 100644 --- a/sanity/engine_client.py +++ b/sanity/engine_client.py @@ -19,6 +19,7 @@ from nado_protocol.engine_client.types.query import ( QueryMaxOrderSizeParams, ) +from nado_protocol.engine_client.types.models import ApplyDelta, ApplyDeltaTx from nado_protocol.utils.bytes32 import ( bytes32_to_hex, str_to_hex, @@ -79,7 +80,7 @@ def run(): pprint(spots_apr) print("querying orderbook for BTC-PERP pair...") - btc_perp_book = client.get_orderbook("BTC-PERP_USDT", 10) + btc_perp_book = client.get_orderbook("BTC-PERP_USDT0", 10) pprint(btc_perp_book) order_price = 100_000 @@ -132,6 +133,29 @@ def run(): subaccount_info = client.get_subaccount_info(sender) print("subaccount info:", subaccount_info.json(indent=2)) + print("querying subaccount info with simulated transaction and pre_state...") + # Simulate applying a delta to a perp product + simulated_tx = ApplyDeltaTx( + apply_delta=ApplyDelta( + product_id=2, + subaccount=sender, + amount_delta="100000000000000000", + v_quote_delta="3033500000000000000000", + ) + ) + subaccount_info_with_pre_state = client.get_subaccount_info( + sender, txs=[simulated_tx], pre_state=True + ) + print( + "subaccount info with simulation:", + subaccount_info_with_pre_state.json(indent=2), + ) + if subaccount_info_with_pre_state.pre_state: + print("✓ pre_state returned successfully") + print("pre_state healths:", subaccount_info_with_pre_state.pre_state.healths) + else: + print("✗ Warning: pre_state was not returned") + print("querying subaccount open orders...") subaccount_open_orders = client.get_subaccount_open_orders(product_id, sender) print("subaccount open orders:", subaccount_open_orders.json(indent=2))