1use cosmwasm_std::{Addr, QuerierWrapper};
2use cw_asset::AssetInfo;
3use thiserror::Error;
4
5use super::{AssetEntry, ChannelEntry, ContractEntry};
6use crate::{
7 ans_host::{
8 state::{
9 ASSET_ADDRESSES, ASSET_PAIRINGS, CHANNELS, CONTRACT_ADDRESSES, POOL_METADATA,
10 REGISTERED_DEXES, REV_ASSET_ADDRESSES,
11 },
12 RegisteredDexesResponse,
13 },
14 objects::{DexAssetPairing, PoolMetadata, PoolReference, UniquePoolId},
15};
16
17#[derive(Error, Debug, PartialEq)]
18pub enum AnsHostError {
19 #[error("Contract {contract} not found in ans_host {ans_host}.")]
21 ContractNotFound {
22 contract: ContractEntry,
23 ans_host: Addr,
24 },
25
26 #[error("Asset {asset} not found in ans_host {ans_host}.")]
28 AssetNotFound { asset: AssetEntry, ans_host: Addr },
29
30 #[error("CW Asset {asset} not found in ans_host {ans_host}.")]
32 CwAssetNotFound { asset: AssetInfo, ans_host: Addr },
33
34 #[error("Channel {channel} not found in ans_host {ans_host}.")]
36 ChannelNotFound {
37 channel: ChannelEntry,
38 ans_host: Addr,
39 },
40
41 #[error("Asset pairing {pairing} not found in ans_host {ans_host}.")]
43 DexPairingNotFound {
44 pairing: DexAssetPairing,
45 ans_host: Addr,
46 },
47
48 #[error("Pool metadata for pool {pool} not found in ans_host {ans_host}.")]
50 PoolMetadataNotFound { pool: UniquePoolId, ans_host: Addr },
51
52 #[error("Object {object} should be formatted {expected} but is {actual}")]
53 FormattingError {
54 object: String,
55 expected: String,
56 actual: String,
57 },
58
59 #[error("Query during '{method_name}' failed: {error}")]
61 QueryFailed {
62 method_name: String,
63 error: cosmwasm_std::StdError,
64 },
65}
66
67pub type AnsHostResult<T> = Result<T, AnsHostError>;
68
69#[cosmwasm_schema::cw_serde]
72pub struct AnsHost {
73 pub address: Addr,
75}
76
77impl AnsHost {
78 pub fn new(address: Addr) -> Self {
80 Self { address }
81 }
82 pub fn query_contracts(
84 &self,
85 querier: &QuerierWrapper,
86 contracts: &[ContractEntry],
87 ) -> AnsHostResult<Vec<Addr>> {
88 let mut resolved_contracts: Vec<Addr> = Vec::new();
89 for key in contracts.iter() {
91 let result = self.query_contract(querier, key)?;
92 resolved_contracts.push(result);
93 }
94 Ok(resolved_contracts)
95 }
96
97 #[function_name::named]
99 pub fn query_contract(
100 &self,
101 querier: &QuerierWrapper,
102 contract: &ContractEntry,
103 ) -> AnsHostResult<Addr> {
104 let result: Addr = CONTRACT_ADDRESSES
105 .query(querier, self.address.clone(), contract)
106 .map_err(|error| AnsHostError::QueryFailed {
107 method_name: function_name!().to_owned(),
108 error,
109 })?
110 .ok_or_else(|| AnsHostError::ContractNotFound {
111 contract: contract.clone(),
112 ans_host: self.address.clone(),
113 })?;
114 Ok(result)
115 }
116
117 pub fn query_assets(
119 &self,
120 querier: &QuerierWrapper,
121 assets: &[AssetEntry],
122 ) -> AnsHostResult<Vec<AssetInfo>> {
123 let mut resolved_assets = Vec::new();
124
125 for asset in assets.iter() {
126 let result = self.query_asset(querier, asset)?;
127 resolved_assets.push(result);
128 }
129 Ok(resolved_assets)
130 }
131
132 #[function_name::named]
134 pub fn query_asset(
135 &self,
136 querier: &QuerierWrapper,
137 asset: &AssetEntry,
138 ) -> AnsHostResult<AssetInfo> {
139 let result = ASSET_ADDRESSES
140 .query(querier, self.address.clone(), asset)
141 .map_err(|error| AnsHostError::QueryFailed {
142 method_name: function_name!().to_owned(),
143 error,
144 })?
145 .ok_or_else(|| AnsHostError::AssetNotFound {
146 asset: asset.clone(),
147 ans_host: self.address.clone(),
148 })?;
149 Ok(result)
150 }
151
152 pub fn query_assets_reverse(
154 &self,
155 querier: &QuerierWrapper,
156 assets: &[AssetInfo],
157 ) -> AnsHostResult<Vec<AssetEntry>> {
158 let mut resolved_assets = vec![];
160
161 for asset in assets.iter() {
162 let result = self.query_asset_reverse(querier, asset)?;
163 resolved_assets.push(result);
164 }
165 Ok(resolved_assets)
166 }
167
168 #[function_name::named]
170 pub fn query_asset_reverse(
171 &self,
172 querier: &QuerierWrapper,
173 asset: &AssetInfo,
174 ) -> AnsHostResult<AssetEntry> {
175 let result = REV_ASSET_ADDRESSES
176 .query(querier, self.address.clone(), asset)
177 .map_err(|error| AnsHostError::QueryFailed {
178 method_name: function_name!().to_owned(),
179 error,
180 })?
181 .ok_or_else(|| AnsHostError::CwAssetNotFound {
182 asset: asset.clone(),
183 ans_host: self.address.clone(),
184 })?;
185 Ok(result)
186 }
187
188 #[function_name::named]
190 pub fn query_channel(
191 &self,
192 querier: &QuerierWrapper,
193 channel: &ChannelEntry,
194 ) -> AnsHostResult<String> {
195 let result: String = CHANNELS
196 .query(querier, self.address.clone(), channel)
197 .map_err(|error| AnsHostError::QueryFailed {
198 method_name: function_name!().to_owned(),
199 error,
200 })?
201 .ok_or_else(|| AnsHostError::ChannelNotFound {
202 channel: channel.clone(),
203 ans_host: self.address.clone(),
204 })?;
205 Ok(result)
207 }
208
209 #[function_name::named]
211 pub fn query_asset_pairing(
212 &self,
213 querier: &QuerierWrapper,
214 dex_asset_pairing: &DexAssetPairing,
215 ) -> AnsHostResult<Vec<PoolReference>> {
216 let result: Vec<PoolReference> = ASSET_PAIRINGS
217 .query(querier, self.address.clone(), dex_asset_pairing)
218 .map_err(|error| AnsHostError::QueryFailed {
219 method_name: function_name!().to_owned(),
220 error,
221 })?
222 .ok_or_else(|| AnsHostError::DexPairingNotFound {
223 pairing: dex_asset_pairing.clone(),
224 ans_host: self.address.clone(),
225 })?;
226 Ok(result)
227 }
228
229 #[function_name::named]
230 pub fn query_pool_metadata(
231 &self,
232 querier: &QuerierWrapper,
233 pool_id: UniquePoolId,
234 ) -> AnsHostResult<PoolMetadata> {
235 let result: PoolMetadata = POOL_METADATA
236 .query(querier, self.address.clone(), pool_id)
237 .map_err(|error| AnsHostError::QueryFailed {
238 method_name: function_name!().to_owned(),
239 error,
240 })?
241 .ok_or_else(|| AnsHostError::PoolMetadataNotFound {
242 pool: pool_id,
243 ans_host: self.address.clone(),
244 })?;
245 Ok(result)
246 }
247
248 #[function_name::named]
249 pub fn query_registered_dexes(
250 &self,
251 querier: &QuerierWrapper,
252 ) -> AnsHostResult<RegisteredDexesResponse> {
253 let dexes = REGISTERED_DEXES
254 .query(querier, self.address.clone())
255 .map_err(|error| AnsHostError::QueryFailed {
256 method_name: function_name!().to_owned(),
257 error,
258 })?;
259 Ok(RegisteredDexesResponse { dexes })
260 }
261}