multiversx_sdk_dapp/
gateway_dapp_proxy.rs

1use gloo_net::http::Request;
2use multiversx_sdk::gateway::{GatewayAsyncService, GatewayRequest, GatewayRequestType};
3
4/// Allows communication with the MultiversX gateway API.
5#[derive(Clone, Debug)]
6pub struct GatewayDappProxy {
7    pub(crate) proxy_url: String,
8}
9
10impl GatewayDappProxy {
11    pub fn new(proxy_url: String) -> Self {
12        Self { proxy_url }
13    }
14
15    /// Performs a request to the gateway.
16    /// Can be either GET or POST, depending on the argument.
17    pub async fn http_request<G>(&self, request: G) -> anyhow::Result<G::Result>
18    where
19        G: GatewayRequest,
20    {
21        let url = format!("{}/{}", self.proxy_url, request.get_endpoint());
22        let request_builder = match request.request_type() {
23            GatewayRequestType::Get => Request::get(&url),
24            GatewayRequestType::Post => Request::post(&url),
25        };
26
27        let response = if let Some(payload) = request.get_payload() {
28            request_builder.json(&payload)?.send().await?
29        } else {
30            request_builder.send().await?
31        };
32
33        let decoded = response.json::<G::DecodedJson>().await?;
34
35        request.process_json(decoded)
36    }
37}
38
39impl GatewayAsyncService for GatewayDappProxy {
40    type Instant = f64;
41
42    fn from_uri(uri: &str) -> Self {
43        Self::new(uri.to_owned())
44    }
45
46    fn request<G>(&self, request: G) -> impl std::future::Future<Output = anyhow::Result<G::Result>>
47    where
48        G: multiversx_sdk::gateway::GatewayRequest,
49    {
50        self.http_request(request)
51    }
52
53    fn sleep(&self, millis: u64) -> impl std::future::Future<Output = ()> {
54        sleep(millis as f32 * 1000f32)
55    }
56
57    fn now(&self) -> Self::Instant {
58        js_sys::Date::now()
59    }
60
61    fn elapsed_seconds(&self, instant: &Self::Instant) -> f32 {
62        ((js_sys::Date::now() - instant) / 1000.0) as f32
63    }
64}
65
66async fn sleep(seconds: f32) {
67    let promise = js_sys::Promise::new(&mut |resolve, _| {
68        if let Some(win) = web_sys::window() {
69            let _ = win
70                .set_timeout_with_callback_and_timeout_and_arguments_0(
71                    &resolve,
72                    (seconds * 1000.0) as i32,
73                )
74                .expect("Failed to set timeout");
75        } else {
76            panic!("No global window object available");
77        }
78    });
79    wasm_bindgen_futures::JsFuture::from(promise).await.unwrap();
80}