1use async_trait::async_trait;
2use eyre::{eyre, Result};
3use serde::de::DeserializeOwned;
4
5use crate::engine::Query::Order;
6use crate::engine::{
7 AllProductsResponse, AssetsResponse, ContractsResponse, EngineStatus, FeeRatesResponse,
8 HealthGroupsResponse, InsuranceResponse, IsolatedPositionsResponse, LinkedSignerResponse,
9 MarketLiquidityResponse, MarketPairsParams, MarketPairsResponse, MarketPriceResponse,
10 MarketPricesResponse, MaxLpMintableResponse, MaxOrderSizeResponse, MaxVlpMintableResponse,
11 MaxWithdrawableResponse, NoncesResponse, OrderResponse, OrderbookParams, OrderbookResponse,
12 Query, QueryResponseData, QueryV2, SubaccountInfoResponse, SubaccountOrdersResponse,
13 SymbolsResponse, Txn,
14};
15use crate::trigger;
16use crate::trigger::ListTriggerOrdersResponse;
17
18use crate::core::base::VertexBase;
19use crate::map_response;
20
21#[async_trait]
22pub trait VertexQuery: VertexBase + Sync {
23 async fn query(&self, query: Query) -> Result<QueryResponseData>;
24
25 async fn query_trigger(&self, query: trigger::Query) -> Result<trigger::QueryResponseData>;
26
27 async fn query_v2<R: DeserializeOwned + Send>(&self, path: &str, query: QueryV2) -> Result<R>;
28
29 async fn get_status(&self) -> Result<EngineStatus> {
30 let query_response = self.query(Query::Status {}).await?;
31 map_response!(query_response, QueryResponseData::StatusResponse)
32 }
33
34 async fn get_contracts(&self) -> Result<ContractsResponse> {
35 let query_response = self.query(Query::Contracts {}).await?;
36 map_response!(query_response, QueryResponseData::Contracts)
37 }
38
39 async fn get_nonces(&self, address: [u8; 20]) -> Result<NoncesResponse> {
40 let query_response = self.query(Query::Nonces { address }).await?;
41 map_response!(query_response, QueryResponseData::Nonces)
42 }
43
44 async fn next_tx_nonce(&self, address: [u8; 20]) -> Result<u64> {
45 let nonces = self.get_nonces(address).await?;
46 let tx_nonce = nonces.tx_nonce;
47 Ok(tx_nonce)
48 }
49
50 async fn get_linked_signer(&self, subaccount: [u8; 32]) -> Result<LinkedSignerResponse> {
51 let query_response = self.query(Query::LinkedSigner { subaccount }).await?;
52 map_response!(query_response, QueryResponseData::LinkedSigner)
53 }
54
55 async fn get_subaccount_info(&self, subaccount: [u8; 32]) -> Result<SubaccountInfoResponse> {
56 self.get_subaccount_info_with_txns(subaccount, vec![]).await
57 }
58
59 async fn get_subaccount_info_with_txns(
60 &self,
61 subaccount: [u8; 32],
62 txns: Vec<Txn>,
63 ) -> Result<SubaccountInfoResponse> {
64 let txns = if txns.is_empty() {
65 None
66 } else {
67 Some(serde_json::to_string(&txns)?)
68 };
69 let query_response = self
70 .query(Query::SubaccountInfo { subaccount, txns })
71 .await?;
72 map_response!(query_response, QueryResponseData::SubaccountInfo)
73 }
74
75 async fn get_all_products(&self) -> Result<AllProductsResponse> {
76 let query = Query::AllProducts {};
77 let query_response = self.query(query).await?;
78 map_response!(query_response, QueryResponseData::AllProducts)
79 }
80
81 async fn get_token_address(&self, product_id: u32) -> Result<[u8; 20]> {
82 let products = self.get_all_products().await?;
83 for p in products.spot_products {
84 if p.product_id == product_id {
85 return Ok(p.config.token);
86 }
87 }
88 Err(eyre!("get_token_address: product id not found"))
89 }
90
91 async fn get_market_price(&self, product_id: u32) -> Result<MarketPriceResponse> {
92 let query_response = self.query(Query::MarketPrice { product_id }).await?;
93 map_response!(query_response, QueryResponseData::MarketPrice)
94 }
95
96 async fn get_market_prices(&self, product_ids: Vec<u32>) -> Result<MarketPricesResponse> {
97 let query_response = self.query(Query::MarketPrices { product_ids }).await?;
98 map_response!(query_response, QueryResponseData::MarketPrices)
99 }
100
101 async fn get_order(&self, product_id: u32, digest: [u8; 32]) -> Result<OrderResponse> {
102 let query = Order { product_id, digest };
103 let query_response = self.query(query).await?;
104 map_response!(query_response, QueryResponseData::Order)
105 }
106
107 async fn get_fee_rates(&self, sender: [u8; 32]) -> Result<FeeRatesResponse> {
108 let query_response = self.query(Query::FeeRates { sender }).await?;
109 map_response!(query_response, QueryResponseData::FeeRates)
110 }
111
112 async fn get_subaccount_orders(
113 &self,
114 sender: [u8; 32],
115 product_id: u32,
116 ) -> Result<SubaccountOrdersResponse> {
117 let query = Query::SubaccountOrders { sender, product_id };
118 let query_response = self.query(query).await?;
119 map_response!(query_response, QueryResponseData::SubaccountOrders)
120 }
121
122 async fn get_market_liquidity(
123 &self,
124 product_id: u32,
125 depth: u32,
126 ) -> Result<MarketLiquidityResponse> {
127 let query_response = self
128 .query(Query::MarketLiquidity { product_id, depth })
129 .await?;
130 map_response!(query_response, QueryResponseData::MarketLiquidity)
131 }
132
133 async fn get_max_order_size(
134 &self,
135 max_order_size_query: Query,
136 ) -> Result<MaxOrderSizeResponse> {
137 let query_response = self.query(max_order_size_query).await?;
138 map_response!(query_response, QueryResponseData::MaxOrderSize)
139 }
140
141 async fn get_max_withdrawable(
142 &self,
143 max_withdrawable_query: Query,
144 ) -> Result<MaxWithdrawableResponse> {
145 let query_response = self.query(max_withdrawable_query).await?;
146 map_response!(query_response, QueryResponseData::MaxWithdrawable)
147 }
148
149 async fn get_max_lp_mintable(
150 &self,
151 max_lp_mintable_query: Query,
152 ) -> Result<MaxLpMintableResponse> {
153 let query_response = self.query(max_lp_mintable_query).await?;
154 map_response!(query_response, QueryResponseData::MaxLpMintable)
155 }
156
157 async fn get_max_vlp_mintable(
158 &self,
159 max_vlp_mintable_query: Query,
160 ) -> Result<MaxVlpMintableResponse> {
161 let query_response = self.query(max_vlp_mintable_query).await?;
162 map_response!(query_response, QueryResponseData::MaxVlpMintable)
163 }
164
165 async fn get_health_groups(&self) -> Result<HealthGroupsResponse> {
166 let query_response = self.query(Query::HealthGroups {}).await?;
167 map_response!(query_response, QueryResponseData::HealthGroups)
168 }
169
170 async fn get_insurance(&self) -> Result<InsuranceResponse> {
171 let query_response = self.query(Query::Insurance {}).await?;
172 map_response!(query_response, QueryResponseData::Insurance)
173 }
174
175 async fn get_symbols(
176 &self,
177 product_ids: Option<Vec<u32>>,
178 product_type: Option<String>,
179 ) -> Result<SymbolsResponse> {
180 let query_response = self
181 .query(Query::Symbols {
182 product_ids,
183 product_type,
184 })
185 .await?;
186 map_response!(query_response, QueryResponseData::Symbols)
187 }
188
189 async fn list_trigger_orders(
190 &self,
191 list_trigger_orders: trigger::Query,
192 ) -> Result<ListTriggerOrdersResponse> {
193 let query_response = self.query_trigger(list_trigger_orders).await?;
194 map_response!(
195 query_response,
196 trigger::QueryResponseData::ListTriggerOrders
197 )
198 }
199
200 async fn get_orderbook(&self, ticker_id: String, depth: u32) -> Result<OrderbookResponse> {
201 let query = QueryV2::Orderbook(OrderbookParams { ticker_id, depth });
202 self.query_v2("/orderbook", query).await
203 }
204
205 async fn get_pairs(&self, market: Option<String>) -> Result<MarketPairsResponse> {
206 let query = QueryV2::Pairs(MarketPairsParams { market });
207 self.query_v2("/pairs", query).await
208 }
209
210 async fn get_assets(&self) -> Result<AssetsResponse> {
211 let query = QueryV2::Assets {};
212 self.query_v2("/assets", query).await
213 }
214
215 async fn get_isolated_positions(
216 &self,
217 subaccount: [u8; 32],
218 ) -> Result<IsolatedPositionsResponse> {
219 let query_response = self.query(Query::IsolatedPositions { subaccount }).await?;
220 map_response!(query_response, QueryResponseData::IsolatedPositions)
221 }
222}