abstract_os/objects/
ans_host.rs

1use super::{asset_entry::AssetEntry, contract_entry::ContractEntry, ChannelEntry};
2use crate::{
3    ans_host::state::{
4        ASSET_ADDRESSES, ASSET_PAIRINGS, CHANNELS, CONTRACT_ADDRESSES, POOL_METADATA,
5        REV_ASSET_ADDRESSES,
6    },
7    objects::{DexAssetPairing, PoolMetadata, PoolReference, UniquePoolId},
8    AbstractResult,
9};
10use cosmwasm_std::{Addr, QuerierWrapper, StdError};
11use cw_asset::AssetInfo;
12use std::collections::BTreeMap;
13
14/// Struct that stores the ans-host contract address.
15/// Implements `AbstractNameService` feature
16#[cosmwasm_schema::cw_serde]
17pub struct AnsHost {
18    /// Address of the ans_host contract
19    pub address: Addr,
20}
21
22impl AnsHost {
23    /// Create a new ans_host instance with the given address.
24    pub fn new(address: Addr) -> Self {
25        Self { address }
26    }
27    /// Raw Query to AnsHost contract
28    pub fn query_contracts(
29        &self,
30        querier: &QuerierWrapper,
31        contracts: Vec<ContractEntry>,
32    ) -> AbstractResult<BTreeMap<ContractEntry, Addr>> {
33        let mut resolved_contracts: BTreeMap<ContractEntry, Addr> = BTreeMap::new();
34
35        // Query over keys
36        for key in contracts.into_iter() {
37            let result = self.query_contract(querier, &key)?;
38            resolved_contracts.insert(key, result);
39        }
40        Ok(resolved_contracts)
41    }
42
43    /// Raw query of a single contract Addr
44    pub fn query_contract(
45        &self,
46        querier: &QuerierWrapper,
47        contract: &ContractEntry,
48    ) -> AbstractResult<Addr> {
49        let result: Addr = CONTRACT_ADDRESSES
50            .query(querier, self.address.clone(), contract)?
51            .ok_or_else(|| {
52                StdError::generic_err(format!("contract {contract} not found in ans_host"))
53            })?;
54        // Addresses are checked when stored.
55        Ok(Addr::unchecked(result))
56    }
57
58    /// Raw Query to AnsHost contract
59    pub fn query_assets(
60        &self,
61        querier: &QuerierWrapper,
62        assets: Vec<AssetEntry>,
63    ) -> AbstractResult<BTreeMap<AssetEntry, AssetInfo>> {
64        let mut resolved_assets: BTreeMap<AssetEntry, AssetInfo> = BTreeMap::new();
65
66        for asset in assets.into_iter() {
67            let result = self.query_asset(querier, &asset)?;
68            resolved_assets.insert(asset, result);
69        }
70        Ok(resolved_assets)
71    }
72
73    /// Raw query of a single AssetInfo
74    pub fn query_asset(
75        &self,
76        querier: &QuerierWrapper,
77        asset: &AssetEntry,
78    ) -> AbstractResult<AssetInfo> {
79        let result = ASSET_ADDRESSES
80            .query(querier, self.address.clone(), asset)?
81            .ok_or_else(|| {
82                StdError::generic_err(format!("asset {} not found in ans_host", &asset))
83            })?;
84        Ok(result)
85    }
86
87    /// Raw Query to AnsHost contract
88    pub fn query_assets_reverse(
89        &self,
90        querier: &QuerierWrapper,
91        assets: Vec<AssetInfo>,
92    ) -> AbstractResult<Vec<AssetEntry>> {
93        // AssetInfo does not implement PartialEq, so we can't use a BTreeMap
94        let mut resolved_assets = vec![];
95
96        for asset in assets.into_iter() {
97            let result = self.query_asset_reverse(querier, &asset)?;
98            resolved_assets.push(result);
99        }
100        Ok(resolved_assets)
101    }
102
103    /// Raw query of a single AssetEntry
104    pub fn query_asset_reverse(
105        &self,
106        querier: &QuerierWrapper,
107        asset: &AssetInfo,
108    ) -> AbstractResult<AssetEntry> {
109        let result = REV_ASSET_ADDRESSES
110            .query(querier, self.address.clone(), asset)?
111            .ok_or_else(|| {
112                StdError::generic_err(format!("cw-asset {} not found in ans_host", &asset))
113            })?;
114        Ok(result)
115    }
116
117    /// Raw query of a single channel Addr
118    pub fn query_channel(
119        &self,
120        querier: &QuerierWrapper,
121        channel: &ChannelEntry,
122    ) -> AbstractResult<String> {
123        let result: String = CHANNELS
124            .query(querier, self.address.clone(), channel)?
125            .ok_or_else(|| {
126                StdError::generic_err(format!("channel {channel} not found in ans_host"))
127            })?;
128        // Addresses are checked when stored.
129        Ok(result)
130    }
131
132    /// Raw query of a single asset pairing
133    pub fn query_asset_pairing(
134        &self,
135        querier: &QuerierWrapper,
136        dex_asset_pairing: &DexAssetPairing,
137    ) -> AbstractResult<Vec<PoolReference>> {
138        let result: Vec<PoolReference> = ASSET_PAIRINGS
139            .query(querier, self.address.clone(), dex_asset_pairing)?
140            .ok_or_else(|| {
141                StdError::generic_err(format!(
142                    "asset pairing {dex_asset_pairing} not found in ans_host"
143                ))
144            })?;
145        Ok(result)
146    }
147
148    pub fn query_pool_metadata(
149        &self,
150        querier: &QuerierWrapper,
151        pool_id: &UniquePoolId,
152    ) -> AbstractResult<PoolMetadata> {
153        let result: PoolMetadata = POOL_METADATA
154            .query(querier, self.address.clone(), *pool_id)?
155            .ok_or_else(|| {
156                StdError::generic_err(format!(
157                    "pool metadata for pool {} not found in ans_host",
158                    pool_id.as_u64()
159                ))
160            })?;
161        Ok(result)
162    }
163}