Skip to content

Commit

Permalink
Merge pull request #96 from sephynox/add-response-models
Browse files Browse the repository at this point in the history
Add response models
  • Loading branch information
LimpidCrypto authored Dec 21, 2024
2 parents e23c7a3 + 7eb651e commit a5e7193
Show file tree
Hide file tree
Showing 84 changed files with 1,929 additions and 349 deletions.
11 changes: 7 additions & 4 deletions src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use crate::{
clients::XRPLClient,
exceptions::XRPLHelperResult,
},
models::{ledger::objects::AccountRoot, results::account_tx::AccountTx, XRPAmount},
models::{
ledger::objects::account_root::AccountRoot, results::account_tx::AccountTxVersionMap,
XRPAmount,
},
};

pub fn does_account_exist<C>(
Expand Down Expand Up @@ -44,7 +47,7 @@ where

pub fn get_xrp_balance<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
client: &'a C,
ledger_index: Option<Cow<'a, str>>,
) -> XRPLHelperResult<XRPAmount<'b>>
where
Expand All @@ -55,7 +58,7 @@ where

pub fn get_account_root<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
client: &'a C,
ledger_index: Cow<'a, str>,
) -> XRPLHelperResult<AccountRoot<'b>>
where
Expand All @@ -67,7 +70,7 @@ where
pub fn get_latest_transaction<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
) -> XRPLHelperResult<AccountTx<'b>>
) -> XRPLHelperResult<AccountTxVersionMap<'b>>
where
C: XRPLClient,
{
Expand Down
23 changes: 12 additions & 11 deletions src/asynch/account/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use alloc::borrow::Cow;
use alloc::borrow::{Cow, ToOwned};

use crate::{
core::addresscodec::{is_valid_xaddress, xaddress_to_classic_address},
models::{
ledger::objects::AccountRoot,
ledger::objects::account_root::AccountRoot,
requests::{account_info::AccountInfo, account_tx::AccountTx},
results::{self},
XRPAmount,
Expand Down Expand Up @@ -38,7 +38,7 @@ pub async fn get_next_valid_seq_number(

pub async fn get_xrp_balance<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
client: &'a C,
ledger_index: Option<Cow<'a, str>>,
) -> XRPLHelperResult<XRPAmount<'b>>
where
Expand All @@ -54,7 +54,7 @@ where

pub async fn get_account_root<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
client: &'a C,
ledger_index: Cow<'a, str>,
) -> XRPLHelperResult<AccountRoot<'b>>
where
Expand All @@ -74,17 +74,17 @@ where
None,
)
.into();
let account_info = client.request(request).await?;
let response = client.request(request).await?;
let account_info = results::account_info::AccountInfoVersionMap::try_from(response)?;
let account_root = account_info.get_account_root().to_owned();

Ok(account_info
.try_into_result::<results::account_info::AccountInfo<'_>>()?
.account_data)
Ok(account_root)
}

pub async fn get_latest_transaction<'a: 'b, 'b, C>(
mut address: Cow<'a, str>,
client: &C,
) -> XRPLHelperResult<crate::models::results::account_tx::AccountTx<'b>>
) -> XRPLHelperResult<crate::models::results::account_tx::AccountTxVersionMap<'b>>
where
C: XRPLAsyncClient,
{
Expand All @@ -103,7 +103,8 @@ where
Some(1),
None,
);
let response = client.request(account_tx.into()).await?;
let response: results::account_tx::AccountTxVersionMap =
client.request(account_tx.into()).await?.try_into()?;

Ok(response.try_into_result::<results::account_tx::AccountTx<'_>>()?)
Ok(response)
}
8 changes: 3 additions & 5 deletions src/asynch/clients/async_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ pub trait XRPLAsyncClient: XRPLClient {

async fn get_common_fields(&self) -> XRPLClientResult<CommonFields<'_>> {
let server_state = self.request(ServerState::new(None).into()).await?;
let state = server_state
.try_into_result::<ServerStateResult<'_>>()?
.state;
let server_state: ServerStateResult = server_state.try_into()?;
let common_fields = CommonFields {
network_id: state.network_id,
build_version: Some(state.build_version),
network_id: server_state.state.network_id,
build_version: Some(server_state.state.build_version),
};

Ok(common_fields)
Expand Down
21 changes: 9 additions & 12 deletions src/asynch/clients/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,16 @@ pub trait XRPLClient {

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.clone()),
None => {
#[cfg(feature = "std")]
{
Some(self.get_random_id())
}
#[cfg(not(feature = "std"))]
unimplemented!(
"Random ID generation is not supported in no_std. Please provide an ID."
)
if common_fields.id.is_none() {
#[cfg(feature = "std")]
{
common_fields.id = Some(self.get_random_id());
}
};
#[cfg(not(feature = "std"))]
unimplemented!(
"Random ID generation is not supported in no_std. Please provide an ID."
);
}
}

/// Generate a random id.
Expand Down
11 changes: 2 additions & 9 deletions src/asynch/clients/json_rpc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

