whisky/builder/
vote.rs

1use crate::*;
2
3use super::{TxBuilder, Vote, WRedeemer};
4
5impl TxBuilder {
6    /// ## Transaction building method
7    ///
8    /// Indicate that the transaction is voting 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 voting_plutus_script(&mut self, language_version: &LanguageVersion) -> &mut Self {
18        match language_version {
19            LanguageVersion::V1 => self.voting_plutus_script_v1(),
20            LanguageVersion::V2 => self.voting_plutus_script_v2(),
21            LanguageVersion::V3 => self.voting_plutus_script_v3(),
22        }
23    }
24
25    /// ## Transaction building method
26    ///
27    /// Indicate that the transaction is voting using a plutus V1 staking script in the TxBuilder instance
28    ///
29    /// ### Returns
30    ///
31    /// * `Self` - The TxBuilder instance
32    pub fn voting_plutus_script_v1(&mut self) -> &mut Self {
33        self.adding_plutus_vote = Some(LanguageVersion::V1);
34        self
35    }
36
37    /// ## Transaction building method
38    ///
39    /// Indicate that the transaction is voting using a plutus V2 staking script in the TxBuilder instance
40    ///
41    /// ### Returns
42    ///
43    /// * `Self` - The TxBuilder instance
44    pub fn voting_plutus_script_v2(&mut self) -> &mut Self {
45        self.adding_plutus_vote = Some(LanguageVersion::V2);
46        self
47    }
48
49    /// ## Transaction building method
50    ///
51    /// Indicate that the transaction is voting using a plutus V3 staking script in the TxBuilder instance
52    ///
53    /// ### Returns
54    ///
55    /// * `Self` - The TxBuilder instance
56    pub fn voting_plutus_script_v3(&mut self) -> &mut Self {
57        self.adding_plutus_vote = Some(LanguageVersion::V3);
58        self
59    }
60
61    /// ## Transaction building method
62    ///
63    /// Add a vote reference to the TxBuilder instance
64    ///
65    /// ### Arguments
66    ///
67    /// * `tx_hash` - The transaction hash
68    /// * `tx_index` - The transaction index
69    /// * `vote_script_hash` - The vote script hash
70    /// * `version` - The language version, if the language version is None, the script is assumed to be a Native Script
71    /// * `script_size` - Size of the script
72    ///
73    /// ### Returns
74    ///
75    /// * `Self` - The TxBuilder instance
76    pub fn vote_tx_in_reference(
77        &mut self,
78        tx_hash: &str,
79        tx_index: u32,
80        vote_script_hash: &str,
81        script_size: usize,
82    ) -> &mut Self {
83        let vote_item = self.vote_item.take();
84        if vote_item.is_none() {
85            panic!("Undefined output")
86        }
87        let vote_item = vote_item.unwrap();
88        match vote_item {
89            Vote::BasicVote(_) => {
90                panic!("Script reference cannot be defined for a pubkey vote")
91            }
92            Vote::SimpleScriptVote(mut simple_script_vote) => {
93                simple_script_vote.simple_script_source = Some(
94                    SimpleScriptSource::InlineSimpleScriptSource(InlineSimpleScriptSource {
95                        ref_tx_in: RefTxIn {
96                            tx_hash: tx_hash.to_string(),
97                            tx_index,
98                            // Script size is already accounted for in script source
99                            script_size: None,
100                        },
101                        simple_script_hash: vote_script_hash.to_string(),
102                        script_size,
103                    }),
104                )
105            }
106            Vote::ScriptVote(mut script_vote) => {
107                script_vote.script_source =
108                    Some(ScriptSource::InlineScriptSource(InlineScriptSource {
109                        ref_tx_in: RefTxIn {
110                            tx_hash: tx_hash.to_string(),
111                            tx_index,
112                            // Script size is already accounted for in script source
113                            script_size: None,
114                        },
115                        script_hash: vote_script_hash.to_string(),
116                        language_version: self
117                            .adding_plutus_vote
118                            .clone()
119                            .expect("Plutus votes require a language version"),
120                        script_size,
121                    }));
122                self.vote_item = Some(Vote::ScriptVote(script_vote));
123            }
124        }
125        self
126    }
127
128    /// ## Transaction building method
129    ///
130    /// Add a vote in the TxBuilder instance
131    ///
132    /// ### Arguments
133    ///
134    /// * `voter` - The voter, can be a ConstitutionalCommittee, a DRep or a StakePool
135    /// * `gov_action_id` - The transaction hash and transaction id of the governance action
136    /// * `voting_precedure` - The voting kind (yes, no, abstain) with an optional anchor
137    ///
138    /// ### Returns
139    ///
140    /// * `Self` - The TxBuilder instance
141    pub fn vote(
142        &mut self,
143        voter: &Voter,
144        gov_action_id: &RefTxIn,
145        voting_procedure: &VotingProcedure,
146    ) -> &mut Self {
147        if self.vote_item.is_some() {
148            self.queue_vote();
149        }
150
151        match self.adding_plutus_vote {
152            Some(_) => {
153                let vote_item = Vote::ScriptVote(ScriptVote {
154                    vote: VoteType {
155                        voter: voter.clone(),
156                        gov_action_id: gov_action_id.clone(),
157                        voting_procedure: voting_procedure.clone(),
158                    },
159                    redeemer: None,
160                    script_source: None,
161                });
162                self.vote_item = Some(vote_item);
163            }
164            None => {
165                let vote_item = Vote::BasicVote(VoteType {
166                    voter: voter.clone(),
167                    gov_action_id: gov_action_id.clone(),
168                    voting_procedure: voting_procedure.clone(),
169                });
170                self.vote_item = Some(vote_item);
171            }
172        }
173        self
174    }
175
176    /// ## Transaction building method
177    ///
178    /// Add a vote script to the TxBuilder instance
179    ///
180    /// ### Arguments
181    ///
182    /// * `script_cbor` - The script in CBOR format
183    ///
184    /// ### Returns
185    ///
186    /// * `Self` - The TxBuilder instance
187    pub fn vote_script(&mut self, script_cbor: &str) -> &mut Self {
188        let vote_item = self.vote_item.take();
189        if vote_item.is_none() {
190            panic!("Undefined vote")
191        }
192        let vote_item = vote_item.unwrap();
193        match vote_item {
194            Vote::BasicVote(_) => {
195                panic!("Script reference cannot be defined for a pubkey vote")
196            }
197            Vote::SimpleScriptVote(mut simple_script_vote) => {
198                simple_script_vote.simple_script_source = Some(
199                    SimpleScriptSource::ProvidedSimpleScriptSource(ProvidedSimpleScriptSource {
200                        script_cbor: script_cbor.to_string(),
201                    }),
202                );
203                self.vote_item = Some(Vote::SimpleScriptVote(simple_script_vote));
204            }
205            Vote::ScriptVote(mut script_vote) => {
206                script_vote.script_source =
207                    Some(ScriptSource::ProvidedScriptSource(ProvidedScriptSource {
208                        script_cbor: script_cbor.to_string(),
209                        language_version: self
210                            .adding_plutus_vote
211                            .clone()
212                            .expect("Plutus votes require a language version"),
213                    }));
214                self.vote_item = Some(Vote::ScriptVote(script_vote));
215                self.adding_plutus_vote = None;
216            }
217        }
218        self
219    }
220
221    /// ## Transaction building method
222    ///
223    /// Set the transaction vote redeemer value in the TxBuilder instance
224    ///
225    /// ### Arguments
226    ///
227    /// * `redeemer` - The redeemer value
228    ///
229    /// ### Returns
230    ///
231    /// * `Self` - The TxBuilder instance
232    pub fn vote_redeemer_value(&mut self, redeemer: &WRedeemer) -> &mut Self {
233        let vote_item = self.vote_item.take();
234        if vote_item.is_none() {
235            panic!("Undefined input")
236        }
237        let vote_item = vote_item.unwrap();
238        match vote_item {
239            Vote::BasicVote(_) => {
240                panic!("Redeemer cannot be defined for a basic vote")
241            }
242            Vote::SimpleScriptVote(_) => {
243                panic!("Redeemer cannot be defined for a native script vote")
244            }
245            Vote::ScriptVote(mut script_vote) => match redeemer.data.to_cbor() {
246                Ok(raw_redeemer) => {
247                    script_vote.redeemer = Some(Redeemer {
248                        data: raw_redeemer,
249                        ex_units: redeemer.clone().ex_units,
250                    });
251                    self.vote_item = Some(Vote::ScriptVote(script_vote));
252                }
253                Err(_) => panic!("Error converting redeemer to CBOR"),
254            },
255        }
256        self
257    }
258
259    /// ## Transaction building method
260    ///
261    /// Set the vote reference redeemer value in the TxBuilder instance
262    ///
263    /// ### Arguments
264    ///
265    /// * `redeemer` - The redeemer value
266    ///
267    /// ### Returns
268    ///
269    /// * `Self` - The TxBuilder instance
270    pub fn vote_reference_tx_in_redeemer_value(&mut self, redeemer: &WRedeemer) -> &mut Self {
271        self.vote_redeemer_value(redeemer)
272    }
273}