use std::sync::Arc;
use crate::chain_config::ChainConfig;
use crate::cosmos_client::query_contract::QueryContractResponse;
use crate::cosmos_client::CosmosClient;
use crate::oracle::error::OracleError;
use crate::tx_builder::TxBuilder;
use cosmrs::proto::cosmos::auth::v1beta1::BaseAccount;
use cosmrs::AccountId;
use serde::{Deserialize, Serialize};
use tendermint_rpc::endpoint::broadcast::tx_commit::Response;
use tendermint_rpc::endpoint::status;
#[derive(Debug)]
pub struct OracleAdminClient {
pub(crate) public_oracle_client: OracleClient,
pub(crate) chain_config: ChainConfig,
}
impl OracleAdminClient {
pub fn new(
cosmos_client: Arc<CosmosClient>,
chain_config: ChainConfig,
) -> Result<Self, OracleError> {
let public_oracle_client =
OracleClient::new(cosmos_client, chain_config.oracle_contract_address.clone())?;
Ok(OracleAdminClient {
public_oracle_client,
chain_config,
})
}
#[cfg(any(test, feature = "test_scenario"))]
pub fn from_scenario(
scenario: &crate::test_utils::test_scenario::TestScenario,
oracle_contract: &str,
) -> Result<Self, OracleError> {
let chain_config = scenario.get_chain_config(oracle_contract);
Self::new(scenario.cosmos_client.clone(), chain_config)
}
pub async fn execute_tx(&self, builder: TxBuilder) -> Result<Response, OracleError> {
self.public_oracle_client
.cosmos_client
.execute_tx(builder)
.await
.map_err(OracleError::CosmosClientError)
}
pub async fn broadcast_tx(&self, signed_bytes: Vec<u8>) -> Result<Response, OracleError> {
self.public_oracle_client
.cosmos_client
.broadcast_tx(signed_bytes)
.await
.map_err(OracleError::CosmosClientError)
}
pub async fn account(&self, account_address: String) -> Result<BaseAccount, OracleError> {
self.public_oracle_client.account(account_address).await
}
}
#[derive(Debug)]
pub struct OracleClient {
pub(crate) cosmos_client: Arc<CosmosClient>,
pub(crate) oracle_contract_address: AccountId,
}
impl OracleClient {
pub fn new(
cosmos_client: Arc<CosmosClient>,
oracle_contract_address: AccountId,
) -> Result<Self, OracleError> {
Ok(OracleClient {
cosmos_client,
oracle_contract_address,
})
}
pub async fn status(&self) -> Result<status::Response, OracleError> {
self.cosmos_client
.status()
.await
.map_err(OracleError::CosmosClientError)
}
pub async fn account(&self, account_address: String) -> Result<BaseAccount, OracleError> {
self.cosmos_client
.account(account_address)
.await
.map_err(OracleError::CosmosClientError)
}
pub(crate) async fn query_contract<QUERY, RESPONSE>(
&self,
contract_address: String,
query: &QUERY,
height: Option<u64>,
) -> Result<QueryContractResponse<RESPONSE>, OracleError>
where
QUERY: Serialize,
for<'de> RESPONSE: Deserialize<'de>,
{
self.cosmos_client
.query_contract(contract_address, query, height)
.await
.map_err(OracleError::CosmosClientError)
}
}
#[cfg(test)]
mod tests {
use serial_test::serial;
use super::*;
use crate::test_utils::test_scenario::TestScenario;
#[tokio::test]
#[serial]
async fn test_oracle_admin_client() {
let test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let oracle_contract_address =
"archway1706lywddqxu24ff6426puftkfaw20tyhdkun30pljux7e9alv2fql0q0ca".to_string();
let client = OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address);
assert!(client.is_ok());
let client = client.unwrap();
let status = client.public_oracle_client.cosmos_client.status().await;
assert!(status.is_ok());
}
#[tokio::test]
#[serial]
async fn test_oracle_client() {
let test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let oracle_contract_address =
"archway1706lywddqxu24ff6426puftkfaw20tyhdkun30pljux7e9alv2fql0q0ca".to_string();
let client = OracleClient::new(
test_scenario.cosmos_client,
oracle_contract_address.parse().unwrap(),
)
.unwrap();
client.cosmos_client.status().await.unwrap();
}
}