Skip to content

Commit 00cd55b

Browse files
feat(wallet): add scan method on blocking esplora client
1 parent 7463fa7 commit 00cd55b

File tree

7 files changed

+137
-69
lines changed

7 files changed

+137
-69
lines changed

bdk-ffi/Cargo.lock

+28-28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bdk-ffi/src/bdk.udl

+39-30
Original file line numberDiff line numberDiff line change
@@ -86,36 +86,6 @@ interface Wallet {
8686

8787
interface Update {};
8888

89-
// ------------------------------------------------------------------------
90-
// bdk crate - bitcoin reexports
91-
// ------------------------------------------------------------------------
92-
93-
enum Network {
94-
"Bitcoin",
95-
"Testnet",
96-
"Signet",
97-
"Regtest",
98-
};
99-
100-
enum WordCount {
101-
"Words12",
102-
"Words15",
103-
"Words18",
104-
"Words21",
105-
"Words24",
106-
};
107-
108-
interface Address {
109-
[Throws=BdkError]
110-
constructor(string address, Network network);
111-
112-
Network network();
113-
114-
string to_qr_uri();
115-
116-
string as_string();
117-
};
118-
11989
// ------------------------------------------------------------------------
12090
// bdk crate - descriptor module
12191
// ------------------------------------------------------------------------
@@ -208,4 +178,43 @@ interface Descriptor {
208178

209179
interface EsploraClient {
210180
constructor(string url);
181+
182+
[Throws=BdkError]
183+
Update scan(Wallet wallet, u64 stop_gap, u64 parallel_requests);
184+
};
185+
186+
// ------------------------------------------------------------------------
187+
// bdk crate - bitcoin re-exports
188+
// ------------------------------------------------------------------------
189+
190+
interface Script {
191+
constructor(sequence<u8> raw_output_script);
192+
193+
sequence<u8> to_bytes();
194+
};
195+
196+
enum Network {
197+
"Bitcoin",
198+
"Testnet",
199+
"Signet",
200+
"Regtest",
201+
};
202+
203+
enum WordCount {
204+
"Words12",
205+
"Words15",
206+
"Words18",
207+
"Words21",
208+
"Words24",
209+
};
210+
211+
interface Address {
212+
[Throws=BdkError]
213+
constructor(string address, Network network);
214+
215+
Network network();
216+
217+
string to_qr_uri();
218+
219+
string as_string();
211220
};

bdk-ffi/src/bitcoin.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
2+
3+
/// A Bitcoin script.
4+
#[derive(Clone, Debug, PartialEq, Eq)]
5+
pub struct Script(pub(crate) BdkScriptBuf);
6+
7+
impl Script {
8+
pub fn new(raw_output_script: Vec<u8>) -> Self {
9+
let script: BdkScriptBuf = raw_output_script.into();
10+
Script(script)
11+
}
12+
13+
pub fn to_bytes(&self) -> Vec<u8> {
14+
self.0.to_bytes()
15+
}
16+
}
17+
18+
impl From<BdkScriptBuf> for Script {
19+
fn from(script: BdkScriptBuf) -> Self {
20+
Script(script)
21+
}
22+
}

bdk-ffi/src/esplora.rs

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
use crate::wallet::{Update, Wallet};
2+
use bdk::wallet::Update as BdkUpdate;
3+
use bdk::Error as BdkError;
14
use bdk_esplora::esplora_client::{BlockingClient, Builder};
5+
use bdk_esplora::EsploraExt;
6+
use std::sync::Arc;
27

38
pub struct EsploraClient(BlockingClient);
49

@@ -8,7 +13,44 @@ impl EsploraClient {
813
Self(client)
914
}
1015

11-
// pub fn scan();
16+
// This is a temporary solution for scanning. The long-term solution involves not passing
17+
// the wallet to the client at all.
18+
pub fn scan(
19+
&self,
20+
wallet: Arc<Wallet>,
21+
stop_gap: u64,
22+
parallel_requests: u64,
23+
) -> Result<Arc<Update>, BdkError> {
24+
let wallet = wallet.get_wallet();
25+
26+
let previous_tip = wallet.latest_checkpoint();
27+
let keychain_spks = wallet.spks_of_all_keychains().into_iter().collect();
28+
29+
let (update_graph, last_active_indices) = self
30+
.0
31+
.scan_txs_with_keychains(
32+
keychain_spks,
33+
None,
34+
None,
35+
stop_gap as usize,
36+
parallel_requests as usize,
37+
)
38+
.unwrap();
39+
40+
let missing_heights = update_graph.missing_heights(wallet.local_chain());
41+
let chain_update = self
42+
.0
43+
.update_local_chain(previous_tip, missing_heights)
44+
.unwrap();
45+
46+
let update = BdkUpdate {
47+
last_active_indices,
48+
graph: update_graph,
49+
chain: Some(chain_update),
50+
};
51+
52+
Ok(Arc::new(Update(update)))
53+
}
1254

1355
// pub fn sync();
1456

bdk-ffi/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod bitcoin;
12
mod descriptor;
23
mod esplora;
34
mod keys;
@@ -15,6 +16,7 @@ use bdk::KeychainKind;
1516
use std::sync::Arc;
1617

1718
// TODO 6: Why are these imports required?
19+
use crate::bitcoin::Script;
1820
use crate::descriptor::Descriptor;
1921
use crate::esplora::EsploraClient;
2022
use crate::keys::DerivationPath;
@@ -24,7 +26,6 @@ use crate::keys::Mnemonic;
2426
use crate::wallet::Update;
2527
use crate::wallet::Wallet;
2628
use bdk::keys::bip39::WordCount;
27-
// use bdk_esplora::EsploraExt;
2829

2930
uniffi::include_scaffolding!("bdk");
3031

bdk-ffi/src/wallet.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ impl Wallet {
6262
}
6363

6464
pub fn apply_update(&self, update: Arc<Update>) -> Result<(), BdkError> {
65-
// self.get_wallet(). .apply_update(update.0).map_err(|e| BdkError::Generic(e.to_string()))
6665
self.get_wallet()
6766
.apply_update(update.0.clone())
6867
.map_err(|e| BdkError::Generic(e.to_string()))
@@ -639,7 +638,7 @@ pub struct Update(pub(crate) BdkUpdate);
639638
// .map(Arc::new)
640639
// }
641640
// }
642-
//
641+
643642
// // The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
644643
// // These tests should not be used to verify `bdk` behavior that is already tested in the `bdk`
645644
// // crate.

0 commit comments

Comments
 (0)