Address custom HTLC TLV fixups
[rust-lightning] / lightning / src / offers / invoice.rs
index 05b2b5d010ec7a8cf36306f95ce481d6c148dd58..c3d4500aaebbb0b8f0c2d6abdb4f4179bfad3cf0 100644 (file)
@@ -9,9 +9,9 @@
 
 //! Data structures and encoding for `invoice` messages.
 //!
-//! An [`Invoice`] can be built from a parsed [`InvoiceRequest`] for the "offer to be paid" flow or
-//! from a [`Refund`] as an "offer for money" flow. The expected recipient of the payment then sends
-//! the invoice to the intended payer, who will then pay it.
+//! A [`Bolt12Invoice`] can be built from a parsed [`InvoiceRequest`] for the "offer to be paid"
+//! flow or from a [`Refund`] as an "offer for money" flow. The expected recipient of the payment
+//! then sends the invoice to the intended payer, who will then pay it.
 //!
 //! The payment recipient must include a [`PaymentHash`], so as to reveal the preimage upon payment
 //! receipt, and one or more [`BlindedPath`]s for the payer to use when sending the payment.
 //! # use lightning::offers::invoice::BlindedPayInfo;
 //! # use lightning::blinded_path::BlindedPath;
 //! #
-//! # fn create_payment_paths() -> Vec<(BlindedPath, BlindedPayInfo)> { unimplemented!() }
+//! # fn create_payment_paths() -> Vec<(BlindedPayInfo, BlindedPath)> { unimplemented!() }
 //! # fn create_payment_hash() -> PaymentHash { unimplemented!() }
 //! #
-//! # fn parse_invoice_request(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::ParseError> {
+//! # fn parse_invoice_request(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::Bolt12ParseError> {
 //! let payment_paths = create_payment_paths();
 //! let payment_hash = create_payment_hash();
 //! let secp_ctx = Secp256k1::new();
@@ -62,7 +62,7 @@
 //! # Ok(())
 //! # }
 //!
-//! # fn parse_refund(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::ParseError> {
+//! # fn parse_refund(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::Bolt12ParseError> {
 //! # let payment_paths = create_payment_paths();
 //! # let payment_hash = create_payment_hash();
 //! # let secp_ctx = Secp256k1::new();
@@ -112,7 +112,7 @@ use crate::ln::msgs::DecodeError;
 use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
 use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, WithoutSignatures, self};
 use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef};
-use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
+use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage};
 use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef};
 use crate::offers::refund::{IV_BYTES as REFUND_IV_BYTES, Refund, RefundContents};
 use crate::offers::signer;
@@ -128,12 +128,14 @@ const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(7200);
 
 pub(super) const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signature");
 
-/// Builds an [`Invoice`] from either:
+/// Builds a [`Bolt12Invoice`] from either:
 /// - an [`InvoiceRequest`] for the "offer to be paid" flow or
 /// - a [`Refund`] for the "offer for money" flow.
 ///
 /// See [module-level documentation] for usage.
 ///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+///
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
 /// [`Refund`]: crate::offers::refund::Refund
 /// [module-level documentation]: self
@@ -144,13 +146,19 @@ pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> {
        signing_pubkey_strategy: core::marker::PhantomData<S>,
 }
 
-/// Indicates how [`Invoice::signing_pubkey`] was set.
+/// Indicates how [`Bolt12Invoice::signing_pubkey`] was set.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub trait SigningPubkeyStrategy {}
 
-/// [`Invoice::signing_pubkey`] was explicitly set.
+/// [`Bolt12Invoice::signing_pubkey`] was explicitly set.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct ExplicitSigningPubkey {}
 
-/// [`Invoice::signing_pubkey`] was derived.
+/// [`Bolt12Invoice::signing_pubkey`] was derived.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct DerivedSigningPubkey {}
 
 impl SigningPubkeyStrategy for ExplicitSigningPubkey {}
