whisky_csl/tx_parser/
withdrawals.rs1use super::context::ParserContext;
2use super::context::RedeemerIndex;
3use super::context::Script;
4use super::CSLParser;
5use cardano_serialization_lib as csl;
6use whisky_common::{
7 PlutusScriptWithdrawal, PubKeyWithdrawal, ScriptSource, SimpleScriptSource,
8 SimpleScriptWithdrawal, WError, Withdrawal,
9};
10
11impl CSLParser {
12 pub fn get_withdrawals(&self) -> &Vec<Withdrawal> {
13 &self.tx_body.withdrawals
14 }
15
16 pub(super) fn extract_withdrawals(&mut self) -> Result<(), WError> {
17 let withdrawals = self.csl_tx_body.withdrawals();
18 if let Some(withdrawals) = withdrawals {
19 self.tx_body.withdrawals = csl_withdrawals_to_withdrawals(&withdrawals, &self.context)?;
20 }
21 Ok(())
22 }
23}
24
25pub fn csl_withdrawals_to_withdrawals(
26 withdrawals: &csl::Withdrawals,
27 context: &ParserContext,
28) -> Result<Vec<Withdrawal>, WError> {
29 let mut result = Vec::new();
30 let withdrawals_keys = withdrawals.keys();
31 let len = withdrawals_keys.len();
32 for i in 0..len {
33 let reward_address = withdrawals_keys.get(i);
34 let reward_address_bech32 = reward_address.to_address().to_bech32(None).map_err(|e| {
35 WError::new(
36 "csl_withdrawals_to_withdrawals",
37 &format!("Failed to convert address to bech32: {:?}", e),
38 )
39 })?;
40 let withdrawal_amount = withdrawals.get(&reward_address);
41 if let Some(withdrawal_amount) = withdrawal_amount {
42 let coin = withdrawal_amount.to_str().parse::<u64>().map_err(|e| {
43 WError::new(
44 "csl_withdrawals_to_withdrawals",
45 &format!("Failed to parse withdrawal amount: {:?}", e),
46 )
47 })?;
48
49 let redeemer = context
50 .script_witness
51 .redeemers
52 .get(&RedeemerIndex::Reward(i));
53
54 let script_hash = reward_address.payment_cred().to_scripthash();
55 let script = script_hash
56 .map(|sh| context.script_witness.scripts.get(&sh))
57 .flatten();
58
59 match script {
60 Some(script) => match script {
61 Script::ProvidedPlutus(plutus_script) => {
62 result.push(Withdrawal::PlutusScriptWithdrawal(PlutusScriptWithdrawal {
63 address: reward_address_bech32,
64 coin,
65 script_source: Some(ScriptSource::ProvidedScriptSource(
66 plutus_script.clone(),
67 )),
68 redeemer: redeemer.cloned(),
69 }));
70 }
71 Script::ProvidedNative(native_script) => {
72 result.push(Withdrawal::SimpleScriptWithdrawal(SimpleScriptWithdrawal {
73 address: reward_address_bech32,
74 coin,
75 script_source: Some(SimpleScriptSource::ProvidedSimpleScriptSource(
76 native_script.clone(),
77 )),
78 }));
79 }
80 Script::ReferencedNative(inline_simple_script_source) => {
81 result.push(Withdrawal::SimpleScriptWithdrawal(SimpleScriptWithdrawal {
82 address: reward_address_bech32,
83 coin,
84 script_source: Some(SimpleScriptSource::InlineSimpleScriptSource(
85 inline_simple_script_source.clone(),
86 )),
87 }));
88 }
89 Script::ReferencedPlutus(inline_script_source) => {
90 result.push(Withdrawal::PlutusScriptWithdrawal(PlutusScriptWithdrawal {
91 address: reward_address_bech32,
92 coin,
93 script_source: Some(ScriptSource::InlineScriptSource(
94 inline_script_source.clone(),
95 )),
96 redeemer: redeemer.cloned(),
97 }));
98 }
99 },
100 None => {
101 result.push(Withdrawal::PubKeyWithdrawal(PubKeyWithdrawal {
102 address: reward_address_bech32,
103 coin,
104 }));
105 }
106 }
107 }
108 }
109
110 Ok(result)
111}