From 3e2b3cb9228444a36414b1ccbe98ddc4ac49dd5e Mon Sep 17 00:00:00 2001 From: LimpidCrypto <97235361+LimpidCrypto@users.noreply.github.com> Date: Sun, 1 Sep 2024 08:46:30 +0200 Subject: [PATCH] Account helpers (#81) * add remaining account helpers --------- Co-authored-by: LimpidCrypto --- src/asynch/account/mod.rs | 75 ++++++++++++++++++++++++++++++-- src/models/results/account_tx.rs | 35 +++++++++++++++ src/models/results/mod.rs | 26 +++++++---- 3 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 src/models/results/account_tx.rs diff --git a/src/asynch/account/mod.rs b/src/asynch/account/mod.rs index 53917f69..e392853b 100644 --- a/src/asynch/account/mod.rs +++ b/src/asynch/account/mod.rs @@ -3,12 +3,31 @@ use anyhow::Result; use crate::{ core::addresscodec::{is_valid_xaddress, xaddress_to_classic_address}, - models::{ledger::AccountRoot, requests::AccountInfo, results}, + models::{ + amount::XRPAmount, + ledger::AccountRoot, + requests::{AccountInfo, AccountTx}, + results, + }, Err, }; use super::clients::AsyncClient; +pub async fn does_account_exist( + address: Cow<'_, str>, + client: &C, + ledger_index: Option>, +) -> Result +where + C: AsyncClient, +{ + match get_account_root(address, client, ledger_index.unwrap_or("validated".into())).await { + Ok(_) => Ok(true), + Err(_) => Ok(false), + } +} + pub async fn get_next_valid_seq_number( address: Cow<'_, str>, client: &impl AsyncClient, @@ -19,11 +38,30 @@ pub async fn get_next_valid_seq_number( Ok(account_info.sequence) } -pub async fn get_account_root<'a>( +pub async fn get_xrp_balance<'a: 'b, 'b, C>( address: Cow<'a, str>, - client: &impl AsyncClient, + client: &C, + ledger_index: Option>, +) -> Result> +where + C: AsyncClient, +{ + let account_info = + get_account_root(address, client, ledger_index.unwrap_or("validated".into())).await?; + match account_info.balance { + Some(balance) => Ok(balance), + None => Ok(0.into()), + } +} + +pub async fn get_account_root<'a: 'b, 'b, C>( + address: Cow<'a, str>, + client: &C, ledger_index: Cow<'a, str>, -) -> Result> { +) -> Result> +where + C: AsyncClient, +{ let mut classic_address = address; if is_valid_xaddress(&classic_address) { classic_address = match xaddress_to_classic_address(&classic_address) { @@ -50,3 +88,32 @@ pub async fn get_account_root<'a>( .try_into_result::>()? .account_data) } + +pub async fn get_latest_transaction<'a: 'b, 'b, C>( + mut address: Cow<'a, str>, + client: &C, +) -> Result> +where + C: AsyncClient, +{ + if is_valid_xaddress(&address) { + address = match xaddress_to_classic_address(&address) { + Ok((address, _, _)) => address.into(), + Err(e) => return Err!(e), + }; + } + let account_tx = AccountTx::new( + None, + address, + None, + Some("validated".into()), + None, + None, + None, + None, + Some(1), + None, + ); + let response = client.request(account_tx.into()).await?; + response.try_into_result::>() +} diff --git a/src/models/results/account_tx.rs b/src/models/results/account_tx.rs new file mode 100644 index 00000000..35b49834 --- /dev/null +++ b/src/models/results/account_tx.rs @@ -0,0 +1,35 @@ +use core::convert::TryFrom; + +use alloc::{borrow::Cow, vec::Vec}; +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +use crate::{models::results::exceptions::XRPLResultException, Err}; + +use super::XRPLResult; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct AccountTx<'a> { + pub account: Cow<'a, str>, + pub ledger_index_min: Option, + pub ledger_index_max: Option, + pub limit: Option, + pub marker: Option, + pub transactions: Vec, + pub validated: Option, +} + +impl<'a> TryFrom> for AccountTx<'a> { + type Error = anyhow::Error; + + fn try_from(result: XRPLResult<'a>) -> Result { + match result { + XRPLResult::AccountTx(account_tx) => Ok(account_tx), + res => Err!(XRPLResultException::UnexpectedResultType( + "AccountTx".to_string(), + res.get_name() + )), + } + } +} diff --git a/src/models/results/mod.rs b/src/models/results/mod.rs index a52d7406..adbf2c79 100644 --- a/src/models/results/mod.rs +++ b/src/models/results/mod.rs @@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; pub mod account_info; +pub mod account_tx; pub mod exceptions; pub mod fee; pub mod ledger; @@ -19,6 +20,7 @@ pub mod server_state; pub mod submit; pub use account_info::*; +pub use account_tx::*; pub use fee::*; pub use ledger::*; pub use server_state::*; @@ -30,26 +32,33 @@ use super::requests::XRPLRequest; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum XRPLResult<'a> { - Fee(Fee<'a>), AccountInfo(AccountInfo<'a>), + AccountTx(AccountTx<'a>), + Fee(Fee<'a>), Ledger(Ledger<'a>), ServerState(ServerState<'a>), Submit(Submit<'a>), Other(Value), } -impl<'a> From> for XRPLResult<'a> { - fn from(fee: Fee<'a>) -> Self { - XRPLResult::Fee(fee) - } -} - impl<'a> From> for XRPLResult<'a> { fn from(account_info: AccountInfo<'a>) -> Self { XRPLResult::AccountInfo(account_info) } } +impl<'a> From> for XRPLResult<'a> { + fn from(account_tx: AccountTx<'a>) -> Self { + XRPLResult::AccountTx(account_tx) + } +} + +impl<'a> From> for XRPLResult<'a> { + fn from(fee: Fee<'a>) -> Self { + XRPLResult::Fee(fee) + } +} + impl<'a> From> for XRPLResult<'a> { fn from(ledger: Ledger<'a>) -> Self { XRPLResult::Ledger(ledger) @@ -91,8 +100,9 @@ impl<'a> TryInto for XRPLResult<'a> { impl XRPLResult<'_> { pub(crate) fn get_name(&self) -> String { match self { - XRPLResult::Fee(_) => "Fee".to_string(), XRPLResult::AccountInfo(_) => "AccountInfo".to_string(), + XRPLResult::AccountTx(_) => "AccountTx".to_string(), + XRPLResult::Fee(_) => "Fee".to_string(), XRPLResult::Ledger(_) => "Ledger".to_string(), XRPLResult::ServerState(_) => "ServerState".to_string(), XRPLResult::Submit(_) => "Submit".to_string(),