diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index 7ad9f6e..7239d11 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -119,6 +119,7 @@ interface ElectrumClientError { CouldntLockReader(); Mpsc(); CouldNotCreateConnection(string error_message); + RequestAlreadyConsumed(); }; [Error] @@ -494,6 +495,9 @@ interface EsploraClient { interface ElectrumClient { [Throws=ElectrumClientError] constructor(string url); + + [Throws=ElectrumClientError] + Update full_scan(FullScanRequest full_scan_request, u64 stop_gap, u64 batch_size, boolean fetch_prev_txouts); }; // ------------------------------------------------------------------------ diff --git a/bdk-ffi/src/electrum.rs b/bdk-ffi/src/electrum.rs index 8f5ee2e..3bcd9c3 100644 --- a/bdk-ffi/src/electrum.rs +++ b/bdk-ffi/src/electrum.rs @@ -1,7 +1,15 @@ use crate::error::ElectrumClientError; +use crate::types::FullScanRequest; +use crate::wallet::Update; +use bdk::chain::spk_client::FullScanRequest as BdkFullScanRequest; +use bdk::chain::spk_client::FullScanResult as BdkFullScanResult; +use bdk_electrum::{ElectrumExt, ElectrumFullScanResult}; +use bdk::KeychainKind; use bdk_electrum::electrum_client::Client as BdkBlockingClient; +use std::sync::Arc; + pub struct ElectrumClient(BdkBlockingClient); impl ElectrumClient { @@ -9,4 +17,39 @@ impl ElectrumClient { let client = BdkBlockingClient::new(url.as_str())?; Ok(Self(client)) } + + pub fn full_scan( + &self, + request: Arc, + stop_gap: u64, + batch_size: u64, + fetch_prev_txouts: bool, + ) -> Result, ElectrumClientError> { + // using option and take is not ideal but the only way to take full ownership of the request + let request: BdkFullScanRequest = request + .0 + .lock() + .unwrap() + .take() + .ok_or(ElectrumClientError::RequestAlreadyConsumed)?; + + let electrum_result: ElectrumFullScanResult = + self.0 + .full_scan( + request, + stop_gap as usize, + batch_size as usize, + fetch_prev_txouts, + )?; + let full_scan_result: BdkFullScanResult = electrum_result + .with_confirmation_time_height_anchor(&self.0)?; + + let update = bdk::wallet::Update { + last_active_indices: full_scan_result.last_active_indices, + graph: full_scan_result.graph_update, + chain: Some(full_scan_result.chain_update), + }; + + Ok(Arc::new(Update(update))) + } } \ No newline at end of file diff --git a/bdk-ffi/src/error.rs b/bdk-ffi/src/error.rs index 1f2e95f..1d108e2 100644 --- a/bdk-ffi/src/error.rs +++ b/bdk-ffi/src/error.rs @@ -305,6 +305,9 @@ pub enum ElectrumClientError { #[error("{error_message}")] CouldNotCreateConnection { error_message: String }, + + #[error("the request has already been consumed")] + RequestAlreadyConsumed, } #[derive(Debug, thiserror::Error)]