bolt_cw_sdk/oracle/
get_prices.rs1use 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)); 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}