anya_core/bitcoin/interface/
mod.rs

1// Bitcoin Interface Module
2// Implements a clean API for Bitcoin network operations
3//
4// [AIR-3][AIS-3][AIT-2][AIM-2][AIP-2][BPC-3][AIP-3][PFM-2]
5// This module provides high interoperability with full Bitcoin protocol compliance
6// and comprehensive security measures for network operations.
7
8// [AIR-3][AIS-3][RES-3]
9// BitcoinInterface trait for hexagonal architecture pattern
10// Following official Bitcoin Improvement Proposals (BIPs) standards
11
12// [AIR-3][AIS-3][BPC-3][RES-3] Import necessary dependencies for Bitcoin interface
13// This follows official Bitcoin Improvement Proposals (BIPs) standards for hexagonal architecture
14use std::error::Error as StdError;
15use std::sync::Arc;
16// [AIR-3][AIS-3][BPC-3][RES-3] Removed unused import: async_trait::async_trait
17
18// Re-export bitcoin types for use by other modules
19pub use crate::bitcoin::error::{BitcoinError, BitcoinResult};
20#[cfg(feature = "rust-bitcoin")]
21pub use bitcoin::{Address, Block, Network, Transaction};
22
23// [AIR-3][AIS-3][BPC-3][RES-3] Import Bitcoin configuration
24// This follows official Bitcoin Improvement Proposals (BIPs) standards for configuration management
25use crate::bitcoin::config::BitcoinConfig as ConfigBitcoinConfig;
26use crate::bitcoin::config::BitcoinConfig as BitcoinInternalConfig;
27// Use fully qualified paths to avoid type conflicts
28
29/// Bitcoin implementation type selection enum
30///
31/// This enum allows for runtime selection between different Bitcoin
32/// implementations while maintaining a consistent API.
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum BitcoinImplementationType {
35    /// Use the Rust bitcoin implementation (rust-bitcoin, BDK)
36    Rust,
37    Core,
38    Electrum,
39    Custom,
40    Web3,
41    RPC,
42}
43
44/// Generic Bitcoin address type that works across implementations
45///
46/// This abstraction allows us to represent Bitcoin addresses
47/// consistently regardless of the underlying implementation.
48#[derive(Debug, Clone, PartialEq, Eq)]
49pub struct BitcoinAddress {
50    /// The actual Bitcoin address string (e.g., "bc1q...")
51    pub address: String,
52    /// The type of address (P2PKH, P2WPKH, etc.)
53    pub address_type: AddressType,
54}
55
56/// Address types supported by both implementations
57///
58/// These represent all the major Bitcoin address types supported
59/// across our implementations.
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
61pub enum AddressType {
62    /// Legacy addresses (1...)
63    P2PKH,
64    /// Pay to Script Hash addresses (3...)
65    P2SH,
66    /// SegWit v0 addresses (bc1q...)
67    P2WPKH,
68    /// SegWit v0 script addresses
69    P2WSH,
70    /// Taproot addresses (SegWit v1, bc1p...)
71    P2TR,
72}
73
74/// Transaction representation that works across implementations
75///
76/// This provides a common structure for representing Bitcoin transactions
77/// regardless of the underlying implementation details.
78#[derive(Debug, Clone)]
79pub struct BitcoinTransaction {
80    /// Transaction ID (hash)
81    pub txid: String,
82    /// Transaction version number
83    pub version: u32,
84    /// Transaction inputs (sources of funds)
85    pub inputs: Vec<TransactionInput>,
86    /// Transaction outputs (destinations of funds)
87    pub outputs: Vec<TransactionOutput>,
88    /// Transaction locktime
89    pub locktime: u32,
90    /// Transaction size in bytes
91    pub size: usize,
92    /// Transaction weight for fee calculation
93    pub weight: usize,
94    /// Optional transaction fee in satoshis
95    pub fee: Option<u64>,
96}
97
98/// Transaction input data
99///
100/// Represents a source of funds in a Bitcoin transaction
101#[derive(Debug, Clone)]
102pub struct TransactionInput {
103    /// Reference to the transaction containing the output being spent
104    pub txid: String,
105    /// The output index in the referenced transaction
106    pub vout: u32,
107    /// Script that satisfies the spending conditions
108    pub script_sig: Vec<u8>,
109    /// Sequence number (used for replace-by-fee, timelocks)
110    pub sequence: u32,
111    /// Witness data for SegWit transactions
112    pub witness: Option<Vec<Vec<u8>>>,
113}
114
115/// Transaction output data
116///
117/// Represents a destination of funds in a Bitcoin transaction
118#[derive(Debug, Clone)]
119pub struct TransactionOutput {
120    /// Amount in satoshis
121    pub value: u64,
122    /// Script defining spending conditions
123    pub script_pubkey: Vec<u8>,
124    /// Optional human-readable address
125    pub address: Option<String>,
126}
127
128/// Block header information
129///
130/// Contains the core data from a Bitcoin block header
131#[derive(Debug, Clone)]
132pub struct BlockHeader {
133    /// Block version
134    pub version: i32,
135    /// Hash of the previous block
136    pub prev_blockhash: String,
137    /// Merkle root of all transactions
138    pub merkle_root: String,
139    /// Block timestamp
140    pub time: u32,
141    /// Difficulty target in compact format
142    pub bits: u32,
143    /// Nonce value for proof of work
144    pub nonce: u32,
145}
146
147/// Common interface for Bitcoin operations
148///
149/// This trait defines the contract that all Bitcoin implementations must fulfill.
150/// It follows the "port" concept from hexagonal architecture, allowing different
151/// adapters (implementations) to be plugged in while maintaining a consistent API.
152///
153/// [AIR-3][AIS-3][BPC-3][RES-3]
154/// Complete implementation as per official Bitcoin Improvement Proposals (BIPs) standards
155#[async_trait::async_trait]
156pub trait BitcoinInterface: Send + Sync {
157    /// Get transaction by txid
158    ///
159    /// Retrieves detailed information about a transaction given its ID.
160    async fn get_transaction(&self, txid: &str) -> BitcoinResult<Transaction>;
161
162    /// Get block by hash
163    ///
164    /// Retrieves all transactions in a block given the block hash.
165    async fn get_block(&self, hash: &str) -> BitcoinResult<Block>;
166
167    /// Get current blockchain height
168    ///
169    /// Returns the current height of the blockchain (number of blocks).
170    async fn get_block_height(&self) -> BitcoinResult<u32>;
171
172    /// Generate a new address
173    ///
174    /// Creates a new Bitcoin address of the specified type.
175    async fn generate_address(&self, address_type: AddressType) -> BitcoinResult<Address>;
176
177    /// Create and sign a transaction
178    ///
179    /// Creates a transaction sending to specified outputs with the given fee rate.
180    /// The implementation handles input selection, change addresses, and signing.
181    async fn create_transaction(
182        &self,
183        outputs: Vec<(String, u64)>,
184        fee_rate: u64,
185    ) -> BitcoinResult<Transaction>;
186
187    /// Broadcast a transaction to the network
188    ///
189    /// Sends a signed transaction to the Bitcoin network.
190    async fn broadcast_transaction(&self, transaction: &Transaction) -> BitcoinResult<String>;
191
192    /// Get balance for wallet/address
193    ///
194    /// Returns the current balance of the wallet in satoshis.
195    async fn get_balance(&self, address: &Address) -> BitcoinResult<u64>;
196
197    /// Estimate fee for a transaction
198    ///
199    /// Estimates the fee rate (in sat/vB) needed for confirmation within target_blocks.
200    async fn estimate_fee(&self, target_blocks: u8) -> BitcoinResult<u64>;
201
202    /// Get block header by hash
203    ///
204    /// Retrieves block header information for a given block hash.
205    async fn get_block_header(&self, hash: &str) -> BitcoinResult<BlockHeader>;
206
207    /// Verify a merkle proof
208    ///
209    /// Verifies a merkle proof for a given transaction hash and block header.
210    async fn verify_merkle_proof(
211        &self,
212        tx_hash: &str,
213        block_header: &BlockHeader,
214    ) -> BitcoinResult<bool>;
215
216    /// Send a transaction
217    ///
218    /// Sends a transaction to the network.
219    async fn send_transaction(&self, tx: &Transaction) -> BitcoinResult<String>;
220
221    /// Implementation type
222    ///
223    /// Returns which implementation type is being used.
224    fn implementation_type(&self) -> BitcoinImplementationType;
225}
226
227/// Create a new Bitcoin interface with the specified implementation type
228///
229/// This factory function creates and returns a Bitcoin interface implementation
230/// based on the requested type and configuration.
231///
232/// [AIR-3][BPC-3] Implementation according to official Bitcoin Improvement Proposals (BIPs)
233pub fn create_bitcoin_interface(
234    implementation_type: BitcoinImplementationType,
235    config: &ConfigBitcoinConfig,
236) -> Result<Arc<dyn BitcoinInterface + 'static>, Box<dyn StdError>> {
237    // [AIR-3][AIS-3][BPC-3][RES-3] Convert from config::BitcoinConfig to bitcoin::config::BitcoinConfig
238    // This follows official Bitcoin Improvement Proposals (BIPs) standards for configuration handling
239    let _internal_config = BitcoinInternalConfig {
240        enabled: true,
241        network: config.network.clone(),
242        rpc_url: Some(
243            config
244                .rpc_url
245                .clone()
246                .unwrap_or_else(|| "http://127.0.0.1:18332".to_string()),
247        ),
248        auth: config.auth.clone(),
249        min_confirmations: 6,
250        default_fee_rate: 10,
251        wallet_path: None,
252    };
253    match implementation_type {
254        BitcoinImplementationType::Rust => {
255            // Use the Rust implementation
256            #[cfg(feature = "rust-bitcoin")]
257            {
258                match crate::bitcoin::rust::RustBitcoinImplementation::new(&_internal_config) {
259                    Ok(implementation) => {
260                        Ok(Arc::new(implementation) as Arc<dyn BitcoinInterface + 'static>)
261                    }
262                    Err(e) => Err(Box::new(BitcoinError::ConfigError(e.to_string()))),
263                }
264            }
265            #[cfg(not(feature = "rust-bitcoin"))]
266            {
267                Err(Box::new(BitcoinError::ConfigError("Rust Bitcoin implementation requested but feature 'rust-bitcoin' is not enabled".to_string())))
268            }
269        }
270        _ => {
271            // Create a Rust implementation for all other cases
272            #[cfg(feature = "rust-bitcoin")]
273            {
274                match crate::bitcoin::rust::RustBitcoinImplementation::new(&_internal_config) {
275                    Ok(implementation) => {
276                        Ok(Arc::new(implementation) as Arc<dyn BitcoinInterface + 'static>)
277                    }
278                    Err(e) => Err(Box::new(BitcoinError::ConfigError(e.to_string()))),
279                }
280            }
281            #[cfg(not(feature = "rust-bitcoin"))]
282            {
283                Err(Box::new(BitcoinError::ConfigError(
284                    "No Bitcoin implementation available for the requested type".to_string(),
285                )))
286            }
287        }
288    }
289}
290
291/// Get the current Bitcoin interface based on configuration
292///
293/// This function returns the appropriate Bitcoin interface implementation
294/// based on the current configuration settings.
295///
296/// [AIR-3][BPC-3] Implementation according to official Bitcoin Improvement Proposals (BIPs)
297pub fn get_current_bitcoin_interface(
298    config: &ConfigBitcoinConfig,
299) -> Result<Arc<dyn BitcoinInterface + 'static>, Box<dyn StdError>> {
300    // [AIR-3][AIS-3][BPC-3][RES-3] Convert from config::BitcoinConfig to bitcoin::config::BitcoinConfig
301    // This follows official Bitcoin Improvement Proposals (BIPs) standards for configuration handling
302    let _internal_config = BitcoinInternalConfig {
303        enabled: true,
304        network: config.network.clone(),
305        rpc_url: Some(
306            config
307                .rpc_url
308                .clone()
309                .unwrap_or_else(|| "http://127.0.0.1:18332".to_string()),
310        ),
311        auth: config.auth.clone(),
312        min_confirmations: 6,
313        default_fee_rate: 10,
314        wallet_path: None,
315    };
316    // [AIR-3][AIS-3][BPC-3][RES-3] Create a Rust implementation of the Bitcoin interface
317    // Properly handle error conversion to avoid Box<dyn StdError> sizing issues
318    let implementation =
319        match crate::bitcoin::rust::RustBitcoinImplementation::new(&_internal_config) {
320            Ok(impl_instance) => impl_instance,
321            Err(e) => return Err(Box::new(BitcoinError::ConfigError(e.to_string()))),
322        };
323    Ok(Arc::new(implementation))
324}