use alloc::{string::ToString, vec};
use serde::Serialize;
use serde_json::{Map, Value};
Expand All @@ -12,20 +13,12 @@ use super::{client::XRPLClient, exceptions::XRPLClientResult};
/// Renames the requests field `command` to `method` for JSON-RPC.
fn request_to_json_rpc(request: &impl Serialize) -> XRPLClientResult<Value> {
let mut json_rpc_request = Map::new();
// let mut request = match serde_json::to_value(request) {
// Ok(request) => match request.as_object().cloned() {
// Some(request) => request,
// None => todo!("Handle non-object requests"),
// },
// Err(error) => return Err!(error),
// };
let request_value = serde_json::to_value(request)?;
let mut request = request_value
.clone()
.as_object()
.ok_or(XRPLSerdeJsonError::UnexpectedValueType {
expected: "Object".to_string(),
found: request_value,
found: request_value.clone(),
})?
.clone();
if let Some(command) = request.remove("command") {
Expand Down
2 changes: 1 addition & 1 deletion src/asynch/clients/websocket/websocket_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ where
};
sender
.send(message)
.map_err(|e| XRPLWebSocketException::MessageChannelError(e))?;
.map_err(XRPLWebSocketException::MessageChannelError)?;
} else {
self.messages.send(message).await;
}
Expand Down
20 changes: 11 additions & 9 deletions src/asynch/ledger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use alloc::string::ToString;

use crate::models::{
requests::{fee::Fee, ledger::Ledger},
results::{fee::Drops, fee::Fee as FeeResult, ledger::Ledger as LedgerResult},
results::{self},
XRPAmount,
};

Expand All @@ -30,10 +30,9 @@ pub async fn get_latest_validated_ledger_sequence(
.into(),
)
.await?;
let ledger_result: results::ledger::Ledger = ledger_response.try_into()?;

Ok(ledger_response
.try_into_result::<LedgerResult<'_>>()?
.ledger_index)
Ok(ledger_result.ledger_index)
}

pub async fn get_latest_open_ledger_sequence(
Expand All @@ -56,10 +55,9 @@ pub async fn get_latest_open_ledger_sequence(
.into(),
)
.await?;
let ledger_result: results::ledger::Ledger = ledger_response.try_into()?;

Ok(ledger_response
.try_into_result::<LedgerResult<'_>>()?
.ledger_index)
Ok(ledger_result.ledger_index)
}

