waves_rust/model/transaction/
sponsor_fee_transaction.rs

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