waves_rust/model/transaction/
sponsor_fee_transaction.rs1use 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}