@@ -89,14 +89,16 @@ mod logger;
8989mod message_handler;
9090mod payment_store;
9191mod peer_store;
92+ mod pj_new_crate;
9293mod sweep;
9394mod tx_broadcaster;
9495mod types;
9596#[ cfg( feature = "uniffi" ) ]
9697mod uniffi_types;
9798mod wallet;
9899
99- pub use bip39;
100+ use crate :: pj_new_crate:: ScheduledChannel ;
101+ use crate :: pjoin:: LDKPayjoin ;
100102pub use bitcoin;
101103pub use lightning;
102104pub use lightning_invoice;
@@ -107,6 +109,8 @@ pub use error::Error as NodeError;
107109use error:: Error ;
108110
109111pub use event:: Event ;
112+ use payjoin:: Uri ;
113+ mod pjoin;
110114pub use types:: ChannelConfig ;
111115
112116pub use io:: utils:: generate_entropy_mnemonic;
@@ -157,18 +161,18 @@ use lightning_transaction_sync::EsploraSyncClient;
157161use lightning:: routing:: router:: { PaymentParameters , RouteParameters } ;
158162use lightning_invoice:: { payment, Bolt11Invoice , Currency } ;
159163
160- use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
161164use bitcoin:: hashes:: Hash ;
162165use bitcoin:: secp256k1:: PublicKey ;
166+ use bitcoin:: { hashes:: sha256:: Hash as Sha256 , Amount } ;
163167
164168use bitcoin:: { Address , Txid } ;
165169
166170use rand:: Rng ;
167171
168- use std:: default:: Default ;
169- use std:: net:: ToSocketAddrs ;
172+ use std:: net:: { SocketAddr , ToSocketAddrs } ;
170173use std:: sync:: { Arc , Mutex , RwLock } ;
171174use std:: time:: { Duration , Instant , SystemTime } ;
175+ use std:: { default:: Default , str:: FromStr } ;
172176
173177#[ cfg( feature = "uniffi" ) ]
174178uniffi:: include_scaffolding!( "ldk_node" ) ;
@@ -188,6 +192,7 @@ pub struct Node<K: KVStore + Sync + Send + 'static> {
188192 channel_manager : Arc < ChannelManager < K > > ,
189193 chain_monitor : Arc < ChainMonitor < K > > ,
190194 output_sweeper : Arc < Sweeper < K > > ,
195+ payjoin : Arc < LDKPayjoin < K > > ,
191196 peer_manager : Arc < PeerManager < K > > ,
192197 keys_manager : Arc < KeysManager > ,
193198 network_graph : Arc < NetworkGraph > ,
@@ -461,7 +466,30 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
461466 } ) ;
462467 }
463468
464- // Regularly reconnect to persisted peers.
469+ let payjoin_handler = Arc :: clone ( & self . payjoin ) ;
470+ let mut stop_payjoin_server = self . stop_sender . subscribe ( ) ;
471+ let pj_port = self . config . payjoin_server_port ;
472+ runtime. spawn ( async move {
473+ let addr = SocketAddr :: from ( ( [ 127 , 0 , 0 , 1 ] , pj_port) ) ;
474+ let listener = tokio:: net:: TcpListener :: bind ( addr) . await . unwrap ( ) ;
475+ loop {
476+ let ( stream, _) = match listener. accept ( ) . await {
477+ Ok ( res) => res,
478+ Err ( e) => {
479+ println ! ( "Failed to accept incoming payjoin connection: {}" , e) ;
480+ continue ;
481+ } ,
482+ } ;
483+ tokio:: select! {
484+ _ = stop_payjoin_server. changed( ) => {
485+ return ;
486+ }
487+ _ = payjoin_handler. serve( stream) => { }
488+ }
489+ }
490+ } ) ;
491+
492+ // Regularly reconnect to channel peers.
465493 let connect_pm = Arc :: clone ( & self . peer_manager ) ;
466494 let connect_logger = Arc :: clone ( & self . logger ) ;
467495 let connect_peer_store = Arc :: clone ( & self . peer_store ) ;
@@ -667,6 +695,33 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
667695 self . runtime . read ( ) . unwrap ( ) . is_some ( )
668696 }
669697
698+ /// Request a new channel to be opened with a remote peer.
699+ pub async fn schedule_payjoin_channel (
700+ & self , channel_amount_sats : u64 , push_msat : Option < u64 > , announce_channel : bool ,
701+ node_id : PublicKey ,
702+ ) -> Result < String , Error > {
703+ let channel =
704+ ScheduledChannel :: new ( channel_amount_sats, push_msat, announce_channel, node_id) ;
705+ self . payjoin . schedule ( channel) . await ;
706+ let bip21 = self . payjoin_bip21 ( channel_amount_sats) ;
707+ bip21
708+ }
709+
710+ /// Generate a BIP21 URI for a payjoin request.
711+ pub fn payjoin_bip21 ( & self , amount_sats : u64 ) -> Result < String , Error > {
712+ let address = self . wallet . get_new_address ( ) ?;
713+ let amount = Amount :: from_sat ( amount_sats) ;
714+ let pj = format ! ( "https://0.0.0.0:{}/payjoin" , self . config. payjoin_server_port) ;
715+ let pj_uri_string = format ! ( "{}?amount={}&pj={}" , address. to_qr_uri( ) , amount. to_btc( ) , pj) ;
716+ assert ! ( Uri :: from_str( & pj_uri_string) . is_ok( ) ) ;
717+ Ok ( pj_uri_string)
718+ }
719+
720+ /// List all scheduled payjoin channels.
721+ pub async fn list_scheduled_channels ( & self ) -> Result < Vec < ScheduledChannel > , Error > {
722+ Ok ( self . payjoin . list_scheduled_channels ( ) . await )
723+ }
724+
670725 /// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
671726 ///
672727 /// After this returns most API methods will return [`Error::NotRunning`].
0 commit comments