use std::time::Duration;
use crate::oracle::add_asset_pairs::AssetPair;
use crate::oracle::client::OracleAdminClient;
use crate::oracle::post_prices::PriceUpdate;
use crate::test_utils::helpers::{
get_test_arch_usdt_pair, TEST_ASSET_ARCH_SYMBOL, TEST_ASSET_USDT_SYMBOL,
};
use crate::test_utils::test_scenario::TestScenario;
use crate::tx_builder::TxBuilder;
use cosmwasm_std::{Addr, Decimal256, Timestamp};
use serde::Serialize;
use tendermint_rpc::endpoint::broadcast::tx_commit::Response;
use super::helpers::{get_test_arch_eth_pair, get_test_eth_usdt_pair, TEST_ASSET_ETH_SYMBOL};
impl TestScenario {
pub async fn instantiate_oracle_contract(
&self,
price_threshold_ratio: Decimal256,
price_expire_millis: Option<u64>,
) -> String {
let init_msg = InstantiateMsg {
admin: Addr::unchecked(self.admin_address.clone()),
price_feeder: Addr::unchecked(self.price_feeder_account.account_id.to_string()),
price_threshold_ratio,
price_expire_millis,
};
let msg = serde_json::to_vec(&init_msg).expect("Failed to serialize init msg");
self.instantiate_contract(msg, self.oracle_code_id, "oracle")
.await
}
pub async fn instantiate_and_setup_oracle(
&self,
price_threshold_ratio: Decimal256,
price_expire_millis: Option<u64>,
asset_pairs: Vec<AssetPair>,
memo: &str,
) -> String {
let oracle_contract_address = self
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
let client = OracleAdminClient::from_scenario(self, &oracle_contract_address)
.expect("Failed to create oracle admin client");
let account = client
.account(self.admin_address.clone())
.await
.expect("Failed to get account from oracle client");
let mut tx_builder = TxBuilder::new(
self.admin_mnemonic.clone(),
self.chain_prefix.clone(),
self.chain_id.clone(),
self.derivation_path,
account.sequence,
account.account_number,
)
.expect("Failed to create tx builder");
client
.append_add_asset_pairs_msg(&mut tx_builder, asset_pairs)
.expect("Failed to append add asset pairs msg");
tx_builder.set_memo(memo.to_string());
tx_builder.set_fee(45_000_000_000_000_000, &self.chain_denom, 400_000u64);
let signed_bytes = tx_builder
.get_signed_bytes()
.expect("Failed to get signed bytes");
let response = client
.broadcast_tx(signed_bytes)
.await
.expect("Failed to broadcast tx");
println!(
"Oracle contract added assets with hash: {:?}",
response.hash.to_string()
);
oracle_contract_address
}
pub async fn set_default_assets(&self, client: &OracleAdminClient) -> Response {
let account = client
.public_oracle_client
.account(self.admin_address.clone())
.await
.expect("Failed to get account from public oracle client");
let mut tx_builder = TxBuilder::new(
self.admin_mnemonic.clone(),
self.chain_prefix.clone(),
self.chain_id.clone(),
self.derivation_path,
account.sequence,
account.account_number,
)
.expect("Failed to create tx builder");
let asset_pairs = vec![
get_test_arch_usdt_pair(),
get_test_eth_usdt_pair(),
get_test_arch_eth_pair(),
];
client
.append_add_asset_pairs_msg(&mut tx_builder, asset_pairs)
.expect("Failed to append add asset pairs msg");
tx_builder.set_memo("From test_default_assets".to_string());
let gas = 500_000u64;
tx_builder.set_fee(70_000_000_000_000_000u128, &self.chain_denom, gas);
let signed_bytes = tx_builder
.get_signed_bytes()
.expect("Failed to get signed bytes");
client
.broadcast_tx(signed_bytes)
.await
.expect("Failed to broadcast tx")
}
pub async fn set_prices(
&self,
client: &OracleAdminClient,
prices: Vec<((String, String), String)>,
price_expiry_timestamp: Duration,
) -> Response {
let account = client
.public_oracle_client
.account(self.price_feeder_account.account_id.to_string())
.await
.expect("Failed to get account from public oracle client");
let mut tx_builder = TxBuilder::new(
self.price_feeder_account.mnemonic.clone(),
self.chain_prefix.clone(),
self.chain_id.clone(),
self.derivation_path,
account.sequence,
account.account_number,
)
.expect("Failed to create tx builder");
let price_updates = prices
.iter()
.map(|((base, quote), price)| PriceUpdate {
base_asset_symbol: base.to_string(),
quote_asset_symbol: quote.to_string(),
price: price.clone(),
price_expiry_time: Some(Timestamp::from_seconds(price_expiry_timestamp.as_secs())),
})
.collect();
client
.append_post_prices_msg(&mut tx_builder, price_updates)
.expect("Append post prices message");
tx_builder.set_memo("From test_post_prices".to_string());
let gas = 500_000u64;
tx_builder.set_fee(70_000_000_000_000_000u128, &self.chain_denom, gas);
let signed_bytes = tx_builder
.get_signed_bytes()
.expect("Failed to get signed bytes");
client
.broadcast_tx(signed_bytes)
.await
.expect("Failed to broadcast tx")
}
pub async fn set_default_prices(
&self,
client: &OracleAdminClient,
price_expiry_timestamp: Duration,
price: &str,
) -> Response {
self.set_prices(
client,
vec![
(
(
TEST_ASSET_ARCH_SYMBOL.to_string(),
TEST_ASSET_USDT_SYMBOL.to_string(),
),
price.to_string(),
),
(
(
TEST_ASSET_ETH_SYMBOL.to_string(),
TEST_ASSET_USDT_SYMBOL.to_string(),
),
price.to_string(),
),
(
(
TEST_ASSET_ARCH_SYMBOL.to_string(),
TEST_ASSET_ETH_SYMBOL.to_string(),
),
price.to_string(),
),
],
price_expiry_timestamp,
)
.await
}
}
#[derive(Serialize)]
struct InstantiateMsg {
pub admin: Addr,
pub price_feeder: Addr,
pub price_threshold_ratio: Decimal256,
pub price_expire_millis: Option<u64>,
}
#[cfg(test)]
mod tests {
use serial_test::serial;
use super::*;
use crate::test_utils::test_scenario::TestScenario;
use std::str::FromStr;
#[tokio::test]
#[serial]
#[ignore]
async fn test_instantiate_oracle_contract() {
let test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let price_threshold_ratio = Decimal256::from_str("0.1").unwrap();
let price_expire_millis = Some(1000);
let contract_addr = test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
println!("Contract address: {:?}", contract_addr);
}
}