cml_chain_wasm/builders/
witness_builder.rs

1use crate::{
2    address::RewardAddress,
3    byron::ByronAddress,
4    crypto::{BootstrapWitness, Vkeywitness},
5    plutus::{utils::PlutusScript, LegacyRedeemer, PlutusData},
6    transaction::TransactionWitnessSet,
7    Ed25519KeyHashList, LegacyRedeemerList, NativeScriptList, PlutusDataList, PlutusV1ScriptList,
8    PlutusV2ScriptList, Script,
9};
10use cml_core_wasm::impl_wasm_conversions;
11use cml_crypto_wasm::{DatumHash, Ed25519KeyHash, ScriptHash};
12use wasm_bindgen::prelude::{wasm_bindgen, JsError};
13
14use super::redeemer_builder::RedeemerWitnessKey;
15
16#[wasm_bindgen]
17#[derive(Debug, Clone)]
18pub struct PlutusScriptWitness(cml_chain::builders::witness_builder::PlutusScriptWitness);
19
20impl_wasm_conversions!(
21    cml_chain::builders::witness_builder::PlutusScriptWitness,
22    PlutusScriptWitness
23);
24
25#[wasm_bindgen]
26impl PlutusScriptWitness {
27    pub fn new_script(script: &PlutusScript) -> Self {
28        cml_chain::builders::witness_builder::PlutusScriptWitness::from(script.as_ref().clone())
29            .into()
30    }
31
32    pub fn new_ref(hash: &ScriptHash) -> Self {
33        cml_chain::builders::witness_builder::PlutusScriptWitness::from(*hash.as_ref()).into()
34    }
35
36    // pub fn script(&self) -> Option<PlutusScript> {
37    //     match self {
38    //         Self::Ref(_) => None,
39    //         Self::Script(script) => Some(script.clone()),
40    //     }
41    // }
42
43    pub fn hash(&self) -> ScriptHash {
44        self.0.hash().into()
45    }
46}
47
48/// A partial Plutus witness
49/// It contains all the information needed to witness the Plutus script execution
50/// except for the redeemer tag and index
51/// Note: no datum is attached because only input script types have datums
52#[wasm_bindgen]
53#[derive(Clone, Debug)]
54pub struct PartialPlutusWitness(cml_chain::builders::witness_builder::PartialPlutusWitness);
55
56impl_wasm_conversions!(
57    cml_chain::builders::witness_builder::PartialPlutusWitness,
58    PartialPlutusWitness
59);
60
61#[wasm_bindgen]
62impl PartialPlutusWitness {
63    pub fn new(script: &PlutusScriptWitness, data: &PlutusData) -> Self {
64        cml_chain::builders::witness_builder::PartialPlutusWitness::new(
65            script.clone().into(),
66            data.clone().into(),
67        )
68        .into()
69    }
70
71    pub fn script(&self) -> PlutusScriptWitness {
72        self.0.script.clone().into()
73    }
74
75    pub fn data(&self) -> PlutusData {
76        self.0.redeemer.clone().into()
77    }
78}
79
80#[wasm_bindgen]
81#[derive(Clone, Debug)]
82pub struct InputAggregateWitnessData(
83    cml_chain::builders::witness_builder::InputAggregateWitnessData,
84);
85
86impl_wasm_conversions!(
87    cml_chain::builders::witness_builder::InputAggregateWitnessData,
88    InputAggregateWitnessData
89);
90
91#[wasm_bindgen]
92impl InputAggregateWitnessData {
93    pub fn plutus_data(&self) -> Option<PlutusData> {
94        self.0.redeemer_plutus_data().map(|d| d.clone().into())
95    }
96}
97
98#[wasm_bindgen]
99#[derive(Clone, Debug, Default)]
100pub struct RequiredWitnessSet(cml_chain::builders::witness_builder::RequiredWitnessSet);
101
102impl_wasm_conversions!(
103    cml_chain::builders::witness_builder::RequiredWitnessSet,
104    RequiredWitnessSet
105);
106
107#[wasm_bindgen]
108impl RequiredWitnessSet {
109    pub fn add_vkey_key_hash(&mut self, hash: &Ed25519KeyHash) {
110        self.0.add_vkey_key_hash(hash.clone().into());
111    }
112
113    pub fn add_bootstrap(&mut self, address: &ByronAddress) {
114        self.0.add_bootstrap(address.clone().into());
115    }
116
117    pub fn add_script_ref(&mut self, script_hash: &ScriptHash) {
118        self.0.add_script_ref(script_hash.clone().into());
119    }
120
121    pub fn add_script_hash(&mut self, script_hash: &ScriptHash) {
122        self.0.add_script_hash(script_hash.clone().into());
123    }
124
125    pub fn add_plutus_datum_hash(&mut self, plutus_datum: &DatumHash) {
126        self.0.add_plutus_datum_hash(plutus_datum.clone().into());
127    }
128
129    pub fn add_redeemer_tag(&mut self, redeemer: &RedeemerWitnessKey) {
130        self.0.add_redeemer_tag((*redeemer).into());
131    }
132
133    pub fn add_all(&mut self, requirements: &RequiredWitnessSet) {
134        self.0.add_all(requirements.clone().into());
135    }
136
137    pub fn new() -> Self {
138        cml_chain::builders::witness_builder::RequiredWitnessSet::new().into()
139    }
140
141    // comes from witsVKeyNeeded in the Ledger spec
142    // this is here instead of withdrawal_builder.rs due to wasm restrictions on &mut params
143    pub fn withdrawal_required_wits(&mut self, address: &RewardAddress) {
144        cml_chain::builders::withdrawal_builder::withdrawal_required_wits(
145            address.as_ref(),
146            &mut self.0,
147        );
148    }
149}
150
151/// Builder de-duplicates witnesses as they are added
152#[wasm_bindgen]
153#[derive(Clone, Default, Debug)]
154pub struct TransactionWitnessSetBuilder(
155    cml_chain::builders::witness_builder::TransactionWitnessSetBuilder,
156);
157
158impl_wasm_conversions!(
159    cml_chain::builders::witness_builder::TransactionWitnessSetBuilder,
160    TransactionWitnessSetBuilder
161);
162
163#[wasm_bindgen]
164impl TransactionWitnessSetBuilder {
165    pub fn add_vkey(&mut self, vkey_witness: &Vkeywitness) {
166        self.0.add_vkey(vkey_witness.clone().into());
167    }
168
169    pub fn add_bootstrap(&mut self, bootstrap: &BootstrapWitness) {
170        self.0.add_bootstrap(bootstrap.clone().into())
171    }
172
173    pub fn add_script(&mut self, script: &Script) {
174        self.0.add_script(script.clone().into());
175    }
176
177    pub fn get_native_script(&self) -> NativeScriptList {
178        self.0.get_native_script().into()
179    }
180
181    pub fn get_plutus_v1_script(&self) -> PlutusV1ScriptList {
182        self.0.get_plutus_v1_script().into()
183    }
184
185    pub fn get_plutus_v2_script(&self) -> PlutusV2ScriptList {
186        self.0.get_plutus_v2_script().into()
187    }
188
189    pub fn add_plutus_datum(&mut self, plutus_datum: PlutusData) {
190        self.0.add_plutus_datum(plutus_datum.into());
191    }
192
193    pub fn get_plutus_datum(&self) -> PlutusDataList {
194        self.0.get_plutus_datum().into()
195    }
196
197    pub fn add_redeemer(&mut self, redeemer: &LegacyRedeemer) {
198        self.0.add_redeemer(redeemer.clone().into());
199    }
200
201    pub fn get_redeemer(&self) -> LegacyRedeemerList {
202        self.0.get_redeemer().into()
203    }
204
205    pub fn add_required_wits(&mut self, required_wits: &RequiredWitnessSet) {
206        self.0.add_required_wits(required_wits.clone().into());
207    }
208
209    pub fn new() -> Self {
210        cml_chain::builders::witness_builder::TransactionWitnessSetBuilder::new().into()
211    }
212
213    pub fn add_existing(&mut self, wit_set: &TransactionWitnessSet) {
214        self.0.add_existing(wit_set.clone().into());
215    }
216
217    pub fn build(&self) -> TransactionWitnessSet {
218        self.0.clone().build().into()
219    }
220
221    pub fn remaining_wits(&self) -> RequiredWitnessSet {
222        self.0.remaining_wits().into()
223    }
224
225    pub fn try_build(&self) -> Result<TransactionWitnessSet, JsError> {
226        self.0.try_build().map(Into::into).map_err(Into::into)
227    }
228
229    pub fn merge_fake_witness(&mut self, required_wits: &RequiredWitnessSet) {
230        cml_chain::builders::witness_builder::merge_fake_witness(
231            &mut self.0,
232            required_wits.as_ref(),
233        );
234    }
235}
236
237#[wasm_bindgen]
238#[derive(Clone, Debug)]
239pub struct NativeScriptWitnessInfo(cml_chain::builders::witness_builder::NativeScriptWitnessInfo);
240
241impl_wasm_conversions!(
242    cml_chain::builders::witness_builder::NativeScriptWitnessInfo,
243    NativeScriptWitnessInfo
244);
245
246#[wasm_bindgen]
247impl NativeScriptWitnessInfo {
248    /// Unsure which keys will sign, but you know the exact number to save on tx fee
249    pub fn num_signatures(num: usize) -> Self {
250        cml_chain::builders::witness_builder::NativeScriptWitnessInfo::num_signatures(num).into()
251    }
252
253    /// This native script will be witnessed by exactly these keys
254    pub fn vkeys(vkeys: &Ed25519KeyHashList) -> Self {
255        cml_chain::builders::witness_builder::NativeScriptWitnessInfo::vkeys(vkeys.clone().into())
256            .into()
257    }
258
259    /// You don't know how many keys will sign, so the maximum possible case will be assumed
260    pub fn assume_signature_count() -> Self {
261        cml_chain::builders::witness_builder::NativeScriptWitnessInfo::assume_signature_count()
262            .into()
263    }
264}