Skip to main content

bolt_cw_sdk/oracle/
get_prices.rs

1use cosmwasm_std::{Decimal256, Timestamp};
2use serde::{Deserialize, Serialize};
3
4use crate::oracle::client::OracleClient;
5use crate::oracle::error::OracleError;
6
7impl OracleClient {
8    pub async fn get_prices(&self) -> Result<Vec<Price>, OracleError> {
9        let query = Query {
10            get_prices: GetPricesRequest {},
11        };
12        let response: GetPricesResponse = self
13            .query_contract(self.oracle_contract_address.to_string(), &query, None)
14            .await?
15            .data;
16        Ok(response.prices)
17    }
18}
19
20#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
21pub struct AssetPair(String);
22
23impl PartialEq<String> for AssetPair {
24    fn eq(&self, other: &String) -> bool {
25        &self.0 == other
26    }
27}
28
29impl From<AssetPair> for String {
30    fn from(pair: AssetPair) -> Self {
31        pair.0
32    }
33}
34
35#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
36pub struct Price {
37    pub asset_pair: AssetPair,
38    pub price: Decimal256,
39    pub expiry_time: Timestamp,
40}
41
42#[derive(Serialize)]
43struct Query {
44    pub get_prices: GetPricesRequest,
45}
46
47#[derive(Serialize)]
48struct GetPricesRequest {}
49
50#[derive(Deserialize)]
51struct GetPricesResponse {
52    pub prices: Vec<Price>,
53}
54
55#[cfg(test)]
56mod tests {
57    use std::ops::Add;
58    use std::str::FromStr;
59    use std::time::{Duration, SystemTime, UNIX_EPOCH};
60
61    use serial_test::serial;
62
63    use super::*;
64    use crate::oracle::client::OracleAdminClient;
65    use crate::test_utils::helpers::{
66        TEST_ASSET_ARCH_ETH_PAIR, TEST_ASSET_ARCH_USDT_PAIR, TEST_ASSET_ETH_USDT_PAIR,
67    };
68    use crate::test_utils::test_scenario::TestScenario;
69
70    #[test]
71    fn eq_asset_pair() {
72        let cmp = "DummyString".to_string();
73        let pair = AssetPair(cmp.clone());
74
75        assert_eq!(pair, cmp);
76        assert_ne!(pair, "NotTheSame :(".to_string())
77    }
78
79    #[tokio::test]
80    #[serial]
81    async fn test_get_prices() {
82        let test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
83
84        let price_threshold_ratio = Decimal256::from_str("0.5").unwrap();
85        let price_expire_millis = Some(1000);
86        let oracle_contract_address = test_scenario
87            .instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
88            .await;
89
90        let client = OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
91            .expect("Failed to create oracle admin client");
92
93        let price_expiry_time = SystemTime::now().add(Duration::from_secs(7200)); // 2h from now
94        let price_expiry_timestamp = price_expiry_time
95            .duration_since(UNIX_EPOCH)
96            .expect("Converting to timestamp failed");
97        let price = Decimal256::from_str("50000").unwrap();
98
99        let prices = client
100            .public_oracle_client
101            .get_prices()
102            .await
103            .expect("Failed to get prices");
104        assert!(
105            prices.is_empty(),
106            "Prices should be empty before setting any"
107        );
108
109        test_scenario.set_default_assets(&client).await;
110        test_scenario
111            .set_default_prices(&client, price_expiry_timestamp, "50000")
112            .await;
113
114        let prices = client.public_oracle_client.get_prices().await.unwrap();
115        let price_arch_usdt = Price {
116            asset_pair: AssetPair(TEST_ASSET_ARCH_USDT_PAIR.to_owned()),
117            price,
118            expiry_time: Timestamp::from_seconds(price_expiry_timestamp.as_secs()),
119        };
120        let price_arch_eth = Price {
121            asset_pair: AssetPair(TEST_ASSET_ARCH_ETH_PAIR.to_owned()),
122            price,
123            expiry_time: Timestamp::from_seconds(price_expiry_timestamp.as_secs()),
124        };
125        let price_eth_usdt = Price {
126            asset_pair: AssetPair(TEST_ASSET_ETH_USDT_PAIR.to_owned()),
127            price,
128            expiry_time: Timestamp::from_seconds(price_expiry_timestamp.as_secs()),
129        };
130        assert_eq!(
131            prices,
132            vec![price_eth_usdt, price_arch_eth, price_arch_usdt]
133        )
134    }
135}