algonaut 0.4.2

A Rusty sdk for the Algorand blockchain.
Documentation
use algonaut_core::MultisigAddress;
use algonaut_transaction::{
    account::Account, contract_account::ContractAccount, error::TransactionError,
    transaction::TransactionSignature, SignedTransaction, Transaction,
};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TransactionSigner {
    BasicAccount(Account),
    ContractAccount(ContractAccount),
    MultisigAccount {
        address: MultisigAddress,
        accounts: Vec<Account>,
    },
}

impl TransactionSigner {
    pub fn sign_transactions(
        &self,
        tx_group: Vec<Transaction>,
    ) -> Result<Vec<SignedTransaction>, TransactionError> {
        match self {
            TransactionSigner::BasicAccount(account) => {
                let mut signed_txs = vec![];
                for tx in tx_group {
                    signed_txs.push(account.sign_transaction(tx)?);
                }
                Ok(signed_txs)
            }

            TransactionSigner::ContractAccount(account) => {
                let mut signed_txs = vec![];
                for tx in tx_group {
                    signed_txs.push(account.sign(tx, vec![])?);
                }
                Ok(signed_txs)
            }

            TransactionSigner::MultisigAccount { address, accounts } => {
                let mut signed_txs = vec![];
                for tx in tx_group {
                    signed_txs.push(sign_msig_tx(address, accounts, tx)?);
                }
                Ok(signed_txs)
            }
        }
    }
}

fn sign_msig_tx(
    address: &MultisigAddress,
    accounts: &[Account],
    tx: Transaction,
) -> Result<SignedTransaction, TransactionError> {
    if let Some(first_account) = accounts.first() {
        let mut msig = first_account.init_transaction_msig(&tx, address)?;
        for account in &accounts[1..accounts.len()] {
            msig = account.append_to_transaction_msig(&tx, msig)?;
        }

        let signed_t = SignedTransaction {
            transaction_id: tx.id()?,
            transaction: tx,
            sig: TransactionSignature::Multi(msig),
            auth_address: None,
        };

        Ok(signed_t)
    } else {
        Err(TransactionError::NoAccountsToSign)
    }
}