Self { bytes, contents, tagged_hash }
}
+ /// Returns the [`TaggedHash`] of the invoice to sign.
+ pub fn tagged_hash(&self) -> &TaggedHash {
+ &self.tagged_hash
+ }
+
/// Signs the [`TaggedHash`] of the invoice request using the given function.
///
/// Note: The hash computation may have included unknown, odd TLV records.
}
} }
+impl UnsignedInvoiceRequest {
+ offer_accessors!(self, self.contents.inner.offer);
+ invoice_request_accessors!(self, self.contents);
+}
+
impl InvoiceRequest {
+ offer_accessors!(self, self.contents.inner.offer);
invoice_request_accessors!(self, self.contents);
/// Signature of the invoice request using [`payer_id`].
self.inner.chain()
}
- fn amount_msats(&self) -> Option<u64> {
+ pub(super) fn amount_msats(&self) -> Option<u64> {
self.inner.amount_msats
}
- fn features(&self) -> &InvoiceRequestFeatures {
+ pub(super) fn features(&self) -> &InvoiceRequestFeatures {
&self.inner.features
}
- fn quantity(&self) -> Option<u64> {
+ pub(super) fn quantity(&self) -> Option<u64> {
self.inner.quantity
}
self.payer_id
}
- fn payer_note(&self) -> Option<PrintableString> {
+ pub(super) fn payer_note(&self) -> Option<PrintableString> {
self.inner.payer_note.as_ref()
.map(|payer_note| PrintableString(payer_note.as_str()))
}
None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
Some(signature) => signature,
};
- merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, contents.payer_id)?;
+ let message = TaggedHash::new(SIGNATURE_TAG, &bytes);
+ merkle::verify_signature(&signature, message, contents.payer_id)?;
Ok(InvoiceRequest { bytes, contents, signature })
}
#[cfg(feature = "std")]
use core::time::Duration;
use crate::sign::KeyMaterial;
- use crate::ln::features::InvoiceRequestFeatures;
+ use crate::ln::features::{InvoiceRequestFeatures, OfferFeatures};
use crate::ln::inbound_payment::ExpandedKey;
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG};
let mut buffer = Vec::new();
unsigned_invoice_request.write(&mut buffer).unwrap();
+ assert_eq!(unsigned_invoice_request.bytes, buffer.as_slice());
+ assert_eq!(unsigned_invoice_request.payer_metadata(), &[1; 32]);
+ assert_eq!(unsigned_invoice_request.chains(), vec![ChainHash::using_genesis_block(Network::Bitcoin)]);
+ assert_eq!(unsigned_invoice_request.metadata(), None);
+ assert_eq!(unsigned_invoice_request.amount(), Some(&Amount::Bitcoin { amount_msats: 1000 }));
+ assert_eq!(unsigned_invoice_request.description(), PrintableString("foo"));
+ assert_eq!(unsigned_invoice_request.offer_features(), &OfferFeatures::empty());
+ assert_eq!(unsigned_invoice_request.absolute_expiry(), None);
+ assert_eq!(unsigned_invoice_request.paths(), &[]);
+ assert_eq!(unsigned_invoice_request.issuer(), None);
+ assert_eq!(unsigned_invoice_request.supported_quantity(), Quantity::One);
+ assert_eq!(unsigned_invoice_request.signing_pubkey(), recipient_pubkey());
+ assert_eq!(unsigned_invoice_request.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
+ assert_eq!(unsigned_invoice_request.amount_msats(), None);
+ assert_eq!(unsigned_invoice_request.invoice_request_features(), &InvoiceRequestFeatures::empty());
+ assert_eq!(unsigned_invoice_request.quantity(), None);
+ assert_eq!(unsigned_invoice_request.payer_id(), payer_pubkey());
+ assert_eq!(unsigned_invoice_request.payer_note(), None);
+
match UnsignedInvoiceRequest::try_from(buffer) {
Err(e) => panic!("error parsing unsigned invoice request: {:?}", e),
Ok(parsed) => {
assert_eq!(invoice_request.bytes, buffer.as_slice());
assert_eq!(invoice_request.payer_metadata(), &[1; 32]);
+ assert_eq!(invoice_request.chains(), vec![ChainHash::using_genesis_block(Network::Bitcoin)]);
+ assert_eq!(invoice_request.metadata(), None);
+ assert_eq!(invoice_request.amount(), Some(&Amount::Bitcoin { amount_msats: 1000 }));
+ assert_eq!(invoice_request.description(), PrintableString("foo"));
+ assert_eq!(invoice_request.offer_features(), &OfferFeatures::empty());
+ assert_eq!(invoice_request.absolute_expiry(), None);
+ assert_eq!(invoice_request.paths(), &[]);
+ assert_eq!(invoice_request.issuer(), None);
+ assert_eq!(invoice_request.supported_quantity(), Quantity::One);
+ assert_eq!(invoice_request.signing_pubkey(), recipient_pubkey());
assert_eq!(invoice_request.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
assert_eq!(invoice_request.amount_msats(), None);
assert_eq!(invoice_request.invoice_request_features(), &InvoiceRequestFeatures::empty());
assert_eq!(invoice_request.quantity(), None);
assert_eq!(invoice_request.payer_id(), payer_pubkey());
assert_eq!(invoice_request.payer_note(), None);
- assert!(
- merkle::verify_signature(
- &invoice_request.signature, SIGNATURE_TAG, &invoice_request.bytes, payer_pubkey()
- ).is_ok()
- );
+
+ let message = TaggedHash::new(SIGNATURE_TAG, &invoice_request.bytes);
+ assert!(merkle::verify_signature(&invoice_request.signature, message, payer_pubkey()).is_ok());
assert_eq!(
invoice_request.as_tlv_stream(),