features, signing_pubkey,
};
- match (offer_tlv_stream.node_id, &offer_tlv_stream.paths) {
- (Some(expected_signing_pubkey), _) => {
- if fields.signing_pubkey != expected_signing_pubkey {
- return Err(Bolt12SemanticError::InvalidSigningPubkey);
- }
-
- let invoice_request = InvoiceRequestContents::try_from(
- (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
- )?;
- Ok(InvoiceContents::ForOffer { invoice_request, fields })
- },
- (None, Some(paths)) => {
- if !paths
- .iter()
- .filter_map(|path| path.blinded_hops.last())
- .any(|last_hop| fields.signing_pubkey == last_hop.blinded_node_id)
- {
- return Err(Bolt12SemanticError::InvalidSigningPubkey);
- }
-
- let invoice_request = InvoiceRequestContents::try_from(
- (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
- )?;
- Ok(InvoiceContents::ForOffer { invoice_request, fields })
- },
- (None, None) => {
- let refund = RefundContents::try_from(
- (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
- )?;
- Ok(InvoiceContents::ForRefund { refund, fields })
- },
+ check_invoice_signing_pubkey(&fields.signing_pubkey, &offer_tlv_stream)?;
+
+ if offer_tlv_stream.node_id.is_none() && offer_tlv_stream.paths.is_none() {
+ let refund = RefundContents::try_from(
+ (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
+ )?;
+ Ok(InvoiceContents::ForRefund { refund, fields })
+ } else {
+ let invoice_request = InvoiceRequestContents::try_from(
+ (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
+ )?;
+ Ok(InvoiceContents::ForOffer { invoice_request, fields })
}
}
}
}
}
+pub(super) fn check_invoice_signing_pubkey(
+ invoice_signing_pubkey: &PublicKey, offer_tlv_stream: &OfferTlvStream
+) -> Result<(), Bolt12SemanticError> {
+ match (&offer_tlv_stream.node_id, &offer_tlv_stream.paths) {
+ (Some(expected_signing_pubkey), _) => {
+ if invoice_signing_pubkey != expected_signing_pubkey {
+ return Err(Bolt12SemanticError::InvalidSigningPubkey);
+ }
+ },
+ (None, Some(paths)) => {
+ if !paths
+ .iter()
+ .filter_map(|path| path.blinded_hops.last())
+ .any(|last_hop| invoice_signing_pubkey == &last_hop.blinded_node_id)
+ {
+ return Err(Bolt12SemanticError::InvalidSigningPubkey);
+ }
+ },
+ _ => {},
+ }
+ Ok(())
+}
+
#[cfg(test)]
mod tests {
use super::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, InvoiceTlvStreamRef, SIGNATURE_TAG, UnsignedBolt12Invoice};