@@ -74,6 +74,7 @@ use vss_client::headers::{FixedHeaders, LnurlAuthToJwtProvider, VssHeaderProvide
7474
7575const VSS_HARDENED_CHILD_INDEX : u32 = 877 ;
7676const VSS_LNURL_AUTH_HARDENED_CHILD_INDEX : u32 = 138 ;
77+ const LSPS_HARDENED_CHILD_INDEX : u32 = 577 ;
7778
7879#[ derive( Debug , Clone ) ]
7980enum ChainDataSourceConfig {
@@ -100,6 +101,8 @@ struct LiquiditySourceConfig {
100101 lsps1_client : Option < LSPS1ClientConfig > ,
101102 // Act as an LSPS2 client connecting to the given service.
102103 lsps2_client : Option < LSPS2ClientConfig > ,
104+ // Act as an LSPS2 service.
105+ lsps2_service : Option < LSPS2ServiceConfig > ,
103106}
104107
105108#[ derive( Debug , Clone ) ]
@@ -116,6 +119,12 @@ struct LSPS2ClientConfig {
116119 token : Option < String > ,
117120}
118121
122+ #[ derive( Debug , Clone ) ]
123+ struct LSPS2ServiceConfig {
124+ token : Option < String > ,
125+ advertise_service : bool ,
126+ }
127+
119128/// An error encountered during building a [`Node`].
120129///
121130/// [`Node`]: crate::Node
@@ -323,6 +332,26 @@ impl NodeBuilder {
323332 self
324333 }
325334
335+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
336+ /// channels to clients.
337+ ///
338+ /// If a `token` is provided, only requests matching this token will be accepted.
339+ ///
340+ /// If `advertise_service` is set, the LSPS service will be announced via the gossip network.
341+ ///
342+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
343+ ///
344+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
345+ pub fn set_liquidity_provider_lsps2 (
346+ & mut self , token : Option < String > , advertise_service : bool ,
347+ ) -> & mut Self {
348+ let liquidity_source_config =
349+ self . liquidity_source_config . get_or_insert ( LiquiditySourceConfig :: default ( ) ) ;
350+ let lsps2_service_config = LSPS2ServiceConfig { token, advertise_service } ;
351+ liquidity_source_config. lsps2_service = Some ( lsps2_service_config) ;
352+ self
353+ }
354+
326355 /// Sets the used storage directory path.
327356 pub fn set_storage_dir_path ( & mut self , storage_dir_path : String ) -> & mut Self {
328357 self . config . storage_dir_path = storage_dir_path;
@@ -658,6 +687,20 @@ impl ArcedNodeBuilder {
658687 self . inner . write ( ) . unwrap ( ) . set_liquidity_source_lsps2 ( node_id, address, token) ;
659688 }
660689
690+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
691+ /// channels to clients.
692+ ///
693+ /// If a `token` is provided, only requests matching this token will be accepted.
694+ ///
695+ /// If `advertise_service` is set, the LSPS service will be announced via the gossip network.
696+ ///
697+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
698+ ///
699+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
700+ pub fn set_liquidity_provider_lsps2 ( & self , token : Option < String > ) {
701+ self . inner . write ( ) . unwrap ( ) . set_liquidity_service_lsps2 ( token) ;
702+ }
703+
661704 /// Sets the used storage directory path.
662705 pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
663706 self . inner . write ( ) . unwrap ( ) . set_storage_dir_path ( storage_dir_path) ;
@@ -1105,39 +1148,56 @@ fn build_with_store_internal(
11051148 } ,
11061149 } ;
11071150
1108- let liquidity_source = liquidity_source_config. as_ref ( ) . map ( |lsc| {
1109- let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1110- Arc :: clone ( & channel_manager) ,
1111- Arc :: clone ( & keys_manager) ,
1112- Arc :: clone ( & chain_source) ,
1113- Arc :: clone ( & config) ,
1114- Arc :: clone ( & logger) ,
1115- ) ;
1151+ let ( liquidity_source, custom_message_handler) =
1152+ if let Some ( lsc) = liquidity_source_config. as_ref ( ) {
1153+ let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1154+ Arc :: clone ( & channel_manager) ,
1155+ Arc :: clone ( & keys_manager) ,
1156+ Arc :: clone ( & chain_source) ,
1157+ Arc :: clone ( & config) ,
1158+ Arc :: clone ( & logger) ,
1159+ ) ;
11161160
1117- lsc. lsps1_client . as_ref ( ) . map ( |config| {
1118- liquidity_source_builder. lsps1_client (
1119- config. node_id ,
1120- config. address . clone ( ) ,
1121- config. token . clone ( ) ,
1122- )
1123- } ) ;
1161+ lsc. lsps1_client . as_ref ( ) . map ( |config| {
1162+ liquidity_source_builder. lsps1_client (
1163+ config. node_id ,
1164+ config. address . clone ( ) ,
1165+ config. token . clone ( ) ,
1166+ )
1167+ } ) ;
11241168
1125- lsc. lsps2_client . as_ref ( ) . map ( |config| {
1126- liquidity_source_builder. lsps2_client (
1127- config. node_id ,
1128- config. address . clone ( ) ,
1129- config. token . clone ( ) ,
1130- )
1131- } ) ;
1169+ lsc. lsps2_client . as_ref ( ) . map ( |config| {
1170+ liquidity_source_builder. lsps2_client (
1171+ config. node_id ,
1172+ config. address . clone ( ) ,
1173+ config. token . clone ( ) ,
1174+ )
1175+ } ) ;
11321176
1133- Arc :: new ( liquidity_source_builder. build ( ) )
1134- } ) ;
1177+ let promise_secret = {
1178+ let lsps_xpriv = derive_xprv (
1179+ Arc :: clone ( & config) ,
1180+ & seed_bytes,
1181+ LSPS_HARDENED_CHILD_INDEX ,
1182+ Arc :: clone ( & logger) ,
1183+ ) ?;
1184+ lsps_xpriv. private_key . secret_bytes ( )
1185+ } ;
1186+ lsc. lsps2_service . as_ref ( ) . map ( |config| {
1187+ liquidity_source_builder. lsps2_service (
1188+ promise_secret,
1189+ config. token . clone ( ) ,
1190+ config. advertise_service ,
1191+ )
1192+ } ) ;
11351193
1136- let custom_message_handler = if let Some ( liquidity_source) = liquidity_source. as_ref ( ) {
1137- Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) )
1138- } else {
1139- Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) )
1140- } ;
1194+ let liquidity_source = Arc :: new ( liquidity_source_builder. build ( ) ) ;
1195+ let custom_message_handler =
1196+ Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) ) ;
1197+ ( Some ( liquidity_source) , custom_message_handler)
1198+ } else {
1199+ ( None , Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) ) )
1200+ } ;
11411201
11421202 let msg_handler = match gossip_source. as_gossip_sync ( ) {
11431203 GossipSync :: P2P ( p2p_gossip_sync) => MessageHandler {
0 commit comments