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 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 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 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 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 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}