use chia_wallet_sdk::prelude::{Allocator, CoinSpend};
use chia_wallet_sdk::signer::{AggSigConstants, RequiredSignature};
use crate::MerkleError;
pub fn required_signatures(
coin_spends: &[CoinSpend],
constants: &AggSigConstants,
) -> Result<Vec<RequiredSignature>, MerkleError> {
let mut allocator = Allocator::new();
RequiredSignature::from_coin_spends(&mut allocator, coin_spends, constants)
.map_err(|error| MerkleError::Signer(error.to_string()))
}
#[cfg(test)]
mod tests {
use super::*;
use chia_wallet_sdk::driver::{SpendContext, StandardLayer};
use chia_wallet_sdk::prelude::MAINNET_CONSTANTS;
use chia_wallet_sdk::test::Simulator;
use chia_wallet_sdk::types::Conditions;
#[test]
fn reports_the_single_agg_sig_me_of_a_standard_spend() {
let mut sim = Simulator::new();
let alice = sim.bls(1);
let alice_p2 = StandardLayer::new(alice.pk);
let mut ctx = SpendContext::new();
let memos = ctx.hint(alice.puzzle_hash).expect("hint allocates");
alice_p2
.spend(
&mut ctx,
alice.coin,
Conditions::new().create_coin(alice.puzzle_hash, 1, memos),
)
.expect("standard spend should build");
let coin_spends = ctx.take();
assert_eq!(coin_spends.len(), 1);
let constants = AggSigConstants::from(&*MAINNET_CONSTANTS);
let required = required_signatures(&coin_spends, &constants).expect("signatures compute");
assert_eq!(required.len(), 1, "one AGG_SIG_ME expected");
match &required[0] {
RequiredSignature::Bls(bls) => {
assert_eq!(bls.public_key, alice.pk, "signed under the spender key");
assert!(
!bls.message().is_empty(),
"a non-empty message must be signed"
);
}
RequiredSignature::Secp(_) => panic!("standard spend uses a BLS key, not secp"),
}
}
#[test]
fn no_coin_spends_require_no_signatures() {
let constants = AggSigConstants::from(&*MAINNET_CONSTANTS);
let required = required_signatures(&[], &constants).expect("empty input is valid");
assert!(required.is_empty());
}
}