diff --git a/contracts/examples/ping-pong-egld/dapp/src/interactor.rs b/contracts/examples/ping-pong-egld/dapp/src/interactor.rs index 5e2479e303..a09df58828 100644 --- a/contracts/examples/ping-pong-egld/dapp/src/interactor.rs +++ b/contracts/examples/ping-pong-egld/dapp/src/interactor.rs @@ -2,7 +2,7 @@ use imports::{Address, Bech32Address, BytesValue}; use multiversx_sc_snippets_dapp::*; use serde::{Deserialize, Serialize}; -const GATEWAY: &str = sdk::gateway::DEVNET_GATEWAY; +const GATEWAY: &str = sdk::core::gateway::DEVNET_GATEWAY; const CONTRACT_ADDRESS: &str = "erd1qqqqqqqqqqqqqpgq6tqvj5f59xrgxwrtwy30elgpu7l4zrv6d8ssnjdwxq"; const PING_PONG_CODE: &[u8] = include_bytes!("../ping-pong-egld.wasm"); diff --git a/framework/snippets-dapp/src/account_tool.rs b/framework/snippets-dapp/src/account_tool.rs index b36df31183..d0c12f834f 100644 --- a/framework/snippets-dapp/src/account_tool.rs +++ b/framework/snippets-dapp/src/account_tool.rs @@ -5,7 +5,7 @@ use multiversx_sc_scenario::{ }; use multiversx_sdk_wbg::{ data::{esdt::EsdtBalance, sdk_address::SdkAddress}, - gateway::GatewayProxy, + GatewayDappProxy, }; use std::collections::{BTreeMap, HashMap}; @@ -17,7 +17,7 @@ pub async fn print_account_as_scenario_set_state( api_string: String, address_bech32_string: String, ) { - let api = GatewayProxy::new(api_string); + let api = GatewayDappProxy::new(api_string); let address = Bech32Address::from_bech32_string(address_bech32_string); let set_state = retrieve_account_as_scenario_set_state(&api, &address).await; let scenario = build_scenario(set_state); @@ -34,7 +34,7 @@ fn build_scenario(set_state: SetStateStep) -> Scenario { } pub async fn retrieve_account_as_scenario_set_state( - api: &GatewayProxy, + api: &GatewayDappProxy, address: &Bech32Address, ) -> SetStateStep { let sdk_address = SdkAddress::from_bech32_string(address.to_bech32_str()).unwrap(); diff --git a/framework/snippets-dapp/src/interactor.rs b/framework/snippets-dapp/src/interactor.rs index d8edb7fdd8..7fba364dc3 100644 --- a/framework/snippets-dapp/src/interactor.rs +++ b/framework/snippets-dapp/src/interactor.rs @@ -7,8 +7,8 @@ use multiversx_sc_scenario::{ }; use multiversx_sdk_wbg::{ data::{network_config::NetworkConfig, sdk_address::SdkAddress as ErdrsAddress}, - gateway::GatewayProxy, wallet::Wallet, + GatewayDappProxy, }; use std::{ collections::HashMap, @@ -22,7 +22,7 @@ use crate::{account_tool::retrieve_account_as_scenario_set_state, Sender}; pub const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json"; pub struct Interactor { - pub proxy: GatewayProxy, + pub proxy: GatewayDappProxy, pub network_config: NetworkConfig, pub sender_map: HashMap, @@ -51,7 +51,7 @@ async fn sleep(seconds: u32) { impl Interactor { pub async fn new(gateway_url: &str) -> Self { - let proxy = GatewayProxy::new(gateway_url.to_string()); + let proxy = GatewayDappProxy::new(gateway_url.to_string()); let network_config = proxy.get_network_config().await.unwrap(); Self { proxy, diff --git a/sdk/core/src/gateway.rs b/sdk/core/src/gateway.rs index b158a0ef2b..565abfe6e0 100644 --- a/sdk/core/src/gateway.rs +++ b/sdk/core/src/gateway.rs @@ -68,12 +68,12 @@ pub enum GatewayRequestType { } /// Models requests to the gateway. -pub trait GatewayRequest: Send { +pub trait GatewayRequest { type Payload: serde::ser::Serialize + ?Sized; type DecodedJson: serde::de::DeserializeOwned; - type Result: Send; + type Result; fn request_type(&self) -> GatewayRequestType; @@ -86,18 +86,18 @@ pub trait GatewayRequest: Send { fn process_json(&self, decoded: Self::DecodedJson) -> anyhow::Result; } -pub trait GatewayAsyncService: Send { +pub trait GatewayAsyncService { /// Keeps track of elapsed time. type Instant; fn request( &self, request: G, - ) -> impl std::future::Future> + Send + ) -> impl std::future::Future> where G: GatewayRequest; - fn sleep(&self, millis: u64) -> impl std::future::Future + Send; + fn sleep(&self, millis: u64) -> impl std::future::Future; fn now(&self) -> Self::Instant; diff --git a/sdk/http/src/gateway_http_proxy.rs b/sdk/http/src/gateway_http_proxy.rs index 1417db3db5..652012876b 100644 --- a/sdk/http/src/gateway_http_proxy.rs +++ b/sdk/http/src/gateway_http_proxy.rs @@ -60,14 +60,14 @@ impl GatewayAsyncService for GatewayHttpProxy { fn request( &self, request: G, - ) -> impl std::future::Future> + Send + ) -> impl std::future::Future> where G: multiversx_sdk::gateway::GatewayRequest, { self.http_request(request) } - fn sleep(&self, millis: u64) -> impl std::future::Future + Send { + fn sleep(&self, millis: u64) -> impl std::future::Future { tokio::time::sleep(Duration::from_millis(millis)) } diff --git a/sdk/wbg/src/gateway.rs b/sdk/wbg/src/gateway.rs deleted file mode 100644 index 5700d20103..0000000000 --- a/sdk/wbg/src/gateway.rs +++ /dev/null @@ -1,18 +0,0 @@ -mod gateway_account; -mod gateway_block; -mod gateway_network; -mod gateway_proxy; -mod gateway_tx; -mod gateway_tx_retrieve; - -pub use gateway_proxy::GatewayProxy; - -pub const MAINNET_GATEWAY: &str = "https://gateway.multiversx.com"; -pub const TESTNET_GATEWAY: &str = "https://testnet-gateway.multiversx.com"; -pub const DEVNET_GATEWAY: &str = "https://devnet-gateway.multiversx.com"; -pub const SIMULATOR_GATEWAY: &str = "http://localhost:8085"; - -// MetachainShardId will be used to identify a shard ID as metachain -pub const METACHAIN_SHARD_ID: u32 = 0xFFFFFFFF; - -pub const DEFAULT_USE_CHAIN_SIMULATOR: bool = false; diff --git a/sdk/wbg/src/gateway/gateway_proxy.rs b/sdk/wbg/src/gateway/gateway_proxy.rs deleted file mode 100644 index 62149f2eae..0000000000 --- a/sdk/wbg/src/gateway/gateway_proxy.rs +++ /dev/null @@ -1,15 +0,0 @@ -/// Allows communication with the MultiversX gateway API. -#[derive(Clone, Debug)] -pub struct GatewayProxy { - pub(crate) proxy_url: String, -} - -impl GatewayProxy { - pub fn new(proxy_url: String) -> Self { - Self { proxy_url } - } - - pub(crate) fn get_endpoint(&self, endpoint: &str) -> String { - format!("{}/{}", self.proxy_url, endpoint) - } -} diff --git a/sdk/wbg/src/gateway_dapp_proxy.rs b/sdk/wbg/src/gateway_dapp_proxy.rs new file mode 100644 index 0000000000..8b04e3aa95 --- /dev/null +++ b/sdk/wbg/src/gateway_dapp_proxy.rs @@ -0,0 +1,89 @@ +use gloo_net::http::Request; +use multiversx_sdk::gateway::{GatewayAsyncService, GatewayRequest, GatewayRequestType}; + +mod gateway_account; +mod gateway_block; +mod gateway_network; +mod gateway_tx; +mod gateway_tx_retrieve; + +// MetachainShardId will be used to identify a shard ID as metachain +pub const METACHAIN_SHARD_ID: u32 = 0xFFFFFFFF; + +/// Allows communication with the MultiversX gateway API. +#[derive(Clone, Debug)] +pub struct GatewayDappProxy { + pub(crate) proxy_url: String, +} + +impl GatewayDappProxy { + pub fn new(proxy_url: String) -> Self { + Self { proxy_url } + } + + pub(crate) fn get_endpoint(&self, endpoint: &str) -> String { + format!("{}/{}", self.proxy_url, endpoint) + } + + /// Performs a request to the gateway. + /// Can be either GET or POST, depending on the argument. + pub async fn http_request(&self, request: G) -> anyhow::Result + where + G: GatewayRequest, + { + let url = format!("{}/{}", self.proxy_url, request.get_endpoint()); + let request_builder = match request.request_type() { + GatewayRequestType::Get => Request::get(&url), + GatewayRequestType::Post => Request::post(&url), + }; + + let response = if let Some(payload) = request.get_payload() { + request_builder.json(&payload)?.send().await? + } else { + request_builder.send().await? + }; + + let decoded = response.json::().await?; + + request.process_json(decoded) + } +} + +impl GatewayAsyncService for GatewayDappProxy { + type Instant = f64; + + fn request(&self, request: G) -> impl std::future::Future> + where + G: multiversx_sdk::gateway::GatewayRequest, + { + self.http_request(request) + } + + fn sleep(&self, millis: u64) -> impl std::future::Future { + sleep(millis as f32 * 1000f32) + } + + fn now(&self) -> Self::Instant { + js_sys::Date::now() + } + + fn elapsed_seconds(&self, instant: &Self::Instant) -> f32 { + ((js_sys::Date::now() - instant) / 1000.0) as f32 + } +} + +async fn sleep(seconds: f32) { + let promise = js_sys::Promise::new(&mut |resolve, _| { + if let Some(win) = web_sys::window() { + let _ = win + .set_timeout_with_callback_and_timeout_and_arguments_0( + &resolve, + (seconds * 1000.0) as i32, + ) + .expect("Failed to set timeout"); + } else { + panic!("No global window object available"); + } + }); + wasm_bindgen_futures::JsFuture::from(promise).await.unwrap(); +} diff --git a/sdk/wbg/src/gateway/gateway_account.rs b/sdk/wbg/src/gateway_dapp_proxy/gateway_account.rs similarity index 98% rename from sdk/wbg/src/gateway/gateway_account.rs rename to sdk/wbg/src/gateway_dapp_proxy/gateway_account.rs index 8742f50f3e..835c9e764d 100644 --- a/sdk/wbg/src/gateway/gateway_account.rs +++ b/sdk/wbg/src/gateway_dapp_proxy/gateway_account.rs @@ -8,12 +8,12 @@ use multiversx_sdk::data::{ }; use std::collections::HashMap; -use super::GatewayProxy; +use super::GatewayDappProxy; const ACCOUNT_ENDPOINT: &str = "address/"; const KEYS_ENDPOINT: &str = "/keys/"; -impl GatewayProxy { +impl GatewayDappProxy { // get_account retrieves an account info from the network (nonce, balance) pub async fn get_account(&self, address: &SdkAddress) -> Result { if !address.is_valid() { diff --git a/sdk/wbg/src/gateway/gateway_block.rs b/sdk/wbg/src/gateway_dapp_proxy/gateway_block.rs similarity index 97% rename from sdk/wbg/src/gateway/gateway_block.rs rename to sdk/wbg/src/gateway_dapp_proxy/gateway_block.rs index 291bccc249..488152299b 100644 --- a/sdk/wbg/src/gateway/gateway_block.rs +++ b/sdk/wbg/src/gateway_dapp_proxy/gateway_block.rs @@ -5,14 +5,14 @@ use multiversx_sdk::data::{ network_status::NetworkStatusResponse, }; -use super::GatewayProxy; +use super::GatewayDappProxy; use super::METACHAIN_SHARD_ID; const GET_HYPER_BLOCK_BY_NONCE_ENDPOINT: &str = "hyperblock/by-nonce/"; const GET_HYPER_BLOCK_BY_HASH_ENDPOINT: &str = "hyperblock/by-hash/"; const GET_NETWORK_STATUS_ENDPOINT: &str = "network/status"; -impl GatewayProxy { +impl GatewayDappProxy { async fn get_hyper_block(&self, endpoint: &str) -> Result { let endpoint = self.get_endpoint(endpoint); let resp = Request::get(&endpoint) diff --git a/sdk/wbg/src/gateway/gateway_network.rs b/sdk/wbg/src/gateway_dapp_proxy/gateway_network.rs similarity index 97% rename from sdk/wbg/src/gateway/gateway_network.rs rename to sdk/wbg/src/gateway_dapp_proxy/gateway_network.rs index 30043c5d4c..7c4f20aea4 100644 --- a/sdk/wbg/src/gateway/gateway_network.rs +++ b/sdk/wbg/src/gateway_dapp_proxy/gateway_network.rs @@ -6,13 +6,13 @@ use multiversx_sdk::data::{ network_status::{NetworkStatus, NetworkStatusResponse}, }; -use super::GatewayProxy; +use super::GatewayDappProxy; const NETWORK_CONFIG_ENDPOINT: &str = "network/config"; const NETWORK_ECONOMICS_ENDPOINT: &str = "network/economics"; const NETWORK_STATUS_ENDPOINT: &str = "network/status"; -impl GatewayProxy { +impl GatewayDappProxy { // get_network_config retrieves the network configuration from the proxy pub async fn get_network_config(&self) -> Result { let endpoint = self.get_endpoint(NETWORK_CONFIG_ENDPOINT); diff --git a/sdk/wbg/src/gateway/gateway_tx.rs b/sdk/wbg/src/gateway_dapp_proxy/gateway_tx.rs similarity index 99% rename from sdk/wbg/src/gateway/gateway_tx.rs rename to sdk/wbg/src/gateway_dapp_proxy/gateway_tx.rs index 25573dd827..ac810acb87 100644 --- a/sdk/wbg/src/gateway/gateway_tx.rs +++ b/sdk/wbg/src/gateway_dapp_proxy/gateway_tx.rs @@ -12,7 +12,7 @@ use multiversx_sdk::data::{ vm::{ResponseVmValue, VMQueryInput, VmValuesResponseData}, }; -use super::GatewayProxy; +use super::GatewayDappProxy; const COST_TRANSACTION_ENDPOINT: &str = "transaction/cost"; const SEND_TRANSACTION_ENDPOINT: &str = "transaction/send"; @@ -21,7 +21,7 @@ const GET_TRANSACTION_INFO_ENDPOINT: &str = "transaction/"; const WITH_RESULTS_QUERY_PARAM: &str = "?withResults=true"; const VM_VALUES_ENDPOINT: &str = "vm-values/query"; -impl GatewayProxy { +impl GatewayDappProxy { // request_transaction_cost retrieves how many gas a transaction will consume pub async fn request_transaction_cost(&self, tx: &Transaction) -> Result { let endpoint = self.get_endpoint(COST_TRANSACTION_ENDPOINT); diff --git a/sdk/wbg/src/gateway/gateway_tx_retrieve.rs b/sdk/wbg/src/gateway_dapp_proxy/gateway_tx_retrieve.rs similarity index 98% rename from sdk/wbg/src/gateway/gateway_tx_retrieve.rs rename to sdk/wbg/src/gateway_dapp_proxy/gateway_tx_retrieve.rs index 0172f0f6ad..662f5f2b2c 100644 --- a/sdk/wbg/src/gateway/gateway_tx_retrieve.rs +++ b/sdk/wbg/src/gateway_dapp_proxy/gateway_tx_retrieve.rs @@ -4,7 +4,7 @@ use multiversx_sdk::data::transaction::TransactionOnNetwork; use wasm_bindgen_futures::JsFuture; use web_sys::window; -use super::GatewayProxy; +use super::GatewayDappProxy; const INITIAL_BACKOFF_DELAY: f32 = 1.4; // seconds const MAX_RETRIES: usize = 8; @@ -26,7 +26,7 @@ async fn sleep(seconds: f32) { JsFuture::from(promise).await.unwrap(); } -impl GatewayProxy { +impl GatewayDappProxy { /// Retrieves a transaction from the network. pub async fn retrieve_tx_on_network(&self, tx_hash: String) -> TransactionOnNetwork { let mut retries = 0; diff --git a/sdk/wbg/src/lib.rs b/sdk/wbg/src/lib.rs index 4a23fc81c2..4ca9648fd7 100644 --- a/sdk/wbg/src/lib.rs +++ b/sdk/wbg/src/lib.rs @@ -1,4 +1,5 @@ -pub mod gateway; +mod gateway_dapp_proxy; +pub use gateway_dapp_proxy::GatewayDappProxy; pub use multiversx_sdk as core;