whisky_csl/utils/
transaction.rs1use cardano_serialization_lib::{self as csl};
2use cryptoxide::blake2b::Blake2b;
3use whisky_common::WError;
4
5pub(crate) fn blake2b256(data: &[u8]) -> [u8; 32] {
6 let mut out = [0; 32];
7 Blake2b::blake2b(&mut out, data, &[]);
8 out
9}
10
11pub fn calculate_tx_hash(tx_hex: &str) -> Result<String, WError> {
12 let csl_tx = csl::FixedTransaction::from_hex(tx_hex).map_err(WError::from_err(
13 "calculate_tx_hash - invalid transaction hex",
14 ))?;
15 Ok(csl::TransactionHash::from(blake2b256(&csl_tx.raw_body())).to_hex())
16}
17
18pub fn sign_transaction(tx_hex: &str, signing_keys: &[&str]) -> Result<String, WError> {
19 let unsigned_transaction: csl::FixedTransaction = csl::FixedTransaction::from_hex(tx_hex)
20 .map_err(WError::from_err(
21 "sign_transaction - invalid transaction hex",
22 ))?;
23 let mut witness_set = unsigned_transaction.witness_set();
24 let mut vkey_witnesses = witness_set
25 .vkeys()
26 .unwrap_or_else(csl::Vkeywitnesses::new)
27 .clone();
28 for key in signing_keys {
29 let clean_hex = if &key[0..4] == "5820" && key.len() == 68 {
30 key[4..].to_string()
31 } else {
32 key.to_string()
33 };
34 let skey = csl::PrivateKey::from_hex(&clean_hex).map_err(WError::from_err(
35 "sign_transaction - invalid signing key hex",
36 ))?;
37 let vkey_witness = csl::make_vkey_witness(
38 &csl::TransactionHash::from(blake2b256(&unsigned_transaction.raw_body())),
39 &skey,
40 );
41 vkey_witnesses.add(&vkey_witness);
42 }
43 witness_set.set_vkeys(&vkey_witnesses);
44 let signed_transaction: csl::FixedTransaction = match &unsigned_transaction.raw_auxiliary_data()
45 {
46 Some(raw_auxiliary_data) => csl::FixedTransaction::new_with_auxiliary(
47 &unsigned_transaction.raw_body(),
48 &unsigned_transaction.raw_witness_set(),
49 raw_auxiliary_data,
50 true,
51 )
52 .map_err(WError::from_err(
53 "sign_transaction - failed to create transaction with auxiliary data",
54 ))?,
55 None => csl::FixedTransaction::new(
56 &unsigned_transaction.raw_body(),
57 &witness_set.to_bytes(),
58 true,
59 )
60 .map_err(WError::from_err(
61 "sign_transaction - failed to create transaction",
62 ))?,
63 };
64 Ok(signed_transaction.to_hex())
65}