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}