@@ -77,6 +77,7 @@ use vss_client::headers::{FixedHeaders, LnurlAuthToJwtProvider, VssHeaderProvide
7777
7878const VSS_HARDENED_CHILD_INDEX : u32 = 877 ;
7979const VSS_LNURL_AUTH_HARDENED_CHILD_INDEX : u32 = 138 ;
80+ const LSPS_HARDENED_CHILD_INDEX : u32 = 577 ;
8081
8182#[ derive( Debug , Clone ) ]
8283enum ChainDataSourceConfig {
@@ -103,6 +104,14 @@ struct LiquiditySourceConfig {
103104 lsps1_client : Option < LSPS1ClientConfig > ,
104105 // Act as an LSPS2 client connecting to the given service.
105106 lsps2_client : Option < LSPS2ClientConfig > ,
107+ // Act as an LSPS2 service.
108+ lsps2_service : Option < LSPS2ServiceConfig > ,
109+ }
110+
111+ #[ derive( Debug , Clone ) ]
112+ struct LSPS2ServiceConfig {
113+ token : Option < String > ,
114+ advertise_service : bool ,
106115}
107116
108117#[ derive( Clone ) ]
@@ -340,6 +349,26 @@ impl NodeBuilder {
340349 self
341350 }
342351
352+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
353+ /// channels to clients.
354+ ///
355+ /// If a `token` is provided, only requests matching this token will be accepted.
356+ ///
357+ /// If `advertise_service` is set, the LSPS service will be announced via the gossip network.
358+ ///
359+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
360+ ///
361+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
362+ pub fn set_liquidity_provider_lsps2 (
363+ & mut self , token : Option < String > , advertise_service : bool ,
364+ ) -> & mut Self {
365+ let liquidity_source_config =
366+ self . liquidity_source_config . get_or_insert ( LiquiditySourceConfig :: default ( ) ) ;
367+ let lsps2_service_config = LSPS2ServiceConfig { token, advertise_service } ;
368+ liquidity_source_config. lsps2_service = Some ( lsps2_service_config) ;
369+ self
370+ }
371+
343372 /// Sets the used storage directory path.
344373 pub fn set_storage_dir_path ( & mut self , storage_dir_path : String ) -> & mut Self {
345374 self . config . storage_dir_path = storage_dir_path;
@@ -692,6 +721,20 @@ impl ArcedNodeBuilder {
692721 self . inner . write ( ) . unwrap ( ) . set_liquidity_source_lsps2 ( node_id, address, token) ;
693722 }
694723
724+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
725+ /// channels to clients.
726+ ///
727+ /// If a `token` is provided, only requests matching this token will be accepted.
728+ ///
729+ /// If `advertise_service` is set, the LSPS service will be announced via the gossip network.
730+ ///
731+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
732+ ///
733+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
734+ pub fn set_liquidity_provider_lsps2 ( & self , token : Option < String > , advertise_service : bool ) {
735+ self . inner . write ( ) . unwrap ( ) . set_liquidity_provider_lsps2 ( token, advertise_service) ;
736+ }
737+
695738 /// Sets the used storage directory path.
696739 pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
697740 self . inner . write ( ) . unwrap ( ) . set_storage_dir_path ( storage_dir_path) ;
@@ -1167,39 +1210,56 @@ fn build_with_store_internal(
11671210 } ,
11681211 } ;
11691212
1170- let liquidity_source = liquidity_source_config. as_ref ( ) . map ( |lsc| {
1171- let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1172- Arc :: clone ( & channel_manager) ,
1173- Arc :: clone ( & keys_manager) ,
1174- Arc :: clone ( & chain_source) ,
1175- Arc :: clone ( & config) ,
1176- Arc :: clone ( & logger) ,
1177- ) ;
1213+ let ( liquidity_source, custom_message_handler) =
1214+ if let Some ( lsc) = liquidity_source_config. as_ref ( ) {
1215+ let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1216+ Arc :: clone ( & channel_manager) ,
1217+ Arc :: clone ( & keys_manager) ,
1218+ Arc :: clone ( & chain_source) ,
1219+ Arc :: clone ( & config) ,
1220+ Arc :: clone ( & logger) ,
1221+ ) ;
11781222
1179- lsc. lsps1_client . as_ref ( ) . map ( |config| {
1180- liquidity_source_builder. lsps1_client (
1181- config. node_id ,
1182- config. address . clone ( ) ,
1183- config. token . clone ( ) ,
1184- )
1185- } ) ;
1223+ lsc. lsps1_client . as_ref ( ) . map ( |config| {
1224+ liquidity_source_builder. lsps1_client (
1225+ config. node_id ,
1226+ config. address . clone ( ) ,
1227+ config. token . clone ( ) ,
1228+ )
1229+ } ) ;
11861230
1187- lsc. lsps2_client . as_ref ( ) . map ( |config| {
1188- liquidity_source_builder. lsps2_client (
1189- config. node_id ,
1190- config. address . clone ( ) ,
1191- config. token . clone ( ) ,
1192- )
1193- } ) ;
1231+ lsc. lsps2_client . as_ref ( ) . map ( |config| {
1232+ liquidity_source_builder. lsps2_client (
1233+ config. node_id ,
1234+ config. address . clone ( ) ,
1235+ config. token . clone ( ) ,
1236+ )
1237+ } ) ;
11941238
1195- Arc :: new ( liquidity_source_builder. build ( ) )
1196- } ) ;
1239+ let promise_secret = {
1240+ let lsps_xpriv = derive_xprv (
1241+ Arc :: clone ( & config) ,
1242+ & seed_bytes,
1243+ LSPS_HARDENED_CHILD_INDEX ,
1244+ Arc :: clone ( & logger) ,
1245+ ) ?;
1246+ lsps_xpriv. private_key . secret_bytes ( )
1247+ } ;
1248+ lsc. lsps2_service . as_ref ( ) . map ( |config| {
1249+ liquidity_source_builder. lsps2_service (
1250+ promise_secret,
1251+ config. token . clone ( ) ,
1252+ config. advertise_service ,
1253+ )
1254+ } ) ;
11971255
1198- let custom_message_handler = if let Some ( liquidity_source) = liquidity_source. as_ref ( ) {
1199- Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) )
1200- } else {
1201- Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) )
1202- } ;
1256+ let liquidity_source = Arc :: new ( liquidity_source_builder. build ( ) ) ;
1257+ let custom_message_handler =
1258+ Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) ) ;
1259+ ( Some ( liquidity_source) , custom_message_handler)
1260+ } else {
1261+ ( None , Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) ) )
1262+ } ;
12031263
12041264 let msg_handler = match gossip_source. as_gossip_sync ( ) {
12051265 GossipSync :: P2P ( p2p_gossip_sync) => MessageHandler {
0 commit comments