@@ -158,9 +166,9 @@ impl SigningPubkeyStrategy for DerivedSigningPubkey {}
 
 impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
        pub(super) fn for_offer(
-               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
                created_at: Duration, payment_hash: PaymentHash
-       ) -> Result<Self, SemanticError> {
+       ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = Self::check_amount_msats(invoice_request)?;
                let signing_pubkey = invoice_request.contents.inner.offer.signing_pubkey();
                let contents = InvoiceContents::ForOffer {
@@ -174,9 +182,9 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
        }
 
        pub(super) fn for_refund(
-               refund: &'a Refund, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, created_at: Duration,
+               refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
                payment_hash: PaymentHash, signing_pubkey: PublicKey
-       ) -> Result<Self, SemanticError> {
+       ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = refund.amount_msats();
                let contents = InvoiceContents::ForRefund {
                        refund: refund.contents.clone(),
@@ -191,9 +199,9 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
 
 impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
        pub(super) fn for_offer_using_keys(
-               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+               invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
                created_at: Duration, payment_hash: PaymentHash, keys: KeyPair
-       ) -> Result<Self, SemanticError> {
+       ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = Self::check_amount_msats(invoice_request)?;
                let signing_pubkey = invoice_request.contents.inner.offer.signing_pubkey();
                let contents = InvoiceContents::ForOffer {
@@ -207,9 +215,9 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
        }
 
        pub(super) fn for_refund_using_keys(
-               refund: &'a Refund, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, created_at: Duration,
+               refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
                payment_hash: PaymentHash, keys: KeyPair,
-       ) -> Result<Self, SemanticError> {
+       ) -> Result<Self, Bolt12SemanticError> {
                let amount_msats = refund.amount_msats();
                let signing_pubkey = keys.public_key();
                let contents = InvoiceContents::ForRefund {
@@ -224,22 +232,22 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
 }
 
 impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
-       fn check_amount_msats(invoice_request: &InvoiceRequest) -> Result<u64, SemanticError> {
+       fn check_amount_msats(invoice_request: &InvoiceRequest) -> Result<u64, Bolt12SemanticError> {
                match invoice_request.amount_msats() {
                        Some(amount_msats) => Ok(amount_msats),
                        None => match invoice_request.contents.inner.offer.amount() {
                                Some(Amount::Bitcoin { amount_msats }) => {
                                        amount_msats.checked_mul(invoice_request.quantity().unwrap_or(1))
-                                               .ok_or(SemanticError::InvalidAmount)
+                                               .ok_or(Bolt12SemanticError::InvalidAmount)
                                },
-                               Some(Amount::Currency { .. }) => Err(SemanticError::UnsupportedCurrency),
-                               None => Err(SemanticError::MissingAmount),
+                               Some(Amount::Currency { .. }) => Err(Bolt12SemanticError::UnsupportedCurrency),
+                               None => Err(Bolt12SemanticError::MissingAmount),
                        },
                }
        }
 
        fn fields(
-               payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, created_at: Duration,
+               payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
                payment_hash: PaymentHash, amount_msats: u64, signing_pubkey: PublicKey
        ) -> InvoiceFields {
                InvoiceFields {
@@ -250,9 +258,9 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
 
        fn new(
                invreq_bytes: &'a Vec<u8>, contents: InvoiceContents, keys: Option<KeyPair>
-       ) -> Result<Self, SemanticError> {
+       ) -> Result<Self, Bolt12SemanticError> {
                if contents.fields().payment_paths.is_empty() {
-                       return Err(SemanticError::MissingPaths);
+                       return Err(Bolt12SemanticError::MissingPaths);
                }
 
                Ok(Self {
@@ -263,8 +271,9 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
                })
        }
 
-       /// Sets the [`Invoice::relative_expiry`] as seconds since [`Invoice::created_at`]. Any expiry
-       /// that has already passed is valid and can be checked for using [`Invoice::is_expired`].
+       /// Sets the [`Bolt12Invoice::relative_expiry`] as seconds since [`Bolt12Invoice::created_at`].
+       /// Any expiry that has already passed is valid and can be checked for using
+       /// [`Bolt12Invoice::is_expired`].
        ///
        /// Successive calls to this method will override the previous setting.
        pub fn relative_expiry(mut self, relative_expiry_secs: u32) -> Self {
@@ -273,7 +282,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
                self
        }
 
-       /// Adds a P2WSH address to [`Invoice::fallbacks`].
+       /// Adds a P2WSH address to [`Bolt12Invoice::fallbacks`].
        ///
        /// Successive calls to this method will add another address. Caller is responsible for not
        /// adding duplicate addresses and only calling if capable of receiving to P2WSH addresses.
@@ -286,7 +295,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
                self
        }
 
-       /// Adds a P2WPKH address to [`Invoice::fallbacks`].
+       /// Adds a P2WPKH address to [`Bolt12Invoice::fallbacks`].
        ///
        /// Successive calls to this method will add another address. Caller is responsible for not
        /// adding duplicate addresses and only calling if capable of receiving to P2WPKH addresses.
@@ -299,7 +308,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
                self
        }
 
-       /// Adds a P2TR address to [`Invoice::fallbacks`].
+       /// Adds a P2TR address to [`Bolt12Invoice::fallbacks`].
        ///
        /// Successive calls to this method will add another address. Caller is responsible for not
        /// adding duplicate addresses and only calling if capable of receiving to P2TR addresses.
@@ -312,7 +321,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
                self
        }
 
-       /// Sets [`Invoice::features`] to indicate MPP may be used. Otherwise, MPP is disallowed.
+       /// Sets [`Bolt12Invoice::features`] to indicate MPP may be used. Otherwise, MPP is disallowed.
        pub fn allow_mpp(mut self) -> Self {
                self.invoice.fields_mut().features.set_basic_mpp_optional();
                self
@@ -320,33 +329,33 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
 }
 
 impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
-       /// Builds an unsigned [`Invoice`] after checking for valid semantics. It can be signed by
-       /// [`UnsignedInvoice::sign`].
-       pub fn build(self) -> Result<UnsignedInvoice<'a>, SemanticError> {
+       /// Builds an unsigned [`Bolt12Invoice`] after checking for valid semantics. It can be signed by
+       /// [`UnsignedBolt12Invoice::sign`].
+       pub fn build(self) -> Result<UnsignedBolt12Invoice<'a>, Bolt12SemanticError> {
                #[cfg(feature = "std")] {
                        if self.invoice.is_offer_or_refund_expired() {
-                               return Err(SemanticError::AlreadyExpired);
+                               return Err(Bolt12SemanticError::AlreadyExpired);
                        }
                }
 
                let InvoiceBuilder { invreq_bytes, invoice, .. } = self;
-               Ok(UnsignedInvoice { invreq_bytes, invoice })
+               Ok(UnsignedBolt12Invoice { invreq_bytes, invoice })
        }
 }
 
 impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
-       /// Builds a signed [`Invoice`] after checking for valid semantics.
+       /// Builds a signed [`Bolt12Invoice`] after checking for valid semantics.
        pub fn build_and_sign<T: secp256k1::Signing>(
                self, secp_ctx: &Secp256k1<T>
-       ) -> Result<Invoice, SemanticError> {
+       ) -> Result<Bolt12Invoice, Bolt12SemanticError> {
                #[cfg(feature = "std")] {
                        if self.invoice.is_offer_or_refund_expired() {
-                               return Err(SemanticError::AlreadyExpired);
+                               return Err(Bolt12SemanticError::AlreadyExpired);
                        }
                }
 
                let InvoiceBuilder { invreq_bytes, invoice, keys, .. } = self;
-               let unsigned_invoice = UnsignedInvoice { invreq_bytes, invoice };
+               let unsigned_invoice = UnsignedBolt12Invoice { invreq_bytes, invoice };
 
                let keys = keys.unwrap();
                let invoice = unsigned_invoice
@@ -356,20 +365,22 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
        }
 }
 
