1use std::marker::PhantomData;
2use std::str::FromStr;
3
4use cosmwasm_std::testing::{MockApi, MockStorage};
5use cosmwasm_std::{
6 from_json, to_json_binary, Addr, AllBalanceResponse, BalanceResponse, BankQuery, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult,
7 QueryRequest, SupplyResponse, SystemError, SystemResult, Uint128, WasmQuery,
8};
9
10use injective_math::FPDecimal;
11
12use crate::exchange::{
13 derivative_market::DerivativeMarket,
14 response::QueryOrderbookResponse,
15 types::{AtomicMarketOrderAccessLevel, MarketVolume, Params, PriceLevel, VolumeByType},
16};
17use crate::oracle::{
18 types::{OracleHistoryOptions, OracleType, PriceState, PythPriceState},
19 volatility::TradeHistoryOptions,
20};
21
22use crate::tokenfactory::response::{TokenFactoryCreateDenomFeeResponse, TokenFactoryDenomSupplyResponse};
23use crate::wasmx::response::QueryContractRegistrationInfoResponse;
24use crate::{
25 CancellationStrategy, Deposit, DerivativeMarketResponse, ExchangeParamsResponse, FullDerivativeMarket, InjectiveQuery, InjectiveQueryWrapper,
26 MarketMidPriceAndTOBResponse, MarketStatus, MarketVolatilityResponse, OracleInfo, OracleVolatilityResponse, OrderSide,
27 PerpetualMarketFundingResponse, PerpetualMarketInfoResponse, PythPriceResponse, QueryAggregateMarketVolumeResponse, QueryAggregateVolumeResponse,
28 QueryMarketAtomicExecutionFeeMultiplierResponse, SpotMarket, SpotMarketResponse, SubaccountDepositResponse,
29 SubaccountEffectivePositionInMarketResponse, SubaccountPositionInMarketResponse, TraderDerivativeOrdersResponse, TraderSpotOrdersResponse,
30};
31use crate::{MarketId, SubaccountId};
32
33pub fn mock_dependencies() -> OwnedDeps<MockStorage, MockApi, WasmMockQuerier, InjectiveQueryWrapper> {
34 let custom_querier: WasmMockQuerier = WasmMockQuerier::new();
35
36 OwnedDeps {
37 api: MockApi::default().with_prefix("inj"),
38 storage: MockStorage::default(),
39 querier: custom_querier,
40 custom_query_type: PhantomData,
41 }
42}
43
44fn default_subaccount_deposit_response_handler() -> QuerierResult {
45 let response = SubaccountDepositResponse {
46 deposits: Deposit {
47 available_balance: FPDecimal::from(10_000_000_000u128),
49 total_balance: FPDecimal::from(10_000_000_000u128),
50 },
51 };
52 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
53}
54
55fn default_spot_market_response_handler(market_id: MarketId) -> QuerierResult {
56 let response = SpotMarketResponse {
57 market: Some(SpotMarket {
58 ticker: "INJ/USDT".to_string(),
59 base_denom: "INJ".to_string(),
60 quote_denom: "USDT".to_string(),
61 maker_fee_rate: FPDecimal::from_str("-0.0001").unwrap(),
62 taker_fee_rate: FPDecimal::from_str("0.001").unwrap(),
63 relayer_fee_share_rate: FPDecimal::from_str("0.4").unwrap(),
64 market_id,
65 status: MarketStatus::Active,
66 min_price_tick_size: FPDecimal::from_str("0.01").unwrap(),
67 min_quantity_tick_size: FPDecimal::from_str("1000000000000000.0").unwrap(),
68 min_notional: FPDecimal::from_str("0.01").unwrap(),
69 }),
70 };
71 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
72}
73
74fn default_trader_spot_orders_response_handler() -> QuerierResult {
75 let response = TraderSpotOrdersResponse { orders: None };
76 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
77}
78
79fn default_trader_spot_orders_to_cancel_up_to_amount_response_handler() -> QuerierResult {
80 let response = TraderSpotOrdersResponse { orders: None };
81 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
82}
83
84fn default_trader_derivative_orders_to_cancel_up_to_amount_response_handler() -> QuerierResult {
85 let response = TraderDerivativeOrdersResponse { orders: None };
86 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
87}
88
89fn default_derivative_market_response_handler(market_id: MarketId) -> QuerierResult {
90 let response = DerivativeMarketResponse {
91 market: Some(FullDerivativeMarket {
92 market: Some(DerivativeMarket {
93 ticker: "ticker".to_string(),
94 oracle_base: "oracle_base".to_string(),
95 oracle_quote: "oracle_quote".to_string(),
96 oracle_type: OracleType::Band,
97 oracle_scale_factor: 1,
98 quote_denom: "inj".to_string(),
99 market_id,
100 initial_margin_ratio: FPDecimal::from_str("0.1").unwrap(),
101 maintenance_margin_ratio: FPDecimal::from_str("0.05").unwrap(),
102 maker_fee_rate: FPDecimal::from_str("0.001").unwrap(),
103 taker_fee_rate: FPDecimal::from_str("0.002").unwrap(),
104 isPerpetual: true,
105 status: MarketStatus::Active,
106 min_price_tick_size: FPDecimal::from_str("100000.0").unwrap(),
107 min_quantity_tick_size: FPDecimal::from_str("0.0001").unwrap(),
108 }),
109 info: None,
110 mark_price: FPDecimal::ONE,
111 }),
112 };
113 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
114}
115
116fn default_subaccount_positions_response_handler() -> QuerierResult {
117 todo!()
118}
119
120fn default_subaccount_position_in_market_response_handler() -> QuerierResult {
121 let response = SubaccountPositionInMarketResponse { state: None };
122 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
123}
124
125fn default_subaccount_effective_position_in_market_response_handler() -> QuerierResult {
126 let response = SubaccountEffectivePositionInMarketResponse { state: None };
127 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
128}
129
130fn default_trader_derivative_orders_response_handler() -> QuerierResult {
131 let response = TraderDerivativeOrdersResponse { orders: None };
132 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
133}
134
135fn default_trader_transient_spot_orders_response_handler() -> QuerierResult {
136 let response = TraderSpotOrdersResponse { orders: None };
137 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
138}
139
140fn default_trader_transient_derivative_orders_response_handler() -> QuerierResult {
141 let response = TraderDerivativeOrdersResponse { orders: None };
142 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
143}
144
145fn default_perpetual_market_info_response_handler() -> QuerierResult {
146 let response = PerpetualMarketInfoResponse { info: None };
147 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
148}
149
150fn default_perpetual_market_funding_response_handler() -> QuerierResult {
151 let response = PerpetualMarketFundingResponse { state: None };
152 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
153}
154
155fn default_market_volatility_response_handler() -> QuerierResult {
156 let response = MarketVolatilityResponse {
157 volatility: Some(FPDecimal::ONE),
158 history_metadata: None,
159 raw_history: None,
160 };
161 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
162}
163
164fn default_spot_market_mid_price_and_tob_response_handler() -> QuerierResult {
165 let response = MarketMidPriceAndTOBResponse {
166 mid_price: Some(FPDecimal::from_str("200000").unwrap()),
167 best_buy_price: None,
168 best_sell_price: None,
169 };
170 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
171}
172
173fn default_derivative_market_mid_price_and_tob_response_handler() -> QuerierResult {
174 let response = MarketMidPriceAndTOBResponse {
175 mid_price: Some(FPDecimal::from_str("200000").unwrap()),
176 best_buy_price: None,
177 best_sell_price: None,
178 };
179 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
180}
181
182fn default_aggregate_market_volume_handler() -> QuerierResult {
183 let response = QueryAggregateMarketVolumeResponse {
184 volume: VolumeByType {
185 maker_volume: FPDecimal::from(100u128),
186 taker_volume: FPDecimal::from(100u128),
187 },
188 };
189 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
190}
191
192fn default_aggregate_account_volume_handler() -> QuerierResult {
193 let response = QueryAggregateVolumeResponse {
194 aggregate_volumes: Some(vec![
195 MarketVolume {
196 market_id: MarketId::unchecked("market_id_1"),
197 volume: VolumeByType {
198 maker_volume: FPDecimal::from(10000000u128),
199 taker_volume: FPDecimal::from(14000000u128),
200 },
201 },
202 MarketVolume {
203 market_id: MarketId::unchecked("market_id_2"),
204 volume: VolumeByType {
205 maker_volume: FPDecimal::from(20000000u128),
206 taker_volume: FPDecimal::from(25000000u128),
207 },
208 },
209 ]),
210 };
211 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
212}
213
214fn default_oracle_volatility_response_handler() -> QuerierResult {
215 let response = OracleVolatilityResponse {
216 volatility: Some(FPDecimal::ONE),
217 history_metadata: None,
218 raw_history: None,
219 };
220 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
221}
222
223fn default_pyth_price_response_handler() -> QuerierResult {
224 let response = PythPriceResponse {
225 price_state: Some(PythPriceState {
226 price_id: "0xff0ec26442c57d7456695b843694e7379b15cf1b250b27e0e47e657f1955aaff".to_string(),
227 ema_price: FPDecimal::ONE,
228 ema_conf: FPDecimal::ONE,
229 conf: FPDecimal::ONE,
230 publish_time: 1i64,
231 price_state: PriceState {
232 price: FPDecimal::ONE,
233 cumulative_price: FPDecimal::ONE,
234 timestamp: 1i64,
235 },
236 }),
237 };
238 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
239}
240
241fn default_token_factory_denom_total_supply_handler() -> QuerierResult {
242 let response = TokenFactoryDenomSupplyResponse {
243 total_supply: Uint128::from(1000u128),
244 };
245 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
246}
247
248fn default_bank_total_supply_handler() -> QuerierResult {
249 let response = SupplyResponse::new(Coin {
250 denom: "inj".to_string(),
251 amount: Uint128::from(1000u128),
252 });
253 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
254}
255
256fn default_token_factory_denom_creation_fee_handler() -> QuerierResult {
257 let response = TokenFactoryCreateDenomFeeResponse {
258 fee: vec![Coin::new(10u128, "inj")],
259 };
260 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
261}
262
263fn default_contract_registration_info_response_handler() -> QuerierResult {
264 let response = QueryContractRegistrationInfoResponse { contract: None };
265 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
266}
267
268fn default_balance_bank_query_handler(denom: impl Into<String>) -> QuerierResult {
269 let response = BalanceResponse::new(Coin::new(1000000000000000u128, denom));
270 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
271}
272
273fn default_all_balances_bank_query_handler() -> QuerierResult {
274 let response = AllBalanceResponse::new(vec![Coin::new(1000000000000000u128, "inj")]);
275 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
276}
277
278fn default_exchange_params_response_handler() -> QuerierResult {
279 let denom = "inj";
280
281 let response = ExchangeParamsResponse {
282 params: Some(Params {
283 spot_market_instant_listing_fee: Coin::new(100000000000000000000u128, denom),
284 derivative_market_instant_listing_fee: Coin::new(1000000000000000000000u128, denom),
285 default_spot_maker_fee_rate: FPDecimal::must_from_str("-0.0001"),
286 default_spot_taker_fee_rate: FPDecimal::must_from_str("0.001"),
287 default_derivative_maker_fee_rate: FPDecimal::must_from_str("-0.0001"),
288 default_derivative_taker_fee_rate: FPDecimal::must_from_str("0.001"),
289 default_initial_margin_ratio: FPDecimal::must_from_str("0.05"),
290 default_maintenance_margin_ratio: FPDecimal::must_from_str("0.02"),
291 default_funding_interval: 3600i64,
292 relayer_fee_share_rate: FPDecimal::must_from_str("0.4"),
294 default_hourly_funding_rate_cap: FPDecimal::must_from_str("0.000625"),
295 default_hourly_interest_rate: FPDecimal::must_from_str("0.00000416666"),
296 max_derivative_order_side_count: 20u32,
297 inj_reward_staked_requirement_threshold: FPDecimal::must_from_str("25000000000000000000"),
298 trading_rewards_vesting_duration: 1209600i64,
299 liquidator_reward_share_rate: FPDecimal::must_from_str("0.05"),
300 binary_options_market_instant_listing_fee: Coin::new(10000000000000000000u128, denom),
301 atomic_market_order_access_level: AtomicMarketOrderAccessLevel::SmartContractsOnly,
302 spot_atomic_market_order_fee_multiplier: FPDecimal::must_from_str("2.0"),
303 derivative_atomic_market_order_fee_multiplier: FPDecimal::must_from_str("2.0"),
304 binary_options_atomic_market_order_fee_multiplier: FPDecimal::must_from_str("2.0"),
305 minimal_protocol_fee_rate: FPDecimal::must_from_str("0.00001"),
306 is_instant_derivative_market_launch_enabled: Some(true),
307 }),
308 };
309 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
310}
311
312fn default_spot_market_orderbook_response_handler() -> QuerierResult {
313 let response = QueryOrderbookResponse {
314 buys_price_level: vec![PriceLevel::new(9u128.into(), 10u128.into()), PriceLevel::new(8u128.into(), 10u128.into())],
315 sells_price_level: vec![
316 PriceLevel::new(11u128.into(), 10u128.into()),
317 PriceLevel::new(12u128.into(), 10u128.into()),
318 ],
319 };
320 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
321}
322
323fn default_derivative_market_orderbook_response_handler() -> QuerierResult {
324 let response = QueryOrderbookResponse {
325 buys_price_level: vec![PriceLevel::new(9u128.into(), 10u128.into()), PriceLevel::new(8u128.into(), 10u128.into())],
326 sells_price_level: vec![
327 PriceLevel::new(11u128.into(), 10u128.into()),
328 PriceLevel::new(12u128.into(), 10u128.into()),
329 ],
330 };
331 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
332}
333
334fn default_market_atomic_execution_fee_multiplier_response_handler() -> QuerierResult {
335 let response = QueryMarketAtomicExecutionFeeMultiplierResponse {
336 multiplier: FPDecimal::from_str("2.0").unwrap(),
337 };
338 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
339}
340
341pub trait HandlesSmartQuery {
342 fn handle(&self, contract_addr: &str, msg: &Binary) -> QuerierResult;
343}
344
345pub trait HandlesRawQuery {
346 fn handle(&self, contract_addr: &str, key: &Binary) -> QuerierResult;
347}
348
349pub trait HandlesContractInfo {
350 fn handle(&self, contract_addr: &str) -> QuerierResult;
351}
352
353pub trait HandlesCodeInfo {
354 fn handle(&self, code_id: u64) -> QuerierResult;
355}
356
357pub trait HandlesBankQuery {
358 fn handle(&self, query: &BankQuery) -> QuerierResult;
359}
360
361pub trait HandlesTraderSpotOrdersToCancelUpToAmountQuery {
362 fn handle(
363 &self,
364 market_id: MarketId,
365 subaccount_id: SubaccountId,
366 base_amount: FPDecimal,
367 quote_amount: FPDecimal,
368 strategy: CancellationStrategy,
369 reference_price: Option<FPDecimal>,
370 ) -> QuerierResult;
371}
372
373pub trait HandlesTraderDerivativeOrdersToCancelUpToAmountQuery {
374 fn handle(
375 &self,
376 market_id: MarketId,
377 subaccount_id: SubaccountId,
378 quote_amount: FPDecimal,
379 strategy: CancellationStrategy,
380 reference_price: Option<FPDecimal>,
381 ) -> QuerierResult;
382}
383
384pub trait HandlesMarketIdQuery {
385 fn handle(&self, market_id: MarketId) -> QuerierResult;
386}
387
388pub trait HandlesSubaccountIdQuery {
389 fn handle(&self, subaccount_id: SubaccountId) -> QuerierResult;
390}
391
392pub trait HandlesMarketAndSubaccountQuery {
393 fn handle(&self, market_id: MarketId, subaccount_id: SubaccountId) -> QuerierResult;
394}
395
396pub trait HandlesSubaccountAndDenomQuery {
397 fn handle(&self, subaccount_id: SubaccountId, denom: String) -> QuerierResult;
398}
399
400pub trait HandlesStakedAmountQuery {
401 fn handle(&self, delegator_address: Addr, max_delegations: u16) -> QuerierResult;
402}
403
404pub trait HandlesOracleVolatilityQuery {
405 fn handle(
406 &self,
407 base_info: Option<OracleInfo>,
408 quote_info: Option<OracleInfo>,
409 oracle_history_options: Option<OracleHistoryOptions>,
410 ) -> QuerierResult;
411}
412
413pub trait HandlesOraclePriceQuery {
414 fn handle(&self, oracle_type: OracleType, base: String, quote: String) -> QuerierResult;
415}
416
417pub trait HandlesPythPriceQuery {
418 fn handle(&self, price_id: String) -> QuerierResult;
419}
420
421pub trait HandlesMarketVolatilityQuery {
422 fn handle(&self, market_id: MarketId, trade_history_options: TradeHistoryOptions) -> QuerierResult;
423}
424
425pub trait HandlesDenomSupplyQuery {
426 fn handle(&self, denom: String) -> QuerierResult;
427}
428
429pub trait HandlesFeeQuery {
430 fn handle(&self) -> QuerierResult;
431}
432
433pub trait HandlesBankBalanceQuery {
434 fn handle(&self, address: String, denom: String) -> QuerierResult;
435}
436
437pub trait HandlesBankAllBalancesQuery {
438 fn handle(&self, address: String) -> QuerierResult;
439}
440
441pub trait HandlesByAddressQuery {
442 fn handle(&self, address: String) -> QuerierResult;
443}
444
445pub trait HandlesMarketVolumeQuery {
446 fn handle(&self, market_id: MarketId) -> QuerierResult;
447}
448
449pub trait HandlesAccountVolumeQuery {
450 fn handle(&self, account: String) -> QuerierResult;
451}
452
453pub trait HandlesDenomDecimalQuery {
454 fn handle(&self, denom: String) -> QuerierResult;
455}
456
457pub trait HandlesDenomDecimalsQuery {
458 fn handle(&self, denoms: Vec<String>) -> QuerierResult;
459}
460
461pub trait HandlesPriceLevelsQuery {
462 fn handle(&self, market_id: MarketId, order_side: OrderSide) -> QuerierResult;
463}
464
465pub trait HandlesDerivativePriceLevelsQuery {
466 fn handle(&self, market_id: MarketId) -> QuerierResult;
467}
468
469pub trait HandlesExchangeParamsQuery {
470 fn handle(&self) -> QuerierResult;
471}
472
473pub struct WasmMockQuerier {
474 pub smart_query_handler: Option<Box<dyn HandlesSmartQuery>>,
475 pub raw_query_handler: Option<Box<dyn HandlesRawQuery>>,
476 pub contract_info_handler: Option<Box<dyn HandlesContractInfo>>,
477 pub code_info_handler: Option<Box<dyn HandlesCodeInfo>>,
478 pub subaccount_deposit_response_handler: Option<Box<dyn HandlesSubaccountAndDenomQuery>>,
479 pub exchange_params_response_handler: Option<Box<dyn HandlesExchangeParamsQuery>>,
480 pub spot_market_response_handler: Option<Box<dyn HandlesMarketIdQuery>>,
481 pub trader_spot_orders_response_handler: Option<Box<dyn HandlesMarketAndSubaccountQuery>>,
482 pub trader_spot_orders_to_cancel_up_to_amount_response_handler: Option<Box<dyn HandlesTraderSpotOrdersToCancelUpToAmountQuery>>,
483 pub trader_derivative_orders_to_cancel_up_to_amount_response_handler: Option<Box<dyn HandlesTraderDerivativeOrdersToCancelUpToAmountQuery>>,
484 pub derivative_market_response_handler: Option<Box<dyn HandlesMarketIdQuery>>,
485 pub subaccount_positions_response_handler: Option<Box<dyn HandlesSubaccountIdQuery>>,
486 pub subaccount_position_in_market_response_handler: Option<Box<dyn HandlesMarketAndSubaccountQuery>>,
487 pub subaccount_effective_position_in_market_response_handler: Option<Box<dyn HandlesMarketAndSubaccountQuery>>,
488 pub trader_derivative_orders_response_handler: Option<Box<dyn HandlesMarketAndSubaccountQuery>>,
489 pub trader_transient_spot_orders_response_handler: Option<Box<dyn HandlesMarketAndSubaccountQuery>>,
490 pub trader_transient_derivative_orders_response_handler: Option<Box<dyn HandlesMarketAndSubaccountQuery>>,
491 pub perpetual_market_info_response_handler: Option<Box<dyn HandlesMarketIdQuery>>,
492 pub perpetual_market_funding_response_handler: Option<Box<dyn HandlesMarketIdQuery>>,
493 pub market_volatility_response_handler: Option<Box<dyn HandlesMarketVolatilityQuery>>,
494 pub spot_market_mid_price_and_tob_response_handler: Option<Box<dyn HandlesMarketIdQuery>>,
495 pub derivative_market_mid_price_and_tob_response_handler: Option<Box<dyn HandlesMarketIdQuery>>,
496 pub aggregate_market_volume_handler: Option<Box<dyn HandlesMarketVolumeQuery>>,
497 pub aggregate_account_volume_handler: Option<Box<dyn HandlesAccountVolumeQuery>>,
498 pub denom_decimal_handler: Option<Box<dyn HandlesDenomDecimalQuery>>,
499 pub denom_decimals_handler: Option<Box<dyn HandlesDenomDecimalsQuery>>,
500 pub staked_amount_handler: Option<Box<dyn HandlesStakedAmountQuery>>,
501 pub oracle_volatility_response_handler: Option<Box<dyn HandlesOracleVolatilityQuery>>,
502 pub oracle_price_response_handler: Option<Box<dyn HandlesOraclePriceQuery>>,
503 pub pyth_price_response_handler: Option<Box<dyn HandlesPythPriceQuery>>,
504 pub token_factory_denom_total_supply_handler: Option<Box<dyn HandlesDenomSupplyQuery>>,
505 pub token_factory_denom_creation_fee_handler: Option<Box<dyn HandlesFeeQuery>>,
506 pub balance_query_handler: Option<Box<dyn HandlesBankBalanceQuery>>,
507 pub all_balances_query_handler: Option<Box<dyn HandlesBankAllBalancesQuery>>,
508 pub total_supply_handler: Option<Box<dyn HandlesDenomSupplyQuery>>,
509 pub registered_contract_info_query_handler: Option<Box<dyn HandlesByAddressQuery>>,
510 pub spot_market_orderbook_response_handler: Option<Box<dyn HandlesPriceLevelsQuery>>,
511 pub derivative_market_orderbook_response_handler: Option<Box<dyn HandlesDerivativePriceLevelsQuery>>,
512 pub market_atomic_execution_fee_multiplier_response_handler: Option<Box<dyn HandlesMarketIdQuery>>,
513}
514
515impl Querier for WasmMockQuerier {
516 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
517 let request: QueryRequest<InjectiveQueryWrapper> = match from_json(bin_request) {
518 Ok(v) => v,
519 Err(e) => {
520 return SystemResult::Err(SystemError::InvalidRequest {
521 error: format!("Parsing query request: {e:?}"),
522 request: bin_request.into(),
523 });
524 }
525 };
526
527 self.handle_query(&request)
528 }
529}
530
531impl WasmMockQuerier {
532 pub fn handle_query(&self, request: &QueryRequest<InjectiveQueryWrapper>) -> QuerierResult {
533 match &request {
534 QueryRequest::Wasm(query) => match query {
535 WasmQuery::Smart { contract_addr, msg } => match &self.smart_query_handler {
536 Some(handler) => handler.handle(contract_addr, msg),
537 None => panic!("Unknown smart query"),
538 },
539 WasmQuery::Raw { contract_addr, key } => match &self.raw_query_handler {
540 Some(handler) => handler.handle(contract_addr, key),
541 None => panic!("Unknown raw query"),
542 },
543 WasmQuery::CodeInfo { code_id } => match &self.code_info_handler {
544 Some(handler) => handler.handle(*code_id),
545 None => panic!("Unknown code info query"),
546 },
547 WasmQuery::ContractInfo { contract_addr } => match &self.contract_info_handler {
548 Some(handler) => handler.handle(contract_addr),
549 None => panic!("Unknown contract info query"),
550 },
551 _ => panic!("unsupported"),
552 },
553 QueryRequest::Bank(query) => match query {
554 BankQuery::Balance { address, denom } => match &self.balance_query_handler {
555 Some(handler) => handler.handle(address.to_string(), denom.to_string()),
556 None => default_balance_bank_query_handler(denom),
557 },
558 #[allow(deprecated)]
559 BankQuery::AllBalances { address } => match &self.all_balances_query_handler {
560 Some(handler) => handler.handle(address.to_string()),
561 None => default_all_balances_bank_query_handler(),
562 },
563 BankQuery::Supply { denom } => match &self.total_supply_handler {
564 Some(handler) => handler.handle(denom.to_string()),
565 None => default_bank_total_supply_handler(),
566 },
567 _ => panic!("unsupported"),
568 },
569 QueryRequest::Custom(query) => match query.query_data.clone() {
570 InjectiveQuery::SubaccountDeposit { subaccount_id, denom } => match &self.subaccount_deposit_response_handler {
571 Some(handler) => handler.handle(subaccount_id, denom),
572 None => default_subaccount_deposit_response_handler(),
573 },
574 InjectiveQuery::ExchangeParams {} => match &self.exchange_params_response_handler {
575 Some(handler) => handler.handle(),
576 None => default_exchange_params_response_handler(),
577 },
578 InjectiveQuery::SpotMarket { market_id } => match &self.spot_market_response_handler {
579 Some(handler) => handler.handle(market_id),
580 None => default_spot_market_response_handler(market_id),
581 },
582 InjectiveQuery::TraderSpotOrders { market_id, subaccount_id } => match &self.trader_spot_orders_response_handler {
583 Some(handler) => handler.handle(market_id, subaccount_id),
584 None => default_trader_spot_orders_response_handler(),
585 },
586 InjectiveQuery::TraderSpotOrdersToCancelUpToAmount {
587 market_id,
588 subaccount_id,
589 base_amount,
590 quote_amount,
591 strategy,
592 reference_price,
593 } => match &self.trader_spot_orders_to_cancel_up_to_amount_response_handler {
594 Some(handler) => handler.handle(market_id, subaccount_id, base_amount, quote_amount, strategy, reference_price),
595 None => default_trader_spot_orders_to_cancel_up_to_amount_response_handler(),
596 },
597 InjectiveQuery::TraderDerivativeOrdersToCancelUpToAmount {
598 market_id,
599 subaccount_id,
600 quote_amount,
601 strategy,
602 reference_price,
603 } => match &self.trader_derivative_orders_to_cancel_up_to_amount_response_handler {
604 Some(handler) => handler.handle(market_id, subaccount_id, quote_amount, strategy, reference_price),
605 None => default_trader_derivative_orders_to_cancel_up_to_amount_response_handler(),
606 },
607 InjectiveQuery::DerivativeMarket { market_id } => match &self.derivative_market_response_handler {
608 Some(handler) => handler.handle(market_id),
609 None => default_derivative_market_response_handler(market_id),
610 },
611 InjectiveQuery::SubaccountPositions { subaccount_id } => match &self.subaccount_positions_response_handler {
612 Some(handler) => handler.handle(subaccount_id),
613 None => default_subaccount_positions_response_handler(),
614 },
615 InjectiveQuery::SubaccountPositionInMarket { market_id, subaccount_id } => {
616 match &self.subaccount_position_in_market_response_handler {
617 Some(handler) => handler.handle(market_id, subaccount_id),
618 None => default_subaccount_position_in_market_response_handler(),
619 }
620 }
621 InjectiveQuery::SubaccountEffectivePositionInMarket { market_id, subaccount_id } => {
622 match &self.subaccount_effective_position_in_market_response_handler {
623 Some(handler) => handler.handle(market_id, subaccount_id),
624 None => default_subaccount_effective_position_in_market_response_handler(),
625 }
626 }
627 InjectiveQuery::TraderDerivativeOrders { market_id, subaccount_id } => match &self.trader_derivative_orders_response_handler {
628 Some(handler) => handler.handle(market_id, subaccount_id),
629 None => default_trader_derivative_orders_response_handler(),
630 },
631 InjectiveQuery::TraderTransientSpotOrders { market_id, subaccount_id } => match &self.trader_transient_spot_orders_response_handler {
632 Some(handler) => handler.handle(market_id, subaccount_id),
633 None => default_trader_transient_spot_orders_response_handler(),
634 },
635 InjectiveQuery::TraderTransientDerivativeOrders { market_id, subaccount_id } => {
636 match &self.trader_transient_derivative_orders_response_handler {
637 Some(handler) => handler.handle(market_id, subaccount_id),
638 None => default_trader_transient_derivative_orders_response_handler(),
639 }
640 }
641 InjectiveQuery::PerpetualMarketInfo { market_id } => match &self.perpetual_market_info_response_handler {
642 Some(handler) => handler.handle(market_id),
643 None => default_perpetual_market_info_response_handler(),
644 },
645 InjectiveQuery::PerpetualMarketFunding { market_id } => match &self.perpetual_market_funding_response_handler {
646 Some(handler) => handler.handle(market_id),
647 None => default_perpetual_market_funding_response_handler(),
648 },
649 InjectiveQuery::MarketVolatility {
650 market_id,
651 trade_history_options,
652 } => match &self.market_volatility_response_handler {
653 Some(handler) => handler.handle(market_id, trade_history_options),
654 None => default_market_volatility_response_handler(),
655 },
656 InjectiveQuery::SpotMarketMidPriceAndTob { market_id } => match &self.spot_market_mid_price_and_tob_response_handler {
657 Some(handler) => handler.handle(market_id),
658 None => default_spot_market_mid_price_and_tob_response_handler(),
659 },
660 InjectiveQuery::DerivativeMarketMidPriceAndTob { market_id } => match &self.derivative_market_mid_price_and_tob_response_handler {
661 Some(handler) => handler.handle(market_id),
662 None => default_derivative_market_mid_price_and_tob_response_handler(),
663 },
664 InjectiveQuery::AggregateMarketVolume { market_id } => match &self.aggregate_market_volume_handler {
665 Some(handler) => handler.handle(market_id),
666 None => default_aggregate_market_volume_handler(),
667 },
668 InjectiveQuery::AggregateAccountVolume { account } => match &self.aggregate_account_volume_handler {
669 Some(handler) => handler.handle(account),
670 None => default_aggregate_account_volume_handler(),
671 },
672 InjectiveQuery::StakedAmount {
673 delegator_address,
674 max_delegations,
675 } => match &self.staked_amount_handler {
676 Some(handler) => handler.handle(delegator_address, max_delegations),
677 None => default_oracle_volatility_response_handler(),
678 },
679 InjectiveQuery::OracleVolatility {
680 base_info,
681 quote_info,
682 oracle_history_options,
683 } => match &self.oracle_volatility_response_handler {
684 Some(handler) => handler.handle(base_info, quote_info, oracle_history_options),
685 None => default_oracle_volatility_response_handler(),
686 },
687 InjectiveQuery::OraclePrice {
688 oracle_type, base, quote, ..
689 } => match &self.oracle_price_response_handler {
690 Some(handler) => handler.handle(oracle_type, base, quote),
691 None => default_oracle_volatility_response_handler(),
692 },
693 InjectiveQuery::PythPrice { price_id } => match &self.pyth_price_response_handler {
694 Some(handler) => handler.handle(price_id),
695 None => default_pyth_price_response_handler(),
696 },
697 InjectiveQuery::TokenFactoryDenomTotalSupply { denom } => match &self.token_factory_denom_total_supply_handler {
698 Some(handler) => handler.handle(denom),
699 None => default_token_factory_denom_total_supply_handler(),
700 },
701 InjectiveQuery::TokenFactoryDenomCreationFee {} => match &self.token_factory_denom_creation_fee_handler {
702 Some(handler) => handler.handle(),
703 None => default_token_factory_denom_creation_fee_handler(),
704 },
705 InjectiveQuery::WasmxRegisteredContractInfo { contract_address } => match &self.registered_contract_info_query_handler {
706 Some(handler) => handler.handle(contract_address),
707 None => default_contract_registration_info_response_handler(),
708 },
709 InjectiveQuery::SpotOrderbook { order_side, market_id, .. } => match &self.spot_market_orderbook_response_handler {
710 Some(handler) => handler.handle(market_id, order_side),
711 None => default_spot_market_orderbook_response_handler(),
712 },
713 InjectiveQuery::DerivativeOrderbook { market_id, .. } => match &self.derivative_market_orderbook_response_handler {
714 Some(handler) => handler.handle(market_id),
715 None => default_derivative_market_orderbook_response_handler(),
716 },
717 InjectiveQuery::MarketAtomicExecutionFeeMultiplier { market_id } => {
718 match &self.market_atomic_execution_fee_multiplier_response_handler {
719 Some(handler) => handler.handle(market_id),
720 None => default_market_atomic_execution_fee_multiplier_response_handler(),
721 }
722 }
723 },
724 _ => panic!("Unknown query"),
725 }
726 }
727}
728
729impl Default for WasmMockQuerier {
730 fn default() -> Self {
731 Self::new()
732 }
733}
734
735impl WasmMockQuerier {
736 pub fn new() -> Self {
737 WasmMockQuerier {
738 smart_query_handler: None,
739 raw_query_handler: None,
740 code_info_handler: None,
741 contract_info_handler: None,
742 subaccount_deposit_response_handler: None,
743 exchange_params_response_handler: None,
744 spot_market_response_handler: None,
745 trader_spot_orders_response_handler: None,
746 trader_spot_orders_to_cancel_up_to_amount_response_handler: None,
747 trader_derivative_orders_to_cancel_up_to_amount_response_handler: None,
748 derivative_market_response_handler: None,
749 subaccount_positions_response_handler: None,
750 subaccount_position_in_market_response_handler: None,
751 subaccount_effective_position_in_market_response_handler: None,
752 trader_derivative_orders_response_handler: None,
753 trader_transient_spot_orders_response_handler: None,
754 trader_transient_derivative_orders_response_handler: None,
755 perpetual_market_info_response_handler: None,
756 perpetual_market_funding_response_handler: None,
757 market_volatility_response_handler: None,
758 spot_market_mid_price_and_tob_response_handler: None,
759 derivative_market_mid_price_and_tob_response_handler: None,
760 aggregate_account_volume_handler: None,
761 denom_decimal_handler: None,
762 aggregate_market_volume_handler: None,
763 staked_amount_handler: None,
764 oracle_volatility_response_handler: None,
765 oracle_price_response_handler: None,
766 pyth_price_response_handler: None,
767 token_factory_denom_total_supply_handler: None,
768 token_factory_denom_creation_fee_handler: None,
769 balance_query_handler: None,
770 all_balances_query_handler: None,
771 registered_contract_info_query_handler: None,
772 denom_decimals_handler: None,
773 spot_market_orderbook_response_handler: None,
774 derivative_market_orderbook_response_handler: None,
775 market_atomic_execution_fee_multiplier_response_handler: None,
776 total_supply_handler: None,
777 }
778 }
779}
780
781pub struct TestCoin {
782 pub amount: FPDecimal,
783 pub denom: String,
784}
785
786impl TestCoin {
787 pub fn new(amount: FPDecimal, denom: String) -> TestCoin {
788 TestCoin { amount, denom }
789 }
790}
791
792pub struct TestDeposit {
793 pub deposit: Deposit,
794 pub denom: String,
795}
796
797impl TestDeposit {
798 pub fn new(deposit: Deposit, denom: String) -> TestDeposit {
799 TestDeposit { deposit, denom }
800 }
801}
802
803pub mod handlers {
804 use cosmwasm_std::{
805 to_json_binary, Addr, AllBalanceResponse, BalanceResponse, Binary, Checksum, CodeInfoResponse, Coin, ContractInfoResponse, ContractResult,
806 QuerierResult, StdResult, SupplyResponse, SystemError, SystemResult, Uint128,
807 };
808 use std::collections::HashMap;
809
810 use injective_math::FPDecimal;
811
812 use crate::exchange::response::QueryOrderbookResponse;
813 use crate::exchange_mock_querier::{HandlesByAddressQuery, HandlesDenomSupplyQuery, HandlesFeeQuery};
814 use crate::oracle::{response::OraclePriceResponse, types::PricePairState};
815 use crate::tokenfactory::response::{TokenFactoryCreateDenomFeeResponse, TokenFactoryDenomSupplyResponse};
816 use crate::wasmx::{response::QueryContractRegistrationInfoResponse, types::RegisteredContract};
817 use crate::{
818 exchange_mock_querier::TestCoin, CancellationStrategy, Deposit, DerivativeMarket, DerivativeMarketResponse, EffectivePosition,
819 FullDerivativeMarket, FullDerivativeMarketPerpetualInfo, HandlesMarketAndSubaccountQuery, HandlesMarketIdQuery, HandlesOracleVolatilityQuery,
820 HandlesPriceLevelsQuery, HandlesRawQuery, HandlesSmartQuery, HandlesSubaccountAndDenomQuery, HandlesTraderSpotOrdersToCancelUpToAmountQuery,
821 MarketId, MetadataStatistics, OracleVolatilityResponse, OrderSide, Position, PriceLevel, QueryMarketAtomicExecutionFeeMultiplierResponse,
822 SpotMarket, SpotMarketResponse, SubaccountDepositResponse, SubaccountEffectivePositionInMarketResponse, SubaccountId,
823 SubaccountPositionInMarketResponse, TradeRecord, TraderDerivativeOrdersResponse, TraderSpotOrdersResponse, TrimmedDerivativeLimitOrder,
824 TrimmedSpotLimitOrder,
825 };
826 use crate::{
827 HandlesBankAllBalancesQuery, HandlesBankBalanceQuery, HandlesCodeInfo, HandlesContractInfo,
828 HandlesTraderDerivativeOrdersToCancelUpToAmountQuery, MarketMidPriceAndTOBResponse, OracleType,
829 };
830
831 use super::{HandlesOraclePriceQuery, TestDeposit};
832
833 pub fn create_subaccount_deposit_handler(coins: Vec<TestCoin>) -> Option<Box<dyn HandlesSubaccountAndDenomQuery>> {
834 struct Temp {
835 coins: Vec<TestCoin>,
836 }
837 impl HandlesSubaccountAndDenomQuery for Temp {
838 fn handle(&self, _: SubaccountId, denom: String) -> QuerierResult {
839 let iter = IntoIterator::into_iter(&self.coins);
840 let matching_coins: Vec<&TestCoin> = iter.filter(|c| c.denom == denom).collect();
841 if matching_coins.is_empty() || matching_coins.len() > 1 {
842 panic!("Expected to find one coin with denom '{}', but found {}", denom, matching_coins.len())
843 }
844
845 let response = SubaccountDepositResponse {
846 deposits: Deposit {
847 available_balance: matching_coins.first().unwrap().amount,
848 total_balance: matching_coins.first().unwrap().amount,
849 },
850 };
851 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
852 }
853 }
854 Some(Box::new(Temp { coins }))
855 }
856
857 pub fn create_subaccount_deposit_complex_handler(deposits: Vec<TestDeposit>) -> Option<Box<dyn HandlesSubaccountAndDenomQuery>> {
858 struct Temp {
859 deposits: Vec<TestDeposit>,
860 }
861 impl HandlesSubaccountAndDenomQuery for Temp {
862 fn handle(&self, _: SubaccountId, denom: String) -> QuerierResult {
863 let iter = IntoIterator::into_iter(&self.deposits);
864 let matching_deposits: Vec<&TestDeposit> = iter.filter(|c| c.denom == denom).collect();
865 if matching_deposits.is_empty() || matching_deposits.len() > 1 {
866 panic!(
867 "Expected to find one deposit with denom '{}', but found {}",
868 denom,
869 matching_deposits.len()
870 )
871 }
872
873 let response = SubaccountDepositResponse {
874 deposits: matching_deposits.first().unwrap().deposit.to_owned(),
875 };
876 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
877 }
878 }
879 Some(Box::new(Temp { deposits }))
880 }
881
882 pub fn create_subaccount_deposit_err_returning_handler() -> Option<Box<dyn HandlesSubaccountAndDenomQuery>> {
883 struct A();
884 impl HandlesSubaccountAndDenomQuery for A {
885 fn handle(&self, _: SubaccountId, _: String) -> QuerierResult {
886 SystemResult::Err(SystemError::Unknown {})
887 }
888 }
889 Some(Box::new(A()))
890 }
891
892 pub fn create_spot_market_handler(market: Option<SpotMarket>) -> Option<Box<dyn HandlesMarketIdQuery>> {
893 struct Temp {
894 market: Option<SpotMarket>,
895 }
896 impl HandlesMarketIdQuery for Temp {
897 fn handle(&self, _: MarketId) -> QuerierResult {
898 let response = SpotMarketResponse {
899 market: self.market.to_owned(),
900 };
901 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
902 }
903 }
904 Some(Box::new(Temp { market }))
905 }
906
907 pub fn create_orderbook_response_handler(orderbooks: HashMap<MarketId, Vec<PriceLevel>>) -> Option<Box<dyn HandlesPriceLevelsQuery>> {
908 struct Temp {
909 orderbooks: HashMap<MarketId, Vec<PriceLevel>>,
910 }
911 impl HandlesPriceLevelsQuery for Temp {
912 fn handle(&self, market_id: MarketId, order_side: OrderSide) -> QuerierResult {
913 let price_levels_opt = self.orderbooks.get(&market_id);
914 if price_levels_opt.is_none() {
915 return SystemResult::Err(SystemError::Unknown {});
916 }
917 let price_levels = price_levels_opt.unwrap().clone();
918 let response = QueryOrderbookResponse {
919 buys_price_level: if order_side != OrderSide::Sell { price_levels.clone() } else { vec![] },
920 sells_price_level: if order_side != OrderSide::Buy { price_levels } else { vec![] },
921 };
922 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
923 }
924 }
925 Some(Box::new(Temp { orderbooks }))
926 }
927
928 pub fn create_spot_multi_market_handler(markets: HashMap<MarketId, SpotMarket>) -> Option<Box<dyn HandlesMarketIdQuery>> {
929 struct Temp {
930 markets: HashMap<MarketId, SpotMarket>,
931 }
932
933 impl HandlesMarketIdQuery for Temp {
934 fn handle(&self, market_id: MarketId) -> QuerierResult {
935 let response = SpotMarketResponse {
936 market: self.markets.get(&market_id).cloned(),
937 };
938 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
939 }
940 }
941
942 Some(Box::new(Temp { markets }))
943 }
944
945 pub type SpotUpToAmountConsumingFunction = fn(MarketId, SubaccountId, FPDecimal, FPDecimal, CancellationStrategy, Option<FPDecimal>);
946
947 pub fn create_spot_orders_up_to_amount_handler(
948 orders: Option<Vec<TrimmedSpotLimitOrder>>,
949 assertion: Option<SpotUpToAmountConsumingFunction>,
950 ) -> Option<Box<dyn HandlesTraderSpotOrdersToCancelUpToAmountQuery>> {
951 struct Temp {
952 orders: Option<Vec<TrimmedSpotLimitOrder>>,
953 assertion: Option<SpotUpToAmountConsumingFunction>,
954 }
955 impl HandlesTraderSpotOrdersToCancelUpToAmountQuery for Temp {
956 fn handle(
957 &self,
958 market_id: MarketId,
959 subaccount_id: SubaccountId,
960 base_amount: FPDecimal,
961 quote_amount: FPDecimal,
962 strategy: CancellationStrategy,
963 reference_price: Option<FPDecimal>,
964 ) -> QuerierResult {
965 if self.assertion.is_some() {
966 self.assertion.as_ref().unwrap()(market_id, subaccount_id, base_amount, quote_amount, strategy, reference_price)
967 }
968 let response = TraderSpotOrdersResponse {
969 orders: self.orders.to_owned(),
970 };
971 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
972 }
973 }
974 Some(Box::new(Temp { orders, assertion }))
975 }
976
977 pub type DerivativeUpToAmountConsumingFunction = fn(MarketId, SubaccountId, FPDecimal, CancellationStrategy, Option<FPDecimal>);
978
979 pub fn create_derivative_orders_up_to_amount_handler(
980 orders: Option<Vec<TrimmedDerivativeLimitOrder>>,
981 assertion: Option<DerivativeUpToAmountConsumingFunction>,
982 ) -> Option<Box<dyn HandlesTraderDerivativeOrdersToCancelUpToAmountQuery>> {
983 struct Temp {
984 orders: Option<Vec<TrimmedDerivativeLimitOrder>>,
985 assertion: Option<DerivativeUpToAmountConsumingFunction>,
986 }
987 impl HandlesTraderDerivativeOrdersToCancelUpToAmountQuery for Temp {
988 fn handle(
989 &self,
990 market_id: MarketId,
991 subaccount_id: SubaccountId,
992 quote_amount: FPDecimal,
993 strategy: CancellationStrategy,
994 reference_price: Option<FPDecimal>,
995 ) -> QuerierResult {
996 if self.assertion.is_some() {
997 self.assertion.as_ref().unwrap()(market_id, subaccount_id, quote_amount, strategy, reference_price)
998 }
999 let response = TraderDerivativeOrdersResponse {
1000 orders: self.orders.to_owned(),
1001 };
1002 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1003 }
1004 }
1005 Some(Box::new(Temp { orders, assertion }))
1006 }
1007
1008 pub fn create_derivative_market_handler(
1009 market: Option<DerivativeMarket>,
1010 info: Option<FullDerivativeMarketPerpetualInfo>,
1011 mark_price: FPDecimal,
1012 ) -> Option<Box<dyn HandlesMarketIdQuery>> {
1013 struct Temp {
1014 market: Option<DerivativeMarket>,
1015 info: Option<FullDerivativeMarketPerpetualInfo>,
1016 mark_price: FPDecimal,
1017 }
1018 impl HandlesMarketIdQuery for Temp {
1019 fn handle(&self, _: MarketId) -> QuerierResult {
1020 let response = DerivativeMarketResponse {
1021 market: Some(FullDerivativeMarket {
1022 market: self.market.to_owned(),
1023 info: self.info.to_owned(),
1024 mark_price: self.mark_price.to_owned(),
1025 }),
1026 };
1027 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1028 }
1029 }
1030 Some(Box::new(Temp { market, info, mark_price }))
1031 }
1032
1033 pub fn create_trader_spot_orders_handler(orders: Option<Vec<TrimmedSpotLimitOrder>>) -> Option<Box<dyn HandlesMarketAndSubaccountQuery>> {
1034 struct Temp {
1035 orders: Option<Vec<TrimmedSpotLimitOrder>>,
1036 }
1037 impl HandlesMarketAndSubaccountQuery for Temp {
1038 fn handle(&self, _: MarketId, _: SubaccountId) -> QuerierResult {
1039 let response = TraderSpotOrdersResponse {
1040 orders: self.orders.to_owned(),
1041 };
1042 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1043 }
1044 }
1045 Some(Box::new(Temp { orders }))
1046 }
1047
1048 pub fn create_trader_derivative_orders_handler(
1049 orders: Option<Vec<TrimmedDerivativeLimitOrder>>,
1050 ) -> Option<Box<dyn HandlesMarketAndSubaccountQuery>> {
1051 struct Temp {
1052 orders: Option<Vec<TrimmedDerivativeLimitOrder>>,
1053 }
1054 impl HandlesMarketAndSubaccountQuery for Temp {
1055 fn handle(&self, _: MarketId, _: SubaccountId) -> QuerierResult {
1056 let response = TraderDerivativeOrdersResponse {
1057 orders: self.orders.to_owned(),
1058 };
1059 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1060 }
1061 }
1062 Some(Box::new(Temp { orders }))
1063 }
1064
1065 pub fn create_subaccount_effective_position_in_market_handler(
1066 position: Option<EffectivePosition>,
1067 ) -> Option<Box<dyn HandlesMarketAndSubaccountQuery>> {
1068 struct Temp {
1069 position: Option<EffectivePosition>,
1070 }
1071
1072 impl HandlesMarketAndSubaccountQuery for Temp {
1073 fn handle(&self, _: MarketId, _: SubaccountId) -> QuerierResult {
1074 let response = SubaccountEffectivePositionInMarketResponse {
1075 state: self.position.to_owned(),
1076 };
1077 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1078 }
1079 }
1080
1081 Some(Box::new(Temp { position }))
1082 }
1083
1084 pub fn create_subaccount_position_in_market_handler(position: Option<Position>) -> Option<Box<dyn HandlesMarketAndSubaccountQuery>> {
1085 struct Temp {
1086 position: Option<Position>,
1087 }
1088
1089 impl HandlesMarketAndSubaccountQuery for Temp {
1090 fn handle(&self, _: MarketId, _: SubaccountId) -> QuerierResult {
1091 let response = SubaccountPositionInMarketResponse {
1092 state: self.position.to_owned(),
1093 };
1094 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1095 }
1096 }
1097
1098 Some(Box::new(Temp { position }))
1099 }
1100
1101 pub fn create_market_mid_price_and_tob_handler(
1102 mid_price: Option<FPDecimal>,
1103 best_buy_price: Option<FPDecimal>,
1104 best_sell_price: Option<FPDecimal>,
1105 ) -> Option<Box<dyn HandlesMarketIdQuery>> {
1106 struct Temp {
1107 mid_price: Option<FPDecimal>,
1108 best_buy_price: Option<FPDecimal>,
1109 best_sell_price: Option<FPDecimal>,
1110 }
1111 impl HandlesMarketIdQuery for Temp {
1112 fn handle(&self, _: MarketId) -> QuerierResult {
1113 let response = MarketMidPriceAndTOBResponse {
1114 mid_price: self.mid_price.to_owned(),
1115 best_buy_price: self.best_buy_price.to_owned(),
1116 best_sell_price: self.best_sell_price.to_owned(),
1117 };
1118 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1119 }
1120 }
1121 Some(Box::new(Temp {
1122 mid_price,
1123 best_buy_price,
1124 best_sell_price,
1125 }))
1126 }
1127
1128 pub fn create_oracle_volatility_handler(
1129 volatility: Option<FPDecimal>,
1130 history_metadata: Option<MetadataStatistics>,
1131 raw_history: Option<Vec<TradeRecord>>,
1132 ) -> Option<Box<dyn HandlesOracleVolatilityQuery>> {
1133 struct Temp {
1134 volatility: Option<FPDecimal>,
1135 history_metadata: Option<MetadataStatistics>,
1136 raw_history: Option<Vec<TradeRecord>>,
1137 }
1138 impl HandlesOracleVolatilityQuery for Temp {
1139 fn handle(
1140 &self,
1141 _: Option<crate::OracleInfo>,
1142 _: Option<crate::OracleInfo>,
1143 _: Option<crate::oracle::types::OracleHistoryOptions>,
1144 ) -> QuerierResult {
1145 let response = OracleVolatilityResponse {
1146 volatility: self.volatility.to_owned(),
1147 history_metadata: self.history_metadata.to_owned(),
1148 raw_history: self.raw_history.to_owned(),
1149 };
1150 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1151 }
1152 }
1153 Some(Box::new(Temp {
1154 volatility,
1155 history_metadata,
1156 raw_history,
1157 }))
1158 }
1159
1160 pub fn create_oracle_query_handler(
1161 pair_price: FPDecimal,
1162 base_price: FPDecimal,
1163 quote_price: FPDecimal,
1164 base_cumulative_price: FPDecimal,
1165 quote_cumulative_price: FPDecimal,
1166 base_timestamp: i64,
1167 quote_timestamp: i64,
1168 ) -> Option<Box<dyn HandlesOraclePriceQuery>> {
1169 struct Temp {
1170 pair_price: FPDecimal,
1171 base_price: FPDecimal,
1172 quote_price: FPDecimal,
1173 base_cumulative_price: FPDecimal,
1174 quote_cumulative_price: FPDecimal,
1175 base_timestamp: i64,
1176 quote_timestamp: i64,
1177 }
1178 impl HandlesOraclePriceQuery for Temp {
1179 fn handle(&self, _: OracleType, _: String, _: String) -> QuerierResult {
1180 let response = OraclePriceResponse {
1181 price_pair_state: Some(PricePairState {
1182 pair_price: self.pair_price.to_owned(),
1183 base_price: self.base_price.to_owned(),
1184 quote_price: self.quote_price.to_owned(),
1185 base_cumulative_price: self.base_cumulative_price.to_owned(),
1186 quote_cumulative_price: self.quote_cumulative_price.to_owned(),
1187 base_timestamp: self.base_timestamp.to_owned(),
1188 quote_timestamp: self.quote_timestamp.to_owned(),
1189 }),
1190 };
1191 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1192 }
1193 }
1194 Some(Box::new(Temp {
1195 pair_price,
1196 base_price,
1197 quote_price,
1198 base_cumulative_price,
1199 quote_cumulative_price,
1200 base_timestamp,
1201 quote_timestamp,
1202 }))
1203 }
1204
1205 pub fn create_bank_supply_handler(supply: Uint128) -> Option<Box<dyn HandlesDenomSupplyQuery>> {
1206 struct Temp {
1207 supply: Uint128,
1208 }
1209 impl HandlesDenomSupplyQuery for Temp {
1210 fn handle(&self, denom: String) -> QuerierResult {
1211 let response = SupplyResponse::new(Coin { denom, amount: self.supply });
1212 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1213 }
1214 }
1215 Some(Box::new(Temp { supply }))
1216 }
1217
1218 pub fn create_denom_supply_handler(supply: Uint128) -> Option<Box<dyn HandlesDenomSupplyQuery>> {
1219 struct Temp {
1220 supply: Uint128,
1221 }
1222 impl HandlesDenomSupplyQuery for Temp {
1223 fn handle(&self, _denom: String) -> QuerierResult {
1224 let response = TokenFactoryDenomSupplyResponse { total_supply: self.supply };
1225 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1226 }
1227 }
1228 Some(Box::new(Temp { supply }))
1229 }
1230
1231 pub fn create_denom_creation_fee_handler(fee: Vec<Coin>) -> Option<Box<dyn HandlesFeeQuery>> {
1232 struct Temp {
1233 fee: Vec<Coin>,
1234 }
1235 impl HandlesFeeQuery for Temp {
1236 fn handle(&self) -> QuerierResult {
1237 let response = TokenFactoryCreateDenomFeeResponse { fee: self.fee.to_owned() };
1238 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1239 }
1240 }
1241 Some(Box::new(Temp { fee }))
1242 }
1243
1244 pub fn create_registered_contract_info_query_handler(contract: Option<RegisteredContract>) -> Option<Box<dyn HandlesByAddressQuery>> {
1245 struct Temp {
1246 contract: Option<RegisteredContract>,
1247 }
1248 impl HandlesByAddressQuery for Temp {
1249 fn handle(&self, _address: String) -> QuerierResult {
1250 let response = QueryContractRegistrationInfoResponse {
1251 contract: self.contract.to_owned(),
1252 };
1253 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1254 }
1255 }
1256 Some(Box::new(Temp { contract }))
1257 }
1258
1259 pub fn create_simple_balance_bank_query_handler(balances: Vec<Coin>) -> Option<Box<dyn HandlesBankBalanceQuery>> {
1260 struct Temp {
1261 balances: Vec<Coin>,
1262 }
1263 impl HandlesBankBalanceQuery for Temp {
1264 fn handle(&self, _: String, denom: String) -> QuerierResult {
1265 let balances = self.balances.to_owned();
1266 let empty = Coin::new(0u128, denom.clone());
1267 let balance = balances.iter().find(|b| -> bool { b.denom == denom }).unwrap_or(&empty);
1268 let res = BalanceResponse::new(balance.to_owned());
1269
1270 SystemResult::Ok(ContractResult::from(to_json_binary(&res)))
1271 }
1272 }
1273 Some(Box::new(Temp { balances }))
1274 }
1275
1276 pub fn create_simple_all_balances_bank_query_handler(balances: Vec<Coin>) -> Option<Box<dyn HandlesBankAllBalancesQuery>> {
1277 struct Temp {
1278 balances: Vec<Coin>,
1279 }
1280 impl HandlesBankAllBalancesQuery for Temp {
1281 fn handle(&self, _: String) -> QuerierResult {
1282 let res = AllBalanceResponse::new(self.balances.to_owned());
1283
1284 SystemResult::Ok(ContractResult::from(to_json_binary(&res)))
1285 }
1286 }
1287 Some(Box::new(Temp { balances }))
1288 }
1289
1290 pub fn create_atomic_order_fee_multiplier_handler(multiplier: FPDecimal) -> Option<Box<dyn HandlesMarketIdQuery>> {
1291 struct Temp {
1292 multiplier: FPDecimal,
1293 }
1294 impl HandlesMarketIdQuery for Temp {
1295 fn handle(&self, _market_id: MarketId) -> QuerierResult {
1296 let response = QueryMarketAtomicExecutionFeeMultiplierResponse { multiplier: self.multiplier };
1297 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1298 }
1299 }
1300 Some(Box::new(Temp { multiplier }))
1301 }
1302
1303 pub fn create_smart_query_handler(result: Result<Binary, SystemError>) -> Option<Box<dyn HandlesSmartQuery>> {
1304 struct Temp {
1305 result: Result<Binary, SystemError>,
1306 }
1307 impl HandlesSmartQuery for Temp {
1308 fn handle(&self, _contract_addr: &str, _msg: &Binary) -> QuerierResult {
1309 match self.result.clone() {
1310 Ok(resp) => SystemResult::Ok(ContractResult::from(StdResult::Ok(resp))),
1311 Err(err) => SystemResult::Err(err),
1312 }
1313 }
1314 }
1315 Some(Box::new(Temp { result }))
1316 }
1317
1318 pub fn create_raw_query_handler(result: Result<Binary, SystemError>) -> Option<Box<dyn HandlesRawQuery>> {
1319 struct Temp {
1320 result: Result<Binary, SystemError>,
1321 }
1322 impl HandlesRawQuery for Temp {
1323 fn handle(&self, _contract_addr: &str, _key: &Binary) -> QuerierResult {
1324 match self.result.clone() {
1325 Ok(resp) => SystemResult::Ok(ContractResult::from(StdResult::Ok(resp))),
1326 Err(err) => SystemResult::Err(err),
1327 }
1328 }
1329 }
1330 Some(Box::new(Temp { result }))
1331 }
1332
1333 pub fn create_contract_info_handler(code_id: u64, creator: Addr) -> Option<Box<dyn HandlesContractInfo>> {
1334 struct Temp {
1335 code_id: u64,
1336 creator: Addr,
1337 }
1338
1339 impl HandlesContractInfo for Temp {
1340 fn handle(&self, _contract_addr: &str) -> QuerierResult {
1341 let response = ContractInfoResponse::new(self.code_id, self.creator.to_owned(), None, false, None);
1342
1343 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1344 }
1345 }
1346
1347 Some(Box::new(Temp { code_id, creator }))
1348 }
1349
1350 pub fn create_code_id_handler(creator: Addr) -> Option<Box<dyn HandlesCodeInfo>> {
1351 struct Temp {
1352 creator: Addr,
1353 }
1354
1355 impl HandlesCodeInfo for Temp {
1356 fn handle(&self, code_id: u64) -> QuerierResult {
1357 let response = CodeInfoResponse::new(code_id, self.creator.to_owned(), Checksum::generate(b"123"));
1358
1359 SystemResult::Ok(ContractResult::from(to_json_binary(&response)))
1360 }
1361 }
1362
1363 Some(Box::new(Temp { creator }))
1364 }
1365}