@@ -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
@@ -132,8 +135,8 @@ use io::utils::write_node_metrics;
132135use liquidity:: LiquiditySource ;
133136use payment:: store:: PaymentStore ;
134137use payment:: {
135- Bolt11Payment , Bolt12Payment , OnchainPayment , PaymentDetails , SpontaneousPayment ,
136- UnifiedQrPayment ,
138+ Bolt11Payment , Bolt12Payment , OnchainPayment , PayjoinPayment , PaymentDetails ,
139+ SpontaneousPayment , UnifiedQrPayment ,
137140} ;
138141use peer_store:: { PeerInfo , PeerStore } ;
139142use types:: {
@@ -187,6 +190,7 @@ pub struct Node {
187190 peer_manager : Arc < PeerManager > ,
188191 onion_messenger : Arc < OnionMessenger > ,
189192 connection_manager : Arc < ConnectionManager < Arc < FilesystemLogger > > > ,
193+ payjoin_handler : Option < Arc < PayjoinHandler > > ,
190194 keys_manager : Arc < KeysManager > ,
191195 network_graph : Arc < Graph > ,
192196 gossip_source : Arc < GossipSource > ,
@@ -254,6 +258,68 @@ impl Node {
254258 . continuously_sync_wallets ( stop_sync_receiver, sync_cman, sync_cmon, sync_sweeper)
255259 . await ;
256260 } ) ;
261+ let sync_logger = Arc :: clone ( & self . logger ) ;
262+ let sync_payjoin = & self . payjoin_handler . as_ref ( ) ;
263+ let sync_payjoin = sync_payjoin. map ( Arc :: clone) ;
264+ let sync_wallet_timestamp = Arc :: clone ( & self . latest_wallet_sync_timestamp ) ;
265+ let sync_monitor_archival_height = Arc :: clone ( & self . latest_channel_monitor_archival_height ) ;
266+ let mut stop_sync = self . stop_sender . subscribe ( ) ;
267+ let wallet_sync_interval_secs =
268+ self . config . wallet_sync_interval_secs . max ( WALLET_SYNC_INTERVAL_MINIMUM_SECS ) ;
269+ runtime. spawn ( async move {
270+ let mut wallet_sync_interval =
271+ tokio:: time:: interval ( Duration :: from_secs ( wallet_sync_interval_secs) ) ;
272+ wallet_sync_interval. set_missed_tick_behavior ( tokio:: time:: MissedTickBehavior :: Skip ) ;
273+ loop {
274+ tokio:: select! {
275+ _ = stop_sync. changed( ) => {
276+ log_trace!(
277+ sync_logger,
278+ "Stopping background syncing Lightning wallet." ,
279+ ) ;
280+ return ;
281+ }
282+ _ = wallet_sync_interval. tick( ) => {
283+ let mut confirmables = vec![
284+ & * sync_cman as & ( dyn Confirm + Sync + Send ) ,
285+ & * sync_cmon as & ( dyn Confirm + Sync + Send ) ,
286+ & * sync_sweeper as & ( dyn Confirm + Sync + Send ) ,
287+ ] ;
288+ if let Some ( sync_payjoin) = sync_payjoin. as_ref( ) {
289+ confirmables. push( sync_payjoin. as_ref( ) as & ( dyn Confirm + Sync + Send ) ) ;
290+ }
291+ let now = Instant :: now( ) ;
292+ let timeout_fut = tokio:: time:: timeout( Duration :: from_secs( LDK_WALLET_SYNC_TIMEOUT_SECS ) , tx_sync. sync( confirmables) ) ;
293+ match timeout_fut. await {
294+ Ok ( res) => match res {
295+ Ok ( ( ) ) => {
296+ log_trace!(
297+ sync_logger,
298+ "Background sync of Lightning wallet finished in {}ms." ,
299+ now. elapsed( ) . as_millis( )
300+ ) ;
301+ let unix_time_secs_opt =
302+ SystemTime :: now( ) . duration_since( UNIX_EPOCH ) . ok( ) . map( |d| d. as_secs( ) ) ;
303+ * sync_wallet_timestamp. write( ) . unwrap( ) = unix_time_secs_opt;
304+
305+ periodically_archive_fully_resolved_monitors(
306+ Arc :: clone( & archive_cman) ,
307+ Arc :: clone( & archive_cmon) ,
308+ Arc :: clone( & sync_monitor_archival_height)
309+ ) ;
310+ }
311+ Err ( e) => {
312+ log_error!( sync_logger, "Background sync of Lightning wallet failed: {}" , e)
313+ }
314+ }
315+ Err ( e) => {
316+ log_error!( sync_logger, "Background sync of Lightning wallet timed out: {}" , e)
317+ }
318+ }
319+ }
320+ }
321+ }
322+ } ) ;
257323
258324 if self . gossip_source . is_rgs ( ) {
259325 let gossip_source = Arc :: clone ( & self . gossip_source ) ;
@@ -960,6 +1026,42 @@ impl Node {
9601026 ) )
9611027 }
9621028
1029+ /// Returns a Payjoin payment handler allowing to send Payjoin transactions
1030+ ///
1031+ /// in order to utilize Payjoin functionality, it is necessary to configure a Payjoin relay
1032+ /// using [`set_payjoin_config`].
1033+ ///
1034+ /// [`set_payjoin_config`]: crate::builder::NodeBuilder::set_payjoin_config
1035+ #[ cfg( not( feature = "uniffi" ) ) ]
1036+ pub fn payjoin_payment ( & self ) -> PayjoinPayment {
1037+ let payjoin_handler = self . payjoin_handler . as_ref ( ) ;
1038+ PayjoinPayment :: new (
1039+ Arc :: clone ( & self . config ) ,
1040+ Arc :: clone ( & self . logger ) ,
1041+ payjoin_handler. map ( Arc :: clone) ,
1042+ Arc :: clone ( & self . runtime ) ,
1043+ Arc :: clone ( & self . tx_broadcaster ) ,
1044+ )
1045+ }
1046+
1047+ /// Returns a Payjoin payment handler allowing to send Payjoin transactions.
1048+ ///
1049+ /// in order to utilize Payjoin functionality, it is necessary to configure a Payjoin relay
1050+ /// using [`set_payjoin_config`].
1051+ ///
1052+ /// [`set_payjoin_config`]: crate::builder::NodeBuilder::set_payjoin_config
1053+ #[ cfg( feature = "uniffi" ) ]
1054+ pub fn payjoin_payment ( & self ) -> Arc < PayjoinPayment > {
1055+ let payjoin_handler = self . payjoin_handler . as_ref ( ) ;
1056+ Arc :: new ( PayjoinPayment :: new (
1057+ Arc :: clone ( & self . config ) ,
1058+ Arc :: clone ( & self . logger ) ,
1059+ payjoin_handler. map ( Arc :: clone) ,
1060+ Arc :: clone ( & self . runtime ) ,
1061+ Arc :: clone ( & self . tx_broadcaster ) ,
1062+ ) )
1063+ }
1064+
9631065 /// Retrieve a list of known channels.
9641066 pub fn list_channels ( & self ) -> Vec < ChannelDetails > {
9651067 self . channel_manager . list_channels ( ) . into_iter ( ) . map ( |c| c. into ( ) ) . collect ( )
@@ -1218,6 +1320,22 @@ impl Node {
12181320 let sync_cman = Arc :: clone ( & self . channel_manager ) ;
12191321 let sync_cmon = Arc :: clone ( & self . chain_monitor ) ;
12201322 let sync_sweeper = Arc :: clone ( & self . output_sweeper ) ;
1323+ let sync_logger = Arc :: clone ( & self . logger ) ;
1324+ let sync_payjoin = & self . payjoin_handler . as_ref ( ) ;
1325+ let mut confirmables = vec ! [
1326+ & * sync_cman as & ( dyn Confirm + Sync + Send ) ,
1327+ & * sync_cmon as & ( dyn Confirm + Sync + Send ) ,
1328+ & * sync_sweeper as & ( dyn Confirm + Sync + Send ) ,
1329+ ] ;
1330+ if let Some ( sync_payjoin) = sync_payjoin {
1331+ confirmables. push ( sync_payjoin. as_ref ( ) as & ( dyn Confirm + Sync + Send ) ) ;
1332+ }
1333+ let sync_wallet_timestamp = Arc :: clone ( & self . latest_wallet_sync_timestamp ) ;
1334+ let sync_fee_rate_update_timestamp =
1335+ Arc :: clone ( & self . latest_fee_rate_cache_update_timestamp ) ;
1336+ let sync_onchain_wallet_timestamp = Arc :: clone ( & self . latest_onchain_wallet_sync_timestamp ) ;
1337+ let sync_monitor_archival_height = Arc :: clone ( & self . latest_channel_monitor_archival_height ) ;
1338+
12211339 tokio:: task:: block_in_place ( move || {
12221340 tokio:: runtime:: Builder :: new_multi_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) . block_on (
12231341 async move {
0 commit comments