Skip to content

Commit

Permalink
add xchain transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
LimpidCrypto committed Sep 11, 2024
1 parent 004261f commit 0cee573
Show file tree
Hide file tree
Showing 9 changed files with 813 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/models/transactions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ pub mod set_regular_key;
pub mod signer_list_set;
pub mod ticket_create;
pub mod trust_set;
pub mod xchain_account_create_commit;
pub mod xchain_add_account_create_attestation;
pub mod xchain_add_claim_attestation;
pub mod xchain_claim;
pub mod xchain_commit;
pub mod xchain_create_bridge;
pub mod xchain_create_claim_id;
pub mod xchain_modify_bridge;

use super::FlagCollection;
use super::{Currency, FlagCollection};
use crate::core::binarycodec::encode;
use crate::models::amount::XRPAmount;
use crate::Err;
Expand Down Expand Up @@ -75,6 +83,14 @@ pub enum TransactionType {
SignerListSet,
TicketCreate,
TrustSet,
XChainAccountCreateCommit,
XChainAddAccountCreateAttestation,
XChainAddClaimAttestation,
XChainClaim,
XChainCommit,
XChainCreateBridge,
XChainCreateClaimID,
XChainModifyBridge,

// Psuedo-Transaction types,
EnableAmendment,
Expand Down Expand Up @@ -358,6 +374,15 @@ pub enum Flag {
EnableAmendment(pseudo_transactions::enable_amendment::EnableAmendmentFlag),
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct XChainBridge<'a> {
pub issuing_chain_door: Cow<'a, str>,
pub issuing_chain_issue: Currency<'a>,
pub locking_chain_door: Cow<'a, str>,
pub locking_chain_issue: Currency<'a>,
}

#[cfg(all(
feature = "std",
feature = "websocket",
Expand Down
107 changes: 107 additions & 0 deletions src/models/transactions/xchain_account_create_commit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use core::fmt::Debug;

use alloc::{borrow::Cow, vec::Vec};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;

use crate::models::{FlagCollection, Model, NoFlags, XRPAmount};

use super::{CommonFields, Memo, Signer, Transaction, TransactionType, XChainBridge};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
#[skip_serializing_none]
pub struct XChainAccountCreateCommit<'a> {
#[serde(flatten)]
pub common_fields: CommonFields<'a, NoFlags>,
pub amount: XRPAmount<'a>,
pub destination: Cow<'a, str>,
#[serde(rename = "XChainBridge")]
pub xchain_bridge: XChainBridge<'a>,
pub signature_reward: Option<XRPAmount<'a>>,
}

impl Model for XChainAccountCreateCommit<'_> {}

impl<'a> Transaction<'a, NoFlags> for XChainAccountCreateCommit<'a> {
fn get_transaction_type(&self) -> super::TransactionType {
TransactionType::XChainAccountCreateCommit
}

fn get_common_fields(&self) -> &CommonFields<'_, NoFlags> {
&self.common_fields
}

fn get_mut_common_fields(&mut self) -> &mut CommonFields<'a, NoFlags> {
&mut self.common_fields
}
}

impl<'a> XChainAccountCreateCommit<'a> {
pub fn new(
account: Cow<'a, str>,
account_txn_id: Option<Cow<'a, str>>,
fee: Option<XRPAmount<'a>>,
last_ledger_sequence: Option<u32>,
memos: Option<Vec<Memo>>,
sequence: Option<u32>,
signers: Option<Vec<Signer<'a>>>,
source_tag: Option<u32>,
ticket_sequence: Option<u32>,
amount: XRPAmount<'a>,
destination: Cow<'a, str>,
xchain_bridge: XChainBridge<'a>,
signature_reward: Option<XRPAmount<'a>>,
) -> XChainAccountCreateCommit<'a> {
XChainAccountCreateCommit {
common_fields: CommonFields {
account,
transaction_type: TransactionType::XChainAccountCreateCommit,
account_txn_id,
fee,
flags: FlagCollection::default(),
last_ledger_sequence,
memos,
sequence,
signers,
source_tag,
ticket_sequence,
network_id: None,
signing_pub_key: None,
txn_signature: None,
},
amount,
destination,
xchain_bridge,
signature_reward,
}
}
}

#[cfg(test)]
mod test_serde {
use super::XChainAccountCreateCommit;

#[test]
fn test_deserialize() {
let json = r#"{
"Account": "rwEqJ2UaQHe7jihxGqmx6J4xdbGiiyMaGa",
"Destination": "rD323VyRjgzzhY4bFpo44rmyh2neB5d8Mo",
"TransactionType": "XChainAccountCreateCommit",
"Amount": "20000000",
"SignatureReward": "100",
"XChainBridge": {
"LockingChainDoor": "rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4",
"LockingChainIssue": {
"currency": "XRP"
},
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"IssuingChainIssue": {
"currency": "XRP"
}
}
}"#;
let txn: XChainAccountCreateCommit<'_> = serde_json::from_str(json).unwrap();
assert_eq!(txn.amount, "20000000".into());
}
}
149 changes: 149 additions & 0 deletions src/models/transactions/xchain_add_account_create_attestation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use alloc::{borrow::Cow, vec::Vec};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;

use crate::models::{Amount, FlagCollection, Model, NoFlags, XRPAmount};

