waves-rust 0.2.6

A Rust library for interacting with the Waves blockchain. Supports node interaction, offline transaction signing and creating addresses and keys.
Documentation
use crate::error::Result;
use crate::model::{Amount, PublicKey, Transaction, TransactionData};
use crate::util::get_current_epoch_millis;

#[derive(Clone, Eq, PartialEq, Debug)]
pub struct TransactionBuilder {
    data: TransactionData,
    fee: Option<Amount>,
    timestamp: Option<u64>,
    public_key: PublicKey,
    version: Option<u8>,
    chain_id: u8,
}

impl TransactionBuilder {
    pub fn new(public_key: &PublicKey, chain_id: u8, data: &TransactionData) -> TransactionBuilder {
        TransactionBuilder {
            data: data.clone(),
            fee: None,
            timestamp: None,
            public_key: public_key.clone(),
            version: None,
            chain_id,
        }
    }

    pub fn fee(&mut self, fee: Amount) -> &mut Self {
        self.fee = Some(fee);
        self
    }

    pub fn timestamp(&mut self, timestamp: u64) -> &mut Self {
        self.timestamp = Some(timestamp);
        self
    }

    pub fn version(&mut self, version: u8) -> &mut Self {
        self.version = Some(version);
        self
    }

    pub fn build(&self) -> Result<Transaction> {
        let transaction_data = self.data.clone();
        let fee = match self.fee.clone() {
            Some(fee) => fee,
            None => transaction_data.get_min_fee()?,
        };

        let timestamp = match self.timestamp {
            Some(timestamp) => timestamp,
            None => get_current_epoch_millis(),
        };

        let version = match self.version {
            Some(version) => version,
            None => transaction_data.get_min_supported_version(),
        };

        Ok(Transaction::new(
            transaction_data,
            fee,
            timestamp,
            self.public_key.clone(),
            version,
            self.chain_id,
        ))
    }
}

#[cfg(test)]
mod tests {
    use crate::model::{
        Amount, BurnTransaction, ChainId, PrivateKey, TransactionBuilder, TransactionData,
    };

    #[test]
    fn test_builder_default_params() {
        let private_key = PrivateKey::from_seed("123", 0).unwrap();

        let burn_transaction = BurnTransaction::new(Amount::new(1, None));

        let signed_tx = TransactionBuilder::new(
            &private_key.public_key(),
            ChainId::TESTNET.byte(),
            &TransactionData::Burn(burn_transaction),
        )
        .build()
        .unwrap()
        .sign(&private_key)
        .unwrap();

        assert_eq!(signed_tx.tx().fee().value(), 100_000);
        assert_eq!(signed_tx.tx().public_key(), private_key.public_key());
        assert_eq!(signed_tx.tx().tx_type(), 6);
        assert_eq!(signed_tx.tx().version(), 3);
        assert_eq!(signed_tx.tx().chain_id(), ChainId::TESTNET.byte())
    }

    #[test]
    fn test_builder_user_defined_params() {
        let private_key = PrivateKey::from_seed("123", 0).unwrap();

        let burn_transaction = BurnTransaction::new(Amount::new(1, None));
        let signed_tx = TransactionBuilder::new(
            &private_key.public_key(),
            ChainId::TESTNET.byte(),
            &TransactionData::Burn(burn_transaction),
        )
        .fee(Amount::new(10, None))
        .timestamp(100)
        .version(4)
        .build()
        .unwrap()
        .sign(&private_key)
        .unwrap();

        assert_eq!(signed_tx.tx().fee().value(), 10);
        assert_eq!(signed_tx.tx().timestamp(), 100);
        assert_eq!(signed_tx.tx().public_key(), private_key.public_key());
        assert_eq!(signed_tx.tx().tx_type(), 6);
        assert_eq!(signed_tx.tx().version(), 4);
        assert_eq!(signed_tx.tx().chain_id(), ChainId::TESTNET.byte())
    }
}