waves_rust/model/transaction/
lease_transaction.rs

1use crate::error::{Error, Result};
2use crate::model::{Address, ByteString};
3use crate::util::JsonDeserializer;
4use crate::waves_proto::{recipient, LeaseTransactionData, Recipient};
5use serde_json::{Map, Value};
6
7const TYPE: u8 = 8;
8
9#[derive(Clone, Eq, PartialEq, Debug)]
10pub struct LeaseTransactionInfo {
11    recipient: Address,
12    amount: u64,
13}
14
15impl LeaseTransactionInfo {
16    pub fn new(recipient: Address, amount: u64) -> Self {
17        Self { recipient, amount }
18    }
19
20    pub fn amount(&self) -> u64 {
21        self.amount
22    }
23
24    pub fn recipient(&self) -> Address {
25        self.recipient.clone()
26    }
27}
28
29impl TryFrom<&Value> for LeaseTransactionInfo {
30    type Error = Error;
31
32    fn try_from(value: &Value) -> Result<Self> {
33        let amount = JsonDeserializer::safe_to_int_from_field(value, "amount")?;
34        let recipient = JsonDeserializer::safe_to_string_from_field(value, "recipient")?;
35
36        Ok(LeaseTransactionInfo {
37            recipient: Address::from_string(&recipient)?,
38            amount: amount as u64,
39        })
40    }
41}
42
43#[derive(Clone, Eq, PartialEq, Debug)]
44pub struct LeaseTransaction {
45    recipient: Address,
46    amount: u64,
47}
48
49impl LeaseTransaction {
50    pub fn new(recipient: Address, amount: u64) -> Self {
51        Self { recipient, amount }
52    }
53
54    pub fn tx_type() -> u8 {
55        TYPE
56    }
57
58    pub fn amount(&self) -> u64 {
59        self.amount
60    }
61
62    pub fn recipient(&self) -> Address {
63        self.recipient.clone()
64    }
65}
66
67impl TryFrom<&Value> for LeaseTransaction {
68    type Error = Error;
69
70    fn try_from(value: &Value) -> Result<Self> {
71        let amount = JsonDeserializer::safe_to_int_from_field(value, "amount")?;
72        let recipient = JsonDeserializer::safe_to_string_from_field(value, "recipient")?;
73
74        Ok(LeaseTransaction {
75            recipient: Address::from_string(&recipient)?,
76            amount: amount as u64,
77        })
78    }
79}
80
81impl TryFrom<&LeaseTransaction> for Map<String, Value> {
82    type Error = Error;
83
84    fn try_from(value: &LeaseTransaction) -> Result<Self> {
85        let mut lease_tx_json = Map::new();
86
87        lease_tx_json.insert("recipient".to_owned(), value.recipient().encoded().into());
88        lease_tx_json.insert("amount".to_owned(), value.amount().into());
89
90        Ok(lease_tx_json)
91    }
92}
93
94impl TryFrom<&LeaseTransaction> for LeaseTransactionData {
95    type Error = Error;
96
97    fn try_from(value: &LeaseTransaction) -> Result<Self> {
98        let recipient = Some(Recipient {
99            recipient: Some(recipient::Recipient::PublicKeyHash(
100                value.recipient().public_key_hash(),
101            )),
102        });
103
104        Ok(LeaseTransactionData {
105            recipient,
106            amount: value.amount as i64,
107        })
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use crate::error::Result;
114    use crate::model::{Address, ByteString, LeaseTransaction, LeaseTransactionInfo};
115    use crate::waves_proto::recipient::Recipient;
116    use crate::waves_proto::LeaseTransactionData;
117    use serde_json::{json, Map, Value};
118    use std::borrow::Borrow;
119    use std::fs;
120
121    #[test]
122    fn test_json_to_lease_transaction() {
123        let data =
124            fs::read_to_string("./tests/resources/lease_rs.json").expect("Unable to read file");
125        let json: Value = serde_json::from_str(&data).expect("failed to generate json from str");
126
127        let lease_from_json: LeaseTransactionInfo = json.borrow().try_into().unwrap();
128
129        assert_eq!(
130            "3MxtrLkrbcG28uTvmbKmhrwGrR65ooHVYvK",
131            lease_from_json.recipient().encoded()
132        );
133        assert_eq!(100, lease_from_json.amount());
134    }
135
136    #[test]
137    fn test_lease_transaction_to_proto() -> Result<()> {
138        let lease_tx = &LeaseTransaction::new(
139            Address::from_string("3MxtrLkrbcG28uTvmbKmhrwGrR65ooHVYvK")?,
140            32,
141        );
142        let proto: LeaseTransactionData = lease_tx.try_into()?;
143
144        assert_eq!(proto.amount as u64, lease_tx.amount());
145
146        let proto_recipient =
147            if let Recipient::PublicKeyHash(bytes) = proto.recipient.unwrap().recipient.unwrap() {
148                bytes
149            } else {
150                panic!("expected dapp public key hash")
151            };
152        assert_eq!(proto_recipient, lease_tx.recipient().public_key_hash());
153        Ok(())
154    }
155
156    #[test]
157    fn test_lease_transaction_to_json() -> Result<()> {
158        let lease_tx = &LeaseTransaction::new(
159            Address::from_string("3MxtrLkrbcG28uTvmbKmhrwGrR65ooHVYvK")?,
160            32,
161        );
162
163        let map: Map<String, Value> = lease_tx.try_into()?;
164        let json: Value = map.into();
165        let expected_json = json!({
166            "amount": 32,
167            "recipient": "3MxtrLkrbcG28uTvmbKmhrwGrR65ooHVYvK"
168        });
169        assert_eq!(expected_json, json);
170        Ok(())
171    }
172}