1- use bdk_kyoto:: builder:: LightClientBuilder as BDKCbfBuilder ;
2- use bdk_kyoto:: builder:: ServiceFlags ;
3- use bdk_kyoto:: builder:: TrustedPeer ;
1+ use bdk_kyoto:: builder:: NodeBuilder as BDKCbfBuilder ;
2+ use bdk_kyoto:: builder:: NodeBuilderExt ;
43use bdk_kyoto:: kyoto:: tokio;
54use bdk_kyoto:: kyoto:: AddrV2 ;
65use bdk_kyoto:: kyoto:: ScriptBuf ;
6+ use bdk_kyoto:: kyoto:: ServiceFlags ;
77use bdk_kyoto:: LightClient as BDKLightClient ;
88use bdk_kyoto:: NodeDefault ;
99use bdk_kyoto:: Receiver ;
1010use bdk_kyoto:: RejectReason ;
1111use bdk_kyoto:: Requester ;
12+ use bdk_kyoto:: TrustedPeer ;
1213use bdk_kyoto:: UnboundedReceiver ;
1314use bdk_kyoto:: UpdateSubscriber ;
1415use bdk_kyoto:: WalletExt ;
@@ -17,7 +18,6 @@ use bdk_kyoto::Warning as Warn;
1718use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr } ;
1819use std:: path:: PathBuf ;
1920use std:: sync:: Arc ;
20- use std:: time:: Duration ;
2121
2222use tokio:: sync:: Mutex ;
2323
@@ -31,7 +31,6 @@ type LogLevel = bdk_kyoto::kyoto::LogLevel;
3131type NodeState = bdk_kyoto:: NodeState ;
3232type ScanType = bdk_kyoto:: ScanType ;
3333
34- const TIMEOUT : u64 = 10 ;
3534const DEFAULT_CONNECTIONS : u8 = 2 ;
3635const CWD_PATH : & str = "." ;
3736
@@ -48,7 +47,8 @@ pub struct CbfComponents {
4847#[ derive( Debug , uniffi:: Object ) ]
4948pub struct CbfClient {
5049 sender : Arc < Requester > ,
51- log_rx : Mutex < Receiver < bdk_kyoto:: Log > > ,
50+ log_rx : Mutex < Receiver < String > > ,
51+ info_rx : Mutex < Receiver < bdk_kyoto:: Info > > ,
5252 warning_rx : Mutex < UnboundedReceiver < bdk_kyoto:: Warning > > ,
5353 update_rx : Mutex < UpdateSubscriber > ,
5454}
@@ -98,6 +98,7 @@ pub struct CbfBuilder {
9898 scan_type : ScanType ,
9999 log_level : LogLevel ,
100100 dns_resolver : Option < Arc < IpAddress > > ,
101+ socks5_proxy : Option < Socks5Proxy > ,
101102 peers : Vec < Peer > ,
102103}
103104
@@ -112,6 +113,7 @@ impl CbfBuilder {
112113 scan_type : ScanType :: default ( ) ,
113114 log_level : LogLevel :: default ( ) ,
114115 dns_resolver : None ,
116+ socks5_proxy : None ,
115117 peers : Vec :: new ( ) ,
116118 }
117119 }
@@ -167,6 +169,13 @@ impl CbfBuilder {
167169 } )
168170 }
169171
172+ pub fn socks5_proxy ( & self , proxy : Socks5Proxy ) -> Arc < Self > {
173+ Arc :: new ( CbfBuilder {
174+ socks5_proxy : Some ( proxy) ,
175+ ..self . clone ( )
176+ } )
177+ }
178+
170179 /// Construct a [`CbfComponents`] for a [`Wallet`].
171180 pub fn build ( & self , wallet : & Wallet ) -> Result < CbfComponents , CbfBuilderError > {
172181 let wallet = wallet. get_wallet ( ) ;
@@ -181,31 +190,41 @@ impl CbfBuilder {
181190 . map ( |path| PathBuf :: from ( & path) )
182191 . unwrap_or ( PathBuf :: from ( CWD_PATH ) ) ;
183192
184- let mut builder = BDKCbfBuilder :: new ( )
185- . connections ( self . connections )
193+ let mut builder = BDKCbfBuilder :: new ( wallet . network ( ) )
194+ . required_peers ( self . connections )
186195 . data_dir ( path_buf)
187- . scan_type ( self . scan_type )
188196 . log_level ( self . log_level )
189- . timeout_duration ( Duration :: from_secs ( TIMEOUT ) )
190- . peers ( trusted_peers) ;
197+ . add_peers ( trusted_peers) ;
191198
192199 if let Some ( ip_addr) = self . dns_resolver . clone ( ) . map ( |ip| ip. inner ) {
193200 builder = builder. dns_resolver ( ip_addr) ;
194201 }
195202
203+ if let Some ( proxy) = & self . socks5_proxy {
204+ let port = proxy. port ;
205+ let addr = proxy. address . inner ;
206+ builder = builder. socks5_proxy ( ( addr, port) ) ;
207+ }
208+
196209 let BDKLightClient {
197210 requester,
198211 log_subscriber,
212+ info_subscriber,
199213 warning_subscriber,
200214 update_subscriber,
201215 node,
202- } = builder. build ( & wallet) ?;
216+ } = builder
217+ . build_with_wallet ( & wallet, self . scan_type )
218+ . map_err ( |e| CbfBuilderError :: DatabaseError {
219+ reason : e. to_string ( ) ,
220+ } ) ?;
203221
204222 let node = CbfNode { node } ;
205223
206224 let client = CbfClient {
207225 sender : Arc :: new ( requester) ,
208226 log_rx : Mutex :: new ( log_subscriber) ,
227+ info_rx : Mutex :: new ( info_subscriber) ,
209228 warning_rx : Mutex :: new ( warning_subscriber) ,
210229 update_rx : Mutex :: new ( update_subscriber) ,
211230 } ;
@@ -220,12 +239,17 @@ impl CbfBuilder {
220239#[ uniffi:: export]
221240impl CbfClient {
222241 /// Return the next available log message from a node. If none is returned, the node has stopped.
223- pub async fn next_log ( & self ) -> Result < Log , CbfError > {
242+ pub async fn next_log ( & self ) -> Result < String , CbfError > {
224243 let mut log_rx = self . log_rx . lock ( ) . await ;
225- log_rx
244+ log_rx. recv ( ) . await . ok_or ( CbfError :: NodeStopped )
245+ }
246+
247+ pub async fn next_info ( & self ) -> Result < Info , CbfError > {
248+ let mut info_rx = self . info_rx . lock ( ) . await ;
249+ info_rx
226250 . recv ( )
227251 . await
228- . map ( |log| log . into ( ) )
252+ . map ( |e| e . into ( ) )
229253 . ok_or ( CbfError :: NodeStopped )
230254 }
231255
@@ -241,33 +265,32 @@ impl CbfClient {
241265
242266 /// Return an [`Update`]. This is method returns once the node syncs to the rest of
243267 /// the network or a new block has been gossiped.
244- pub async fn update ( & self ) -> Option < Arc < Update > > {
268+ pub async fn update ( & self ) -> Arc < Update > {
245269 let update = self . update_rx . lock ( ) . await . update ( ) . await ;
246- update . map ( |update| Arc :: new ( Update ( update) ) )
270+ Arc :: new ( Update ( update) )
247271 }
248272
249273 /// Add scripts for the node to watch for as they are revealed. Typically used after creating
250274 /// a transaction or revealing a receive address.
251275 ///
252276 /// Note that only future blocks will be checked for these scripts, not past blocks.
253- pub async fn add_revealed_scripts ( & self , wallet : & Wallet ) -> Result < ( ) , CbfError > {
277+ pub fn add_revealed_scripts ( & self , wallet : & Wallet ) -> Result < ( ) , CbfError > {
254278 let script_iter: Vec < ScriptBuf > = {
255279 let wallet_lock = wallet. get_wallet ( ) ;
256280 wallet_lock. peek_revealed_plus_lookahead ( ) . collect ( )
257281 } ;
258282 for script in script_iter. into_iter ( ) {
259283 self . sender
260284 . add_script ( script)
261- . await
262285 . map_err ( |_| CbfError :: NodeStopped ) ?
263286 }
264287 Ok ( ( ) )
265288 }
266289
267290 /// Broadcast a transaction to the network, erroring if the node has stopped running.
268- pub async fn broadcast ( & self , transaction : & Transaction ) -> Result < ( ) , CbfError > {
291+ pub fn broadcast ( & self , transaction : & Transaction ) -> Result < ( ) , CbfError > {
269292 let tx = transaction. into ( ) ;
270- self . sender . broadcast_random ( tx) . await . map_err ( From :: from)
293+ self . sender . broadcast_random ( tx) . map_err ( From :: from)
271294 }
272295
273296 /// The minimum fee rate required to broadcast a transcation to all connected peers.
@@ -280,44 +303,41 @@ impl CbfClient {
280303 }
281304
282305 /// Check if the node is still running in the background.
283- pub async fn is_running ( & self ) -> bool {
284- self . sender . is_running ( ) . await
306+ pub fn is_running ( & self ) -> bool {
307+ self . sender . is_running ( )
285308 }
286309
287310 /// Stop the [`CbfNode`]. Errors if the node is already stopped.
288- pub async fn shutdown ( & self ) -> Result < ( ) , CbfError > {
289- self . sender . shutdown ( ) . await . map_err ( From :: from)
311+ pub fn shutdown ( & self ) -> Result < ( ) , CbfError > {
312+ self . sender . shutdown ( ) . map_err ( From :: from)
290313 }
291314}
292315
293316/// A log message from the node.
294317#[ derive( Debug , uniffi:: Enum ) ]
295- pub enum Log {
296- /// A human-readable debug message.
297- Debug { log : String } ,
318+ pub enum Info {
298319 /// All the required connections have been met. This is subject to change.
299320 ConnectionsMet ,
300321 /// A percentage value of filters that have been scanned.
301322 Progress { progress : f32 } ,
302323 /// A state in the node syncing process.
303324 StateUpdate { node_state : NodeState } ,
304- /// A transaction was broadcast over the wire.
325+ /// A transaction was broadcast over the wire to a peer that requested it from our inventory .
305326 /// The transaction may or may not be rejected by recipient nodes.
306- TxSent { txid : String } ,
327+ TxGossiped { wtxid : String } ,
307328}
308329
309- impl From < bdk_kyoto:: Log > for Log {
310- fn from ( value : bdk_kyoto:: Log ) -> Log {
330+ impl From < bdk_kyoto:: Info > for Info {
331+ fn from ( value : bdk_kyoto:: Info ) -> Info {
311332 match value {
312- bdk_kyoto:: Log :: Debug ( log) => Log :: Debug { log } ,
313- bdk_kyoto:: Log :: ConnectionsMet => Log :: ConnectionsMet ,
314- bdk_kyoto:: Log :: Progress ( progress) => Log :: Progress {
333+ bdk_kyoto:: Info :: ConnectionsMet => Info :: ConnectionsMet ,
334+ bdk_kyoto:: Info :: Progress ( progress) => Info :: Progress {
315335 progress : progress. percentage_complete ( ) ,
316336 } ,
317- bdk_kyoto:: Log :: TxSent ( txid ) => Log :: TxSent {
318- txid : txid . to_string ( ) ,
337+ bdk_kyoto:: Info :: TxGossiped ( wtxid ) => Info :: TxGossiped {
338+ wtxid : wtxid . to_string ( ) ,
319339 } ,
320- bdk_kyoto:: Log :: StateChange ( state) => Log :: StateUpdate { node_state : state } ,
340+ bdk_kyoto:: Info :: StateChange ( state) => Info :: StateUpdate { node_state : state } ,
321341 }
322342 }
323343}
@@ -354,7 +374,7 @@ pub enum Warning {
354374 EvaluatingFork ,
355375 /// The peer database has no values.
356376 EmptyPeerDatabase ,
357- /// An unexpected error occured processing a peer-to-peer message.
377+ /// An unexpected error occurred processing a peer-to-peer message.
358378 UnexpectedSyncError { warning : String } ,
359379 /// The node failed to respond to a message sent from the client.
360380 RequestFailed ,
@@ -393,11 +413,13 @@ impl From<Warn> for Warning {
393413/// Select the category of messages for the node to emit.
394414#[ uniffi:: remote( Enum ) ]
395415pub enum LogLevel {
396- /// Send `Log::Debug` messages. These messages are intended for debugging or troubleshooting
416+ /// Send string messages. These messages are intended for debugging or troubleshooting
397417 /// node operation.
398418 Debug ,
399- /// Omit `Log::Debug` messages, including their memory allocations. Ideal for a production
400- /// application that uses minimal logging.
419+ /// Send info and warning messages, but omit debug strings - including their memory allocations.
420+ /// Ideal for a production application that uses minimal logging.
421+ Info ,
422+ /// Omit debug strings and info messages, including their memory allocations.
401423 Warning ,
402424}
403425
@@ -415,6 +437,7 @@ pub enum NodeState {
415437 /// We found all known transactions to the wallet.
416438 TransactionsSynced ,
417439}
440+
418441/// Sync a wallet from the last known block hash, recover a wallet from a specified height,
419442/// or perform an expedited block header download for a new wallet.
420443#[ uniffi:: remote( Enum ) ]
@@ -468,6 +491,16 @@ impl IpAddress {
468491 }
469492}
470493
494+ /// A proxy to route network traffic, most likely through a Tor daemon. Normally this proxy is
495+ /// exposed at 127.0.0.1:9050.
496+ #[ derive( Debug , Clone , uniffi:: Record ) ]
497+ pub struct Socks5Proxy {
498+ /// The IP address, likely `127.0.0.1`
499+ pub address : Arc < IpAddress > ,
500+ /// The listening port, likely `9050`
501+ pub port : u16 ,
502+ }
503+
471504impl From < Peer > for TrustedPeer {
472505 fn from ( peer : Peer ) -> Self {
473506 let services = if peer. v2_transport {
0 commit comments