1+ use crate :: channel_scheduler:: ChannelScheduler ;
12use crate :: config:: {
23 Config , BDK_CLIENT_CONCURRENCY , BDK_CLIENT_STOP_GAP , DEFAULT_ESPLORA_SERVER_URL ,
34 WALLET_KEYS_SEED_LEN ,
@@ -11,6 +12,7 @@ use crate::io::sqlite_store::SqliteStore;
1112use crate :: liquidity:: LiquiditySource ;
1213use crate :: logger:: { log_error, log_info, FilesystemLogger , Logger } ;
1314use crate :: message_handler:: NodeCustomMessageHandler ;
15+ use crate :: payjoin_handler:: { PayjoinReceiver , PayjoinSender } ;
1416use crate :: payment:: store:: PaymentStore ;
1517use crate :: peer_store:: PeerStore ;
1618use crate :: tx_broadcaster:: TransactionBroadcaster ;
@@ -94,6 +96,13 @@ struct LiquiditySourceConfig {
9496 lsps2_service : Option < ( SocketAddress , PublicKey , Option < String > ) > ,
9597}
9698
99+ #[ derive( Debug , Clone ) ]
100+ struct PayjoinConfig {
101+ payjoin_directory : payjoin:: Url ,
102+ payjoin_relay : payjoin:: Url ,
103+ ohttp_keys : Option < payjoin:: OhttpKeys > ,
104+ }
105+
97106impl Default for LiquiditySourceConfig {
98107 fn default ( ) -> Self {
99108 Self { lsps2_service : None }
@@ -173,6 +182,7 @@ pub struct NodeBuilder {
173182 chain_data_source_config : Option < ChainDataSourceConfig > ,
174183 gossip_source_config : Option < GossipSourceConfig > ,
175184 liquidity_source_config : Option < LiquiditySourceConfig > ,
185+ payjoin_config : Option < PayjoinConfig > ,
176186}
177187
178188impl NodeBuilder {
@@ -188,12 +198,14 @@ impl NodeBuilder {
188198 let chain_data_source_config = None ;
189199 let gossip_source_config = None ;
190200 let liquidity_source_config = None ;
201+ let payjoin_config = None ;
191202 Self {
192203 config,
193204 entropy_source_config,
194205 chain_data_source_config,
195206 gossip_source_config,
196207 liquidity_source_config,
208+ payjoin_config,
197209 }
198210 }
199211
@@ -248,6 +260,16 @@ impl NodeBuilder {
248260 self
249261 }
250262
263+ /// Configures the [`Node`] instance to source its gossip data from the given RapidGossipSync
264+ /// server.
265+ pub fn set_payjoin_config (
266+ & mut self , payjoin_directory : payjoin:: Url , payjoin_relay : payjoin:: Url ,
267+ ohttp_keys : Option < payjoin:: OhttpKeys > ,
268+ ) -> & mut Self {
269+ self . payjoin_config = Some ( PayjoinConfig { payjoin_directory, payjoin_relay, ohttp_keys } ) ;
270+ self
271+ }
272+
251273 /// Configures the [`Node`] instance to source its inbound liquidity from the given
252274 /// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
253275 /// service.
@@ -369,6 +391,7 @@ impl NodeBuilder {
369391 seed_bytes,
370392 logger,
371393 vss_store,
394+ self . payjoin_config . as_ref ( ) ,
372395 )
373396 }
374397
@@ -390,6 +413,7 @@ impl NodeBuilder {
390413 seed_bytes,
391414 logger,
392415 kv_store,
416+ self . payjoin_config . as_ref ( ) ,
393417 )
394418 }
395419}
@@ -460,6 +484,18 @@ impl ArcedNodeBuilder {
460484 self . inner . write ( ) . unwrap ( ) . set_gossip_source_rgs ( rgs_server_url) ;
461485 }
462486
487+ /// Configures the [`Node`] instance to use payjoin.
488+ pub fn set_payjoin_config (
489+ & self , payjoin_directory : payjoin:: Url , payjoin_relay : payjoin:: Url ,
490+ ohttp_keys : Option < payjoin:: OhttpKeys > ,
491+ ) {
492+ self . inner . write ( ) . unwrap ( ) . set_payjoin_config (
493+ payjoin_directory,
494+ payjoin_relay,
495+ ohttp_keys,
496+ ) ;
497+ }
498+
463499 /// Configures the [`Node`] instance to source its inbound liquidity from the given
464500 /// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
465501 /// service.
@@ -523,7 +559,7 @@ fn build_with_store_internal(
523559 config : Arc < Config > , chain_data_source_config : Option < & ChainDataSourceConfig > ,
524560 gossip_source_config : Option < & GossipSourceConfig > ,
525561 liquidity_source_config : Option < & LiquiditySourceConfig > , seed_bytes : [ u8 ; 64 ] ,
526- logger : Arc < FilesystemLogger > , kv_store : Arc < DynStore > ,
562+ logger : Arc < FilesystemLogger > , kv_store : Arc < DynStore > , payjoin_config : Option < & PayjoinConfig > ,
527563) -> Result < Node , BuildError > {
528564 // Initialize the on-chain wallet and chain access
529565 let xprv = bitcoin:: bip32:: ExtendedPrivKey :: new_master ( config. network . into ( ) , & seed_bytes)
@@ -556,6 +592,7 @@ fn build_with_store_internal(
556592 log_error ! ( logger, "Failed to set up wallet: {}" , e) ;
557593 BuildError :: WalletSetupFailed
558594 } ) ?;
595+ let channel_scheduler = Arc :: new ( tokio:: sync:: Mutex :: new ( ChannelScheduler :: new ( ) ) ) ;
559596
560597 let ( blockchain, tx_sync, tx_broadcaster, fee_estimator) = match chain_data_source_config {
561598 Some ( ChainDataSourceConfig :: Esplora ( server_url) ) => {
@@ -566,6 +603,7 @@ fn build_with_store_internal(
566603 let tx_broadcaster = Arc :: new ( TransactionBroadcaster :: new (
567604 tx_sync. client ( ) . clone ( ) ,
568605 Arc :: clone ( & logger) ,
606+ Arc :: clone ( & channel_scheduler) ,
569607 ) ) ;
570608 let fee_estimator = Arc :: new ( OnchainFeeEstimator :: new (
571609 tx_sync. client ( ) . clone ( ) ,
@@ -584,6 +622,7 @@ fn build_with_store_internal(
584622 let tx_broadcaster = Arc :: new ( TransactionBroadcaster :: new (
585623 tx_sync. client ( ) . clone ( ) ,
586624 Arc :: clone ( & logger) ,
625+ Arc :: clone ( & channel_scheduler) ,
587626 ) ) ;
588627 let fee_estimator = Arc :: new ( OnchainFeeEstimator :: new (
589628 tx_sync. client ( ) . clone ( ) ,
@@ -973,6 +1012,29 @@ fn build_with_store_internal(
9731012 } ;
9741013
9751014 let ( stop_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
1015+ let ( payjoin_receiver, payjoin_sender) = if let Some ( payjoin_config) = payjoin_config {
1016+ let payjoin_receiver = match PayjoinReceiver :: enroll (
1017+ & payjoin_config. ohttp_keys ,
1018+ & payjoin_config. payjoin_directory ,
1019+ & payjoin_config. payjoin_relay ,
1020+ Arc :: clone ( & channel_scheduler) ,
1021+ Arc :: clone ( & wallet) ,
1022+ Arc :: clone ( & channel_manager) ,
1023+ Arc :: clone ( & logger) ,
1024+ ) {
1025+ Ok ( r) => Some ( Arc :: new ( r) ) ,
1026+ Err ( _e) => None ,
1027+ } ;
1028+ let payjoin_sender = PayjoinSender :: new (
1029+ Arc :: clone ( & logger) ,
1030+ Arc :: clone ( & wallet) ,
1031+ & payjoin_config. payjoin_relay ,
1032+ & payjoin_config. payjoin_directory ,
1033+ ) ;
1034+ ( payjoin_receiver, Some ( Arc :: new ( payjoin_sender) ) )
1035+ } else {
1036+ ( None , None )
1037+ } ;
9761038
9771039 let is_listening = Arc :: new ( AtomicBool :: new ( false ) ) ;
9781040 let latest_wallet_sync_timestamp = Arc :: new ( RwLock :: new ( None ) ) ;
@@ -993,6 +1055,8 @@ fn build_with_store_internal(
9931055 channel_manager,
9941056 chain_monitor,
9951057 output_sweeper,
1058+ payjoin_receiver,
1059+ payjoin_sender,
9961060 peer_manager,
9971061 connection_manager,
9981062 keys_manager,
0 commit comments