feat: add full_scan method on electrum client

This commit is contained in:
thunderbiscuit 2024-05-15 12:16:07 -04:00
parent 8d30c86076
commit 815fe5f62d
No known key found for this signature in database
GPG Key ID: 88253696EB836462
3 changed files with 50 additions and 0 deletions

View File

@ -119,6 +119,7 @@ interface ElectrumClientError {
CouldntLockReader(); CouldntLockReader();
Mpsc(); Mpsc();
CouldNotCreateConnection(string error_message); CouldNotCreateConnection(string error_message);
RequestAlreadyConsumed();
}; };
[Error] [Error]
@ -494,6 +495,9 @@ interface EsploraClient {
interface ElectrumClient { interface ElectrumClient {
[Throws=ElectrumClientError] [Throws=ElectrumClientError]
constructor(string url); constructor(string url);
[Throws=ElectrumClientError]
Update full_scan(FullScanRequest full_scan_request, u64 stop_gap, u64 batch_size, boolean fetch_prev_txouts);
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -1,7 +1,15 @@
use crate::error::ElectrumClientError; 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 bdk_electrum::electrum_client::Client as BdkBlockingClient;
use std::sync::Arc;
pub struct ElectrumClient(BdkBlockingClient); pub struct ElectrumClient(BdkBlockingClient);
impl ElectrumClient { impl ElectrumClient {
@ -9,4 +17,39 @@ impl ElectrumClient {
let client = BdkBlockingClient::new(url.as_str())?; let client = BdkBlockingClient::new(url.as_str())?;
Ok(Self(client)) Ok(Self(client))
} }
pub fn full_scan(
&self,
request: Arc<FullScanRequest>,
stop_gap: u64,
batch_size: u64,
fetch_prev_txouts: bool,
) -> Result<Arc<Update>, ElectrumClientError> {
// using option and take is not ideal but the only way to take full ownership of the request
let request: BdkFullScanRequest<KeychainKind> = request
.0
.lock()
.unwrap()
.take()
.ok_or(ElectrumClientError::RequestAlreadyConsumed)?;
let electrum_result: ElectrumFullScanResult<KeychainKind> =
self.0
.full_scan(
request,
stop_gap as usize,
batch_size as usize,
fetch_prev_txouts,
)?;
let full_scan_result: BdkFullScanResult<KeychainKind> = 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)))
}
} }

View File

@ -305,6 +305,9 @@ pub enum ElectrumClientError {
#[error("{error_message}")] #[error("{error_message}")]
CouldNotCreateConnection { error_message: String }, CouldNotCreateConnection { error_message: String },
#[error("the request has already been consumed")]
RequestAlreadyConsumed,
} }
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]