injective_cosmwasm/
querier.rs

1use crate::oracle::{
2    response::{OraclePriceResponse, PythPriceResponse},
3    types::{OracleHistoryOptions, OracleInfo, OracleType},
4    volatility::TradeHistoryOptions,
5};
6use crate::query::{InjectiveQuery, InjectiveQueryWrapper};
7use crate::route::InjectiveRoute;
8use crate::tokenfactory::response::{TokenFactoryCreateDenomFeeResponse, TokenFactoryDenomSupplyResponse};
9use crate::wasmx::response::QueryContractRegistrationInfoResponse;
10use crate::{
11    exchange::{
12        cancel::CancellationStrategy,
13        order::OrderSide,
14        response::{
15            DerivativeMarketResponse, ExchangeParamsResponse, MarketMidPriceAndTOBResponse, MarketVolatilityResponse, OracleVolatilityResponse,
16            PerpetualMarketFundingResponse, PerpetualMarketInfoResponse, QueryAggregateMarketVolumeResponse, QueryAggregateVolumeResponse,
17            QueryMarketAtomicExecutionFeeMultiplierResponse, QueryOrderbookResponse, SpotMarketResponse, StakedAmountResponse,
18            SubaccountDepositResponse, SubaccountEffectivePositionInMarketResponse, SubaccountPositionInMarketResponse,
19            TraderDerivativeOrdersResponse, TraderSpotOrdersResponse,
20        },
21        types::{MarketId, SubaccountId},
22    },
23    oracle::types::ScalingOptions,
24};
25use cosmwasm_std::{Addr, QuerierWrapper, StdResult};
26use injective_math::FPDecimal;
27
28pub struct InjectiveQuerier<'a> {
29    querier: &'a QuerierWrapper<'a, InjectiveQueryWrapper>,
30}
31
32impl<'a> InjectiveQuerier<'a> {
33    pub fn new(querier: &'a QuerierWrapper<InjectiveQueryWrapper>) -> Self {
34        InjectiveQuerier { querier }
35    }
36
37    // Exchange
38    pub fn query_exchange_params(&self) -> StdResult<ExchangeParamsResponse> {
39        let request = InjectiveQueryWrapper {
40            route: InjectiveRoute::Exchange,
41            query_data: InjectiveQuery::ExchangeParams {},
42        };
43
44        let res: ExchangeParamsResponse = self.querier.query(&request.into())?;
45        Ok(res)
46    }
47
48    pub fn query_subaccount_deposit<T: Into<SubaccountId> + Clone, P: Into<String> + Clone>(
49        &self,
50        subaccount_id: &'a T,
51        denom: &'a P,
52    ) -> StdResult<SubaccountDepositResponse> {
53        let request = InjectiveQueryWrapper {
54            route: InjectiveRoute::Exchange,
55            query_data: InjectiveQuery::SubaccountDeposit {
56                subaccount_id: subaccount_id.clone().into(),
57                denom: denom.clone().into(),
58            },
59        };
60
61        let res: SubaccountDepositResponse = self.querier.query(&request.into())?;
62        Ok(res)
63    }
64
65    pub fn query_derivative_market<T: Into<MarketId> + Clone>(&self, market_id: &'a T) -> StdResult<DerivativeMarketResponse> {
66        let request = InjectiveQueryWrapper {
67            route: InjectiveRoute::Exchange,
68            query_data: InjectiveQuery::DerivativeMarket {
69                market_id: market_id.clone().into(),
70            },
71        };
72
73        let res: DerivativeMarketResponse = self.querier.query(&request.into())?;
74        Ok(res)
75    }
76
77    pub fn query_spot_market<T: Into<MarketId> + Clone>(&self, market_id: &'a T) -> StdResult<SpotMarketResponse> {
78        let request = InjectiveQueryWrapper {
79            route: InjectiveRoute::Exchange,
80            query_data: InjectiveQuery::SpotMarket {
81                market_id: market_id.clone().into(),
82            },
83        };
84
85        let res: SpotMarketResponse = self.querier.query(&request.into())?;
86        Ok(res)
87    }
88
89    pub fn query_effective_subaccount_position<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
90        &self,
91        market_id: &'a T,
92        subaccount_id: &'a P,
93    ) -> StdResult<SubaccountEffectivePositionInMarketResponse> {
94        let request = InjectiveQueryWrapper {
95            route: InjectiveRoute::Exchange,
96            query_data: InjectiveQuery::SubaccountEffectivePositionInMarket {
97                market_id: market_id.clone().into(),
98                subaccount_id: subaccount_id.clone().into(),
99            },
100        };
101
102        let res: SubaccountEffectivePositionInMarketResponse = self.querier.query(&request.into())?;
103        Ok(res)
104    }
105
106    pub fn query_vanilla_subaccount_position<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
107        &self,
108        market_id: &'a T,
109        subaccount_id: &'a P,
110    ) -> StdResult<SubaccountPositionInMarketResponse> {
111        let request = InjectiveQueryWrapper {
112            route: InjectiveRoute::Exchange,
113            query_data: InjectiveQuery::SubaccountPositionInMarket {
114                market_id: market_id.clone().into(),
115                subaccount_id: subaccount_id.clone().into(),
116            },
117        };
118
119        let res: SubaccountPositionInMarketResponse = self.querier.query(&request.into())?;
120        Ok(res)
121    }
122
123    pub fn query_trader_derivative_orders<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
124        &self,
125        market_id: &'a T,
126        subaccount_id: &'a P,
127    ) -> StdResult<TraderDerivativeOrdersResponse> {
128        let request = InjectiveQueryWrapper {
129            route: InjectiveRoute::Exchange,
130            query_data: InjectiveQuery::TraderDerivativeOrders {
131                market_id: market_id.clone().into(),
132                subaccount_id: subaccount_id.clone().into(),
133            },
134        };
135
136        let res: TraderDerivativeOrdersResponse = self.querier.query(&request.into())?;
137        Ok(res)
138    }
139
140    pub fn query_trader_transient_spot_orders<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
141        &self,
142        market_id: &'a T,
143        subaccount_id: &'a P,
144    ) -> StdResult<TraderSpotOrdersResponse> {
145        let request = InjectiveQueryWrapper {
146            route: InjectiveRoute::Exchange,
147            query_data: InjectiveQuery::TraderTransientSpotOrders {
148                market_id: market_id.clone().into(),
149                subaccount_id: subaccount_id.clone().into(),
150            },
151        };
152
153        let res: TraderSpotOrdersResponse = self.querier.query(&request.into())?;
154        Ok(res)
155    }
156
157    pub fn query_trader_transient_derivative_orders<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
158        &self,
159        market_id: &'a T,
160        subaccount_id: &'a P,
161    ) -> StdResult<TraderDerivativeOrdersResponse> {
162        let request = InjectiveQueryWrapper {
163            route: InjectiveRoute::Exchange,
164            query_data: InjectiveQuery::TraderTransientDerivativeOrders {
165                market_id: market_id.clone().into(),
166                subaccount_id: subaccount_id.clone().into(),
167            },
168        };
169
170        let res: TraderDerivativeOrdersResponse = self.querier.query(&request.into())?;
171        Ok(res)
172    }
173
174    pub fn query_trader_spot_orders<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
175        &self,
176        market_id: &'a T,
177        subaccount_id: &'a P,
178    ) -> StdResult<TraderSpotOrdersResponse> {
179        let request = InjectiveQueryWrapper {
180            route: InjectiveRoute::Exchange,
181            query_data: InjectiveQuery::TraderSpotOrders {
182                market_id: market_id.clone().into(),
183                subaccount_id: subaccount_id.clone().into(),
184            },
185        };
186
187        let res: TraderSpotOrdersResponse = self.querier.query(&request.into())?;
188        Ok(res)
189    }
190
191    pub fn query_spot_orders_to_cancel_up_to_amount<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
192        &self,
193        market_id: &'a T,
194        subaccount_id: &'a P,
195        base_amount: FPDecimal,
196        quote_amount: FPDecimal,
197        strategy: CancellationStrategy,
198        reference_price: Option<FPDecimal>,
199    ) -> StdResult<TraderSpotOrdersResponse> {
200        let request = InjectiveQueryWrapper {
201            route: InjectiveRoute::Exchange,
202            query_data: InjectiveQuery::TraderSpotOrdersToCancelUpToAmount {
203                market_id: market_id.clone().into(),
204                subaccount_id: subaccount_id.clone().into(),
205                base_amount,
206                quote_amount,
207                strategy,
208                reference_price,
209            },
210        };
211
212        let res: TraderSpotOrdersResponse = self.querier.query(&request.into())?;
213        Ok(res)
214    }
215
216    pub fn query_derivative_orders_to_cancel_up_to_amount<T: Into<MarketId> + Clone, P: Into<SubaccountId> + Clone>(
217        &self,
218        market_id: &'a T,
219        subaccount_id: &'a P,
220        quote_amount: FPDecimal,
221        strategy: CancellationStrategy,
222        reference_price: Option<FPDecimal>,
223    ) -> StdResult<TraderDerivativeOrdersResponse> {
224        let request = InjectiveQueryWrapper {
225            route: InjectiveRoute::Exchange,
226            query_data: InjectiveQuery::TraderDerivativeOrdersToCancelUpToAmount {
227                market_id: market_id.clone().into(),
228                subaccount_id: subaccount_id.clone().into(),
229                quote_amount,
230                strategy,
231                reference_price,
232            },
233        };
234
235        let res: TraderDerivativeOrdersResponse = self.querier.query(&request.into())?;
236        Ok(res)
237    }
238
239    pub fn query_perpetual_market_info<T: Into<MarketId> + Clone>(&self, market_id: &'a T) -> StdResult<PerpetualMarketInfoResponse> {
240        let request = InjectiveQueryWrapper {
241            route: InjectiveRoute::Exchange,
242            query_data: InjectiveQuery::PerpetualMarketInfo {
243                market_id: market_id.clone().into(),
244            },
245        };
246
247        let res: PerpetualMarketInfoResponse = self.querier.query(&request.into())?;
248        Ok(res)
249    }
250
251    pub fn query_perpetual_market_funding<T: Into<MarketId> + Clone>(&self, market_id: &'a T) -> StdResult<PerpetualMarketFundingResponse> {
252        let request = InjectiveQueryWrapper {
253            route: InjectiveRoute::Exchange,
254            query_data: InjectiveQuery::PerpetualMarketFunding {
255                market_id: market_id.clone().into(),
256            },
257        };
258
259        let res: PerpetualMarketFundingResponse = self.querier.query(&request.into())?;
260        Ok(res)
261    }
262
263    pub fn query_market_volatility<T: Into<MarketId> + Clone>(
264        &self,
265        market_id: &'a T,
266        trade_grouping_sec: u64,
267        max_age: u64,
268        include_raw_history: bool,
269        include_metadata: bool,
270    ) -> StdResult<MarketVolatilityResponse> {
271        let request = InjectiveQueryWrapper {
272            route: InjectiveRoute::Exchange,
273            query_data: InjectiveQuery::MarketVolatility {
274                market_id: market_id.clone().into(),
275                trade_history_options: TradeHistoryOptions {
276                    trade_grouping_sec,
277                    max_age,
278                    include_raw_history,
279                    include_metadata,
280                },
281            },
282        };
283
284        let res: MarketVolatilityResponse = self.querier.query(&request.into())?;
285        Ok(res)
286    }
287
288    pub fn query_derivative_market_mid_price_and_tob<T: Into<MarketId> + Clone>(&self, market_id: &'a T) -> StdResult<MarketMidPriceAndTOBResponse> {
289        let request = InjectiveQueryWrapper {
290            route: InjectiveRoute::Exchange,
291            query_data: InjectiveQuery::DerivativeMarketMidPriceAndTob {
292                market_id: market_id.clone().into(),
293            },
294        };
295
296        let res: MarketMidPriceAndTOBResponse = self.querier.query(&request.into())?;
297        Ok(res)
298    }
299
300    pub fn query_aggregate_market_volume<T: Into<MarketId> + Clone>(&self, market_id: &'a T) -> StdResult<QueryAggregateMarketVolumeResponse> {
301        let request = InjectiveQueryWrapper {
302            route: InjectiveRoute::Exchange,
303            query_data: InjectiveQuery::AggregateMarketVolume {
304                market_id: market_id.clone().into(),
305            },
306        };
307
308        let res: QueryAggregateMarketVolumeResponse = self.querier.query(&request.into())?;
309        Ok(res)
310    }
311
312    pub fn query_aggregate_account_volume<T: Into<String> + Clone>(&self, account_id: &'a T) -> StdResult<QueryAggregateVolumeResponse> {
313        let request = InjectiveQueryWrapper {
314            route: InjectiveRoute::Exchange,
315            query_data: InjectiveQuery::AggregateAccountVolume {
316                account: account_id.clone().into(),
317            },
318        };
319        let res: QueryAggregateVolumeResponse = self.querier.query(&request.into())?;
320        Ok(res)
321    }
322
323    pub fn query_spot_market_mid_price_and_tob<T: Into<MarketId> + Clone>(&self, market_id: &'a T) -> StdResult<MarketMidPriceAndTOBResponse> {
324        let request = InjectiveQueryWrapper {
325            route: InjectiveRoute::Exchange,
326            query_data: InjectiveQuery::SpotMarketMidPriceAndTob {
327                market_id: market_id.clone().into(),
328            },
329        };
330
331        let res: MarketMidPriceAndTOBResponse = self.querier.query(&request.into())?;
332        Ok(res)
333    }
334
335    pub fn query_spot_market_orderbook<T: Into<MarketId> + Clone>(
336        &self,
337        market_id: &'a T,
338        side: OrderSide,
339        limit_cumulative_quantity: Option<FPDecimal>,
340        limit_cumulative_notional: Option<FPDecimal>,
341    ) -> StdResult<QueryOrderbookResponse> {
342        let request = InjectiveQueryWrapper {
343            route: InjectiveRoute::Exchange,
344            query_data: InjectiveQuery::SpotOrderbook {
345                market_id: market_id.clone().into(),
346                order_side: side,
347                limit: 0,
348                limit_cumulative_quantity,
349                limit_cumulative_notional,
350            },
351        };
352        let res: QueryOrderbookResponse = self.querier.query(&request.into())?;
353        Ok(res)
354    }
355
356    pub fn query_derivative_market_orderbook<T: Into<MarketId> + Clone>(
357        &self,
358        market_id: &'a T,
359        limit_cumulative_notional: FPDecimal,
360    ) -> StdResult<QueryOrderbookResponse> {
361        let request = InjectiveQueryWrapper {
362            route: InjectiveRoute::Exchange,
363            query_data: InjectiveQuery::DerivativeOrderbook {
364                market_id: market_id.clone().into(),
365                limit: 0,
366                limit_cumulative_notional: Some(limit_cumulative_notional),
367            },
368        };
369        let res: QueryOrderbookResponse = self.querier.query(&request.into())?;
370        Ok(res)
371    }
372
373    pub fn query_market_atomic_execution_fee_multiplier<T: Into<MarketId> + Clone>(
374        &self,
375        market_id: &'a T,
376    ) -> StdResult<QueryMarketAtomicExecutionFeeMultiplierResponse> {
377        let request = InjectiveQueryWrapper {
378            route: InjectiveRoute::Exchange,
379            query_data: InjectiveQuery::MarketAtomicExecutionFeeMultiplier {
380                market_id: market_id.clone().into(),
381            },
382        };
383
384        let res: QueryMarketAtomicExecutionFeeMultiplierResponse = self.querier.query(&request.into())?;
385        Ok(res)
386    }
387
388    // Staking
389    pub fn query_staked_amount(&self, delegator_address: Addr, max_delegations: u16) -> StdResult<StakedAmountResponse> {
390        let request = InjectiveQueryWrapper {
391            route: InjectiveRoute::Staking,
392            query_data: InjectiveQuery::StakedAmount {
393                delegator_address,
394                max_delegations,
395            },
396        };
397
398        let res: StakedAmountResponse = self.querier.query(&request.into())?;
399        Ok(res)
400    }
401
402    // Oracle
403    pub fn query_oracle_volatility(
404        &self,
405        base_info: &'a Option<OracleInfo>,
406        quote_info: &'a Option<OracleInfo>,
407        max_age: u64,
408        include_raw_history: bool,
409        include_metadata: bool,
410    ) -> StdResult<OracleVolatilityResponse> {
411        let request = InjectiveQueryWrapper {
412            route: InjectiveRoute::Oracle,
413            query_data: InjectiveQuery::OracleVolatility {
414                base_info: base_info.clone(),
415                quote_info: quote_info.clone(),
416                oracle_history_options: Some(OracleHistoryOptions {
417                    max_age,
418                    include_raw_history,
419                    include_metadata,
420                }),
421            },
422        };
423
424        let res: OracleVolatilityResponse = self.querier.query(&request.into())?;
425        Ok(res)
426    }
427
428    pub fn query_oracle_price(
429        &self,
430        oracle_type: &'a OracleType,
431        base: &str,
432        quote: &str,
433        scaling_options: Option<ScalingOptions>,
434    ) -> StdResult<OraclePriceResponse> {
435        let request = InjectiveQueryWrapper {
436            route: InjectiveRoute::Oracle,
437            query_data: InjectiveQuery::OraclePrice {
438                oracle_type: *oracle_type,
439                base: base.into(),
440                quote: quote.into(),
441                scaling_options,
442            },
443        };
444
445        let res: OraclePriceResponse = self.querier.query(&request.into())?;
446        Ok(res)
447    }
448
449    pub fn query_pyth_price(&self, price_id: &str) -> StdResult<PythPriceResponse> {
450        let request = InjectiveQueryWrapper {
451            route: InjectiveRoute::Oracle,
452            query_data: InjectiveQuery::PythPrice {
453                price_id: price_id.to_string(),
454            },
455        };
456
457        let res: PythPriceResponse = self.querier.query(&request.into())?;
458        Ok(res)
459    }
460
461    // Tokenfactory
462    pub fn query_token_factory_denom_total_supply<T: Into<String> + Clone>(&self, denom: &'a T) -> StdResult<TokenFactoryDenomSupplyResponse> {
463        let request = InjectiveQueryWrapper {
464            route: InjectiveRoute::Tokenfactory,
465            query_data: InjectiveQuery::TokenFactoryDenomTotalSupply { denom: denom.clone().into() },
466        };
467
468        let res: TokenFactoryDenomSupplyResponse = self.querier.query(&request.into())?;
469        Ok(res)
470    }
471
472    pub fn query_token_factory_creation_fee(&self) -> StdResult<TokenFactoryCreateDenomFeeResponse> {
473        let request = InjectiveQueryWrapper {
474            route: InjectiveRoute::Tokenfactory,
475            query_data: InjectiveQuery::TokenFactoryDenomCreationFee {},
476        };
477
478        let res: TokenFactoryCreateDenomFeeResponse = self.querier.query(&request.into())?;
479        Ok(res)
480    }
481
482    // Wasmx
483    pub fn query_contract_registration_info<A: Into<String> + Clone>(
484        &self,
485        contract_address: &'a A,
486    ) -> StdResult<QueryContractRegistrationInfoResponse> {
487        let request = InjectiveQueryWrapper {
488            route: InjectiveRoute::Wasmx,
489            query_data: InjectiveQuery::WasmxRegisteredContractInfo {
490                contract_address: contract_address.clone().into(),
491            },
492        };
493
494        let res = self.querier.query(&request.into())?;
495
496        Ok(res)
497    }
498}