1 #![cfg_attr(feature = "std", doc = "
51 .respond_with(payment_paths, payment_hash)?
52")]
53#![cfg_attr(not(feature = "std"), doc = "
54 .respond_with_no_std(payment_paths, payment_hash, core::time::Duration::from_secs(0))?
55")]
56#![cfg_attr(feature = "std", doc = "
84 .respond_with(payment_paths, payment_hash, pubkey)?
85")]
86#![cfg_attr(not(feature = "std"), doc = "
87 .respond_with_no_std(payment_paths, payment_hash, pubkey, core::time::Duration::from_secs(0))?
88")]
89use bitcoin::{WitnessProgram, Network, WitnessVersion};
106use bitcoin::constants::ChainHash;
107use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, self};
108use bitcoin::secp256k1::schnorr::Signature;
109use bitcoin::address::Address;
110use core::time::Duration;
111use core::hash::{Hash, Hasher};
112use crate::io;
113use crate::blinded_path::BlindedPath;
114use crate::blinded_path::message::BlindedMessagePath;
115use crate::blinded_path::payment::{BlindedPayInfo, BlindedPaymentPath};
116use crate::types::payment::PaymentHash;
117use crate::ln::channelmanager::PaymentId;
118use crate::types::features::{Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
119use crate::ln::inbound_payment::{ExpandedKey, IV_LEN};
120use crate::ln::msgs::DecodeError;
121use crate::offers::invoice_macros::{invoice_accessors_common, invoice_builder_methods_common};
122#[cfg(test)]
123use crate::offers::invoice_macros::invoice_builder_methods_test_common;
124use crate::offers::invoice_request::{EXPERIMENTAL_INVOICE_REQUEST_TYPES, ExperimentalInvoiceRequestTlvStream, ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
125use crate::offers::merkle::{SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream, self};
126use crate::offers::nonce::Nonce;
127use crate::offers::offer::{Amount, EXPERIMENTAL_OFFER_TYPES, ExperimentalOfferTlvStream, ExperimentalOfferTlvStreamRef, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef, Quantity};
128use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage};
129use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef};
130use crate::offers::refund::{IV_BYTES_WITH_METADATA as REFUND_IV_BYTES_WITH_METADATA, IV_BYTES_WITHOUT_METADATA as REFUND_IV_BYTES_WITHOUT_METADATA, Refund, RefundContents};
131use crate::offers::signer::{Metadata, self};
132use crate::util::ser::{CursorReadable, HighZeroBytesDroppedBigSize, Iterable, Readable, WithoutLength, Writeable, Writer};
133use crate::util::string::PrintableString;
134
135#[allow(unused_imports)]
136use crate::prelude::*;
137
138#[cfg(feature = "std")]
139use std::time::SystemTime;
140
141pub(crate) const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(7200);
142
143pub const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signature");
145
146pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> {
158 invreq_bytes: &'a Vec<u8>,
159 invoice: InvoiceContents,
160 signing_pubkey_strategy: S,
161}
162
163#[cfg(c_bindings)]
173pub struct InvoiceWithExplicitSigningPubkeyBuilder<'a> {
174 invreq_bytes: &'a Vec<u8>,
175 invoice: InvoiceContents,
176 signing_pubkey_strategy: ExplicitSigningPubkey,
177}
178
179#[cfg(c_bindings)]
189pub struct InvoiceWithDerivedSigningPubkeyBuilder<'a> {
190 invreq_bytes: &'a Vec<u8>,
191 invoice: InvoiceContents,
192 signing_pubkey_strategy: DerivedSigningPubkey,
193}
194
195pub trait SigningPubkeyStrategy {}
199
200pub struct ExplicitSigningPubkey {}
204
205pub struct DerivedSigningPubkey(pub(super) Keypair);
209
210impl SigningPubkeyStrategy for ExplicitSigningPubkey {}
211impl SigningPubkeyStrategy for DerivedSigningPubkey {}
212
213macro_rules! invoice_explicit_signing_pubkey_builder_methods { ($self: ident, $self_type: ty) => {
214 #[cfg_attr(c_bindings, allow(dead_code))]
215 pub(super) fn for_offer(
216 invoice_request: &'a InvoiceRequest, payment_paths: Vec<BlindedPaymentPath>,
217 created_at: Duration, payment_hash: PaymentHash, signing_pubkey: PublicKey
218 ) -> Result<Self, Bolt12SemanticError> {
219 let amount_msats = Self::amount_msats(invoice_request)?;
220 let contents = InvoiceContents::ForOffer {
221 invoice_request: invoice_request.contents.clone(),
222 fields: Self::fields(
223 payment_paths, created_at, payment_hash, amount_msats, signing_pubkey
224 ),
225 };
226
227 Self::new(&invoice_request.bytes, contents, ExplicitSigningPubkey {})
228 }
229
230 #[cfg_attr(c_bindings, allow(dead_code))]
231 pub(super) fn for_refund(
232 refund: &'a Refund, payment_paths: Vec<BlindedPaymentPath>, created_at: Duration,
233 payment_hash: PaymentHash, signing_pubkey: PublicKey
234 ) -> Result<Self, Bolt12SemanticError> {
235 let amount_msats = refund.amount_msats();
236 let contents = InvoiceContents::ForRefund {
237 refund: refund.contents.clone(),
238 fields: Self::fields(
239 payment_paths, created_at, payment_hash, amount_msats, signing_pubkey
240 ),
241 };
242
243 Self::new(&refund.bytes, contents, ExplicitSigningPubkey {})
244 }
245
246 pub fn build($self: $self_type) -> Result<UnsignedBolt12Invoice, Bolt12SemanticError> {
249 #[cfg(feature = "std")] {
250 if $self.invoice.is_offer_or_refund_expired() {
251 return Err(Bolt12SemanticError::AlreadyExpired);
252 }
253 }
254
255 #[cfg(not(feature = "std"))] {
256 if $self.invoice.is_offer_or_refund_expired_no_std($self.invoice.created_at()) {
257 return Err(Bolt12SemanticError::AlreadyExpired);
258 }
259 }
260
261 let Self { invreq_bytes, invoice, .. } = $self;
262 #[cfg(not(c_bindings))] {
263 Ok(UnsignedBolt12Invoice::new(invreq_bytes, invoice))
264 }
265 #[cfg(c_bindings)] {
266 Ok(UnsignedBolt12Invoice::new(invreq_bytes, invoice.clone()))
267 }
268 }
269} }
270
271macro_rules! invoice_derived_signing_pubkey_builder_methods { ($self: ident, $self_type: ty) => {
272 #[cfg_attr(c_bindings, allow(dead_code))]
273 pub(super) fn for_offer_using_keys(
274 invoice_request: &'a InvoiceRequest, payment_paths: Vec<BlindedPaymentPath>,
275 created_at: Duration, payment_hash: PaymentHash, keys: Keypair
276 ) -> Result<Self, Bolt12SemanticError> {
277 let amount_msats = Self::amount_msats(invoice_request)?;
278 let signing_pubkey = keys.public_key();
279 let contents = InvoiceContents::ForOffer {
280 invoice_request: invoice_request.contents.clone(),
281 fields: Self::fields(
282 payment_paths, created_at, payment_hash, amount_msats, signing_pubkey
283 ),
284 };
285
286 Self::new(&invoice_request.bytes, contents, DerivedSigningPubkey(keys))
287 }
288
289 #[cfg_attr(c_bindings, allow(dead_code))]
290 pub(super) fn for_refund_using_keys(
291 refund: &'a Refund, payment_paths: Vec<BlindedPaymentPath>, created_at: Duration,
292 payment_hash: PaymentHash, keys: Keypair,
293 ) -> Result<Self, Bolt12SemanticError> {
294 let amount_msats = refund.amount_msats();
295 let signing_pubkey = keys.public_key();
296 let contents = InvoiceContents::ForRefund {
297 refund: refund.contents.clone(),
298 fields: Self::fields(
299 payment_paths, created_at, payment_hash, amount_msats, signing_pubkey
300 ),
301 };
302
303 Self::new(&refund.bytes, contents, DerivedSigningPubkey(keys))
304 }
305
306 pub fn build_and_sign<T: secp256k1::Signing>(
308 $self: $self_type, secp_ctx: &Secp256k1<T>
309 ) -> Result<Bolt12Invoice, Bolt12SemanticError> {
310 #[cfg(feature = "std")] {
311 if $self.invoice.is_offer_or_refund_expired() {
312 return Err(Bolt12SemanticError::AlreadyExpired);
313 }
314 }
315
316 #[cfg(not(feature = "std"))] {
317 if $self.invoice.is_offer_or_refund_expired_no_std($self.invoice.created_at()) {
318 return Err(Bolt12SemanticError::AlreadyExpired);
319 }
320 }
321
322 let Self {
323 invreq_bytes, invoice, signing_pubkey_strategy: DerivedSigningPubkey(keys)
324 } = $self;
325 #[cfg(not(c_bindings))]
326 let unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice);
327 #[cfg(c_bindings)]
328 let mut unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice.clone());
329
330 let invoice = unsigned_invoice
331 .sign(|message: &UnsignedBolt12Invoice|
332 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
333 )
334 .unwrap();
335 Ok(invoice)
336 }
337} }
338
339macro_rules! invoice_builder_methods { (
340 $self: ident, $self_type: ty, $return_type: ty, $return_value: expr, $type_param: ty $(, $self_mut: tt)?
341) => {
342 pub(crate) fn amount_msats(
343 invoice_request: &InvoiceRequest
344 ) -> Result<u64, Bolt12SemanticError> {
345 match invoice_request.contents.inner.amount_msats() {
346 Some(amount_msats) => Ok(amount_msats),
347 None => match invoice_request.contents.inner.offer.amount() {
348 Some(Amount::Bitcoin { amount_msats }) => {
349 amount_msats.checked_mul(invoice_request.quantity().unwrap_or(1))
350 .ok_or(Bolt12SemanticError::InvalidAmount)
351 },
352 Some(Amount::Currency { .. }) => Err(Bolt12SemanticError::UnsupportedCurrency),
353 None => Err(Bolt12SemanticError::MissingAmount),
354 },
355 }
356 }
357
358 #[cfg_attr(c_bindings, allow(dead_code))]
359 fn fields(
360 payment_paths: Vec<BlindedPaymentPath>, created_at: Duration, payment_hash: PaymentHash,
361 amount_msats: u64, signing_pubkey: PublicKey
362 ) -> InvoiceFields {
363 InvoiceFields {
364 payment_paths, created_at, relative_expiry: None, payment_hash, amount_msats,
365 fallbacks: None, features: Bolt12InvoiceFeatures::empty(), signing_pubkey,
366 #[cfg(test)]
367 experimental_baz: None,
368 }
369 }
370
371 #[cfg_attr(c_bindings, allow(dead_code))]
372 fn new(
373 invreq_bytes: &'a Vec<u8>, contents: InvoiceContents, signing_pubkey_strategy: $type_param
374 ) -> Result<Self, Bolt12SemanticError> {
375 if contents.fields().payment_paths.is_empty() {
376 return Err(Bolt12SemanticError::MissingPaths);
377 }
378
379 Ok(Self { invreq_bytes, invoice: contents, signing_pubkey_strategy })
380 }
381} }
382
383#[cfg(test)]
384macro_rules! invoice_builder_methods_test { (
385 $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
386 $(, $self_mut: tt)?
387) => {
388 #[cfg_attr(c_bindings, allow(dead_code))]
389 pub(crate) fn amount_msats_unchecked(
390 $($self_mut)* $self: $self_type, amount_msats: u64,
391 ) -> $return_type {
392 $self.invoice.fields_mut().amount_msats = amount_msats;
393 $return_value
394 }
395} }
396
397impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
398 invoice_explicit_signing_pubkey_builder_methods!(self, Self);
399}
400
401impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
402 invoice_derived_signing_pubkey_builder_methods!(self, Self);
403}
404
405impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
406 invoice_builder_methods!(self, Self, Self, self, S, mut);
407 invoice_builder_methods_common!(self, Self, self.invoice.fields_mut(), Self, self, Bolt12Invoice, mut);
408
409 #[cfg(test)]
410 invoice_builder_methods_test!(self, Self, Self, self, mut);
411 #[cfg(test)]
412 invoice_builder_methods_test_common!(self, Self, self.invoice.fields_mut(), Self, self, mut);
413}
414
415#[cfg(all(c_bindings, not(test)))]
416impl<'a> InvoiceWithExplicitSigningPubkeyBuilder<'a> {
417 invoice_explicit_signing_pubkey_builder_methods!(self, &mut Self);
418 invoice_builder_methods!(self, &mut Self, (), (), ExplicitSigningPubkey);
419 invoice_builder_methods_common!(self, &mut Self, self.invoice.fields_mut(), (), (), Bolt12Invoice);
420}
421
422#[cfg(all(c_bindings, test))]
423impl<'a> InvoiceWithExplicitSigningPubkeyBuilder<'a> {
424 invoice_explicit_signing_pubkey_builder_methods!(self, &mut Self);
425 invoice_builder_methods!(self, &mut Self, &mut Self, self, ExplicitSigningPubkey);
426 invoice_builder_methods_common!(self, &mut Self, self.invoice.fields_mut(), &mut Self, self, Bolt12Invoice);
427 invoice_builder_methods_test!(self, &mut Self, &mut Self, self);
428 invoice_builder_methods_test_common!(self, &mut Self, self.invoice.fields_mut(), &mut Self, self);
429}
430
431#[cfg(all(c_bindings, not(test)))]
432impl<'a> InvoiceWithDerivedSigningPubkeyBuilder<'a> {
433 invoice_derived_signing_pubkey_builder_methods!(self, &mut Self);
434 invoice_builder_methods!(self, &mut Self, (), (), DerivedSigningPubkey);
435 invoice_builder_methods_common!(self, &mut Self, self.invoice.fields_mut(), (), (), Bolt12Invoice);
436}
437
438#[cfg(all(c_bindings, test))]
439impl<'a> InvoiceWithDerivedSigningPubkeyBuilder<'a> {
440 invoice_derived_signing_pubkey_builder_methods!(self, &mut Self);
441 invoice_builder_methods!(self, &mut Self, &mut Self, self, DerivedSigningPubkey);
442 invoice_builder_methods_common!(self, &mut Self, self.invoice.fields_mut(), &mut Self, self, Bolt12Invoice);
443 invoice_builder_methods_test!(self, &mut Self, &mut Self, self);
444 invoice_builder_methods_test_common!(self, &mut Self, self.invoice.fields_mut(), &mut Self, self);
445}
446
447#[cfg(c_bindings)]
448impl<'a> From<InvoiceWithExplicitSigningPubkeyBuilder<'a>>
449for InvoiceBuilder<'a, ExplicitSigningPubkey> {
450 fn from(builder: InvoiceWithExplicitSigningPubkeyBuilder<'a>) -> Self {
451 let InvoiceWithExplicitSigningPubkeyBuilder {
452 invreq_bytes, invoice, signing_pubkey_strategy,
453 } = builder;
454
455 Self {
456 invreq_bytes, invoice, signing_pubkey_strategy,
457 }
458 }
459}
460
461#[cfg(c_bindings)]
462impl<'a> From<InvoiceWithDerivedSigningPubkeyBuilder<'a>>
463for InvoiceBuilder<'a, DerivedSigningPubkey> {
464 fn from(builder: InvoiceWithDerivedSigningPubkeyBuilder<'a>) -> Self {
465 let InvoiceWithDerivedSigningPubkeyBuilder {
466 invreq_bytes, invoice, signing_pubkey_strategy,
467 } = builder;
468
469 Self {
470 invreq_bytes, invoice, signing_pubkey_strategy,
471 }
472 }
473}
474
475#[derive(Clone)]
482pub struct UnsignedBolt12Invoice {
483 bytes: Vec<u8>,
484 experimental_bytes: Vec<u8>,
485 contents: InvoiceContents,
486 tagged_hash: TaggedHash,
487}
488
489pub trait SignBolt12InvoiceFn {
491 fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()>;
493}
494
495impl<F> SignBolt12InvoiceFn for F
496where
497 F: Fn(&UnsignedBolt12Invoice) -> Result<Signature, ()>,
498{
499 fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()> {
500 self(message)
501 }
502}
503
504impl<F> SignFn<UnsignedBolt12Invoice> for F
505where
506 F: SignBolt12InvoiceFn,
507{
508 fn sign(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()> {
509 self.sign_invoice(message)
510 }
511}
512
513impl UnsignedBolt12Invoice {
514 fn new(invreq_bytes: &[u8], contents: InvoiceContents) -> Self {
515 const NON_EXPERIMENTAL_TYPES: core::ops::Range<u64> = 0..INVOICE_REQUEST_TYPES.end;
517 const EXPERIMENTAL_TYPES: core::ops::Range<u64> =
518 EXPERIMENTAL_OFFER_TYPES.start..EXPERIMENTAL_INVOICE_REQUEST_TYPES.end;
519
520 let (_, _, _, invoice_tlv_stream, _, _, experimental_invoice_tlv_stream) =
521 contents.as_tlv_stream();
522
523 const INVOICE_ALLOCATION_SIZE: usize = 1024;
524 let mut bytes = Vec::with_capacity(INVOICE_ALLOCATION_SIZE);
525
526 for record in TlvStream::new(invreq_bytes).range(NON_EXPERIMENTAL_TYPES) {
530 record.write(&mut bytes).unwrap();
531 }
532
533 let remaining_bytes = &invreq_bytes[bytes.len()..];
534
535 invoice_tlv_stream.write(&mut bytes).unwrap();
536
537 const EXPERIMENTAL_TLV_ALLOCATION_SIZE: usize = 0;
538 let mut experimental_bytes = Vec::with_capacity(EXPERIMENTAL_TLV_ALLOCATION_SIZE);
539
540 let experimental_tlv_stream = TlvStream::new(remaining_bytes)
541 .range(EXPERIMENTAL_TYPES);
542 for record in experimental_tlv_stream {
543 record.write(&mut experimental_bytes).unwrap();
544 }
545
546 experimental_invoice_tlv_stream.write(&mut experimental_bytes).unwrap();
547
548 let tlv_stream = TlvStream::new(&bytes).chain(TlvStream::new(&experimental_bytes));
549 let tagged_hash = TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
550
551 Self { bytes, experimental_bytes, contents, tagged_hash }
552 }
553
554 pub fn tagged_hash(&self) -> &TaggedHash {
556 &self.tagged_hash
557 }
558}
559
560macro_rules! unsigned_invoice_sign_method { ($self: ident, $self_type: ty $(, $self_mut: tt)?) => {
561 pub fn sign<F: SignBolt12InvoiceFn>(
565 $($self_mut)* $self: $self_type, sign: F
566 ) -> Result<Bolt12Invoice, SignError> {
567 let pubkey = $self.contents.fields().signing_pubkey;
568 let signature = merkle::sign_message(sign, &$self, pubkey)?;
569
570 let signature_tlv_stream = SignatureTlvStreamRef {
572 signature: Some(&signature),
573 };
574 signature_tlv_stream.write(&mut $self.bytes).unwrap();
575
576 $self.bytes.extend_from_slice(&$self.experimental_bytes);
578
579 Ok(Bolt12Invoice {
580 #[cfg(not(c_bindings))]
581 bytes: $self.bytes,
582 #[cfg(c_bindings)]
583 bytes: $self.bytes.clone(),
584 #[cfg(not(c_bindings))]
585 contents: $self.contents,
586 #[cfg(c_bindings)]
587 contents: $self.contents.clone(),
588 signature,
589 #[cfg(not(c_bindings))]
590 tagged_hash: $self.tagged_hash,
591 #[cfg(c_bindings)]
592 tagged_hash: $self.tagged_hash.clone(),
593 })
594 }
595} }
596
597#[cfg(not(c_bindings))]
598impl UnsignedBolt12Invoice {
599 unsigned_invoice_sign_method!(self, Self, mut);
600}
601
602#[cfg(c_bindings)]
603impl UnsignedBolt12Invoice {
604 unsigned_invoice_sign_method!(self, &mut Self);
605}
606
607impl AsRef<TaggedHash> for UnsignedBolt12Invoice {
608 fn as_ref(&self) -> &TaggedHash {
609 &self.tagged_hash
610 }
611}
612
613#[derive(Clone, Debug)]
622pub struct Bolt12Invoice {
623 bytes: Vec<u8>,
624 contents: InvoiceContents,
625 signature: Signature,
626 tagged_hash: TaggedHash,
627}
628
629#[derive(Clone, Debug)]
634#[cfg_attr(test, derive(PartialEq))]
635enum InvoiceContents {
636 ForOffer {
640 invoice_request: InvoiceRequestContents,
641 fields: InvoiceFields,
642 },
643 ForRefund {
647 refund: RefundContents,
648 fields: InvoiceFields,
649 },
650}
651
652#[derive(Clone, Debug, PartialEq)]
654struct InvoiceFields {
655 payment_paths: Vec<BlindedPaymentPath>,
656 created_at: Duration,
657 relative_expiry: Option<Duration>,
658 payment_hash: PaymentHash,
659 amount_msats: u64,
660 fallbacks: Option<Vec<FallbackAddress>>,
661 features: Bolt12InvoiceFeatures,
662 signing_pubkey: PublicKey,
663 #[cfg(test)]
664 experimental_baz: Option<u64>,
665}
666
667macro_rules! invoice_accessors { ($self: ident, $contents: expr) => {
668 pub fn offer_chains(&$self) -> Option<Vec<ChainHash>> {
674 $contents.offer_chains()
675 }
676
677 pub fn chain(&$self) -> ChainHash {
685 $contents.chain()
686 }
687
688 pub fn metadata(&$self) -> Option<&Vec<u8>> {
696 $contents.metadata()
697 }
698
699 pub fn amount(&$self) -> Option<Amount> {
707 $contents.amount()
708 }
709
710 pub fn offer_features(&$self) -> Option<&OfferFeatures> {
718 $contents.offer_features()
719 }
720
721 pub fn description(&$self) -> Option<PrintableString> {
727 $contents.description()
728 }
729
730 pub fn absolute_expiry(&$self) -> Option<Duration> {
736 $contents.absolute_expiry()
737 }
738
739 pub fn issuer(&$self) -> Option<PrintableString> {
745 $contents.issuer()
746 }
747
748 pub fn message_paths(&$self) -> &[BlindedMessagePath] {
754 $contents.message_paths()
755 }
756
757 pub fn supported_quantity(&$self) -> Option<Quantity> {
764 $contents.supported_quantity()
765 }
766
767 pub fn issuer_signing_pubkey(&$self) -> Option<PublicKey> {
774 $contents.issuer_signing_pubkey()
775 }
776
777 pub fn payer_metadata(&$self) -> &[u8] {
781 $contents.payer_metadata()
782 }
783
784 pub fn invoice_request_features(&$self) -> &InvoiceRequestFeatures {
788 &$contents.invoice_request_features()
789 }
790
791 pub fn quantity(&$self) -> Option<u64> {
795 $contents.quantity()
796 }
797
798 pub fn payer_signing_pubkey(&$self) -> PublicKey {
803 $contents.payer_signing_pubkey()
804 }
805
806 pub fn payer_note(&$self) -> Option<PrintableString> {
810 $contents.payer_note()
811 }
812
813 pub fn payment_hash(&$self) -> PaymentHash {
815 $contents.payment_hash()
816 }
817
818 pub fn amount_msats(&$self) -> u64 {
820 $contents.amount_msats()
821 }
822} }
823
824macro_rules! invoice_accessors_signing_pubkey {
825 ($self: ident, $contents: expr, $invoice_type: ty) =>
826{
827 pub fn signing_pubkey(&$self) -> PublicKey {
841 $contents.signing_pubkey()
842 }
843} }
844
845impl UnsignedBolt12Invoice {
846 invoice_accessors_common!(self, self.contents, UnsignedBolt12Invoice);
847 invoice_accessors_signing_pubkey!(self, self.contents, UnsignedBolt12Invoice);
848 invoice_accessors!(self, self.contents);
849}
850
851impl Bolt12Invoice {
852 invoice_accessors_common!(self, self.contents, Bolt12Invoice);
853 invoice_accessors_signing_pubkey!(self, self.contents, Bolt12Invoice);
854 invoice_accessors!(self, self.contents);
855
856 pub fn signature(&self) -> Signature {
858 self.signature
859 }
860
861 pub fn signable_hash(&self) -> [u8; 32] {
863 self.tagged_hash.as_digest().as_ref().clone()
864 }
865
866 pub fn verify_using_metadata<T: secp256k1::Signing>(
871 &self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
872 ) -> Result<PaymentId, ()> {
873 let (metadata, iv_bytes) = match &self.contents {
874 InvoiceContents::ForOffer { invoice_request, .. } => {
875 (&invoice_request.inner.payer.0, INVOICE_REQUEST_IV_BYTES)
876 },
877 InvoiceContents::ForRefund { refund, .. } => {
878 (&refund.payer.0, REFUND_IV_BYTES_WITH_METADATA)
879 },
880 };
881 self.contents.verify(&self.bytes, metadata, key, iv_bytes, secp_ctx)
882 }
883
884 pub fn verify_using_payer_data<T: secp256k1::Signing>(
888 &self, payment_id: PaymentId, nonce: Nonce, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
889 ) -> Result<PaymentId, ()> {
890 let metadata = Metadata::payer_data(payment_id, nonce, key);
891 let iv_bytes = match &self.contents {
892 InvoiceContents::ForOffer { .. } => INVOICE_REQUEST_IV_BYTES,
893 InvoiceContents::ForRefund { .. } => REFUND_IV_BYTES_WITHOUT_METADATA,
894 };
895 self.contents
896 .verify(&self.bytes, &metadata, key, iv_bytes, secp_ctx)
897 .and_then(|extracted_payment_id| (payment_id == extracted_payment_id)
898 .then(|| payment_id)
899 .ok_or(())
900 )
901 }
902
903 pub(crate) fn as_tlv_stream(&self) -> FullInvoiceTlvStreamRef {
904 let (
905 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
906 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
907 experimental_invoice_tlv_stream,
908 ) = self.contents.as_tlv_stream();
909 let signature_tlv_stream = SignatureTlvStreamRef {
910 signature: Some(&self.signature),
911 };
912 (
913 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
914 signature_tlv_stream, experimental_offer_tlv_stream,
915 experimental_invoice_request_tlv_stream, experimental_invoice_tlv_stream,
916 )
917 }
918
919 pub(crate) fn is_for_refund_without_paths(&self) -> bool {
920 match self.contents {
921 InvoiceContents::ForOffer { .. } => false,
922 InvoiceContents::ForRefund { .. } => self.message_paths().is_empty(),
923 }
924 }
925}
926
927impl PartialEq for Bolt12Invoice {
928 fn eq(&self, other: &Self) -> bool {
929 self.bytes.eq(&other.bytes)
930 }
931}
932
933impl Eq for Bolt12Invoice {}
934
935impl Hash for Bolt12Invoice {
936 fn hash<H: Hasher>(&self, state: &mut H) {
937 self.bytes.hash(state);
938 }
939}
940
941impl InvoiceContents {
942 #[cfg(feature = "std")]
944 fn is_offer_or_refund_expired(&self) -> bool {
945 match self {
946 InvoiceContents::ForOffer { invoice_request, .. } =>
947 invoice_request.inner.offer.is_expired(),
948 InvoiceContents::ForRefund { refund, .. } => refund.is_expired(),
949 }
950 }
951
952 #[cfg(not(feature = "std"))]
953 fn is_offer_or_refund_expired_no_std(&self, duration_since_epoch: Duration) -> bool {
954 match self {
955 InvoiceContents::ForOffer { invoice_request, .. } =>
956 invoice_request.inner.offer.is_expired_no_std(duration_since_epoch),
957 InvoiceContents::ForRefund { refund, .. } =>
958 refund.is_expired_no_std(duration_since_epoch),
959 }
960 }
961
962 fn offer_chains(&self) -> Option<Vec<ChainHash>> {
963 match self {
964 InvoiceContents::ForOffer { invoice_request, .. } =>
965 Some(invoice_request.inner.offer.chains()),
966 InvoiceContents::ForRefund { .. } => None,
967 }
968 }
969
970 fn chain(&self) -> ChainHash {
971 match self {
972 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.chain(),
973 InvoiceContents::ForRefund { refund, .. } => refund.chain(),
974 }
975 }
976
977 fn metadata(&self) -> Option<&Vec<u8>> {
978 match self {
979 InvoiceContents::ForOffer { invoice_request, .. } =>
980 invoice_request.inner.offer.metadata(),
981 InvoiceContents::ForRefund { .. } => None,
982 }
983 }
984
985 fn amount(&self) -> Option<Amount> {
986 match self {
987 InvoiceContents::ForOffer { invoice_request, .. } =>
988 invoice_request.inner.offer.amount(),
989 InvoiceContents::ForRefund { .. } => None,
990 }
991 }
992
993 fn description(&self) -> Option<PrintableString> {
994 match self {
995 InvoiceContents::ForOffer { invoice_request, .. } => {
996 invoice_request.inner.offer.description()
997 },
998 InvoiceContents::ForRefund { refund, .. } => Some(refund.description()),
999 }
1000 }
1001
1002 fn offer_features(&self) -> Option<&OfferFeatures> {
1003 match self {
1004 InvoiceContents::ForOffer { invoice_request, .. } => {
1005 Some(invoice_request.inner.offer.features())
1006 },
1007 InvoiceContents::ForRefund { .. } => None,
1008 }
1009 }
1010
1011 fn absolute_expiry(&self) -> Option<Duration> {
1012 match self {
1013 InvoiceContents::ForOffer { invoice_request, .. } => {
1014 invoice_request.inner.offer.absolute_expiry()
1015 },
1016 InvoiceContents::ForRefund { refund, .. } => refund.absolute_expiry(),
1017 }
1018 }
1019
1020 fn issuer(&self) -> Option<PrintableString> {
1021 match self {
1022 InvoiceContents::ForOffer { invoice_request, .. } => {
1023 invoice_request.inner.offer.issuer()
1024 },
1025 InvoiceContents::ForRefund { refund, .. } => refund.issuer(),
1026 }
1027 }
1028
1029 fn message_paths(&self) -> &[BlindedMessagePath] {
1030 match self {
1031 InvoiceContents::ForOffer { invoice_request, .. } => {
1032 invoice_request.inner.offer.paths()
1033 },
1034 InvoiceContents::ForRefund { refund, .. } => refund.paths(),
1035 }
1036 }
1037
1038 fn supported_quantity(&self) -> Option<Quantity> {
1039 match self {
1040 InvoiceContents::ForOffer { invoice_request, .. } => {
1041 Some(invoice_request.inner.offer.supported_quantity())
1042 },
1043 InvoiceContents::ForRefund { .. } => None,
1044 }
1045 }
1046
1047 fn issuer_signing_pubkey(&self) -> Option<PublicKey> {
1048 match self {
1049 InvoiceContents::ForOffer { invoice_request, .. } => {
1050 invoice_request.inner.offer.issuer_signing_pubkey()
1051 },
1052 InvoiceContents::ForRefund { .. } => None,
1053 }
1054 }
1055
1056 fn payer_metadata(&self) -> &[u8] {
1057 match self {
1058 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.metadata(),
1059 InvoiceContents::ForRefund { refund, .. } => refund.metadata(),
1060 }
1061 }
1062
1063 fn invoice_request_features(&self) -> &InvoiceRequestFeatures {
1064 match self {
1065 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.features(),
1066 InvoiceContents::ForRefund { refund, .. } => refund.features(),
1067 }
1068 }
1069
1070 fn quantity(&self) -> Option<u64> {
1071 match self {
1072 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.quantity(),
1073 InvoiceContents::ForRefund { refund, .. } => refund.quantity(),
1074 }
1075 }
1076
1077 fn payer_signing_pubkey(&self) -> PublicKey {
1078 match self {
1079 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.payer_signing_pubkey(),
1080 InvoiceContents::ForRefund { refund, .. } => refund.payer_signing_pubkey(),
1081 }
1082 }
1083
1084 fn payer_note(&self) -> Option<PrintableString> {
1085 match self {
1086 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.payer_note(),
1087 InvoiceContents::ForRefund { refund, .. } => refund.payer_note(),
1088 }
1089 }
1090
1091 fn payment_paths(&self) -> &[BlindedPaymentPath] {
1092 &self.fields().payment_paths[..]
1093 }
1094
1095 fn created_at(&self) -> Duration {
1096 self.fields().created_at
1097 }
1098
1099 fn relative_expiry(&self) -> Duration {
1100 self.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
1101 }
1102
1103 #[cfg(feature = "std")]
1104 fn is_expired(&self) -> bool {
1105 is_expired(self.created_at(), self.relative_expiry())
1106 }
1107
1108 fn payment_hash(&self) -> PaymentHash {
1109 self.fields().payment_hash
1110 }
1111
1112 fn amount_msats(&self) -> u64 {
1113 self.fields().amount_msats
1114 }
1115
1116 fn fallbacks(&self) -> Vec<Address> {
1117 self.fields().fallbacks
1118 .as_ref()
1119 .map(|fallbacks| filter_fallbacks(self.chain(), fallbacks))
1120 .unwrap_or_default()
1121 }
1122
1123 fn features(&self) -> &Bolt12InvoiceFeatures {
1124 &self.fields().features
1125 }
1126
1127 fn signing_pubkey(&self) -> PublicKey {
1128 self.fields().signing_pubkey
1129 }
1130
1131 fn fields(&self) -> &InvoiceFields {
1132 match self {
1133 InvoiceContents::ForOffer { fields, .. } => fields,
1134 InvoiceContents::ForRefund { fields, .. } => fields,
1135 }
1136 }
1137
1138 fn fields_mut(&mut self) -> &mut InvoiceFields {
1139 match self {
1140 InvoiceContents::ForOffer { fields, .. } => fields,
1141 InvoiceContents::ForRefund { fields, .. } => fields,
1142 }
1143 }
1144
1145 fn verify<T: secp256k1::Signing>(
1146 &self, bytes: &[u8], metadata: &Metadata, key: &ExpandedKey, iv_bytes: &[u8; IV_LEN],
1147 secp_ctx: &Secp256k1<T>,
1148 ) -> Result<PaymentId, ()> {
1149 const EXPERIMENTAL_TYPES: core::ops::Range<u64> =
1150 EXPERIMENTAL_OFFER_TYPES.start..EXPERIMENTAL_INVOICE_REQUEST_TYPES.end;
1151
1152 let offer_records = TlvStream::new(bytes).range(OFFER_TYPES);
1153 let invreq_records = TlvStream::new(bytes).range(INVOICE_REQUEST_TYPES).filter(|record| {
1154 match record.r#type {
1155 PAYER_METADATA_TYPE => false, INVOICE_REQUEST_PAYER_ID_TYPE => !metadata.derives_payer_keys(),
1157 _ => true,
1158 }
1159 });
1160 let experimental_records = TlvStream::new(bytes).range(EXPERIMENTAL_TYPES);
1161 let tlv_stream = offer_records.chain(invreq_records).chain(experimental_records);
1162
1163 let signing_pubkey = self.payer_signing_pubkey();
1164 signer::verify_payer_metadata(
1165 metadata.as_ref(), key, iv_bytes, signing_pubkey, tlv_stream, secp_ctx,
1166 )
1167 }
1168
1169 fn as_tlv_stream(&self) -> PartialInvoiceTlvStreamRef {
1170 let (
1171 payer, offer, invoice_request, experimental_offer, experimental_invoice_request,
1172 ) = match self {
1173 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.as_tlv_stream(),
1174 InvoiceContents::ForRefund { refund, .. } => refund.as_tlv_stream(),
1175 };
1176 let (invoice, experimental_invoice) = self.fields().as_tlv_stream();
1177
1178 (
1179 payer, offer, invoice_request, invoice, experimental_offer,
1180 experimental_invoice_request, experimental_invoice,
1181 )
1182 }
1183}
1184
1185#[cfg(feature = "std")]
1186pub(super) fn is_expired(created_at: Duration, relative_expiry: Duration) -> bool {
1187 let absolute_expiry = created_at.checked_add(relative_expiry);
1188 match absolute_expiry {
1189 Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
1190 Ok(elapsed) => elapsed > seconds_from_epoch,
1191 Err(_) => false,
1192 },
1193 None => false,
1194 }
1195}
1196
1197pub(super) fn filter_fallbacks(
1198 chain: ChainHash, fallbacks: &Vec<FallbackAddress>
1199) -> Vec<Address> {
1200 let network = if chain == ChainHash::using_genesis_block(Network::Bitcoin) {
1201 Network::Bitcoin
1202 } else if chain == ChainHash::using_genesis_block(Network::Testnet) {
1203 Network::Testnet
1204 } else if chain == ChainHash::using_genesis_block(Network::Signet) {
1205 Network::Signet
1206 } else if chain == ChainHash::using_genesis_block(Network::Regtest) {
1207 Network::Regtest
1208 } else {
1209 return Vec::new()
1210 };
1211
1212 let to_valid_address = |address: &FallbackAddress| {
1213 let version = match WitnessVersion::try_from(address.version) {
1214 Ok(version) => version,
1215 Err(_) => return None,
1216 };
1217
1218 let witness_program = match WitnessProgram::new(version, &address.program) {
1219 Ok(witness_program) => witness_program,
1220 Err(_) => return None,
1221 };
1222 Some(Address::from_witness_program(witness_program, network))
1223 };
1224
1225 fallbacks.iter().filter_map(to_valid_address).collect()
1226}
1227
1228impl InvoiceFields {
1229 fn as_tlv_stream(&self) -> (InvoiceTlvStreamRef, ExperimentalInvoiceTlvStreamRef) {
1230 let features = {
1231 if self.features == Bolt12InvoiceFeatures::empty() { None }
1232 else { Some(&self.features) }
1233 };
1234
1235 (
1236 InvoiceTlvStreamRef {
1237 paths: Some(Iterable(self.payment_paths.iter().map(|path| path.inner_blinded_path()))),
1238 blindedpay: Some(Iterable(self.payment_paths.iter().map(|path| &path.payinfo))),
1239 created_at: Some(self.created_at.as_secs()),
1240 relative_expiry: self.relative_expiry.map(|duration| duration.as_secs() as u32),
1241 payment_hash: Some(&self.payment_hash),
1242 amount: Some(self.amount_msats),
1243 fallbacks: self.fallbacks.as_ref(),
1244 features,
1245 node_id: Some(&self.signing_pubkey),
1246 message_paths: None,
1247 },
1248 ExperimentalInvoiceTlvStreamRef {
1249 #[cfg(test)]
1250 experimental_baz: self.experimental_baz,
1251 },
1252 )
1253 }
1254}
1255
1256impl Writeable for UnsignedBolt12Invoice {
1257 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1258 WithoutLength(&self.bytes).write(writer)
1259 }
1260}
1261
1262impl Writeable for Bolt12Invoice {
1263 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1264 WithoutLength(&self.bytes).write(writer)
1265 }
1266}
1267
1268impl Readable for Bolt12Invoice {
1269 fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
1270 let bytes: WithoutLength<Vec<u8>> = Readable::read(reader)?;
1271 Self::try_from(bytes.0).map_err(|_| DecodeError::InvalidValue)
1272 }
1273}
1274
1275impl Writeable for InvoiceContents {
1276 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1277 self.as_tlv_stream().write(writer)
1278 }
1279}
1280
1281impl TryFrom<Vec<u8>> for UnsignedBolt12Invoice {
1282 type Error = Bolt12ParseError;
1283
1284 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1285 let invoice = ParsedMessage::<PartialInvoiceTlvStream>::try_from(bytes)?;
1286 let ParsedMessage { mut bytes, tlv_stream } = invoice;
1287 let contents = InvoiceContents::try_from(tlv_stream)?;
1288
1289 let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
1290
1291 let offset = TlvStream::new(&bytes)
1292 .range(0..INVOICE_TYPES.end)
1293 .last()
1294 .map_or(0, |last_record| last_record.end);
1295 let experimental_bytes = bytes.split_off(offset);
1296
1297 Ok(UnsignedBolt12Invoice { bytes, experimental_bytes, contents, tagged_hash })
1298 }
1299}
1300
1301impl TryFrom<Vec<u8>> for Bolt12Invoice {
1302 type Error = Bolt12ParseError;
1303
1304 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1305 let parsed_invoice = ParsedMessage::<FullInvoiceTlvStream>::try_from(bytes)?;
1306 Bolt12Invoice::try_from(parsed_invoice)
1307 }
1308}
1309
1310pub(super) const INVOICE_TYPES: core::ops::Range<u64> = 160..240;
1312
1313tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef<'a>, INVOICE_TYPES, {
1314 (160, paths: (Vec<BlindedPath>, WithoutLength, Iterable<'a, BlindedPathIter<'a>, BlindedPath>)),
1315 (162, blindedpay: (Vec<BlindedPayInfo>, WithoutLength, Iterable<'a, BlindedPayInfoIter<'a>, BlindedPayInfo>)),
1316 (164, created_at: (u64, HighZeroBytesDroppedBigSize)),
1317 (166, relative_expiry: (u32, HighZeroBytesDroppedBigSize)),
1318 (168, payment_hash: PaymentHash),
1319 (170, amount: (u64, HighZeroBytesDroppedBigSize)),
1320 (172, fallbacks: (Vec<FallbackAddress>, WithoutLength)),
1321 (174, features: (Bolt12InvoiceFeatures, WithoutLength)),
1322 (176, node_id: PublicKey),
1323 (236, message_paths: (Vec<BlindedMessagePath>, WithoutLength)),
1325});
1326
1327pub(super) const EXPERIMENTAL_INVOICE_TYPES: core::ops::RangeFrom<u64> = 3_000_000_000..;
1329
1330#[cfg(not(test))]
1331tlv_stream!(
1332 ExperimentalInvoiceTlvStream, ExperimentalInvoiceTlvStreamRef, EXPERIMENTAL_INVOICE_TYPES, {
1333 }
1337);
1338
1339#[cfg(test)]
1340tlv_stream!(
1341 ExperimentalInvoiceTlvStream, ExperimentalInvoiceTlvStreamRef, EXPERIMENTAL_INVOICE_TYPES, {
1342 (3_999_999_999, experimental_baz: (u64, HighZeroBytesDroppedBigSize)),
1343 }
1344);
1345
1346pub(super) type BlindedPathIter<'a> = core::iter::Map<
1347 core::slice::Iter<'a, BlindedPaymentPath>,
1348 for<'r> fn(&'r BlindedPaymentPath) -> &'r BlindedPath,
1349>;
1350
1351pub(super) type BlindedPayInfoIter<'a> = core::iter::Map<
1352 core::slice::Iter<'a, BlindedPaymentPath>,
1353 for<'r> fn(&'r BlindedPaymentPath) -> &'r BlindedPayInfo,
1354>;
1355
1356#[derive(Clone, Debug, PartialEq)]
1358pub(super) struct FallbackAddress {
1359 pub(super) version: u8,
1360 pub(super) program: Vec<u8>,
1361}
1362
1363impl_writeable!(FallbackAddress, { version, program });
1364
1365type FullInvoiceTlvStream =(
1366 PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, InvoiceTlvStream, SignatureTlvStream,
1367 ExperimentalOfferTlvStream, ExperimentalInvoiceRequestTlvStream, ExperimentalInvoiceTlvStream,
1368);
1369
1370type FullInvoiceTlvStreamRef<'a> = (
1371 PayerTlvStreamRef<'a>,
1372 OfferTlvStreamRef<'a>,
1373 InvoiceRequestTlvStreamRef<'a>,
1374 InvoiceTlvStreamRef<'a>,
1375 SignatureTlvStreamRef<'a>,
1376 ExperimentalOfferTlvStreamRef,
1377 ExperimentalInvoiceRequestTlvStreamRef,
1378 ExperimentalInvoiceTlvStreamRef,
1379);
1380
1381impl CursorReadable for FullInvoiceTlvStream {
1382 fn read<R: AsRef<[u8]>>(r: &mut io::Cursor<R>) -> Result<Self, DecodeError> {
1383 let payer = CursorReadable::read(r)?;
1384 let offer = CursorReadable::read(r)?;
1385 let invoice_request = CursorReadable::read(r)?;
1386 let invoice = CursorReadable::read(r)?;
1387 let signature = CursorReadable::read(r)?;
1388 let experimental_offer = CursorReadable::read(r)?;
1389 let experimental_invoice_request = CursorReadable::read(r)?;
1390 let experimental_invoice = CursorReadable::read(r)?;
1391
1392 Ok(
1393 (
1394 payer, offer, invoice_request, invoice, signature, experimental_offer,
1395 experimental_invoice_request, experimental_invoice,
1396 )
1397 )
1398 }
1399}
1400
1401type PartialInvoiceTlvStream = (
1402 PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, InvoiceTlvStream,
1403 ExperimentalOfferTlvStream, ExperimentalInvoiceRequestTlvStream, ExperimentalInvoiceTlvStream,
1404);
1405
1406type PartialInvoiceTlvStreamRef<'a> = (
1407 PayerTlvStreamRef<'a>,
1408 OfferTlvStreamRef<'a>,
1409 InvoiceRequestTlvStreamRef<'a>,
1410 InvoiceTlvStreamRef<'a>,
1411 ExperimentalOfferTlvStreamRef,
1412 ExperimentalInvoiceRequestTlvStreamRef,
1413 ExperimentalInvoiceTlvStreamRef,
1414);
1415
1416impl CursorReadable for PartialInvoiceTlvStream {
1417 fn read<R: AsRef<[u8]>>(r: &mut io::Cursor<R>) -> Result<Self, DecodeError> {
1418 let payer = CursorReadable::read(r)?;
1419 let offer = CursorReadable::read(r)?;
1420 let invoice_request = CursorReadable::read(r)?;
1421 let invoice = CursorReadable::read(r)?;
1422 let experimental_offer = CursorReadable::read(r)?;
1423 let experimental_invoice_request = CursorReadable::read(r)?;
1424 let experimental_invoice = CursorReadable::read(r)?;
1425
1426 Ok(
1427 (
1428 payer, offer, invoice_request, invoice, experimental_offer,
1429 experimental_invoice_request, experimental_invoice,
1430 )
1431 )
1432 }
1433}
1434
1435impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Bolt12Invoice {
1436 type Error = Bolt12ParseError;
1437
1438 fn try_from(invoice: ParsedMessage<FullInvoiceTlvStream>) -> Result<Self, Self::Error> {
1439 let ParsedMessage { bytes, tlv_stream } = invoice;
1440 let (
1441 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
1442 SignatureTlvStream { signature },
1443 experimental_offer_tlv_stream,
1444 experimental_invoice_request_tlv_stream,
1445 experimental_invoice_tlv_stream,
1446 ) = tlv_stream;
1447 let contents = InvoiceContents::try_from(
1448 (
1449 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
1450 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
1451 experimental_invoice_tlv_stream,
1452 )
1453 )?;
1454
1455 let signature = signature.ok_or(
1456 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)
1457 )?;
1458 let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
1459 let pubkey = contents.fields().signing_pubkey;
1460 merkle::verify_signature(&signature, &tagged_hash, pubkey)?;
1461
1462 Ok(Bolt12Invoice { bytes, contents, signature, tagged_hash })
1463 }
1464}
1465
1466impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
1467 type Error = Bolt12SemanticError;
1468
1469 fn try_from(tlv_stream: PartialInvoiceTlvStream) -> Result<Self, Self::Error> {
1470 let (
1471 payer_tlv_stream,
1472 offer_tlv_stream,
1473 invoice_request_tlv_stream,
1474 InvoiceTlvStream {
1475 paths, blindedpay, created_at, relative_expiry, payment_hash, amount, fallbacks,
1476 features, node_id, message_paths,
1477 },
1478 experimental_offer_tlv_stream,
1479 experimental_invoice_request_tlv_stream,
1480 ExperimentalInvoiceTlvStream {
1481 #[cfg(test)]
1482 experimental_baz,
1483 },
1484 ) = tlv_stream;
1485
1486 if message_paths.is_some() { return Err(Bolt12SemanticError::UnexpectedPaths) }
1487
1488 let payment_paths = construct_payment_paths(blindedpay, paths)?;
1489
1490 let created_at = match created_at {
1491 None => return Err(Bolt12SemanticError::MissingCreationTime),
1492 Some(timestamp) => Duration::from_secs(timestamp),
1493 };
1494
1495 let relative_expiry = relative_expiry
1496 .map(Into::<u64>::into)
1497 .map(Duration::from_secs);
1498
1499 let payment_hash = payment_hash.ok_or(Bolt12SemanticError::MissingPaymentHash)?;
1500
1501 let amount_msats = amount.ok_or(Bolt12SemanticError::MissingAmount)?;
1502
1503 let features = features.unwrap_or_else(Bolt12InvoiceFeatures::empty);
1504
1505 let signing_pubkey = node_id.ok_or(Bolt12SemanticError::MissingSigningPubkey)?;
1506
1507 let fields = InvoiceFields {
1508 payment_paths, created_at, relative_expiry, payment_hash, amount_msats, fallbacks,
1509 features, signing_pubkey,
1510 #[cfg(test)]
1511 experimental_baz,
1512 };
1513
1514 check_invoice_signing_pubkey(&fields.signing_pubkey, &offer_tlv_stream)?;
1515
1516 if offer_tlv_stream.issuer_id.is_none() && offer_tlv_stream.paths.is_none() {
1517 let refund = RefundContents::try_from(
1518 (
1519 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
1520 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
1521 )
1522 )?;
1523
1524 if amount_msats != refund.amount_msats() {
1525 return Err(Bolt12SemanticError::InvalidAmount);
1526 }
1527
1528 Ok(InvoiceContents::ForRefund { refund, fields })
1529 } else {
1530 let invoice_request = InvoiceRequestContents::try_from(
1531 (
1532 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
1533 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
1534 )
1535 )?;
1536
1537 if let Some(requested_amount_msats) = invoice_request.amount_msats() {
1538 if amount_msats != requested_amount_msats {
1539 return Err(Bolt12SemanticError::InvalidAmount);
1540 }
1541 }
1542
1543 Ok(InvoiceContents::ForOffer { invoice_request, fields })
1544 }
1545 }
1546}
1547
1548pub(super) fn construct_payment_paths(
1549 blinded_payinfos: Option<Vec<BlindedPayInfo>>, blinded_paths: Option<Vec<BlindedPath>>
1550) -> Result<Vec<BlindedPaymentPath>, Bolt12SemanticError> {
1551 match (blinded_payinfos, blinded_paths) {
1552 (_, None) => Err(Bolt12SemanticError::MissingPaths),
1553 (None, _) => Err(Bolt12SemanticError::InvalidPayInfo),
1554 (_, Some(paths)) if paths.is_empty() => Err(Bolt12SemanticError::MissingPaths),
1555 (Some(blindedpay), Some(paths)) if paths.len() != blindedpay.len() => {
1556 Err(Bolt12SemanticError::InvalidPayInfo)
1557 },
1558 (Some(blindedpay), Some(paths)) => {
1559 Ok(blindedpay
1560 .into_iter()
1561 .zip(paths.into_iter())
1562 .map(|(payinfo, path)| BlindedPaymentPath::from_parts(path, payinfo))
1563 .collect::<Vec<_>>()
1564 )
1565 },
1566 }
1567}
1568
1569pub(super) fn check_invoice_signing_pubkey(
1570 invoice_signing_pubkey: &PublicKey, offer_tlv_stream: &OfferTlvStream
1571) -> Result<(), Bolt12SemanticError> {
1572 match (&offer_tlv_stream.issuer_id, &offer_tlv_stream.paths) {
1573 (Some(issuer_signing_pubkey), _) => {
1574 if invoice_signing_pubkey != issuer_signing_pubkey {
1575 return Err(Bolt12SemanticError::InvalidSigningPubkey);
1576 }
1577 },
1578 (None, Some(paths)) => {
1579 if !paths
1580 .iter()
1581 .filter_map(|path| path.blinded_hops().last())
1582 .any(|last_hop| invoice_signing_pubkey == &last_hop.blinded_node_id)
1583 {
1584 return Err(Bolt12SemanticError::InvalidSigningPubkey);
1585 }
1586 },
1587 _ => {},
1588 }
1589 Ok(())
1590}
1591
1592#[cfg(test)]
1593mod tests {
1594 use super::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, EXPERIMENTAL_INVOICE_TYPES, ExperimentalInvoiceTlvStreamRef, FallbackAddress, FullInvoiceTlvStreamRef, INVOICE_TYPES, InvoiceTlvStreamRef, SIGNATURE_TAG, UnsignedBolt12Invoice};
1595
1596 use bitcoin::{CompressedPublicKey, WitnessProgram, WitnessVersion};
1597 use bitcoin::constants::ChainHash;
1598 use bitcoin::script::ScriptBuf;
1599 use bitcoin::hashes::Hash;
1600 use bitcoin::network::Network;
1601 use bitcoin::secp256k1::{Keypair, Message, Secp256k1, SecretKey, XOnlyPublicKey, self};
1602 use bitcoin::address::Address;
1603 use bitcoin::key::TweakedPublicKey;
1604
1605 use core::time::Duration;
1606
1607 use crate::blinded_path::BlindedHop;
1608 use crate::blinded_path::message::BlindedMessagePath;
1609 use crate::types::features::{Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
1610 use crate::ln::channelmanager::PaymentId;
1611 use crate::ln::inbound_payment::ExpandedKey;
1612 use crate::ln::msgs::DecodeError;
1613 use crate::offers::invoice_request::{ExperimentalInvoiceRequestTlvStreamRef, InvoiceRequestTlvStreamRef};
1614 use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, TlvStream, self};
1615 use crate::offers::nonce::Nonce;
1616 use crate::offers::offer::{Amount, ExperimentalOfferTlvStreamRef, OfferTlvStreamRef, Quantity};
1617 use crate::prelude::*;
1618 #[cfg(not(c_bindings))]
1619 use {
1620 crate::offers::offer::OfferBuilder,
1621 crate::offers::refund::RefundBuilder,
1622 };
1623 #[cfg(c_bindings)]
1624 use {
1625 crate::offers::offer::OfferWithExplicitMetadataBuilder as OfferBuilder,
1626 crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder as RefundBuilder,
1627 };
1628 use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
1629 use crate::offers::payer::PayerTlvStreamRef;
1630 use crate::offers::test_utils::*;
1631 use crate::util::ser::{BigSize, Iterable, Writeable};
1632 use crate::util::string::PrintableString;
1633
1634 trait ToBytes {
1635 fn to_bytes(&self) -> Vec<u8>;
1636 }
1637
1638 impl<'a> ToBytes for FullInvoiceTlvStreamRef<'a> {
1639 fn to_bytes(&self) -> Vec<u8> {
1640 let mut buffer = Vec::new();
1641 self.0.write(&mut buffer).unwrap();
1642 self.1.write(&mut buffer).unwrap();
1643 self.2.write(&mut buffer).unwrap();
1644 self.3.write(&mut buffer).unwrap();
1645 self.4.write(&mut buffer).unwrap();
1646 buffer
1647 }
1648 }
1649
1650 #[test]
1651 fn builds_invoice_for_offer_with_defaults() {
1652 let expanded_key = ExpandedKey::new([42; 32]);
1653 let entropy = FixedEntropy {};
1654 let nonce = Nonce::from_entropy_source(&entropy);
1655 let secp_ctx = Secp256k1::new();
1656 let payment_id = PaymentId([1; 32]);
1657 let encrypted_payment_id = expanded_key.crypt_for_offer(payment_id.0, nonce);
1658
1659 let payment_paths = payment_paths();
1660 let payment_hash = payment_hash();
1661 let now = now();
1662 let unsigned_invoice = OfferBuilder::new(recipient_pubkey())
1663 .amount_msats(1000)
1664 .build().unwrap()
1665 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1666 .build_and_sign().unwrap()
1667 .respond_with_no_std(payment_paths.clone(), payment_hash, now).unwrap()
1668 .build().unwrap();
1669
1670 let mut buffer = Vec::new();
1671 unsigned_invoice.write(&mut buffer).unwrap();
1672
1673 assert_eq!(unsigned_invoice.bytes, buffer.as_slice());
1674 assert_eq!(unsigned_invoice.payer_metadata(), &encrypted_payment_id);
1675 assert_eq!(unsigned_invoice.offer_chains(), Some(vec![ChainHash::using_genesis_block(Network::Bitcoin)]));
1676 assert_eq!(unsigned_invoice.metadata(), None);
1677 assert_eq!(unsigned_invoice.amount(), Some(Amount::Bitcoin { amount_msats: 1000 }));
1678 assert_eq!(unsigned_invoice.description(), Some(PrintableString("")));
1679 assert_eq!(unsigned_invoice.offer_features(), Some(&OfferFeatures::empty()));
1680 assert_eq!(unsigned_invoice.absolute_expiry(), None);
1681 assert_eq!(unsigned_invoice.message_paths(), &[]);
1682 assert_eq!(unsigned_invoice.issuer(), None);
1683 assert_eq!(unsigned_invoice.supported_quantity(), Some(Quantity::One));
1684 assert_eq!(unsigned_invoice.signing_pubkey(), recipient_pubkey());
1685 assert_eq!(unsigned_invoice.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
1686 assert_eq!(unsigned_invoice.amount_msats(), 1000);
1687 assert_eq!(unsigned_invoice.invoice_request_features(), &InvoiceRequestFeatures::empty());
1688 assert_eq!(unsigned_invoice.quantity(), None);
1689 assert_eq!(unsigned_invoice.payer_note(), None);
1690 assert_eq!(unsigned_invoice.payment_paths(), payment_paths.as_slice());
1691 assert_eq!(unsigned_invoice.created_at(), now);
1692 assert_eq!(unsigned_invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
1693 #[cfg(feature = "std")]
1694 assert!(!unsigned_invoice.is_expired());
1695 assert_eq!(unsigned_invoice.payment_hash(), payment_hash);
1696 assert!(unsigned_invoice.fallbacks().is_empty());
1697 assert_eq!(unsigned_invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
1698
1699 match UnsignedBolt12Invoice::try_from(buffer) {
1700 Err(e) => panic!("error parsing unsigned invoice: {:?}", e),
1701 Ok(parsed) => {
1702 assert_eq!(parsed.bytes, unsigned_invoice.bytes);
1703 assert_eq!(parsed.tagged_hash, unsigned_invoice.tagged_hash);
1704 },
1705 }
1706
1707 #[cfg(c_bindings)]
1708 let mut unsigned_invoice = unsigned_invoice;
1709 let invoice = unsigned_invoice.sign(recipient_sign).unwrap();
1710
1711 let mut buffer = Vec::new();
1712 invoice.write(&mut buffer).unwrap();
1713
1714 assert_eq!(invoice.bytes, buffer.as_slice());
1715 assert_eq!(invoice.payer_metadata(), &encrypted_payment_id);
1716 assert_eq!(invoice.offer_chains(), Some(vec![ChainHash::using_genesis_block(Network::Bitcoin)]));
1717 assert_eq!(invoice.metadata(), None);
1718 assert_eq!(invoice.amount(), Some(Amount::Bitcoin { amount_msats: 1000 }));
1719 assert_eq!(invoice.description(), Some(PrintableString("")));
1720 assert_eq!(invoice.offer_features(), Some(&OfferFeatures::empty()));
1721 assert_eq!(invoice.absolute_expiry(), None);
1722 assert_eq!(invoice.message_paths(), &[]);
1723 assert_eq!(invoice.issuer(), None);
1724 assert_eq!(invoice.supported_quantity(), Some(Quantity::One));
1725 assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
1726 assert_eq!(invoice.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
1727 assert_eq!(invoice.amount_msats(), 1000);
1728 assert_eq!(invoice.invoice_request_features(), &InvoiceRequestFeatures::empty());
1729 assert_eq!(invoice.quantity(), None);
1730 assert_eq!(
1731 invoice.verify_using_payer_data(payment_id, nonce, &expanded_key, &secp_ctx),
1732 Ok(payment_id),
1733 );
1734 assert_eq!(invoice.payer_note(), None);
1735 assert_eq!(invoice.payment_paths(), payment_paths.as_slice());
1736 assert_eq!(invoice.created_at(), now);
1737 assert_eq!(invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
1738 #[cfg(feature = "std")]
1739 assert!(!invoice.is_expired());
1740 assert_eq!(invoice.payment_hash(), payment_hash);
1741 assert!(invoice.fallbacks().is_empty());
1742 assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
1743 assert!(!invoice.is_for_refund_without_paths());
1744
1745 let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice.bytes);
1746 assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
1747
1748 let digest = Message::from_digest(invoice.signable_hash());
1749 let pubkey = recipient_pubkey().into();
1750 let secp_ctx = Secp256k1::verification_only();
1751 assert!(secp_ctx.verify_schnorr(&invoice.signature, &digest, &pubkey).is_ok());
1752
1753 assert_eq!(
1754 invoice.as_tlv_stream(),
1755 (
1756 PayerTlvStreamRef { metadata: Some(&encrypted_payment_id.to_vec()) },
1757 OfferTlvStreamRef {
1758 chains: None,
1759 metadata: None,
1760 currency: None,
1761 amount: Some(1000),
1762 description: Some(&String::from("")),
1763 features: None,
1764 absolute_expiry: None,
1765 paths: None,
1766 issuer: None,
1767 quantity_max: None,
1768 issuer_id: Some(&recipient_pubkey()),
1769 },
1770 InvoiceRequestTlvStreamRef {
1771 chain: None,
1772 amount: None,
1773 features: None,
1774 quantity: None,
1775 payer_id: Some(&invoice.payer_signing_pubkey()),
1776 payer_note: None,
1777 paths: None,
1778 offer_from_hrn: None,
1779 },
1780 InvoiceTlvStreamRef {
1781 paths: Some(Iterable(payment_paths.iter().map(|path| path.inner_blinded_path()))),
1782 blindedpay: Some(Iterable(payment_paths.iter().map(|path| &path.payinfo))),
1783 created_at: Some(now.as_secs()),
1784 relative_expiry: None,
1785 payment_hash: Some(&payment_hash),
1786 amount: Some(1000),
1787 fallbacks: None,
1788 features: None,
1789 node_id: Some(&recipient_pubkey()),
1790 message_paths: None,
1791 },
1792 SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
1793 ExperimentalOfferTlvStreamRef {
1794 experimental_foo: None,
1795 },
1796 ExperimentalInvoiceRequestTlvStreamRef {
1797 experimental_bar: None,
1798 },
1799 ExperimentalInvoiceTlvStreamRef {
1800 experimental_baz: None,
1801 },
1802 ),
1803 );
1804
1805 if let Err(e) = Bolt12Invoice::try_from(buffer) {
1806 panic!("error parsing invoice: {:?}", e);
1807 }
1808 }
1809
1810 #[test]
1811 fn builds_invoice_for_refund_with_defaults() {
1812 let payment_paths = payment_paths();
1813 let payment_hash = payment_hash();
1814 let now = now();
1815 let invoice = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
1816 .build().unwrap()
1817 .respond_with_no_std(payment_paths.clone(), payment_hash, recipient_pubkey(), now)
1818 .unwrap()
1819 .build().unwrap()
1820 .sign(recipient_sign).unwrap();
1821
1822 let mut buffer = Vec::new();
1823 invoice.write(&mut buffer).unwrap();
1824
1825 assert_eq!(invoice.bytes, buffer.as_slice());
1826 assert_eq!(invoice.payer_metadata(), &[1; 32]);
1827 assert_eq!(invoice.offer_chains(), None);
1828 assert_eq!(invoice.metadata(), None);
1829 assert_eq!(invoice.amount(), None);
1830 assert_eq!(invoice.description(), Some(PrintableString("")));
1831 assert_eq!(invoice.offer_features(), None);
1832 assert_eq!(invoice.absolute_expiry(), None);
1833 assert_eq!(invoice.message_paths(), &[]);
1834 assert_eq!(invoice.issuer(), None);
1835 assert_eq!(invoice.supported_quantity(), None);
1836 assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
1837 assert_eq!(invoice.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
1838 assert_eq!(invoice.amount_msats(), 1000);
1839 assert_eq!(invoice.invoice_request_features(), &InvoiceRequestFeatures::empty());
1840 assert_eq!(invoice.quantity(), None);
1841 assert_eq!(invoice.payer_signing_pubkey(), payer_pubkey());
1842 assert_eq!(invoice.payer_note(), None);
1843 assert_eq!(invoice.payment_paths(), payment_paths.as_slice());
1844 assert_eq!(invoice.created_at(), now);
1845 assert_eq!(invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
1846 #[cfg(feature = "std")]
1847 assert!(!invoice.is_expired());
1848 assert_eq!(invoice.payment_hash(), payment_hash);
1849 assert!(invoice.fallbacks().is_empty());
1850 assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
1851 assert!(invoice.is_for_refund_without_paths());
1852
1853 let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice.bytes);
1854 assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
1855
1856 assert_eq!(
1857 invoice.as_tlv_stream(),
1858 (
1859 PayerTlvStreamRef { metadata: Some(&vec![1; 32]) },
1860 OfferTlvStreamRef {
1861 chains: None,
1862 metadata: None,
1863 currency: None,
1864 amount: None,
1865 description: Some(&String::from("")),
1866 features: None,
1867 absolute_expiry: None,
1868 paths: None,
1869 issuer: None,
1870 quantity_max: None,
1871 issuer_id: None,
1872 },
1873 InvoiceRequestTlvStreamRef {
1874 chain: None,
1875 amount: Some(1000),
1876 features: None,
1877 quantity: None,
1878 payer_id: Some(&payer_pubkey()),
1879 payer_note: None,
1880 paths: None,
1881 offer_from_hrn: None,
1882 },
1883 InvoiceTlvStreamRef {
1884 paths: Some(Iterable(payment_paths.iter().map(|path| path.inner_blinded_path()))),
1885 blindedpay: Some(Iterable(payment_paths.iter().map(|path| &path.payinfo))),
1886 created_at: Some(now.as_secs()),
1887 relative_expiry: None,
1888 payment_hash: Some(&payment_hash),
1889 amount: Some(1000),
1890 fallbacks: None,
1891 features: None,
1892 node_id: Some(&recipient_pubkey()),
1893 message_paths: None,
1894 },
1895 SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
1896 ExperimentalOfferTlvStreamRef {
1897 experimental_foo: None,
1898 },
1899 ExperimentalInvoiceRequestTlvStreamRef {
1900 experimental_bar: None,
1901 },
1902 ExperimentalInvoiceTlvStreamRef {
1903 experimental_baz: None,
1904 },
1905 ),
1906 );
1907
1908 if let Err(e) = Bolt12Invoice::try_from(buffer) {
1909 panic!("error parsing invoice: {:?}", e);
1910 }
1911 }
1912
1913 #[cfg(feature = "std")]
1914 #[test]
1915 fn builds_invoice_from_offer_with_expiration() {
1916 let expanded_key = ExpandedKey::new([42; 32]);
1917 let entropy = FixedEntropy {};
1918 let nonce = Nonce::from_entropy_source(&entropy);
1919 let secp_ctx = Secp256k1::new();
1920 let payment_id = PaymentId([1; 32]);
1921
1922 let future_expiry = Duration::from_secs(u64::max_value());
1923 let past_expiry = Duration::from_secs(0);
1924
1925 if let Err(e) = OfferBuilder::new(recipient_pubkey())
1926 .amount_msats(1000)
1927 .absolute_expiry(future_expiry)
1928 .build().unwrap()
1929 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1930 .build_and_sign().unwrap()
1931 .respond_with(payment_paths(), payment_hash())
1932 .unwrap()
1933 .build()
1934 {
1935 panic!("error building invoice: {:?}", e);
1936 }
1937
1938 match OfferBuilder::new(recipient_pubkey())
1939 .amount_msats(1000)
1940 .absolute_expiry(past_expiry)
1941 .build().unwrap()
1942 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1943 .build_unchecked_and_sign()
1944 .respond_with(payment_paths(), payment_hash())
1945 .unwrap()
1946 .build()
1947 {
1948 Ok(_) => panic!("expected error"),
1949 Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
1950 }
1951 }
1952
1953 #[cfg(feature = "std")]
1954 #[test]
1955 fn builds_invoice_from_refund_with_expiration() {
1956 let future_expiry = Duration::from_secs(u64::max_value());
1957 let past_expiry = Duration::from_secs(0);
1958
1959 if let Err(e) = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
1960 .absolute_expiry(future_expiry)
1961 .build().unwrap()
1962 .respond_with(payment_paths(), payment_hash(), recipient_pubkey())
1963 .unwrap()
1964 .build()
1965 {
1966 panic!("error building invoice: {:?}", e);
1967 }
1968
1969 match RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
1970 .absolute_expiry(past_expiry)
1971 .build().unwrap()
1972 .respond_with(payment_paths(), payment_hash(), recipient_pubkey())
1973 .unwrap()
1974 .build()
1975 {
1976 Ok(_) => panic!("expected error"),
1977 Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
1978 }
1979 }
1980
1981 #[test]
1982 fn builds_invoice_from_offer_using_derived_keys() {
1983 let node_id = recipient_pubkey();
1984 let expanded_key = ExpandedKey::new([42; 32]);
1985 let entropy = FixedEntropy {};
1986 let nonce = Nonce::from_entropy_source(&entropy);
1987 let secp_ctx = Secp256k1::new();
1988 let payment_id = PaymentId([1; 32]);
1989
1990 let blinded_path = BlindedMessagePath::from_raw(
1991 pubkey(40), pubkey(41),
1992 vec![
1993 BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
1994 BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
1995 ]
1996 );
1997
1998 #[cfg(c_bindings)]
1999 use crate::offers::offer::OfferWithDerivedMetadataBuilder as OfferBuilder;
2000 let invoice_request = OfferBuilder
2001 ::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
2002 .amount_msats(1000)
2003 .path(blinded_path)
2004 .experimental_foo(42)
2005 .build().unwrap()
2006 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2007 .build_and_sign().unwrap();
2008
2009 if let Err(e) = invoice_request.clone()
2010 .verify_using_recipient_data(nonce, &expanded_key, &secp_ctx).unwrap()
2011 .respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now()).unwrap()
2012 .build_and_sign(&secp_ctx)
2013 {
2014 panic!("error building invoice: {:?}", e);
2015 }
2016
2017 let expanded_key = ExpandedKey::new([41; 32]);
2018 assert!(
2019 invoice_request.verify_using_recipient_data(nonce, &expanded_key, &secp_ctx).is_err()
2020 );
2021
2022 let invoice_request = OfferBuilder
2023 ::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
2024 .amount_msats(1000)
2025 .experimental_foo(42)
2027 .build().unwrap()
2028 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2029 .build_and_sign().unwrap();
2030
2031 match invoice_request
2032 .verify_using_metadata(&expanded_key, &secp_ctx).unwrap()
2033 .respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now())
2034 {
2035 Ok(_) => panic!("expected error"),
2036 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
2037 }
2038 }
2039
2040 #[test]
2041 fn builds_invoice_from_refund_using_derived_keys() {
2042 let expanded_key = ExpandedKey::new([42; 32]);
2043 let entropy = FixedEntropy {};
2044 let secp_ctx = Secp256k1::new();
2045
2046 let refund = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
2047 .experimental_foo(42)
2048 .build().unwrap();
2049
2050 if let Err(e) = refund
2051 .respond_using_derived_keys_no_std(
2052 payment_paths(), payment_hash(), now(), &expanded_key, &entropy
2053 )
2054 .unwrap()
2055 .build_and_sign(&secp_ctx)
2056 {
2057 panic!("error building invoice: {:?}", e);
2058 }
2059 }
2060
2061 #[test]
2062 fn builds_invoice_from_refund_with_path() {
2063 let node_id = payer_pubkey();
2064 let expanded_key = ExpandedKey::new([42; 32]);
2065 let entropy = FixedEntropy {};
2066 let secp_ctx = Secp256k1::new();
2067
2068 let blinded_path = BlindedMessagePath::from_raw(
2069 pubkey(40), pubkey(41),
2070 vec![
2071 BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
2072 BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
2073 ]
2074 );
2075
2076 let refund = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
2077 .path(blinded_path)
2078 .build().unwrap();
2079
2080 let invoice = refund
2081 .respond_using_derived_keys_no_std(
2082 payment_paths(), payment_hash(), now(), &expanded_key, &entropy
2083 )
2084 .unwrap()
2085 .build_and_sign(&secp_ctx)
2086 .unwrap();
2087 assert!(!invoice.message_paths().is_empty());
2088 assert!(!invoice.is_for_refund_without_paths());
2089 }
2090
2091 #[test]
2092 fn builds_invoice_with_relative_expiry() {
2093 let expanded_key = ExpandedKey::new([42; 32]);
2094 let entropy = FixedEntropy {};
2095 let nonce = Nonce::from_entropy_source(&entropy);
2096 let secp_ctx = Secp256k1::new();
2097 let payment_id = PaymentId([1; 32]);
2098
2099 let now = now();
2100 let one_hour = Duration::from_secs(3600);
2101
2102 let invoice = OfferBuilder::new(recipient_pubkey())
2103 .amount_msats(1000)
2104 .build().unwrap()
2105 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2106 .build_and_sign().unwrap()
2107 .respond_with_no_std(payment_paths(), payment_hash(), now).unwrap()
2108 .relative_expiry(one_hour.as_secs() as u32)
2109 .build().unwrap()
2110 .sign(recipient_sign).unwrap();
2111 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2112 #[cfg(feature = "std")]
2113 assert!(!invoice.is_expired());
2114 assert_eq!(invoice.relative_expiry(), one_hour);
2115 assert_eq!(tlv_stream.relative_expiry, Some(one_hour.as_secs() as u32));
2116
2117 let invoice = OfferBuilder::new(recipient_pubkey())
2118 .amount_msats(1000)
2119 .build().unwrap()
2120 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2121 .build_and_sign().unwrap()
2122 .respond_with_no_std(payment_paths(), payment_hash(), now - one_hour).unwrap()
2123 .relative_expiry(one_hour.as_secs() as u32 - 1)
2124 .build().unwrap()
2125 .sign(recipient_sign).unwrap();
2126 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2127 #[cfg(feature = "std")]
2128 assert!(invoice.is_expired());
2129 assert_eq!(invoice.relative_expiry(), one_hour - Duration::from_secs(1));
2130 assert_eq!(tlv_stream.relative_expiry, Some(one_hour.as_secs() as u32 - 1));
2131 }
2132
2133 #[test]
2134 fn builds_invoice_with_amount_from_request() {
2135 let expanded_key = ExpandedKey::new([42; 32]);
2136 let entropy = FixedEntropy {};
2137 let nonce = Nonce::from_entropy_source(&entropy);
2138 let secp_ctx = Secp256k1::new();
2139 let payment_id = PaymentId([1; 32]);
2140
2141 let invoice = OfferBuilder::new(recipient_pubkey())
2142 .amount_msats(1000)
2143 .build().unwrap()
2144 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2145 .amount_msats(1001).unwrap()
2146 .build_and_sign().unwrap()
2147 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2148 .build().unwrap()
2149 .sign(recipient_sign).unwrap();
2150 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2151 assert_eq!(invoice.amount_msats(), 1001);
2152 assert_eq!(tlv_stream.amount, Some(1001));
2153 }
2154
2155 #[test]
2156 fn builds_invoice_with_quantity_from_request() {
2157 let expanded_key = ExpandedKey::new([42; 32]);
2158 let entropy = FixedEntropy {};
2159 let nonce = Nonce::from_entropy_source(&entropy);
2160 let secp_ctx = Secp256k1::new();
2161 let payment_id = PaymentId([1; 32]);
2162
2163 let invoice = OfferBuilder::new(recipient_pubkey())
2164 .amount_msats(1000)
2165 .supported_quantity(Quantity::Unbounded)
2166 .build().unwrap()
2167 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2168 .quantity(2).unwrap()
2169 .build_and_sign().unwrap()
2170 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2171 .build().unwrap()
2172 .sign(recipient_sign).unwrap();
2173 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2174 assert_eq!(invoice.amount_msats(), 2000);
2175 assert_eq!(tlv_stream.amount, Some(2000));
2176
2177 match OfferBuilder::new(recipient_pubkey())
2178 .amount_msats(1000)
2179 .supported_quantity(Quantity::Unbounded)
2180 .build().unwrap()
2181 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2182 .quantity(u64::max_value()).unwrap()
2183 .build_unchecked_and_sign()
2184 .respond_with_no_std(payment_paths(), payment_hash(), now())
2185 {
2186 Ok(_) => panic!("expected error"),
2187 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
2188 }
2189 }
2190
2191 #[test]
2192 fn builds_invoice_with_fallback_address() {
2193 let expanded_key = ExpandedKey::new([42; 32]);
2194 let entropy = FixedEntropy {};
2195 let nonce = Nonce::from_entropy_source(&entropy);
2196 let secp_ctx = Secp256k1::new();
2197 let payment_id = PaymentId([1; 32]);
2198
2199 let script = ScriptBuf::new();
2200 let pubkey = bitcoin::key::PublicKey::new(recipient_pubkey());
2201 let x_only_pubkey = XOnlyPublicKey::from_keypair(&recipient_keys()).0;
2202 let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(x_only_pubkey);
2203
2204 let invoice = OfferBuilder::new(recipient_pubkey())
2205 .amount_msats(1000)
2206 .build().unwrap()
2207 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2208 .build_and_sign().unwrap()
2209 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2210 .fallback_v0_p2wsh(&script.wscript_hash())
2211 .fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
2212 .fallback_v1_p2tr_tweaked(&tweaked_pubkey)
2213 .build().unwrap()
2214 .sign(recipient_sign).unwrap();
2215 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2216 assert_eq!(
2217 invoice.fallbacks(),
2218 vec![
2219 Address::p2wsh(&script, Network::Bitcoin),
2220 Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin),
2221 Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
2222 ],
2223 );
2224 assert_eq!(
2225 tlv_stream.fallbacks,
2226 Some(&vec![
2227 FallbackAddress {
2228 version: WitnessVersion::V0.to_num(),
2229 program: Vec::from(script.wscript_hash().to_byte_array()),
2230 },
2231 FallbackAddress {
2232 version: WitnessVersion::V0.to_num(),
2233 program: Vec::from(pubkey.wpubkey_hash().unwrap().to_byte_array()),
2234 },
2235 FallbackAddress {
2236 version: WitnessVersion::V1.to_num(),
2237 program: Vec::from(&tweaked_pubkey.serialize()[..]),
2238 },
2239 ])
2240 );
2241 }
2242
2243 #[test]
2244 fn builds_invoice_with_allow_mpp() {
2245 let expanded_key = ExpandedKey::new([42; 32]);
2246 let entropy = FixedEntropy {};
2247 let nonce = Nonce::from_entropy_source(&entropy);
2248 let secp_ctx = Secp256k1::new();
2249 let payment_id = PaymentId([1; 32]);
2250
2251 let mut features = Bolt12InvoiceFeatures::empty();
2252 features.set_basic_mpp_optional();
2253
2254 let invoice = OfferBuilder::new(recipient_pubkey())
2255 .amount_msats(1000)
2256 .build().unwrap()
2257 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2258 .build_and_sign().unwrap()
2259 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2260 .allow_mpp()
2261 .build().unwrap()
2262 .sign(recipient_sign).unwrap();
2263 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2264 assert_eq!(invoice.invoice_features(), &features);
2265 assert_eq!(tlv_stream.features, Some(&features));
2266 }
2267
2268 #[test]
2269 fn fails_signing_invoice() {
2270 let expanded_key = ExpandedKey::new([42; 32]);
2271 let entropy = FixedEntropy {};
2272 let nonce = Nonce::from_entropy_source(&entropy);
2273 let secp_ctx = Secp256k1::new();
2274 let payment_id = PaymentId([1; 32]);
2275
2276 match OfferBuilder::new(recipient_pubkey())
2277 .amount_msats(1000)
2278 .build().unwrap()
2279 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2280 .build_and_sign().unwrap()
2281 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2282 .build().unwrap()
2283 .sign(fail_sign)
2284 {
2285 Ok(_) => panic!("expected error"),
2286 Err(e) => assert_eq!(e, SignError::Signing),
2287 }
2288
2289 match OfferBuilder::new(recipient_pubkey())
2290 .amount_msats(1000)
2291 .build().unwrap()
2292 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2293 .build_and_sign().unwrap()
2294 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2295 .build().unwrap()
2296 .sign(payer_sign)
2297 {
2298 Ok(_) => panic!("expected error"),
2299 Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::IncorrectSignature)),
2300 }
2301 }
2302
2303 #[test]
2304 fn parses_invoice_with_payment_paths() {
2305 let expanded_key = ExpandedKey::new([42; 32]);
2306 let entropy = FixedEntropy {};
2307 let nonce = Nonce::from_entropy_source(&entropy);
2308 let secp_ctx = Secp256k1::new();
2309 let payment_id = PaymentId([1; 32]);
2310
2311 let invoice = OfferBuilder::new(recipient_pubkey())
2312 .amount_msats(1000)
2313 .build().unwrap()
2314 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2315 .build_and_sign().unwrap()
2316 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2317 .build().unwrap()
2318 .sign(recipient_sign).unwrap();
2319
2320 let mut buffer = Vec::new();
2321 invoice.write(&mut buffer).unwrap();
2322
2323 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2324 panic!("error parsing invoice: {:?}", e);
2325 }
2326
2327 let mut tlv_stream = invoice.as_tlv_stream();
2328 tlv_stream.3.paths = None;
2329
2330 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2331 Ok(_) => panic!("expected error"),
2332 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)),
2333 }
2334
2335 let mut tlv_stream = invoice.as_tlv_stream();
2336 tlv_stream.3.blindedpay = None;
2337
2338 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2339 Ok(_) => panic!("expected error"),
2340 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)),
2341 }
2342
2343 let empty_payment_paths = vec![];
2344 let mut tlv_stream = invoice.as_tlv_stream();
2345 tlv_stream.3.paths = Some(Iterable(empty_payment_paths.iter().map(|path| path.inner_blinded_path())));
2346
2347 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2348 Ok(_) => panic!("expected error"),
2349 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)),
2350 }
2351
2352 let mut payment_paths = payment_paths();
2353 payment_paths.pop();
2354 let mut tlv_stream = invoice.as_tlv_stream();
2355 tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|path| &path.payinfo)));
2356
2357 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2358 Ok(_) => panic!("expected error"),
2359 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)),
2360 }
2361 }
2362
2363 #[test]
2364 fn parses_invoice_with_created_at() {
2365 let expanded_key = ExpandedKey::new([42; 32]);
2366 let entropy = FixedEntropy {};
2367 let nonce = Nonce::from_entropy_source(&entropy);
2368 let secp_ctx = Secp256k1::new();
2369 let payment_id = PaymentId([1; 32]);
2370
2371 let invoice = OfferBuilder::new(recipient_pubkey())
2372 .amount_msats(1000)
2373 .build().unwrap()
2374 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2375 .build_and_sign().unwrap()
2376 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2377 .build().unwrap()
2378 .sign(recipient_sign).unwrap();
2379
2380 let mut buffer = Vec::new();
2381 invoice.write(&mut buffer).unwrap();
2382
2383 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2384 panic!("error parsing invoice: {:?}", e);
2385 }
2386
2387 let mut tlv_stream = invoice.as_tlv_stream();
2388 tlv_stream.3.created_at = None;
2389
2390 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2391 Ok(_) => panic!("expected error"),
2392 Err(e) => {
2393 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingCreationTime));
2394 },
2395 }
2396 }
2397
2398 #[test]
2399 fn parses_invoice_with_relative_expiry() {
2400 let expanded_key = ExpandedKey::new([42; 32]);
2401 let entropy = FixedEntropy {};
2402 let nonce = Nonce::from_entropy_source(&entropy);
2403 let secp_ctx = Secp256k1::new();
2404 let payment_id = PaymentId([1; 32]);
2405
2406 let invoice = OfferBuilder::new(recipient_pubkey())
2407 .amount_msats(1000)
2408 .build().unwrap()
2409 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2410 .build_and_sign().unwrap()
2411 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2412 .relative_expiry(3600)
2413 .build().unwrap()
2414 .sign(recipient_sign).unwrap();
2415
2416 let mut buffer = Vec::new();
2417 invoice.write(&mut buffer).unwrap();
2418
2419 match Bolt12Invoice::try_from(buffer) {
2420 Ok(invoice) => assert_eq!(invoice.relative_expiry(), Duration::from_secs(3600)),
2421 Err(e) => panic!("error parsing invoice: {:?}", e),
2422 }
2423 }
2424
2425 #[test]
2426 fn parses_invoice_with_payment_hash() {
2427 let expanded_key = ExpandedKey::new([42; 32]);
2428 let entropy = FixedEntropy {};
2429 let nonce = Nonce::from_entropy_source(&entropy);
2430 let secp_ctx = Secp256k1::new();
2431 let payment_id = PaymentId([1; 32]);
2432
2433 let invoice = OfferBuilder::new(recipient_pubkey())
2434 .amount_msats(1000)
2435 .build().unwrap()
2436 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2437 .build_and_sign().unwrap()
2438 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2439 .build().unwrap()
2440 .sign(recipient_sign).unwrap();
2441
2442 let mut buffer = Vec::new();
2443 invoice.write(&mut buffer).unwrap();
2444
2445 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2446 panic!("error parsing invoice: {:?}", e);
2447 }
2448
2449 let mut tlv_stream = invoice.as_tlv_stream();
2450 tlv_stream.3.payment_hash = None;
2451
2452 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2453 Ok(_) => panic!("expected error"),
2454 Err(e) => {
2455 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaymentHash));
2456 },
2457 }
2458 }
2459
2460 #[test]
2461 fn parses_invoice_with_amount() {
2462 let expanded_key = ExpandedKey::new([42; 32]);
2463 let entropy = FixedEntropy {};
2464 let nonce = Nonce::from_entropy_source(&entropy);
2465 let secp_ctx = Secp256k1::new();
2466 let payment_id = PaymentId([1; 32]);
2467
2468 let invoice = OfferBuilder::new(recipient_pubkey())
2469 .amount_msats(1000)
2470 .build().unwrap()
2471 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2472 .build_and_sign().unwrap()
2473 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2474 .build().unwrap()
2475 .sign(recipient_sign).unwrap();
2476
2477 let mut buffer = Vec::new();
2478 invoice.write(&mut buffer).unwrap();
2479
2480 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2481 panic!("error parsing invoice: {:?}", e);
2482 }
2483
2484 let mut tlv_stream = invoice.as_tlv_stream();
2485 tlv_stream.3.amount = None;
2486
2487 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2488 Ok(_) => panic!("expected error"),
2489 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)),
2490 }
2491 }
2492
2493 #[test]
2494 fn parses_invoice_with_allow_mpp() {
2495 let expanded_key = ExpandedKey::new([42; 32]);
2496 let entropy = FixedEntropy {};
2497 let nonce = Nonce::from_entropy_source(&entropy);
2498 let secp_ctx = Secp256k1::new();
2499 let payment_id = PaymentId([1; 32]);
2500
2501 let invoice = OfferBuilder::new(recipient_pubkey())
2502 .amount_msats(1000)
2503 .build().unwrap()
2504 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2505 .build_and_sign().unwrap()
2506 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2507 .allow_mpp()
2508 .build().unwrap()
2509 .sign(recipient_sign).unwrap();
2510
2511 let mut buffer = Vec::new();
2512 invoice.write(&mut buffer).unwrap();
2513
2514 match Bolt12Invoice::try_from(buffer) {
2515 Ok(invoice) => {
2516 let mut features = Bolt12InvoiceFeatures::empty();
2517 features.set_basic_mpp_optional();
2518 assert_eq!(invoice.invoice_features(), &features);
2519 },
2520 Err(e) => panic!("error parsing invoice: {:?}", e),
2521 }
2522 }
2523
2524 #[test]
2525 fn parses_invoice_with_fallback_address() {
2526 let expanded_key = ExpandedKey::new([42; 32]);
2527 let entropy = FixedEntropy {};
2528 let nonce = Nonce::from_entropy_source(&entropy);
2529 let secp_ctx = Secp256k1::new();
2530 let payment_id = PaymentId([1; 32]);
2531
2532 let script = ScriptBuf::new();
2533 let pubkey = bitcoin::key::PublicKey::new(recipient_pubkey());
2534 let x_only_pubkey = XOnlyPublicKey::from_keypair(&recipient_keys()).0;
2535 let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(x_only_pubkey);
2536
2537 let invoice_request = OfferBuilder::new(recipient_pubkey())
2538 .amount_msats(1000)
2539 .build().unwrap()
2540 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2541 .build_and_sign().unwrap();
2542 #[cfg(not(c_bindings))]
2543 let invoice_builder = invoice_request
2544 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap();
2545 #[cfg(c_bindings)]
2546 let mut invoice_builder = invoice_request
2547 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap();
2548 let invoice_builder = invoice_builder
2549 .fallback_v0_p2wsh(&script.wscript_hash())
2550 .fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
2551 .fallback_v1_p2tr_tweaked(&tweaked_pubkey);
2552 #[cfg(not(c_bindings))]
2553 let mut invoice_builder = invoice_builder;
2554
2555 let fallbacks = invoice_builder.invoice.fields_mut().fallbacks.as_mut().unwrap();
2557 fallbacks.push(FallbackAddress { version: 1, program: vec![0u8; 41] });
2559 fallbacks.push(FallbackAddress { version: 2, program: vec![0u8; 1] });
2560 fallbacks.push(FallbackAddress { version: 17, program: vec![0u8; 40] });
2561 fallbacks.push(FallbackAddress { version: 1, program: vec![0u8; 33] });
2563 fallbacks.push(FallbackAddress { version: 2, program: vec![0u8; 40] });
2564
2565 let invoice = invoice_builder.build().unwrap().sign(recipient_sign).unwrap();
2566 let mut buffer = Vec::new();
2567 invoice.write(&mut buffer).unwrap();
2568
2569 match Bolt12Invoice::try_from(buffer) {
2570 Ok(invoice) => {
2571 let v1_witness_program = WitnessProgram::new(WitnessVersion::V1, &[0u8; 33]).unwrap();
2572 let v2_witness_program = WitnessProgram::new(WitnessVersion::V2, &[0u8; 40]).unwrap();
2573 assert_eq!(
2574 invoice.fallbacks(),
2575 vec![
2576 Address::p2wsh(&script, Network::Bitcoin),
2577 Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin),
2578 Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
2579 Address::from_witness_program(v1_witness_program, Network::Bitcoin),
2580 Address::from_witness_program(v2_witness_program, Network::Bitcoin),
2581 ],
2582 );
2583 },
2584 Err(e) => panic!("error parsing invoice: {:?}", e),
2585 }
2586 }
2587
2588 #[test]
2589 fn parses_invoice_with_node_id() {
2590 let expanded_key = ExpandedKey::new([42; 32]);
2591 let entropy = FixedEntropy {};
2592 let nonce = Nonce::from_entropy_source(&entropy);
2593 let secp_ctx = Secp256k1::new();
2594 let payment_id = PaymentId([1; 32]);
2595
2596 let invoice = OfferBuilder::new(recipient_pubkey())
2597 .amount_msats(1000)
2598 .build().unwrap()
2599 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2600 .build_and_sign().unwrap()
2601 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2602 .build().unwrap()
2603 .sign(recipient_sign).unwrap();
2604
2605 let mut buffer = Vec::new();
2606 invoice.write(&mut buffer).unwrap();
2607
2608 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2609 panic!("error parsing invoice: {:?}", e);
2610 }
2611
2612 let mut tlv_stream = invoice.as_tlv_stream();
2613 tlv_stream.3.node_id = None;
2614
2615 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2616 Ok(_) => panic!("expected error"),
2617 Err(e) => {
2618 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey));
2619 },
2620 }
2621
2622 let invalid_pubkey = payer_pubkey();
2623 let mut tlv_stream = invoice.as_tlv_stream();
2624 tlv_stream.3.node_id = Some(&invalid_pubkey);
2625
2626 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2627 Ok(_) => panic!("expected error"),
2628 Err(e) => {
2629 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey));
2630 },
2631 }
2632 }
2633
2634 #[test]
2635 fn parses_invoice_with_node_id_from_blinded_path() {
2636 let expanded_key = ExpandedKey::new([42; 32]);
2637 let entropy = FixedEntropy {};
2638 let nonce = Nonce::from_entropy_source(&entropy);
2639 let secp_ctx = Secp256k1::new();
2640 let payment_id = PaymentId([1; 32]);
2641
2642 let paths = vec![
2643 BlindedMessagePath::from_raw(
2644 pubkey(40), pubkey(41),
2645 vec![
2646 BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
2647 BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
2648 ]
2649 ),
2650 BlindedMessagePath::from_raw(
2651 pubkey(40), pubkey(41),
2652 vec![
2653 BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
2654 BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
2655 ]
2656 ),
2657 ];
2658
2659 let blinded_node_id_sign = |message: &UnsignedBolt12Invoice| {
2660 let secp_ctx = Secp256k1::new();
2661 let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[46; 32]).unwrap());
2662 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2663 };
2664
2665 let invoice = OfferBuilder::new(recipient_pubkey())
2666 .clear_issuer_signing_pubkey()
2667 .amount_msats(1000)
2668 .path(paths[0].clone())
2669 .path(paths[1].clone())
2670 .build().unwrap()
2671 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2672 .build_and_sign().unwrap()
2673 .respond_with_no_std_using_signing_pubkey(
2674 payment_paths(), payment_hash(), now(), pubkey(46)
2675 ).unwrap()
2676 .build().unwrap()
2677 .sign(blinded_node_id_sign).unwrap();
2678
2679 let mut buffer = Vec::new();
2680 invoice.write(&mut buffer).unwrap();
2681
2682 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2683 panic!("error parsing invoice: {:?}", e);
2684 }
2685
2686 let invoice = OfferBuilder::new(recipient_pubkey())
2687 .clear_issuer_signing_pubkey()
2688 .amount_msats(1000)
2689 .path(paths[0].clone())
2690 .path(paths[1].clone())
2691 .build().unwrap()
2692 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2693 .build_and_sign().unwrap()
2694 .respond_with_no_std_using_signing_pubkey(
2695 payment_paths(), payment_hash(), now(), recipient_pubkey()
2696 ).unwrap()
2697 .build().unwrap()
2698 .sign(recipient_sign).unwrap();
2699
2700 let mut buffer = Vec::new();
2701 invoice.write(&mut buffer).unwrap();
2702
2703 match Bolt12Invoice::try_from(buffer) {
2704 Ok(_) => panic!("expected error"),
2705 Err(e) => {
2706 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey));
2707 },
2708 }
2709 }
2710
2711 #[test]
2712 fn fails_parsing_invoice_with_wrong_amount() {
2713 let expanded_key = ExpandedKey::new([42; 32]);
2714 let entropy = FixedEntropy {};
2715 let nonce = Nonce::from_entropy_source(&entropy);
2716 let secp_ctx = Secp256k1::new();
2717 let payment_id = PaymentId([1; 32]);
2718
2719 let invoice = OfferBuilder::new(recipient_pubkey())
2720 .amount_msats(1000)
2721 .build().unwrap()
2722 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2723 .build_and_sign().unwrap()
2724 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2725 .amount_msats_unchecked(2000)
2726 .build().unwrap()
2727 .sign(recipient_sign).unwrap();
2728
2729 let mut buffer = Vec::new();
2730 invoice.write(&mut buffer).unwrap();
2731
2732 match Bolt12Invoice::try_from(buffer) {
2733 Ok(_) => panic!("expected error"),
2734 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)),
2735 }
2736
2737 let invoice = OfferBuilder::new(recipient_pubkey())
2738 .amount_msats(1000)
2739 .build().unwrap()
2740 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2741 .amount_msats(1000).unwrap()
2742 .build_and_sign().unwrap()
2743 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2744 .amount_msats_unchecked(2000)
2745 .build().unwrap()
2746 .sign(recipient_sign).unwrap();
2747
2748 let mut buffer = Vec::new();
2749 invoice.write(&mut buffer).unwrap();
2750
2751 match Bolt12Invoice::try_from(buffer) {
2752 Ok(_) => panic!("expected error"),
2753 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)),
2754 }
2755
2756 let invoice = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
2757 .build().unwrap()
2758 .respond_using_derived_keys_no_std(
2759 payment_paths(), payment_hash(), now(), &expanded_key, &entropy
2760 )
2761 .unwrap()
2762 .amount_msats_unchecked(2000)
2763 .build_and_sign(&secp_ctx).unwrap();
2764
2765 let mut buffer = Vec::new();
2766 invoice.write(&mut buffer).unwrap();
2767
2768 match Bolt12Invoice::try_from(buffer) {
2769 Ok(_) => panic!("expected error"),
2770 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)),
2771 }
2772 }
2773
2774 #[test]
2775 fn fails_parsing_invoice_without_signature() {
2776 let expanded_key = ExpandedKey::new([42; 32]);
2777 let entropy = FixedEntropy {};
2778 let nonce = Nonce::from_entropy_source(&entropy);
2779 let secp_ctx = Secp256k1::new();
2780 let payment_id = PaymentId([1; 32]);
2781
2782 let mut buffer = Vec::new();
2783 OfferBuilder::new(recipient_pubkey())
2784 .amount_msats(1000)
2785 .build().unwrap()
2786 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2787 .build_and_sign().unwrap()
2788 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2789 .build().unwrap()
2790 .contents
2791 .write(&mut buffer).unwrap();
2792
2793 match Bolt12Invoice::try_from(buffer) {
2794 Ok(_) => panic!("expected error"),
2795 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
2796 }
2797 }
2798
2799 #[test]
2800 fn fails_parsing_invoice_with_invalid_signature() {
2801 let expanded_key = ExpandedKey::new([42; 32]);
2802 let entropy = FixedEntropy {};
2803 let nonce = Nonce::from_entropy_source(&entropy);
2804 let secp_ctx = Secp256k1::new();
2805 let payment_id = PaymentId([1; 32]);
2806
2807 let mut invoice = OfferBuilder::new(recipient_pubkey())
2808 .amount_msats(1000)
2809 .build().unwrap()
2810 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2811 .build_and_sign().unwrap()
2812 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2813 .build().unwrap()
2814 .sign(recipient_sign).unwrap();
2815 let last_signature_byte = invoice.bytes.last_mut().unwrap();
2816 *last_signature_byte = last_signature_byte.wrapping_add(1);
2817
2818 let mut buffer = Vec::new();
2819 invoice.write(&mut buffer).unwrap();
2820
2821 match Bolt12Invoice::try_from(buffer) {
2822 Ok(_) => panic!("expected error"),
2823 Err(e) => {
2824 assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature));
2825 },
2826 }
2827 }
2828
2829 #[test]
2830 fn parses_invoice_with_unknown_tlv_records() {
2831 let expanded_key = ExpandedKey::new([42; 32]);
2832 let entropy = FixedEntropy {};
2833 let nonce = Nonce::from_entropy_source(&entropy);
2834 let payment_id = PaymentId([1; 32]);
2835
2836 const UNKNOWN_ODD_TYPE: u64 = INVOICE_TYPES.end - 1;
2837 assert!(UNKNOWN_ODD_TYPE % 2 == 1);
2838
2839 let secp_ctx = Secp256k1::new();
2840 let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2841 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
2842 .amount_msats(1000)
2843 .build().unwrap()
2844 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2845 .build_and_sign().unwrap()
2846 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2847 .build().unwrap();
2848
2849 let mut unknown_bytes = Vec::new();
2850 BigSize(UNKNOWN_ODD_TYPE).write(&mut unknown_bytes).unwrap();
2851 BigSize(32).write(&mut unknown_bytes).unwrap();
2852 [42u8; 32].write(&mut unknown_bytes).unwrap();
2853
2854 unsigned_invoice.bytes.extend_from_slice(&unknown_bytes);
2855 unsigned_invoice.tagged_hash =
2856 TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &unsigned_invoice.bytes);
2857
2858 let invoice = unsigned_invoice
2859 .sign(|message: &UnsignedBolt12Invoice|
2860 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2861 )
2862 .unwrap();
2863
2864 let mut encoded_invoice = Vec::new();
2865 invoice.write(&mut encoded_invoice).unwrap();
2866
2867 match Bolt12Invoice::try_from(encoded_invoice.clone()) {
2868 Ok(invoice) => assert_eq!(invoice.bytes, encoded_invoice),
2869 Err(e) => panic!("error parsing invoice: {:?}", e),
2870 }
2871
2872 const UNKNOWN_EVEN_TYPE: u64 = INVOICE_TYPES.end - 2;
2873 assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
2874
2875 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
2876 .amount_msats(1000)
2877 .build().unwrap()
2878 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2879 .build_and_sign().unwrap()
2880 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2881 .build().unwrap();
2882
2883 let mut unknown_bytes = Vec::new();
2884 BigSize(UNKNOWN_EVEN_TYPE).write(&mut unknown_bytes).unwrap();
2885 BigSize(32).write(&mut unknown_bytes).unwrap();
2886 [42u8; 32].write(&mut unknown_bytes).unwrap();
2887
2888 unsigned_invoice.bytes.extend_from_slice(&unknown_bytes);
2889 unsigned_invoice.tagged_hash =
2890 TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &unsigned_invoice.bytes);
2891
2892 let invoice = unsigned_invoice
2893 .sign(|message: &UnsignedBolt12Invoice|
2894 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2895 )
2896 .unwrap();
2897
2898 let mut encoded_invoice = Vec::new();
2899 invoice.write(&mut encoded_invoice).unwrap();
2900
2901 match Bolt12Invoice::try_from(encoded_invoice) {
2902 Ok(_) => panic!("expected error"),
2903 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
2904 }
2905 }
2906
2907 #[test]
2908 fn parses_invoice_with_experimental_tlv_records() {
2909 let expanded_key = ExpandedKey::new([42; 32]);
2910 let entropy = FixedEntropy {};
2911 let nonce = Nonce::from_entropy_source(&entropy);
2912 let payment_id = PaymentId([1; 32]);
2913
2914 let secp_ctx = Secp256k1::new();
2915 let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2916 let invoice = OfferBuilder::new(keys.public_key())
2917 .amount_msats(1000)
2918 .build().unwrap()
2919 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2920 .build_and_sign().unwrap()
2921 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2922 .experimental_baz(42)
2923 .build().unwrap()
2924 .sign(|message: &UnsignedBolt12Invoice|
2925 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2926 )
2927 .unwrap();
2928
2929 let mut encoded_invoice = Vec::new();
2930 invoice.write(&mut encoded_invoice).unwrap();
2931
2932 assert!(Bolt12Invoice::try_from(encoded_invoice).is_ok());
2933
2934 const UNKNOWN_ODD_TYPE: u64 = EXPERIMENTAL_INVOICE_TYPES.start + 1;
2935 assert!(UNKNOWN_ODD_TYPE % 2 == 1);
2936
2937 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
2938 .amount_msats(1000)
2939 .build().unwrap()
2940 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2941 .build_and_sign().unwrap()
2942 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2943 .build().unwrap();
2944
2945 let mut unknown_bytes = Vec::new();
2946 BigSize(UNKNOWN_ODD_TYPE).write(&mut unknown_bytes).unwrap();
2947 BigSize(32).write(&mut unknown_bytes).unwrap();
2948 [42u8; 32].write(&mut unknown_bytes).unwrap();
2949
2950 unsigned_invoice.experimental_bytes.extend_from_slice(&unknown_bytes);
2951
2952 let tlv_stream = TlvStream::new(&unsigned_invoice.bytes)
2953 .chain(TlvStream::new(&unsigned_invoice.experimental_bytes));
2954 unsigned_invoice.tagged_hash = TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2955
2956 let invoice = unsigned_invoice
2957 .sign(|message: &UnsignedBolt12Invoice|
2958 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2959 )
2960 .unwrap();
2961
2962 let mut encoded_invoice = Vec::new();
2963 invoice.write(&mut encoded_invoice).unwrap();
2964
2965 match Bolt12Invoice::try_from(encoded_invoice.clone()) {
2966 Ok(invoice) => assert_eq!(invoice.bytes, encoded_invoice),
2967 Err(e) => panic!("error parsing invoice: {:?}", e),
2968 }
2969
2970 const UNKNOWN_EVEN_TYPE: u64 = EXPERIMENTAL_INVOICE_TYPES.start;
2971 assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
2972
2973 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
2974 .amount_msats(1000)
2975 .build().unwrap()
2976 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2977 .build_and_sign().unwrap()
2978 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2979 .build().unwrap();
2980
2981 let mut unknown_bytes = Vec::new();
2982 BigSize(UNKNOWN_EVEN_TYPE).write(&mut unknown_bytes).unwrap();
2983 BigSize(32).write(&mut unknown_bytes).unwrap();
2984 [42u8; 32].write(&mut unknown_bytes).unwrap();
2985
2986 unsigned_invoice.experimental_bytes.extend_from_slice(&unknown_bytes);
2987
2988 let tlv_stream = TlvStream::new(&unsigned_invoice.bytes)
2989 .chain(TlvStream::new(&unsigned_invoice.experimental_bytes));
2990 unsigned_invoice.tagged_hash = TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2991
2992 let invoice = unsigned_invoice
2993 .sign(|message: &UnsignedBolt12Invoice|
2994 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2995 )
2996 .unwrap();
2997
2998 let mut encoded_invoice = Vec::new();
2999 invoice.write(&mut encoded_invoice).unwrap();
3000
3001 match Bolt12Invoice::try_from(encoded_invoice) {
3002 Ok(_) => panic!("expected error"),
3003 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
3004 }
3005
3006 let invoice = OfferBuilder::new(keys.public_key())
3007 .amount_msats(1000)
3008 .build().unwrap()
3009 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
3010 .build_and_sign().unwrap()
3011 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
3012 .build().unwrap()
3013 .sign(|message: &UnsignedBolt12Invoice|
3014 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3015 )
3016 .unwrap();
3017
3018 let mut encoded_invoice = Vec::new();
3019 invoice.write(&mut encoded_invoice).unwrap();
3020
3021 BigSize(UNKNOWN_ODD_TYPE).write(&mut encoded_invoice).unwrap();
3022 BigSize(32).write(&mut encoded_invoice).unwrap();
3023 [42u8; 32].write(&mut encoded_invoice).unwrap();
3024
3025 match Bolt12Invoice::try_from(encoded_invoice) {
3026 Ok(_) => panic!("expected error"),
3027 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature)),
3028 }
3029 }
3030
3031 #[test]
3032 fn fails_parsing_invoice_with_out_of_range_tlv_records() {
3033 let expanded_key = ExpandedKey::new([42; 32]);
3034 let entropy = FixedEntropy {};
3035 let nonce = Nonce::from_entropy_source(&entropy);
3036 let secp_ctx = Secp256k1::new();
3037 let payment_id = PaymentId([1; 32]);
3038
3039 let invoice = OfferBuilder::new(recipient_pubkey())
3040 .amount_msats(1000)
3041 .build().unwrap()
3042 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
3043 .build_and_sign().unwrap()
3044 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
3045 .build().unwrap()
3046 .sign(recipient_sign).unwrap();
3047
3048 let mut encoded_invoice = Vec::new();
3049 invoice.write(&mut encoded_invoice).unwrap();
3050 BigSize(1002).write(&mut encoded_invoice).unwrap();
3051 BigSize(32).write(&mut encoded_invoice).unwrap();
3052 [42u8; 32].write(&mut encoded_invoice).unwrap();
3053
3054 match Bolt12Invoice::try_from(encoded_invoice) {
3055 Ok(_) => panic!("expected error"),
3056 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
3057 }
3058 }
3059
3060 #[test]
3061 fn fails_parsing_invoice_with_message_paths() {
3062 let expanded_key = ExpandedKey::new([42; 32]);
3063 let entropy = FixedEntropy {};
3064 let nonce = Nonce::from_entropy_source(&entropy);
3065 let secp_ctx = Secp256k1::new();
3066 let payment_id = PaymentId([1; 32]);
3067
3068 let invoice = OfferBuilder::new(recipient_pubkey())
3069 .amount_msats(1000)
3070 .build().unwrap()
3071 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
3072 .build_and_sign().unwrap()
3073 .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
3074 .build().unwrap()
3075 .sign(recipient_sign).unwrap();
3076
3077 let blinded_path = BlindedMessagePath::from_raw(
3078 pubkey(40), pubkey(41),
3079 vec![
3080 BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
3081 BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 44] },
3082 ]
3083 );
3084
3085 let mut tlv_stream = invoice.as_tlv_stream();
3086 let message_paths = vec![blinded_path];
3087 tlv_stream.3.message_paths = Some(&message_paths);
3088
3089 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
3090 Ok(_) => panic!("expected error"),
3091 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedPaths)),
3092 }
3093 }
3094}