-/// A semantically valid [`Invoice`] that hasn't been signed.
-pub struct UnsignedInvoice<'a> {
+/// A semantically valid [`Bolt12Invoice`] that hasn't been signed.
+pub struct UnsignedBolt12Invoice<'a> {
        invreq_bytes: &'a Vec<u8>,
        invoice: InvoiceContents,
 }
 
-impl<'a> UnsignedInvoice<'a> {
+impl<'a> UnsignedBolt12Invoice<'a> {
        /// The public key corresponding to the key needed to sign the invoice.
        pub fn signing_pubkey(&self) -> PublicKey {
                self.invoice.fields().signing_pubkey
        }
 
        /// Signs the invoice using the given function.
-       pub fn sign<F, E>(self, sign: F) -> Result<Invoice, SignError<E>>
+       ///
+       /// This is not exported to bindings users as functions aren't currently mapped.
+       pub fn sign<F, E>(self, sign: F) -> Result<Bolt12Invoice, SignError<E>>
        where
                F: FnOnce(&Message) -> Result<Signature, E>
        {
@@ -392,7 +403,7 @@ impl<'a> UnsignedInvoice<'a> {
                };
                signature_tlv_stream.write(&mut bytes).unwrap();
 
-               Ok(Invoice {
+               Ok(Bolt12Invoice {
                        bytes,
                        contents: self.invoice,
                        signature,
@@ -400,7 +411,7 @@ impl<'a> UnsignedInvoice<'a> {
        }
 }
 
-/// An `Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`].
+/// A `Bolt12Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`].
 ///
 /// An invoice may be sent in response to an [`InvoiceRequest`] in the case of an offer or sent
 /// directly after scanning a refund. It includes all the information needed to pay a recipient.
@@ -410,27 +421,27 @@ impl<'a> UnsignedInvoice<'a> {
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
 #[derive(Clone, Debug)]
 #[cfg_attr(test, derive(PartialEq))]
-pub struct Invoice {
+pub struct Bolt12Invoice {
        bytes: Vec<u8>,
        contents: InvoiceContents,
        signature: Signature,
 }
 
-/// The contents of an [`Invoice`] for responding to either an [`Offer`] or a [`Refund`].
+/// The contents of an [`Bolt12Invoice`] for responding to either an [`Offer`] or a [`Refund`].
 ///
 /// [`Offer`]: crate::offers::offer::Offer
 /// [`Refund`]: crate::offers::refund::Refund
 #[derive(Clone, Debug)]
 #[cfg_attr(test, derive(PartialEq))]
 enum InvoiceContents {
-       /// Contents for an [`Invoice`] corresponding to an [`Offer`].
+       /// Contents for an [`Bolt12Invoice`] corresponding to an [`Offer`].
        ///
        /// [`Offer`]: crate::offers::offer::Offer
        ForOffer {
                invoice_request: InvoiceRequestContents,
                fields: InvoiceFields,
        },
-       /// Contents for an [`Invoice`] corresponding to a [`Refund`].
+       /// Contents for an [`Bolt12Invoice`] corresponding to a [`Refund`].
        ///
        /// [`Refund`]: crate::offers::refund::Refund
        ForRefund {
@@ -442,7 +453,7 @@ enum InvoiceContents {
 /// Invoice-specific fields for an `invoice` message.
 #[derive(Clone, Debug, PartialEq)]
 struct InvoiceFields {
-       payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+       payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
        created_at: Duration,
        relative_expiry: Option<Duration>,
        payment_hash: PaymentHash,
@@ -452,7 +463,7 @@ struct InvoiceFields {
        signing_pubkey: PublicKey,
 }
 
-impl Invoice {
+impl Bolt12Invoice {
        /// A complete description of the purpose of the originating offer or refund. Intended to be
        /// displayed to the user but with the caveat that it has not been verified in any way.
        pub fn description(&self) -> PrintableString {
@@ -463,8 +474,11 @@ impl Invoice {
        /// needed for routing payments across them.
        ///
        /// Blinded paths provide recipient privacy by obfuscating its node id. Note, however, that this
-       /// privacy is lost if a public node id is used for [`Invoice::signing_pubkey`].
-       pub fn payment_paths(&self) -> &[(BlindedPath, BlindedPayInfo)] {
+       /// privacy is lost if a public node id is used for [`Bolt12Invoice::signing_pubkey`].
+       ///
+       /// This is not exported to bindings users as slices with non-reference types cannot be ABI
+       /// matched in another language.
+       pub fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
                &self.contents.fields().payment_paths[..]
        }
 
@@ -473,8 +487,8 @@ impl Invoice {
                self.contents.fields().created_at
        }
 
-       /// Duration since [`Invoice::created_at`] when the invoice has expired and therefore should no
-       /// longer be paid.
+       /// Duration since [`Bolt12Invoice::created_at`] when the invoice has expired and therefore
+       /// should no longer be paid.
        pub fn relative_expiry(&self) -> Duration {
                self.contents.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
        }
@@ -567,7 +581,7 @@ impl Invoice {
                self.contents.fields().signing_pubkey
        }
 
-       /// Signature of the invoice verified using [`Invoice::signing_pubkey`].
+       /// Signature of the invoice verified using [`Bolt12Invoice::signing_pubkey`].
        pub fn signature(&self) -> Signature {
                self.signature
        }
@@ -691,8 +705,8 @@ impl InvoiceFields {
                };
 
                InvoiceTlvStreamRef {
-                       paths: Some(Iterable(self.payment_paths.iter().map(|(path, _)| path))),
-                       blindedpay: Some(Iterable(self.payment_paths.iter().map(|(_, payinfo)| payinfo))),
+                       paths: Some(Iterable(self.payment_paths.iter().map(|(_, path)| path))),
+                       blindedpay: Some(Iterable(self.payment_paths.iter().map(|(payinfo, _)| payinfo))),
                        created_at: Some(self.created_at.as_secs()),
                        relative_expiry: self.relative_expiry.map(|duration| duration.as_secs() as u32),
                        payment_hash: Some(&self.payment_hash),
@@ -704,7 +718,7 @@ impl InvoiceFields {
        }
 }
 
-impl Writeable for Invoice {
+impl Writeable for Bolt12Invoice {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                WithoutLength(&self.bytes).write(writer)
        }
@@ -716,12 +730,12 @@ impl Writeable for InvoiceContents {
        }
 }
 
-impl TryFrom<Vec<u8>> for Invoice {
-       type Error = ParseError;
+impl TryFrom<Vec<u8>> for Bolt12Invoice {
+       type Error = Bolt12ParseError;
 
        fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
                let parsed_invoice = ParsedMessage::<FullInvoiceTlvStream>::try_from(bytes)?;
-               Invoice::try_from(parsed_invoice)
+               Bolt12Invoice::try_from(parsed_invoice)
        }
 }
 
@@ -738,13 +752,13 @@ tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, {
 });
 
 type BlindedPathIter<'a> = core::iter::Map<
-       core::slice::Iter<'a, (BlindedPath, BlindedPayInfo)>,
-       for<'r> fn(&'r (BlindedPath, BlindedPayInfo)) -> &'r BlindedPath,
+       core::slice::Iter<'a, (BlindedPayInfo, BlindedPath)>,
+       for<'r> fn(&'r (BlindedPayInfo, BlindedPath)) -> &'r BlindedPath,
 >;
 
 type BlindedPayInfoIter<'a> = core::iter::Map<
-       core::slice::Iter<'a, (BlindedPath, BlindedPayInfo)>,
-       for<'r> fn(&'r (BlindedPath, BlindedPayInfo)) -> &'r BlindedPayInfo,
+       core::slice::Iter<'a, (BlindedPayInfo, BlindedPath)>,
+       for<'r> fn(&'r (BlindedPayInfo, BlindedPath)) -> &'r BlindedPayInfo,
 >;
 
 /// Information needed to route a payment across a [`BlindedPath`].
@@ -828,8 +842,8 @@ type PartialInvoiceTlvStreamRef<'a> = (
        InvoiceTlvStreamRef<'a>,
 );
 
-impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Invoice {
-       type Error = ParseError;
+impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Bolt12Invoice {
+       type Error = Bolt12ParseError;
 
        fn try_from(invoice: ParsedMessage<FullInvoiceTlvStream>) -> Result<Self, Self::Error> {
                let ParsedMessage { bytes, tlv_stream } = invoice;
@@ -842,18 +856,18 @@ impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Invoice {
                )?;
 
                let signature = match signature {
-                       None => return Err(ParseError::InvalidSemantics(SemanticError::MissingSignature)),
+                       None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
                        Some(signature) => signature,
                };
                let pubkey = contents.fields().signing_pubkey;
                merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, pubkey)?;
 
-               Ok(Invoice { bytes, contents, signature })
+               Ok(Bolt12Invoice { bytes, contents, signature })
        }
 }
 
 impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
-       type Error = SemanticError;
+       type Error = Bolt12SemanticError;
 
        fn try_from(tlv_stream: PartialInvoiceTlvStream) -> Result<Self, Self::Error> {
                let (
@@ -866,20 +880,20 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
                        },
                ) = tlv_stream;
 
-               let payment_paths = match (paths, blindedpay) {
-                       (None, _) => return Err(SemanticError::MissingPaths),
-                       (_, None) => return Err(SemanticError::InvalidPayInfo),
-                       (Some(paths), _) if paths.is_empty() => return Err(SemanticError::MissingPaths),
-                       (Some(paths), Some(blindedpay)) if paths.len() != blindedpay.len() => {
-                               return Err(SemanticError::InvalidPayInfo);
+               let payment_paths = match (blindedpay, paths) {
+                       (_, None) => return Err(Bolt12SemanticError::MissingPaths),
+                       (None, _) => return Err(Bolt12SemanticError::InvalidPayInfo),
+                       (_, Some(paths)) if paths.is_empty() => return Err(Bolt12SemanticError::MissingPaths),
+                       (Some(blindedpay), Some(paths)) if paths.len() != blindedpay.len() => {
+                               return Err(Bolt12SemanticError::InvalidPayInfo);
                        },
-                       (Some(paths), Some(blindedpay)) => {
-                               paths.into_iter().zip(blindedpay.into_iter()).collect::<Vec<_>>()
+                       (Some(blindedpay), Some(paths)) => {
+                               blindedpay.into_iter().zip(paths.into_iter()).collect::<Vec<_>>()
                        },
                };
 
                let created_at = match created_at {
-                       None => return Err(SemanticError::MissingCreationTime),
+                       None => return Err(Bolt12SemanticError::MissingCreationTime),
                        Some(timestamp) => Duration::from_secs(timestamp),
                };
 
@@ -888,19 +902,19 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
                        .map(Duration::from_secs);
 
                let payment_hash = match payment_hash {
-                       None => return Err(SemanticError::MissingPaymentHash),
+                       None => return Err(Bolt12SemanticError::MissingPaymentHash),
                        Some(payment_hash) => payment_hash,
                };
 
                let amount_msats = match amount {
-                       None => return Err(SemanticError::MissingAmount),
+                       None => return Err(Bolt12SemanticError::MissingAmount),
                        Some(amount) => amount,
                };
 
                let features = features.unwrap_or_else(Bolt12InvoiceFeatures::empty);
 
                let signing_pubkey = match node_id {
-                       None => return Err(SemanticError::MissingSigningPubkey),
+                       None => return Err(Bolt12SemanticError::MissingSigningPubkey),
                        Some(node_id) => node_id,
                };
 
@@ -912,7 +926,7 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
                match offer_tlv_stream.node_id {
                        Some(expected_signing_pubkey) => {
                                if fields.signing_pubkey != expected_signing_pubkey {
-                                       return Err(SemanticError::InvalidSigningPubkey);
+                                       return Err(Bolt12SemanticError::InvalidSigningPubkey);
                                }
 
                                let invoice_request = InvoiceRequestContents::try_from(
@@ -932,7 +946,7 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
 
 #[cfg(test)]
 mod tests {
-       use super::{DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, Invoice, InvoiceTlvStreamRef, SIGNATURE_TAG};
+       use super::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, InvoiceTlvStreamRef, SIGNATURE_TAG};
 
        use bitcoin::blockdata::script::Script;
        use bitcoin::hashes::Hash;
@@ -943,14 +957,14 @@ mod tests {
        use core::convert::TryFrom;
        use core::time::Duration;
        use crate::blinded_path::{BlindedHop, BlindedPath};
-       use crate::chain::keysinterface::KeyMaterial;
+       use crate::sign::KeyMaterial;
        use crate::ln::features::Bolt12InvoiceFeatures;
        use crate::ln::inbound_payment::ExpandedKey;
        use crate::ln::msgs::DecodeError;
        use crate::offers::invoice_request::InvoiceRequestTlvStreamRef;
        use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self};
        use crate::offers::offer::{OfferBuilder, OfferTlvStreamRef, Quantity};
-       use crate::offers::parse::{ParseError, SemanticError};
+       use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
        use crate::offers::payer::PayerTlvStreamRef;
        use crate::offers::refund::RefundBuilder;
        use crate::offers::test_utils::*;
@@ -1040,8 +1054,8 @@ mod tests {
                                        payer_note: None,
                                },
                                InvoiceTlvStreamRef {
-                                       paths: Some(Iterable(payment_paths.iter().map(|(path, _)| path))),
-                                       blindedpay: Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo))),
+                                       paths: Some(Iterable(payment_paths.iter().map(|(_, path)| path))),
+                                       blindedpay: Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo))),
                                        created_at: Some(now.as_secs()),
                                        relative_expiry: None,
                                        payment_hash: Some(&payment_hash),
@@ -1054,7 +1068,7 @@ mod tests {
                        ),
                );
 
-               if let Err(e) = Invoice::try_from(buffer) {
+               if let Err(e) = Bolt12Invoice::try_from(buffer) {
                        panic!("error parsing invoice: {:?}", e);
                }
        }
@@ -1118,8 +1132,8 @@ mod tests {
                                        payer_note: None,
                                },
                                InvoiceTlvStreamRef {
-                                       paths: Some(Iterable(payment_paths.iter().map(|(path, _)| path))),
-                                       blindedpay: Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo))),
+                                       paths: Some(Iterable(payment_paths.iter().map(|(_, path)| path))),
+                                       blindedpay: Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo))),
                                        created_at: Some(now.as_secs()),
                                        relative_expiry: None,
                                        payment_hash: Some(&payment_hash),
@@ -1132,7 +1146,7 @@ mod tests {
                        ),
                );
 
-               if let Err(e) = Invoice::try_from(buffer) {
+               if let Err(e) = Bolt12Invoice::try_from(buffer) {
                        panic!("error parsing invoice: {:?}", e);
                }
        }
@@ -1169,7 +1183,7 @@ mod tests {
                        .build()
                {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, SemanticError::AlreadyExpired),
+                       Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
                }
        }
 
@@ -1197,7 +1211,7 @@ mod tests {
                        .build()
                {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, SemanticError::AlreadyExpired),
+                       Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
                }
        }
 
@@ -1242,7 +1256,7 @@ mod tests {
                        payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx
                ) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, SemanticError::InvalidMetadata),
+                       Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
                }
 
                let desc = "foo".to_string();
