@@ -19,6 +19,8 @@ use lightning::events::HTLCHandlingFailureType;
1919use lightning:: ln:: channelmanager:: { InterceptId , MIN_FINAL_CLTV_EXPIRY_DELTA } ;
2020use lightning:: ln:: msgs:: SocketAddress ;
2121use lightning:: ln:: types:: ChannelId ;
22+ use lightning:: offers:: offer:: OfferId ;
23+ use lightning:: onion_message:: messenger:: OnionMessageInterceptor ;
2224use lightning:: routing:: router:: { RouteHint , RouteHintHop } ;
2325use lightning:: sign:: EntropySource ;
2426use lightning_invoice:: { Bolt11Invoice , Bolt11InvoiceDescription , InvoiceBuilder , RoutingFees } ;
@@ -32,6 +34,7 @@ use lightning_liquidity::lsps1::msgs::{
3234use lightning_liquidity:: lsps2:: client:: LSPS2ClientConfig as LdkLSPS2ClientConfig ;
3335use lightning_liquidity:: lsps2:: event:: { LSPS2ClientEvent , LSPS2ServiceEvent } ;
3436use lightning_liquidity:: lsps2:: msgs:: { LSPS2OpeningFeeParams , LSPS2RawOpeningFeeParams } ;
37+ use lightning_liquidity:: lsps2:: router:: LSPS2Bolt12InvoiceParameters ;
3538use lightning_liquidity:: lsps2:: service:: LSPS2ServiceConfig as LdkLSPS2ServiceConfig ;
3639use lightning_liquidity:: lsps2:: utils:: compute_opening_fee;
3740use lightning_liquidity:: { LiquidityClientConfig , LiquidityServiceConfig } ;
@@ -44,7 +47,8 @@ use crate::connection::ConnectionManager;
4447use crate :: logger:: { log_debug, log_error, log_info, LdkLogger , Logger } ;
4548use crate :: runtime:: Runtime ;
4649use crate :: types:: {
47- Broadcaster , ChannelManager , DynStore , KeysManager , LiquidityManager , PeerManager , Wallet ,
50+ Broadcaster , ChannelManager , DynStore , KeysManager , LiquidityManager , PeerManager , Router ,
51+ Wallet ,
4852} ;
4953use crate :: { total_anchor_channels_reserve_sats, Config , Error } ;
5054
@@ -154,11 +158,13 @@ where
154158 lsps2_service : Option < LSPS2Service > ,
155159 wallet : Arc < Wallet > ,
156160 channel_manager : Arc < ChannelManager > ,
161+ router : Arc < Router > ,
157162 keys_manager : Arc < KeysManager > ,
158163 chain_source : Arc < ChainSource > ,
159164 tx_broadcaster : Arc < Broadcaster > ,
160165 kv_store : Arc < DynStore > ,
161166 config : Arc < Config > ,
167+ onion_message_interceptor : Option < Arc < dyn OnionMessageInterceptor + Send + Sync > > ,
162168 logger : L ,
163169}
164170
@@ -168,8 +174,10 @@ where
168174{
169175 pub ( crate ) fn new (
170176 wallet : Arc < Wallet > , channel_manager : Arc < ChannelManager > , keys_manager : Arc < KeysManager > ,
171- chain_source : Arc < ChainSource > , tx_broadcaster : Arc < Broadcaster > , kv_store : Arc < DynStore > ,
172- config : Arc < Config > , logger : L ,
177+ router : Arc < Router > , chain_source : Arc < ChainSource > , tx_broadcaster : Arc < Broadcaster > ,
178+ kv_store : Arc < DynStore > , config : Arc < Config > ,
179+ onion_message_interceptor : Option < Arc < dyn OnionMessageInterceptor + Send + Sync > > ,
180+ logger : L ,
173181 ) -> Self {
174182 let lsps1_client = None ;
175183 let lsps2_client = None ;
@@ -180,11 +188,13 @@ where
180188 lsps2_service,
181189 wallet,
182190 channel_manager,
191+ router,
183192 keys_manager,
184193 chain_source,
185194 tx_broadcaster,
186195 kv_store,
187196 config,
197+ onion_message_interceptor,
188198 logger,
189199 }
190200 }
@@ -262,7 +272,7 @@ where
262272 Arc :: clone ( & self . tx_broadcaster ) ,
263273 liquidity_service_config,
264274 liquidity_client_config,
265- None ,
275+ self . onion_message_interceptor ,
266276 )
267277 . await
268278 . map_err ( |_| BuildError :: ReadFailed ) ?,
@@ -274,6 +284,7 @@ where
274284 lsps2_service : self . lsps2_service ,
275285 wallet : self . wallet ,
276286 channel_manager : self . channel_manager ,
287+ router : self . router ,
277288 peer_manager : RwLock :: new ( None ) ,
278289 keys_manager : self . keys_manager ,
279290 liquidity_manager,
@@ -292,6 +303,7 @@ where
292303 lsps2_service : Option < LSPS2Service > ,
293304 wallet : Arc < Wallet > ,
294305 channel_manager : Arc < ChannelManager > ,
306+ router : Arc < Router > ,
295307 peer_manager : RwLock < Option < Weak < PeerManager > > > ,
296308 keys_manager : Arc < KeysManager > ,
297309 liquidity_manager : Arc < LiquidityManager > ,
@@ -1192,6 +1204,104 @@ where
11921204 Ok ( ( invoice, min_prop_fee_ppm_msat) )
11931205 }
11941206
1207+ pub ( crate ) async fn lsps2_register_bolt12_payment_paths (
1208+ & self , offer_id : OfferId , amount_msat : u64 , max_total_lsp_fee_limit_msat : Option < u64 > ,
1209+ ) -> Result < u64 , Error > {
1210+ let fee_response = self . lsps2_request_opening_fee_params ( ) . await ?;
1211+
1212+ let ( min_total_fee_msat, min_opening_params) = fee_response
1213+ . opening_fee_params_menu
1214+ . into_iter ( )
1215+ . filter_map ( |params| {
1216+ if amount_msat < params. min_payment_size_msat
1217+ || amount_msat > params. max_payment_size_msat
1218+ {
1219+ log_debug ! ( self . logger,
1220+ "Skipping LSP-offered JIT parameters as the payment of {}msat doesn't meet LSP limits (min: {}msat, max: {}msat)" ,
1221+ amount_msat,
1222+ params. min_payment_size_msat,
1223+ params. max_payment_size_msat
1224+ ) ;
1225+ None
1226+ } else {
1227+ compute_opening_fee ( amount_msat, params. min_fee_msat , params. proportional as u64 )
1228+ . map ( |fee| ( fee, params) )
1229+ }
1230+ } )
1231+ . min_by_key ( |p| p. 0 )
1232+ . ok_or_else ( || {
1233+ log_error ! ( self . logger, "Failed to handle response from liquidity service" , ) ;
1234+ Error :: LiquidityRequestFailed
1235+ } ) ?;
1236+
1237+ if let Some ( max_total_lsp_fee_limit_msat) = max_total_lsp_fee_limit_msat {
1238+ if min_total_fee_msat > max_total_lsp_fee_limit_msat {
1239+ log_error ! ( self . logger,
1240+ "Failed to request inbound JIT channel as LSP's requested total opening fee of {}msat exceeds our fee limit of {}msat" ,
1241+ min_total_fee_msat, max_total_lsp_fee_limit_msat
1242+ ) ;
1243+ return Err ( Error :: LiquidityFeeTooHigh ) ;
1244+ }
1245+ }
1246+
1247+ let buy_response =
1248+ self . lsps2_send_buy_request ( Some ( amount_msat) , min_opening_params) . await ?;
1249+ self . register_lsps2_bolt12_payment_paths ( offer_id, buy_response) ?;
1250+
1251+ Ok ( min_total_fee_msat)
1252+ }
1253+
1254+ pub ( crate ) async fn lsps2_register_variable_amount_bolt12_payment_paths (
1255+ & self , offer_id : OfferId , max_proportional_lsp_fee_limit_ppm_msat : Option < u64 > ,
1256+ ) -> Result < u64 , Error > {
1257+ let fee_response = self . lsps2_request_opening_fee_params ( ) . await ?;
1258+
1259+ let ( min_prop_fee_ppm_msat, min_opening_params) = fee_response
1260+ . opening_fee_params_menu
1261+ . into_iter ( )
1262+ . map ( |params| ( params. proportional as u64 , params) )
1263+ . min_by_key ( |p| p. 0 )
1264+ . ok_or_else ( || {
1265+ log_error ! ( self . logger, "Failed to handle response from liquidity service" , ) ;
1266+ Error :: LiquidityRequestFailed
1267+ } ) ?;
1268+
1269+ if let Some ( max_proportional_lsp_fee_limit_ppm_msat) =
1270+ max_proportional_lsp_fee_limit_ppm_msat
1271+ {
1272+ if min_prop_fee_ppm_msat > max_proportional_lsp_fee_limit_ppm_msat {
1273+ log_error ! ( self . logger,
1274+ "Failed to request inbound JIT channel as LSP's requested proportional opening fee of {} ppm msat exceeds our fee limit of {} ppm msat" ,
1275+ min_prop_fee_ppm_msat,
1276+ max_proportional_lsp_fee_limit_ppm_msat
1277+ ) ;
1278+ return Err ( Error :: LiquidityFeeTooHigh ) ;
1279+ }
1280+ }
1281+
1282+ let buy_response = self . lsps2_send_buy_request ( None , min_opening_params) . await ?;
1283+ self . register_lsps2_bolt12_payment_paths ( offer_id, buy_response) ?;
1284+
1285+ Ok ( min_prop_fee_ppm_msat)
1286+ }
1287+
1288+ fn register_lsps2_bolt12_payment_paths (
1289+ & self , offer_id : OfferId , buy_response : LSPS2BuyResponse ,
1290+ ) -> Result < ( ) , Error > {
1291+ let lsps2_client = self . lsps2_client . as_ref ( ) . ok_or ( Error :: LiquiditySourceUnavailable ) ?;
1292+
1293+ self . router . register_offer (
1294+ offer_id,
1295+ LSPS2Bolt12InvoiceParameters {
1296+ counterparty_node_id : lsps2_client. lsp_node_id ,
1297+ intercept_scid : buy_response. intercept_scid ,
1298+ cltv_expiry_delta : buy_response. cltv_expiry_delta ,
1299+ } ,
1300+ ) ;
1301+
1302+ Ok ( ( ) )
1303+ }
1304+
11951305 async fn lsps2_request_opening_fee_params ( & self ) -> Result < LSPS2FeeResponse , Error > {
11961306 let lsps2_client = self . lsps2_client . as_ref ( ) . ok_or ( Error :: LiquiditySourceUnavailable ) ?;
11971307
@@ -1304,7 +1414,14 @@ where
13041414 src_node_id: lsps2_client. lsp_node_id,
13051415 short_channel_id: buy_response. intercept_scid,
13061416 fees: RoutingFees { base_msat: 0 , proportional_millionths: 0 } ,
1307- cltv_expiry_delta: buy_response. cltv_expiry_delta as u16 ,
1417+ cltv_expiry_delta: u16 :: try_from( buy_response. cltv_expiry_delta) . map_err( |_| {
1418+ log_error!(
1419+ self . logger,
1420+ "Failed to create JIT invoice as LSPS2 CLTV delta {} exceeds supported range" ,
1421+ buy_response. cltv_expiry_delta
1422+ ) ;
1423+ Error :: LiquidityRequestFailed
1424+ } ) ?,
13081425 htlc_minimum_msat: None ,
13091426 htlc_maximum_msat: None ,
13101427 } ] ) ;
0 commit comments