use cosmwasm_std::{Decimal256, Timestamp};
use serde::{Deserialize, Serialize};
use crate::oracle::client::OracleClient;
use crate::oracle::error::OracleError;
impl OracleClient {
pub async fn get_prices(&self) -> Result<Vec<Price>, OracleError> {
let query = Query {
get_prices: GetPricesRequest {},
};
let response: GetPricesResponse = self
.query_contract(self.oracle_contract_address.to_string(), &query, None)
.await?
.data;
Ok(response.prices)
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct AssetPair(String);
impl PartialEq<String> for AssetPair {
fn eq(&self, other: &String) -> bool {
&self.0 == other
}
}
impl From<AssetPair> for String {
fn from(pair: AssetPair) -> Self {
pair.0
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct Price {
pub asset_pair: AssetPair,
pub price: Decimal256,
pub expiry_time: Timestamp,
}
#[derive(Serialize)]
struct Query {
pub get_prices: GetPricesRequest,
}
#[derive(Serialize)]
struct GetPricesRequest {}
#[derive(Deserialize)]
struct GetPricesResponse {
pub prices: Vec<Price>,
}
#[cfg(test)]
mod tests {
use std::ops::Add;
use std::str::FromStr;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use serial_test::serial;
use super::*;
use crate::oracle::client::OracleAdminClient;
use crate::test_utils::helpers::{
TEST_ASSET_ARCH_ETH_PAIR, TEST_ASSET_ARCH_USDT_PAIR, TEST_ASSET_ETH_USDT_PAIR,
};
use crate::test_utils::test_scenario::TestScenario;
#[test]
fn eq_asset_pair() {
let cmp = "DummyString".to_string();
let pair = AssetPair(cmp.clone());
assert_eq!(pair, cmp);
assert_ne!(pair, "NotTheSame :(".to_string())
}
#[tokio::test]
#[serial]
async fn test_get_prices() {
let 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 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");
let price = Decimal256::from_str("50000").unwrap();
let prices = client
.public_oracle_client
.get_prices()
.await
.expect("Failed to get prices");
assert!(
prices.is_empty(),
"Prices should be empty before setting any"
);
test_scenario.set_default_assets(&client).await;
test_scenario
.set_default_prices(&client, price_expiry_timestamp, "50000")
.await;
let prices = client.public_oracle_client.get_prices().await.unwrap();
let price_arch_usdt = Price {
asset_pair: AssetPair(TEST_ASSET_ARCH_USDT_PAIR.to_owned()),
price,
expiry_time: Timestamp::from_seconds(price_expiry_timestamp.as_secs()),
};
let price_arch_eth = Price {
asset_pair: AssetPair(TEST_ASSET_ARCH_ETH_PAIR.to_owned()),
price,
expiry_time: Timestamp::from_seconds(price_expiry_timestamp.as_secs()),
};
let price_eth_usdt = Price {
asset_pair: AssetPair(TEST_ASSET_ETH_USDT_PAIR.to_owned()),
price,
expiry_time: Timestamp::from_seconds(price_expiry_timestamp.as_secs()),
};
assert_eq!(
prices,
vec![price_eth_usdt, price_arch_eth, price_arch_usdt]
)
}
}