1
+ use crate :: channel_scheduler:: ChannelScheduler ;
1
2
use crate :: config:: {
2
3
Config , BDK_CLIENT_CONCURRENCY , BDK_CLIENT_STOP_GAP , DEFAULT_ESPLORA_SERVER_URL ,
3
4
WALLET_KEYS_SEED_LEN ,
@@ -11,6 +12,7 @@ use crate::io::sqlite_store::SqliteStore;
11
12
use crate :: liquidity:: LiquiditySource ;
12
13
use crate :: logger:: { log_error, log_info, FilesystemLogger , Logger } ;
13
14
use crate :: message_handler:: NodeCustomMessageHandler ;
15
+ use crate :: payjoin_handler:: { PayjoinReceiver , PayjoinSender } ;
14
16
use crate :: payment:: store:: PaymentStore ;
15
17
use crate :: peer_store:: PeerStore ;
16
18
use crate :: tx_broadcaster:: TransactionBroadcaster ;
@@ -94,6 +96,13 @@ struct LiquiditySourceConfig {
94
96
lsps2_service : Option < ( SocketAddress , PublicKey , Option < String > ) > ,
95
97
}
96
98
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
+
97
106
impl Default for LiquiditySourceConfig {
98
107
fn default ( ) -> Self {
99
108
Self { lsps2_service : None }
@@ -173,6 +182,7 @@ pub struct NodeBuilder {
173
182
chain_data_source_config : Option < ChainDataSourceConfig > ,
174
183
gossip_source_config : Option < GossipSourceConfig > ,
175
184
liquidity_source_config : Option < LiquiditySourceConfig > ,
185
+ payjoin_config : Option < PayjoinConfig > ,
176
186
}
177
187
178
188
impl NodeBuilder {
@@ -188,12 +198,14 @@ impl NodeBuilder {
188
198
let chain_data_source_config = None ;
189
199
let gossip_source_config = None ;
190
200
let liquidity_source_config = None ;
201
+ let payjoin_config = None ;
191
202
Self {
192
203
config,
193
204
entropy_source_config,
194
205
chain_data_source_config,
195
206
gossip_source_config,
196
207
liquidity_source_config,
208
+ payjoin_config,
197
209
}
198
210
}
199
211
@@ -248,6 +260,16 @@ impl NodeBuilder {
248
260
self
249
261
}
250
262
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
+
251
273
/// Configures the [`Node`] instance to source its inbound liquidity from the given
252
274
/// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
253
275
/// service.
@@ -369,6 +391,7 @@ impl NodeBuilder {
369
391
seed_bytes,
370
392
logger,
371
393
vss_store,
394
+ self . payjoin_config . as_ref ( ) ,
372
395
)
373
396
}
374
397
@@ -390,6 +413,7 @@ impl NodeBuilder {
390
413
seed_bytes,
391
414
logger,
392
415
kv_store,
416
+ self . payjoin_config . as_ref ( ) ,
393
417
)
394
418
}
395
419
}
@@ -460,6 +484,18 @@ impl ArcedNodeBuilder {
460
484
self . inner . write ( ) . unwrap ( ) . set_gossip_source_rgs ( rgs_server_url) ;
461
485
}
462
486
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
+
463
499
/// Configures the [`Node`] instance to source its inbound liquidity from the given
464
500
/// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
465
501
/// service.
@@ -523,7 +559,7 @@ fn build_with_store_internal(
523
559
config : Arc < Config > , chain_data_source_config : Option < & ChainDataSourceConfig > ,
524
560
gossip_source_config : Option < & GossipSourceConfig > ,
525
561
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 > ,
527
563
) -> Result < Node , BuildError > {
528
564
// Initialize the on-chain wallet and chain access
529
565
let xprv = bitcoin:: bip32:: ExtendedPrivKey :: new_master ( config. network . into ( ) , & seed_bytes)
@@ -556,6 +592,7 @@ fn build_with_store_internal(
556
592
log_error ! ( logger, "Failed to set up wallet: {}" , e) ;
557
593
BuildError :: WalletSetupFailed
558
594
} ) ?;
595
+ let channel_scheduler = Arc :: new ( tokio:: sync:: Mutex :: new ( ChannelScheduler :: new ( ) ) ) ;
559
596
560
597
let ( blockchain, tx_sync, tx_broadcaster, fee_estimator) = match chain_data_source_config {
561
598
Some ( ChainDataSourceConfig :: Esplora ( server_url) ) => {
@@ -566,6 +603,7 @@ fn build_with_store_internal(
566
603
let tx_broadcaster = Arc :: new ( TransactionBroadcaster :: new (
567
604
tx_sync. client ( ) . clone ( ) ,
568
605
Arc :: clone ( & logger) ,
606
+ Arc :: clone ( & channel_scheduler) ,
569
607
) ) ;
570
608
let fee_estimator = Arc :: new ( OnchainFeeEstimator :: new (
571
609
tx_sync. client ( ) . clone ( ) ,
@@ -584,6 +622,7 @@ fn build_with_store_internal(
584
622
let tx_broadcaster = Arc :: new ( TransactionBroadcaster :: new (
585
623
tx_sync. client ( ) . clone ( ) ,
586
624
Arc :: clone ( & logger) ,
625
+ Arc :: clone ( & channel_scheduler) ,
587
626
) ) ;
588
627
let fee_estimator = Arc :: new ( OnchainFeeEstimator :: new (
589
628
tx_sync. client ( ) . clone ( ) ,
@@ -973,6 +1012,29 @@ fn build_with_store_internal(
973
1012
} ;
974
1013
975
1014
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
+ } ;
976
1038
977
1039
let is_listening = Arc :: new ( AtomicBool :: new ( false ) ) ;
978
1040
let latest_wallet_sync_timestamp = Arc :: new ( RwLock :: new ( None ) ) ;
@@ -993,6 +1055,8 @@ fn build_with_store_internal(
993
1055
channel_manager,
994
1056
chain_monitor,
995
1057
output_sweeper,
1058
+ payjoin_receiver,
1059
+ payjoin_sender,
996
1060
peer_manager,
997
1061
connection_manager,
998
1062
keys_manager,
0 commit comments