Skip to content

Commit 343601a

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 0a2a46a commit 343601a

File tree

5 files changed

+74
-4
lines changed

5 files changed

+74
-4
lines changed

lightning/src/ln/channelmanager.rs

+34
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, Retry};
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;
@@ -5318,6 +5322,36 @@ where
53185322
Ok(payment_secret)
53195323
}
53205324

5325+
/// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
5326+
/// [`OnionMessenger`] when handling [`InvoiceRequest`] messages for the offer.
5327+
///
5328+
/// [`Offer`]: crate::offers::offer::Offer
5329+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
5330+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
5331+
pub fn create_offer_builder(&self, description: String) -> OfferBuilder {
5332+
let nonce = inbound_payment::Nonce::from_entropy_source(&*self.entropy_source);
5333+
let signing_pubkey = DerivedPubkey::new(&self.inbound_payment_key, nonce);
5334+
5335+
// TODO: Set blinded paths
5336+
OfferBuilder::deriving_signing_pubkey(description, signing_pubkey)
5337+
}
5338+
5339+
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
5340+
/// [`OnionMessenger`] when handling [`Invoice`] messages for the refund.
5341+
///
5342+
/// [`Refund`]: crate::offers::refund::Refund
5343+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
5344+
/// [`Invoice`]: crate::offers::invoice::Invoice
5345+
pub fn create_refund_builder(
5346+
&self, description: String, amount_msats: u64
5347+
) -> Result<RefundBuilder, SemanticError> {
5348+
let nonce = inbound_payment::Nonce::from_entropy_source(&*self.entropy_source);
5349+
let payer_id = DerivedPubkey::new(&self.inbound_payment_key, nonce);
5350+
5351+
// TODO: Set blinded paths
5352+
RefundBuilder::deriving_payer_id(description, payer_id, amount_msats)
5353+
}
5354+
53215355
/// Gets a payment secret and payment hash for use in an invoice given to a third party wishing
53225356
/// to pay us.
53235357
///

lightning/src/ln/inbound_payment.rs

+4-1
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

-1
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

+18-1
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

+18-1
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)