Skip to main content

vertex_sdk/core/
query.rs

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}