cardano_serialization_lib/builders/
voting_proposal_builder.rs1use crate::*;
2use std::collections::BTreeMap;
3
4#[wasm_bindgen]
5#[derive(Clone, Debug)]
6pub struct VotingProposalBuilder {
7 proposals: BTreeMap<VotingProposal, Option<ScriptWitnessType>>,
8}
9
10#[wasm_bindgen]
11impl VotingProposalBuilder {
12 pub fn new() -> Self {
13 Self {
14 proposals: BTreeMap::new(),
15 }
16 }
17
18 pub fn add(&mut self, proposal: &VotingProposal) -> Result<(), JsError> {
19 if proposal.has_script_hash() {
20 return Err(JsError::from_str("Proposal has a script hash. Use add_with_plutus_witness instead."));
21 }
22 self.proposals.insert(proposal.clone(), None);
23 Ok(())
24 }
25
26 pub fn add_with_plutus_witness(
27 &mut self,
28 proposal: &VotingProposal,
29 witness: &PlutusWitness,
30 ) -> Result<(), JsError> {
31 self.proposals.insert(
32 proposal.clone(),
33 Some(ScriptWitnessType::PlutusScriptWitness(witness.clone())),
34 );
35 Ok(())
36 }
37
38 pub fn get_plutus_witnesses(&self) -> PlutusWitnesses {
39 let tag = RedeemerTag::new_voting_proposal();
40 let mut scripts = PlutusWitnesses::new();
41 for (i, (_, script_wit)) in self.proposals.iter().enumerate() {
42 if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit {
43 let index = BigNum::from(i);
44 scripts.add(&s.clone_with_redeemer_index_and_tag(&index, &tag));
45 }
46 }
47 scripts
48 }
49
50 pub fn get_ref_inputs(&self) -> TransactionInputs {
51 let mut inputs = Vec::new();
52 for (_, script_wit) in &self.proposals {
53 match script_wit {
54 Some(script_witness) => {
55 if let Some(input) = script_witness.get_script_ref_input() {
56 inputs.push(input);
57 }
58 if let Some(input) = script_witness.get_datum_ref_input() {
59 inputs.push(input);
60 }
61 }
62 None => {}
63 }
64 }
65 TransactionInputs::from_vec(inputs)
66 }
67
68 pub(crate) fn get_total_deposit(&self) -> Result<Coin, JsError> {
69 self.proposals.iter().fold(
70 Ok(Coin::zero()),
71 |acc: Result<Coin, JsError>, (proposal, _)| {
72 acc.and_then(|acc| {
73 acc.checked_add(&proposal.deposit)
74 .or_else(|_| Err(JsError::from_str("Overflow when calculating total deposit")))
75 })
76 },
77 )
78 }
79
80 pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet<Language> {
81 let mut used_langs = BTreeSet::new();
82 for (_, script_wit) in &self.proposals {
83 if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit {
84 used_langs.insert(s.script.language());
85 }
86 }
87 used_langs
88 }
89
90 pub(crate) fn get_script_ref_inputs_with_size(
94 &self,
95 ) -> impl Iterator<Item = (&TransactionInput, usize)> {
96 self.proposals.iter()
97 .filter_map(|(_, script_wit)| script_wit.as_ref())
98 .filter_map(|script_wit| script_wit.get_script_ref_input_with_size())
99 }
100
101 pub fn has_plutus_scripts(&self) -> bool {
102 for (_, script_wit) in &self.proposals {
103 if let Some(ScriptWitnessType::PlutusScriptWitness(_)) = script_wit {
104 return true;
105 }
106 }
107 false
108 }
109
110 pub fn build(&self) -> VotingProposals {
111 let mut proposals = Vec::new();
112 for (voter, _) in &self.proposals {
113 proposals.push(voter.clone());
114 }
115 VotingProposals::from_vec(proposals)
116 }
117}