wasm_multisig/multisig.rs
1use std::collections::HashMap;
2
3pub struct MultisigWallet {
4 pub signers: HashMap<String, bool>, // List of signers and their signature status
5 pub threshold: usize, // Minimum number of signatures required
6 pub signed_count: usize, // Count of valid signatures so far
7}
8
9impl MultisigWallet {
10 /// Creates a new MultisigWallet instance.
11 ///
12 /// # Arguments
13 /// * `signers` - A list of signer addresses.
14 /// * `threshold` - The minimum number of signatures required to approve a transaction.
15 ///
16 /// # Returns
17 /// * A new instance of `MultisigWallet`.
18 pub fn new(signers: Vec<String>, threshold: usize) -> Self {
19 let mut signer_map = HashMap::new();
20 for signer in signers {
21 signer_map.insert(signer, false); // Initialize all signers with a 'false' status (not signed)
22 }
23 MultisigWallet {
24 signers: signer_map,
25 threshold,
26 signed_count: 0, // Initially, no signers have signed
27 }
28 }
29
30 /// Adds a signature to the wallet if the signer is valid and the signature is verified.
31 ///
32 /// # Arguments
33 /// * `signer` - The signer's address.
34 /// * `signature` - The cryptographic signature of the signer.
35 ///
36 /// # Returns
37 /// * `Ok(())` if the signature is successfully added.
38 /// * `Err` if the signature is invalid or the signer has already signed.
39 pub fn sign(&mut self, signer: &String, signature: &str) -> Result<(), &'static str> {
40 // First, verify the signature using an immutable reference
41 let is_valid_signature = self.verify_signature(signer, signature);
42
43 if is_valid_signature {
44 // If the signature is valid, update the mutable state
45 if let Some(signed) = self.signers.get_mut(signer) {
46 if !*signed {
47 *signed = true; // Mark the signer as having signed
48 self.signed_count += 1; // Increment the count of valid signatures
49 return Ok(());
50 }
51 }
52 } else {
53 return Err("Invalid signature");
54 }
55
56 Err("Signer not found or already signed")
57 }
58
59 /// Verifies the signer's cryptographic signature.
60 ///
61 /// This is a placeholder function and should be replaced with actual signature verification logic.
62 ///
63 /// # Arguments
64 /// * `signer` - The address of the signer.
65 /// * `signature` - The signature to be verified.
66 ///
67 /// # Returns
68 /// * `true` if the signature is valid.
69 fn verify_signature(&self, _signer: &String, _signature: &str) -> bool {
70 // Placeholder logic for signature verification.
71 // Replace this with real cryptographic signature verification.
72 true
73 }
74
75 /// Adds a new signer to the wallet.
76 ///
77 /// # Arguments
78 /// * `signer` - The new signer's address to be added.
79 pub fn add_signer(&mut self, signer: String) {
80 self.signers.insert(signer, false); // Add the new signer with a default 'not signed' status
81 }
82
83 /// Removes a signer from the wallet and updates the signature count if necessary.
84 ///
85 /// # Arguments
86 /// * `signer` - The signer's address to be removed.
87 pub fn remove_signer(&mut self, signer: &String) {
88 if let Some(signed) = self.signers.remove(signer) {
89 if signed {
90 self.signed_count -= 1; // Decrement the signature count if the signer had already signed
91 }
92 }
93 // If removing the signer makes the signature count less than the threshold, panic
94 if self.signers.len() < self.threshold {
95 panic!("Not enough signers remaining to meet the threshold");
96 }
97 }
98
99 /// Updates the signature threshold and checks if the current signature count is still valid.
100 ///
101 /// # Arguments
102 /// * `new_threshold` - The new signature threshold.
103 ///
104 /// # Returns
105 /// * `Ok(())` if the threshold is successfully updated.
106 /// * `Err` if the threshold is invalid or if the current signatures do not meet the new threshold.
107 pub fn update_threshold(&mut self, new_threshold: usize) -> Result<(), &'static str> {
108 if new_threshold > self.signers.len() || new_threshold == 0 {
109 return Err("Invalid threshold");
110 }
111 self.threshold = new_threshold;
112
113 // Check if the current signature count meets the new threshold
114 if self.signed_count < self.threshold {
115 Err("Not enough valid signatures to meet the new threshold")
116 } else {
117 Ok(())
118 }
119 }
120
121 /// Checks if the number of valid signatures meets or exceeds the threshold.
122 ///
123 /// # Returns
124 /// * `true` if the required number of signatures is met.
125 pub fn collect_signatures(&self) -> bool {
126 self.signed_count >= self.threshold
127 }
128}