Skip to content

Commit a092188

Browse files
committed
Introduce VerifiedInvoiceRequest<S: SigningPubkeyStrategy>
This commit reintroduces `VerifiedInvoiceRequest`, now parameterized by `SigningPubkeyStrategy`. The key motivation is to restrict which functions can be called on a `VerifiedInvoiceRequest` based on its strategy type. This enables compile-time guarantees — ensuring that an incorrect `InvoiceBuilder` cannot be constructed for a given request, and misuses are caught early.
1 parent 24b7c4c commit a092188

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

lightning/src/offers/invoice_request.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ use crate::io;
7171
use crate::ln::channelmanager::PaymentId;
7272
use crate::ln::inbound_payment::{ExpandedKey, IV_LEN};
7373
use crate::ln::msgs::DecodeError;
74+
use crate::offers::invoice::{DerivedSigningPubkey, ExplicitSigningPubkey, SigningPubkeyStrategy};
7475
use crate::offers::merkle::{
7576
self, SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream,
7677
};
@@ -96,7 +97,7 @@ use bitcoin::secp256k1::schnorr::Signature;
9697
use bitcoin::secp256k1::{self, Keypair, PublicKey, Secp256k1};
9798

9899
#[cfg(not(c_bindings))]
99-
use crate::offers::invoice::{DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder};
100+
use crate::offers::invoice::InvoiceBuilder;
100101
#[cfg(c_bindings)]
101102
use crate::offers::invoice::{
102103
InvoiceWithDerivedSigningPubkeyBuilder, InvoiceWithExplicitSigningPubkeyBuilder,
@@ -615,6 +616,50 @@ pub struct VerifiedInvoiceRequestLegacy {
615616
pub keys: Option<Keypair>,
616617
}
617618

619+
/// An [`InvoiceRequest`] that has been verified by [`InvoiceRequest::verify_using_metadata`] or
620+
/// [`InvoiceRequest::verify_using_recipient_data`] and exposes different ways to respond depending
621+
/// on whether the signing keys were derived.
622+
#[derive(Clone, Debug)]
623+
pub struct VerifiedInvoiceRequest<S: SigningPubkeyStrategy> {
624+
/// The identifier of the [`Offer`] for which the [`InvoiceRequest`] was made.
625+
pub offer_id: OfferId,
626+
627+
/// The verified request.
628+
pub(crate) inner: InvoiceRequest,
629+
630+
/// Keys for signing a [`Bolt12Invoice`] for the request.
631+
///
632+
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
633+
pub keys: S,
634+
}
635+
636+
/// An enum representing a verified invoice request, which can either have derived signing keys or
637+
/// require explicit signing keys.
638+
pub enum VerifiedInvoiceRequestEnum {
639+
/// An invoice request with signing keys that can be derived from the metadata.
640+
WithKeys(VerifiedInvoiceRequest<DerivedSigningPubkey>),
641+
/// An invoice request without derived signing keys, which must be explicitly provided.
642+
WithoutKeys(VerifiedInvoiceRequest<ExplicitSigningPubkey>),
643+
}
644+
645+
impl VerifiedInvoiceRequestEnum {
646+
/// Returns a reference to the underlying `InvoiceRequest`.
647+
pub fn inner(&self) -> &InvoiceRequest {
648+
match self {
649+
VerifiedInvoiceRequestEnum::WithKeys(req) => &req.inner,
650+
VerifiedInvoiceRequestEnum::WithoutKeys(req) => &req.inner,
651+
}
652+
}
653+
654+
/// Returns the `OfferId` of the offer this invoice request is for.
655+
pub fn offer_id(&self) -> OfferId {
656+
match self {
657+
VerifiedInvoiceRequestEnum::WithKeys(req) => req.offer_id,
658+
VerifiedInvoiceRequestEnum::WithoutKeys(req) => req.offer_id,
659+
}
660+
}
661+
}
662+
618663
/// The contents of an [`InvoiceRequest`], which may be shared with an [`Bolt12Invoice`].
619664
///
620665
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
@@ -1022,6 +1067,24 @@ impl VerifiedInvoiceRequestLegacy {
10221067
);
10231068
}
10241069

1070+
impl VerifiedInvoiceRequest<DerivedSigningPubkey> {
1071+
offer_accessors!(self, self.inner.contents.inner.offer);
1072+
invoice_request_accessors!(self, self.inner.contents);
1073+
fields_accessor!(self, self.inner.contents);
1074+
}
1075+
1076+
impl VerifiedInvoiceRequest<ExplicitSigningPubkey> {
1077+
offer_accessors!(self, self.inner.contents.inner.offer);
1078+
invoice_request_accessors!(self, self.inner.contents);
1079+
fields_accessor!(self, self.inner.contents);
1080+
}
1081+
1082+
impl VerifiedInvoiceRequestEnum {
1083+
offer_accessors!(self, self.inner().contents.inner.offer);
1084+
invoice_request_accessors!(self, self.inner().contents);
1085+
fields_accessor!(self, self.inner().contents);
1086+
}
1087+
10251088
/// `String::truncate(new_len)` panics if you split inside a UTF-8 code point,
10261089
/// which would leave the `String` containing invalid UTF-8. This function will
10271090
/// instead truncate the string to the next smaller code point boundary so the

0 commit comments

Comments
 (0)