@@ -1258,7 +1272,7 @@ mod tests {
                        payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx
                ) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, SemanticError::InvalidMetadata),
+                       Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
                }
        }
 
@@ -1365,7 +1379,7 @@ mod tests {
                        .respond_with_no_std(payment_paths(), payment_hash(), now())
                {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, SemanticError::InvalidAmount),
+                       Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
                }
        }
 
@@ -1482,43 +1496,43 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               if let Err(e) = Invoice::try_from(buffer) {
+               if let Err(e) = Bolt12Invoice::try_from(buffer) {
                        panic!("error parsing invoice: {:?}", e);
                }
 
                let mut tlv_stream = invoice.as_tlv_stream();
                tlv_stream.3.paths = None;
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)),
+                       Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)),
                }
 
                let mut tlv_stream = invoice.as_tlv_stream();
                tlv_stream.3.blindedpay = None;
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)),
+                       Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)),
                }
 
                let empty_payment_paths = vec![];
                let mut tlv_stream = invoice.as_tlv_stream();
-               tlv_stream.3.paths = Some(Iterable(empty_payment_paths.iter().map(|(path, _)| path)));
+               tlv_stream.3.paths = Some(Iterable(empty_payment_paths.iter().map(|(_, path)| path)));
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)),
+                       Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)),
                }
 
                let mut payment_paths = payment_paths();
                payment_paths.pop();
                let mut tlv_stream = invoice.as_tlv_stream();
