@@ -1360,6 +1360,117 @@ where
1360
1360
/// # }
1361
1361
/// ```
1362
1362
///
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
+ ///
1363
1474
/// # Persistence
1364
1475
///
1365
1476
/// Implements [`Writeable`] to write out all channel state to disk. Implies [`peer_disconnected`] for
@@ -1423,6 +1534,15 @@ where
1423
1534
/// [`create_channel`]: Self::create_channel
1424
1535
/// [`close_channel`]: Self::force_close_broadcasting_latest_txn
1425
1536
/// [`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
1426
1546
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
1427
1547
/// [`funding_created`]: msgs::FundingCreated
1428
1548
/// [`funding_transaction_generated`]: Self::funding_transaction_generated
0 commit comments