pub enum FeeType {
Expand All @@ -75,7 +73,8 @@ pub async fn get_fee(
) -> XRPLHelperResult<XRPAmount<'_>> {
let fee_request = Fee::new(None);
let response = client.request(fee_request.into()).await?;
let drops = response.try_into_result::<FeeResult<'_>>()?.drops;
let result: results::fee::Fee = response.try_into()?;
let drops = result.drops;
let fee = match_fee_type(fee_type, drops)?;

if let Some(max_fee) = max_fee {
Expand All @@ -85,7 +84,10 @@ pub async fn get_fee(
}
}

fn match_fee_type(fee_type: Option<FeeType>, drops: Drops<'_>) -> XRPLHelperResult<u32> {
fn match_fee_type(
fee_type: Option<FeeType>,
drops: results::fee::Drops<'_>,
) -> XRPLHelperResult<u32> {
match fee_type {
None | Some(FeeType::Open) => Ok(drops.open_ledger_fee.try_into()?),
Some(FeeType::Minimum) => Ok(drops.minimum_fee.try_into()?),
Expand Down
13 changes: 5 additions & 8 deletions src/asynch/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ where
let req = Submit::new(None, txn_blob.into(), None);
let res = client.request(req.into()).await?;

Ok(res.try_into_result::<SubmitResult<'_>>()?)
Ok(res.try_into()?)
}

pub async fn calculate_fee_per_transaction_type<'a, 'b, 'c, T, F, C>(
Expand Down Expand Up @@ -222,11 +222,8 @@ async fn get_owner_reserve_from_response(
client: &impl XRPLAsyncClient,
) -> XRPLHelperResult<XRPAmount<'_>> {
let owner_reserve_response = client.request(ServerState::new(None).into()).await?;
match owner_reserve_response
.try_into_result::<ServerStateResult<'_>>()?
.state
.validated_ledger
{
let result: ServerStateResult = owner_reserve_response.try_into()?;
match result.state.validated_ledger {
Some(validated_ledger) => Ok(validated_ledger.reserve_base),
None => Err(XRPLModelException::MissingField("validated_ledger".to_string()).into()),
}
Expand Down Expand Up @@ -271,14 +268,14 @@ fn txn_needs_network_id(common_fields: CommonFields<'_>) -> XRPLHelperResult<boo
Ok(is_not_later_rippled_version) => {
Ok(is_higher_restricted_networks && is_not_later_rippled_version)
}
Err(e) => Err(e.into()),
Err(e) => Err(e),
}
} else {
Ok(false)
}
}

fn is_not_later_rippled_version<'a>(source: String, target: String) -> XRPLHelperResult<bool> {
fn is_not_later_rippled_version(source: String, target: String) -> XRPLHelperResult<bool> {
if source == target {
Ok(true)
} else {
Expand Down
49 changes: 36 additions & 13 deletions src/asynch/transaction/submit_and_wait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ use crate::{
},
wait_seconds,
},
models::{requests, results::tx::Tx, transactions::Transaction, Model},
models::{
requests::{self},
results::tx::{TxMetaV1, TxV1, TxVersionMap},
transactions::Transaction,
Model,
},
wallet::Wallet,
};

Expand All @@ -27,7 +32,7 @@ pub async fn submit_and_wait<'a: 'b, 'b, T, F, C>(
wallet: Option<&Wallet>,
check_fee: Option<bool>,
autofill: Option<bool>,
) -> XRPLHelperResult<Tx<'b>>
) -> XRPLHelperResult<TxVersionMap<'b>>
where
T: Transaction<'a, F> + Model + Clone + DeserializeOwned + Debug,
F: IntoEnumIterator + Serialize + Debug + PartialEq + Debug + Clone + 'a,
Expand All @@ -40,7 +45,7 @@ where
async fn send_reliable_submission<'a: 'b, 'b, T, F, C>(
transaction: &'b mut T,
client: &C,
) -> XRPLHelperResult<Tx<'b>>
) -> XRPLHelperResult<TxVersionMap<'b>>
where
T: Transaction<'a, F> + Model + Clone + DeserializeOwned + Debug,
F: IntoEnumIterator + Serialize + Debug + PartialEq + Debug + Clone + 'a,
Expand Down Expand Up @@ -72,7 +77,7 @@ async fn wait_for_final_transaction_result<'a: 'b, 'b, C>(
tx_hash: Cow<'a, str>,
client: &C,
last_ledger_sequence: u32,
) -> XRPLHelperResult<Tx<'b>>
) -> XRPLHelperResult<TxVersionMap<'b>>
where
C: XRPLAsyncClient,
{
Expand All @@ -81,7 +86,12 @@ where
while validated_ledger_sequence < last_ledger_sequence {
c += 1;
if c > 20 {
panic!()
return Err(XRPLSubmitAndWaitException::SubmissionTimeout {
last_ledger_sequence,
validated_ledger_sequence,
prelim_result: "Transaction not included in ledger".into(),
}
.into());
}
validated_ledger_sequence = get_latest_validated_ledger_sequence(client).await?;
// sleep for 1 second
Expand All @@ -94,18 +104,31 @@ where
if error == "txnNotFound" {
continue;
} else {
return Err(XRPLSubmitAndWaitException::SubmissionFailed(
format!("{}: {}", error, response.error_message.unwrap_or("".into()))
.into(),
)
return Err(XRPLSubmitAndWaitException::SubmissionFailed(format!(
"{}: {}",
error,
response.error_message.unwrap_or("".into())
))
.into());
}
} else {
let opt_result = response.try_into_opt_result::<Tx>()?;
let validated = opt_result.try_get_typed("validated")?;
let result: TxVersionMap = response.try_into()?;
let base = match &result {
TxVersionMap::Default(tx) => tx.base.clone(),
TxVersionMap::V1(tx) => tx.base.clone(),
};
let validated = base.validated.unwrap_or(false);
if validated {
let result = opt_result.try_into_result()?;
let return_code = match result.meta.get("TransactionResult") {
let meta = match result {
TxVersionMap::Default(ref tx) => tx.meta.clone(),
TxVersionMap::V1(TxV1 {
meta: Some(TxMetaV1::Json(ref meta)),
..
}) => Some(meta.clone()),
_ => None,
};
let meta = meta.unwrap(); // safe to unwrap because we requested using non-binary mode and we checked that the transaction was validated
let return_code = match meta.get("TransactionResult") {
Some(Value::String(s)) => s,
_ => {
return Err(XRPLSubmitAndWaitException::ExpectedFieldInTxMeta(
Expand Down
2 changes: 1 addition & 1 deletion src/asynch/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ where
Ok(client.get_faucet_url(url)?)
}

async fn check_balance<'a: 'b, 'b, C>(client: &C, address: Cow<'a, str>) -> XRPAmount<'b>
async fn check_balance<'a: 'b, 'b, C>(client: &'a C, address: Cow<'a, str>) -> XRPAmount<'b>
where
C: XRPLClient,
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/addresscodec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub fn decode_seed(seed: &str) -> XRPLCoreResult<([u8; SEED_LENGTH], CryptoAlgor
Some(Ok(val)) => {
let decoded: [u8; SEED_LENGTH] = val
.try_into()
.map_err(|err| XRPLAddressCodecException::VecResizeError(err))?;
.map_err(XRPLAddressCodecException::VecResizeError)?;
Ok((decoded, algo.expect("decode_seed")))
}
Some(Err(_)) | None => Err(XRPLAddressCodecException::UnknownSeedEncoding.into()),
Expand Down
Loading

0 comments on commit a5e7193

Please sign in to comment.