-               tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo)));
+               tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo)));
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)),
+                       Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)),
                }
        }
 
@@ -1537,17 +1551,17 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               if let Err(e) = Invoice::try_from(buffer) {
+               if let Err(e) = Bolt12Invoice::try_from(buffer) {
                        panic!("error parsing invoice: {:?}", e);
                }
 
                let mut tlv_stream = invoice.as_tlv_stream();
                tlv_stream.3.created_at = None;
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
                        Err(e) => {
-                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingCreationTime));
+                               assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingCreationTime));
                        },
                }
        }
@@ -1568,7 +1582,7 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               match Invoice::try_from(buffer) {
+               match Bolt12Invoice::try_from(buffer) {
                        Ok(invoice) => assert_eq!(invoice.relative_expiry(), Duration::from_secs(3600)),
                        Err(e) => panic!("error parsing invoice: {:?}", e),
                }
@@ -1589,17 +1603,17 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               if let Err(e) = Invoice::try_from(buffer) {
+               if let Err(e) = Bolt12Invoice::try_from(buffer) {
                        panic!("error parsing invoice: {:?}", e);
                }
 
                let mut tlv_stream = invoice.as_tlv_stream();
                tlv_stream.3.payment_hash = None;
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
                        Err(e) => {
-                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaymentHash));
+                               assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaymentHash));
                        },
                }
        }
