Skip to main content

bolt_cw_sdk/oracle/
asset_pairs.rs

1use serde::{Deserialize, Serialize};
2
3use crate::oracle::client::OracleClient;
4use crate::oracle::error::OracleError;
5
6impl OracleClient {
7    pub async fn asset_pairs(&self) -> Result<Vec<AssetPairs>, OracleError> {
8        let query = Query {
9            asset_pairs: AssetPairsRequest {},
10        };
11        let response: AssetPairsResponse = self
12            .query_contract(self.oracle_contract_address.to_string(), &query, None)
13            .await?
14            .data;
15        Ok(response.list)
16    }
17}
18
19#[derive(Serialize, Deserialize, PartialEq, Debug)]
20pub struct AssetPairs {
21    pub base: Asset,
22    pub quote: Asset,
23}
24
25#[derive(Serialize, Deserialize, PartialEq, Debug)]
26pub struct Asset {
27    pub name: String,
28    pub symbol: String,
29    pub precision: u8,
30}
31
32#[derive(Serialize)]
33struct Query {
34    pub asset_pairs: AssetPairsRequest,
35}
36
37#[derive(Serialize)]
38struct AssetPairsRequest {}
39
40#[derive(Deserialize)]
41struct AssetPairsResponse {
42    pub list: Vec<AssetPairs>,
43}
44
45#[cfg(test)]
46mod tests {
47    use std::str::FromStr;
48
49    use cosmwasm_std::Decimal256;
50    use serial_test::serial;
51
52    use super::*;
53    use crate::oracle::client::OracleAdminClient;
54    use crate::test_utils::helpers::{
55        TEST_ASSET_ARCH_NAME, TEST_ASSET_ARCH_PRECISION, TEST_ASSET_ARCH_SYMBOL,
56        TEST_ASSET_ETH_NAME, TEST_ASSET_ETH_PRECISION, TEST_ASSET_ETH_SYMBOL, TEST_ASSET_USDT_NAME,
57        TEST_ASSET_USDT_PRECISION, TEST_ASSET_USDT_SYMBOL,
58    };
59    use crate::test_utils::test_scenario::TestScenario;
60
61    #[tokio::test]
62    #[serial]
63    async fn test_asset_pairs_against_wrong_contract() {
64        let test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
65        let client = OracleAdminClient::from_scenario(&test_scenario, &test_scenario.admin_address)
66            .expect("Failed to create oracle admin client");
67
68        let err = client
69            .public_oracle_client
70            .asset_pairs()
71            .await
72            .expect_err("Expected error when querying asset pairs against wrong contract");
73        assert!(matches!(err, OracleError::CosmosClientError(_)))
74    }
75
76    #[tokio::test]
77    #[serial]
78    async fn test_asset_pairs() {
79        let test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
80
81        let price_threshold_ratio = Decimal256::from_str("0.5").unwrap();
82        let price_expire_millis = Some(1000);
83        let oracle_contract_address = test_scenario
84            .instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
85            .await;
86
87        let client = OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
88            .expect("Failed to create oracle admin client");
89
90        let asset_pairs = client
91            .public_oracle_client
92            .asset_pairs()
93            .await
94            .expect("Failed to get asset pairs");
95        assert!(asset_pairs.is_empty()); // We haven't setup any asset pairs yet
96
97        let _ = test_scenario.set_default_assets(&client).await;
98
99        let asset_pairs = client.public_oracle_client.asset_pairs().await.unwrap();
100
101        let expected = vec![
102            AssetPairs {
103                base: Asset {
104                    name: TEST_ASSET_ETH_NAME.to_string(),
105                    symbol: TEST_ASSET_ETH_SYMBOL.to_string(),
106                    precision: TEST_ASSET_ETH_PRECISION,
107                },
108                quote: Asset {
109                    name: TEST_ASSET_USDT_NAME.to_string(),
110                    symbol: TEST_ASSET_USDT_SYMBOL.to_string(),
111                    precision: TEST_ASSET_USDT_PRECISION,
112                },
113            },
114            AssetPairs {
115                base: Asset {
116                    name: TEST_ASSET_ARCH_NAME.to_string(),
117                    symbol: TEST_ASSET_ARCH_SYMBOL.to_string(),
118                    precision: TEST_ASSET_ARCH_PRECISION,
119                },
120                quote: Asset {
121                    name: TEST_ASSET_USDT_NAME.to_string(),
122                    symbol: TEST_ASSET_USDT_SYMBOL.to_string(),
123                    precision: TEST_ASSET_USDT_PRECISION,
124                },
125            },
126            AssetPairs {
127                base: Asset {
128                    name: TEST_ASSET_ARCH_NAME.to_string(),
129                    symbol: TEST_ASSET_ARCH_SYMBOL.to_string(),
130                    precision: TEST_ASSET_ARCH_PRECISION,
131                },
132                quote: Asset {
133                    name: TEST_ASSET_ETH_NAME.to_string(),
134                    symbol: TEST_ASSET_ETH_SYMBOL.to_string(),
135                    precision: TEST_ASSET_ETH_PRECISION,
136                },
137            },
138        ];
139        assert_eq!(asset_pairs, expected);
140    }
141}