diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml index c8feaf76..84b268c5 100644 --- a/.github/workflows/unit_test.yml +++ b/.github/workflows/unit_test.yml @@ -19,26 +19,57 @@ jobs: with: toolchain: stable - uses: actions-rs/cargo@v1 + name: Build with default features with: command: build - args: --release --all-features + args: --release - uses: actions-rs/cargo@v1 + name: Build with no default features with: command: build - args: --release --no-default-features --features core,models,websocket-std + args: --release --no-default-features - uses: actions-rs/cargo@v1 + name: Build for no_std with: - command: test - args: --all-features + command: build + args: --release --no-default-features --features embassy-rt,core,wallet,models,helpers,websocket,json-rpc - uses: actions-rs/cargo@v1 + name: Build only core with: - command: test - args: --no-default-features --features core,models,websocket-std + command: build + args: --release --no-default-features --features core + - uses: actions-rs/cargo@v1 + name: Build only wallet + with: + command: build + args: --release --no-default-features --features wallet + - uses: actions-rs/cargo@v1 + name: Build only models + with: + command: build + args: --release --no-default-features --features models + - uses: actions-rs/cargo@v1 + name: Build only helpers + with: + command: build + args: --release --no-default-features --features helpers,tokio-rt + - uses: actions-rs/cargo@v1 + name: Build only websocket + with: + command: build + args: --release --no-default-features --features websocket + - uses: actions-rs/cargo@v1 + name: Build only core + with: + command: build + args: --release --no-default-features --features json-rpc - uses: actions-rs/cargo@v1 + name: Test with default features with: command: test - args: --no-default-features --features std,models,websocket,websocket-codec + args: --release - uses: actions-rs/cargo@v1 + name: Test for no_std with: command: test - args: --no-default-features --features std,websocket-std,helpers + args: --release --no-default-features --features embassy-rt,core,wallet,models,helpers,websocket,json-rpc diff --git a/Cargo.toml b/Cargo.toml index 0a9c4cc6..6f46ef3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,6 @@ tag-name = "{{version}}" [lib] name = "xrpl" crate-type = ["lib"] -proc-macro = true [dependencies] lazy_static = "1.4.0" @@ -62,37 +61,29 @@ fnv = { version = "1.0.7", default-features = false } derive-new = { version = "0.6.0", default-features = false } thiserror-no-std = "2.0.2" anyhow = { version = "1.0.69", default-features = false } +embassy-sync = "0.6.0" # networking -url = { version = "2.2.2", default-features = false, optional = true } -# websocket -embassy-sync = { version = "0.6.0", optional = true } +url = { version = "2.2.2", default-features = false } embedded-io-async = { version = "0.6.1", optional = true } -embedded-websocket = { version = "0.9.3", default-features = false, optional = true } futures = { version = "0.3.30", optional = true } -rand_core = { version = "0.6.4", default-features = false } -# websocket-codec -bytes = { version = "1.7.1", default-features = false, optional = true } -tokio-util = { version = "0.7.11", features = ["codec"], optional = true } -# websocket-std -embassy-futures = { version = "0.1.1", optional = true } -tokio = { version = "1.0", default-features = false, features = [ - "net", -], optional = true } +tokio = { version = "1.0", optional = true } +embassy-time = { version = "0.3.2", optional = true } +embedded-websocket = { git = "https://github.com/LimpidCrypto/embedded-websocket", branch = "embedded-io-async", optional = true, default-features = false, features = [ + "embedded-io-async", +] } +reqwless = { version = "0.12.1", optional = true } +reqwest = { version = "0.12.7", optional = true, features = ["json"] } tokio-tungstenite = { version = "0.23.1", optional = true, features = [ "native-tls", ] } +embassy-futures = { version = "0.1.1", optional = true } embedded-nal-async = { version = "0.7.1", optional = true } -# json-rpc -reqwless = { version = "0.12.1", optional = true } -# json-rpc-std -reqwest = { version = "0.12.5", features = ["json"], optional = true } -embassy-time = { version = "0.3.2", optional = true } [dev-dependencies] criterion = "0.5.1" tokio = { version = "1.0", features = ["full"] } -tokio-util = { version = "0.7.11", features = ["codec"] } +embedded-io-adapters = { version = "0.6.1", features = ["tokio-1"] } [[bench]] name = "benchmarks" @@ -101,63 +92,56 @@ harness = false [features] default = [ "std", + "tokio-rt", "core", "wallet", "models", "utils", "helpers", - "websocket-std", + "websocket", + "json-rpc", +] +models = [ + "transaction-models", + "request-models", + "ledger-models", + "result-models", ] -models = ["core", "transactions", "requests", "ledger", "results"] -transactions = ["core", "amounts", "currencies"] -requests = ["core", "amounts", "currencies"] -results = ["core", "amounts", "currencies"] -ledger = ["core", "amounts", "currencies"] +transaction-models = ["core"] +request-models = [] +result-models = ["request-models", "ledger-models"] +ledger-models = [] helpers = [ "account-helpers", "ledger-helpers", "transaction-helpers", "wallet-helpers", ] -account-helpers = ["amounts", "currencies", "requests", "results"] -ledger-helpers = ["amounts", "currencies", "requests", "results"] -wallet-helpers = ["requests", "results"] +account-helpers = ["core", "request-models", "result-models"] +ledger-helpers = ["request-models", "result-models"] +wallet-helpers = ["wallet", "request-models", "result-models"] transaction-helpers = [ "wallet", - "amounts", - "currencies", - "requests", - "results", - "transactions", - "ledger", - "embassy-time", + "account-helpers", + "ledger-helpers", + "request-models", + "result-models", + "transaction-models", + "ledger-models", ] -amounts = ["core"] -currencies = ["core"] -json-rpc = ["url", "reqwless", "embassy-sync", "embedded-nal-async"] -json-rpc-std = ["url", "reqwest", "embassy-sync", "tokio"] wallet = ["core"] +json-rpc = ["reqwless", "embedded-nal-async"] websocket = [ - "url", + "request-models", + "result-models", "futures", - "embedded-websocket", "embedded-io-async", - "embassy-sync", -] -websocket-codec = ["bytes", "tokio-util"] -websocket-std = [ - "url", - "futures", - "tokio", - "tokio-tungstenite", "embassy-futures", - "embassy-sync", + "embedded-websocket", ] core = ["utils"] utils = [] std = [ - "embedded-websocket/std", - "futures/std", "rand/std", "regex/std", "chrono/std", @@ -168,6 +152,12 @@ std = [ "serde/std", "indexmap/std", "secp256k1/std", - "embassy-time/std", + "embedded-websocket/std", + "reqwest", + "tokio", + "tokio-tungstenite", + "futures/std", ] -embassy-time = ["dep:embassy-time"] +# runtimes +tokio-rt = ["tokio"] +embassy-rt = ["embassy-time"] diff --git a/src/asynch/account/mod.rs b/src/asynch/account/mod.rs index 0a629024..0ebc5cf9 100644 --- a/src/asynch/account/mod.rs +++ b/src/asynch/account/mod.rs @@ -4,10 +4,9 @@ use anyhow::Result; use crate::{ core::addresscodec::{is_valid_xaddress, xaddress_to_classic_address}, models::{ - amount::XRPAmount, - ledger::AccountRoot, - requests::{AccountInfo, AccountTx}, - results, + ledger::objects::AccountRoot, + requests::{account_info::AccountInfo, account_tx::AccountTx}, + results, XRPAmount, }, Err, }; @@ -82,14 +81,14 @@ where let account_info = client.request(request).await?; Ok(account_info - .try_into_result::>()? + .try_into_result::>()? .account_data) } pub async fn get_latest_transaction<'a: 'b, 'b, C>( mut address: Cow<'a, str>, client: &C, -) -> Result> +) -> Result> where C: AsyncClient, { @@ -112,5 +111,5 @@ where None, ); let response = client.request(account_tx.into()).await?; - response.try_into_result::>() + response.try_into_result::>() } diff --git a/src/asynch/clients/async_client.rs b/src/asynch/clients/async_client.rs index af7e8eaf..6a0433a8 100644 --- a/src/asynch/clients/async_client.rs +++ b/src/asynch/clients/async_client.rs @@ -1,7 +1,7 @@ use super::{client::Client, CommonFields}; use crate::models::{ - requests::{ServerState, XRPLRequest}, - results::{ServerState as ServerStateResult, XRPLResponse}, + requests::{server_state::ServerState, XRPLRequest}, + results::{server_state::ServerState as ServerStateResult, XRPLResponse}, }; use anyhow::Result; diff --git a/src/asynch/clients/client.rs b/src/asynch/clients/client.rs index 7a678ae2..060fb22d 100644 --- a/src/asynch/clients/client.rs +++ b/src/asynch/clients/client.rs @@ -2,25 +2,34 @@ use crate::models::{ requests::{Request, XRPLRequest}, results::XRPLResponse, }; -#[cfg(feature = "std")] -use crate::utils::get_random_id; -use alloc::borrow::{Cow, ToOwned}; +use alloc::{ + borrow::ToOwned, + string::{String, ToString}, +}; use anyhow::Result; +use rand::Rng; use url::Url; +/// Generate a random id. +pub fn get_random_id(rng: &mut T) -> String { + let id: u32 = rng.gen(); + id.to_string() +} + #[allow(async_fn_in_trait)] pub trait Client { async fn request_impl<'a: 'b, 'b>(&self, request: XRPLRequest<'a>) -> Result>; fn get_host(&self) -> Url; - fn set_request_id(&self, request: &mut XRPLRequest<'_>) -> () { + fn set_request_id(&self, request: &mut XRPLRequest<'_>) { let common_fields = request.get_common_fields_mut(); common_fields.id = match &common_fields.id { Some(id) => Some(id.to_owned()), None => { #[cfg(feature = "std")] { + use alloc::borrow::Cow; let mut rng = rand::thread_rng(); Some(Cow::Owned(get_random_id(&mut rng))) } diff --git a/src/asynch/clients/json_rpc/exceptions.rs b/src/asynch/clients/json_rpc/exceptions.rs index 21fc86f5..bc10b2d7 100644 --- a/src/asynch/clients/json_rpc/exceptions.rs +++ b/src/asynch/clients/json_rpc/exceptions.rs @@ -1,12 +1,10 @@ -use reqwest::Response; use thiserror_no_std::Error; #[derive(Debug, Error)] pub enum XRPLJsonRpcException { - #[cfg(feature = "json-rpc")] #[error("Reqwless error")] ReqwlessError, - #[cfg(feature = "json-rpc-std")] + #[cfg(feature = "std")] #[error("Request error: {0:?}")] - RequestError(Response), + RequestError(reqwest::Response), } diff --git a/src/asynch/clients/json_rpc/mod.rs b/src/asynch/clients/json_rpc/mod.rs index dd1a2623..db0cb844 100644 --- a/src/asynch/clients/json_rpc/mod.rs +++ b/src/asynch/clients/json_rpc/mod.rs @@ -2,31 +2,14 @@ use alloc::{string::ToString, vec}; use anyhow::Result; use serde::Serialize; use serde_json::{Map, Value}; -use url::Url; -use crate::{ - asynch::wallet::get_faucet_url, - models::{requests::FundFaucet, results::XRPLResponse}, - Err, -}; +use crate::{models::results::XRPLResponse, Err}; mod exceptions; pub use exceptions::XRPLJsonRpcException; use super::client::Client; -#[allow(async_fn_in_trait)] -pub trait XRPLFaucet: Client { - fn get_faucet_url(&self, url: Option) -> Result - where - Self: Sized + Client, - { - get_faucet_url(self, url) - } - - async fn request_funding(&self, url: Option, request: FundFaucet<'_>) -> Result<()>; -} - /// Renames the requests field `command` to `method` for JSON-RPC. fn request_to_json_rpc(request: &impl Serialize) -> Result { let mut json_rpc_request = Map::new(); @@ -48,9 +31,12 @@ fn request_to_json_rpc(request: &impl Serialize) -> Result { Ok(Value::Object(json_rpc_request)) } -#[cfg(feature = "json-rpc-std")] +#[cfg(all(feature = "json-rpc", feature = "std"))] mod _std { - use crate::models::requests::{FundFaucet, XRPLRequest}; + use crate::{ + asynch::clients::XRPLFaucet, + models::requests::{FundFaucet, XRPLRequest}, + }; use super::*; use alloc::string::ToString; @@ -101,7 +87,7 @@ mod _std { let client = HttpClient::new(); let request_json_rpc = serde_json::to_value(&request).unwrap(); let response = client - .post(&faucet_url.to_string()) + .post(faucet_url.to_string()) .json(&request_json_rpc) .send() .await; @@ -122,9 +108,12 @@ mod _std { } } -#[cfg(feature = "json-rpc")] +#[cfg(all(feature = "json-rpc", not(feature = "std")))] mod _no_std { - use crate::{asynch::clients::SingleExecutorMutex, models::requests::XRPLRequest}; + use crate::{ + asynch::clients::{SingleExecutorMutex, XRPLFaucet}, + models::requests::{FundFaucet, XRPLRequest}, + }; use super::*; use alloc::sync::Arc; @@ -153,7 +142,7 @@ mod _no_std { T: TcpConnect + 'a, D: Dns + 'a, { - pub fn new(url: Url, tcp: &'a T, dns: &'a D) -> Self { + pub fn connect(url: Url, tcp: &'a T, dns: &'a D) -> Self { Self { url, client: Arc::new(Mutex::new(HttpClient::new(tcp, dns))), @@ -187,7 +176,7 @@ mod _no_std { Ok(client) => { if let Err(_error) = client .body(request_buf) - .content_type(ContentType::TextPlain) + .content_type(ContentType::ApplicationJson) .send(&mut rx_buffer) .await { @@ -209,9 +198,52 @@ mod _no_std { self.url.clone() } } + + impl<'a, const BUF: usize, T, D, M> XRPLFaucet for AsyncJsonRpcClient<'a, BUF, T, D, M> + where + M: RawMutex, + T: TcpConnect + 'a, + D: Dns + 'a, + { + async fn request_funding(&self, url: Option, request: FundFaucet<'_>) -> Result<()> { + let faucet_url = self.get_faucet_url(url)?; + let request_json_rpc = serde_json::to_value(&request).unwrap(); + let request_string = request_json_rpc.to_string(); + let request_buf = request_string.as_bytes(); + let mut rx_buffer = [0; BUF]; + let mut client = self.client.lock().await; + let response = match client.request(Method::POST, faucet_url.as_str()).await { + Ok(client) => { + if let Err(_error) = client + .body(request_buf) + .content_type(ContentType::ApplicationJson) + .send(&mut rx_buffer) + .await + { + Err!(XRPLJsonRpcException::ReqwlessError) + } else { + if let Ok(response) = serde_json::from_slice::>(&rx_buffer) + { + if response.is_success() { + Ok(()) + } else { + todo!() + // Err!(XRPLJsonRpcException::RequestError()) + } + } else { + Err!(XRPLJsonRpcException::ReqwlessError) + } + } + } + Err(_error) => Err!(XRPLJsonRpcException::ReqwlessError), + }; + + response + } + } } -#[cfg(all(feature = "json-rpc", not(feature = "json-rpc-std")))] +#[cfg(all(feature = "json-rpc", not(feature = "std")))] pub use _no_std::AsyncJsonRpcClient; -#[cfg(all(feature = "json-rpc-std", not(feature = "json-rpc")))] +#[cfg(all(feature = "json-rpc", feature = "std"))] pub use _std::AsyncJsonRpcClient; diff --git a/src/asynch/clients/mod.rs b/src/asynch/clients/mod.rs index 0843eb30..fdf420b1 100644 --- a/src/asynch/clients/mod.rs +++ b/src/asynch/clients/mod.rs @@ -1,23 +1,41 @@ pub mod async_client; pub mod client; -#[cfg(any(feature = "json-rpc-std", feature = "json-rpc"))] -pub mod json_rpc; -#[cfg(any(feature = "websocket-std", feature = "websocket"))] -pub mod websocket; +#[cfg(feature = "json-rpc")] +mod json_rpc; +#[cfg(feature = "websocket")] +mod websocket; use alloc::borrow::Cow; +use anyhow::Result; use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; -pub type MultiExecutorMutex = CriticalSectionRawMutex; -pub type SingleExecutorMutex = NoopRawMutex; +use serde::{Deserialize, Serialize}; +use url::Url; pub use async_client::*; pub use client::*; -#[cfg(any(feature = "json-rpc-std", feature = "json-rpc"))] +#[cfg(feature = "json-rpc")] pub use json_rpc::*; -use serde::{Deserialize, Serialize}; -#[cfg(any(feature = "websocket-std", feature = "websocket"))] +#[cfg(feature = "websocket")] pub use websocket::*; +pub type MultiExecutorMutex = CriticalSectionRawMutex; +pub type SingleExecutorMutex = NoopRawMutex; + +#[cfg(feature = "wallet-helpers")] +use crate::{asynch::wallet::get_faucet_url, models::requests::FundFaucet}; +#[allow(async_fn_in_trait)] +#[cfg(feature = "wallet-helpers")] +pub trait XRPLFaucet: Client { + fn get_faucet_url(&self, url: Option) -> Result + where + Self: Sized + Client, + { + get_faucet_url(self, url) + } + + async fn request_funding(&self, url: Option, request: FundFaucet<'_>) -> Result<()>; +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CommonFields<'a> { pub build_version: Option>, diff --git a/src/asynch/clients/websocket/_no_std.rs b/src/asynch/clients/websocket/_no_std.rs index 2f3926d2..8baef20c 100644 --- a/src/asynch/clients/websocket/_no_std.rs +++ b/src/asynch/clients/websocket/_no_std.rs @@ -1,8 +1,4 @@ -use core::{ - fmt::{Debug, Display}, - marker::PhantomData, - ops::{Deref, DerefMut}, -}; +use core::{marker::PhantomData, ops::DerefMut}; use alloc::{ string::{String, ToString}, @@ -16,12 +12,10 @@ use embedded_websocket::{ framer_async::{Framer, ReadResult}, Client, WebSocketClient, WebSocketOptions, WebSocketSendMessageType, }; -use futures::Sink; -use futures::Stream; -use rand_core::RngCore; +use rand::RngCore; use url::Url; -use super::{WebsocketClosed, WebsocketOpen}; +use super::{WebSocketClosed, WebSocketOpen}; use crate::{ asynch::clients::SingleExecutorMutex, models::requests::{Request, XRPLRequest}, @@ -37,18 +31,15 @@ use crate::{ use super::exceptions::XRPLWebsocketException; -pub struct AsyncWebsocketClient< +pub struct AsyncWebSocketClient< const BUF: usize, Tcp, - B, - E, Rng: RngCore, M = SingleExecutorMutex, - Status = WebsocketClosed, + Status = WebSocketClosed, > where M: RawMutex, - B: Deref + AsRef<[u8]>, - Tcp: Stream> + for<'a> Sink<&'a [u8], Error = E> + Unpin, + Tcp: Read + Write + Unpin, { tcp: Arc>, websocket: Arc>>, @@ -58,19 +49,18 @@ pub struct AsyncWebsocketClient< status: PhantomData, } -impl - AsyncWebsocketClient +impl AsyncWebSocketClient where M: RawMutex, - B: Deref + AsRef<[u8]>, - E: Debug + Display, - Tcp: Stream> + for<'a> Sink<&'a [u8], Error = E> + Unpin, + Tcp: Read + Write + Unpin, { pub async fn open( - rng: Rng, tcp: Tcp, url: Url, - ) -> Result> { + rng: Rng, + sub_protocols: Option<&[&str]>, + additional_headers: Option<&[&str]>, + ) -> Result> { // replace the scheme with http or https let scheme = match url.scheme() { "wss" => "https", @@ -89,15 +79,15 @@ where let path = url.path(); let host = match url.host_str() { Some(host) => host, - None => return Err!(XRPLWebsocketException::::Disconnected), + None => return Err!(XRPLWebsocketException::::Disconnected), }; let origin = scheme.to_string() + "://" + host + ":" + &port + path; let websocket_options = WebSocketOptions { path, host, origin: &origin, - sub_protocols: None, - additional_headers: None, + sub_protocols, + additional_headers, }; let websocket = Arc::new(Mutex::new(Framer::new(WebSocketClient::new_client(rng)))); let tcp = Arc::new(Mutex::new(tcp)); @@ -120,24 +110,30 @@ where } } - Ok(AsyncWebsocketClient { + Ok(AsyncWebSocketClient { tcp, websocket, tx_buffer: buffer, websocket_base: Arc::new(Mutex::new(WebsocketBase::new())), uri: url, - status: PhantomData::, + status: PhantomData::, }) } } -impl - AsyncWebsocketClient +impl ErrorType + for AsyncWebSocketClient where M: RawMutex, - B: Deref + AsRef<[u8]>, - E: Debug + Display, - Tcp: Stream> + for<'a> Sink<&'a [u8], Error = E> + Unpin, + Tcp: Read + Write + Unpin, +{ + type Error = XRPLWebsocketException<::Error>; +} + +impl AsyncWebSocketClient +where + M: RawMutex, + Tcp: Read + Write + Unpin, { async fn do_write(&self, buf: &[u8]) -> Result::Error> { let mut inner = self.websocket.lock().await; @@ -154,7 +150,7 @@ where .await { Ok(()) => Ok(buf.len()), - Err(error) => Err(XRPLWebsocketException::::from(error)), + Err(error) => Err(XRPLWebsocketException::from(error)), } } @@ -166,57 +162,40 @@ where Some(Ok(ReadResult::Binary(b))) => Ok(b.len()), Some(Ok(ReadResult::Ping(_))) => Ok(0), Some(Ok(ReadResult::Pong(_))) => Ok(0), - Some(Ok(ReadResult::Close(_))) => Err(XRPLWebsocketException::::Disconnected), - Some(Err(error)) => Err(XRPLWebsocketException::::from(error)), - None => Err(XRPLWebsocketException::::Disconnected), + Some(Ok(ReadResult::Close(_))) => Err(XRPLWebsocketException::Disconnected), + Some(Err(error)) => Err(XRPLWebsocketException::from(error)), + None => Err(XRPLWebsocketException::Disconnected), } } } -impl ErrorType - for AsyncWebsocketClient -where - M: RawMutex, - B: Deref + AsRef<[u8]>, - E: Debug + Display, - Tcp: Stream> + for<'a> Sink<&'a [u8], Error = E> + Unpin, -{ - type Error = XRPLWebsocketException; -} - -impl Write - for AsyncWebsocketClient +impl Write + for AsyncWebSocketClient where M: RawMutex, - B: Deref + AsRef<[u8]>, - E: Debug + Display, - Tcp: Stream> + for<'a> Sink<&'a [u8], Error = E> + Unpin, + Tcp: Read + Write + Unpin, { async fn write(&mut self, buf: &[u8]) -> Result { self.do_write(buf).await } } -impl Read - for AsyncWebsocketClient +impl Read + for AsyncWebSocketClient where M: RawMutex, - B: Deref + AsRef<[u8]>, - E: Debug + Display, - Tcp: Stream> + for<'a> Sink<&'a [u8], Error = E> + Unpin, + Tcp: Read + Write + Unpin, { async fn read(&mut self, buf: &mut [u8]) -> Result { self.do_read(buf).await } } -impl MessageHandler - for AsyncWebsocketClient +impl MessageHandler + for AsyncWebSocketClient where M: RawMutex, - B: Deref + AsRef<[u8]>, - E: Debug + Display, - Tcp: Stream> + for<'a> Sink<&'a [u8], Error = E> + Unpin, + Tcp: Read + Write + Unpin, { async fn setup_request_future(&mut self, id: String) { let mut websocket_base = self.websocket_base.lock().await; @@ -239,13 +218,11 @@ where } } -impl ClientTrait - for AsyncWebsocketClient +impl ClientTrait + for AsyncWebSocketClient where M: RawMutex, - B: Deref + AsRef<[u8]>, - E: Debug + Display, - Tcp: Stream> + for<'b> Sink<&'b [u8], Error = E> + Unpin, + Tcp: Read + Write + Unpin, { fn get_host(&self) -> Url { self.uri.clone() @@ -281,7 +258,9 @@ where } let message_str = match core::str::from_utf8(&rx_buffer[..u_size]) { Ok(response_str) => response_str, - Err(error) => return Err!(XRPLWebsocketException::::Utf8(error)), + Err(error) => { + return Err!(XRPLWebsocketException::::Utf8(error)) + } }; websocket_base .handle_message(message_str.to_string()) diff --git a/src/asynch/clients/websocket/_std.rs b/src/asynch/clients/websocket/_std.rs index ef05d70c..78688688 100644 --- a/src/asynch/clients/websocket/_std.rs +++ b/src/asynch/clients/websocket/_std.rs @@ -1,5 +1,5 @@ use super::exceptions::XRPLWebsocketException; -use super::{WebsocketClosed, WebsocketOpen}; +use super::{WebSocketClosed, WebSocketOpen}; use crate::asynch::clients::client::Client; use crate::asynch::clients::websocket::websocket_base::{MessageHandler, WebsocketBase}; use crate::asynch::clients::SingleExecutorMutex; @@ -24,7 +24,7 @@ use tokio_tungstenite::connect_async as tokio_tungstenite_connect_async; type TokioTungsteniteMaybeTlsStream = WebSocketStream>; -pub struct AsyncWebsocketClient +pub struct AsyncWebSocketClient where M: RawMutex, { @@ -34,7 +34,7 @@ where status: PhantomData, } -impl Sink for AsyncWebsocketClient +impl Sink for AsyncWebSocketClient where M: RawMutex, { @@ -85,7 +85,7 @@ where } } -impl Stream for AsyncWebsocketClient +impl Stream for AsyncWebSocketClient where M: RawMutex, { @@ -130,25 +130,25 @@ where } } -impl AsyncWebsocketClient +impl AsyncWebSocketClient where M: RawMutex, { - pub async fn open(uri: Url) -> Result> { + pub async fn open(uri: Url) -> Result> { let stream = match tokio_tungstenite_connect_async(uri.to_string()).await { Ok((stream, _)) => stream, Err(error) => return Err!(error), }; - Ok(AsyncWebsocketClient { + Ok(AsyncWebSocketClient { websocket: Arc::new(Mutex::new(stream)), websocket_base: Arc::new(Mutex::new(WebsocketBase::new())), uri, - status: PhantomData::, + status: PhantomData::, }) } } -impl AsyncWebsocketClient +impl AsyncWebSocketClient where M: RawMutex, { @@ -163,16 +163,16 @@ where } } -impl AsyncWebsocketClient +impl AsyncWebSocketClient where M: RawMutex, { pub fn is_open(&self) -> bool { - core::any::type_name::() == core::any::type_name::() + core::any::type_name::() == core::any::type_name::() } } -impl MessageHandler for AsyncWebsocketClient +impl MessageHandler for AsyncWebSocketClient where M: RawMutex, { @@ -197,7 +197,7 @@ where } } -impl Client for AsyncWebsocketClient +impl Client for AsyncWebSocketClient where M: RawMutex, { diff --git a/src/asynch/clients/websocket/codec.rs b/src/asynch/clients/websocket/codec.rs deleted file mode 100644 index 95e9b09b..00000000 --- a/src/asynch/clients/websocket/codec.rs +++ /dev/null @@ -1,30 +0,0 @@ -use alloc::{io, vec::Vec}; -use bytes::{BufMut, BytesMut}; -use tokio_util::codec::{Decoder, Encoder}; - -pub struct Codec; - -impl Decoder for Codec { - type Item = Vec; - type Error = io::Error; - - fn decode(&mut self, src: &mut BytesMut) -> Result>, io::Error> { - if !src.is_empty() { - let len = src.len(); - let data = src.split_to(len).to_vec(); - Ok(Some(data)) - } else { - Ok(None) - } - } -} - -impl Encoder<&[u8]> for Codec { - type Error = io::Error; - - fn encode(&mut self, data: &[u8], buf: &mut BytesMut) -> Result<(), io::Error> { - buf.reserve(data.len()); - buf.put(data); - Ok(()) - } -} diff --git a/src/asynch/clients/websocket/exceptions.rs b/src/asynch/clients/websocket/exceptions.rs index 63052bb9..f659efb3 100644 --- a/src/asynch/clients/websocket/exceptions.rs +++ b/src/asynch/clients/websocket/exceptions.rs @@ -1,16 +1,13 @@ use core::fmt::Debug; use core::str::Utf8Error; -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(all(feature = "websocket", not(feature = "std")))] use embedded_io_async::{Error as EmbeddedIoError, ErrorKind}; -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(all(feature = "websocket", not(feature = "std")))] use embedded_websocket::framer_async::FramerError; use thiserror_no_std::Error; #[derive(Debug, Error)] pub enum XRPLWebsocketException { - #[cfg(all(feature = "websocket-std", not(feature = "websocket")))] - #[error("Unable to connect to websocket")] - UnableToConnect(tokio_tungstenite::tungstenite::Error), // FramerError #[error("I/O error: {0:?}")] Io(E), @@ -20,7 +17,7 @@ pub enum XRPLWebsocketException { Utf8(Utf8Error), #[error("Invalid HTTP header")] HttpHeader, - #[cfg(all(feature = "websocket", not(feature = "websocket-std")))] + #[cfg(all(feature = "websocket", not(feature = "std")))] #[error("Websocket error: {0:?}")] WebSocket(embedded_websocket::Error), #[error("Disconnected")] @@ -29,7 +26,7 @@ pub enum XRPLWebsocketException { RxBufferTooSmall(usize), #[error("Unexpected message type")] UnexpectedMessageType, - #[cfg(all(feature = "websocket", not(feature = "websocket-std")))] + #[cfg(all(feature = "websocket", not(feature = "std")))] #[error("Embedded I/O error: {0:?}")] EmbeddedIoError(ErrorKind), #[error("Missing request channel sender.")] @@ -40,7 +37,7 @@ pub enum XRPLWebsocketException { InvalidMessage, } -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(all(feature = "websocket", not(feature = "std")))] impl From> for XRPLWebsocketException { fn from(value: FramerError) -> Self { match value { @@ -55,7 +52,7 @@ impl From> for XRPLWebsocketException { } } -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(all(feature = "websocket", not(feature = "std")))] impl EmbeddedIoError for XRPLWebsocketException { fn kind(&self) -> ErrorKind { match self { diff --git a/src/asynch/clients/websocket/mod.rs b/src/asynch/clients/websocket/mod.rs index 9fc26d28..04520815 100644 --- a/src/asynch/clients/websocket/mod.rs +++ b/src/asynch/clients/websocket/mod.rs @@ -2,37 +2,35 @@ use crate::{ models::{requests::XRPLRequest, results::XRPLResponse}, Err, }; -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] +#[cfg(feature = "std")] use alloc::string::String; -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(not(feature = "std"))] use alloc::string::ToString; use anyhow::Result; -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(not(feature = "std"))] use core::fmt::Display; -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(not(feature = "std"))] use embedded_io_async::{ErrorType, Read as EmbeddedIoRead, Write as EmbeddedIoWrite}; -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] +#[cfg(feature = "std")] use futures::{Sink, SinkExt, Stream, StreamExt}; mod websocket_base; use websocket_base::MessageHandler; -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(all(feature = "websocket", not(feature = "std")))] mod _no_std; -#[cfg(all(feature = "websocket-codec", feature = "std"))] -pub mod codec; mod exceptions; -pub use exceptions::XRPLWebsocketException; -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] +pub use exceptions::*; +#[cfg(all(feature = "websocket", feature = "std"))] mod _std; -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(all(feature = "websocket", not(feature = "std")))] pub use _no_std::*; -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] +#[cfg(all(feature = "websocket", feature = "std"))] pub use _std::*; -pub struct WebsocketOpen; -pub struct WebsocketClosed; +pub struct WebSocketOpen; +pub struct WebSocketClosed; #[allow(async_fn_in_trait)] pub trait XRPLWebsocketIO { @@ -41,7 +39,7 @@ pub trait XRPLWebsocketIO { async fn xrpl_receive(&mut self) -> Result>>; } -#[cfg(all(feature = "websocket", not(feature = "websocket-std")))] +#[cfg(not(feature = "std"))] impl XRPLWebsocketIO for T where ::Error: Display, @@ -86,7 +84,7 @@ where } } -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] +#[cfg(feature = "std")] impl XRPLWebsocketIO for T where T: Stream> + Sink + MessageHandler + Unpin, diff --git a/src/asynch/ledger/mod.rs b/src/asynch/ledger/mod.rs index cd03be65..1ff7b40a 100644 --- a/src/asynch/ledger/mod.rs +++ b/src/asynch/ledger/mod.rs @@ -4,9 +4,9 @@ use alloc::string::ToString; use anyhow::Result; use crate::models::{ - amount::XRPAmount, - requests::{Fee, Ledger}, - results::{Drops, Fee as FeeResult, Ledger as LedgerResult}, + requests::{fee::Fee, ledger::Ledger}, + results::{fee::Drops, fee::Fee as FeeResult, ledger::Ledger as LedgerResult}, + XRPAmount, }; use super::clients::AsyncClient; diff --git a/src/asynch/mod.rs b/src/asynch/mod.rs index b045b44c..b94b9b75 100644 --- a/src/asynch/mod.rs +++ b/src/asynch/mod.rs @@ -1,15 +1,22 @@ -#[cfg(feature = "account-helpers")] -pub mod account; -#[cfg(any( - feature = "websocket-std", - feature = "websocket", - feature = "json-rpc-std", - feature = "json-rpc" +#[cfg(all( + feature = "account-helpers", + any(feature = "websocket", feature = "json-rpc") ))] +pub mod account; +#[cfg(any(feature = "websocket", feature = "json-rpc"))] pub mod clients; -#[cfg(feature = "ledger-helpers")] +#[cfg(all( + feature = "ledger-helpers", + any(feature = "websocket", feature = "json-rpc") +))] pub mod ledger; -#[cfg(feature = "transaction-helpers")] +#[cfg(all( + feature = "transaction-helpers", + any(feature = "websocket", feature = "json-rpc") +))] pub mod transaction; -#[cfg(all(feature = "wallet-helpers", feature = "json-rpc-std"))] +#[cfg(all( + feature = "wallet-helpers", + any(feature = "websocket", feature = "json-rpc") +))] pub mod wallet; diff --git a/src/asynch/transaction/exceptions.rs b/src/asynch/transaction/exceptions.rs index 4e37a1ca..49ccb3fc 100644 --- a/src/asynch/transaction/exceptions.rs +++ b/src/asynch/transaction/exceptions.rs @@ -3,7 +3,7 @@ use core::num::ParseIntError; use alloc::borrow::Cow; use thiserror_no_std::Error; -use crate::models::amount::XRPAmount; +use crate::models::XRPAmount; #[derive(Error, Debug, PartialEq)] pub enum XRPLTransactionException<'a> { diff --git a/src/asynch/transaction/mod.rs b/src/asynch/transaction/mod.rs index c23b63ce..374cd4e5 100644 --- a/src/asynch/transaction/mod.rs +++ b/src/asynch/transaction/mod.rs @@ -16,12 +16,12 @@ use crate::{ keypairs::sign as keypairs_sign, }, models::{ - amount::XRPAmount, - exceptions::XRPLModelException, - requests::{ServerState, Submit}, - results::{ServerState as ServerStateResult, Submit as SubmitResult}, - transactions::{Signer, Transaction, TransactionType, XRPLTransactionFieldException}, - Model, + requests::{server_state::ServerState, submit::Submit}, + results::{server_state::ServerState as ServerStateResult, submit::Submit as SubmitResult}, + transactions::{ + exceptions::XRPLTransactionFieldException, Signer, Transaction, TransactionType, + }, + Model, XRPAmount, XRPLModelException, }, utils::transactions::{ get_transaction_field_value, set_transaction_field_value, validate_transaction_has_field, @@ -175,7 +175,7 @@ where let res = client.request(req.into()).await?; match res.try_into_result::>() { Ok(value) => { - let submit_result = SubmitResult::from(value); + let submit_result = value; Ok(submit_result) } Err(e) => Err!(e), @@ -444,18 +444,18 @@ where Ok(t) => t, Err(error) => return Err!(error), }; - validate_transaction_has_field(prepared_transaction, &account_field_name)?; - set_transaction_field_value(prepared_transaction, &account_field_name, address)?; + validate_transaction_has_field(prepared_transaction, account_field_name)?; + set_transaction_field_value(prepared_transaction, account_field_name, address)?; - if validate_transaction_has_field(prepared_transaction, &tag_field_name).is_ok() - && get_transaction_field_value(prepared_transaction, &tag_field_name).unwrap_or(Some(0)) + if validate_transaction_has_field(prepared_transaction, tag_field_name).is_ok() + && get_transaction_field_value(prepared_transaction, tag_field_name).unwrap_or(Some(0)) != tag { Err!(XRPLSignTransactionException::TagFieldMismatch( - &tag_field_name + tag_field_name )) } else { - set_transaction_field_value(prepared_transaction, &tag_field_name, tag)?; + set_transaction_field_value(prepared_transaction, tag_field_name, tag)?; Ok(()) } @@ -481,15 +481,15 @@ where } } -#[cfg(all(feature = "websocket-std", feature = "std", not(feature = "websocket")))] +#[cfg(all(feature = "websocket", feature = "std"))] #[cfg(test)] mod test_autofill { use super::autofill; use crate::{ - asynch::clients::{AsyncWebsocketClient, SingleExecutorMutex}, + asynch::clients::{AsyncWebSocketClient, SingleExecutorMutex}, models::{ - amount::{IssuedCurrencyAmount, XRPAmount}, - transactions::{OfferCreate, Transaction}, + transactions::{offer_create::OfferCreate, Transaction}, + IssuedCurrencyAmount, XRPAmount, }, }; use anyhow::Result; @@ -517,7 +517,7 @@ mod test_autofill { None, None, ); - let client = AsyncWebsocketClient::::open( + let client = AsyncWebSocketClient::::open( "wss://testnet.xrpl-labs.com/".parse().unwrap(), ) .await @@ -533,17 +533,17 @@ mod test_autofill { } } -#[cfg(all(feature = "websocket-std", feature = "std", not(feature = "websocket")))] +#[cfg(all(feature = "websocket", feature = "std"))] #[cfg(test)] mod test_sign { use alloc::borrow::Cow; use crate::{ asynch::{ - clients::{AsyncWebsocketClient, SingleExecutorMutex}, + clients::{AsyncWebSocketClient, SingleExecutorMutex}, transaction::{autofill_and_sign, sign}, }, - models::transactions::{AccountSet, Transaction}, + models::transactions::{account_set::AccountSet, Transaction}, wallet::Wallet, }; @@ -602,7 +602,7 @@ mod test_sign { None, None, ); - let client = AsyncWebsocketClient::::open( + let client = AsyncWebSocketClient::::open( "wss://testnet.xrpl-labs.com/".parse().unwrap(), ) .await diff --git a/src/asynch/transaction/submit_and_wait.rs b/src/asynch/transaction/submit_and_wait.rs index 0f9b456f..210dfefd 100644 --- a/src/asynch/transaction/submit_and_wait.rs +++ b/src/asynch/transaction/submit_and_wait.rs @@ -27,7 +27,7 @@ pub async fn submit_and_wait<'a: 'b, 'b, T, F, C>( wallet: Option<&Wallet>, check_fee: Option, autofill: Option, -) -> Result> +) -> Result> where T: Transaction<'a, F> + Model + Clone + DeserializeOwned + Debug, F: IntoEnumIterator + Serialize + Debug + PartialEq + Debug + Clone + 'a, @@ -40,7 +40,7 @@ where async fn send_reliable_submission<'a: 'b, 'b, T, F, C>( transaction: &'b mut T, client: &C, -) -> Result> +) -> Result> where T: Transaction<'a, F> + Model + Clone + DeserializeOwned + Debug, F: IntoEnumIterator + Serialize + Debug + PartialEq + Debug + Clone + 'a, @@ -72,18 +72,28 @@ async fn wait_for_final_transaction_result<'a: 'b, 'b, C>( tx_hash: Cow<'a, str>, client: &C, last_ledger_sequence: u32, -) -> Result> +) -> Result> where C: AsyncClient, { let mut validated_ledger_sequence = 0; + let mut c = 0; while validated_ledger_sequence < last_ledger_sequence { + c += 1; + if c > 20 { + panic!() + } validated_ledger_sequence = get_latest_validated_ledger_sequence(client).await?; // sleep for 1 second - // embassy_time::Timer::after_secs(1).await; + #[cfg(feature = "embassy-rt")] + embassy_time::Timer::after_secs(1).await; + #[cfg(any( + feature = "tokio-rt", + all(feature = "embassy-rt", feature = "tokio-rt") + ))] tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; let response = client - .request(requests::Tx::new(None, None, None, None, Some(tx_hash.clone())).into()) + .request(requests::tx::Tx::new(None, None, None, None, Some(tx_hash.clone())).into()) .await?; if response.is_success() { if let Some(error) = response.error { @@ -96,7 +106,7 @@ where )); } } else { - let opt_result = response.try_into_opt_result::()?; + let opt_result = response.try_into_opt_result::()?; let validated = opt_result.try_get_typed("validated")?; if validated { let result = opt_result.try_into_result()?; @@ -119,9 +129,9 @@ where } } } - return Err!(XRPLSubmitAndWaitException::SubmissionFailed( + Err!(XRPLSubmitAndWaitException::SubmissionFailed( "Transaction not included in ledger".into() - )); + )) } async fn get_signed_transaction<'a, T, F, C>( @@ -161,23 +171,25 @@ where } #[cfg(all( - feature = "websocket-std", - not(feature = "websocket"), - feature = "transactions", - feature = "wallet" + feature = "std", + feature = "json-rpc", + feature = "wallet-helpers", + feature = "tokio-rt" ))] #[cfg(test)] mod test_submit_and_wait { use super::*; use crate::{ - asynch::clients::{AsyncWebsocketClient, SingleExecutorMutex}, - models::transactions::AccountSet, - wallet::Wallet, + asynch::{clients::AsyncJsonRpcClient, wallet::generate_faucet_wallet}, + models::transactions::account_set::AccountSet, }; #[tokio::test] async fn test_submit_and_wait() { - let wallet = Wallet::new("sEdT7wHTCLzDG7ueaw4hroSTBvH7Mk5", 0).unwrap(); + let client = AsyncJsonRpcClient::connect("https://testnet.xrpl-labs.com/".parse().unwrap()); + let wallet = generate_faucet_wallet(&client, None, None, None, None) + .await + .unwrap(); let mut tx = AccountSet::new( Cow::from(wallet.classic_address.clone()), None, @@ -198,11 +210,6 @@ mod test_submit_and_wait { None, None, ); - let client = AsyncWebsocketClient::::open( - "wss://testnet.xrpl-labs.com/".parse().unwrap(), - ) - .await - .unwrap(); submit_and_wait(&mut tx, &client, Some(&wallet), Some(true), Some(true)) .await .unwrap(); diff --git a/src/asynch/wallet/mod.rs b/src/asynch/wallet/mod.rs index 9e26c6ab..13b27168 100644 --- a/src/asynch/wallet/mod.rs +++ b/src/asynch/wallet/mod.rs @@ -7,7 +7,7 @@ use url::Url; use crate::{ asynch::account::get_next_valid_seq_number, - models::{amount::XRPAmount, requests::FundFaucet}, + models::{requests::FundFaucet, XRPAmount}, wallet::Wallet, Err, }; @@ -17,8 +17,8 @@ use super::{ clients::{Client, XRPLFaucet}, }; -const TEST_FAUCET_URL: &'static str = "https://faucet.altnet.rippletest.net/accounts"; -const DEV_FAUCET_URL: &'static str = "https://faucet.devnet.rippletest.net/accounts"; +const TEST_FAUCET_URL: &str = "https://faucet.altnet.rippletest.net/accounts"; +const DEV_FAUCET_URL: &str = "https://faucet.devnet.rippletest.net/accounts"; const TIMEOUT_SECS: u8 = 40; @@ -54,6 +54,12 @@ where let mut is_funded = false; for _ in 0..TIMEOUT_SECS { // wait 1 second + #[cfg(all(feature = "embassy-rt", not(feature = "tokio-rt")))] + embassy_time::Timer::after_secs(1).await; + #[cfg(any( + feature = "tokio-rt", + all(feature = "embassy-rt", feature = "tokio-rt") + ))] tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; if !is_funded { let balance = check_balance(client, address.into()).await; @@ -85,8 +91,8 @@ where let host_str = host.host_str().unwrap(); if host_str.contains("altnet") || host_str.contains("testnet") { match Url::parse(TEST_FAUCET_URL) { - Ok(url) => return Ok(url), - Err(error) => return Err!(error), + Ok(url) => Ok(url), + Err(error) => Err!(error), } } else if host_str.contains("devnet") { match Url::parse(DEV_FAUCET_URL) { @@ -130,16 +136,11 @@ where Ok(()) } -#[cfg(all( - feature = "json-rpc-std", - not(feature = "json-rpc"), - feature = "helpers", - feature = "models" -))] +#[cfg(all(feature = "json-rpc", feature = "std"))] #[cfg(test)] mod test_faucet_wallet_generation { use super::*; - use crate::asynch::clients::json_rpc::AsyncJsonRpcClient; + use crate::asynch::clients::AsyncJsonRpcClient; use url::Url; #[tokio::test] diff --git a/src/core/binarycodec/mod.rs b/src/core/binarycodec/mod.rs index 713872fd..47d1cf86 100644 --- a/src/core/binarycodec/mod.rs +++ b/src/core/binarycodec/mod.rs @@ -2,14 +2,13 @@ //! canonical binary format and decoding them. use super::types::{AccountId, STObject}; -use crate::{models::transactions::Transaction, Err}; +use crate::Err; use alloc::{borrow::Cow, string::String, vec::Vec}; use anyhow::Result; use core::{convert::TryFrom, fmt::Debug}; use hex::ToHex; use serde::{de::DeserializeOwned, Serialize}; -use strum::IntoEnumIterator; pub mod binary_wrappers; pub mod exceptions; @@ -21,18 +20,16 @@ pub use binary_wrappers::*; const TRANSACTION_SIGNATURE_PREFIX: i32 = 0x53545800; const TRANSACTION_MULTISIG_PREFIX: i32 = 0x534D5400; -pub fn encode<'a, T, F>(signed_transaction: &T) -> Result +pub fn encode<'a, T>(signed_transaction: &T) -> Result where - F: IntoEnumIterator + Serialize + Debug + PartialEq, - T: Transaction<'a, F> + Serialize + DeserializeOwned + Clone + Debug, + T: Serialize + DeserializeOwned + Clone + Debug, { serialize_json(signed_transaction, None, None, false) } -pub fn encode_for_signing<'a, T, F>(prepared_transaction: &T) -> Result +pub fn encode_for_signing<'a, T>(prepared_transaction: &T) -> Result where - F: IntoEnumIterator + Serialize + Debug + PartialEq, - T: Transaction<'a, F> + Serialize + DeserializeOwned + Clone + Debug, + T: Serialize + DeserializeOwned + Clone + Debug, { serialize_json( prepared_transaction, @@ -42,13 +39,12 @@ where ) } -pub fn encode_for_multisigning<'a, T, F>( +pub fn encode_for_multisigning( prepared_transaction: &T, - signing_account: Cow<'a, str>, + signing_account: Cow<'_, str>, ) -> Result where - F: IntoEnumIterator + Serialize + Debug + PartialEq, - T: Transaction<'a, F> + Serialize + DeserializeOwned + Clone + Debug, + T: Serialize + DeserializeOwned + Clone + Debug, { let signing_account_id = AccountId::try_from(signing_account.as_ref()).unwrap(); @@ -60,15 +56,14 @@ where ) } -fn serialize_json<'a, T, F>( +fn serialize_json<'a, T>( prepared_transaction: &T, prefix: Option<&[u8]>, suffix: Option<&[u8]>, signing_only: bool, ) -> Result where - F: IntoEnumIterator + Serialize + Debug + PartialEq, - T: Transaction<'a, F> + Serialize + DeserializeOwned + Clone + Debug, + T: Serialize + DeserializeOwned + Clone + Debug, { let mut buffer = Vec::new(); if let Some(p) = prefix { diff --git a/src/core/keypairs/algorithms.rs b/src/core/keypairs/algorithms.rs index 72284424..0dc47a03 100644 --- a/src/core/keypairs/algorithms.rs +++ b/src/core/keypairs/algorithms.rs @@ -414,7 +414,7 @@ impl CryptoImplementation for Ed25519 { .as_slice() .try_into() .map_err(|_| XRPLKeypairsException::InvalidSecret)?; - let private: ed25519_dalek::SecretKey = (*raw_private_slice).into(); + let private: ed25519_dalek::SecretKey = *raw_private_slice; let mut signing_key: ed25519_dalek::SigningKey = private.into(); let signature = signing_key.sign(message); diff --git a/src/core/types/mod.rs b/src/core/types/mod.rs index a34da2c6..a454dc99 100644 --- a/src/core/types/mod.rs +++ b/src/core/types/mod.rs @@ -101,7 +101,7 @@ impl XRPLTypes { "UInt8" => Ok(XRPLTypes::UInt8(value as u8)), "UInt16" => Ok(XRPLTypes::UInt16(value as u16)), "UInt32" => Ok(XRPLTypes::UInt32(value as u32)), - "UInt64" => Ok(XRPLTypes::UInt64(value as u64)), + "UInt64" => Ok(XRPLTypes::UInt64(value)), _ => Err!(exceptions::XRPLTypeException::UnknownXRPLType), } } else if let Some(value) = value.as_object() { @@ -151,9 +151,9 @@ impl XRPLTypes { } } -impl Into for XRPLTypes { - fn into(self) -> SerializedType { - match self { +impl From for SerializedType { + fn from(val: XRPLTypes) -> Self { + match val { XRPLTypes::AccountID(account_id) => SerializedType::from(account_id), XRPLTypes::Amount(amount) => SerializedType::from(amount), XRPLTypes::Blob(blob) => SerializedType::from(blob), @@ -298,7 +298,6 @@ impl STObject { /// assert_eq!(hex, buffer); /// ``` pub fn try_from_value(value: Value, signing_only: bool) -> Result { - // dbg!(&value); let object = match value { Value::Object(map) => map, _ => return Err!(exceptions::XRPLSerializeMapException::ExpectedObject), @@ -382,10 +381,9 @@ impl STObject { } } - // dbg!(&value_xaddress_handled); let mut sorted_keys: Vec = Vec::new(); for (field, _) in &value_xaddress_handled { - let field_instance = get_field_instance(&field); + let field_instance = get_field_instance(field); if let Some(field_instance) = field_instance { if value_xaddress_handled.contains_key(&field_instance.name) && field_instance.is_serialized @@ -413,7 +411,6 @@ impl STObject { associated_value.to_owned(), )?; let associated_value: SerializedType = associated_value.into(); - // dbg!(&field_instance, &associated_value.to_string(),); if field_instance.name == "TransactionType" && associated_value.to_string() == UNL_MODIFY_TX_TYPE { diff --git a/src/lib.rs b/src/lib.rs index e56b4b6a..98486805 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,18 +25,17 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std as alloc; +#[cfg(all(feature = "request-models", feature = "result-models"))] pub mod asynch; pub mod constants; #[cfg(feature = "core")] pub mod core; pub mod macros; #[cfg(any( - feature = "amounts", - feature = "currencies", - feature = "ledger", - feature = "requests", - feature = "results", - feature = "transactions" + feature = "ledger-models", + feature = "request-models", + feature = "result-models", + feature = "transaction-models" ))] pub mod models; #[cfg(feature = "transaction-helpers")] @@ -46,8 +45,21 @@ pub mod utils; #[cfg(feature = "wallet")] pub mod wallet; -// pub extern crate indexmap; pub extern crate serde_json; mod _anyhow; +#[cfg(any( + feature = "ledger-models", + feature = "request-models", + feature = "result-models", + feature = "transaction-models" +))] mod _serde; + +#[cfg(all(feature = "embassy-rt", feature = "tokio-rt"))] +compile_error!("Cannot enable both `embassy-rt` and `tokio-rt` features at the same time."); +#[cfg(all( + any(feature = "transaction-helpers", feature = "wallet-helpers"), + not(any(feature = "embassy-rt", feature = "tokio-rt")) +))] +compile_error!("Cannot enable `transaction-helpers` or `wallet-helpers` without enabling either `embassy-rt` or `tokio-rt`."); diff --git a/src/models/amount/mod.rs b/src/models/amount/mod.rs index 313e7107..25893015 100644 --- a/src/models/amount/mod.rs +++ b/src/models/amount/mod.rs @@ -1,13 +1,14 @@ -pub mod exceptions; -pub mod issued_currency_amount; -pub mod xrp_amount; +mod exceptions; +mod issued_currency_amount; +mod xrp_amount; -use core::convert::TryInto; +pub use exceptions::*; pub use issued_currency_amount::*; -use rust_decimal::Decimal; pub use xrp_amount::*; use crate::models::Model; +use core::convert::TryInto; +use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use strum_macros::Display; diff --git a/src/models/exceptions.rs b/src/models/exceptions.rs index 1acd1b47..c1f3089a 100644 --- a/src/models/exceptions.rs +++ b/src/models/exceptions.rs @@ -1,19 +1,11 @@ //! General XRPL Model Exception. -use crate::models::requests::XRPLRequestException; -use crate::models::transactions::XRPLTransactionException; use alloc::string::String; use serde::{Deserialize, Serialize}; use thiserror_no_std::Error; #[derive(Debug, Clone, PartialEq, Error)] pub enum XRPLModelException<'a> { - #[error("Issued Currency can not be XRP")] - InvalidICCannotBeXRP, - #[error("Transaction Model Error: {0}")] - XRPLTransactionError(XRPLTransactionException<'a>), - #[error("Request Model Error: {0}")] - XRPLRequestError(XRPLRequestException<'a>), #[error("Missing Field: {0}")] MissingField(&'a str), } @@ -34,4 +26,4 @@ pub enum XRPLFlagsException { } #[cfg(feature = "std")] -impl<'a> alloc::error::Error for XRPLFlagsException {} +impl alloc::error::Error for XRPLFlagsException {} diff --git a/src/models/flag_collection.rs b/src/models/flag_collection.rs new file mode 100644 index 00000000..38d35bb0 --- /dev/null +++ b/src/models/flag_collection.rs @@ -0,0 +1,97 @@ +use core::convert::TryFrom; + +use alloc::vec::Vec; +use anyhow::Result; +use derive_new::new; +use serde::{Deserialize, Serialize}; +use strum::IntoEnumIterator; +use strum_macros::{AsRefStr, Display, EnumIter}; + +use crate::{models::XRPLFlagsException, Err}; + +/// Represents the type of flags when the XRPL model has no flags. +#[derive( + Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Display, AsRefStr, EnumIter, Copy, +)] +pub enum NoFlags {} + +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, new)] +pub struct FlagCollection(pub(crate) Vec) +where + T: IntoEnumIterator; + +impl Iterator for FlagCollection +where + T: IntoEnumIterator, +{ + type Item = T; + + fn next(&mut self) -> Option { + self.0.pop() + } +} + +impl Default for FlagCollection +where + T: IntoEnumIterator, +{ + fn default() -> Self { + FlagCollection(Vec::new()) + } +} + +impl From> for FlagCollection +where + T: IntoEnumIterator, +{ + fn from(flags: Vec) -> Self { + FlagCollection(flags) + } +} + +impl TryFrom for FlagCollection +where + T: IntoEnumIterator + Serialize, +{ + type Error = anyhow::Error; + + fn try_from(flags: u32) -> Result { + let mut flag_collection = Vec::new(); + for flag in T::iter() { + let flag_as_u32 = flag_to_u32(&flag)?; + if flags & flag_as_u32 == flag_as_u32 { + flag_collection.push(flag); + } + } + Ok(FlagCollection::new(flag_collection)) + } +} + +impl TryFrom> for u32 +where + T: IntoEnumIterator + Serialize, +{ + type Error = anyhow::Error; + + fn try_from(flag_collection: FlagCollection) -> Result { + let mut flags = 0; + for flag in flag_collection { + let flag_as_u32 = flag_to_u32(&flag)?; + flags |= flag_as_u32; + } + Ok(flags) + } +} + +fn flag_to_u32(flag: &T) -> Result +where + T: Serialize, +{ + match serde_json::to_string(flag) { + Ok(flag_as_string) => match flag_as_string.parse::() { + Ok(flag_as_u32) => Ok(flag_as_u32), + Err(_error) => Err!(XRPLFlagsException::CannotConvertFlagToU32), + }, + Err(_error) => Err!(XRPLFlagsException::CannotConvertFlagToU32), + } +} diff --git a/src/models/ledger/mod.rs b/src/models/ledger/mod.rs index bcfa65b2..15ee7f6c 100644 --- a/src/models/ledger/mod.rs +++ b/src/models/ledger/mod.rs @@ -1,2 +1 @@ pub mod objects; -pub use objects::*; diff --git a/src/models/ledger/objects/account_root.rs b/src/models/ledger/objects/account_root.rs index 56180386..021ef523 100644 --- a/src/models/ledger/objects/account_root.rs +++ b/src/models/ledger/objects/account_root.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::{amount::XRPAmount, Model}; use alloc::borrow::Cow; diff --git a/src/models/ledger/objects/amendments.rs b/src/models/ledger/objects/amendments.rs index 6740200b..3bf17097 100644 --- a/src/models/ledger/objects/amendments.rs +++ b/src/models/ledger/objects/amendments.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::{Model, NoFlags}; @@ -80,7 +80,7 @@ impl<'a> Amendments<'a> { #[cfg(test)] mod tests { - use crate::models::ledger::{Amendments, Majority}; + use crate::models::ledger::objects::{Amendments, Majority}; use alloc::borrow::Cow; use alloc::string::ToString; use alloc::vec; diff --git a/src/models/ledger/objects/amm.rs b/src/models/ledger/objects/amm.rs index 48f965df..910621db 100644 --- a/src/models/ledger/objects/amm.rs +++ b/src/models/ledger/objects/amm.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::NoFlags; use crate::models::{amount::Amount, Currency, Model}; @@ -132,7 +132,7 @@ impl<'a> AMM<'a> { mod test_serde { use crate::models::amount::{Amount, IssuedCurrencyAmount}; use crate::models::currency::{Currency, IssuedCurrency, XRP}; - use crate::models::ledger::amm::{AuctionSlot, AuthAccount, VoteEntry, AMM}; + use crate::models::ledger::objects::amm::{AuctionSlot, AuthAccount, VoteEntry, AMM}; use alloc::borrow::Cow; use alloc::string::ToString; use alloc::vec; diff --git a/src/models/ledger/objects/check.rs b/src/models/ledger/objects/check.rs index 3800ea0e..ce2dba34 100644 --- a/src/models/ledger/objects/check.rs +++ b/src/models/ledger/objects/check.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::NoFlags; use crate::models::{amount::Amount, Model}; diff --git a/src/models/ledger/objects/deposit_preauth.rs b/src/models/ledger/objects/deposit_preauth.rs index 926a0c08..4d390fbc 100644 --- a/src/models/ledger/objects/deposit_preauth.rs +++ b/src/models/ledger/objects/deposit_preauth.rs @@ -1,6 +1,6 @@ use crate::models::FlagCollection; use crate::models::Model; -use crate::models::{ledger::LedgerEntryType, NoFlags}; +use crate::models::{ledger::objects::LedgerEntryType, NoFlags}; use alloc::borrow::Cow; use serde::{Deserialize, Serialize}; diff --git a/src/models/ledger/objects/directory_node.rs b/src/models/ledger/objects/directory_node.rs index b8cad877..68d24c1d 100644 --- a/src/models/ledger/objects/directory_node.rs +++ b/src/models/ledger/objects/directory_node.rs @@ -1,6 +1,6 @@ use crate::models::FlagCollection; use crate::models::Model; -use crate::models::{ledger::LedgerEntryType, NoFlags}; +use crate::models::{ledger::objects::LedgerEntryType, NoFlags}; use alloc::borrow::Cow; use alloc::vec::Vec; use serde::{Deserialize, Serialize}; diff --git a/src/models/ledger/objects/escrow.rs b/src/models/ledger/objects/escrow.rs index 9ab60cb5..a0eb9144 100644 --- a/src/models/ledger/objects/escrow.rs +++ b/src/models/ledger/objects/escrow.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::NoFlags; use crate::models::{amount::Amount, Model}; diff --git a/src/models/ledger/objects/fee_settings.rs b/src/models/ledger/objects/fee_settings.rs index 67ef763a..58e10f45 100644 --- a/src/models/ledger/objects/fee_settings.rs +++ b/src/models/ledger/objects/fee_settings.rs @@ -1,6 +1,6 @@ use crate::models::FlagCollection; use crate::models::Model; -use crate::models::{ledger::LedgerEntryType, NoFlags}; +use crate::models::{ledger::objects::LedgerEntryType, NoFlags}; use alloc::borrow::Cow; use serde::{Deserialize, Serialize}; diff --git a/src/models/ledger/objects/ledger_hashes.rs b/src/models/ledger/objects/ledger_hashes.rs index db47a071..c5d292af 100644 --- a/src/models/ledger/objects/ledger_hashes.rs +++ b/src/models/ledger/objects/ledger_hashes.rs @@ -1,6 +1,6 @@ use crate::models::FlagCollection; use crate::models::Model; -use crate::models::{ledger::LedgerEntryType, NoFlags}; +use crate::models::{ledger::objects::LedgerEntryType, NoFlags}; use alloc::borrow::Cow; use alloc::vec::Vec; use serde::{Deserialize, Serialize}; diff --git a/src/models/ledger/objects/negative_unl.rs b/src/models/ledger/objects/negative_unl.rs index b6d2eeae..3f4e7542 100644 --- a/src/models/ledger/objects/negative_unl.rs +++ b/src/models/ledger/objects/negative_unl.rs @@ -1,6 +1,6 @@ use crate::models::FlagCollection; use crate::models::Model; -use crate::models::{ledger::LedgerEntryType, NoFlags}; +use crate::models::{ledger::objects::LedgerEntryType, NoFlags}; use alloc::borrow::Cow; use alloc::string::String; use alloc::vec::Vec; diff --git a/src/models/ledger/objects/nftoken_offer.rs b/src/models/ledger/objects/nftoken_offer.rs index 224982dd..b139e876 100644 --- a/src/models/ledger/objects/nftoken_offer.rs +++ b/src/models/ledger/objects/nftoken_offer.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::{amount::Amount, Model}; use alloc::borrow::Cow; diff --git a/src/models/ledger/objects/nftoken_page.rs b/src/models/ledger/objects/nftoken_page.rs index 750ed97e..1489da22 100644 --- a/src/models/ledger/objects/nftoken_page.rs +++ b/src/models/ledger/objects/nftoken_page.rs @@ -1,6 +1,6 @@ use crate::models::FlagCollection; use crate::models::Model; -use crate::models::{ledger::LedgerEntryType, NoFlags}; +use crate::models::{ledger::objects::LedgerEntryType, NoFlags}; use alloc::borrow::Cow; use alloc::vec::Vec; use derive_new::new; diff --git a/src/models/ledger/objects/offer.rs b/src/models/ledger/objects/offer.rs index fc3c9fc9..ecc9d558 100644 --- a/src/models/ledger/objects/offer.rs +++ b/src/models/ledger/objects/offer.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::{amount::Amount, Model}; use alloc::borrow::Cow; diff --git a/src/models/ledger/objects/pay_channel.rs b/src/models/ledger/objects/pay_channel.rs index 95fe2d3b..6043603f 100644 --- a/src/models/ledger/objects/pay_channel.rs +++ b/src/models/ledger/objects/pay_channel.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::NoFlags; use crate::models::{amount::Amount, Model}; diff --git a/src/models/ledger/objects/ripple_state.rs b/src/models/ledger/objects/ripple_state.rs index ac207c4d..49074554 100644 --- a/src/models/ledger/objects/ripple_state.rs +++ b/src/models/ledger/objects/ripple_state.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::{amount::Amount, Model}; use alloc::borrow::Cow; diff --git a/src/models/ledger/objects/signer_list.rs b/src/models/ledger/objects/signer_list.rs index f95cbfdd..3b1f8e09 100644 --- a/src/models/ledger/objects/signer_list.rs +++ b/src/models/ledger/objects/signer_list.rs @@ -1,4 +1,4 @@ -use crate::models::ledger::LedgerEntryType; +use crate::models::ledger::objects::LedgerEntryType; use crate::models::FlagCollection; use crate::models::Model; use alloc::borrow::Cow; diff --git a/src/models/ledger/objects/ticket.rs b/src/models/ledger/objects/ticket.rs index 0f85331c..d1778b47 100644 --- a/src/models/ledger/objects/ticket.rs +++ b/src/models/ledger/objects/ticket.rs @@ -1,6 +1,6 @@ use crate::models::FlagCollection; use crate::models::Model; -use crate::models::{ledger::LedgerEntryType, NoFlags}; +use crate::models::{ledger::objects::LedgerEntryType, NoFlags}; use alloc::borrow::Cow; use serde::{Deserialize, Serialize}; diff --git a/src/models/mod.rs b/src/models/mod.rs index 6d9c5ebd..2e402d77 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -7,61 +7,34 @@ //! 4. Required specific fields in alphabetical order //! 5. Optional specific fields in alphabetical order -pub mod exceptions; -#[cfg(feature = "ledger")] +#[cfg(feature = "ledger-models")] +#[allow(clippy::too_many_arguments)] pub mod ledger; -pub mod model; -#[cfg(feature = "requests")] +#[cfg(feature = "request-models")] #[allow(clippy::too_many_arguments)] pub mod requests; -#[cfg(feature = "results")] +#[cfg(feature = "result-models")] +#[allow(clippy::too_many_arguments)] pub mod results; -#[cfg(feature = "transactions")] +#[cfg(feature = "transaction-models")] #[allow(clippy::too_many_arguments)] pub mod transactions; -#[cfg(feature = "amounts")] -pub mod amount; -#[cfg(feature = "currencies")] -pub mod currency; -pub mod utils; +mod amount; +mod currency; +mod exceptions; +mod flag_collection; +mod model; -use core::convert::TryFrom; +pub use amount::*; +pub use currency::*; +pub use exceptions::*; +pub use flag_collection::*; +pub use model::*; +use alloc::borrow::Cow; use derive_new::new; -pub use model::Model; -use strum::IntoEnumIterator; - -use crate::models::currency::{Currency, XRP}; -use crate::models::exceptions::XRPLFlagsException; -use crate::Err; -use alloc::{borrow::Cow, vec::Vec}; -use anyhow::Result; use serde::{Deserialize, Serialize}; -use strum_macros::{AsRefStr, Display, EnumIter}; - -/// Represents the object types that an AccountObjects -/// Request can ask for. -#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Display)] -#[strum(serialize_all = "snake_case")] -#[serde(rename_all = "snake_case")] -#[serde(tag = "type")] -pub enum AccountObjectType { - Check, - DepositPreauth, - Escrow, - Offer, - PaymentChannel, - SignerList, - RippleState, - Ticket, -} - -/// Represents the type of flags when the XRPL model has no flags. -#[derive( - Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Display, AsRefStr, EnumIter, Copy, -)] -pub enum NoFlags {} /// A PathStep represents an individual step along a Path. #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, Clone, new)] @@ -74,133 +47,7 @@ pub struct PathStep<'a> { type_hex: Option>, } -/// Returns a Currency as XRP for the currency, without a value. -fn default_xrp_currency<'a>() -> Currency<'a> { - Currency::XRP(XRP::new()) -} - -/// For use with serde defaults. -fn default_true() -> Option { - Some(true) -} - /// For use with serde defaults. fn default_false() -> Option { Some(false) } - -/// For use with serde defaults. -fn default_limit_200() -> Option { - Some(200) -} - -/// For use with serde defaults. -fn default_limit_300() -> Option { - Some(300) -} - -/// For use with serde defaults. -fn default_fee_mult_max() -> Option { - Some(10) -} - -/// For use with serde defaults. -fn default_fee_div_max() -> Option { - Some(1) -} - -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, new)] -pub struct FlagCollection(pub(crate) Vec) -where - T: IntoEnumIterator; - -impl Iterator for FlagCollection -where - T: IntoEnumIterator, -{ - type Item = T; - - fn next(&mut self) -> Option { - self.0.pop() - } -} - -impl Default for FlagCollection -where - T: IntoEnumIterator, -{ - fn default() -> Self { - FlagCollection(Vec::new()) - } -} - -impl From> for FlagCollection -where - T: IntoEnumIterator, -{ - fn from(flags: Vec) -> Self { - FlagCollection(flags) - } -} - -impl TryFrom for FlagCollection -where - T: IntoEnumIterator + Serialize, -{ - type Error = anyhow::Error; - - fn try_from(flags: u32) -> Result { - let mut flag_collection = Vec::new(); - for flag in T::iter() { - let flag_as_u32 = flag_to_u32(&flag)?; - if flags & flag_as_u32 == flag_as_u32 { - flag_collection.push(flag); - } - } - Ok(FlagCollection::new(flag_collection)) - } -} - -impl TryFrom> for u32 -where - T: IntoEnumIterator + Serialize, -{ - type Error = anyhow::Error; - - fn try_from(flag_collection: FlagCollection) -> Result { - let mut flags = 0; - for flag in flag_collection { - let flag_as_u32 = flag_to_u32(&flag)?; - flags |= flag_as_u32; - } - Ok(flags) - } -} - -fn flag_to_u32(flag: &T) -> Result -where - T: Serialize, -{ - match serde_json::to_string(flag) { - Ok(flag_as_string) => match flag_as_string.parse::() { - Ok(flag_as_u32) => Ok(flag_as_u32), - Err(_error) => Err!(XRPLFlagsException::CannotConvertFlagToU32), - }, - Err(_error) => Err!(XRPLFlagsException::CannotConvertFlagToU32), - } -} - -// pub trait SignAndSubmitError { -// fn _get_field_error(&self) -> Result<(), XRPLSignAndSubmitException>; -// fn _get_key_type_error(&self) -> Result<(), XRPLSignAndSubmitException>; -// } -// -// pub trait SignForError { -// fn _get_field_error(&self) -> Result<(), XRPLSignForException>; -// fn _get_key_type_error(&self) -> Result<(), XRPLSignForException>; -// } -// -// pub trait SignError { -// fn _get_field_error(&self) -> Result<(), XRPLSignException>; -// fn _get_key_type_error(&self) -> Result<(), XRPLSignException>; -// } diff --git a/src/models/model.rs b/src/models/model.rs index a4325db2..7271c0de 100644 --- a/src/models/model.rs +++ b/src/models/model.rs @@ -16,12 +16,4 @@ pub trait Model { Err(error) => Err(error), } } - - /// Returns whether the structure is valid. - fn is_valid(&self) -> bool { - match self.get_errors() { - Ok(_no_error) => true, - Err(_error) => false, - } - } } diff --git a/src/models/requests/account_channels.rs b/src/models/requests/account_channels.rs index df0753ed..7c8903bb 100644 --- a/src/models/requests/account_channels.rs +++ b/src/models/requests/account_channels.rs @@ -21,7 +21,7 @@ use super::{CommonFields, Request}; /// ## Basic usage /// /// ``` -/// use xrpl::models::requests::AccountChannels; +/// use xrpl::models::requests::account_channels::AccountChannels; /// /// let json = r#"{"command":"account_channels","account":"rH6ZiHU1PGamME2LvVTxrgvfjQpppWKGmr","marker":12345678}"#.to_string(); /// let model: AccountChannels = serde_json::from_str(&json).expect(""); diff --git a/src/models/requests/channel_authorize.rs b/src/models/requests/channel_authorize.rs index 466fa425..4b84c5c5 100644 --- a/src/models/requests/channel_authorize.rs +++ b/src/models/requests/channel_authorize.rs @@ -4,7 +4,7 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; -use crate::models::requests::XRPLChannelAuthorizeException; +use crate::models::requests::exceptions::XRPLChannelAuthorizeException; use crate::{ constants::CryptoAlgorithm, models::{requests::RequestMethod, Model}, diff --git a/src/models/requests/ledger_entry.rs b/src/models/requests/ledger_entry.rs index 0022437c..2cf0cad5 100644 --- a/src/models/requests/ledger_entry.rs +++ b/src/models/requests/ledger_entry.rs @@ -5,7 +5,7 @@ use derive_new::new; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; -use crate::models::requests::XRPLLedgerEntryException; +use crate::models::requests::exceptions::XRPLLedgerEntryException; use crate::models::{requests::RequestMethod, Model}; use super::{CommonFields, Request}; @@ -215,7 +215,7 @@ pub trait LedgerEntryError { #[cfg(test)] mod test_ledger_entry_errors { use super::Offer; - use crate::models::requests::XRPLLedgerEntryException; + use crate::models::requests::exceptions::XRPLLedgerEntryException; use crate::models::Model; use alloc::string::ToString; diff --git a/src/models/requests/mod.rs b/src/models/requests/mod.rs index 1c4f318a..5df5ee31 100644 --- a/src/models/requests/mod.rs +++ b/src/models/requests/mod.rs @@ -35,47 +35,10 @@ pub mod transaction_entry; pub mod tx; pub mod unsubscribe; -pub use account_channels::*; -pub use account_currencies::*; -pub use account_info::*; -pub use account_lines::*; -pub use account_nfts::*; -pub use account_objects::*; -pub use account_offers::*; -pub use account_tx::*; use alloc::borrow::Cow; -pub use book_offers::*; -pub use channel_authorize::*; -pub use channel_verify::*; -pub use deposit_authorize::*; use derive_new::new; -pub use exceptions::*; -pub use fee::*; -pub use gateway_balances::*; -pub use ledger::*; -pub use ledger_closed::*; -pub use ledger_current::*; -pub use ledger_data::*; -pub use ledger_entry::*; -pub use manifest::*; -pub use nft_buy_offers::*; -pub use nft_sell_offers::*; -pub use no_ripple_check::*; -pub use path_find::*; -pub use ping::*; -pub use random::*; -pub use ripple_path_find::*; -use serde_with::skip_serializing_none; -pub use server_info::*; -pub use server_state::*; -pub use submit::*; -pub use submit_multisigned::*; -pub use subscribe::*; -pub use transaction_entry::*; -pub use tx::*; -pub use unsubscribe::*; - use serde::{Deserialize, Serialize}; +use serde_with::skip_serializing_none; use strum_macros::Display; /// Represents the different options for the `method` @@ -141,249 +104,249 @@ pub enum RequestMethod { #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] #[serde(untagged)] pub enum XRPLRequest<'a> { - AccountChannels(AccountChannels<'a>), - AccountCurrencies(AccountCurrencies<'a>), - AccountInfo(AccountInfo<'a>), - AccountLines(AccountLines<'a>), - AccountNfts(AccountNfts<'a>), - AccountObjects(AccountObjects<'a>), - AccountOffers(AccountOffers<'a>), - AccountTx(AccountTx<'a>), - GatewayBalances(GatewayBalances<'a>), - NoRippleCheck(NoRippleCheck<'a>), - Submit(Submit<'a>), - SubmitMultisigned(SubmitMultisigned<'a>), - TransactionEntry(TransactionEntry<'a>), - Tx(Tx<'a>), - ChannelAuthorize(ChannelAuthorize<'a>), - ChannelVerify(ChannelVerify<'a>), - BookOffers(BookOffers<'a>), - DepositAuthorized(DepositAuthorized<'a>), - NftBuyOffers(NftBuyOffers<'a>), - NftSellOffers(NftSellOffers<'a>), - PathFind(PathFind<'a>), - RipplePathFind(RipplePathFind<'a>), - Ledger(Ledger<'a>), - LedgerClosed(LedgerClosed<'a>), - LedgerCurrent(LedgerCurrent<'a>), - LedgerData(LedgerData<'a>), - LedgerEntry(LedgerEntry<'a>), - Subscribe(Subscribe<'a>), - Unsubscribe(Unsubscribe<'a>), - Fee(Fee<'a>), - Manifest(Manifest<'a>), - ServerInfo(ServerInfo<'a>), - ServerState(ServerState<'a>), - Ping(Ping<'a>), - Random(Random<'a>), -} - -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountChannels<'a>) -> Self { + AccountChannels(account_channels::AccountChannels<'a>), + AccountCurrencies(account_currencies::AccountCurrencies<'a>), + AccountInfo(account_info::AccountInfo<'a>), + AccountLines(account_lines::AccountLines<'a>), + AccountNfts(account_nfts::AccountNfts<'a>), + AccountObjects(account_objects::AccountObjects<'a>), + AccountOffers(account_offers::AccountOffers<'a>), + AccountTx(account_tx::AccountTx<'a>), + GatewayBalances(gateway_balances::GatewayBalances<'a>), + NoRippleCheck(no_ripple_check::NoRippleCheck<'a>), + Submit(submit::Submit<'a>), + SubmitMultisigned(submit_multisigned::SubmitMultisigned<'a>), + TransactionEntry(transaction_entry::TransactionEntry<'a>), + Tx(tx::Tx<'a>), + ChannelAuthorize(channel_authorize::ChannelAuthorize<'a>), + ChannelVerify(channel_verify::ChannelVerify<'a>), + BookOffers(book_offers::BookOffers<'a>), + DepositAuthorized(deposit_authorize::DepositAuthorized<'a>), + NftBuyOffers(nft_buy_offers::NftBuyOffers<'a>), + NftSellOffers(nft_sell_offers::NftSellOffers<'a>), + PathFind(path_find::PathFind<'a>), + RipplePathFind(ripple_path_find::RipplePathFind<'a>), + Ledger(ledger::Ledger<'a>), + LedgerClosed(ledger_closed::LedgerClosed<'a>), + LedgerCurrent(ledger_current::LedgerCurrent<'a>), + LedgerData(ledger_data::LedgerData<'a>), + LedgerEntry(ledger_entry::LedgerEntry<'a>), + Subscribe(subscribe::Subscribe<'a>), + Unsubscribe(unsubscribe::Unsubscribe<'a>), + Fee(fee::Fee<'a>), + Manifest(manifest::Manifest<'a>), + ServerInfo(server_info::ServerInfo<'a>), + ServerState(server_state::ServerState<'a>), + Ping(ping::Ping<'a>), + Random(random::Random<'a>), +} + +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_channels::AccountChannels<'a>) -> Self { XRPLRequest::AccountChannels(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountCurrencies<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_currencies::AccountCurrencies<'a>) -> Self { XRPLRequest::AccountCurrencies(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountInfo<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_info::AccountInfo<'a>) -> Self { XRPLRequest::AccountInfo(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountLines<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_lines::AccountLines<'a>) -> Self { XRPLRequest::AccountLines(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountNfts<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_nfts::AccountNfts<'a>) -> Self { XRPLRequest::AccountNfts(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountObjects<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_objects::AccountObjects<'a>) -> Self { XRPLRequest::AccountObjects(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountOffers<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_offers::AccountOffers<'a>) -> Self { XRPLRequest::AccountOffers(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: AccountTx<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: account_tx::AccountTx<'a>) -> Self { XRPLRequest::AccountTx(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: GatewayBalances<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: gateway_balances::GatewayBalances<'a>) -> Self { XRPLRequest::GatewayBalances(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: NoRippleCheck<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: no_ripple_check::NoRippleCheck<'a>) -> Self { XRPLRequest::NoRippleCheck(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Submit<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: submit::Submit<'a>) -> Self { XRPLRequest::Submit(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: SubmitMultisigned<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: submit_multisigned::SubmitMultisigned<'a>) -> Self { XRPLRequest::SubmitMultisigned(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: TransactionEntry<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: transaction_entry::TransactionEntry<'a>) -> Self { XRPLRequest::TransactionEntry(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Tx<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: tx::Tx<'a>) -> Self { XRPLRequest::Tx(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: ChannelAuthorize<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: channel_authorize::ChannelAuthorize<'a>) -> Self { XRPLRequest::ChannelAuthorize(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: ChannelVerify<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: channel_verify::ChannelVerify<'a>) -> Self { XRPLRequest::ChannelVerify(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: BookOffers<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: book_offers::BookOffers<'a>) -> Self { XRPLRequest::BookOffers(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: DepositAuthorized<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: deposit_authorize::DepositAuthorized<'a>) -> Self { XRPLRequest::DepositAuthorized(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: NftBuyOffers<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: nft_buy_offers::NftBuyOffers<'a>) -> Self { XRPLRequest::NftBuyOffers(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: NftSellOffers<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: nft_sell_offers::NftSellOffers<'a>) -> Self { XRPLRequest::NftSellOffers(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: PathFind<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: path_find::PathFind<'a>) -> Self { XRPLRequest::PathFind(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: RipplePathFind<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: ripple_path_find::RipplePathFind<'a>) -> Self { XRPLRequest::RipplePathFind(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Ledger<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: ledger::Ledger<'a>) -> Self { XRPLRequest::Ledger(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: LedgerClosed<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: ledger_closed::LedgerClosed<'a>) -> Self { XRPLRequest::LedgerClosed(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: LedgerCurrent<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: ledger_current::LedgerCurrent<'a>) -> Self { XRPLRequest::LedgerCurrent(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: LedgerData<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: ledger_data::LedgerData<'a>) -> Self { XRPLRequest::LedgerData(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: LedgerEntry<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: ledger_entry::LedgerEntry<'a>) -> Self { XRPLRequest::LedgerEntry(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Subscribe<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: subscribe::Subscribe<'a>) -> Self { XRPLRequest::Subscribe(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Unsubscribe<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: unsubscribe::Unsubscribe<'a>) -> Self { XRPLRequest::Unsubscribe(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Fee<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: fee::Fee<'a>) -> Self { XRPLRequest::Fee(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Manifest<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: manifest::Manifest<'a>) -> Self { XRPLRequest::Manifest(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: ServerInfo<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: server_info::ServerInfo<'a>) -> Self { XRPLRequest::ServerInfo(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: ServerState<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: server_state::ServerState<'a>) -> Self { XRPLRequest::ServerState(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Ping<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: ping::Ping<'a>) -> Self { XRPLRequest::Ping(request) } } -impl<'a> From> for XRPLRequest<'a> { - fn from(request: Random<'a>) -> Self { +impl<'a> From> for XRPLRequest<'a> { + fn from(request: random::Random<'a>) -> Self { XRPLRequest::Random(request) } } diff --git a/src/models/requests/unsubscribe.rs b/src/models/requests/unsubscribe.rs index b056b688..8ea56076 100644 --- a/src/models/requests/unsubscribe.rs +++ b/src/models/requests/unsubscribe.rs @@ -7,7 +7,7 @@ use serde_with::skip_serializing_none; use crate::models::{ currency::Currency, default_false, - requests::{RequestMethod, StreamParameter}, + requests::{subscribe::StreamParameter, RequestMethod}, Model, }; diff --git a/src/models/response.rs b/src/models/response.rs deleted file mode 100644 index a6ef23c5..00000000 --- a/src/models/response.rs +++ /dev/null @@ -1 +0,0 @@ -// TODO: Add `Response` model diff --git a/src/models/results/account_info.rs b/src/models/results/account_info.rs index 0a33d78f..4372e084 100644 --- a/src/models/results/account_info.rs +++ b/src/models/results/account_info.rs @@ -4,7 +4,7 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use crate::{ - models::{ledger::AccountRoot, results::exceptions::XRPLResultException}, + models::{ledger::objects::AccountRoot, results::exceptions::XRPLResultException}, Err, }; diff --git a/src/models/results/ledger.rs b/src/models/results/ledger.rs index 0cf0dd69..b81456db 100644 --- a/src/models/results/ledger.rs +++ b/src/models/results/ledger.rs @@ -41,7 +41,7 @@ impl<'a> TryFrom> for Ledger<'a> { match result { XRPLResult::Ledger(ledger) => Ok(ledger), res => Err!(XRPLResultException::UnexpectedResultType( - "Ledger".to_string(), + "ledger-models".to_string(), res.get_name() )), } diff --git a/src/models/results/mod.rs b/src/models/results/mod.rs index 678f9547..fd2e19ca 100644 --- a/src/models/results/mod.rs +++ b/src/models/results/mod.rs @@ -1,5 +1,14 @@ -use core::convert::{TryFrom, TryInto}; +pub mod account_info; +pub mod account_tx; +pub mod exceptions; +pub mod fee; +pub mod ledger; +pub mod server_state; +pub mod submit; +pub mod tx; +use super::requests::XRPLRequest; +use crate::Err; use alloc::{ borrow::{Cow, ToOwned}, format, @@ -7,31 +16,11 @@ use alloc::{ vec::Vec, }; use anyhow::Result; +use core::convert::{TryFrom, TryInto}; use exceptions::XRPLResultException; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde_json::{value::Index, Map, Value}; -pub mod account_info; -pub mod account_tx; -pub mod exceptions; -pub mod fee; -pub mod ledger; -pub mod server_state; -pub mod submit; -pub mod tx; - -pub use account_info::*; -pub use account_tx::*; -pub use fee::*; -pub use ledger::*; -pub use server_state::*; -pub use submit::*; -pub use tx::*; - -use crate::Err; - -use super::requests::XRPLRequest; - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum XRPLOptionalResult { Result(T), @@ -102,9 +91,9 @@ impl From for XRPLOtherResult { } } -impl Into for XRPLOtherResult { - fn into(self) -> Value { - self.0 +impl From for Value { + fn from(val: XRPLOtherResult) -> Self { + val.0 } } @@ -131,54 +120,54 @@ impl XRPLOtherResult { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum XRPLResult<'a> { - AccountInfo(AccountInfo<'a>), - AccountTx(AccountTx<'a>), - Fee(Fee<'a>), - Ledger(Ledger<'a>), - ServerState(ServerState<'a>), - Submit(Submit<'a>), - Tx(Tx<'a>), + AccountInfo(account_info::AccountInfo<'a>), + AccountTx(account_tx::AccountTx<'a>), + Fee(fee::Fee<'a>), + Ledger(ledger::Ledger<'a>), + ServerState(server_state::ServerState<'a>), + Submit(submit::Submit<'a>), + Tx(tx::Tx<'a>), Other(XRPLOtherResult), } -impl<'a> From> for XRPLResult<'a> { - fn from(account_info: AccountInfo<'a>) -> Self { +impl<'a> From> for XRPLResult<'a> { + fn from(account_info: account_info::AccountInfo<'a>) -> Self { XRPLResult::AccountInfo(account_info) } } -impl<'a> From> for XRPLResult<'a> { - fn from(account_tx: AccountTx<'a>) -> Self { +impl<'a> From> for XRPLResult<'a> { + fn from(account_tx: account_tx::AccountTx<'a>) -> Self { XRPLResult::AccountTx(account_tx) } } -impl<'a> From> for XRPLResult<'a> { - fn from(fee: Fee<'a>) -> Self { +impl<'a> From> for XRPLResult<'a> { + fn from(fee: fee::Fee<'a>) -> Self { XRPLResult::Fee(fee) } } -impl<'a> From> for XRPLResult<'a> { - fn from(ledger: Ledger<'a>) -> Self { +impl<'a> From> for XRPLResult<'a> { + fn from(ledger: ledger::Ledger<'a>) -> Self { XRPLResult::Ledger(ledger) } } -impl<'a> From> for XRPLResult<'a> { - fn from(server_state: ServerState<'a>) -> Self { +impl<'a> From> for XRPLResult<'a> { + fn from(server_state: server_state::ServerState<'a>) -> Self { XRPLResult::ServerState(server_state) } } -impl<'a> From> for XRPLResult<'a> { - fn from(submit: Submit<'a>) -> Self { +impl<'a> From> for XRPLResult<'a> { + fn from(submit: submit::Submit<'a>) -> Self { XRPLResult::Submit(submit) } } -impl<'a> From> for XRPLResult<'a> { - fn from(tx: Tx<'a>) -> Self { +impl<'a> From> for XRPLResult<'a> { + fn from(tx: tx::Tx<'a>) -> Self { XRPLResult::Tx(tx) } } @@ -215,7 +204,7 @@ impl XRPLResult<'_> { XRPLResult::AccountInfo(_) => "AccountInfo".to_string(), XRPLResult::AccountTx(_) => "AccountTx".to_string(), XRPLResult::Fee(_) => "Fee".to_string(), - XRPLResult::Ledger(_) => "Ledger".to_string(), + XRPLResult::Ledger(_) => "ledger-models".to_string(), XRPLResult::ServerState(_) => "ServerState".to_string(), XRPLResult::Submit(_) => "Submit".to_string(), XRPLResult::Tx(_) => "Tx".to_string(), @@ -339,7 +328,19 @@ impl TryInto for XRPLResponse<'_> { impl<'a> XRPLResponse<'a> { pub fn is_success(&self) -> bool { - self.status == Some(ResponseStatus::Success) + if let Some(status) = &self.status { + status == &ResponseStatus::Success + } else if let Some(result) = &self.result { + match serde_json::to_value(result) { + Ok(value) => match value.get("status") { + Some(Value::String(status)) => status == "success", + _ => false, + }, + _ => false, + } + } else { + false + } } pub fn try_into_opt_result(self) -> Result> diff --git a/src/models/transactions/account_delete.rs b/src/models/transactions/account_delete.rs index 53036f76..4fbae6cc 100644 --- a/src/models/transactions/account_delete.rs +++ b/src/models/transactions/account_delete.rs @@ -7,8 +7,8 @@ use crate::models::amount::XRPAmount; use crate::models::transactions::CommonFields; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Transaction, TransactionType}, + Model, }; use super::{Memo, Signer}; diff --git a/src/models/transactions/account_set.rs b/src/models/transactions/account_set.rs index 2984bc77..b8560c92 100644 --- a/src/models/transactions/account_set.rs +++ b/src/models/transactions/account_set.rs @@ -7,15 +7,15 @@ use serde_with::skip_serializing_none; use strum_macros::{AsRefStr, Display, EnumIter}; use crate::models::amount::XRPAmount; -use crate::models::transactions::{CommonFields, XRPLAccountSetException}; +use crate::models::transactions::{exceptions::XRPLAccountSetException, CommonFields}; use crate::{ constants::{ DISABLE_TICK_SIZE, MAX_DOMAIN_LENGTH, MAX_TICK_SIZE, MAX_TRANSFER_RATE, MIN_TICK_SIZE, MIN_TRANSFER_RATE, SPECIAL_CASE_TRANFER_RATE, }, models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }, Err, }; diff --git a/src/models/transactions/check_cancel.rs b/src/models/transactions/check_cancel.rs index adfc0603..ae7026d1 100644 --- a/src/models/transactions/check_cancel.rs +++ b/src/models/transactions/check_cancel.rs @@ -7,8 +7,8 @@ use crate::models::amount::XRPAmount; use crate::models::transactions::CommonFields; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Transaction, TransactionType}, + Model, }; use super::{Memo, Signer}; diff --git a/src/models/transactions/check_cash.rs b/src/models/transactions/check_cash.rs index eb7c37fe..dd73dedc 100644 --- a/src/models/transactions/check_cash.rs +++ b/src/models/transactions/check_cash.rs @@ -6,12 +6,12 @@ use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; -use crate::models::transactions::{CommonFields, XRPLCheckCashException}; +use crate::models::transactions::{exceptions::XRPLCheckCashException, CommonFields}; use crate::models::NoFlags; use crate::models::{ amount::Amount, - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; /// Cancels an unredeemed Check, removing it from the ledger without diff --git a/src/models/transactions/check_create.rs b/src/models/transactions/check_create.rs index 1b3dc2ed..171139a0 100644 --- a/src/models/transactions/check_create.rs +++ b/src/models/transactions/check_create.rs @@ -9,8 +9,8 @@ use crate::models::transactions::CommonFields; use crate::models::NoFlags; use crate::models::{ amount::Amount, - model::Model, transactions::{Transaction, TransactionType}, + Model, }; use super::{Memo, Signer}; diff --git a/src/models/transactions/deposit_preauth.rs b/src/models/transactions/deposit_preauth.rs index 0a2c808e..ad19e4eb 100644 --- a/src/models/transactions/deposit_preauth.rs +++ b/src/models/transactions/deposit_preauth.rs @@ -6,11 +6,11 @@ use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; -use crate::models::transactions::{CommonFields, XRPLDepositPreauthException}; +use crate::models::transactions::{exceptions::XRPLDepositPreauthException, CommonFields}; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; /// A DepositPreauth transaction gives another account pre-approval diff --git a/src/models/transactions/escrow_cancel.rs b/src/models/transactions/escrow_cancel.rs index 149e93de..696084ff 100644 --- a/src/models/transactions/escrow_cancel.rs +++ b/src/models/transactions/escrow_cancel.rs @@ -8,8 +8,8 @@ use crate::models::amount::XRPAmount; use crate::models::transactions::CommonFields; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Transaction, TransactionType}, + Model, }; use super::{Memo, Signer}; diff --git a/src/models/transactions/escrow_create.rs b/src/models/transactions/escrow_create.rs index 3e206002..134c8659 100644 --- a/src/models/transactions/escrow_create.rs +++ b/src/models/transactions/escrow_create.rs @@ -6,11 +6,11 @@ use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; -use crate::models::transactions::{CommonFields, XRPLEscrowCreateException}; +use crate::models::transactions::{exceptions::XRPLEscrowCreateException, CommonFields}; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; /// Creates an Escrow, which requests XRP until the escrow process either finishes or is canceled. diff --git a/src/models/transactions/escrow_finish.rs b/src/models/transactions/escrow_finish.rs index e3355f94..eada6dd2 100644 --- a/src/models/transactions/escrow_finish.rs +++ b/src/models/transactions/escrow_finish.rs @@ -5,12 +5,12 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; -use crate::models::transactions::XRPLEscrowFinishException; +use crate::models::transactions::exceptions::XRPLEscrowFinishException; use crate::models::NoFlags; use crate::models::{ amount::XRPAmount, - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/exceptions.rs b/src/models/transactions/exceptions.rs index c36bc9b6..c13198fb 100644 --- a/src/models/transactions/exceptions.rs +++ b/src/models/transactions/exceptions.rs @@ -1,4 +1,4 @@ -use crate::models::transactions::{AccountSetFlag, PaymentFlag}; +use crate::models::transactions::{account_set::AccountSetFlag, payment::PaymentFlag}; use alloc::borrow::Cow; use core::fmt::Debug; use strum_macros::Display; diff --git a/src/models/transactions/mod.rs b/src/models/transactions/mod.rs index a6b109b8..bb00ea68 100644 --- a/src/models/transactions/mod.rs +++ b/src/models/transactions/mod.rs @@ -25,56 +25,26 @@ pub mod signer_list_set; pub mod ticket_create; pub mod trust_set; -use core::fmt::Debug; - -pub use account_delete::*; -pub use account_set::*; -use alloc::format; -pub use check_cancel::*; -pub use check_cash::*; -pub use check_create::*; -pub use deposit_preauth::*; -pub use escrow_cancel::*; -pub use escrow_create::*; -pub use escrow_finish::*; -pub use exceptions::*; -pub use nftoken_accept_offer::*; -pub use nftoken_burn::*; -pub use nftoken_cancel_offer::*; -pub use nftoken_create_offer::*; -pub use nftoken_mint::*; -pub use offer_cancel::*; -pub use offer_create::*; -pub use payment::*; -pub use payment_channel_claim::*; -pub use payment_channel_create::*; -pub use payment_channel_fund::*; -pub use pseudo_transactions::*; - -use serde::de::DeserializeOwned; -pub use set_regular_key::*; -use sha2::{Digest, Sha512}; -pub use signer_list_set::*; -pub use ticket_create::*; -pub use trust_set::*; - +use super::FlagCollection; use crate::core::binarycodec::encode; use crate::models::amount::XRPAmount; use crate::Err; use crate::{_serde::txn_flags, serde_with_tag}; use alloc::borrow::Cow; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; use anyhow::Result; +use core::fmt::Debug; use derive_new::new; +use serde::de::DeserializeOwned; use serde::ser::SerializeMap; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; +use sha2::{Digest, Sha512}; use strum::IntoEnumIterator; use strum_macros::{AsRefStr, Display}; -use super::FlagCollection; - const TRANSACTION_HASH_PREFIX: u32 = 0x54584E00; /// Enum containing the different Transaction types. @@ -373,22 +343,21 @@ where #[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Display, AsRefStr)] pub enum Flag { - AccountSet(AccountSetFlag), - NFTokenCreateOffer(NFTokenCreateOfferFlag), - NFTokenMint(NFTokenMintFlag), - OfferCreate(OfferCreateFlag), - Payment(PaymentFlag), - PaymentChannelClaim(PaymentChannelClaimFlag), - TrustSet(TrustSetFlag), - EnableAmendment(EnableAmendmentFlag), + AccountSet(account_set::AccountSetFlag), + NFTokenCreateOffer(nftoken_create_offer::NFTokenCreateOfferFlag), + NFTokenMint(nftoken_mint::NFTokenMintFlag), + OfferCreate(offer_create::OfferCreateFlag), + Payment(payment::PaymentFlag), + PaymentChannelClaim(payment_channel_claim::PaymentChannelClaimFlag), + TrustSet(trust_set::TrustSetFlag), + EnableAmendment(pseudo_transactions::enable_amendment::EnableAmendmentFlag), } #[cfg(all( - feature = "websocket-std", - not(feature = "websocket"), - feature = "transactions", + feature = "std", + feature = "websocket", + feature = "transaction-models", feature = "transaction-helpers", - feature = "amounts", feature = "wallet" ))] #[cfg(test)] @@ -396,7 +365,7 @@ mod test_tx_common_fields { use super::*; use crate::{ asynch::transaction::sign, - models::{amount::IssuedCurrencyAmount, transactions::OfferCreate}, + models::{amount::IssuedCurrencyAmount, transactions::offer_create::OfferCreate}, wallet::Wallet, }; diff --git a/src/models/transactions/nftoken_accept_offer.rs b/src/models/transactions/nftoken_accept_offer.rs index 103bc94a..4a26e8de 100644 --- a/src/models/transactions/nftoken_accept_offer.rs +++ b/src/models/transactions/nftoken_accept_offer.rs @@ -8,12 +8,12 @@ use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; -use crate::models::transactions::XRPLNFTokenAcceptOfferException; +use crate::models::transactions::exceptions::XRPLNFTokenAcceptOfferException; use crate::models::NoFlags; use crate::models::{ amount::Amount, - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/nftoken_burn.rs b/src/models/transactions/nftoken_burn.rs index 6d260dbb..dc3458af 100644 --- a/src/models/transactions/nftoken_burn.rs +++ b/src/models/transactions/nftoken_burn.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/nftoken_cancel_offer.rs b/src/models/transactions/nftoken_cancel_offer.rs index f2d13729..a0043370 100644 --- a/src/models/transactions/nftoken_cancel_offer.rs +++ b/src/models/transactions/nftoken_cancel_offer.rs @@ -6,11 +6,11 @@ use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; -use crate::models::transactions::XRPLNFTokenCancelOfferException; +use crate::models::transactions::exceptions::XRPLNFTokenCancelOfferException; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/nftoken_create_offer.rs b/src/models/transactions/nftoken_create_offer.rs index 5922a12a..e8858896 100644 --- a/src/models/transactions/nftoken_create_offer.rs +++ b/src/models/transactions/nftoken_create_offer.rs @@ -9,12 +9,12 @@ use serde_with::skip_serializing_none; use strum_macros::{AsRefStr, Display, EnumIter}; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use crate::models::amount::{Amount, XRPAmount}; -use crate::models::transactions::XRPLNFTokenCreateOfferException; +use crate::models::transactions::exceptions::XRPLNFTokenCreateOfferException; use crate::Err; use super::{CommonFields, FlagCollection}; diff --git a/src/models/transactions/nftoken_mint.rs b/src/models/transactions/nftoken_mint.rs index 1477d014..6c803ab1 100644 --- a/src/models/transactions/nftoken_mint.rs +++ b/src/models/transactions/nftoken_mint.rs @@ -9,14 +9,14 @@ use strum_macros::{AsRefStr, Display, EnumIter}; use crate::{ constants::{MAX_TRANSFER_FEE, MAX_URI_LENGTH}, models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }, Err, }; use crate::models::amount::XRPAmount; -use crate::models::transactions::XRPLNFTokenMintException; +use crate::models::transactions::exceptions::XRPLNFTokenMintException; use super::{CommonFields, FlagCollection}; diff --git a/src/models/transactions/offer_cancel.rs b/src/models/transactions/offer_cancel.rs index 7834ad68..8416573a 100644 --- a/src/models/transactions/offer_cancel.rs +++ b/src/models/transactions/offer_cancel.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/offer_create.rs b/src/models/transactions/offer_create.rs index 2e71f511..fb973671 100644 --- a/src/models/transactions/offer_create.rs +++ b/src/models/transactions/offer_create.rs @@ -8,8 +8,8 @@ use strum_macros::{AsRefStr, Display, EnumIter}; use crate::models::{ amount::Amount, - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use crate::models::amount::XRPAmount; diff --git a/src/models/transactions/payment.rs b/src/models/transactions/payment.rs index e4dab26c..6cd0dba4 100644 --- a/src/models/transactions/payment.rs +++ b/src/models/transactions/payment.rs @@ -8,13 +8,12 @@ use strum_macros::{AsRefStr, Display, EnumIter}; use crate::models::{ amount::Amount, - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, - PathStep, + Model, PathStep, }; use crate::models::amount::XRPAmount; -use crate::models::transactions::XRPLPaymentException; +use crate::models::transactions::exceptions::XRPLPaymentException; use crate::Err; use super::{CommonFields, FlagCollection}; diff --git a/src/models/transactions/payment_channel_claim.rs b/src/models/transactions/payment_channel_claim.rs index 68d55bc6..229c0511 100644 --- a/src/models/transactions/payment_channel_claim.rs +++ b/src/models/transactions/payment_channel_claim.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use strum_macros::{AsRefStr, Display, EnumIter}; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use crate::models::amount::XRPAmount; diff --git a/src/models/transactions/payment_channel_create.rs b/src/models/transactions/payment_channel_create.rs index 68950884..43ce7eea 100644 --- a/src/models/transactions/payment_channel_create.rs +++ b/src/models/transactions/payment_channel_create.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/payment_channel_fund.rs b/src/models/transactions/payment_channel_fund.rs index 85b2528e..d46aab24 100644 --- a/src/models/transactions/payment_channel_fund.rs +++ b/src/models/transactions/payment_channel_fund.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use crate::models::NoFlags; use crate::models::{ amount::XRPAmount, - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/pseudo_transactions/enable_amendment.rs b/src/models/transactions/pseudo_transactions/enable_amendment.rs index 9d7db323..bb309c97 100644 --- a/src/models/transactions/pseudo_transactions/enable_amendment.rs +++ b/src/models/transactions/pseudo_transactions/enable_amendment.rs @@ -9,8 +9,8 @@ use strum_macros::{AsRefStr, Display, EnumIter}; use crate::models::amount::XRPAmount; use crate::models::transactions::{CommonFields, FlagCollection, Memo, Signer}; use crate::models::{ - model::Model, transactions::{Transaction, TransactionType}, + Model, }; #[derive( diff --git a/src/models/transactions/pseudo_transactions/set_fee.rs b/src/models/transactions/pseudo_transactions/set_fee.rs index f861c39b..c573fa7f 100644 --- a/src/models/transactions/pseudo_transactions/set_fee.rs +++ b/src/models/transactions/pseudo_transactions/set_fee.rs @@ -8,8 +8,8 @@ use crate::models::amount::XRPAmount; use crate::models::transactions::{CommonFields, Memo, Signer}; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Transaction, TransactionType}, + Model, }; /// See SetFee: diff --git a/src/models/transactions/pseudo_transactions/unl_modify.rs b/src/models/transactions/pseudo_transactions/unl_modify.rs index 259b8979..e3c081a5 100644 --- a/src/models/transactions/pseudo_transactions/unl_modify.rs +++ b/src/models/transactions/pseudo_transactions/unl_modify.rs @@ -10,8 +10,8 @@ use crate::models::transactions::{CommonFields, Memo, Signer}; use crate::models::NoFlags; use crate::models::{ amount::XRPAmount, - model::Model, transactions::{Transaction, TransactionType}, + Model, }; #[derive( diff --git a/src/models/transactions/set_regular_key.rs b/src/models/transactions/set_regular_key.rs index f0bec596..f3ee7d06 100644 --- a/src/models/transactions/set_regular_key.rs +++ b/src/models/transactions/set_regular_key.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/signer_list_set.rs b/src/models/transactions/signer_list_set.rs index 3b34833a..4538fbaa 100644 --- a/src/models/transactions/signer_list_set.rs +++ b/src/models/transactions/signer_list_set.rs @@ -7,12 +7,12 @@ use derive_new::new; use serde::{ser::SerializeMap, Deserialize, Serialize}; use serde_with::skip_serializing_none; -use crate::models::transactions::XRPLSignerListSetException; +use crate::models::transactions::exceptions::XRPLSignerListSetException; use crate::models::NoFlags; use crate::models::{ amount::XRPAmount, - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use crate::{serde_with_tag, Err}; diff --git a/src/models/transactions/ticket_create.rs b/src/models/transactions/ticket_create.rs index 3ae9bddb..1dc6e9a8 100644 --- a/src/models/transactions/ticket_create.rs +++ b/src/models/transactions/ticket_create.rs @@ -6,8 +6,8 @@ use serde_with::skip_serializing_none; use crate::models::amount::XRPAmount; use crate::models::NoFlags; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use super::CommonFields; diff --git a/src/models/transactions/trust_set.rs b/src/models/transactions/trust_set.rs index 31397e7d..bd8287f0 100644 --- a/src/models/transactions/trust_set.rs +++ b/src/models/transactions/trust_set.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use strum_macros::{AsRefStr, Display, EnumIter}; use crate::models::{ - model::Model, transactions::{Memo, Signer, Transaction, TransactionType}, + Model, }; use crate::models::amount::{IssuedCurrencyAmount, XRPAmount}; diff --git a/src/models/utils.rs b/src/models/utils.rs deleted file mode 100644 index cf1c177c..00000000 --- a/src/models/utils.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! Helper util functions for the models module. -use crate::models::exceptions::JSONRPCException; -use alloc::string::String; -use serde::{Deserialize, Serialize}; - -/// JSONRPC Request -#[derive(Debug, Clone, Serialize)] -pub struct Request { - pub method: String, - pub params: Option, - pub id: serde_json::Value, - pub jsonrpc: Option, -} - -/// JSONRPC Response -#[derive(Debug, Clone, Deserialize)] -pub struct Response { - pub id: serde_json::Value, - pub result: Option, - pub error: Option, - pub jsonrpc: Option, -} diff --git a/src/transaction/multisign.rs b/src/transaction/multisign.rs index 8159bdb1..437629a6 100644 --- a/src/transaction/multisign.rs +++ b/src/transaction/multisign.rs @@ -21,7 +21,7 @@ where Some(signers) => signers, None => return Err!(XRPLMultisignException::NoSigners), }; - let tx_signer = match tx_signers.get(0) { + let tx_signer = match tx_signers.first() { Some(signer) => signer, None => return Err!(XRPLMultisignException::NoSigners), }; @@ -40,7 +40,7 @@ mod test { use super::*; use crate::asynch::transaction::sign; - use crate::models::transactions::AccountSet; + use crate::models::transactions::account_set::AccountSet; use crate::wallet::Wallet; #[tokio::test] diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 7f06707e..953b6e98 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,6 +2,7 @@ pub mod exceptions; pub mod time_conversion; +#[cfg(feature = "transaction-models")] pub(crate) mod transactions; pub mod xrpl_conversion; @@ -9,10 +10,7 @@ pub use self::time_conversion::*; pub use self::xrpl_conversion::*; use crate::constants::*; -use alloc::string::String; -use alloc::string::ToString; use alloc::vec::Vec; -use rand::Rng; use regex::Regex; /// Determine if the address string is a hex address. @@ -69,12 +67,6 @@ pub fn is_iso_hex(value: &str) -> bool { regex.is_match(value) } -/// Generate a random id. -pub fn get_random_id(rng: &mut T) -> String { - let id: u32 = rng.gen(); - id.to_string() -} - /// Converter to byte array with endianness. pub trait ToBytes { /// Return the byte array of self. diff --git a/src/utils/transactions.rs b/src/utils/transactions.rs index 739954f5..c932b913 100644 --- a/src/utils/transactions.rs +++ b/src/utils/transactions.rs @@ -5,7 +5,7 @@ use serde::{de::DeserializeOwned, Serialize}; use strum::IntoEnumIterator; use crate::{ - models::transactions::{Transaction, XRPLTransactionFieldException}, + models::transactions::{exceptions::XRPLTransactionFieldException, Transaction}, Err, }; diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index 00e2443d..7b84f314 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -1,5 +1,7 @@ //! Methods for working with XRPL wallets. +use core::fmt::Display; + use crate::constants::CryptoAlgorithm; use crate::core::addresscodec::classic_address_to_xaddress; use crate::core::addresscodec::exceptions::XRPLAddressCodecException; @@ -7,9 +9,7 @@ use crate::core::keypairs::derive_classic_address; use crate::core::keypairs::derive_keypair; use crate::core::keypairs::exceptions::XRPLKeypairsException; use crate::core::keypairs::generate_seed; -use alloc::format; use alloc::string::String; -use alloc::string::ToString; use zeroize::Zeroize; /// The cryptographic keys needed to control an @@ -84,15 +84,13 @@ impl Wallet { } } -impl ToString for Wallet { +impl Display for Wallet { /// Returns a string representation of a Wallet. - fn to_string(&self) -> String { - let string_list = [ - format!("public_key: {}", self.public_key), - format!("private_key: {}", "-HIDDEN-"), - format!("classic_address: {}", self.classic_address), - ]; - - string_list.join("-") + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!( + f, + "Wallet {{ public_key: {}, private_key: -HIDDEN-, classic_address: {} }}", + self.public_key, self.classic_address + ) } } diff --git a/src/wallet/wallet_generation.rs b/src/wallet/wallet_generation.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/common/mod.rs b/tests/common/mod.rs index d3fe32d6..6c55fb26 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,63 +1,35 @@ -mod constants; +use anyhow::Result; +#[cfg(all(feature = "websocket", not(feature = "std")))] +use embedded_io_adapters::tokio_1::FromTokio; +#[cfg(all(feature = "websocket", not(feature = "std")))] +use rand::rngs::OsRng; +#[cfg(all(feature = "websocket", not(feature = "std")))] +use tokio::net::TcpStream; +use url::Url; +#[cfg(feature = "websocket")] +use xrpl::asynch::clients::{AsyncWebSocketClient, SingleExecutorMutex, WebSocketOpen}; -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] -mod tungstenite_clients { - use super::constants::*; - use anyhow::anyhow; - use anyhow::Result; - use xrpl::asynch::clients::AsyncWebsocketClient; - use xrpl::asynch::clients::{SingleExecutorMutex, WebsocketOpen}; +#[cfg(all(feature = "websocket", not(feature = "std")))] +pub async fn open_websocket( + uri: Url, +) -> Result< + AsyncWebSocketClient<4096, FromTokio, OsRng, SingleExecutorMutex, WebSocketOpen>, +> { + let port = uri.port().unwrap_or(80); + let url = format!("{}:{}", uri.host_str().unwrap(), port); - pub async fn connect_to_wss_tungstinite_test_net<'a>( - ) -> Result> { - match AsyncWebsocketClient::open(XRPL_WSS_TEST_NET.parse().unwrap()).await { - Ok(websocket) => { - assert!(websocket.is_open()); - Ok(websocket) - } - Err(err) => Err(anyhow!("Error connecting to websocket: {:?}", err)), - } + let tcp = TcpStream::connect(&url).await.unwrap(); + let stream = FromTokio::new(tcp); + let rng = OsRng; + match AsyncWebSocketClient::open(stream, uri, rng, None, None).await { + Ok(client) => Ok(client), + Err(e) => Err(e), } } -#[cfg(all(feature = "websocket", feature = "std", not(feature = "websocket-std")))] -mod embedded_ws_clients { - use super::constants::*; - use anyhow::anyhow; - use anyhow::Result; - use std::io; - use tokio::net::TcpStream; - use tokio_util::codec::Framed; - use xrpl::asynch::clients::{ - codec::Codec, AsyncWebsocketClient, SingleExecutorMutex, WebsocketOpen, - }; - - pub async fn connect_to_ws_embedded_websocket_tokio_echo( - stream: Framed, - ) -> Result< - AsyncWebsocketClient< - 4096, - Framed, - Vec, - io::Error, - rand_core::OsRng, - SingleExecutorMutex, - WebsocketOpen, - >, - > { - let rng = rand_core::OsRng; - let url = ECHO_WS_SERVER.parse().unwrap(); - match AsyncWebsocketClient::open(rng, stream, url).await { - Ok(websocket) => { - // assert!(websocket.is_open()); - Ok(websocket) - } - Err(err) => Err(anyhow!("Error connecting to websocket: {:?}", err)), - } - } +#[cfg(all(feature = "websocket", feature = "std"))] +pub async fn open_websocket( + uri: Url, +) -> Result> { + AsyncWebSocketClient::open(uri).await } - -#[cfg(all(feature = "websocket", feature = "std", not(feature = "websocket-std")))] -pub use embedded_ws_clients::*; -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] -pub use tungstenite_clients::*; diff --git a/tests/integration/clients/mod.rs b/tests/integration/clients/mod.rs index e4b68521..8b137891 100644 --- a/tests/integration/clients/mod.rs +++ b/tests/integration/clients/mod.rs @@ -1,78 +1 @@ -use anyhow::Result; -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] -pub async fn test_websocket_tungstenite_test_net() -> Result<()> { - use crate::common::connect_to_wss_tungstinite_test_net; - use xrpl::{asynch::clients::XRPLWebsocketIO, models::requests::Fee}; - - let mut websocket = connect_to_wss_tungstinite_test_net().await?; - let fee = Fee::new(None); - - websocket.xrpl_send(fee.into()).await.unwrap(); - let message = websocket.xrpl_receive().await.unwrap(); - assert!(message.unwrap().result.is_some()); - Ok(()) -} - -#[cfg(all(feature = "websocket-std", not(feature = "websocket")))] -pub async fn test_websocket_tungstenite_request() -> Result<()> { - use crate::common::connect_to_wss_tungstinite_test_net; - use xrpl::{asynch::clients::AsyncClient, models::requests::Fee}; - - let websocket = connect_to_wss_tungstinite_test_net().await?; - let fee = Fee::new(None); - - let message = websocket.request(fee.into()).await.unwrap(); - assert!(message.result.is_some()); - Ok(()) -} - -#[cfg(all(feature = "websocket", feature = "std", not(feature = "websocket-std")))] -pub async fn test_embedded_websocket_echo() -> Result<()> { - use crate::common::connect_to_ws_embedded_websocket_tokio_echo; - use tokio_util::codec::Framed; - use xrpl::asynch::clients::codec::Codec; - use xrpl::asynch::clients::XRPLWebsocketIO; - use xrpl::models::requests::Fee; - - let tcp_stream = tokio::net::TcpStream::connect("ws.vi-server.org:80") - .await - .unwrap(); - let framed = Framed::new(tcp_stream, Codec); - let mut websocket = connect_to_ws_embedded_websocket_tokio_echo(framed).await?; - let fee = Fee::new(None); - websocket.xrpl_send(fee.into()).await?; - let _ = websocket.xrpl_receive().await.unwrap(); - Ok(()) -} - -#[cfg(all(feature = "websocket", feature = "std", not(feature = "websocket-std")))] -pub async fn test_embedded_websocket_request() -> Result<()> { - use crate::common::connect_to_ws_embedded_websocket_tokio_echo; - use tokio_util::codec::Framed; - use xrpl::asynch::clients::codec::Codec; - use xrpl::asynch::clients::AsyncClient; - use xrpl::models::requests::Fee; - - let tcp_stream = tokio::net::TcpStream::connect("ws.vi-server.org:80") - .await - .unwrap(); - let framed = Framed::new(tcp_stream, Codec); - let websocket = connect_to_ws_embedded_websocket_tokio_echo(framed).await?; - let fee = Fee::new(None); - let _res = websocket.request(fee.into()).await?; - Ok(()) -} - -#[cfg(all(feature = "json-rpc-std", not(feature = "json-rpc")))] -pub async fn test_json_rpc_std() -> Result<()> { - use xrpl::{ - asynch::clients::{AsyncClient, AsyncJsonRpcClient, SingleExecutorMutex}, - models::requests::Fee, - }; - let client: AsyncJsonRpcClient = - AsyncJsonRpcClient::connect("https://s1.ripple.com:51234/".parse().unwrap()); - let fee_result = client.request(Fee::new(None).into()).await.unwrap(); - assert!(fee_result.result.is_some()); - Ok(()) -} diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index c243b8c0..8732ebce 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -2,36 +2,3 @@ mod common; mod integration; - -use anyhow::Result; - -#[cfg(any(feature = "websocket-std", all(feature = "websocket", feature = "std")))] -#[tokio::test] -async fn test_asynch_clients() -> Result<()> { - #[cfg(all(feature = "websocket-std", not(feature = "websocket")))] - return integration::clients::test_websocket_tungstenite_test_net().await; - #[cfg(all(feature = "websocket", feature = "std", not(feature = "websocket-std")))] - return integration::clients::test_embedded_websocket_echo().await; - #[allow(unreachable_code)] - Ok(()) -} - -#[cfg(any(feature = "websocket-std", feature = "websocket", feature = "std"))] -#[tokio::test] -async fn test_asynch_clients_request() -> Result<()> { - #[cfg(all(feature = "websocket-std", feature = "std", not(feature = "websocket")))] - return integration::clients::test_websocket_tungstenite_request().await; - #[cfg(all(feature = "websocket", feature = "std", not(feature = "websocket-std")))] - return integration::clients::test_embedded_websocket_request().await; - #[allow(unreachable_code)] - Ok(()) -} - -#[cfg(all(feature = "json-rpc-std", not(feature = "json-rpc")))] -#[tokio::test] -async fn test_asynch_clients_json_rpc() -> Result<()> { - #[cfg(all(feature = "json-rpc-std", not(feature = "json-rpc")))] - return integration::clients::test_json_rpc_std().await; - #[allow(unreachable_code)] - Ok(()) -} diff --git a/tests/test_utils.rs b/tests/test_utils.rs index eca718e9..51f1d6ba 100644 --- a/tests/test_utils.rs +++ b/tests/test_utils.rs @@ -1,11 +1,14 @@ +#[cfg(feature = "utils")] use xrpl::utils::{posix_to_ripple_time, ripple_time_to_posix}; #[test] +#[cfg(feature = "utils")] fn it_converts_posix_to_ripple_time() { assert_eq!(posix_to_ripple_time(1660187459), Ok(713502659_i64)); } #[test] +#[cfg(feature = "utils")] fn it_converts_ripple_time_to_posix() { assert_eq!(ripple_time_to_posix(713502659), Ok(1660187459)); }