@@ -1619,16 +1633,16 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               if let Err(e) = Invoice::try_from(buffer) {
+               if let Err(e) = Bolt12Invoice::try_from(buffer) {
                        panic!("error parsing invoice: {:?}", e);
                }
 
                let mut tlv_stream = invoice.as_tlv_stream();
                tlv_stream.3.amount = None;
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)),
+                       Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)),
                }
        }
 
@@ -1648,7 +1662,7 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               match Invoice::try_from(buffer) {
+               match Bolt12Invoice::try_from(buffer) {
                        Ok(invoice) => {
                                let mut features = Bolt12InvoiceFeatures::empty();
                                features.set_basic_mpp_optional();
@@ -1693,7 +1707,7 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               match Invoice::try_from(buffer) {
+               match Bolt12Invoice::try_from(buffer) {
                        Ok(invoice) => {
                                assert_eq!(
                                        invoice.fallbacks(),
@@ -1737,17 +1751,17 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               if let Err(e) = Invoice::try_from(buffer) {
+               if let Err(e) = Bolt12Invoice::try_from(buffer) {
                        panic!("error parsing invoice: {:?}", e);
                }
 
                let mut tlv_stream = invoice.as_tlv_stream();
                tlv_stream.3.node_id = None;
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
                        Err(e) => {
-                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey));
+                               assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey));
                        },
                }
 
@@ -1755,10 +1769,10 @@ mod tests {
                let mut tlv_stream = invoice.as_tlv_stream();
                tlv_stream.3.node_id = Some(&invalid_pubkey);
 
-               match Invoice::try_from(tlv_stream.to_bytes()) {
+               match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
                        Ok(_) => panic!("expected error"),
                        Err(e) => {
-                               assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidSigningPubkey));
+                               assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey));
                        },
                }
        }
@@ -1777,9 +1791,9 @@ mod tests {
                        .invoice
                        .write(&mut buffer).unwrap();
 
-               match Invoice::try_from(buffer) {
+               match Bolt12Invoice::try_from(buffer) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSignature)),
+                       Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
                }
        }
 
@@ -1800,10 +1814,10 @@ mod tests {
                let mut buffer = Vec::new();
                invoice.write(&mut buffer).unwrap();
 
-               match Invoice::try_from(buffer) {
+               match Bolt12Invoice::try_from(buffer) {
                        Ok(_) => panic!("expected error"),
                        Err(e) => {
-                               assert_eq!(e, ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
+                               assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
                        },
                }
        }
@@ -1826,9 +1840,9 @@ mod tests {
                BigSize(32).write(&mut encoded_invoice).unwrap();
                [42u8; 32].write(&mut encoded_invoice).unwrap();
 
-               match Invoice::try_from(encoded_invoice) {
+               match Bolt12Invoice::try_from(encoded_invoice) {
                        Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)),
+                       Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
                }
        }
 }