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}