@@ -11,6 +11,7 @@ use crate::io::sqlite_store::SqliteStore;
1111use crate :: liquidity:: LiquiditySource ;
1212use crate :: logger:: { log_error, log_info, FilesystemLogger , Logger } ;
1313use crate :: message_handler:: NodeCustomMessageHandler ;
14+ use crate :: payment:: payjoin:: handler:: PayjoinHandler ;
1415use crate :: payment:: store:: PaymentStore ;
1516use crate :: peer_store:: PeerStore ;
1617use crate :: tx_broadcaster:: TransactionBroadcaster ;
@@ -93,6 +94,11 @@ struct LiquiditySourceConfig {
9394 lsps2_service : Option < ( SocketAddress , PublicKey , Option < String > ) > ,
9495}
9596
97+ #[ derive( Debug , Clone ) ]
98+ struct PayjoinConfig {
99+ payjoin_relay : payjoin:: Url ,
100+ }
101+
96102impl Default for LiquiditySourceConfig {
97103 fn default ( ) -> Self {
98104 Self { lsps2_service : None }
@@ -132,6 +138,8 @@ pub enum BuildError {
132138 WalletSetupFailed ,
133139 /// We failed to setup the logger.
134140 LoggerSetupFailed ,
141+ /// Invalid Payjoin configuration.
142+ InvalidPayjoinConfig ,
135143}
136144
137145impl fmt:: Display for BuildError {
@@ -152,6 +160,10 @@ impl fmt::Display for BuildError {
152160 Self :: KVStoreSetupFailed => write ! ( f, "Failed to setup KVStore." ) ,
153161 Self :: WalletSetupFailed => write ! ( f, "Failed to setup onchain wallet." ) ,
154162 Self :: LoggerSetupFailed => write ! ( f, "Failed to setup the logger." ) ,
163+ Self :: InvalidPayjoinConfig => write ! (
164+ f,
165+ "Invalid Payjoin configuration. Make sure the provided arguments are valid URLs."
166+ ) ,
155167 }
156168 }
157169}
@@ -172,6 +184,7 @@ pub struct NodeBuilder {
172184 chain_data_source_config : Option < ChainDataSourceConfig > ,
173185 gossip_source_config : Option < GossipSourceConfig > ,
174186 liquidity_source_config : Option < LiquiditySourceConfig > ,
187+ payjoin_config : Option < PayjoinConfig > ,
175188}
176189
177190impl NodeBuilder {
@@ -187,12 +200,14 @@ impl NodeBuilder {
187200 let chain_data_source_config = None ;
188201 let gossip_source_config = None ;
189202 let liquidity_source_config = None ;
203+ let payjoin_config = None ;
190204 Self {
191205 config,
192206 entropy_source_config,
193207 chain_data_source_config,
194208 gossip_source_config,
195209 liquidity_source_config,
210+ payjoin_config,
196211 }
197212 }
198213
@@ -247,6 +262,14 @@ impl NodeBuilder {
247262 self
248263 }
249264
265+ /// Configures the [`Node`] instance to enable payjoin transactions.
266+ pub fn set_payjoin_config ( & mut self , payjoin_relay : String ) -> Result < & mut Self , BuildError > {
267+ let payjoin_relay =
268+ payjoin:: Url :: parse ( & payjoin_relay) . map_err ( |_| BuildError :: InvalidPayjoinConfig ) ?;
269+ self . payjoin_config = Some ( PayjoinConfig { payjoin_relay } ) ;
270+ Ok ( self )
271+ }
272+
250273 /// Configures the [`Node`] instance to source its inbound liquidity from the given
251274 /// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
252275 /// service.
@@ -365,6 +388,7 @@ impl NodeBuilder {
365388 self . chain_data_source_config . as_ref ( ) ,
366389 self . gossip_source_config . as_ref ( ) ,
367390 self . liquidity_source_config . as_ref ( ) ,
391+ self . payjoin_config . as_ref ( ) ,
368392 seed_bytes,
369393 logger,
370394 vss_store,
@@ -386,6 +410,7 @@ impl NodeBuilder {
386410 self . chain_data_source_config . as_ref ( ) ,
387411 self . gossip_source_config . as_ref ( ) ,
388412 self . liquidity_source_config . as_ref ( ) ,
413+ self . payjoin_config . as_ref ( ) ,
389414 seed_bytes,
390415 logger,
391416 kv_store,
@@ -453,6 +478,11 @@ impl ArcedNodeBuilder {
453478 self . inner . write ( ) . unwrap ( ) . set_gossip_source_p2p ( ) ;
454479 }
455480
481+ /// Configures the [`Node`] instance to enable payjoin transactions.
482+ pub fn set_payjoin_config ( & self , payjoin_relay : String ) -> Result < ( ) , BuildError > {
483+ self . inner . write ( ) . unwrap ( ) . set_payjoin_config ( payjoin_relay) . map ( |_| ( ) )
484+ }
485+
456486 /// Configures the [`Node`] instance to source its gossip data from the given RapidGossipSync
457487 /// server.
458488 pub fn set_gossip_source_rgs ( & self , rgs_server_url : String ) {
@@ -521,8 +551,9 @@ impl ArcedNodeBuilder {
521551fn build_with_store_internal (
522552 config : Arc < Config > , chain_data_source_config : Option < & ChainDataSourceConfig > ,
523553 gossip_source_config : Option < & GossipSourceConfig > ,
524- liquidity_source_config : Option < & LiquiditySourceConfig > , seed_bytes : [ u8 ; 64 ] ,
525- logger : Arc < FilesystemLogger > , kv_store : Arc < DynStore > ,
554+ liquidity_source_config : Option < & LiquiditySourceConfig > ,
555+ payjoin_config : Option < & PayjoinConfig > , seed_bytes : [ u8 ; 64 ] , logger : Arc < FilesystemLogger > ,
556+ kv_store : Arc < DynStore > ,
526557) -> Result < Node , BuildError > {
527558 // Initialize the on-chain wallet and chain access
528559 let xprv = bitcoin:: bip32:: ExtendedPrivKey :: new_master ( config. network . into ( ) , & seed_bytes)
@@ -966,6 +997,17 @@ fn build_with_store_internal(
966997 let ( stop_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
967998 let ( event_handling_stopped_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
968999
1000+ let payjoin_handler = payjoin_config. map ( |pj_config| {
1001+ Arc :: new ( PayjoinHandler :: new (
1002+ Arc :: clone ( & tx_sync) ,
1003+ Arc :: clone ( & event_queue) ,
1004+ Arc :: clone ( & logger) ,
1005+ pj_config. payjoin_relay . clone ( ) ,
1006+ Arc :: clone ( & payment_store) ,
1007+ Arc :: clone ( & wallet) ,
1008+ ) )
1009+ } ) ;
1010+
9691011 let is_listening = Arc :: new ( AtomicBool :: new ( false ) ) ;
9701012 let latest_wallet_sync_timestamp = Arc :: new ( RwLock :: new ( None ) ) ;
9711013 let latest_onchain_wallet_sync_timestamp = Arc :: new ( RwLock :: new ( None ) ) ;
@@ -987,6 +1029,7 @@ fn build_with_store_internal(
9871029 channel_manager,
9881030 chain_monitor,
9891031 output_sweeper,
1032+ payjoin_handler,
9901033 peer_manager,
9911034 connection_manager,
9921035 keys_manager,
0 commit comments