whisky-csl 1.0.23

Wrapper around the cardano-serialization-lib for easier transaction building, heavily inspired by cardano-cli APIs
Documentation
use cardano_serialization_lib::{self as csl};
use cryptoxide::blake2b::Blake2b;
use whisky_common::WError;

pub(crate) fn blake2b256(data: &[u8]) -> [u8; 32] {
    let mut out = [0; 32];
    Blake2b::blake2b(&mut out, data, &[]);
    out
}

pub fn calculate_tx_hash(tx_hex: &str) -> Result<String, WError> {
    let csl_tx = csl::FixedTransaction::from_hex(tx_hex).map_err(WError::from_err(
        "calculate_tx_hash - invalid transaction hex",
    ))?;
    Ok(csl_tx.transaction_hash().to_hex())
}

pub fn sign_transaction(tx_hex: &str, signing_keys: &[&str]) -> Result<String, WError> {
    let unsigned_transaction: csl::FixedTransaction = csl::FixedTransaction::from_hex(tx_hex)
        .map_err(WError::from_err(
            "sign_transaction - invalid transaction hex",
        ))?;
    let mut witness_set = unsigned_transaction.witness_set();
    let mut vkey_witnesses = witness_set
        .vkeys()
        .unwrap_or_else(csl::Vkeywitnesses::new)
        .clone();
    for key in signing_keys {
        let clean_hex = if &key[0..4] == "5820" && key.len() == 68 {
            key[4..].to_string()
        } else {
            key.to_string()
        };
        let skey = csl::PrivateKey::from_hex(&clean_hex).map_err(WError::from_err(
            "sign_transaction - invalid signing key hex",
        ))?;
        let vkey_witness = csl::make_vkey_witness(
            &csl::TransactionHash::from(blake2b256(&unsigned_transaction.raw_body())),
            &skey,
        );
        vkey_witnesses.add(&vkey_witness);
    }
    witness_set.set_vkeys(&vkey_witnesses);
    let signed_transaction: csl::FixedTransaction = match &unsigned_transaction.raw_auxiliary_data()
    {
        Some(raw_auxiliary_data) => csl::FixedTransaction::new_with_auxiliary(
            &unsigned_transaction.raw_body(),
            &unsigned_transaction.raw_witness_set(),
            raw_auxiliary_data,
            true,
        )
        .map_err(WError::from_err(
            "sign_transaction - failed to create transaction with auxiliary data",
        ))?,
        None => csl::FixedTransaction::new(
            &unsigned_transaction.raw_body(),
            &witness_set.to_bytes(),
            true,
        )
        .map_err(WError::from_err(
            "sign_transaction - failed to create transaction",
        ))?,
    };
    Ok(signed_transaction.to_hex())
}