Skip to content

Commit 3dd3fb3

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 9db834f commit 3dd3fb3

File tree

4 files changed

+94
-1
lines changed

4 files changed

+94
-1
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VA
5555
use crate::ln::outbound_payment;
5656
use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment};
5757
use crate::ln::wire::Encode;
58+
use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder};
59+
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
60+
use crate::offers::parse::SemanticError;
61+
use crate::offers::refund::RefundBuilder;
5862
use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, ChannelSigner, WriteableEcdsaChannelSigner};
5963
use crate::util::config::{UserConfig, ChannelConfig};
6064
use crate::util::wakers::{Future, Notifier};
@@ -5734,6 +5738,60 @@ where
57345738
Ok(payment_secret)
57355739
}
57365740

5741+
/// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
5742+
/// [`OnionMessenger`] when handling [`InvoiceRequest`] messages for the offer.
5743+
///
5744+
/// [`Offer`]: crate::offers::offer::Offer
5745+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
5746+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
5747+
pub fn create_offer_builder(
5748+
&self, description: String
5749+
) -> OfferBuilder<DerivedMetadata, secp256k1::All> {
5750+
let node_id = self.get_our_node_id();
5751+
let expanded_key = &self.inbound_payment_key;
5752+
let entropy = &*self.entropy_source;
5753+
let secp_ctx = &self.secp_ctx;
5754+
5755+
// TODO: Set blinded paths
5756+
OfferBuilder::deriving_signing_pubkey(description, node_id, expanded_key, entropy, secp_ctx)
5757+
}
5758+
5759+
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
5760+
/// [`OnionMessenger`] when handling [`Invoice`] messages for the refund.
5761+
///
5762+
/// [`Refund`]: crate::offers::refund::Refund
5763+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
5764+
/// [`Invoice`]: crate::offers::invoice::Invoice
5765+
pub fn create_refund_builder(
5766+
&self, description: String, amount_msats: u64
5767+
) -> Result<RefundBuilder<secp256k1::All>, SemanticError> {
5768+
let node_id = self.get_our_node_id();
5769+
let expanded_key = &self.inbound_payment_key;
5770+
let entropy = &*self.entropy_source;
5771+
let secp_ctx = &self.secp_ctx;
5772+
5773+
// TODO: Set blinded paths
5774+
RefundBuilder::deriving_payer_id(
5775+
description, node_id, expanded_key, entropy, secp_ctx, amount_msats
5776+
)
5777+
}
5778+
5779+
/// Creates an [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is
5780+
/// recognized by the [`OnionMessenger`] when handling [`Invoice`] messages for the request.
5781+
///
5782+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
5783+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
5784+
/// [`Invoice`]: crate::offers::invoice::Invoice
5785+
pub fn create_invoice_request_builder<'a, 'b>(
5786+
&'b self, offer: &'a Offer
5787+
) -> Result<InvoiceRequestBuilder<'a, 'b, DerivedPayerId, secp256k1::All>, SemanticError> {
5788+
let expanded_key = &self.inbound_payment_key;
5789+
let entropy = &*self.entropy_source;
5790+
let secp_ctx = &self.secp_ctx;
5791+
5792+
offer.request_invoice_deriving_payer_id(expanded_key, entropy, secp_ctx)
5793+
}
5794+
57375795
/// Gets a payment secret and payment hash for use in an invoice given to a third party wishing
57385796
/// to pay us.
57395797
///

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 & 0 deletions
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;
@@ -131,6 +141,14 @@ impl<'a> OfferBuilder<'a, ExplicitMetadata, secp256k1::SignOnly> {
131141
/// while the offer is valid.
132142
///
133143
/// Use a different pubkey per offer to avoid correlating offers.
144+
///
145+
/// # Note
146+
///
147+
/// If constructing an [`Offer`] for use with a [`ChannelManager`], use
148+
/// [`ChannelManager::create_offer_builder`] instead of [`OfferBuilder::new`].
149+
///
150+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
151+
/// [`ChannelManager::create_offer_builder`]: crate::ln::channelmanager::ChannelManager::create_offer_builder
134152
pub fn new(description: String, signing_pubkey: PublicKey) -> Self {
135153
OfferBuilder {
136154
offer: OfferContents {

lightning/src/offers/refund.rs

Lines changed: 18 additions & 0 deletions
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;
@@ -119,6 +129,14 @@ impl<'a> RefundBuilder<'a, secp256k1::SignOnly> {
119129
///
120130
/// Additionally, sets the required [`Refund::description`], [`Refund::metadata`], and
121131
/// [`Refund::amount_msats`].
132+
///
133+
/// # Note
134+
///
135+
/// If constructing a [`Refund`] for use with a [`ChannelManager`], use
136+
/// [`ChannelManager::create_refund_builder`] instead of [`RefundBuilder::new`].
137+
///
138+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
139+
/// [`ChannelManager::create_refund_builder`]: crate::ln::channelmanager::ChannelManager::create_refund_builder
122140
pub fn new(
123141
description: String, metadata: Vec<u8>, payer_id: PublicKey, amount_msats: u64
124142
) -> Result<Self, SemanticError> {

0 commit comments

Comments
 (0)