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