Skip to content

Commit bd97482

Browse files
committed
Add receive_via_jit_channel_for_hash() method
1 parent 0a2bccd commit bd97482

File tree

3 files changed

+79
-13
lines changed

3 files changed

+79
-13
lines changed

src/event.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,8 @@ where
683683
// the payment has been registered via `_for_hash` variants and needs to be manually claimed via
684684
// user interaction.
685685
match info.kind {
686-
PaymentKind::Bolt11 { preimage, .. } => {
686+
PaymentKind::Bolt11 { preimage, .. }
687+
| PaymentKind::Bolt11Jit { preimage, .. } => {
687688
if purpose.preimage().is_none() {
688689
debug_assert!(
689690
preimage.is_none(),

src/liquidity.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ where
987987

988988
pub(crate) async fn lsps2_receive_to_jit_channel(
989989
&self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32,
990-
max_total_lsp_fee_limit_msat: Option<u64>,
990+
max_total_lsp_fee_limit_msat: Option<u64>, payment_hash: Option<PaymentHash>,
991991
) -> Result<(Bolt11Invoice, u64), Error> {
992992
let fee_response = self.lsps2_request_opening_fee_params().await?;
993993

@@ -1039,6 +1039,7 @@ where
10391039
Some(amount_msat),
10401040
description,
10411041
expiry_secs,
1042+
payment_hash,
10421043
)?;
10431044

10441045
log_info!(self.logger, "JIT-channel invoice created: {}", invoice);
@@ -1047,7 +1048,7 @@ where
10471048

10481049
pub(crate) async fn lsps2_receive_variable_amount_to_jit_channel(
10491050
&self, description: &Bolt11InvoiceDescription, expiry_secs: u32,
1050-
max_proportional_lsp_fee_limit_ppm_msat: Option<u64>,
1051+
max_proportional_lsp_fee_limit_ppm_msat: Option<u64>, payment_hash: Option<PaymentHash>,
10511052
) -> Result<(Bolt11Invoice, u64), Error> {
10521053
let fee_response = self.lsps2_request_opening_fee_params().await?;
10531054

@@ -1081,8 +1082,13 @@ where
10811082
);
10821083

10831084
let buy_response = self.lsps2_send_buy_request(None, min_opening_params).await?;
1084-
let invoice =
1085-
self.lsps2_create_jit_invoice(buy_response, None, description, expiry_secs)?;
1085+
let invoice = self.lsps2_create_jit_invoice(
1086+
buy_response,
1087+
None,
1088+
description,
1089+
expiry_secs,
1090+
payment_hash,
1091+
)?;
10861092

10871093
log_info!(self.logger, "JIT-channel invoice created: {}", invoice);
10881094
Ok((invoice, min_prop_fee_ppm_msat))
@@ -1165,18 +1171,36 @@ where
11651171
fn lsps2_create_jit_invoice(
11661172
&self, buy_response: LSPS2BuyResponse, amount_msat: Option<u64>,
11671173
description: &Bolt11InvoiceDescription, expiry_secs: u32,
1174+
payment_hash: Option<PaymentHash>,
11681175
) -> Result<Bolt11Invoice, Error> {
11691176
let lsps2_client = self.lsps2_client.as_ref().ok_or(Error::LiquiditySourceUnavailable)?;
11701177

11711178
// LSPS2 requires min_final_cltv_expiry_delta to be at least 2 more than usual.
11721179
let min_final_cltv_expiry_delta = MIN_FINAL_CLTV_EXPIRY_DELTA + 2;
1173-
let (payment_hash, payment_secret) = self
1174-
.channel_manager
1175-
.create_inbound_payment(None, expiry_secs, Some(min_final_cltv_expiry_delta))
1176-
.map_err(|e| {
1177-
log_error!(self.logger, "Failed to register inbound payment: {:?}", e);
1178-
Error::InvoiceCreationFailed
1179-
})?;
1180+
let (payment_hash, payment_secret) = match payment_hash {
1181+
Some(payment_hash) => {
1182+
let payment_secret = self
1183+
.channel_manager
1184+
.create_inbound_payment_for_hash(
1185+
payment_hash,
1186+
None,
1187+
expiry_secs,
1188+
Some(min_final_cltv_expiry_delta),
1189+
)
1190+
.map_err(|e| {
1191+
log_error!(self.logger, "Failed to register inbound payment: {:?}", e);
1192+
Error::InvoiceCreationFailed
1193+
})?;
1194+
(payment_hash, payment_secret)
1195+
},
1196+
None => self
1197+
.channel_manager
1198+
.create_inbound_payment(None, expiry_secs, Some(min_final_cltv_expiry_delta))
1199+
.map_err(|e| {
1200+
log_error!(self.logger, "Failed to register inbound payment: {:?}", e);
1201+
Error::InvoiceCreationFailed
1202+
})?,
1203+
};
11801204

11811205
let route_hint = RouteHint(vec![RouteHintHop {
11821206
src_node_id: lsps2_client.lsp_node_id,

src/payment/bolt11.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,44 @@ impl Bolt11Payment {
578578
expiry_secs,
579579
max_total_lsp_fee_limit_msat,
580580
None,
581+
None,
582+
)?;
583+
Ok(maybe_wrap(invoice))
584+
}
585+
586+
/// Returns a payable invoice that can be used to request a payment of the amount given and
587+
/// receive it via a newly created just-in-time (JIT) channel.
588+
///
589+
/// When the returned invoice is paid, the configured [LSPS2]-compliant LSP will open a channel
590+
/// to us, supplying just-in-time inbound liquidity.
591+
///
592+
/// If set, `max_total_lsp_fee_limit_msat` will limit how much fee we allow the LSP to take for opening the
593+
/// channel to us. We'll use its cheapest offer otherwise.
594+
///
595+
/// We will register the given payment hash and emit a [`PaymentClaimable`] event once
596+
/// the inbound payment arrives.
597+
///
598+
/// **Note:** users *MUST* handle this event and claim the payment manually via
599+
/// [`claim_for_hash`] as soon as they have obtained access to the preimage of the given
600+
/// payment hash. If they're unable to obtain the preimage, they *MUST* immediately fail the payment via
601+
/// [`fail_for_hash`].
602+
///
603+
/// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
604+
/// [`PaymentClaimable`]: crate::Event::PaymentClaimable
605+
/// [`claim_for_hash`]: Self::claim_for_hash
606+
/// [`fail_for_hash`]: Self::fail_for_hash
607+
pub fn receive_via_jit_channel_for_hash(
608+
&self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32,
609+
max_total_lsp_fee_limit_msat: Option<u64>, payment_hash: PaymentHash,
610+
) -> Result<Bolt11Invoice, Error> {
611+
let description = maybe_try_convert_enum(description)?;
612+
let invoice = self.receive_via_jit_channel_inner(
613+
Some(amount_msat),
614+
&description,
615+
expiry_secs,
616+
max_total_lsp_fee_limit_msat,
617+
None,
618+
Some(payment_hash),
581619
)?;
582620
Ok(maybe_wrap(invoice))
583621
}
@@ -604,14 +642,15 @@ impl Bolt11Payment {
604642
expiry_secs,
605643
None,
606644
max_proportional_lsp_fee_limit_ppm_msat,
645+
None,
607646
)?;
608647
Ok(maybe_wrap(invoice))
609648
}
610649

611650
fn receive_via_jit_channel_inner(
612651
&self, amount_msat: Option<u64>, description: &LdkBolt11InvoiceDescription,
613652
expiry_secs: u32, max_total_lsp_fee_limit_msat: Option<u64>,
614-
max_proportional_lsp_fee_limit_ppm_msat: Option<u64>,
653+
max_proportional_lsp_fee_limit_ppm_msat: Option<u64>, payment_hash: Option<PaymentHash>,
615654
) -> Result<LdkBolt11Invoice, Error> {
616655
let liquidity_source =
617656
self.liquidity_source.as_ref().ok_or(Error::LiquiditySourceUnavailable)?;
@@ -649,6 +688,7 @@ impl Bolt11Payment {
649688
description,
650689
expiry_secs,
651690
max_total_lsp_fee_limit_msat,
691+
payment_hash,
652692
)
653693
.await
654694
.map(|(invoice, total_fee)| (invoice, Some(total_fee), None))
@@ -658,6 +698,7 @@ impl Bolt11Payment {
658698
description,
659699
expiry_secs,
660700
max_proportional_lsp_fee_limit_ppm_msat,
701+
payment_hash,
661702
)
662703
.await
663704
.map(|(invoice, prop_fee)| (invoice, None, Some(prop_fee)))

0 commit comments

Comments
 (0)