ldk_node/payment/
bolt11.rs

1// This file is Copyright its original authors, visible in version control history.
2//
3// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
6// accordance with one or both of these licenses.
7
8//! Holds a payment handler allowing to create and pay [BOLT 11] invoices.
9//!
10//! [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
11
12use std::sync::{Arc, RwLock};
13
14use bitcoin::hashes::sha256::Hash as Sha256;
15use bitcoin::hashes::Hash;
16use lightning::ln::channelmanager::{
17	Bolt11InvoiceParameters, Bolt11PaymentError, PaymentId, Retry, RetryableSendFailure,
18};
19use lightning::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig};
20use lightning_invoice::{
21	Bolt11Invoice as LdkBolt11Invoice, Bolt11InvoiceDescription as LdkBolt11InvoiceDescription,
22};
23use lightning_types::payment::{PaymentHash, PaymentPreimage};
24
25use crate::config::{Config, LDK_PAYMENT_RETRY_TIMEOUT};
26use crate::connection::ConnectionManager;
27use crate::data_store::DataStoreUpdateResult;
28use crate::error::Error;
29use crate::ffi::{maybe_deref, maybe_try_convert_enum, maybe_wrap};
30use crate::liquidity::LiquiditySource;
31use crate::logger::{log_error, log_info, LdkLogger, Logger};
32use crate::payment::store::{
33	LSPFeeLimits, PaymentDetails, PaymentDetailsUpdate, PaymentDirection, PaymentKind,
34	PaymentStatus,
35};
36use crate::peer_store::{PeerInfo, PeerStore};
37use crate::runtime::Runtime;
38use crate::types::{ChannelManager, PaymentStore};
39
40#[cfg(not(feature = "uniffi"))]
41type Bolt11Invoice = LdkBolt11Invoice;
42#[cfg(feature = "uniffi")]
43type Bolt11Invoice = Arc<crate::ffi::Bolt11Invoice>;
44
45#[cfg(not(feature = "uniffi"))]
46type Bolt11InvoiceDescription = LdkBolt11InvoiceDescription;
47#[cfg(feature = "uniffi")]
48type Bolt11InvoiceDescription = crate::ffi::Bolt11InvoiceDescription;
49
50/// A payment handler allowing to create and pay [BOLT 11] invoices.
51///
52/// Should be retrieved by calling [`Node::bolt11_payment`].
53///
54/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
55/// [`Node::bolt11_payment`]: crate::Node::bolt11_payment
56pub struct Bolt11Payment {
57	runtime: Arc<Runtime>,
58	channel_manager: Arc<ChannelManager>,
59	connection_manager: Arc<ConnectionManager<Arc<Logger>>>,
60	liquidity_source: Option<Arc<LiquiditySource<Arc<Logger>>>>,
61	payment_store: Arc<PaymentStore>,
62	peer_store: Arc<PeerStore<Arc<Logger>>>,
63	config: Arc<Config>,
64	is_running: Arc<RwLock<bool>>,
65	logger: Arc<Logger>,
66}
67
68impl Bolt11Payment {
69	pub(crate) fn new(
70		runtime: Arc<Runtime>, channel_manager: Arc<ChannelManager>,
71		connection_manager: Arc<ConnectionManager<Arc<Logger>>>,
72		liquidity_source: Option<Arc<LiquiditySource<Arc<Logger>>>>,
73		payment_store: Arc<PaymentStore>, peer_store: Arc<PeerStore<Arc<Logger>>>,
74		config: Arc<Config>, is_running: Arc<RwLock<bool>>, logger: Arc<Logger>,
75	) -> Self {
76		Self {
77			runtime,
78			channel_manager,
79			connection_manager,
80			liquidity_source,
81			payment_store,
82			peer_store,
83			config,
84			is_running,
85			logger,
86		}
87	}
88
89	/// Send a payment given an invoice.
90	///
91	/// If `route_parameters` are provided they will override the default as well as the
92	/// node-wide parameters configured via [`Config::route_parameters`] on a per-field basis.
93	pub fn send(
94		&self, invoice: &Bolt11Invoice, route_parameters: Option<RouteParametersConfig>,
95	) -> Result<PaymentId, Error> {
96		if !*self.is_running.read().unwrap() {
97			return Err(Error::NotRunning);
98		}
99
100		let invoice = maybe_deref(invoice);
101		let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
102		let payment_id = PaymentId(invoice.payment_hash().to_byte_array());
103		if let Some(payment) = self.payment_store.get(&payment_id) {
104			if payment.status == PaymentStatus::Pending
105				|| payment.status == PaymentStatus::Succeeded
106			{
107				log_error!(self.logger, "Payment error: an invoice must not be paid twice.");
108				return Err(Error::DuplicatePayment);
109			}
110		}
111
112		let route_parameters =
113			route_parameters.or(self.config.route_parameters).unwrap_or_default();
114		let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
115		let payment_secret = Some(*invoice.payment_secret());
116
117		match self.channel_manager.pay_for_bolt11_invoice(
118			invoice,
119			payment_id,
120			None,
121			route_parameters,
122			retry_strategy,
123		) {
124			Ok(()) => {
125				let payee_pubkey = invoice.recover_payee_pub_key();
126				let amt_msat = invoice.amount_milli_satoshis().unwrap();
127				log_info!(self.logger, "Initiated sending {}msat to {}", amt_msat, payee_pubkey);
128
129				let kind = PaymentKind::Bolt11 {
130					hash: payment_hash,
131					preimage: None,
132					secret: payment_secret,
133				};
134				let payment = PaymentDetails::new(
135					payment_id,
136					kind,
137					invoice.amount_milli_satoshis(),
138					None,
139					PaymentDirection::Outbound,
140					PaymentStatus::Pending,
141				);
142
143				self.payment_store.insert(payment)?;
144
145				Ok(payment_id)
146			},
147			Err(Bolt11PaymentError::InvalidAmount) => {
148				log_error!(self.logger,
149					"Failed to send payment due to the given invoice being \"zero-amount\". Please use send_using_amount instead."
150				);
151				return Err(Error::InvalidInvoice);
152			},
153			Err(Bolt11PaymentError::SendingFailed(e)) => {
154				log_error!(self.logger, "Failed to send payment: {:?}", e);
155				match e {
156					RetryableSendFailure::DuplicatePayment => Err(Error::DuplicatePayment),
157					_ => {
158						let kind = PaymentKind::Bolt11 {
159							hash: payment_hash,
160							preimage: None,
161							secret: payment_secret,
162						};
163						let payment = PaymentDetails::new(
164							payment_id,
165							kind,
166							invoice.amount_milli_satoshis(),
167							None,
168							PaymentDirection::Outbound,
169							PaymentStatus::Failed,
170						);
171
172						self.payment_store.insert(payment)?;
173						Err(Error::PaymentSendingFailed)
174					},
175				}
176			},
177		}
178	}
179
180	/// Send a payment given an invoice and an amount in millisatoshis.
181	///
182	/// This will fail if the amount given is less than the value required by the given invoice.
183	///
184	/// This can be used to pay a so-called "zero-amount" invoice, i.e., an invoice that leaves the
185	/// amount paid to be determined by the user.
186	///
187	/// If `route_parameters` are provided they will override the default as well as the
188	/// node-wide parameters configured via [`Config::route_parameters`] on a per-field basis.
189	pub fn send_using_amount(
190		&self, invoice: &Bolt11Invoice, amount_msat: u64,
191		route_parameters: Option<RouteParametersConfig>,
192	) -> Result<PaymentId, Error> {
193		if !*self.is_running.read().unwrap() {
194			return Err(Error::NotRunning);
195		}
196
197		let invoice = maybe_deref(invoice);
198		if let Some(invoice_amount_msat) = invoice.amount_milli_satoshis() {
199			if amount_msat < invoice_amount_msat {
200				log_error!(
201					self.logger,
202					"Failed to pay as the given amount needs to be at least the invoice amount: required {}msat, gave {}msat.", invoice_amount_msat, amount_msat);
203				return Err(Error::InvalidAmount);
204			}
205		}
206
207		let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
208		let payment_id = PaymentId(invoice.payment_hash().to_byte_array());
209		if let Some(payment) = self.payment_store.get(&payment_id) {
210			if payment.status == PaymentStatus::Pending
211				|| payment.status == PaymentStatus::Succeeded
212			{
213				log_error!(self.logger, "Payment error: an invoice must not be paid twice.");
214				return Err(Error::DuplicatePayment);
215			}
216		}
217
218		let route_parameters =
219			route_parameters.or(self.config.route_parameters).unwrap_or_default();
220		let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
221		let payment_secret = Some(*invoice.payment_secret());
222
223		match self.channel_manager.pay_for_bolt11_invoice(
224			invoice,
225			payment_id,
226			Some(amount_msat),
227			route_parameters,
228			retry_strategy,
229		) {
230			Ok(()) => {
231				let payee_pubkey = invoice.recover_payee_pub_key();
232				log_info!(
233					self.logger,
234					"Initiated sending {} msat to {}",
235					amount_msat,
236					payee_pubkey
237				);
238
239				let kind = PaymentKind::Bolt11 {
240					hash: payment_hash,
241					preimage: None,
242					secret: payment_secret,
243				};
244
245				let payment = PaymentDetails::new(
246					payment_id,
247					kind,
248					Some(amount_msat),
249					None,
250					PaymentDirection::Outbound,
251					PaymentStatus::Pending,
252				);
253				self.payment_store.insert(payment)?;
254
255				Ok(payment_id)
256			},
257			Err(Bolt11PaymentError::InvalidAmount) => {
258				log_error!(
259					self.logger,
260					"Failed to send payment due to amount given being insufficient."
261				);
262				return Err(Error::InvalidInvoice);
263			},
264			Err(Bolt11PaymentError::SendingFailed(e)) => {
265				log_error!(self.logger, "Failed to send payment: {:?}", e);
266				match e {
267					RetryableSendFailure::DuplicatePayment => Err(Error::DuplicatePayment),
268					_ => {
269						let kind = PaymentKind::Bolt11 {
270							hash: payment_hash,
271							preimage: None,
272							secret: payment_secret,
273						};
274						let payment = PaymentDetails::new(
275							payment_id,
276							kind,
277							Some(amount_msat),
278							None,
279							PaymentDirection::Outbound,
280							PaymentStatus::Failed,
281						);
282
283						self.payment_store.insert(payment)?;
284						Err(Error::PaymentSendingFailed)
285					},
286				}
287			},
288		}
289	}
290
291	/// Allows to attempt manually claiming payments with the given preimage that have previously
292	/// been registered via [`receive_for_hash`] or [`receive_variable_amount_for_hash`].
293	///
294	/// This should be called in reponse to a [`PaymentClaimable`] event as soon as the preimage is
295	/// available.
296	///
297	/// Will check that the payment is known, and that the given preimage and claimable amount
298	/// match our expectations before attempting to claim the payment, and will return an error
299	/// otherwise.
300	///
301	/// When claiming the payment has succeeded, a [`PaymentReceived`] event will be emitted.
302	///
303	/// [`receive_for_hash`]: Self::receive_for_hash
304	/// [`receive_variable_amount_for_hash`]: Self::receive_variable_amount_for_hash
305	/// [`PaymentClaimable`]: crate::Event::PaymentClaimable
306	/// [`PaymentReceived`]: crate::Event::PaymentReceived
307	pub fn claim_for_hash(
308		&self, payment_hash: PaymentHash, claimable_amount_msat: u64, preimage: PaymentPreimage,
309	) -> Result<(), Error> {
310		let payment_id = PaymentId(payment_hash.0);
311
312		let expected_payment_hash = PaymentHash(Sha256::hash(&preimage.0).to_byte_array());
313
314		if expected_payment_hash != payment_hash {
315			log_error!(
316				self.logger,
317				"Failed to manually claim payment as the given preimage doesn't match the hash {}",
318				payment_hash
319			);
320			return Err(Error::InvalidPaymentPreimage);
321		}
322
323		if let Some(details) = self.payment_store.get(&payment_id) {
324			// For payments requested via `receive*_via_jit_channel_for_hash()`
325			// `skimmed_fee_msat` held by LSP must be taken into account.
326			let skimmed_fee_msat = match details.kind {
327				PaymentKind::Bolt11Jit {
328					counterparty_skimmed_fee_msat: Some(skimmed_fee_msat),
329					..
330				} => skimmed_fee_msat,
331				_ => 0,
332			};
333			if let Some(invoice_amount_msat) = details.amount_msat {
334				if claimable_amount_msat < invoice_amount_msat - skimmed_fee_msat {
335					log_error!(
336						self.logger,
337						"Failed to manually claim payment {} as the claimable amount is less than expected",
338						payment_id
339					);
340					return Err(Error::InvalidAmount);
341				}
342			}
343		} else {
344			log_error!(
345				self.logger,
346				"Failed to manually claim unknown payment with hash: {}",
347				payment_hash
348			);
349			return Err(Error::InvalidPaymentHash);
350		}
351
352		self.channel_manager.claim_funds(preimage);
353		Ok(())
354	}
355
356	/// Allows to manually fail payments with the given hash that have previously
357	/// been registered via [`receive_for_hash`] or [`receive_variable_amount_for_hash`].
358	///
359	/// This should be called in reponse to a [`PaymentClaimable`] event if the payment needs to be
360	/// failed back, e.g., if the correct preimage can't be retrieved in time before the claim
361	/// deadline has been reached.
362	///
363	/// Will check that the payment is known before failing the payment, and will return an error
364	/// otherwise.
365	///
366	/// [`receive_for_hash`]: Self::receive_for_hash
367	/// [`receive_variable_amount_for_hash`]: Self::receive_variable_amount_for_hash
368	/// [`PaymentClaimable`]: crate::Event::PaymentClaimable
369	pub fn fail_for_hash(&self, payment_hash: PaymentHash) -> Result<(), Error> {
370		let payment_id = PaymentId(payment_hash.0);
371
372		let update = PaymentDetailsUpdate {
373			status: Some(PaymentStatus::Failed),
374			..PaymentDetailsUpdate::new(payment_id)
375		};
376
377		match self.payment_store.update(&update) {
378			Ok(DataStoreUpdateResult::Updated) | Ok(DataStoreUpdateResult::Unchanged) => (),
379			Ok(DataStoreUpdateResult::NotFound) => {
380				log_error!(
381					self.logger,
382					"Failed to manually fail unknown payment with hash {}",
383					payment_hash,
384				);
385				return Err(Error::InvalidPaymentHash);
386			},
387			Err(e) => {
388				log_error!(
389					self.logger,
390					"Failed to manually fail payment with hash {}: {}",
391					payment_hash,
392					e
393				);
394				return Err(e);
395			},
396		}
397
398		self.channel_manager.fail_htlc_backwards(&payment_hash);
399		Ok(())
400	}
401
402	/// Returns a payable invoice that can be used to request and receive a payment of the amount
403	/// given.
404	///
405	/// The inbound payment will be automatically claimed upon arrival.
406	pub fn receive(
407		&self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32,
408	) -> Result<Bolt11Invoice, Error> {
409		let description = maybe_try_convert_enum(description)?;
410		let invoice = self.receive_inner(Some(amount_msat), &description, expiry_secs, None)?;
411		Ok(maybe_wrap(invoice))
412	}
413
414	/// Returns a payable invoice that can be used to request a payment of the amount
415	/// given for the given payment hash.
416	///
417	/// We will register the given payment hash and emit a [`PaymentClaimable`] event once
418	/// the inbound payment arrives.
419	///
420	/// **Note:** users *MUST* handle this event and claim the payment manually via
421	/// [`claim_for_hash`] as soon as they have obtained access to the preimage of the given
422	/// payment hash. If they're unable to obtain the preimage, they *MUST* immediately fail the payment via
423	/// [`fail_for_hash`].
424	///
425	/// [`PaymentClaimable`]: crate::Event::PaymentClaimable
426	/// [`claim_for_hash`]: Self::claim_for_hash
427	/// [`fail_for_hash`]: Self::fail_for_hash
428	pub fn receive_for_hash(
429		&self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32,
430		payment_hash: PaymentHash,
431	) -> Result<Bolt11Invoice, Error> {
432		let description = maybe_try_convert_enum(description)?;
433		let invoice =
434			self.receive_inner(Some(amount_msat), &description, expiry_secs, Some(payment_hash))?;
435		Ok(maybe_wrap(invoice))
436	}
437
438	/// Returns a payable invoice that can be used to request and receive a payment for which the
439	/// amount is to be determined by the user, also known as a "zero-amount" invoice.
440	///
441	/// The inbound payment will be automatically claimed upon arrival.
442	pub fn receive_variable_amount(
443		&self, description: &Bolt11InvoiceDescription, expiry_secs: u32,
444	) -> Result<Bolt11Invoice, Error> {
445		let description = maybe_try_convert_enum(description)?;
446		let invoice = self.receive_inner(None, &description, expiry_secs, None)?;
447		Ok(maybe_wrap(invoice))
448	}
449
450	/// Returns a payable invoice that can be used to request a payment for the given payment hash
451	/// and the amount to be determined by the user, also known as a "zero-amount" invoice.
452	///
453	/// We will register the given payment hash and emit a [`PaymentClaimable`] event once
454	/// the inbound payment arrives.
455	///
456	/// **Note:** users *MUST* handle this event and claim the payment manually via
457	/// [`claim_for_hash`] as soon as they have obtained access to the preimage of the given
458	/// payment hash. If they're unable to obtain the preimage, they *MUST* immediately fail the payment via
459	/// [`fail_for_hash`].
460	///
461	/// [`PaymentClaimable`]: crate::Event::PaymentClaimable
462	/// [`claim_for_hash`]: Self::claim_for_hash
463	/// [`fail_for_hash`]: Self::fail_for_hash
464	pub fn receive_variable_amount_for_hash(
465		&self, description: &Bolt11InvoiceDescription, expiry_secs: u32, payment_hash: PaymentHash,
466	) -> Result<Bolt11Invoice, Error> {
467		let description = maybe_try_convert_enum(description)?;
468		let invoice = self.receive_inner(None, &description, expiry_secs, Some(payment_hash))?;
469		Ok(maybe_wrap(invoice))
470	}
471
472	pub(crate) fn receive_inner(
473		&self, amount_msat: Option<u64>, invoice_description: &LdkBolt11InvoiceDescription,
474		expiry_secs: u32, manual_claim_payment_hash: Option<PaymentHash>,
475	) -> Result<LdkBolt11Invoice, Error> {
476		let invoice = {
477			let invoice_params = Bolt11InvoiceParameters {
478				amount_msats: amount_msat,
479				description: invoice_description.clone(),
480				invoice_expiry_delta_secs: Some(expiry_secs),
481				payment_hash: manual_claim_payment_hash,
482				..Default::default()
483			};
484
485			match self.channel_manager.create_bolt11_invoice(invoice_params) {
486				Ok(inv) => {
487					log_info!(self.logger, "Invoice created: {}", inv);
488					inv
489				},
490				Err(e) => {
491					log_error!(self.logger, "Failed to create invoice: {}", e);
492					return Err(Error::InvoiceCreationFailed);
493				},
494			}
495		};
496
497		let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
498		let payment_secret = invoice.payment_secret();
499		let id = PaymentId(payment_hash.0);
500		let preimage = if manual_claim_payment_hash.is_none() {
501			// If the user hasn't registered a custom payment hash, we're positive ChannelManager
502			// will know the preimage at this point.
503			let res = self
504				.channel_manager
505				.get_payment_preimage(payment_hash, payment_secret.clone())
506				.ok();
507			debug_assert!(res.is_some(), "We just let ChannelManager create an inbound payment, it can't have forgotten the preimage by now.");
508			res
509		} else {
510			None
511		};
512		let kind = PaymentKind::Bolt11 {
513			hash: payment_hash,
514			preimage,
515			secret: Some(payment_secret.clone()),
516		};
517		let payment = PaymentDetails::new(
518			id,
519			kind,
520			amount_msat,
521			None,
522			PaymentDirection::Inbound,
523			PaymentStatus::Pending,
524		);
525		self.payment_store.insert(payment)?;
526
527		Ok(invoice)
528	}
529
530	/// Returns a payable invoice that can be used to request a payment of the amount given and
531	/// receive it via a newly created just-in-time (JIT) channel.
532	///
533	/// When the returned invoice is paid, the configured [LSPS2]-compliant LSP will open a channel
534	/// to us, supplying just-in-time inbound liquidity.
535	///
536	/// If set, `max_total_lsp_fee_limit_msat` will limit how much fee we allow the LSP to take for opening the
537	/// channel to us. We'll use its cheapest offer otherwise.
538	///
539	/// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
540	pub fn receive_via_jit_channel(
541		&self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32,
542		max_total_lsp_fee_limit_msat: Option<u64>,
543	) -> Result<Bolt11Invoice, Error> {
544		let description = maybe_try_convert_enum(description)?;
545		let invoice = self.receive_via_jit_channel_inner(
546			Some(amount_msat),
547			&description,
548			expiry_secs,
549			max_total_lsp_fee_limit_msat,
550			None,
551			None,
552		)?;
553		Ok(maybe_wrap(invoice))
554	}
555
556	/// Returns a payable invoice that can be used to request a payment of the amount given and
557	/// receive it via a newly created just-in-time (JIT) channel.
558	///
559	/// When the returned invoice is paid, the configured [LSPS2]-compliant LSP will open a channel
560	/// to us, supplying just-in-time inbound liquidity.
561	///
562	/// If set, `max_total_lsp_fee_limit_msat` will limit how much fee we allow the LSP to take for opening the
563	/// channel to us. We'll use its cheapest offer otherwise.
564	///
565	/// We will register the given payment hash and emit a [`PaymentClaimable`] event once
566	/// the inbound payment arrives. The check that [`counterparty_skimmed_fee_msat`] is within the limits
567	/// is performed *before* emitting the event.
568	///
569	/// **Note:** users *MUST* handle this event and claim the payment manually via
570	/// [`claim_for_hash`] as soon as they have obtained access to the preimage of the given
571	/// payment hash. If they're unable to obtain the preimage, they *MUST* immediately fail the payment via
572	/// [`fail_for_hash`].
573	///
574	/// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
575	/// [`PaymentClaimable`]: crate::Event::PaymentClaimable
576	/// [`claim_for_hash`]: Self::claim_for_hash
577	/// [`fail_for_hash`]: Self::fail_for_hash
578	/// [`counterparty_skimmed_fee_msat`]: crate::payment::PaymentKind::Bolt11Jit::counterparty_skimmed_fee_msat
579	pub fn receive_via_jit_channel_for_hash(
580		&self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32,
581		max_total_lsp_fee_limit_msat: Option<u64>, payment_hash: PaymentHash,
582	) -> Result<Bolt11Invoice, Error> {
583		let description = maybe_try_convert_enum(description)?;
584		let invoice = self.receive_via_jit_channel_inner(
585			Some(amount_msat),
586			&description,
587			expiry_secs,
588			max_total_lsp_fee_limit_msat,
589			None,
590			Some(payment_hash),
591		)?;
592		Ok(maybe_wrap(invoice))
593	}
594
595	/// Returns a payable invoice that can be used to request a variable amount payment (also known
596	/// as "zero-amount" invoice) and receive it via a newly created just-in-time (JIT) channel.
597	///
598	/// When the returned invoice is paid, the configured [LSPS2]-compliant LSP will open a channel
599	/// to us, supplying just-in-time inbound liquidity.
600	///
601	/// If set, `max_proportional_lsp_fee_limit_ppm_msat` will limit how much proportional fee, in
602	/// parts-per-million millisatoshis, we allow the LSP to take for opening the channel to us.
603	/// We'll use its cheapest offer otherwise.
604	///
605	/// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
606	pub fn receive_variable_amount_via_jit_channel(
607		&self, description: &Bolt11InvoiceDescription, expiry_secs: u32,
608		max_proportional_lsp_fee_limit_ppm_msat: Option<u64>,
609	) -> Result<Bolt11Invoice, Error> {
610		let description = maybe_try_convert_enum(description)?;
611		let invoice = self.receive_via_jit_channel_inner(
612			None,
613			&description,
614			expiry_secs,
615			None,
616			max_proportional_lsp_fee_limit_ppm_msat,
617			None,
618		)?;
619		Ok(maybe_wrap(invoice))
620	}
621
622	/// Returns a payable invoice that can be used to request a variable amount payment (also known
623	/// as "zero-amount" invoice) and receive it via a newly created just-in-time (JIT) channel.
624	///
625	/// When the returned invoice is paid, the configured [LSPS2]-compliant LSP will open a channel
626	/// to us, supplying just-in-time inbound liquidity.
627	///
628	/// If set, `max_proportional_lsp_fee_limit_ppm_msat` will limit how much proportional fee, in
629	/// parts-per-million millisatoshis, we allow the LSP to take for opening the channel to us.
630	/// We'll use its cheapest offer otherwise.
631	///
632	/// We will register the given payment hash and emit a [`PaymentClaimable`] event once
633	/// the inbound payment arrives. The check that [`counterparty_skimmed_fee_msat`] is within the limits
634	/// is performed *before* emitting the event.
635	///
636	/// **Note:** users *MUST* handle this event and claim the payment manually via
637	/// [`claim_for_hash`] as soon as they have obtained access to the preimage of the given
638	/// payment hash. If they're unable to obtain the preimage, they *MUST* immediately fail the payment via
639	/// [`fail_for_hash`].
640	///
641	/// [LSPS2]: https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md
642	/// [`PaymentClaimable`]: crate::Event::PaymentClaimable
643	/// [`claim_for_hash`]: Self::claim_for_hash
644	/// [`fail_for_hash`]: Self::fail_for_hash
645	/// [`counterparty_skimmed_fee_msat`]: crate::payment::PaymentKind::Bolt11Jit::counterparty_skimmed_fee_msat
646	pub fn receive_variable_amount_via_jit_channel_for_hash(
647		&self, description: &Bolt11InvoiceDescription, expiry_secs: u32,
648		max_proportional_lsp_fee_limit_ppm_msat: Option<u64>, payment_hash: PaymentHash,
649	) -> Result<Bolt11Invoice, Error> {
650		let description = maybe_try_convert_enum(description)?;
651		let invoice = self.receive_via_jit_channel_inner(
652			None,
653			&description,
654			expiry_secs,
655			None,
656			max_proportional_lsp_fee_limit_ppm_msat,
657			Some(payment_hash),
658		)?;
659		Ok(maybe_wrap(invoice))
660	}
661
662	fn receive_via_jit_channel_inner(
663		&self, amount_msat: Option<u64>, description: &LdkBolt11InvoiceDescription,
664		expiry_secs: u32, max_total_lsp_fee_limit_msat: Option<u64>,
665		max_proportional_lsp_fee_limit_ppm_msat: Option<u64>, payment_hash: Option<PaymentHash>,
666	) -> Result<LdkBolt11Invoice, Error> {
667		let liquidity_source =
668			self.liquidity_source.as_ref().ok_or(Error::LiquiditySourceUnavailable)?;
669
670		let (node_id, address) =
671			liquidity_source.get_lsps2_lsp_details().ok_or(Error::LiquiditySourceUnavailable)?;
672
673		let peer_info = PeerInfo { node_id, address };
674
675		let con_node_id = peer_info.node_id;
676		let con_addr = peer_info.address.clone();
677		let con_cm = Arc::clone(&self.connection_manager);
678
679		// We need to use our main runtime here as a local runtime might not be around to poll
680		// connection futures going forward.
681		self.runtime.block_on(async move {
682			con_cm.connect_peer_if_necessary(con_node_id, con_addr).await
683		})?;
684
685		log_info!(self.logger, "Connected to LSP {}@{}. ", peer_info.node_id, peer_info.address);
686
687		let liquidity_source = Arc::clone(&liquidity_source);
688		let (invoice, lsp_total_opening_fee, lsp_prop_opening_fee) =
689			self.runtime.block_on(async move {
690				if let Some(amount_msat) = amount_msat {
691					liquidity_source
692						.lsps2_receive_to_jit_channel(
693							amount_msat,
694							description,
695							expiry_secs,
696							max_total_lsp_fee_limit_msat,
697							payment_hash,
698						)
699						.await
700						.map(|(invoice, total_fee)| (invoice, Some(total_fee), None))
701				} else {
702					liquidity_source
703						.lsps2_receive_variable_amount_to_jit_channel(
704							description,
705							expiry_secs,
706							max_proportional_lsp_fee_limit_ppm_msat,
707							payment_hash,
708						)
709						.await
710						.map(|(invoice, prop_fee)| (invoice, None, Some(prop_fee)))
711				}
712			})?;
713
714		// Register payment in payment store.
715		let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
716		let payment_secret = invoice.payment_secret();
717		let lsp_fee_limits = LSPFeeLimits {
718			max_total_opening_fee_msat: lsp_total_opening_fee,
719			max_proportional_opening_fee_ppm_msat: lsp_prop_opening_fee,
720		};
721		let id = PaymentId(payment_hash.0);
722		let preimage =
723			self.channel_manager.get_payment_preimage(payment_hash, payment_secret.clone()).ok();
724		let kind = PaymentKind::Bolt11Jit {
725			hash: payment_hash,
726			preimage,
727			secret: Some(payment_secret.clone()),
728			counterparty_skimmed_fee_msat: None,
729			lsp_fee_limits,
730		};
731		let payment = PaymentDetails::new(
732			id,
733			kind,
734			amount_msat,
735			None,
736			PaymentDirection::Inbound,
737			PaymentStatus::Pending,
738		);
739		self.payment_store.insert(payment)?;
740
741		// Persist LSP peer to make sure we reconnect on restart.
742		self.peer_store.add_peer(peer_info)?;
743
744		Ok(invoice)
745	}
746
747	/// Sends payment probes over all paths of a route that would be used to pay the given invoice.
748	///
749	/// This may be used to send "pre-flight" probes, i.e., to train our scorer before conducting
750	/// the actual payment. Note this is only useful if there likely is sufficient time for the
751	/// probe to settle before sending out the actual payment, e.g., when waiting for user
752	/// confirmation in a wallet UI.
753	///
754	/// Otherwise, there is a chance the probe could take up some liquidity needed to complete the
755	/// actual payment. Users should therefore be cautious and might avoid sending probes if
756	/// liquidity is scarce and/or they don't expect the probe to return before they send the
757	/// payment. To mitigate this issue, channels with available liquidity less than the required
758	/// amount times [`Config::probing_liquidity_limit_multiplier`] won't be used to send
759	/// pre-flight probes.
760	///
761	/// If `route_parameters` are provided they will override the default as well as the
762	/// node-wide parameters configured via [`Config::route_parameters`] on a per-field basis.
763	pub fn send_probes(
764		&self, invoice: &Bolt11Invoice, route_parameters: Option<RouteParametersConfig>,
765	) -> Result<(), Error> {
766		if !*self.is_running.read().unwrap() {
767			return Err(Error::NotRunning);
768		}
769
770		let invoice = maybe_deref(invoice);
771		let payment_params = PaymentParameters::from_bolt11_invoice(invoice);
772
773		let amount_msat = invoice.amount_milli_satoshis().ok_or_else(|| {
774			log_error!(self.logger, "Failed to send probes due to the given invoice being \"zero-amount\". Please use send_probes_using_amount instead.");
775			Error::InvalidInvoice
776		})?;
777
778		let mut route_params =
779			RouteParameters::from_payment_params_and_value(payment_params, amount_msat);
780
781		if let Some(RouteParametersConfig {
782			max_total_routing_fee_msat,
783			max_total_cltv_expiry_delta,
784			max_path_count,
785			max_channel_saturation_power_of_half,
786		}) = route_parameters.as_ref().or(self.config.route_parameters.as_ref())
787		{
788			route_params.max_total_routing_fee_msat = *max_total_routing_fee_msat;
789			route_params.payment_params.max_total_cltv_expiry_delta = *max_total_cltv_expiry_delta;
790			route_params.payment_params.max_path_count = *max_path_count;
791			route_params.payment_params.max_channel_saturation_power_of_half =
792				*max_channel_saturation_power_of_half;
793		}
794
795		let liquidity_limit_multiplier = Some(self.config.probing_liquidity_limit_multiplier);
796
797		self.channel_manager
798			.send_preflight_probes(route_params, liquidity_limit_multiplier)
799			.map_err(|e| {
800				log_error!(self.logger, "Failed to send payment probes: {:?}", e);
801				Error::ProbeSendingFailed
802			})?;
803
804		Ok(())
805	}
806
807	/// Sends payment probes over all paths of a route that would be used to pay the given
808	/// zero-value invoice using the given amount.
809	///
810	/// This can be used to send pre-flight probes for a so-called "zero-amount" invoice, i.e., an
811	/// invoice that leaves the amount paid to be determined by the user.
812	///
813	/// If `route_parameters` are provided they will override the default as well as the
814	/// node-wide parameters configured via [`Config::route_parameters`] on a per-field basis.
815	///
816	/// See [`Self::send_probes`] for more information.
817	pub fn send_probes_using_amount(
818		&self, invoice: &Bolt11Invoice, amount_msat: u64,
819		route_parameters: Option<RouteParametersConfig>,
820	) -> Result<(), Error> {
821		if !*self.is_running.read().unwrap() {
822			return Err(Error::NotRunning);
823		}
824
825		let invoice = maybe_deref(invoice);
826		let payment_params = PaymentParameters::from_bolt11_invoice(invoice);
827
828		if let Some(invoice_amount_msat) = invoice.amount_milli_satoshis() {
829			if amount_msat < invoice_amount_msat {
830				log_error!(
831					self.logger,
832					"Failed to send probes as the given amount needs to be at least the invoice amount: required {}msat, gave {}msat.",
833					invoice_amount_msat,
834					amount_msat
835				);
836				return Err(Error::InvalidAmount);
837			}
838		}
839
840		let mut route_params =
841			RouteParameters::from_payment_params_and_value(payment_params, amount_msat);
842
843		if let Some(RouteParametersConfig {
844			max_total_routing_fee_msat,
845			max_total_cltv_expiry_delta,
846			max_path_count,
847			max_channel_saturation_power_of_half,
848		}) = route_parameters.as_ref().or(self.config.route_parameters.as_ref())
849		{
850			route_params.max_total_routing_fee_msat = *max_total_routing_fee_msat;
851			route_params.payment_params.max_total_cltv_expiry_delta = *max_total_cltv_expiry_delta;
852			route_params.payment_params.max_path_count = *max_path_count;
853			route_params.payment_params.max_channel_saturation_power_of_half =
854				*max_channel_saturation_power_of_half;
855		}
856
857		let liquidity_limit_multiplier = Some(self.config.probing_liquidity_limit_multiplier);
858
859		self.channel_manager
860			.send_preflight_probes(route_params, liquidity_limit_multiplier)
861			.map_err(|e| {
862				log_error!(self.logger, "Failed to send payment probes: {:?}", e);
863				Error::ProbeSendingFailed
864			})?;
865
866		Ok(())
867	}
868}