@@ -77,6 +77,7 @@ use vss_client::headers::{FixedHeaders, LnurlAuthToJwtProvider, VssHeaderProvide
77
77
78
78
const VSS_HARDENED_CHILD_INDEX : u32 = 877 ;
79
79
const VSS_LNURL_AUTH_HARDENED_CHILD_INDEX : u32 = 138 ;
80
+ const LSPS_HARDENED_CHILD_INDEX : u32 = 577 ;
80
81
81
82
#[ derive( Debug , Clone ) ]
82
83
enum ChainDataSourceConfig {
@@ -103,6 +104,8 @@ struct LiquiditySourceConfig {
103
104
lsps1_client : Option < LSPS1ClientConfig > ,
104
105
// Act as an LSPS2 client connecting to the given service.
105
106
lsps2_client : Option < LSPS2ClientConfig > ,
107
+ // Act as an LSPS2 service.
108
+ lsps2_service : Option < LSPS2ServiceConfig > ,
106
109
}
107
110
108
111
#[ derive( Debug , Clone ) ]
@@ -119,6 +122,12 @@ struct LSPS2ClientConfig {
119
122
token : Option < String > ,
120
123
}
121
124
125
+ #[ derive( Debug , Clone ) ]
126
+ struct LSPS2ServiceConfig {
127
+ token : Option < String > ,
128
+ advertise_service : bool ,
129
+ }
130
+
122
131
#[ derive( Clone ) ]
123
132
enum LogWriterConfig {
124
133
File { log_file_path : Option < String > , log_level : Option < LogLevel > } ,
@@ -354,6 +363,26 @@ impl NodeBuilder {
354
363
self
355
364
}
356
365
366
+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
367
+ /// channels to clients.
368
+ ///
369
+ /// If a `token` is provided, only requests matching this token will be accepted.
370
+ ///
371
+ /// If `advertise_service` is set, the LSPS service will be announced via the gossip network.
372
+ ///
373
+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
374
+ ///
375
+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
376
+ pub fn set_liquidity_provider_lsps2 (
377
+ & mut self , token : Option < String > , advertise_service : bool ,
378
+ ) -> & mut Self {
379
+ let liquidity_source_config =
380
+ self . liquidity_source_config . get_or_insert ( LiquiditySourceConfig :: default ( ) ) ;
381
+ let lsps2_service_config = LSPS2ServiceConfig { token, advertise_service } ;
382
+ liquidity_source_config. lsps2_service = Some ( lsps2_service_config) ;
383
+ self
384
+ }
385
+
357
386
/// Sets the used storage directory path.
358
387
pub fn set_storage_dir_path ( & mut self , storage_dir_path : String ) -> & mut Self {
359
388
self . config . storage_dir_path = storage_dir_path;
@@ -706,6 +735,20 @@ impl ArcedNodeBuilder {
706
735
self . inner . write ( ) . unwrap ( ) . set_liquidity_source_lsps2 ( node_id, address, token) ;
707
736
}
708
737
738
+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
739
+ /// channels to clients.
740
+ ///
741
+ /// If a `token` is provided, only requests matching this token will be accepted.
742
+ ///
743
+ /// If `advertise_service` is set, the LSPS service will be announced via the gossip network.
744
+ ///
745
+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
746
+ ///
747
+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
748
+ pub fn set_liquidity_provider_lsps2 ( & self , token : Option < String > , advertise_service : bool ) {
749
+ self . inner . write ( ) . unwrap ( ) . set_liquidity_provider_lsps2 ( token, advertise_service) ;
750
+ }
751
+
709
752
/// Sets the used storage directory path.
710
753
pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
711
754
self . inner . write ( ) . unwrap ( ) . set_storage_dir_path ( storage_dir_path) ;
@@ -1181,39 +1224,56 @@ fn build_with_store_internal(
1181
1224
} ,
1182
1225
} ;
1183
1226
1184
- let liquidity_source = liquidity_source_config. as_ref ( ) . map ( |lsc| {
1185
- let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1186
- Arc :: clone ( & channel_manager) ,
1187
- Arc :: clone ( & keys_manager) ,
1188
- Arc :: clone ( & chain_source) ,
1189
- Arc :: clone ( & config) ,
1190
- Arc :: clone ( & logger) ,
1191
- ) ;
1227
+ let ( liquidity_source, custom_message_handler) =
1228
+ if let Some ( lsc) = liquidity_source_config. as_ref ( ) {
1229
+ let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1230
+ Arc :: clone ( & channel_manager) ,
1231
+ Arc :: clone ( & keys_manager) ,
1232
+ Arc :: clone ( & chain_source) ,
1233
+ Arc :: clone ( & config) ,
1234
+ Arc :: clone ( & logger) ,
1235
+ ) ;
1192
1236
1193
- lsc. lsps1_client . as_ref ( ) . map ( |config| {
1194
- liquidity_source_builder. lsps1_client (
1195
- config. node_id ,
1196
- config. address . clone ( ) ,
1197
- config. token . clone ( ) ,
1198
- )
1199
- } ) ;
1237
+ lsc. lsps1_client . as_ref ( ) . map ( |config| {
1238
+ liquidity_source_builder. lsps1_client (
1239
+ config. node_id ,
1240
+ config. address . clone ( ) ,
1241
+ config. token . clone ( ) ,
1242
+ )
1243
+ } ) ;
1200
1244
1201
- lsc. lsps2_client . as_ref ( ) . map ( |config| {
1202
- liquidity_source_builder. lsps2_client (
1203
- config. node_id ,
1204
- config. address . clone ( ) ,
1205
- config. token . clone ( ) ,
1206
- )
1207
- } ) ;
1245
+ lsc. lsps2_client . as_ref ( ) . map ( |config| {
1246
+ liquidity_source_builder. lsps2_client (
1247
+ config. node_id ,
1248
+ config. address . clone ( ) ,
1249
+ config. token . clone ( ) ,
1250
+ )
1251
+ } ) ;
1208
1252
1209
- Arc :: new ( liquidity_source_builder. build ( ) )
1210
- } ) ;
1253
+ let promise_secret = {
1254
+ let lsps_xpriv = derive_xprv (
1255
+ Arc :: clone ( & config) ,
1256
+ & seed_bytes,
1257
+ LSPS_HARDENED_CHILD_INDEX ,
1258
+ Arc :: clone ( & logger) ,
1259
+ ) ?;
1260
+ lsps_xpriv. private_key . secret_bytes ( )
1261
+ } ;
1262
+ lsc. lsps2_service . as_ref ( ) . map ( |config| {
1263
+ liquidity_source_builder. lsps2_service (
1264
+ promise_secret,
1265
+ config. token . clone ( ) ,
1266
+ config. advertise_service ,
1267
+ )
1268
+ } ) ;
1211
1269
1212
- let custom_message_handler = if let Some ( liquidity_source) = liquidity_source. as_ref ( ) {
1213
- Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) )
1214
- } else {
1215
- Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) )
1216
- } ;
1270
+ let liquidity_source = Arc :: new ( liquidity_source_builder. build ( ) ) ;
1271
+ let custom_message_handler =
1272
+ Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) ) ;
1273
+ ( Some ( liquidity_source) , custom_message_handler)
1274
+ } else {
1275
+ ( None , Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) ) )
1276
+ } ;
1217
1277
1218
1278
let msg_handler = match gossip_source. as_gossip_sync ( ) {
1219
1279
GossipSync :: P2P ( p2p_gossip_sync) => MessageHandler {
0 commit comments