use serde::{Deserialize, Serialize};
use std::fmt;
pub mod testing;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum BPCLevel {
None = 0,
Basic = 1,
Enhanced = 2,
#[default]
Full = 3,
BPC3 = 4,
}
impl fmt::Display for BPCLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BPCLevel::None => write!(f, "None"),
BPCLevel::Basic => write!(f, "Basic"),
BPCLevel::Enhanced => write!(f, "Enhanced"),
BPCLevel::Full => write!(f, "Full"),
BPCLevel::BPC3 => write!(f, "BPC3"),
}
}
}
#[derive(Debug, Default, Clone)]
pub struct BitcoinProtocol {
pub level: BPCLevel,
pub supported_bips: Vec<u32>,
}
impl BitcoinProtocol {
pub fn new() -> Self {
Self {
level: BPCLevel::Full,
supported_bips: vec![341, 342, 174, 370, 340], }
}
pub fn validate_compliance(&self) -> Result<bool, Box<dyn std::error::Error>> {
let required_bips = vec![341, 342, 174, 340];
for bip in required_bips {
if !self.supported_bips.contains(&bip) {
return Err(format!("Missing required BIP-{bip}").into());
}
}
Ok(true)
}
pub fn get_info(&self) -> ProtocolInfo {
ProtocolInfo {
level: self.level,
supported_bips: self.supported_bips.clone(),
features: vec![
"Taproot (BIP-341)".to_string(),
"Tapscript (BIP-342)".to_string(),
"PSBT v1/v2 (BIP-174/370)".to_string(),
"Schnorr Signatures (BIP-340)".to_string(),
],
}
}
pub fn validate_transaction(
&self,
tx: &bitcoin::Transaction,
) -> Result<(), crate::bitcoin::error::BitcoinError> {
if tx.output.is_empty() {
return Err(crate::bitcoin::error::BitcoinError::ValidationError(
"Transaction has no outputs".to_string(),
));
}
Ok(())
}
pub fn is_taproot_enabled(&self) -> bool {
self.supported_bips.contains(&341) }
pub fn get_level(&self) -> BPCLevel {
self.level
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProtocolInfo {
pub level: BPCLevel,
pub supported_bips: Vec<u32>,
pub features: Vec<String>,
}