@@ -18,7 +18,9 @@ use crate::gossip::GossipSource;
18
18
use crate :: io:: sqlite_store:: SqliteStore ;
19
19
use crate :: io:: utils:: { read_node_metrics, write_node_metrics} ;
20
20
use crate :: io:: vss_store:: VssStore ;
21
- use crate :: liquidity:: { LSPS1ClientConfig , LSPS2ClientConfig , LiquiditySourceBuilder } ;
21
+ use crate :: liquidity:: {
22
+ LSPS1ClientConfig , LSPS2ClientConfig , LSPS2ServiceConfig , LiquiditySourceBuilder ,
23
+ } ;
22
24
use crate :: logger:: { log_error, log_info, LdkLogger , LogLevel , LogWriter , Logger } ;
23
25
use crate :: message_handler:: NodeCustomMessageHandler ;
24
26
use crate :: payment:: store:: PaymentStore ;
@@ -77,6 +79,7 @@ use vss_client::headers::{FixedHeaders, LnurlAuthToJwtProvider, VssHeaderProvide
77
79
78
80
const VSS_HARDENED_CHILD_INDEX : u32 = 877 ;
79
81
const VSS_LNURL_AUTH_HARDENED_CHILD_INDEX : u32 = 138 ;
82
+ const LSPS_HARDENED_CHILD_INDEX : u32 = 577 ;
80
83
81
84
#[ derive( Debug , Clone ) ]
82
85
enum ChainDataSourceConfig {
@@ -103,6 +106,8 @@ struct LiquiditySourceConfig {
103
106
lsps1_client : Option < LSPS1ClientConfig > ,
104
107
// Act as an LSPS2 client connecting to the given service.
105
108
lsps2_client : Option < LSPS2ClientConfig > ,
109
+ // Act as an LSPS2 service.
110
+ lsps2_service : Option < LSPS2ServiceConfig > ,
106
111
}
107
112
108
113
#[ derive( Clone ) ]
@@ -342,6 +347,21 @@ impl NodeBuilder {
342
347
self
343
348
}
344
349
350
+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
351
+ /// channels to clients.
352
+ ///
353
+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
354
+ ///
355
+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
356
+ pub fn set_liquidity_provider_lsps2 (
357
+ & mut self , service_config : LSPS2ServiceConfig ,
358
+ ) -> & mut Self {
359
+ let liquidity_source_config =
360
+ self . liquidity_source_config . get_or_insert ( LiquiditySourceConfig :: default ( ) ) ;
361
+ liquidity_source_config. lsps2_service = Some ( service_config) ;
362
+ self
363
+ }
364
+
345
365
/// Sets the used storage directory path.
346
366
pub fn set_storage_dir_path ( & mut self , storage_dir_path : String ) -> & mut Self {
347
367
self . config . storage_dir_path = storage_dir_path;
@@ -699,6 +719,16 @@ impl ArcedNodeBuilder {
699
719
self . inner . write ( ) . unwrap ( ) . set_liquidity_source_lsps2 ( node_id, address, token) ;
700
720
}
701
721
722
+ /// Configures the [`Node`] instance to provide an [LSPS2] service, issuing just-in-time
723
+ /// channels to clients.
724
+ ///
725
+ /// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
726
+ ///
727
+ /// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
728
+ pub fn set_liquidity_provider_lsps2 ( & self , service_config : LSPS2ServiceConfig ) {
729
+ self . inner . write ( ) . unwrap ( ) . set_liquidity_provider_lsps2 ( service_config) ;
730
+ }
731
+
702
732
/// Sets the used storage directory path.
703
733
pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
704
734
self . inner . write ( ) . unwrap ( ) . set_storage_dir_path ( storage_dir_path) ;
@@ -1179,39 +1209,52 @@ fn build_with_store_internal(
1179
1209
} ,
1180
1210
} ;
1181
1211
1182
- let liquidity_source = liquidity_source_config. as_ref ( ) . map ( |lsc| {
1183
- let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1184
- Arc :: clone ( & channel_manager) ,
1185
- Arc :: clone ( & keys_manager) ,
1186
- Arc :: clone ( & chain_source) ,
1187
- Arc :: clone ( & config) ,
1188
- Arc :: clone ( & logger) ,
1189
- ) ;
1190
-
1191
- lsc. lsps1_client . as_ref ( ) . map ( |config| {
1192
- liquidity_source_builder. lsps1_client (
1193
- config. node_id ,
1194
- config. address . clone ( ) ,
1195
- config. token . clone ( ) ,
1196
- )
1197
- } ) ;
1212
+ let ( liquidity_source, custom_message_handler) =
1213
+ if let Some ( lsc) = liquidity_source_config. as_ref ( ) {
1214
+ let mut liquidity_source_builder = LiquiditySourceBuilder :: new (
1215
+ Arc :: clone ( & channel_manager) ,
1216
+ Arc :: clone ( & keys_manager) ,
1217
+ Arc :: clone ( & chain_source) ,
1218
+ Arc :: clone ( & config) ,
1219
+ Arc :: clone ( & logger) ,
1220
+ ) ;
1198
1221
1199
- lsc. lsps2_client . as_ref ( ) . map ( |config| {
1200
- liquidity_source_builder. lsps2_client (
1201
- config. node_id ,
1202
- config. address . clone ( ) ,
1203
- config. token . clone ( ) ,
1204
- )
1205
- } ) ;
1222
+ lsc. lsps1_client . as_ref ( ) . map ( |config| {
1223
+ liquidity_source_builder. lsps1_client (
1224
+ config. node_id ,
1225
+ config. address . clone ( ) ,
1226
+ config. token . clone ( ) ,
1227
+ )
1228
+ } ) ;
1206
1229
1207
- Arc :: new ( liquidity_source_builder. build ( ) )
1208
- } ) ;
1230
+ lsc. lsps2_client . as_ref ( ) . map ( |config| {
1231
+ liquidity_source_builder. lsps2_client (
1232
+ config. node_id ,
1233
+ config. address . clone ( ) ,
1234
+ config. token . clone ( ) ,
1235
+ )
1236
+ } ) ;
1209
1237
1210
- let custom_message_handler = if let Some ( liquidity_source) = liquidity_source. as_ref ( ) {
1211
- Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) )
1212
- } else {
1213
- Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) )
1214
- } ;
1238
+ let promise_secret = {
1239
+ let lsps_xpriv = derive_xprv (
1240
+ Arc :: clone ( & config) ,
1241
+ & seed_bytes,
1242
+ LSPS_HARDENED_CHILD_INDEX ,
1243
+ Arc :: clone ( & logger) ,
1244
+ ) ?;
1245
+ lsps_xpriv. private_key . secret_bytes ( )
1246
+ } ;
1247
+ lsc. lsps2_service . as_ref ( ) . map ( |config| {
1248
+ liquidity_source_builder. lsps2_service ( promise_secret, config. clone ( ) )
1249
+ } ) ;
1250
+
1251
+ let liquidity_source = Arc :: new ( liquidity_source_builder. build ( ) ) ;
1252
+ let custom_message_handler =
1253
+ Arc :: new ( NodeCustomMessageHandler :: new_liquidity ( Arc :: clone ( & liquidity_source) ) ) ;
1254
+ ( Some ( liquidity_source) , custom_message_handler)
1255
+ } else {
1256
+ ( None , Arc :: new ( NodeCustomMessageHandler :: new_ignoring ( ) ) )
1257
+ } ;
1215
1258
1216
1259
let msg_handler = match gossip_source. as_gossip_sync ( ) {
1217
1260
GossipSync :: P2P ( p2p_gossip_sync) => MessageHandler {
0 commit comments