use super::{CommonFields, Memo, Signer, Transaction, TransactionType, XChainBridge};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
#[skip_serializing_none]
pub struct XChainAddAccountCreateAttestation<'a> {
#[serde(flatten)]
pub common_fields: CommonFields<'a, NoFlags>,
pub amount: Amount<'a>,
pub attestation_reward_account: Cow<'a, str>,
pub attestation_signer_account: Cow<'a, str>,
pub destination: Cow<'a, str>,
pub other_chain_source: Cow<'a, str>,
pub public_key: Cow<'a, str>,
pub signature: Cow<'a, str>,
pub signature_reward: Amount<'a>,
pub was_locking_chain_send: u8,
#[serde(rename = "XChainAccountCreateCount")]
pub xchain_account_create_count: Cow<'a, str>,
#[serde(rename = "XChainBridge")]
pub xchain_bridge: XChainBridge<'a>,
}

impl Model for XChainAddAccountCreateAttestation<'_> {}

impl<'a> Transaction<'a, NoFlags> for XChainAddAccountCreateAttestation<'a> {
fn get_transaction_type(&self) -> super::TransactionType {
TransactionType::XChainAddAccountCreateAttestation
}

fn get_common_fields(&self) -> &super::CommonFields<'_, NoFlags> {
&self.common_fields
}

fn get_mut_common_fields(&mut self) -> &mut super::CommonFields<'a, NoFlags> {
&mut self.common_fields
}
}

impl<'a> XChainAddAccountCreateAttestation<'a> {
pub fn new(
account: Cow<'a, str>,
account_txn_id: Option<Cow<'a, str>>,
fee: Option<XRPAmount<'a>>,
last_ledger_sequence: Option<u32>,
memos: Option<Vec<Memo>>,
sequence: Option<u32>,
signers: Option<Vec<Signer<'a>>>,
source_tag: Option<u32>,
ticket_sequence: Option<u32>,
amount: Amount<'a>,
attestation_reward_account: Cow<'a, str>,
attestation_signer_account: Cow<'a, str>,
destination: Cow<'a, str>,
other_chain_source: Cow<'a, str>,
public_key: Cow<'a, str>,
signature: Cow<'a, str>,
signature_reward: Amount<'a>,
was_locking_chain_send: u8,
xchain_account_create_count: Cow<'a, str>,
xchain_bridge: XChainBridge<'a>,
) -> XChainAddAccountCreateAttestation<'a> {
XChainAddAccountCreateAttestation {
common_fields: CommonFields {
account,
transaction_type: TransactionType::XChainAddAccountCreateAttestation,
account_txn_id,
fee,
flags: FlagCollection::default(),
last_ledger_sequence,
memos,
sequence,
signers,
source_tag,
ticket_sequence,
network_id: None,
signing_pub_key: None,
txn_signature: None,
},
amount,
attestation_reward_account,
attestation_signer_account,
destination,
other_chain_source,
public_key,
signature,
signature_reward,
was_locking_chain_send,
xchain_account_create_count,
xchain_bridge,
}
}
}

#[cfg(test)]
mod test_serde {
const EXAMPLE_JSON: &'static str = r#"{
"Account": "rDr5okqGKmMpn44Bbhe5WAfDQx8e9XquEv",
"Flags": 0,
"TransactionType": "XChainAddAccountCreateAttestation",
"OtherChainSource": "rUzB7yg1LcFa7m3q1hfrjr5w53vcWzNh3U",
"Destination": "rJMfWNVbyjcCtds8kpoEjEbYQ41J5B6MUd",
"Amount": "2000000000",
"PublicKey": "EDF7C3F9C80C102AF6D241752B37356E91ED454F26A35C567CF6F8477960F66614",
"Signature": "F95675BA8FDA21030DE1B687937A79E8491CE51832D6BEEBC071484FA5AF5B8A0E9AFF11A4AA46F09ECFFB04C6A8DAE8284AF3ED8128C7D0046D842448478500",
"WasLockingChainSend": 1,
"AttestationRewardAccount": "rpFp36UHW6FpEcZjZqq5jSJWY6UCj3k4Es",
"AttestationSignerAccount": "rpWLegmW9WrFBzHUj7brhQNZzrxgLj9oxw",
"XChainAccountCreateCount": "2",
"SignatureReward": "204",
"XChainBridge": {
"LockingChainDoor": "r3nCVTbZGGYoWvZ58BcxDmiMUU7ChMa1eC",
"LockingChainIssue": {
"currency": "XRP"
},
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"IssuingChainIssue": {
"currency": "XRP"
}
},
"Fee": "20"
}"#;
use serde_json::Value;

use super::*;

#[test]
fn test_deserialize() {
let json = EXAMPLE_JSON;
let deserialized: Result<XChainAddAccountCreateAttestation, _> = serde_json::from_str(json);
assert!(deserialized.is_ok());
}

#[test]
fn test_serialize() {
let attestation: XChainAddAccountCreateAttestation<'_> =
serde_json::from_str(EXAMPLE_JSON).unwrap();
let actual = serde_json::to_value(&attestation).unwrap();
let expected: Value = serde_json::from_str(EXAMPLE_JSON).unwrap();

assert_eq!(actual, expected);
}
}
Loading

0 comments on commit 0cee573

Please sign in to comment.