injective_cosmwasm/
exchange_mock_querier.rs

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            // NOTE: this is 100 with 8 decimal places
48            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            // default_multiple: 3600i64,
293            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}