Skip to content

Commit 4a11100

Browse files
committed
Stateless offer and refund builder utilities
Add utility functions to ChannelManager for creating OfferBuilder and RefundBuilder such that derived keys are used for the signing pubkey and payer id, respectively. This allows for stateless verification of any InvoiceRequest and Invoice messages. Later, blinded paths can be included in the returned builders.
1 parent 7fa4e23 commit 4a11100

File tree

5 files changed

+74
-4
lines changed

5 files changed

+74
-4
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ use crate::ln::outbound_payment;
5656
use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment};
5757
use crate::ln::wire::Encode;
5858
use crate::chain::keysinterface::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, ChannelSigner};
59+
use crate::offers::offer::OfferBuilder;
60+
use crate::offers::parse::SemanticError;
61+
use crate::offers::refund::RefundBuilder;
62+
use crate::offers::signer::DerivedPubkey;
5963
use crate::util::config::{UserConfig, ChannelConfig};
6064
use crate::util::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
6165
use crate::util::events;
@@ -5377,6 +5381,36 @@ where
53775381
Ok(payment_secret)
53785382
}
53795383

5384+
/// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
5385+
/// [`OnionMessenger`] when handling [`InvoiceRequest`] messages for the offer.
5386+
///
5387+
/// [`Offer`]: crate::offers::offer::Offer
5388+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
5389+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
5390+
pub fn create_offer_builder(&self, description: String) -> OfferBuilder {
5391+
let nonce = inbound_payment::Nonce::from_entropy_source(&*self.entropy_source);
5392+
let signing_pubkey = DerivedPubkey::new(&self.inbound_payment_key, nonce);
5393+
5394+
// TODO: Set blinded paths
5395+
OfferBuilder::deriving_signing_pubkey(description, signing_pubkey)
5396+
}
5397+
5398+
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
5399+
/// [`OnionMessenger`] when handling [`Invoice`] messages for the refund.
5400+
///
5401+
/// [`Refund`]: crate::offers::refund::Refund
5402+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
5403+
/// [`Invoice`]: crate::offers::invoice::Invoice
5404+
pub fn create_refund_builder(
5405+
&self, description: String, amount_msats: u64
5406+
) -> Result<RefundBuilder, SemanticError> {
5407+
let nonce = inbound_payment::Nonce::from_entropy_source(&*self.entropy_source);
5408+
let payer_id = DerivedPubkey::new(&self.inbound_payment_key, nonce);
5409+
5410+
// TODO: Set blinded paths
5411+
RefundBuilder::deriving_payer_id(description, payer_id, amount_msats)
5412+
}
5413+
53805414
/// Gets a payment secret and payment hash for use in an invoice given to a third party wishing
53815415
/// to pay us.
53825416
///

