1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use super::{
    certificate_builder::CertificateBuilderResult, input_builder::InputBuilderResult,
    mint_builder::MintBuilderResult, withdrawal_builder::WithdrawalBuilderResult,
};
use crate::plutus::{ExUnits, LegacyRedeemer, PlutusData, RedeemerTag, Redeemers};
use cml_core_wasm::impl_wasm_conversions;
use wasm_bindgen::prelude::{wasm_bindgen, JsError};

#[wasm_bindgen]
#[derive(Clone, Copy, PartialOrd, Ord, Debug, PartialEq, Eq, Hash)]
pub struct RedeemerWitnessKey(cml_chain::builders::redeemer_builder::RedeemerWitnessKey);

impl_wasm_conversions!(
    cml_chain::builders::redeemer_builder::RedeemerWitnessKey,
    RedeemerWitnessKey
);

#[wasm_bindgen]
impl RedeemerWitnessKey {
    pub fn new(tag: RedeemerTag, index: u64) -> Self {
        cml_chain::builders::redeemer_builder::RedeemerWitnessKey::new(tag, index).into()
    }

    pub fn from_redeemer(redeemer: &LegacyRedeemer) -> Self {
        cml_chain::builders::redeemer_builder::RedeemerWitnessKey::from(redeemer.as_ref()).into()
    }
}

/// Redeemer without the tag of index
/// This allows builder code to return partial redeemers
/// and then later have them placed in the right context
#[wasm_bindgen]
#[derive(Clone, Debug)]
pub struct UntaggedRedeemer(cml_chain::builders::redeemer_builder::UntaggedRedeemer);

impl_wasm_conversions!(
    cml_chain::builders::redeemer_builder::UntaggedRedeemer,
    UntaggedRedeemer
);

#[wasm_bindgen]
impl UntaggedRedeemer {
    pub fn new(data: &PlutusData, ex_units: &ExUnits) -> Self {
        cml_chain::builders::redeemer_builder::UntaggedRedeemer::new(
            data.clone().into(),
            ex_units.clone().into(),
        )
        .into()
    }
}

/// In order to calculate the index from the sorted set, "add_*" methods in this builder
/// must be called along with the "add_*" methods in transaction builder.
#[wasm_bindgen]
#[derive(Clone, Default, Debug)]
pub struct RedeemerSetBuilder(cml_chain::builders::redeemer_builder::RedeemerSetBuilder);

impl_wasm_conversions!(
    cml_chain::builders::redeemer_builder::RedeemerSetBuilder,
    RedeemerSetBuilder
);

#[wasm_bindgen]
impl RedeemerSetBuilder {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    /// note: will override existing value if called twice with the same key
    pub fn update_ex_units(&mut self, key: &RedeemerWitnessKey, ex_units: &ExUnits) {
        self.0
            .update_ex_units((*key).into(), ex_units.clone().into());
    }

    pub fn add_spend(&mut self, result: &InputBuilderResult) {
        self.0.add_spend(result.as_ref());
    }

    pub fn add_mint(&mut self, result: &MintBuilderResult) {
        self.0.add_mint(result.as_ref());
    }

    pub fn add_reward(&mut self, result: &WithdrawalBuilderResult) {
        self.0.add_reward(result.as_ref());
    }

    pub fn add_cert(&mut self, result: &CertificateBuilderResult) {
        self.0.add_cert(result.as_ref());
    }

    pub fn build(&self, default_to_dummy_exunits: bool) -> Result<Redeemers, JsError> {
        self.0
            .build(default_to_dummy_exunits)
            .map(Into::into)
            .map_err(Into::into)
    }
}