use crate::cosmos_client::query_contract::QueryContractResponse;
use crate::router::client::RouterClient;
use crate::router::error::RouterError;
use cosmrs::Coin;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
impl RouterClient {
pub async fn quotes_for_user_all(
&self,
user: String,
height: Option<u64>,
) -> Result<QueryContractResponse<HashMap<String, Vec<Coin>>>, RouterError> {
let query = Query {
quotes_for_user_all: QuotesForUserAllRequest { lp_address: user },
};
let response = self
.query_contract::<_, QuotesForUserAllResponse>(
self.router_contract_address.to_string(),
&query,
height,
)
.await?;
let data = response
.data
.quotes
.into_iter()
.map(|(addr, coins)| {
let cosmr_coins = coins
.iter()
.map(|c| Coin::new(c.amount.u128(), &c.denom))
.collect::<Result<Vec<_>, _>>();
match cosmr_coins {
Ok(coins) => Ok((addr, coins)),
Err(err) => Err(err),
}
})
.collect::<Result<HashMap<_, _>, _>>()
.map_err(RouterError::EyreError)?;
Ok(QueryContractResponse {
data,
height: response.height,
})
}
}
#[derive(Serialize)]
struct Query {
pub quotes_for_user_all: QuotesForUserAllRequest,
}
#[derive(Serialize)]
pub struct QuotesForUserAllRequest {
pub lp_address: String,
}
#[derive(Deserialize)]
pub struct QuotesForUserAllResponse {
pub quotes: HashMap<String, Vec<cosmwasm_std::Coin>>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::market::client::MarketAdminClient;
use crate::oracle::client::OracleAdminClient;
use crate::router::client::RouterAdminClient;
use crate::test_utils::helpers::{
TEST_ASSET_ARCH_SYMBOL, TEST_ASSET_ETH_SYMBOL, TEST_ASSET_USDT_SYMBOL,
};
use crate::test_utils::test_scenario::TestScenario;
use cosmrs::AccountId;
use cosmwasm_std::{Decimal256, Uint128};
use serial_test::serial;
use std::ops::Add;
use std::str::FromStr;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[tokio::test]
#[serial]
async fn test_quotes_for_user_all() {
let mut test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let price_threshold_ratio = Decimal256::from_str("0.5").unwrap();
let price_expire_millis = Some(1000);
let oracle_contract_address = test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
let default_protocol_fee = Decimal256::from_str("0.1").unwrap();
let default_lp_fee = Decimal256::from_str("0.1").unwrap();
let router_contract_address = test_scenario
.instantiate_router_contract(
oracle_contract_address.clone(),
oracle_contract_address.clone(),
default_protocol_fee,
default_lp_fee,
)
.await;
let oracle_client =
OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
.expect("Failed to create oracle admin client");
let price_expiry_time = SystemTime::now().add(Duration::from_secs(7200)); let price_expiry_timestamp = price_expiry_time
.duration_since(UNIX_EPOCH)
.expect("Converting to timestamp failed");
test_scenario.set_default_assets(&oracle_client).await;
test_scenario
.set_default_prices(&oracle_client, price_expiry_timestamp, "50000")
.await;
let router_client = RouterAdminClient::from_scenario(
&test_scenario,
router_contract_address.parse().unwrap(),
)
.expect("Failed to create router admin client");
let market_address = test_scenario
.create_market(
&router_client,
TEST_ASSET_USDT_SYMBOL,
&[TEST_ASSET_ARCH_SYMBOL, TEST_ASSET_ETH_SYMBOL],
Uint128::new(10),
)
.await;
let market_client = MarketAdminClient::from_scenario(&test_scenario)
.expect("Failed to create market client");
let admin_account = test_scenario.admin_account();
test_scenario
.deposit_base(
&market_client,
AccountId::from_str(market_address.as_str()).unwrap(),
&admin_account,
Coin::new(10000000, TEST_ASSET_USDT_SYMBOL).unwrap(),
)
.await;
for (quote, amount) in [(TEST_ASSET_ARCH_SYMBOL, 100), (TEST_ASSET_ETH_SYMBOL, 90)] {
test_scenario
.swap_exact_in(
&router_client,
TEST_ASSET_USDT_SYMBOL,
None,
None,
amount,
quote.to_string(),
)
.await;
}
let quotes = router_client
.public_router_client
.quotes_for_user_all(test_scenario.admin_address, None)
.await
.expect("Failed to fetch quotes")
.data;
let assets = quotes
.get(&market_address)
.expect("Expected market address to be in response");
assert_eq!(assets.len(), 2);
let arch_amount = assets
.iter()
.find(|a| a.denom.as_ref() == TEST_ASSET_ARCH_SYMBOL)
.map(|coin| coin.amount)
.expect("Expected arch to be in response");
assert_eq!(arch_amount, 90);
let eth_amount = assets
.iter()
.find(|a| a.denom.as_ref() == TEST_ASSET_ETH_SYMBOL)
.map(|coin| coin.amount)
.expect("Expected eth to be in response");
assert_eq!(eth_amount, 81);
}
}