@@ -1408,6 +1408,124 @@ where
1408
1408
/// # }
1409
1409
/// ```
1410
1410
///
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
+ ///
1411
1529
/// # Persistence
1412
1530
///
1413
1531
/// Implements [`Writeable`] to write out all channel state to disk. Implies [`peer_disconnected`] for
@@ -1474,6 +1592,15 @@ where
1474
1592
/// [`create_channel`]: Self::create_channel
1475
1593
/// [`close_channel`]: Self::force_close_broadcasting_latest_txn
1476
1594
/// [`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
1477
1604
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
1478
1605
/// [`funding_created`]: msgs::FundingCreated
1479
1606
/// [`funding_transaction_generated`]: Self::funding_transaction_generated
0 commit comments