4747use std:: fmt:: Display ;
4848
4949use bdk_wallet:: {
50- chain:: { CheckPoint , IndexedTxGraph } ,
51- Wallet ,
50+ chain:: {
51+ keychain_txout:: KeychainTxOutIndex , CheckPoint , ConfirmationBlockTime , DescriptorExt ,
52+ DescriptorId , IndexedTxGraph ,
53+ } ,
54+ KeychainKind , Wallet ,
5255} ;
5356pub use bip157:: Builder ;
5457use bip157:: { chain:: ChainState , HeaderCheckpoint } ;
@@ -64,15 +67,21 @@ pub trait BuilderExt {
6467 self ,
6568 wallet : & Wallet ,
6669 scan_type : ScanType ,
67- ) -> Result < LightClient < Idle > , BuilderError > ;
70+ ) -> Result < LightClient < Idle , crate :: wallets:: Single > , BuilderError > ;
71+
72+ /// Attempt to build the node with scripts from multiple [`Wallet`]s and following a [`ScanType`].
73+ fn build_with_wallets (
74+ self ,
75+ wallets : Vec < ( & Wallet , ScanType ) > ,
76+ ) -> Result < LightClient < Idle , crate :: wallets:: Multiple > , BuilderError > ;
6877}
6978
7079impl BuilderExt for Builder {
7180 fn build_with_wallet (
7281 mut self ,
7382 wallet : & Wallet ,
7483 scan_type : ScanType ,
75- ) -> Result < LightClient < Idle > , BuilderError > {
84+ ) -> Result < LightClient < Idle , crate :: wallets :: Single > , BuilderError > {
7685 let network = wallet. network ( ) ;
7786 if self . network ( ) . ne ( & network) {
7887 return Err ( BuilderError :: NetworkMismatch ) ;
@@ -96,7 +105,7 @@ impl BuilderExt for Builder {
96105 event_rx,
97106 } = client;
98107 let indexed_graph = IndexedTxGraph :: new ( wallet. spk_index ( ) . clone ( ) ) ;
99- let update_subscriber = UpdateSubscriber :: new (
108+ let update_subscriber = UpdateSubscriber :: < crate :: wallets :: Single > :: new (
100109 requester. clone ( ) ,
101110 scan_type,
102111 event_rx,
@@ -114,6 +123,72 @@ impl BuilderExt for Builder {
114123 ) ;
115124 Ok ( client)
116125 }
126+
127+ fn build_with_wallets (
128+ mut self ,
129+ wallets : Vec < ( & Wallet , ScanType ) > ,
130+ ) -> Result < LightClient < Idle , crate :: wallets:: Multiple > , BuilderError > {
131+ let network = wallets
132+ . first ( )
133+ . ok_or ( BuilderError :: EmptyIterator ) ?
134+ . 0
135+ . network ( ) ;
136+ if self . network ( ) . ne ( & network) {
137+ return Err ( BuilderError :: NetworkMismatch ) ;
138+ }
139+ let cp_min = wallets
140+ . iter ( )
141+ . map ( |( wallet, scan_type) | match scan_type {
142+ ScanType :: Sync => walk_back_max_reorg ( wallet. latest_checkpoint ( ) ) ,
143+ ScanType :: Recovery {
144+ used_script_index : _,
145+ checkpoint,
146+ } => * checkpoint,
147+ } )
148+ . min ( )
149+ . ok_or ( BuilderError :: EmptyIterator ) ?;
150+ self = self . chain_state ( ChainState :: Checkpoint ( cp_min) ) ;
151+ let ( node, client) = self . build ( ) ;
152+ let bip157:: Client {
153+ requester,
154+ info_rx,
155+ warn_rx,
156+ event_rx,
157+ } = client;
158+ let wallet_iter = wallets
159+ . into_iter ( )
160+ . map ( |( wallet, scan_type) | {
161+ (
162+ wallet
163+ . public_descriptor ( KeychainKind :: External )
164+ . descriptor_id ( ) ,
165+ scan_type,
166+ wallet. latest_checkpoint ( ) ,
167+ IndexedTxGraph :: new ( wallet. spk_index ( ) . clone ( ) ) ,
168+ )
169+ } )
170+ . collect :: < Vec < (
171+ DescriptorId ,
172+ ScanType ,
173+ CheckPoint ,
174+ IndexedTxGraph < ConfirmationBlockTime , KeychainTxOutIndex < KeychainKind > > ,
175+ ) > > ( ) ;
176+ let update_subscriber = UpdateSubscriber :: < crate :: wallets:: Multiple > :: new_multiple (
177+ requester. clone ( ) ,
178+ event_rx,
179+ wallet_iter. into_iter ( ) ,
180+ ) ;
181+ let client = LightClient :: new (
182+ requester,
183+ LoggingSubscribers {
184+ info_subscriber : info_rx,
185+ warning_subscriber : warn_rx,
186+ } ,
187+ update_subscriber,
188+ node,
189+ ) ;
190+ Ok ( client)
191+ }
117192}
118193
119194/// Walk back 7 blocks in case the last sync was an orphan block.
@@ -134,6 +209,8 @@ fn walk_back_max_reorg(checkpoint: CheckPoint) -> HeaderCheckpoint {
134209pub enum BuilderError {
135210 /// The wallet network and node network do not match.
136211 NetworkMismatch ,
212+ /// The wallet iterator is empty.
213+ EmptyIterator ,
137214}
138215
139216impl Display for BuilderError {
@@ -142,6 +219,7 @@ impl Display for BuilderError {
142219 BuilderError :: NetworkMismatch => {
143220 write ! ( f, "wallet network and node network do not match" )
144221 }
222+ BuilderError :: EmptyIterator => write ! ( f, "empty wallet iterator." ) ,
145223 }
146224 }
147225}
0 commit comments