multiversx_sdk_http/
gateway_http_proxy.rs

1mod http_account;
2mod http_block;
3mod http_chain_simulator;
4mod http_network;
5mod http_tx;
6
7use multiversx_sdk::gateway::{GatewayAsyncService, GatewayRequest, GatewayRequestType};
8use reqwest::Method;
9use std::time::Duration;
10
11/// Allows communication with the MultiversX gateway API.
12#[derive(Clone, Debug)]
13pub struct GatewayHttpProxy {
14    pub(crate) proxy_uri: String,
15    pub(crate) client: reqwest::Client,
16}
17
18/// Converts from common sdk type to reqwest type.
19fn reqwest_method(request_type: GatewayRequestType) -> Method {
20    match request_type {
21        GatewayRequestType::Get => Method::GET,
22        GatewayRequestType::Post => Method::POST,
23    }
24}
25
26impl GatewayHttpProxy {
27    pub fn new(proxy_uri: String) -> Self {
28        Self {
29            proxy_uri,
30            client: reqwest::Client::new(),
31        }
32    }
33
34    /// Performs a request to the gateway.
35    /// Can be either GET or POST, depending on the argument.
36    pub async fn http_request<G>(&self, request: G) -> anyhow::Result<G::Result>
37    where
38        G: GatewayRequest,
39    {
40        let url = format!("{}/{}", self.proxy_uri, request.get_endpoint());
41        let method = request.request_type();
42        log::info!("{method} request: {url}");
43
44        let mut request_builder = self.client.request(reqwest_method(method), url);
45        if let Some(payload) = request.get_payload() {
46            log::trace!("{method} payload: {}", serde_json::to_string(payload)?);
47            request_builder = request_builder.json(&payload);
48        }
49
50        let http_request = request_builder.build()?;
51        let http_response = self.client.execute(http_request).await?;
52        let http_response_text = http_response.text().await?;
53        log::trace!("{method} response: {http_response_text}");
54
55        let decoded = serde_json::from_str::<G::DecodedJson>(&http_response_text)?;
56
57        request.process_json(decoded)
58    }
59}
60
61impl GatewayAsyncService for GatewayHttpProxy {
62    type Instant = std::time::Instant;
63
64    fn from_uri(uri: &str) -> Self {
65        Self::new(uri.to_owned())
66    }
67
68    fn request<G>(&self, request: G) -> impl std::future::Future<Output = anyhow::Result<G::Result>>
69    where
70        G: multiversx_sdk::gateway::GatewayRequest,
71    {
72        self.http_request(request)
73    }
74
75    fn sleep(&self, millis: u64) -> impl std::future::Future<Output = ()> {
76        tokio::time::sleep(Duration::from_millis(millis))
77    }
78
79    fn now(&self) -> Self::Instant {
80        std::time::Instant::now()
81    }
82
83    fn elapsed_seconds(&self, instant: &Self::Instant) -> f32 {
84        instant.elapsed().as_secs_f32()
85    }
86}