lightning/src/ln/inbound_payment.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ impl Nonce {
109109
pub const LENGTH: usize = 16;
110110

111111
/// Creates a `Nonce` from the given [`EntropySource`].
112-
pub fn from_entropy_source<ES: EntropySource>(entropy_source: &ES) -> Self {
112+
pub fn from_entropy_source<ES: Deref>(entropy_source: ES) -> Self
113+
where
114+
ES::Target: EntropySource,
115+
{
113116
let mut bytes = [0u8; Self::LENGTH];
114117
let rand_bytes = entropy_source.get_secure_random_bytes();
115118
bytes.copy_from_slice(&rand_bytes[..Self::LENGTH]);

lightning/src/offers/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ pub mod offer;
1919
pub mod parse;
2020
mod payer;
2121
pub mod refund;
22-
#[allow(unused)]
2322
pub(crate) mod signer;
2423
#[cfg(test)]
2524
mod test_utils;

lightning/src/offers/offer.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
//! published as a QR code to be scanned by a customer. The customer uses the offer to request an
1414
//! invoice from the merchant to be paid.
1515
//!
16+
//! # Example
17+
//!
1618
//! ```
1719
//! extern crate bitcoin;
1820
//! extern crate core;
@@ -65,6 +67,14 @@
6567
//! # Ok(())
6668
//! # }
6769
//! ```
70+
//!
71+
//! # Note
72+
//!
73+
//! If constructing an [`Offer`] for use with a [`ChannelManager`], use
74+
//! [`ChannelManager::create_offer_builder`] instead of [`OfferBuilder::new`].
75+
//!
76+
//! [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
77+
//! [`ChannelManager::create_offer_builder`]: crate::ln::channelmanager::ChannelManager::create_offer_builder
6878
6979
use bitcoin::blockdata::constants::ChainHash;
7080
use bitcoin::network::constants::Network;
@@ -106,6 +116,14 @@ impl OfferBuilder {
106116
/// while the offer is valid.
107117
///
108118
/// Use a different pubkey per offer to avoid correlating offers.
119+
///
120+
/// # Note
121+
///
122+
/// If constructing an [`Offer`] for use with a [`ChannelManager`], use
123+
/// [`ChannelManager::create_offer_builder`] instead of [`OfferBuilder::new`].
124+
///
125+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
126+
/// [`ChannelManager::create_offer_builder`]: crate::ln::channelmanager::ChannelManager::create_offer_builder
109127
pub fn new(description: String, signing_pubkey: PublicKey) -> Self {
110128
let offer = OfferContents {
111129
chains: None, metadata: None, amount: None, description,
@@ -123,7 +141,6 @@ impl OfferBuilder {
123141
///
124142
/// [`InvoiceRequest::verify`]: crate::offers::invoice_request::InvoiceRequest::verify
125143
/// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey
126-
#[allow(unused)]
127144
pub(crate) fn deriving_signing_pubkey(
128145
description: String, signing_pubkey: DerivedPubkey
129146
) -> Self {

lightning/src/offers/refund.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
//! [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
1919
//! [`Offer`]: crate::offers::offer::Offer
2020
//!
21+
//! # Example
22+
//!
2123
//! ```
2224
//! extern crate bitcoin;
2325
//! extern crate core;
@@ -70,6 +72,14 @@
7072
//! # Ok(())
7173
//! # }
7274
//! ```
75+
//!
76+
//! # Note
77+
//!
78+
//! If constructing a [`Refund`] for use with a [`ChannelManager`], use
79+
//! [`ChannelManager::create_refund_builder`] instead of [`RefundBuilder::new`].
80+
//!
81+
//! [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
82+
//! [`ChannelManager::create_refund_builder`]: crate::ln::channelmanager::ChannelManager::create_refund_builder
7383
7484
use bitcoin::blockdata::constants::ChainHash;
7585
use bitcoin::network::constants::Network;
@@ -114,6 +124,14 @@ impl RefundBuilder {
114124
///
115125
/// Additionally, sets the required [`Refund::description`], [`Refund::metadata`], and
116126
/// [`Refund::amount_msats`].
127+
///
128+
/// # Note
129+
///
130+
/// If constructing a [`Refund`] for use with a [`ChannelManager`], use
131+
/// [`ChannelManager::create_refund_builder`] instead of [`RefundBuilder::new`].
132+
///
133+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
134+
/// [`ChannelManager::create_refund_builder`]: crate::ln::channelmanager::ChannelManager::create_refund_builder
117135
pub fn new(
118136
description: String, metadata: Vec<u8>, payer_id: PublicKey, amount_msats: u64
119137
) -> Result<Self, SemanticError> {
@@ -138,7 +156,6 @@ impl RefundBuilder {
138156
///
139157
/// [`Invoice::verify`]: crate::offers::invoice::Invoice::verify
140158
/// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey
141-
#[allow(unused)]
142159
pub(crate) fn deriving_payer_id(
143160
description: String, payer_id: DerivedPubkey, amount_msats: u64
144161
) -> Result<Self, SemanticError> {

0 commit comments

Comments
 (0)