use pallas_applying::UTxOs; use pallas_codec::{minicbor::bytes::ByteVec, utils::TagWrap}; use pallas_primitives::{ alonzo::{MintedTx, TransactionBody, TransactionOutput, Value}, babbage::{ MintedDatumOption, MintedPostAlonzoTransactionOutput, MintedScriptRef, MintedTransactionBody, MintedTransactionOutput, MintedTx as BabbageMintedTx, PseudoTransactionOutput, }, byron::{Address, MintedTxPayload, Tx, TxOut}, }; use pallas_traverse::{Era, MultiEraInput, MultiEraOutput}; use std::{borrow::Cow, iter::zip, vec::Vec}; use pallas_codec::utils::{Bytes, CborWrap}; use pallas_crypto::hash::Hash; pub fn cbor_to_bytes(input: &str) -> Vec { hex::decode(input).unwrap() } pub fn minted_tx_from_cbor(tx_cbor: &[u8]) -> MintedTx<'_> { pallas_codec::minicbor::decode::(tx_cbor).unwrap() } pub fn babbage_minted_tx_from_cbor(tx_cbor: &[u8]) -> BabbageMintedTx<'_> { pallas_codec::minicbor::decode::(&tx_cbor[..]).unwrap() } pub fn minted_tx_payload_from_cbor<'a>(tx_cbor: &'a Vec) -> MintedTxPayload<'a> { pallas_codec::minicbor::decode::(&tx_cbor[..]).unwrap() } pub fn mk_utxo_for_byron_tx<'a>(tx: &Tx, tx_outs_info: &[(String, u64)]) -> UTxOs<'a> { let mut utxos: UTxOs = UTxOs::new(); for (tx_in, (address_payload, amount)) in zip(tx.inputs.clone().to_vec(), tx_outs_info) { let input_tx_out_addr: Address = match hex::decode(address_payload) { Ok(addr_bytes) => Address { payload: TagWrap(ByteVec::from(addr_bytes)), crc: 3430631884, }, _ => panic!("Unable to decode input address"), }; let tx_out: TxOut = TxOut { address: input_tx_out_addr, amount: *amount, }; let multi_era_in: MultiEraInput = MultiEraInput::Byron(Box::new(Cow::Owned(tx_in))); let multi_era_out: MultiEraOutput = MultiEraOutput::Byron(Box::new(Cow::Owned(tx_out))); utxos.insert(multi_era_in, multi_era_out); } utxos } pub fn mk_utxo_for_alonzo_compatible_tx<'a>( tx_body: &TransactionBody, tx_outs_info: &[( String, // address in string format Value, Option>, )], ) -> UTxOs<'a> { let mut utxos: UTxOs = UTxOs::new(); for (tx_in, (address, amount, datum_hash)) in zip(tx_body.inputs.clone(), tx_outs_info) { let multi_era_in: MultiEraInput = MultiEraInput::AlonzoCompatible(Box::new(Cow::Owned(tx_in))); let address_bytes: Bytes = match hex::decode(address) { Ok(bytes_vec) => Bytes::from(bytes_vec), _ => panic!("Unable to decode input address"), }; let tx_out: TransactionOutput = TransactionOutput { address: address_bytes, amount: amount.clone(), datum_hash: *datum_hash, }; let multi_era_out: MultiEraOutput = MultiEraOutput::AlonzoCompatible(Box::new(Cow::Owned(tx_out)), Era::Alonzo); utxos.insert(multi_era_in, multi_era_out); } utxos } pub fn mk_utxo_for_babbage_tx<'a>( tx_body: &MintedTransactionBody, tx_outs_info: &'a [( String, // address in string format Value, Option, Option>, )], ) -> UTxOs<'a> { let mut utxos: UTxOs = UTxOs::new(); for (tx_in, (addr, val, datum_opt, script_ref)) in zip(tx_body.inputs.clone(), tx_outs_info) { let multi_era_in: MultiEraInput = MultiEraInput::AlonzoCompatible(Box::new(Cow::Owned(tx_in))); let address_bytes: Bytes = match hex::decode(addr) { Ok(bytes_vec) => Bytes::from(bytes_vec), _ => panic!("Unable to decode input address"), }; let tx_out: MintedTransactionOutput = PseudoTransactionOutput::PostAlonzo(MintedPostAlonzoTransactionOutput { address: address_bytes, value: val.clone(), datum_option: datum_opt.clone(), script_ref: script_ref.clone(), }); let multi_era_out: MultiEraOutput = MultiEraOutput::Babbage(Box::new(Cow::Owned(tx_out))); utxos.insert(multi_era_in, multi_era_out); } utxos } pub fn add_collateral_alonzo<'a>( tx_body: &TransactionBody, utxos: &mut UTxOs<'_>, collateral_info: &[( String, // address in string format Value, Option>, )], ) { match &tx_body.collateral { Some(collaterals) => { for (tx_in, (address, amount, datum_hash)) in zip(collaterals, collateral_info) { let address_bytes: Bytes = match hex::decode(address) { Ok(bytes_vec) => Bytes::from(bytes_vec), _ => panic!("Unable to decode input address"), }; let tx_out: TransactionOutput = TransactionOutput { address: address_bytes, amount: amount.clone(), datum_hash: *datum_hash, }; let multi_era_in: MultiEraInput = MultiEraInput::AlonzoCompatible(Box::new(Cow::Owned(tx_in.clone()))); let multi_era_out: MultiEraOutput = MultiEraOutput::AlonzoCompatible(Box::new(Cow::Owned(tx_out)), Era::Alonzo); utxos.insert(multi_era_in, multi_era_out); } } None => panic!("Adding collateral to UTxO failed due to an empty list of collaterals"), } } pub fn add_collateral_babbage<'a>( tx_body: &MintedTransactionBody, utxos: &mut UTxOs<'a>, collateral_info: &'a [( String, // address in string format Value, Option, Option>, )], ) { match &tx_body.collateral { Some(collaterals) => { if collaterals.is_empty() { panic!("UTxO addition error - collateral input missing") } else { for (tx_in, (addr, val, datum_opt, script_ref)) in zip(collaterals.clone(), collateral_info) { let multi_era_in: MultiEraInput = MultiEraInput::AlonzoCompatible(Box::new(Cow::Owned(tx_in))); let address_bytes: Bytes = match hex::decode(addr) { Ok(bytes_vec) => Bytes::from(bytes_vec), _ => panic!("Unable to decode input address"), }; let tx_out: MintedTransactionOutput = PseudoTransactionOutput::PostAlonzo(MintedPostAlonzoTransactionOutput { address: address_bytes, value: val.clone(), datum_option: datum_opt.clone(), script_ref: script_ref.clone(), }); let multi_era_out: MultiEraOutput = MultiEraOutput::Babbage(Box::new(Cow::Owned(tx_out))); utxos.insert(multi_era_in, multi_era_out); } } } None => panic!("UTxO addition error - collateral input missing"), } } pub fn add_ref_input_babbage<'a>( tx_body: &MintedTransactionBody, utxos: &mut UTxOs<'a>, ref_input_info: &'a [( String, // address in string format Value, Option, Option>, )], ) { match &tx_body.reference_inputs { Some(ref_inputs) => { if ref_inputs.is_empty() { panic!("UTxO addition error - reference input missing") } else { for (tx_in, (addr, val, datum_opt, script_ref)) in zip(ref_inputs.clone(), ref_input_info) { let multi_era_in: MultiEraInput = MultiEraInput::AlonzoCompatible(Box::new(Cow::Owned(tx_in))); let address_bytes: Bytes = match hex::decode(addr) { Ok(bytes_vec) => Bytes::from(bytes_vec), _ => panic!("Unable to decode input address"), }; let tx_out: MintedTransactionOutput = PseudoTransactionOutput::PostAlonzo(MintedPostAlonzoTransactionOutput { address: address_bytes, value: val.clone(), datum_option: datum_opt.clone(), script_ref: script_ref.clone(), }); let multi_era_out: MultiEraOutput = MultiEraOutput::Babbage(Box::new(Cow::Owned(tx_out))); utxos.insert(multi_era_in, multi_era_out); } } } None => panic!("UTxO addition error - reference input missing"), } }