1use anyhow::Result;
2use std::cmp::Ordering;
3use std::path::{Path, PathBuf};
4
5#[derive(Debug, Clone)]
7pub enum InstallationSource {
8 LocalBuild,
9 GitRepository(String),
10 PreBuiltBinary(String),
11}
12
13#[derive(Debug, Clone)]
15pub struct BitcoinConfig {
16 pub network: String,
17 pub data_dir: PathBuf,
18}
19
20pub struct AnyaInstaller {
22 installation_source: InstallationSource,
23 #[allow(dead_code)]
24 bitcoin_config: BitcoinConfig,
26}
27
28impl AnyaInstaller {
29 pub fn new(install_source: InstallationSource, bitcoin_config: BitcoinConfig) -> Result<Self> {
30 Ok(Self {
31 installation_source: install_source,
32 bitcoin_config,
33 })
34 }
35
36 pub async fn install(&self, target_dir: PathBuf) -> Result<()> {
38 self.validate_source()?;
40
41 self.execute_installation(&target_dir).await?;
43
44 Ok(())
45 }
46
47 fn validate_source(&self) -> Result<()> {
48 match &self.installation_source {
49 InstallationSource::LocalBuild => {
50 Ok(())
52 }
53 InstallationSource::GitRepository(url) => {
54 if url.is_empty() {
56 anyhow::bail!("Git repository URL cannot be empty");
57 }
58 Ok(())
59 }
60 InstallationSource::PreBuiltBinary(path) => {
61 if path.is_empty() {
63 anyhow::bail!("Binary path cannot be empty");
64 }
65 Ok(())
66 }
67 }
68 }
69
70 async fn execute_installation(&self, _target_dir: &Path) -> Result<()> {
71 Ok(())
73 }
74}
75
76pub mod protocol {
78 use super::*;
79
80 pub fn verify_bip_support(required_bips: &[u32], installed_bips: &[u32]) -> Result<()> {
81 let missing: Vec<_> = required_bips
82 .iter()
83 .filter(|bip| !installed_bips.contains(bip))
84 .collect();
85
86 if !missing.is_empty() {
87 anyhow::bail!("Missing required BIPs: {:?}", missing);
88 }
89
90 Ok(())
91 }
92
93 pub fn check_taproot_activation(height: u64) -> Result<()> {
94 const TAPROOT_ACTIVATION_HEIGHT: u64 = 709632; if height < TAPROOT_ACTIVATION_HEIGHT {
97 anyhow::bail!(
98 "Taproot not active until block {}",
99 TAPROOT_ACTIVATION_HEIGHT
100 );
101 }
102
103 Ok(())
104 }
105}
106
107pub fn version_compare(v1: &str, v2: &str) -> Ordering {
109 v1.cmp(v2)
111}