novax-executor 0.2.12

Part of the NovaX framework, this crate facilitates the execution of transactions and queries against smart contracts on the blockchain.
use async_trait::async_trait;
use reqwest::Client;

use crate::error::executor::ExecutorError;
use crate::network::query::models::request::VmValuesQueryRequest;
use crate::network::query::models::response::{VmValuesQueryResponse, VmValuesQueryResponseData};
use crate::NetworkQueryError;

#[async_trait]
pub trait BlockchainProxy: Send + Sync {
    fn new(gateway_url: String) -> Self;

    async fn execute_vmquery(
        &self,
        vm_request: &VmValuesQueryRequest,
    ) -> Result<VmValuesQueryResponseData, ExecutorError>;
}

pub struct NetworkBlockchainProxy {
    pub gateway_url: String
}

#[async_trait]
impl BlockchainProxy for NetworkBlockchainProxy {
    fn new(gateway_url: String) -> Self {
        Self {
            gateway_url,
        }
    }

    async fn execute_vmquery(&self, vm_request: &VmValuesQueryRequest) -> Result<VmValuesQueryResponseData, ExecutorError> {
        let url = format!("{}/vm-values/query", self.gateway_url);

        let json = serde_json::to_string(vm_request)
            .map_err(|_| NetworkQueryError::CannotSerializeVmValuesRequestBody)?;

        let result = match Client::new()
            .post(url)
            .body(json.clone())
            .send()
            .await
        {
            Ok(result) => result,
            Err(error) => return Err(NetworkQueryError::ErrorWhileSendingRequest { request_body: json, message: error.to_string() }.into())
        };

        let text = match result
            .text()
            .await
        {
            Ok(result) => result,
            Err(error) => return Err(NetworkQueryError::ErrorWhileSendingRequest { request_body: json, message: error.to_string() }.into())
        };

        let response = serde_json::from_str::<VmValuesQueryResponse>(&text)
            .map_err(|_| NetworkQueryError::CannotDeserializeVmValuesResponse)?;

        let Some(response_data) = response.data else {
            return Err(NetworkQueryError::ErrorInResponse { message: response.error }.into())
        };

        Ok(response_data)
    }
}