whisky/builder/
withdrawal.rs

1use crate::*;
2
3use super::{TxBuilder, WRedeemer};
4
5impl TxBuilder {
6    /// ## Transaction building method
7    ///
8    /// Indicate that the transaction is withdrawing using a plutus staking script in the TxBuilder instance
9    ///
10    /// ### Arguments
11    ///
12    /// * `language_version` - The language version of the script
13    ///
14    /// ### Returns
15    ///
16    /// * `Self` - The TxBuilder instance
17    pub fn withdrawal_plutus_script(&mut self, language_version: &LanguageVersion) -> &mut Self {
18        match language_version {
19            LanguageVersion::V1 => self.withdrawal_plutus_script_v1(),
20            LanguageVersion::V2 => self.withdrawal_plutus_script_v2(),
21            LanguageVersion::V3 => self.withdrawal_plutus_script_v3(),
22        }
23    }
24
25    /// ## Transaction building method
26    ///
27    /// Indicate that the transaction is withdrawing using a plutus V1 staking script in the TxBuilder instance
28    ///
29    /// ### Returns
30    ///
31    /// * `Self` - The TxBuilder instance
32    pub fn withdrawal_plutus_script_v1(&mut self) -> &mut Self {
33        self.adding_plutus_withdrawal = Some(LanguageVersion::V1);
34        self
35    }
36
37    /// ## Transaction building method
38    ///
39    /// Indicate that the transaction is withdrawing using a plutus V2 staking script in the TxBuilder instance
40    ///
41    /// ### Returns
42    ///
43    /// * `Self` - The TxBuilder instance
44    pub fn withdrawal_plutus_script_v2(&mut self) -> &mut Self {
45        self.adding_plutus_withdrawal = Some(LanguageVersion::V2);
46        self
47    }
48
49    /// ## Transaction building method
50    ///
51    /// Indicate that the transaction is withdrawing using a plutus V3 staking script in the TxBuilder instance
52    ///
53    /// ### Returns
54    ///
55    /// * `Self` - The TxBuilder instance
56    pub fn withdrawal_plutus_script_v3(&mut self) -> &mut Self {
57        self.adding_plutus_withdrawal = Some(LanguageVersion::V3);
58        self
59    }
60
61    /// ## Transaction building method
62    ///
63    /// Add a withdrawal reference to the TxBuilder instance
64    ///
65    /// ### Arguments
66    ///
67    /// * `tx_hash` - The transaction hash
68    /// * `tx_index` - The transaction index
69    /// * `withdrawal_script_hash` - The withdrawal script hash
70    /// * `script_size` - Size of the script
71    ///
72    /// ### Returns
73    ///
74    /// * `Self` - The TxBuilder instance
75    pub fn withdrawal_tx_in_reference(
76        &mut self,
77        tx_hash: &str,
78        tx_index: u32,
79        withdrawal_script_hash: &str,
80        script_size: usize,
81    ) -> &mut Self {
82        let withdrawal_item = self.withdrawal_item.take();
83        if withdrawal_item.is_none() {
84            panic!("Undefined output")
85        }
86        let withdrawal_item = withdrawal_item.unwrap();
87        match withdrawal_item {
88            Withdrawal::PubKeyWithdrawal(_) => {
89                panic!("Script reference cannot be defined for a pubkey withdrawal")
90            }
91            Withdrawal::SimpleScriptWithdrawal(mut withdrawal) => {
92                withdrawal.script_source = Some(SimpleScriptSource::InlineSimpleScriptSource(
93                    InlineSimpleScriptSource {
94                        ref_tx_in: RefTxIn {
95                            tx_hash: tx_hash.to_string(),
96                            tx_index,
97                            script_size: None,
98                        },
99                        simple_script_hash: withdrawal_script_hash.to_string(),
100                        script_size,
101                    },
102                ));
103                self.withdrawal_item = Some(Withdrawal::SimpleScriptWithdrawal(withdrawal));
104            }
105            Withdrawal::PlutusScriptWithdrawal(mut withdrawal) => {
106                withdrawal.script_source =
107                    Some(ScriptSource::InlineScriptSource(InlineScriptSource {
108                        ref_tx_in: RefTxIn {
109                            tx_hash: tx_hash.to_string(),
110                            tx_index,
111                            // Script size is already accounted for in script source
112                            script_size: None,
113                        },
114                        script_hash: withdrawal_script_hash.to_string(),
115                        language_version: self
116                            .adding_plutus_withdrawal
117                            .clone()
118                            .expect("Plutus withdrawals require a language version"),
119                        script_size,
120                    }));
121                self.withdrawal_item = Some(Withdrawal::PlutusScriptWithdrawal(withdrawal));
122            }
123        }
124        self
125    }
126
127    /// ## Transaction building method
128    ///
129    /// Withdraw stake rewards in the TxBuilder instance
130    ///
131    /// ### Arguments
132    ///
133    /// * `stake_address` - The address corresponding to the stake key
134    /// * `coin` - The amount of lovelaces in the withdrawal
135    ///
136    /// ### Returns
137    ///
138    /// * `Self` - The TxBuilder instance
139    pub fn withdrawal(&mut self, stake_address: &str, coin: u64) -> &mut Self {
140        if self.withdrawal_item.is_some() {
141            self.queue_withdrawal();
142        }
143
144        match self.adding_plutus_withdrawal {
145            Some(_) => {
146                let withdrawal_item = Withdrawal::PlutusScriptWithdrawal(PlutusScriptWithdrawal {
147                    address: stake_address.to_string(),
148                    coin,
149                    script_source: None,
150                    redeemer: None,
151                });
152                self.withdrawal_item = Some(withdrawal_item);
153            }
154            None => {
155                let withdrawal_item = Withdrawal::PubKeyWithdrawal(PubKeyWithdrawal {
156                    address: stake_address.to_string(),
157                    coin,
158                });
159                self.withdrawal_item = Some(withdrawal_item);
160            }
161        }
162        self
163    }
164
165    /// ## Transaction building method
166    ///
167    /// Add a withdrawal script to the TxBuilder instance
168    ///
169    /// ### Arguments
170    ///
171    /// * `script_cbor` - The script in CBOR format
172    ///
173    /// ### Returns
174    ///
175    /// * `Self` - The TxBuilder instance
176    pub fn withdrawal_script(&mut self, script_cbor: &str) -> &mut Self {
177        let withdrawal_item = self.withdrawal_item.take();
178        if withdrawal_item.is_none() {
179            panic!("Undefined withdrawal")
180        }
181        let withdrawal_item = withdrawal_item.unwrap();
182        match withdrawal_item {
183            Withdrawal::PubKeyWithdrawal(_) => {
184                panic!("Script cannot be defined for a pubkey withdrawal")
185            }
186            Withdrawal::SimpleScriptWithdrawal(mut withdraw) => {
187                withdraw.script_source = Some(SimpleScriptSource::ProvidedSimpleScriptSource(
188                    ProvidedSimpleScriptSource {
189                        script_cbor: script_cbor.to_string(),
190                    },
191                ));
192                self.withdrawal_item = Some(Withdrawal::SimpleScriptWithdrawal(withdraw));
193            }
194            Withdrawal::PlutusScriptWithdrawal(mut withdraw) => {
195                withdraw.script_source =
196                    Some(ScriptSource::ProvidedScriptSource(ProvidedScriptSource {
197                        script_cbor: script_cbor.to_string(),
198                        language_version: self
199                            .adding_plutus_withdrawal
200                            .clone()
201                            .expect("Plutus withdrawals require a language version"),
202                    }));
203                self.withdrawal_item = Some(Withdrawal::PlutusScriptWithdrawal(withdraw));
204                self.adding_plutus_withdrawal = None;
205            }
206        }
207        self
208    }
209
210    /// ## Transaction building method
211    ///
212    /// Set the transaction withdrawal redeemer value in the TxBuilder instance
213    ///
214    /// ### Arguments
215    ///
216    /// * `redeemer` - The redeemer value
217    ///
218    /// ### Returns
219    ///
220    /// * `Self` - The TxBuilder instance
221    pub fn withdrawal_redeemer_value(&mut self, redeemer: &WRedeemer) -> &mut Self {
222        let withdrawal_item = self.withdrawal_item.take();
223        if withdrawal_item.is_none() {
224            panic!("Undefined input")
225        }
226        let withdrawal_item = withdrawal_item.unwrap();
227        match withdrawal_item {
228            Withdrawal::PubKeyWithdrawal(_) => {
229                panic!("Redeemer cannot be defined for a pubkey withdrawal")
230            }
231            Withdrawal::SimpleScriptWithdrawal(_) => {
232                panic!("Redeemer cannot be defined for a native script withdrawal")
233            }
234            Withdrawal::PlutusScriptWithdrawal(mut withdraw) => match redeemer.data.to_cbor() {
235                Ok(raw_redeemer) => {
236                    withdraw.redeemer = Some(Redeemer {
237                        data: raw_redeemer,
238                        ex_units: redeemer.clone().ex_units,
239                    });
240                    self.withdrawal_item = Some(Withdrawal::PlutusScriptWithdrawal(withdraw));
241                }
242                Err(_) => panic!("Error converting redeemer to CBOR"),
243            },
244        }
245        self
246    }
247
248    /// ## Transaction building method
249    ///
250    /// Set the withdrawal reference redeemer value in the TxBuilder instance
251    ///
252    /// ### Arguments
253    ///
254    /// * `redeemer` - The redeemer value
255    ///
256    /// ### Returns
257    ///
258    /// * `Self` - The TxBuilder instance
259    pub fn withdrawal_reference_tx_in_redeemer_value(&mut self, redeemer: &WRedeemer) -> &mut Self {
260        self.withdrawal_redeemer_value(redeemer)
261    }
262}