Skip to content

Commit c618318

Browse files
committed
Add a payments section to ChannelManager docs
1 parent 11d07c6 commit c618318

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,124 @@ where
14081408
/// # }
14091409
/// ```
14101410
///
1411+
/// # Payments
1412+
///
1413+
/// [`ChannelManager`] is responsible for sending, forwarding, and receiving payments through its
1414+
/// channels. A payment is typically initiated from a [BOLT 11] invoice or a [BOLT 12] offer, though
1415+
/// spontaneous (i.e., keysend) payments are also possible. Incoming payments don't require
1416+
/// maintaining any additional state as [`ChannelManager`] can reconstruct the [`PaymentPreimage`]
1417+
/// from the [`PaymentSecret`]. Sending payments, however, require tracking in order to retry failed
1418+
/// HTLCs.
1419+
///
1420+
/// After a payment is initiated, it will appear in [`list_recent_payments`] until a short time
1421+
/// after either an [`Event::PaymentSent`] or [`Event::PaymentFailed`] is generated. Failed HTLCs
1422+
/// for a payment will be retried according to the payment's [`Retry`] strategy or until
1423+
/// [`abandon_payment`] is called.
1424+
///
1425+
/// ## BOLT 11 Invoices
1426+
///
1427+
/// The [`lightning-invoice`] crate is useful for creating BOLT 11 invoices. Specifically, use the
1428+
/// functions in its `utils` module for constructing invoices that are compatible with
1429+
/// [`ChannelManager`]. These functions serve as a convenience for building invoices with the
1430+
/// [`PaymentHash`] and [`PaymentSecret`] returned from [`create_inbound_payment`]. To provide your
1431+
/// own [`PaymentHash`], use [`create_inbound_payment_for_hash`] or the corresponding
1432+
/// [`lightning-invoice`] utilities.
1433+
///
1434+
/// [`ChannelManager`] generates an [`Event::PaymentClaimable`] once the full payment has been
1435+
/// received. Call [`claim_funds`] to release the [`PaymentPreimage`], which in turn will result in
1436+
/// an [`Event::PaymentClaimed`].
1437+
///
1438+
/// ```
1439+
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
1440+
/// # use lightning::ln::channelmanager::AChannelManager;
1441+
/// #
1442+
/// # fn example<T: AChannelManager>(channel_manager: T) {
1443+
/// # let channel_manager = channel_manager.get_cm();
1444+
/// // Or use utils::create_invoice_from_channelmanager
1445+
/// let known_payment_hash = match channel_manager.create_inbound_payment(
1446+
/// Some(10_000_000), 3600, None
1447+
/// ) {
1448+
/// Ok((payment_hash, _payment_secret)) => {
1449+
/// println!("Creating inbound payment {}", payment_hash);
1450+
/// payment_hash
1451+
/// },
1452+
/// Err(()) => panic!("Error creating inbound payment"),
1453+
/// };
1454+
///
1455+
/// // On the event processing thread
1456+
/// channel_manager.process_pending_events(&|event| match event {
1457+
/// Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
1458+
/// PaymentPurpose::InvoicePayment { payment_preimage: Some(payment_preimage), .. } => {
1459+
/// assert_eq!(payment_hash, known_payment_hash);
1460+
/// println!("Claiming payment {}", payment_hash);
1461+
/// channel_manager.claim_funds(payment_preimage);
1462+
/// },
1463+
/// PaymentPurpose::InvoicePayment { payment_preimage: None, .. } => {
1464+
/// println!("Unknown payment hash: {}", payment_hash);
1465+
/// },
1466+
/// PaymentPurpose::SpontaneousPayment(payment_preimage) => {
1467+
/// assert_ne!(payment_hash, known_payment_hash);
1468+
/// println!("Claiming spontaneous payment {}", payment_hash);
1469+
/// channel_manager.claim_funds(payment_preimage);
1470+
/// },
1471+
/// },
1472+
/// Event::PaymentClaimed { payment_hash, amount_msat, .. } => {
1473+
/// assert_eq!(payment_hash, known_payment_hash);
1474+
/// println!("Claimed {} msats", amount_msat);
1475+
/// },
1476+
/// // ...
1477+
/// # _ => {},
1478+
/// });
1479+
/// # }
1480+
/// ```
1481+
///
1482+
/// For paying an invoice, [`lightning-invoice`] provides a `payment` module with convenience
1483+
/// functions for use with [`send_payment`].
1484+
///
1485+
/// ```
1486+
/// # use lightning::events::{Event, EventsProvider};
1487+
/// # use lightning::ln::PaymentHash;
1488+
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, RecipientOnionFields, Retry};
1489+
/// # use lightning::routing::router::RouteParameters;
1490+
/// #
1491+
/// # fn example<T: AChannelManager>(
1492+
/// # channel_manager: T, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
1493+
/// # route_params: RouteParameters, retry: Retry
1494+
/// # ) {
1495+
/// # let channel_manager = channel_manager.get_cm();
1496+
/// // let (payment_hash, recipient_onion, route_params) =
1497+
/// // payment::payment_parameters_from_invoice(&invoice);
1498+
/// let payment_id = PaymentId([42; 32]);
1499+
/// match channel_manager.send_payment(
1500+
/// payment_hash, recipient_onion, payment_id, route_params, retry
1501+
/// ) {
1502+
/// Ok(()) => println!("Sending payment with hash {}", payment_hash),
1503+
/// Err(e) => println!("Failed sending payment with hash {}: {:?}", payment_hash, e),
1504+
/// }
1505+
///
1506+
/// let expected_payment_id = payment_id;
1507+
/// let expected_payment_hash = payment_hash;
1508+
/// assert!(
1509+
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
1510+
/// details,
1511+
/// RecentPaymentDetails::Pending {
1512+
/// payment_id: expected_payment_id,
1513+
/// payment_hash: expected_payment_hash,
1514+
/// ..
1515+
/// }
1516+
/// )).is_some()
1517+
/// );
1518+
///
1519+
/// // On the event processing thread
1520+
/// channel_manager.process_pending_events(&|event| match event {
1521+
/// Event::PaymentSent { payment_hash, .. } => println!("Paid {}", payment_hash),
1522+
/// Event::PaymentFailed { payment_hash, .. } => println!("Failed paying {}", payment_hash),
1523+
/// // ...
1524+
/// # _ => {},
1525+
/// });
1526+
/// # }
1527+
/// ```
1528+
///
14111529
/// # Persistence
14121530
///
14131531
/// Implements [`Writeable`] to write out all channel state to disk. Implies [`peer_disconnected`] for
@@ -1474,6 +1592,15 @@ where
14741592
/// [`create_channel`]: Self::create_channel
14751593
/// [`close_channel`]: Self::force_close_broadcasting_latest_txn
14761594
/// [`force_close_broadcasting_latest_txn`]: Self::force_close_broadcasting_latest_txn
1595+
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
1596+
/// [BOLT 12]: https://github.com/rustyrussell/lightning-rfc/blob/guilt/offers/12-offer-encoding.md
1597+
/// [`list_recent_payments`]: Self::list_recent_payments
1598+
/// [`abandon_payment`]: Self::abandon_payment
1599+
/// [`lightning-invoice`]: https://docs.rs/lightning_invoice/latest/lightning_invoice
1600+
/// [`create_inbound_payment`]: Self::create_inbound_payment
1601+
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
1602+
/// [`claim_funds`]: Self::claim_funds
1603+
/// [`send_payment`]: Self::send_payment
14771604
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
14781605
/// [`funding_created`]: msgs::FundingCreated
14791606
/// [`funding_transaction_generated`]: Self::funding_transaction_generated

0 commit comments

Comments
 (0)