waves_rust/model/transaction/
payment_transaction.rs

1use crate::error::{Error, Result};
2use crate::model::{Address, ByteString};
3use crate::util::JsonDeserializer;
4use crate::waves_proto::PaymentTransactionData;
5use serde_json::Value;
6
7const TYPE: u8 = 2;
8
9#[derive(Clone, Eq, PartialEq, Debug)]
10pub struct PaymentTransactionInfo {
11    recipient: Address,
12    amount: u64,
13}
14
15impl PaymentTransactionInfo {
16    pub fn new(recipient: Address, amount: u64) -> Self {
17        Self { recipient, amount }
18    }
19
20    pub fn recipient(&self) -> Address {
21        self.recipient.clone()
22    }
23
24    pub fn amount(&self) -> u64 {
25        self.amount
26    }
27}
28
29#[derive(Clone, Eq, PartialEq, Debug)]
30pub struct PaymentTransaction {
31    recipient: Address,
32    amount: u64,
33}
34
35impl PaymentTransaction {
36    pub fn new(recipient: Address, amount: u64) -> Self {
37        Self { recipient, amount }
38    }
39
40    pub fn recipient(&self) -> Address {
41        self.recipient.clone()
42    }
43
44    pub fn amount(&self) -> u64 {
45        self.amount
46    }
47
48    pub fn tx_type() -> u8 {
49        TYPE
50    }
51}
52
53impl TryFrom<&PaymentTransaction> for PaymentTransactionData {
54    type Error = Error;
55
56    fn try_from(value: &PaymentTransaction) -> Result<Self> {
57        Ok(PaymentTransactionData {
58            recipient_address: value.recipient().bytes(),
59            amount: value.amount() as i64,
60        })
61    }
62}
63
64impl TryFrom<&Value> for PaymentTransactionInfo {
65    type Error = Error;
66
67    fn try_from(value: &Value) -> Result<Self> {
68        let amount = JsonDeserializer::safe_to_int_from_field(value, "amount")?;
69        let recipient = JsonDeserializer::safe_to_string_from_field(value, "recipient")?;
70        Ok(PaymentTransactionInfo {
71            recipient: Address::from_string(&recipient)?,
72            amount: amount as u64,
73        })
74    }
75}
76
77impl TryFrom<&Value> for PaymentTransaction {
78    type Error = Error;
79
80    fn try_from(value: &Value) -> Result<Self> {
81        let amount = JsonDeserializer::safe_to_int_from_field(value, "amount")?;
82        let recipient = JsonDeserializer::safe_to_string_from_field(value, "recipient")?;
83        Ok(PaymentTransaction {
84            recipient: Address::from_string(&recipient)?,
85            amount: amount as u64,
86        })
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use crate::error::Result;
93    use crate::model::{
94        Address, ByteString, PaymentTransaction, SignedTransaction, TransactionInfoResponse,
95    };
96    use crate::waves_proto::PaymentTransactionData;
97    use serde_json::Value;
98    use std::fs;
99
100    #[test]
101    fn test_json_to_payment_transaction() -> Result<()> {
102        let data = fs::read_to_string("./tests/resources/payment_transaction_rs.json")
103            .expect("Unable to read file");
104        let json: &Value = &serde_json::from_str(&data).expect("failed to generate json from str");
105
106        let payment_tx: SignedTransaction = json.try_into()?;
107
108        let payment_tx_info: TransactionInfoResponse = json.try_into()?;
109
110        assert_eq!(payment_tx.id()?, payment_tx_info.id());
111
112        let payment_from_json: PaymentTransaction = json.try_into().unwrap();
113
114        assert_eq!(910924657498, payment_from_json.amount());
115        assert_eq!(
116            "3PP4hNGAJaMqmx9vpdYUHk8owF3mwbUevoz",
117            payment_from_json.recipient().encoded()
118        );
119        Ok(())
120    }
121
122    #[test]
123    fn test_payment_to_proto() -> Result<()> {
124        let payment_tx = &PaymentTransaction::new(
125            Address::from_string("3PP4hNGAJaMqmx9vpdYUHk8owF3mwbUevoz")?,
126            32,
127        );
128        let proto: PaymentTransactionData = payment_tx.try_into()?;
129
130        assert_eq!(proto.recipient_address, payment_tx.recipient().bytes());
131        assert_eq!(proto.amount as u64, payment_tx.amount());
132        Ok(())
133    }
134}