Skip to content

Commit 8fae222

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 cfc1975 commit 8fae222

File tree

4 files changed

+93
-1
lines changed

4 files changed

+93
-1
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutb
5757
use crate::ln::wire::Encode;
5858
use crate::offers::invoice::{DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, InvoiceBuilder};
5959
use crate::offers::invoice_error::InvoiceError;
60+
use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder};
6061
use crate::offers::merkle::SignError;
62+
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
6163
use crate::offers::parse::SemanticError;
64+
use crate::offers::refund::RefundBuilder;
6265
use crate::onion_message::{OffersMessage, OffersMessageHandler};
6366
use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, ChannelSigner, WriteableEcdsaChannelSigner};
6467
use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate};
@@ -6080,6 +6083,60 @@ where
60806083
}
60816084
}
60826085

6086+
/// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
6087+
/// [`OnionMessenger`] when handling [`InvoiceRequest`] messages for the offer.
6088+
///
6089+
/// [`Offer`]: crate::offers::offer::Offer
6090+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
6091+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
6092+
pub fn create_offer_builder(
6093+
&self, description: String
6094+
) -> OfferBuilder<DerivedMetadata, secp256k1::All> {
6095+
let node_id = self.get_our_node_id();
6096+
let expanded_key = &self.inbound_payment_key;
6097+
let entropy = &*self.entropy_source;
6098+
let secp_ctx = &self.secp_ctx;
6099+
6100+
// TODO: Set blinded paths
6101+
OfferBuilder::deriving_signing_pubkey(description, node_id, expanded_key, entropy, secp_ctx)
6102+
}
6103+
6104+
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
6105+
/// [`OnionMessenger`] when handling [`Invoice`] messages for the refund.
6106+
///
6107+
/// [`Refund`]: crate::offers::refund::Refund
6108+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
6109+
/// [`Invoice`]: crate::offers::invoice::Invoice
6110+
pub fn create_refund_builder(
6111+
&self, description: String, amount_msats: u64
6112+
) -> Result<RefundBuilder<secp256k1::All>, SemanticError> {
6113+
let node_id = self.get_our_node_id();
6114+
let expanded_key = &self.inbound_payment_key;
6115+
let entropy = &*self.entropy_source;
6116+
let secp_ctx = &self.secp_ctx;
6117+
6118+
// TODO: Set blinded paths
6119+
RefundBuilder::deriving_payer_id(
6120+
description, node_id, expanded_key, entropy, secp_ctx, amount_msats
6121+
)
6122+
}
6123+
6124+
/// Creates an [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is
6125+
/// recognized by the [`OnionMessenger`] when handling [`Invoice`] messages for the request.
6126+
///
6127+
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
6128+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
6129+
/// [`Invoice`]: crate::offers::invoice::Invoice
6130+
pub fn create_invoice_request_builder<'a, 'b>(
6131+
&'b self, offer: &'a Offer
6132+
) -> Result<InvoiceRequestBuilder<'a, 'b, DerivedPayerId, secp256k1::All>, SemanticError> {
6133+
let expanded_key = &self.inbound_payment_key;
6134+
let entropy = &*self.entropy_source;
6135+
let secp_ctx = &self.secp_ctx;
6136+
6137+
offer.request_invoice_deriving_payer_id(expanded_key, entropy, secp_ctx)
6138+
}
6139+
60836140
/// Gets a payment secret and payment hash for use in an invoice given to a third party wishing
60846141
/// to pay us.
60856142
///

lightning/src/offers/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ pub mod offer;
2020
pub mod parse;
2121
mod payer;
2222
pub mod refund;
23-
#[allow(unused)]
2423
pub(crate) mod signer;
2524
#[cfg(test)]
2625
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)