waves_rust/model/transaction/
transaction_builder.rs1use crate::error::Result;
2use crate::model::{Amount, PublicKey, Transaction, TransactionData};
3use crate::util::get_current_epoch_millis;
4
5#[derive(Clone, Eq, PartialEq, Debug)]
6pub struct TransactionBuilder {
7 data: TransactionData,
8 fee: Option<Amount>,
9 timestamp: Option<u64>,
10 public_key: PublicKey,
11 version: Option<u8>,
12 chain_id: u8,
13}
14
15impl TransactionBuilder {
16 pub fn new(public_key: &PublicKey, chain_id: u8, data: &TransactionData) -> TransactionBuilder {
17 TransactionBuilder {
18 data: data.clone(),
19 fee: None,
20 timestamp: None,
21 public_key: public_key.clone(),
22 version: None,
23 chain_id,
24 }
25 }
26
27 pub fn fee(&mut self, fee: Amount) -> &mut Self {
28 self.fee = Some(fee);
29 self
30 }
31
32 pub fn timestamp(&mut self, timestamp: u64) -> &mut Self {
33 self.timestamp = Some(timestamp);
34 self
35 }
36
37 pub fn version(&mut self, version: u8) -> &mut Self {
38 self.version = Some(version);
39 self
40 }
41
42 pub fn build(&self) -> Result<Transaction> {
43 let transaction_data = self.data.clone();
44 let fee = match self.fee.clone() {
45 Some(fee) => fee,
46 None => transaction_data.get_min_fee()?,
47 };
48
49 let timestamp = match self.timestamp {
50 Some(timestamp) => timestamp,
51 None => get_current_epoch_millis(),
52 };
53
54 let version = match self.version {
55 Some(version) => version,
56 None => transaction_data.get_min_supported_version(),
57 };
58
59 Ok(Transaction::new(
60 transaction_data,
61 fee,
62 timestamp,
63 self.public_key.clone(),
64 version,
65 self.chain_id,
66 ))
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use crate::model::{
73 Amount, BurnTransaction, ChainId, PrivateKey, TransactionBuilder, TransactionData,
74 };
75
76 #[test]
77 fn test_builder_default_params() {
78 let private_key = PrivateKey::from_seed("123", 0).unwrap();
79
80 let burn_transaction = BurnTransaction::new(Amount::new(1, None));
81
82 let signed_tx = TransactionBuilder::new(
83 &private_key.public_key(),
84 ChainId::TESTNET.byte(),
85 &TransactionData::Burn(burn_transaction),
86 )
87 .build()
88 .unwrap()
89 .sign(&private_key)
90 .unwrap();
91
92 assert_eq!(signed_tx.tx().fee().value(), 100_000);
93 assert_eq!(signed_tx.tx().public_key(), private_key.public_key());
94 assert_eq!(signed_tx.tx().tx_type(), 6);
95 assert_eq!(signed_tx.tx().version(), 3);
96 assert_eq!(signed_tx.tx().chain_id(), ChainId::TESTNET.byte())
97 }
98
99 #[test]
100 fn test_builder_user_defined_params() {
101 let private_key = PrivateKey::from_seed("123", 0).unwrap();
102
103 let burn_transaction = BurnTransaction::new(Amount::new(1, None));
104 let signed_tx = TransactionBuilder::new(
105 &private_key.public_key(),
106 ChainId::TESTNET.byte(),
107 &TransactionData::Burn(burn_transaction),
108 )
109 .fee(Amount::new(10, None))
110 .timestamp(100)
111 .version(4)
112 .build()
113 .unwrap()
114 .sign(&private_key)
115 .unwrap();
116
117 assert_eq!(signed_tx.tx().fee().value(), 10);
118 assert_eq!(signed_tx.tx().timestamp(), 100);
119 assert_eq!(signed_tx.tx().public_key(), private_key.public_key());
120 assert_eq!(signed_tx.tx().tx_type(), 6);
121 assert_eq!(signed_tx.tx().version(), 4);
122 assert_eq!(signed_tx.tx().chain_id(), ChainId::TESTNET.byte())
123 }
124}