@@ -33,6 +33,7 @@ use lightning_liquidity::lsps1::msgs::{
3333use lightning_liquidity:: lsps2:: client:: LSPS2ClientConfig as LdkLSPS2ClientConfig ;
3434use lightning_liquidity:: lsps2:: event:: { LSPS2ClientEvent , LSPS2ServiceEvent } ;
3535use lightning_liquidity:: lsps2:: msgs:: { LSPS2OpeningFeeParams , LSPS2RawOpeningFeeParams } ;
36+ use lightning_liquidity:: lsps2:: router:: LSPS2Bolt12InvoiceParameters ;
3637use lightning_liquidity:: lsps2:: service:: LSPS2ServiceConfig as LdkLSPS2ServiceConfig ;
3738use lightning_liquidity:: lsps2:: utils:: compute_opening_fee;
3839use lightning_liquidity:: { LiquidityClientConfig , LiquidityServiceConfig } ;
@@ -1232,6 +1233,114 @@ where
12321233 Ok ( invoice)
12331234 }
12341235
1236+ pub ( crate ) async fn lsps2_bolt12_payment_metadata (
1237+ & self , amount_msat : u64 , max_total_lsp_fee_limit_msat : Option < u64 > ,
1238+ ) -> Result < ( u64 , PaymentMetadata ) , Error > {
1239+ let fee_response = self . lsps2_request_opening_fee_params ( ) . await ?;
1240+
1241+ let ( min_total_fee_msat, min_opening_params) = fee_response
1242+ . opening_fee_params_menu
1243+ . into_iter ( )
1244+ . filter_map ( |params| {
1245+ if amount_msat < params. min_payment_size_msat
1246+ || amount_msat > params. max_payment_size_msat
1247+ {
1248+ log_debug ! ( self . logger,
1249+ "Skipping LSP-offered JIT parameters as the payment of {}msat doesn't meet LSP limits (min: {}msat, max: {}msat)" ,
1250+ amount_msat,
1251+ params. min_payment_size_msat,
1252+ params. max_payment_size_msat
1253+ ) ;
1254+ None
1255+ } else {
1256+ compute_opening_fee ( amount_msat, params. min_fee_msat , params. proportional as u64 )
1257+ . map ( |fee| ( fee, params) )
1258+ }
1259+ } )
1260+ . min_by_key ( |p| p. 0 )
1261+ . ok_or_else ( || {
1262+ log_error ! ( self . logger, "Failed to handle response from liquidity service" , ) ;
1263+ Error :: LiquidityRequestFailed
1264+ } ) ?;
1265+
1266+ if let Some ( max_total_lsp_fee_limit_msat) = max_total_lsp_fee_limit_msat {
1267+ if min_total_fee_msat > max_total_lsp_fee_limit_msat {
1268+ log_error ! ( self . logger,
1269+ "Failed to request inbound JIT channel as LSP's requested total opening fee of {}msat exceeds our fee limit of {}msat" ,
1270+ min_total_fee_msat, max_total_lsp_fee_limit_msat
1271+ ) ;
1272+ return Err ( Error :: LiquidityFeeTooHigh ) ;
1273+ }
1274+ }
1275+
1276+ let buy_response =
1277+ self . lsps2_send_buy_request ( Some ( amount_msat) , min_opening_params) . await ?;
1278+ let metadata = self . lsps2_bolt12_metadata_from_buy_response (
1279+ buy_response,
1280+ LSPS2Parameters {
1281+ max_total_opening_fee_msat : Some ( min_total_fee_msat) ,
1282+ max_proportional_opening_fee_ppm_msat : None ,
1283+ } ,
1284+ ) ?;
1285+
1286+ Ok ( ( min_total_fee_msat, metadata) )
1287+ }
1288+
1289+ pub ( crate ) async fn lsps2_variable_amount_bolt12_payment_metadata (
1290+ & self , max_proportional_lsp_fee_limit_ppm_msat : Option < u64 > ,
1291+ ) -> Result < ( u64 , PaymentMetadata ) , Error > {
1292+ let fee_response = self . lsps2_request_opening_fee_params ( ) . await ?;
1293+
1294+ let ( min_prop_fee_ppm_msat, min_opening_params) = fee_response
1295+ . opening_fee_params_menu
1296+ . into_iter ( )
1297+ . map ( |params| ( params. proportional as u64 , params) )
1298+ . min_by_key ( |p| p. 0 )
1299+ . ok_or_else ( || {
1300+ log_error ! ( self . logger, "Failed to handle response from liquidity service" , ) ;
1301+ Error :: LiquidityRequestFailed
1302+ } ) ?;
1303+
1304+ if let Some ( max_proportional_lsp_fee_limit_ppm_msat) =
1305+ max_proportional_lsp_fee_limit_ppm_msat
1306+ {
1307+ if min_prop_fee_ppm_msat > max_proportional_lsp_fee_limit_ppm_msat {
1308+ log_error ! ( self . logger,
1309+ "Failed to request inbound JIT channel as LSP's requested proportional opening fee of {} ppm msat exceeds our fee limit of {} ppm msat" ,
1310+ min_prop_fee_ppm_msat,
1311+ max_proportional_lsp_fee_limit_ppm_msat
1312+ ) ;
1313+ return Err ( Error :: LiquidityFeeTooHigh ) ;
1314+ }
1315+ }
1316+
1317+ let buy_response = self . lsps2_send_buy_request ( None , min_opening_params) . await ?;
1318+ let metadata = self . lsps2_bolt12_metadata_from_buy_response (
1319+ buy_response,
1320+ LSPS2Parameters {
1321+ max_total_opening_fee_msat : None ,
1322+ max_proportional_opening_fee_ppm_msat : Some ( min_prop_fee_ppm_msat) ,
1323+ } ,
1324+ ) ?;
1325+
1326+ Ok ( ( min_prop_fee_ppm_msat, metadata) )
1327+ }
1328+
1329+ fn lsps2_bolt12_metadata_from_buy_response (
1330+ & self , buy_response : LSPS2BuyResponse , lsps2_parameters : LSPS2Parameters ,
1331+ ) -> Result < PaymentMetadata , Error > {
1332+ let lsps2_client = self . lsps2_client . as_ref ( ) . ok_or ( Error :: LiquiditySourceUnavailable ) ?;
1333+
1334+ Ok ( PaymentMetadata {
1335+ lsps2_parameters : Some ( lsps2_parameters) ,
1336+ lsps2_bolt12_invoice_parameters : Some ( LSPS2Bolt12InvoiceParameters {
1337+ counterparty_node_id : lsps2_client. lsp_node_id ,
1338+ intercept_scid : buy_response. intercept_scid ,
1339+ cltv_expiry_delta : buy_response. cltv_expiry_delta ,
1340+ } ) ,
1341+ } )
1342+ }
1343+
12351344 async fn lsps2_request_opening_fee_params ( & self ) -> Result < LSPS2FeeResponse , Error > {
12361345 let lsps2_client = self . lsps2_client . as_ref ( ) . ok_or ( Error :: LiquiditySourceUnavailable ) ?;
12371346
@@ -1317,8 +1426,11 @@ where
13171426
13181427 // LSPS2 requires min_final_cltv_expiry_delta to be at least 2 more than usual.
13191428 let min_final_cltv_expiry_delta = MIN_FINAL_CLTV_EXPIRY_DELTA + 2 ;
1320- let encoded_payment_metadata =
1321- PaymentMetadata { lsps2_parameters : Some ( lsps2_parameters) } . encode ( ) ;
1429+ let encoded_payment_metadata = PaymentMetadata {
1430+ lsps2_parameters : Some ( lsps2_parameters) ,
1431+ lsps2_bolt12_invoice_parameters : None ,
1432+ }
1433+ . encode ( ) ;
13221434 let ( payment_hash, payment_secret, payment_metadata) = match payment_hash {
13231435 Some ( payment_hash) => {
13241436 let ( payment_secret, payment_metadata) = self
@@ -1354,7 +1466,7 @@ where
13541466 src_node_id: lsps2_client. lsp_node_id,
13551467 short_channel_id: buy_response. intercept_scid,
13561468 fees: RoutingFees { base_msat: 0 , proportional_millionths: 0 } ,
1357- cltv_expiry_delta: buy_response. cltv_expiry_delta as u16 ,
1469+ cltv_expiry_delta: buy_response. cltv_expiry_delta,
13581470 htlc_minimum_msat: None ,
13591471 htlc_maximum_msat: None ,
13601472 } ] ) ;
0 commit comments