multiversx_sdk_http/
gateway_http_proxy.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
mod http_account;
mod http_block;
mod http_chain_simulator;
mod http_network;
mod http_tx;

use std::time::Duration;

use multiversx_sdk::gateway::{GatewayAsyncService, GatewayRequest};

/// Allows communication with the MultiversX gateway API.
#[derive(Clone, Debug)]
pub struct GatewayHttpProxy {
    pub(crate) proxy_uri: String,
    pub(crate) client: reqwest::Client,
}

impl GatewayHttpProxy {
    pub fn new(proxy_uri: String) -> Self {
        Self {
            proxy_uri,
            client: reqwest::Client::new(),
        }
    }

    /// Performs a request to the gateway.
    /// Can be either GET or POST, depending on the argument.
    pub async fn http_request<G>(&self, request: G) -> anyhow::Result<G::Result>
    where
        G: GatewayRequest,
    {
        let url = format!("{}/{}", self.proxy_uri, request.get_endpoint());
        let mut request_builder;
        match request.request_type() {
            multiversx_sdk::gateway::GatewayRequestType::Get => {
                request_builder = self.client.get(url);
            },
            multiversx_sdk::gateway::GatewayRequestType::Post => {
                request_builder = self.client.post(url);
            },
        }

        if let Some(payload) = request.get_payload() {
            request_builder = request_builder.json(&payload);
        }

        let decoded = request_builder
            .send()
            .await?
            .json::<G::DecodedJson>()
            .await?;

        request.process_json(decoded)
    }
}

impl GatewayAsyncService for GatewayHttpProxy {
    type Instant = std::time::Instant;

    fn from_uri(uri: &str) -> Self {
        Self::new(uri.to_owned())
    }

    fn request<G>(&self, request: G) -> impl std::future::Future<Output = anyhow::Result<G::Result>>
    where
        G: multiversx_sdk::gateway::GatewayRequest,
    {
        self.http_request(request)
    }

    fn sleep(&self, millis: u64) -> impl std::future::Future<Output = ()> {
        tokio::time::sleep(Duration::from_millis(millis))
    }

    fn now(&self) -> Self::Instant {
        std::time::Instant::now()
    }

    fn elapsed_seconds(&self, instant: &Self::Instant) -> f32 {
        instant.elapsed().as_secs_f32()
    }
}