bolt-cw-sdk 1.0.0

SDK for the BOLT protocol, providing utilities for interacting with the BOLT contracts.
Documentation
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();
    }
}