use blvm_sdk::governance::{GovernanceKeypair, GovernanceMessage, Multisig};
use blvm_sdk::{sign_message, verify_signature};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Multisig Workflow Example ===\n");
println!("1. Generating keypairs for 6-of-7 multisig...");
let keypairs: Vec<_> = (0..7)
.map(|_| GovernanceKeypair::generate().unwrap())
.collect();
let public_keys: Vec<_> = keypairs.iter().map(|kp| kp.public_key()).collect();
for (i, keypair) in keypairs.iter().enumerate() {
println!(" Keypair {}: {}", i + 1, keypair.public_key());
}
println!();
println!("2. Creating multisig...");
let multisig = Multisig::new(6, 7, public_keys)?;
println!(
" Threshold: {}/{}",
multisig.threshold(),
multisig.total()
);
println!();
println!("3. Creating governance messages...");
let messages = [
GovernanceMessage::Release {
version: "v1.0.0".to_string(),
commit_hash: "abc123def456".to_string(),
},
GovernanceMessage::ModuleApproval {
module_name: "lightning-network".to_string(),
version: "v2.0.0".to_string(),
},
GovernanceMessage::BudgetDecision {
amount: 1000000,
purpose: "development and maintenance".to_string(),
},
];
for (i, message) in messages.iter().enumerate() {
println!(" Message {}: {}", i + 1, message.description());
}
println!();
println!("4. Signing messages with 6 keys...");
for (msg_idx, message) in messages.iter().enumerate() {
println!(" Signing message {}...", msg_idx + 1);
let signatures: Vec<_> = keypairs[0..6]
.iter()
.map(|kp| {
let sig = sign_message(&kp.secret_key, &message.to_signing_bytes()).unwrap();
println!(" Signed with key: {}", kp.public_key());
sig
})
.collect();
let verified = multisig.verify(&message.to_signing_bytes(), &signatures)?;
println!(" Multisig verified: {}", verified);
println!();
}
println!("5. Testing with mixed valid/invalid signatures...");
let message = &messages[0]; let mut signatures = Vec::new();
for kp in &keypairs[0..4] {
let sig = sign_message(&kp.secret_key, &message.to_signing_bytes()).unwrap();
signatures.push(sig);
println!(" Added valid signature from: {}", kp.public_key());
}
let wrong_message = GovernanceMessage::Release {
version: "v2.0.0".to_string(),
commit_hash: "def456ghi789".to_string(),
};
for kp in &keypairs[4..6] {
let sig = sign_message(&kp.secret_key, &wrong_message.to_signing_bytes()).unwrap();
signatures.push(sig);
println!(" Added invalid signature from: {}", kp.public_key());
}
let sig = sign_message(&keypairs[6].secret_key, &message.to_signing_bytes()).unwrap();
signatures.push(sig);
println!(
" Added valid signature from: {}",
keypairs[6].public_key()
);
println!();
let verified = multisig.verify(&message.to_signing_bytes(), &signatures)?;
println!(" Mixed signatures verified: {}", verified);
println!();
println!("6. Testing signature collection...");
let valid_indices =
multisig.collect_valid_signatures(&message.to_signing_bytes(), &signatures)?;
println!(" Valid signature indices: {:?}", valid_indices);
println!(" Valid signatures count: {}", valid_indices.len());
println!();
println!("7. Testing individual signature validation...");
for (i, signature) in signatures.iter().enumerate() {
let mut verified = false;
for (j, public_key) in multisig.public_keys().iter().enumerate() {
if verify_signature(signature, &message.to_signing_bytes(), public_key).unwrap() {
verified = true;
println!(" Signature {} verified with key {}", i + 1, j + 1);
break;
}
}
if !verified {
println!(" Signature {} not verified", i + 1);
}
}
println!();
println!("8. Testing edge cases...");
let exact_signatures: Vec<_> = keypairs[0..6]
.iter()
.map(|kp| sign_message(&kp.secret_key, &message.to_signing_bytes()).unwrap())
.collect();
let exact_verified = multisig.verify(&message.to_signing_bytes(), &exact_signatures)?;
println!(
" Exactly threshold signatures verified: {}",
exact_verified
);
let all_signatures: Vec<_> = keypairs
.iter()
.map(|kp| sign_message(&kp.secret_key, &message.to_signing_bytes()).unwrap())
.collect();
let all_verified = multisig.verify(&message.to_signing_bytes(), &all_signatures)?;
println!(" All signatures verified: {}", all_verified);
println!();
println!("=== Example Complete ===");
Ok(())
}