use crate::asset::{Asset, AssetInfo, PairInfo};
use crate::factory::{
Config as FactoryConfig, FeeInfoResponse, PairType, PairsResponse, QueryMsg as FactoryQueryMsg,
TrackerConfig,
};
use crate::pair::{QueryMsg as PairQueryMsg, ReverseSimulationResponse, SimulationResponse};
use cosmwasm_std::{
from_json, Addr, AllBalanceResponse, BankQuery, Coin, CustomQuery, Decimal, QuerierWrapper,
QueryRequest, StdError, StdResult, Uint128,
};
use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg, TokenInfoResponse};
pub fn query_balance<C>(
querier: &QuerierWrapper<C>,
account_addr: impl Into<String>,
denom: impl Into<String>,
) -> StdResult<Uint128>
where
C: CustomQuery,
{
querier
.query_balance(account_addr, denom)
.map(|coin| coin.amount)
}
pub fn query_all_balances(querier: &QuerierWrapper, account_addr: Addr) -> StdResult<Vec<Coin>> {
let all_balances: AllBalanceResponse =
querier.query(&QueryRequest::Bank(BankQuery::AllBalances {
address: String::from(account_addr),
}))?;
Ok(all_balances.amount)
}
pub fn query_token_balance<C>(
querier: &QuerierWrapper<C>,
contract_addr: impl Into<String>,
account_addr: impl Into<String>,
) -> StdResult<Uint128>
where
C: CustomQuery,
{
let resp: Cw20BalanceResponse = querier
.query_wasm_smart(
contract_addr,
&Cw20QueryMsg::Balance {
address: account_addr.into(),
},
)
.unwrap_or_else(|_| Cw20BalanceResponse {
balance: Uint128::zero(),
});
Ok(resp.balance)
}
pub fn query_token_symbol<C>(
querier: &QuerierWrapper<C>,
contract_addr: impl Into<String>,
) -> StdResult<String>
where
C: CustomQuery,
{
let res: TokenInfoResponse =
querier.query_wasm_smart(contract_addr, &Cw20QueryMsg::TokenInfo {})?;
Ok(res.symbol)
}
pub fn query_supply<C>(
querier: &QuerierWrapper<C>,
contract_addr: impl Into<String>,
) -> StdResult<Uint128>
where
C: CustomQuery,
{
let res: TokenInfoResponse =
querier.query_wasm_smart(contract_addr, &Cw20QueryMsg::TokenInfo {})?;
Ok(res.total_supply)
}
pub fn query_native_supply<C>(
querier: &QuerierWrapper<C>,
denom: impl Into<String>,
) -> StdResult<Uint128>
where
C: CustomQuery,
{
querier.query_supply(denom).map(|res| res.amount)
}
pub fn query_token_precision<C>(
querier: &QuerierWrapper<C>,
asset_info: &AssetInfo,
factory_addr: &Addr,
) -> StdResult<u8>
where
C: CustomQuery,
{
Ok(match asset_info {
AssetInfo::NativeToken { denom } => {
let res = query_factory_config(querier, factory_addr)?;
let result = crate::native_coin_registry::COINS_INFO.query(
querier,
res.coin_registry_address,
denom.to_string(),
)?;
if let Some(decimals) = result {
decimals
} else {
return Err(StdError::generic_err(format!(
"The {denom} precision was not found"
)));
}
}
AssetInfo::Token { contract_addr } => {
let res: TokenInfoResponse =
querier.query_wasm_smart(contract_addr, &Cw20QueryMsg::TokenInfo {})?;
res.decimals
}
})
}
pub fn query_factory_config<C>(
querier: &QuerierWrapper<C>,
factory_contract: impl Into<String>,
) -> StdResult<FactoryConfig>
where
C: CustomQuery,
{
if let Some(res) = querier.query_wasm_raw(factory_contract, b"config".as_slice())? {
let res = from_json(res)?;
Ok(res)
} else {
Err(StdError::generic_err("The factory config not found!"))
}
}
pub fn query_tracker_config<C>(
querier: &QuerierWrapper<C>,
factory_contract: impl Into<String>,
) -> StdResult<TrackerConfig>
where
C: CustomQuery,
{
if let Some(res) = querier.query_wasm_raw(factory_contract, b"tracker_config".as_slice())? {
Ok(from_json(res)?)
} else {
Err(StdError::generic_err("The tracker config not found!"))
}
}
#[derive(Clone)]
pub struct FeeInfo {
pub fee_address: Option<Addr>,
pub total_fee_rate: Decimal,
pub maker_fee_rate: Decimal,
}
pub fn query_fee_info<C>(
querier: &QuerierWrapper<C>,
factory_contract: impl Into<String>,
pair_type: PairType,
) -> StdResult<FeeInfo>
where
C: CustomQuery,
{
let res: FeeInfoResponse =
querier.query_wasm_smart(factory_contract, &FactoryQueryMsg::FeeInfo { pair_type })?;
Ok(FeeInfo {
fee_address: res.fee_address,
total_fee_rate: Decimal::from_ratio(res.total_fee_bps, 10000u16),
maker_fee_rate: Decimal::from_ratio(res.maker_fee_bps, 10000u16),
})
}
pub fn query_pair_info(
querier: &QuerierWrapper,
factory_contract: impl Into<String>,
asset_infos: &[AssetInfo],
) -> StdResult<PairInfo> {
querier.query_wasm_smart(
factory_contract,
&FactoryQueryMsg::Pair {
asset_infos: asset_infos.to_vec(),
},
)
}
pub fn query_pairs_info(
querier: &QuerierWrapper,
factory_contract: impl Into<String>,
start_after: Option<Vec<AssetInfo>>,
limit: Option<u32>,
) -> StdResult<PairsResponse> {
querier.query_wasm_smart(
factory_contract,
&FactoryQueryMsg::Pairs { start_after, limit },
)
}
pub fn simulate(
querier: &QuerierWrapper,
pair_contract: impl Into<String>,
offer_asset: &Asset,
) -> StdResult<SimulationResponse> {
querier.query_wasm_smart(
pair_contract,
&PairQueryMsg::Simulation {
offer_asset: offer_asset.clone(),
ask_asset_info: None,
},
)
}
pub fn reverse_simulate(
querier: &QuerierWrapper,
pair_contract: impl Into<String>,
ask_asset: &Asset,
) -> StdResult<ReverseSimulationResponse> {
querier.query_wasm_smart(
pair_contract,
&PairQueryMsg::ReverseSimulation {
offer_asset_info: None,
ask_asset: ask_asset.clone(),
},
)
}