Skip to content

Commit bb5384e

Browse files
committed
Add a payments section to ChannelManager docs
1 parent 685b493 commit bb5384e

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

lightning/src/ln/channelmanager.rs

+120
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,117 @@ where
13601360
/// # }
13611361
/// ```
13621362
///
1363+
/// # Payments
1364+
///
1365+
/// [`ChannelManager`] is responsible for sending, forwarding, and receiving payments through its
1366+
/// channels. A payment is typically initiated from a [BOLT 11] invoice or a [BOLT 12] offer, though
1367+
/// spontaneous (i.e., keysend) payments are also possible. Incoming payments don't require
1368+
/// maintaining any additional state as [`ChannelManager`] can reconstruct the [`PaymentPreimage`]
1369+
/// from the [`PaymentSecret`]. Sending payments, however, require tracking in order to retry failed
1370+
/// HTLCs.
1371+
///
1372+
/// After a payment is initiated, it will appear in [`list_recent_payments`] until a short time
1373+
/// after either an [`Event::PaymentSent`] or [`Event::PaymentFailed`] is generated. Failed HTLCs
1374+
/// for a payment will be retried according to the payment's [`Retry`] strategy or until
1375+
/// [`abandon_payment`] is called.
1376+
///
1377+
/// ## BOLT 11 Invoices
1378+
///
1379+
/// The [`lightning-invoice`] crate is useful for creating BOLT 11 invoices. Specifically, use the
1380+
/// functions in its `utils` module for constructing invoices that are compatible with
1381+
/// [`ChannelManager`]. These functions are a convenience for building invoices with the
1382+
/// [`PaymentHash`] and [`PaymentSecret`] returned from [`create_inbound_payment`]. To provide your
1383+
/// own [`PaymentHash`], use [`create_inbound_payment_for_hash`] or the corresponding
1384+
/// [`lightning-invoice`] utilities.
1385+
///
1386+
/// [`ChannelManager`] generates an [`Event::PaymentClaimable`] once the full payment has been
1387+
/// received. Call [`claim_funds`] to release the [`PaymentPreimage`], which in turn will result in
1388+
/// an [`Event::PaymentClaimed`].
1389+
///
1390+
/// ```
1391+
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
1392+
/// # use lightning::ln::channelmanager::AChannelManager;
1393+
/// #
1394+
/// # fn example<T: AChannelManager>(channel_manager: T) {
1395+
/// # let channel_manager = channel_manager.get_cm();
1396+
/// // Or use utils::create_invoice_from_channelmanager
1397+
/// let known_payment_hash = match channel_manager.create_inbound_payment(
1398+
/// Some(10_000_000), 3600, None
1399+
/// ) {
1400+
/// Ok((payment_hash, _payment_secret)) => {
1401+
/// println!("Creating inbound payment {}", payment_hash);
1402+
/// payment_hash
1403+
/// },
1404+
/// Err(()) => panic!("Error creating inbound payment"),
1405+
/// };
1406+
///
1407+
/// // On the event processing thread
1408+
/// channel_manager.process_pending_events(&|event| match event {
1409+
/// Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
1410+
/// PaymentPurpose::InvoicePayment { payment_preimage: Some(payment_preimage), .. } => {
1411+
/// assert_eq!(payment_hash, known_payment_hash);
1412+
/// println!("Claiming payment {}", payment_hash);
1413+
/// channel_manager.claim_funds(payment_preimage);
1414+
/// },
1415+
/// PaymentPurpose::InvoicePayment { payment_preimage: None, .. } => {
1416+
/// println!("Unknown payment hash: {}", payment_hash);
1417+
/// },
1418+
/// PaymentPurpose::SpontaneousPayment(payment_preimage) => {
1419+
/// assert_ne!(payment_hash, known_payment_hash);
1420+
/// println!("Claiming spontaneous payment {}", payment_hash);
1421+
/// channel_manager.claim_funds(payment_preimage);
1422+
/// },
1423+
/// },
1424+
/// Event::PaymentClaimed { payment_hash, amount_msat, .. } => {
1425+
/// assert_eq!(payment_hash, known_payment_hash);
1426+
/// println!("Claimed {} msats", amount_msat);
1427+
/// },
1428+
/// // ...
1429+
/// # _ => {},
1430+
/// });
1431+
/// # }
1432+
/// ```
1433+
///
1434+
/// For paying an invoice, [`lightning-invoice`] provides a `payment` module with convenience
1435+
/// functions for use with [`send_payment`].
1436+
///
1437+
/// ```
1438+
/// # use core::time::Duration;
1439+
/// # use lightning::events::{Event, EventsProvider};
1440+
/// # use lightning::ln::PaymentHash;
1441+
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecipientOnionFields, Retry};
1442+
/// # use lightning::routing::router::RouteParameters;
1443+
/// #
1444+
/// # fn example<T: AChannelManager>(
1445+
/// # channel_manager: T, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
1446+
/// # route_params: RouteParameters
1447+
/// # ) {
1448+
/// # let channel_manager = channel_manager.get_cm();
1449+
/// // let (payment_hash, recipient_onion, route_params) =
1450+
/// // payment::payment_parameters_from_invoice(&invoice);
1451+
/// let payment_id = PaymentId([42; 32]);
1452+
/// let retry = Retry::Timeout(Duration::from_secs(60));
1453+
/// match channel_manager.send_payment(
1454+
/// payment_hash, recipient_onion, payment_id, route_params, retry
1455+
/// ) {
1456+
/// Ok(()) => println!("Sending payment with hash {}", payment_hash),
1457+
/// Err(e) => println!("Failed sending payment with hash {}: {:?}", payment_hash, e),
1458+
/// }
1459+
///
1460+
/// // On the event processing thread
1461+
/// channel_manager.process_pending_events(&|event| match event {
1462+
/// Event::PaymentSent { payment_hash, .. } => println!("Paid {}", payment_hash),
1463+
/// Event::PaymentFailed { payment_hash, .. } => println!("Failed paying {}", payment_hash),
1464+
/// // ...
1465+
/// # _ => {},
1466+
/// });
1467+
/// # }
1468+
/// ```
1469+
///
1470+
/// ## BOLT 12 Offers
1471+
///
1472+
/// TODO
1473+
///
13631474
/// # Persistence
13641475
///
13651476
/// Implements [`Writeable`] to write out all channel state to disk. Implies [`peer_disconnected`] for
@@ -1423,6 +1534,15 @@ where
14231534
/// [`create_channel`]: Self::create_channel
14241535
/// [`close_channel`]: Self::force_close_broadcasting_latest_txn
14251536
/// [`force_close_broadcasting_latest_txn`]: Self::force_close_broadcasting_latest_txn
1537+
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
1538+
/// [BOLT 12]: https://github.com/rustyrussell/lightning-rfc/blob/guilt/offers/12-offer-encoding.md
1539+
/// [`list_recent_payments`]: Self::list_recent_payments
1540+
/// [`abandon_payment`]: Self::abandon_payment
1541+
/// [`lightning-invoice`]: https://docs.rs/lightning_invoice/latest/lightning_invoice
1542+
/// [`create_inbound_payment`]: Self::create_inbound_payment
1543+
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
1544+
/// [`claim_funds`]: Self::claim_funds
1545+
/// [`send_payment`]: Self::send_payment
14261546
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
14271547
/// [`funding_created`]: msgs::FundingCreated
14281548
/// [`funding_transaction_generated`]: Self::funding_transaction_generated

0 commit comments

Comments
 (0)