use std::error::Error;
use std::sync::Arc;
use crate::bitcoin::config::BitcoinConfig;
use crate::bitcoin::interface::{
Address,
AddressType,
BitcoinImplementationType,
BitcoinInterface,
BitcoinResult,
Block,
BlockHeader,
Transaction,
};
#[allow(dead_code)]
pub struct BitcoinAdapter {
config: Arc<BitcoinConfig>,
implementation: Arc<dyn BitcoinInterface>,
}
impl BitcoinAdapter {
pub async fn new(config: BitcoinConfig) -> Result<Self, Box<dyn Error>> {
let implementation = Arc::new(crate::bitcoin::rust::RustBitcoinImplementation::new(
&config,
)?) as Arc<dyn BitcoinInterface>;
Ok(Self {
config: Arc::new(config),
implementation,
})
}
pub fn get_implementation(&self) -> Arc<dyn BitcoinInterface> {
self.implementation.clone()
}
}
#[async_trait::async_trait]
impl BitcoinInterface for BitcoinAdapter {
async fn get_transaction(&self, txid: &str) -> BitcoinResult<Transaction> {
self.implementation.get_transaction(txid).await
}
async fn get_block(&self, hash: &str) -> BitcoinResult<Block> {
self.implementation.get_block(hash).await
}
async fn get_block_height(&self) -> BitcoinResult<u32> {
self.implementation.get_block_height().await
}
async fn generate_address(&self, address_type: AddressType) -> BitcoinResult<Address> {
self.implementation.generate_address(address_type).await
}
async fn create_transaction(
&self,
outputs: Vec<(String, u64)>,
fee_rate: u64,
) -> BitcoinResult<Transaction> {
self.implementation
.create_transaction(outputs, fee_rate)
.await
}
async fn broadcast_transaction(&self, transaction: &Transaction) -> BitcoinResult<String> {
self.implementation.broadcast_transaction(transaction).await
}
async fn get_balance(&self, address: &Address) -> BitcoinResult<u64> {
self.implementation.get_balance(address).await
}
async fn estimate_fee(&self, target_blocks: u8) -> BitcoinResult<u64> {
self.implementation.estimate_fee(target_blocks).await
}
async fn get_block_header(&self, hash: &str) -> BitcoinResult<BlockHeader> {
self.implementation.get_block_header(hash).await
}
async fn verify_merkle_proof(
&self,
tx_hash: &str,
block_header: &BlockHeader,
) -> BitcoinResult<bool> {
self.implementation
.verify_merkle_proof(tx_hash, block_header)
.await
}
async fn send_transaction(&self, tx: &Transaction) -> BitcoinResult<String> {
self.implementation.send_transaction(tx).await
}
fn implementation_type(&self) -> BitcoinImplementationType {
self.implementation.implementation_type()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_adapter_initialization() -> Result<(), Box<dyn Error>> {
let config = BitcoinConfig::default();
let adapter = BitcoinAdapter::new(config).await?;
let implementation = adapter.get_implementation();
assert_eq!(
implementation.implementation_type(),
BitcoinImplementationType::Rust
);
assert_eq!(
adapter.implementation_type(),
BitcoinImplementationType::Rust
);
Ok(())
}
}