@@ -106,7 +106,10 @@ pub use balance::{BalanceDetails, LightningBalance, PendingSweepBalance};
106106pub use error:: Error as NodeError ;
107107use error:: Error ;
108108
109+ #[ cfg( feature = "uniffi" ) ]
110+ use crate :: event:: PayjoinPaymentFailureReason ;
109111pub use event:: Event ;
112+ use payment:: payjoin:: handler:: PayjoinHandler ;
110113
111114pub use io:: utils:: generate_entropy_mnemonic;
112115
@@ -131,8 +134,8 @@ use graph::NetworkGraph;
131134use io:: utils:: write_node_metrics;
132135use liquidity:: LiquiditySource ;
133136use payment:: {
134- Bolt11Payment , Bolt12Payment , OnchainPayment , PaymentDetails , SpontaneousPayment ,
135- UnifiedQrPayment ,
137+ Bolt11Payment , Bolt12Payment , OnchainPayment , PayjoinPayment , PaymentDetails ,
138+ SpontaneousPayment , UnifiedQrPayment ,
136139} ;
137140use peer_store:: { PeerInfo , PeerStore } ;
138141use types:: {
@@ -185,6 +188,7 @@ pub struct Node {
185188 peer_manager : Arc < PeerManager > ,
186189 onion_messenger : Arc < OnionMessenger > ,
187190 connection_manager : Arc < ConnectionManager < Arc < FilesystemLogger > > > ,
191+ payjoin_handler : Option < Arc < PayjoinHandler > > ,
188192 keys_manager : Arc < KeysManager > ,
189193 network_graph : Arc < Graph > ,
190194 gossip_source : Arc < GossipSource > ,
@@ -252,6 +256,68 @@ impl Node {
252256 . continuously_sync_wallets ( stop_sync_receiver, sync_cman, sync_cmon, sync_sweeper)
253257 . await ;
254258 } ) ;
259+ let sync_logger = Arc :: clone ( & self . logger ) ;
260+ let sync_payjoin = & self . payjoin_handler . as_ref ( ) ;
261+ let sync_payjoin = sync_payjoin. map ( Arc :: clone) ;
262+ let sync_wallet_timestamp = Arc :: clone ( & self . latest_wallet_sync_timestamp ) ;
263+ let sync_monitor_archival_height = Arc :: clone ( & self . latest_channel_monitor_archival_height ) ;
264+ let mut stop_sync = self . stop_sender . subscribe ( ) ;
265+ let wallet_sync_interval_secs =
266+ self . config . wallet_sync_interval_secs . max ( WALLET_SYNC_INTERVAL_MINIMUM_SECS ) ;
267+ runtime. spawn ( async move {
268+ let mut wallet_sync_interval =
269+ tokio:: time:: interval ( Duration :: from_secs ( wallet_sync_interval_secs) ) ;
270+ wallet_sync_interval. set_missed_tick_behavior ( tokio:: time:: MissedTickBehavior :: Skip ) ;
271+ loop {
272+ tokio:: select! {
273+ _ = stop_sync. changed( ) => {
274+ log_trace!(
275+ sync_logger,
276+ "Stopping background syncing Lightning wallet." ,
277+ ) ;
278+ return ;
279+ }
280+ _ = wallet_sync_interval. tick( ) => {
281+ let mut confirmables = vec![
282+ & * sync_cman as & ( dyn Confirm + Sync + Send ) ,
283+ & * sync_cmon as & ( dyn Confirm + Sync + Send ) ,
284+ & * sync_sweeper as & ( dyn Confirm + Sync + Send ) ,
285+ ] ;
286+ if let Some ( sync_payjoin) = sync_payjoin. as_ref( ) {
287+ confirmables. push( sync_payjoin. as_ref( ) as & ( dyn Confirm + Sync + Send ) ) ;
288+ }
289+ let now = Instant :: now( ) ;
290+ let timeout_fut = tokio:: time:: timeout( Duration :: from_secs( LDK_WALLET_SYNC_TIMEOUT_SECS ) , tx_sync. sync( confirmables) ) ;
291+ match timeout_fut. await {
292+ Ok ( res) => match res {
293+ Ok ( ( ) ) => {
294+ log_trace!(
295+ sync_logger,
296+ "Background sync of Lightning wallet finished in {}ms." ,
297+ now. elapsed( ) . as_millis( )
298+ ) ;
299+ let unix_time_secs_opt =
300+ SystemTime :: now( ) . duration_since( UNIX_EPOCH ) . ok( ) . map( |d| d. as_secs( ) ) ;
301+ * sync_wallet_timestamp. write( ) . unwrap( ) = unix_time_secs_opt;
302+
303+ periodically_archive_fully_resolved_monitors(
304+ Arc :: clone( & archive_cman) ,
305+ Arc :: clone( & archive_cmon) ,
306+ Arc :: clone( & sync_monitor_archival_height)
307+ ) ;
308+ }
309+ Err ( e) => {
310+ log_error!( sync_logger, "Background sync of Lightning wallet failed: {}" , e)
311+ }
312+ }
313+ Err ( e) => {
314+ log_error!( sync_logger, "Background sync of Lightning wallet timed out: {}" , e)
315+ }
316+ }
317+ }
318+ }
319+ }
320+ } ) ;
255321
256322 if self . gossip_source . is_rgs ( ) {
257323 let gossip_source = Arc :: clone ( & self . gossip_source ) ;
@@ -947,6 +1013,42 @@ impl Node {
9471013 ) )
9481014 }
9491015
1016+ /// Returns a Payjoin payment handler allowing to send Payjoin transactions
1017+ ///
1018+ /// in order to utilize Payjoin functionality, it is necessary to configure a Payjoin relay
1019+ /// using [`set_payjoin_config`].
1020+ ///
1021+ /// [`set_payjoin_config`]: crate::builder::NodeBuilder::set_payjoin_config
1022+ #[ cfg( not( feature = "uniffi" ) ) ]
1023+ pub fn payjoin_payment ( & self ) -> PayjoinPayment {
1024+ let payjoin_handler = self . payjoin_handler . as_ref ( ) ;
1025+ PayjoinPayment :: new (
1026+ Arc :: clone ( & self . config ) ,
1027+ Arc :: clone ( & self . logger ) ,
1028+ payjoin_handler. map ( Arc :: clone) ,
1029+ Arc :: clone ( & self . runtime ) ,
1030+ Arc :: clone ( & self . tx_broadcaster ) ,
1031+ )
1032+ }
1033+
1034+ /// Returns a Payjoin payment handler allowing to send Payjoin transactions.
1035+ ///
1036+ /// in order to utilize Payjoin functionality, it is necessary to configure a Payjoin relay
1037+ /// using [`set_payjoin_config`].
1038+ ///
1039+ /// [`set_payjoin_config`]: crate::builder::NodeBuilder::set_payjoin_config
1040+ #[ cfg( feature = "uniffi" ) ]
1041+ pub fn payjoin_payment ( & self ) -> Arc < PayjoinPayment > {
1042+ let payjoin_handler = self . payjoin_handler . as_ref ( ) ;
1043+ Arc :: new ( PayjoinPayment :: new (
1044+ Arc :: clone ( & self . config ) ,
1045+ Arc :: clone ( & self . logger ) ,
1046+ payjoin_handler. map ( Arc :: clone) ,
1047+ Arc :: clone ( & self . runtime ) ,
1048+ Arc :: clone ( & self . tx_broadcaster ) ,
1049+ ) )
1050+ }
1051+
9501052 /// Retrieve a list of known channels.
9511053 pub fn list_channels ( & self ) -> Vec < ChannelDetails > {
9521054 self . channel_manager . list_channels ( ) . into_iter ( ) . map ( |c| c. into ( ) ) . collect ( )
@@ -1205,6 +1307,22 @@ impl Node {
12051307 let sync_cman = Arc :: clone ( & self . channel_manager ) ;
12061308 let sync_cmon = Arc :: clone ( & self . chain_monitor ) ;
12071309 let sync_sweeper = Arc :: clone ( & self . output_sweeper ) ;
1310+ let sync_logger = Arc :: clone ( & self . logger ) ;
1311+ let sync_payjoin = & self . payjoin_handler . as_ref ( ) ;
1312+ let mut confirmables = vec ! [
1313+ & * sync_cman as & ( dyn Confirm + Sync + Send ) ,
1314+ & * sync_cmon as & ( dyn Confirm + Sync + Send ) ,
1315+ & * sync_sweeper as & ( dyn Confirm + Sync + Send ) ,
1316+ ] ;
1317+ if let Some ( sync_payjoin) = sync_payjoin {
1318+ confirmables. push ( sync_payjoin. as_ref ( ) as & ( dyn Confirm + Sync + Send ) ) ;
1319+ }
1320+ let sync_wallet_timestamp = Arc :: clone ( & self . latest_wallet_sync_timestamp ) ;
1321+ let sync_fee_rate_update_timestamp =
1322+ Arc :: clone ( & self . latest_fee_rate_cache_update_timestamp ) ;
1323+ let sync_onchain_wallet_timestamp = Arc :: clone ( & self . latest_onchain_wallet_sync_timestamp ) ;
1324+ let sync_monitor_archival_height = Arc :: clone ( & self . latest_channel_monitor_archival_height ) ;
1325+
12081326 tokio:: task:: block_in_place ( move || {
12091327 tokio:: runtime:: Builder :: new_multi_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) . block_on (
12101328 async move {
0 commit comments