whisky-csl 1.0.13

Wrapper around the cardano-serialization-lib for easier transaction building, heavily inspired by cardano-cli APIs
Documentation
use super::context::ParserContext;
use super::context::RedeemerIndex;
use super::context::Script;
use super::CSLParser;
use cardano_serialization_lib as csl;
use whisky_common::{
    PlutusScriptWithdrawal, PubKeyWithdrawal, ScriptSource, SimpleScriptSource,
    SimpleScriptWithdrawal, WError, Withdrawal,
};

impl CSLParser {
    pub fn get_withdrawals(&self) -> &Vec<Withdrawal> {
        &self.tx_body.withdrawals
    }

    pub(super) fn extract_withdrawals(&mut self) -> Result<(), WError> {
        let withdrawals = self.csl_tx_body.withdrawals();
        if let Some(withdrawals) = withdrawals {
            self.tx_body.withdrawals = csl_withdrawals_to_withdrawals(&withdrawals, &self.context)?;
        }
        Ok(())
    }
}

pub fn csl_withdrawals_to_withdrawals(
    withdrawals: &csl::Withdrawals,
    context: &ParserContext,
) -> Result<Vec<Withdrawal>, WError> {
    let mut result = Vec::new();
    let withdrawals_keys = withdrawals.keys();
    let len = withdrawals_keys.len();
    for i in 0..len {
        let reward_address = withdrawals_keys.get(i);
        let reward_address_bech32 = reward_address.to_address().to_bech32(None).map_err(|e| {
            WError::new(
                "csl_withdrawals_to_withdrawals",
                &format!("Failed to convert address to bech32: {:?}", e),
            )
        })?;
        let withdrawal_amount = withdrawals.get(&reward_address);
        if let Some(withdrawal_amount) = withdrawal_amount {
            let coin = withdrawal_amount.to_str().parse::<u64>().map_err(|e| {
                WError::new(
                    "csl_withdrawals_to_withdrawals",
                    &format!("Failed to parse withdrawal amount: {:?}", e),
                )
            })?;

            let redeemer = context
                .script_witness
                .redeemers
                .get(&RedeemerIndex::Reward(i));

            let script_hash = reward_address.payment_cred().to_scripthash();
            let script = script_hash
                .map(|sh| context.script_witness.scripts.get(&sh))
                .flatten();

            match script {
                Some(script) => match script {
                    Script::ProvidedPlutus(plutus_script) => {
                        result.push(Withdrawal::PlutusScriptWithdrawal(PlutusScriptWithdrawal {
                            address: reward_address_bech32,
                            coin,
                            script_source: Some(ScriptSource::ProvidedScriptSource(
                                plutus_script.clone(),
                            )),
                            redeemer: redeemer.cloned(),
                        }));
                    }
                    Script::ProvidedNative(native_script) => {
                        result.push(Withdrawal::SimpleScriptWithdrawal(SimpleScriptWithdrawal {
                            address: reward_address_bech32,
                            coin,
                            script_source: Some(SimpleScriptSource::ProvidedSimpleScriptSource(
                                native_script.clone(),
                            )),
                        }));
                    }
                    Script::ReferencedNative(inline_simple_script_source) => {
                        result.push(Withdrawal::SimpleScriptWithdrawal(SimpleScriptWithdrawal {
                            address: reward_address_bech32,
                            coin,
                            script_source: Some(SimpleScriptSource::InlineSimpleScriptSource(
                                inline_simple_script_source.clone(),
                            )),
                        }));
                    }
                    Script::ReferencedPlutus(inline_script_source) => {
                        result.push(Withdrawal::PlutusScriptWithdrawal(PlutusScriptWithdrawal {
                            address: reward_address_bech32,
                            coin,
                            script_source: Some(ScriptSource::InlineScriptSource(
                                inline_script_source.clone(),
                            )),
                            redeemer: redeemer.cloned(),
                        }));
                    }
                },
                None => {
                    result.push(Withdrawal::PubKeyWithdrawal(PubKeyWithdrawal {
                        address: reward_address_bech32,
                        coin,
                    }));
                }
            }
        }
    }

    Ok(result)
}