whisky_csl/tx_parser/
outputs.rs1use cardano_serialization_lib::{self as csl};
2use whisky_common::*;
3
4use super::TxParser;
5
6impl TxParser {
7 pub fn outputs(&mut self) -> Result<Vec<Output>, WError> {
8 let mut parsed_outputs = vec![];
9 for i in 0..self.csl_tx_body.outputs().len() {
10 let tx_output = self.csl_tx_body.outputs().get(i);
11 parsed_outputs.push(
12 csl_output_to_whisky_output(tx_output)
13 .map_err(WError::from_err("TxParser - outputs"))?,
14 )
15 }
16 self.tx_body.outputs = parsed_outputs.clone();
17 Ok(parsed_outputs)
18 }
19
20 pub fn get_tx_outs_utxo(&self) -> Result<Vec<UTxO>, WError> {
21 let tx_outs = self.tx_body.outputs.clone();
22 let mut result = vec![];
23 tx_outs.iter().enumerate().for_each(|(i, current_tx_out)| {
24 let (data_hash, plutus_data) = match current_tx_out.clone().datum {
25 Some(Datum::Hash(data)) => {
26 let data_hash = Some(data);
27 (data_hash, None)
28 }
29 Some(Datum::Inline(data)) => {
30 let datum_cbor =
31 csl::PlutusData::from_json(&data, csl::PlutusDatumSchema::DetailedSchema)
32 .unwrap() .to_hex();
34 let plutus_data = Some(datum_cbor);
35 (None, plutus_data)
36 }
37 Some(Datum::Embedded(data)) => {
38 let data_hash = Some(data);
39 (data_hash, None)
40 }
41 None => (None, None),
42 };
43 let tx_out_utxo: UTxO = UTxO {
44 input: UtxoInput {
45 output_index: i as u32,
46 tx_hash: self.tx_hash.clone(),
47 },
48 output: UtxoOutput {
49 address: current_tx_out.address.clone(),
50 amount: current_tx_out.amount.clone(),
51 data_hash,
52 plutus_data,
53 script_ref: None,
54 script_hash: None,
55 },
56 };
57 result.push(tx_out_utxo);
58 });
59 Ok(result)
60 }
61
62 pub fn get_tx_outs_cbor(&self) -> Vec<String> {
63 let tx_outs = self.csl_tx_body.outputs();
64 let mut result = vec![];
65 for i in 0..tx_outs.len() {
66 let tx_out: csl::TransactionOutput = tx_outs.get(i);
67 let tx_out_cbor = tx_out.to_hex();
68 result.push(tx_out_cbor);
69 }
70 result
71 }
72}
73
74fn csl_output_to_whisky_output(output: csl::TransactionOutput) -> Result<Output, WError> {
75 let mut value: Vec<Asset> = vec![];
76 value.push(Asset::new_from_str(
77 "lovelace",
78 &output.amount().coin().to_str(),
79 ));
80 let multi_asset = output.amount().multiasset();
81
82 match multi_asset {
83 None => {}
84 Some(multi_asset) => {
85 for policy_id_index in 0..multi_asset.keys().len() {
86 let policy_id = multi_asset.keys().get(policy_id_index);
87 let assets = multi_asset.get(&policy_id).unwrap();
88 for asset_index in 0..assets.keys().len() {
89 let asset_name = assets.keys().get(asset_index);
90 let asset_quantity = assets.get(&asset_name).unwrap();
91 let concated_name = policy_id.to_hex() + &asset_name.to_string();
92
93 value.push(Asset::new_from_str(
94 &concated_name,
95 &asset_quantity.to_str(),
96 ))
97 }
98 }
99 }
100 }
101
102 let datum: Option<Datum> = output.plutus_data().map(|csl_datum| {
104 Datum::Inline(
105 csl_datum
106 .to_json(csl::PlutusDatumSchema::DetailedSchema)
107 .unwrap(),
108 )
109 });
110
111 let reference_script: Option<OutputScriptSource> = match output.script_ref() {
112 Some(csl_script_ref) => {
113 let plutus_script = csl_script_ref.plutus_script().unwrap();
114 let language_version = match plutus_script.language_version().kind() {
115 csl::LanguageKind::PlutusV1 => LanguageVersion::V1,
116 csl::LanguageKind::PlutusV2 => LanguageVersion::V2,
117 csl::LanguageKind::PlutusV3 => LanguageVersion::V3,
118 };
119 Some(OutputScriptSource::ProvidedScriptSource(
120 ProvidedScriptSource {
121 script_cbor: plutus_script.to_hex(),
122 language_version,
123 },
124 ))
125 }
126 None => None,
127 };
128 Ok(Output {
129 address: output.address().to_bech32(None).unwrap(),
130 amount: value,
131 datum,
132 reference_script,
133 })
134}