1#![cfg_attr(
51 feature = "std",
52 doc = "
53 .respond_with(payment_paths, payment_hash)?
54"
55)]
56#![cfg_attr(
57 not(feature = "std"),
58 doc = "
59 .respond_with_no_std(payment_paths, payment_hash, core::time::Duration::from_secs(0))?
60"
61)]
62#![cfg_attr(
90 feature = "std",
91 doc = "
92 .respond_with(payment_paths, payment_hash, pubkey)?
93"
94)]
95#![cfg_attr(
96 not(feature = "std"),
97 doc = "
98 .respond_with_no_std(payment_paths, payment_hash, pubkey, core::time::Duration::from_secs(0))?
99"
100)]
101use crate::blinded_path::message::BlindedMessagePath;
118use crate::blinded_path::payment::{BlindedPayInfo, BlindedPaymentPath};
119use crate::blinded_path::BlindedPath;
120use crate::io;
121use crate::ln::channelmanager::PaymentId;
122use crate::ln::inbound_payment::{ExpandedKey, IV_LEN};
123use crate::ln::msgs::DecodeError;
124#[cfg(test)]
125use crate::offers::invoice_macros::invoice_builder_methods_test_common;
126use crate::offers::invoice_macros::{invoice_accessors_common, invoice_builder_methods_common};
127use crate::offers::invoice_request::{
128 ExperimentalInvoiceRequestTlvStream, ExperimentalInvoiceRequestTlvStreamRef, InvoiceRequest,
129 InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef,
130 EXPERIMENTAL_INVOICE_REQUEST_TYPES, INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES,
131 IV_BYTES as INVOICE_REQUEST_IV_BYTES,
132};
133use crate::offers::merkle::{
134 self, SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream,
135};
136use crate::offers::nonce::Nonce;
137use crate::offers::offer::{
138 Amount, ExperimentalOfferTlvStream, ExperimentalOfferTlvStreamRef, OfferId, OfferTlvStream,
139 OfferTlvStreamRef, Quantity, EXPERIMENTAL_OFFER_TYPES, OFFER_TYPES,
140};
141use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage};
142use crate::offers::payer::{PayerTlvStream, PayerTlvStreamRef, PAYER_METADATA_TYPE};
143use crate::offers::refund::{
144 Refund, RefundContents, IV_BYTES_WITHOUT_METADATA as REFUND_IV_BYTES_WITHOUT_METADATA,
145 IV_BYTES_WITH_METADATA as REFUND_IV_BYTES_WITH_METADATA,
146};
147use crate::offers::signer::{self, Metadata};
148use crate::types::features::{Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
149use crate::types::payment::PaymentHash;
150use crate::types::string::PrintableString;
151use crate::util::ser::{
152 CursorReadable, HighZeroBytesDroppedBigSize, Iterable, LengthLimitedRead, LengthReadable,
153 WithoutLength, Writeable, Writer,
154};
155use bitcoin::address::Address;
156use bitcoin::constants::ChainHash;
157use bitcoin::secp256k1::schnorr::Signature;
158use bitcoin::secp256k1::{self, Keypair, PublicKey, Secp256k1};
159use bitcoin::{Network, WitnessProgram, WitnessVersion};
160use core::hash::{Hash, Hasher};
161use core::time::Duration;
162
163#[allow(unused_imports)]
164use crate::prelude::*;
165
166#[cfg(feature = "std")]
167use std::time::SystemTime;
168
169pub(crate) const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(7200);
170
171pub const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signature");
173
174pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> {
186 invreq_bytes: &'a Vec<u8>,
187 invoice: InvoiceContents,
188 signing_pubkey_strategy: S,
189}
190
191#[cfg(c_bindings)]
201pub struct InvoiceWithExplicitSigningPubkeyBuilder<'a> {
202 invreq_bytes: &'a Vec<u8>,
203 invoice: InvoiceContents,
204 signing_pubkey_strategy: ExplicitSigningPubkey,
205}
206
207#[cfg(c_bindings)]
217pub struct InvoiceWithDerivedSigningPubkeyBuilder<'a> {
218 invreq_bytes: &'a Vec<u8>,
219 invoice: InvoiceContents,
220 signing_pubkey_strategy: DerivedSigningPubkey,
221}
222
223pub trait SigningPubkeyStrategy {}
227
228pub struct ExplicitSigningPubkey {}
232
233pub struct DerivedSigningPubkey(pub(super) Keypair);
237
238impl SigningPubkeyStrategy for ExplicitSigningPubkey {}
239impl SigningPubkeyStrategy for DerivedSigningPubkey {}
240
241macro_rules! invoice_explicit_signing_pubkey_builder_methods {
242 ($self: ident, $self_type: ty) => {
243 #[cfg_attr(c_bindings, allow(dead_code))]
244 pub(super) fn for_offer(
245 invoice_request: &'a InvoiceRequest, payment_paths: Vec<BlindedPaymentPath>,
246 created_at: Duration, payment_hash: PaymentHash, signing_pubkey: PublicKey,
247 ) -> Result<Self, Bolt12SemanticError> {
248 let amount_msats = Self::amount_msats(invoice_request)?;
249 let contents = InvoiceContents::ForOffer {
250 invoice_request: invoice_request.contents.clone(),
251 fields: Self::fields(
252 payment_paths,
253 created_at,
254 payment_hash,
255 amount_msats,
256 signing_pubkey,
257 ),
258 };
259
260 Self::new(&invoice_request.bytes, contents, ExplicitSigningPubkey {})
261 }
262
263 #[cfg_attr(c_bindings, allow(dead_code))]
264 pub(super) fn for_refund(
265 refund: &'a Refund, payment_paths: Vec<BlindedPaymentPath>, created_at: Duration,
266 payment_hash: PaymentHash, signing_pubkey: PublicKey,
267 ) -> Result<Self, Bolt12SemanticError> {
268 let amount_msats = refund.amount_msats();
269 let contents = InvoiceContents::ForRefund {
270 refund: refund.contents.clone(),
271 fields: Self::fields(
272 payment_paths,
273 created_at,
274 payment_hash,
275 amount_msats,
276 signing_pubkey,
277 ),
278 };
279
280 Self::new(&refund.bytes, contents, ExplicitSigningPubkey {})
281 }
282
283 pub fn build($self: $self_type) -> Result<UnsignedBolt12Invoice, Bolt12SemanticError> {
286 #[cfg(feature = "std")]
287 {
288 if $self.invoice.is_offer_or_refund_expired() {
289 return Err(Bolt12SemanticError::AlreadyExpired);
290 }
291 }
292
293 #[cfg(not(feature = "std"))]
294 {
295 if $self.invoice.is_offer_or_refund_expired_no_std($self.invoice.created_at()) {
296 return Err(Bolt12SemanticError::AlreadyExpired);
297 }
298 }
299
300 let Self { invreq_bytes, invoice, .. } = $self;
301 #[cfg(not(c_bindings))]
302 {
303 Ok(UnsignedBolt12Invoice::new(invreq_bytes, invoice))
304 }
305 #[cfg(c_bindings)]
306 {
307 Ok(UnsignedBolt12Invoice::new(invreq_bytes, invoice.clone()))
308 }
309 }
310 };
311}
312
313macro_rules! invoice_derived_signing_pubkey_builder_methods {
314 ($self: ident, $self_type: ty) => {
315 #[cfg_attr(c_bindings, allow(dead_code))]
316 pub(super) fn for_offer_using_keys(
317 invoice_request: &'a InvoiceRequest, payment_paths: Vec<BlindedPaymentPath>,
318 created_at: Duration, payment_hash: PaymentHash, keys: Keypair,
319 ) -> Result<Self, Bolt12SemanticError> {
320 let amount_msats = Self::amount_msats(invoice_request)?;
321 let signing_pubkey = keys.public_key();
322 let contents = InvoiceContents::ForOffer {
323 invoice_request: invoice_request.contents.clone(),
324 fields: Self::fields(
325 payment_paths,
326 created_at,
327 payment_hash,
328 amount_msats,
329 signing_pubkey,
330 ),
331 };
332
333 Self::new(&invoice_request.bytes, contents, DerivedSigningPubkey(keys))
334 }
335
336 #[cfg_attr(c_bindings, allow(dead_code))]
337 pub(super) fn for_refund_using_keys(
338 refund: &'a Refund, payment_paths: Vec<BlindedPaymentPath>, created_at: Duration,
339 payment_hash: PaymentHash, keys: Keypair,
340 ) -> Result<Self, Bolt12SemanticError> {
341 let amount_msats = refund.amount_msats();
342 let signing_pubkey = keys.public_key();
343 let contents = InvoiceContents::ForRefund {
344 refund: refund.contents.clone(),
345 fields: Self::fields(
346 payment_paths,
347 created_at,
348 payment_hash,
349 amount_msats,
350 signing_pubkey,
351 ),
352 };
353
354 Self::new(&refund.bytes, contents, DerivedSigningPubkey(keys))
355 }
356
357 pub fn build_and_sign<T: secp256k1::Signing>(
359 $self: $self_type, secp_ctx: &Secp256k1<T>,
360 ) -> Result<Bolt12Invoice, Bolt12SemanticError> {
361 #[cfg(feature = "std")]
362 {
363 if $self.invoice.is_offer_or_refund_expired() {
364 return Err(Bolt12SemanticError::AlreadyExpired);
365 }
366 }
367
368 #[cfg(not(feature = "std"))]
369 {
370 if $self.invoice.is_offer_or_refund_expired_no_std($self.invoice.created_at()) {
371 return Err(Bolt12SemanticError::AlreadyExpired);
372 }
373 }
374
375 let Self { invreq_bytes, invoice, signing_pubkey_strategy: DerivedSigningPubkey(keys) } =
376 $self;
377 #[cfg(not(c_bindings))]
378 let unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice);
379 #[cfg(c_bindings)]
380 let mut unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice.clone());
381
382 let invoice = unsigned_invoice
383 .sign(|message: &UnsignedBolt12Invoice| {
384 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
385 })
386 .unwrap();
387 Ok(invoice)
388 }
389 };
390}
391
392macro_rules! invoice_builder_methods {
393 (
394 $self: ident, $self_type: ty, $return_type: ty, $return_value: expr, $type_param: ty $(, $self_mut: tt)?
395) => {
396 pub(crate) fn amount_msats(
397 invoice_request: &InvoiceRequest,
398 ) -> Result<u64, Bolt12SemanticError> {
399 match invoice_request.contents.inner.amount_msats() {
400 Some(amount_msats) => Ok(amount_msats),
401 None => match invoice_request.contents.inner.offer.amount() {
402 Some(Amount::Bitcoin { amount_msats }) => amount_msats
403 .checked_mul(invoice_request.quantity().unwrap_or(1))
404 .ok_or(Bolt12SemanticError::InvalidAmount),
405 Some(Amount::Currency { .. }) => Err(Bolt12SemanticError::UnsupportedCurrency),
406 None => Err(Bolt12SemanticError::MissingAmount),
407 },
408 }
409 }
410
411 #[cfg_attr(c_bindings, allow(dead_code))]
412 fn fields(
413 payment_paths: Vec<BlindedPaymentPath>, created_at: Duration,
414 payment_hash: PaymentHash, amount_msats: u64, signing_pubkey: PublicKey,
415 ) -> InvoiceFields {
416 InvoiceFields {
417 payment_paths,
418 created_at,
419 relative_expiry: None,
420 payment_hash,
421 amount_msats,
422 fallbacks: None,
423 features: Bolt12InvoiceFeatures::empty(),
424 signing_pubkey,
425 #[cfg(test)]
426 experimental_baz: None,
427 }
428 }
429
430 #[cfg_attr(c_bindings, allow(dead_code))]
431 fn new(
432 invreq_bytes: &'a Vec<u8>, contents: InvoiceContents,
433 signing_pubkey_strategy: $type_param,
434 ) -> Result<Self, Bolt12SemanticError> {
435 if contents.fields().payment_paths.is_empty() {
436 return Err(Bolt12SemanticError::MissingPaths);
437 }
438
439 Ok(Self { invreq_bytes, invoice: contents, signing_pubkey_strategy })
440 }
441 };
442}
443
444#[cfg(test)]
445macro_rules! invoice_builder_methods_test { (
446 $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
447 $(, $self_mut: tt)?
448) => {
449 #[cfg_attr(c_bindings, allow(dead_code))]
450 pub(crate) fn amount_msats_unchecked(
451 $($self_mut)* $self: $self_type, amount_msats: u64,
452 ) -> $return_type {
453 $self.invoice.fields_mut().amount_msats = amount_msats;
454 $return_value
455 }
456} }
457
458impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
459 invoice_explicit_signing_pubkey_builder_methods!(self, Self);
460}
461
462impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
463 invoice_derived_signing_pubkey_builder_methods!(self, Self);
464}
465
466impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
467 invoice_builder_methods!(self, Self, Self, self, S, mut);
468 invoice_builder_methods_common!(
469 self,
470 Self,
471 self.invoice.fields_mut(),
472 Self,
473 self,
474 Bolt12Invoice,
475 mut
476 );
477
478 #[cfg(test)]
479 invoice_builder_methods_test!(self, Self, Self, self, mut);
480 #[cfg(test)]
481 invoice_builder_methods_test_common!(self, Self, self.invoice.fields_mut(), Self, self, mut);
482}
483
484#[cfg(all(c_bindings, not(test)))]
485impl<'a> InvoiceWithExplicitSigningPubkeyBuilder<'a> {
486 invoice_explicit_signing_pubkey_builder_methods!(self, &mut Self);
487 invoice_builder_methods!(self, &mut Self, (), (), ExplicitSigningPubkey);
488 invoice_builder_methods_common!(
489 self,
490 &mut Self,
491 self.invoice.fields_mut(),
492 (),
493 (),
494 Bolt12Invoice
495 );
496}
497
498#[cfg(all(c_bindings, test))]
499impl<'a> InvoiceWithExplicitSigningPubkeyBuilder<'a> {
500 invoice_explicit_signing_pubkey_builder_methods!(self, &mut Self);
501 invoice_builder_methods!(self, &mut Self, &mut Self, self, ExplicitSigningPubkey);
502 invoice_builder_methods_common!(
503 self,
504 &mut Self,
505 self.invoice.fields_mut(),
506 &mut Self,
507 self,
508 Bolt12Invoice
509 );
510 invoice_builder_methods_test!(self, &mut Self, &mut Self, self);
511 invoice_builder_methods_test_common!(
512 self,
513 &mut Self,
514 self.invoice.fields_mut(),
515 &mut Self,
516 self
517 );
518}
519
520#[cfg(all(c_bindings, not(test)))]
521impl<'a> InvoiceWithDerivedSigningPubkeyBuilder<'a> {
522 invoice_derived_signing_pubkey_builder_methods!(self, &mut Self);
523 invoice_builder_methods!(self, &mut Self, (), (), DerivedSigningPubkey);
524 invoice_builder_methods_common!(
525 self,
526 &mut Self,
527 self.invoice.fields_mut(),
528 (),
529 (),
530 Bolt12Invoice
531 );
532}
533
534#[cfg(all(c_bindings, test))]
535impl<'a> InvoiceWithDerivedSigningPubkeyBuilder<'a> {
536 invoice_derived_signing_pubkey_builder_methods!(self, &mut Self);
537 invoice_builder_methods!(self, &mut Self, &mut Self, self, DerivedSigningPubkey);
538 invoice_builder_methods_common!(
539 self,
540 &mut Self,
541 self.invoice.fields_mut(),
542 &mut Self,
543 self,
544 Bolt12Invoice
545 );
546 invoice_builder_methods_test!(self, &mut Self, &mut Self, self);
547 invoice_builder_methods_test_common!(
548 self,
549 &mut Self,
550 self.invoice.fields_mut(),
551 &mut Self,
552 self
553 );
554}
555
556#[cfg(c_bindings)]
557impl<'a> From<InvoiceWithExplicitSigningPubkeyBuilder<'a>>
558 for InvoiceBuilder<'a, ExplicitSigningPubkey>
559{
560 fn from(builder: InvoiceWithExplicitSigningPubkeyBuilder<'a>) -> Self {
561 let InvoiceWithExplicitSigningPubkeyBuilder {
562 invreq_bytes,
563 invoice,
564 signing_pubkey_strategy,
565 } = builder;
566
567 Self { invreq_bytes, invoice, signing_pubkey_strategy }
568 }
569}
570
571#[cfg(c_bindings)]
572impl<'a> From<InvoiceWithDerivedSigningPubkeyBuilder<'a>>
573 for InvoiceBuilder<'a, DerivedSigningPubkey>
574{
575 fn from(builder: InvoiceWithDerivedSigningPubkeyBuilder<'a>) -> Self {
576 let InvoiceWithDerivedSigningPubkeyBuilder {
577 invreq_bytes,
578 invoice,
579 signing_pubkey_strategy,
580 } = builder;
581
582 Self { invreq_bytes, invoice, signing_pubkey_strategy }
583 }
584}
585
586#[derive(Clone)]
593pub struct UnsignedBolt12Invoice {
594 bytes: Vec<u8>,
595 experimental_bytes: Vec<u8>,
596 contents: InvoiceContents,
597 tagged_hash: TaggedHash,
598}
599
600pub trait SignBolt12InvoiceFn {
602 fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()>;
604}
605
606impl<F> SignBolt12InvoiceFn for F
607where
608 F: Fn(&UnsignedBolt12Invoice) -> Result<Signature, ()>,
609{
610 fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()> {
611 self(message)
612 }
613}
614
615impl<F> SignFn<UnsignedBolt12Invoice> for F
616where
617 F: SignBolt12InvoiceFn,
618{
619 fn sign(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()> {
620 self.sign_invoice(message)
621 }
622}
623
624impl UnsignedBolt12Invoice {
625 fn new(invreq_bytes: &[u8], contents: InvoiceContents) -> Self {
626 const NON_EXPERIMENTAL_TYPES: core::ops::Range<u64> = 0..INVOICE_REQUEST_TYPES.end;
628 const EXPERIMENTAL_TYPES: core::ops::Range<u64> =
629 EXPERIMENTAL_OFFER_TYPES.start..EXPERIMENTAL_INVOICE_REQUEST_TYPES.end;
630
631 let (_, _, _, invoice_tlv_stream, _, _, experimental_invoice_tlv_stream) =
632 contents.as_tlv_stream();
633
634 const INVOICE_ALLOCATION_SIZE: usize = 1024;
635 let mut bytes = Vec::with_capacity(INVOICE_ALLOCATION_SIZE);
636
637 for record in TlvStream::new(invreq_bytes).range(NON_EXPERIMENTAL_TYPES) {
641 record.write(&mut bytes).unwrap();
642 }
643
644 let remaining_bytes = &invreq_bytes[bytes.len()..];
645
646 invoice_tlv_stream.write(&mut bytes).unwrap();
647
648 const EXPERIMENTAL_TLV_ALLOCATION_SIZE: usize = 0;
649 let mut experimental_bytes = Vec::with_capacity(EXPERIMENTAL_TLV_ALLOCATION_SIZE);
650
651 let experimental_tlv_stream = TlvStream::new(remaining_bytes).range(EXPERIMENTAL_TYPES);
652 for record in experimental_tlv_stream {
653 record.write(&mut experimental_bytes).unwrap();
654 }
655
656 experimental_invoice_tlv_stream.write(&mut experimental_bytes).unwrap();
657
658 let tlv_stream = TlvStream::new(&bytes).chain(TlvStream::new(&experimental_bytes));
659 let tagged_hash = TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
660
661 Self { bytes, experimental_bytes, contents, tagged_hash }
662 }
663
664 pub fn tagged_hash(&self) -> &TaggedHash {
666 &self.tagged_hash
667 }
668}
669
670macro_rules! unsigned_invoice_sign_method { ($self: ident, $self_type: ty $(, $self_mut: tt)?) => {
671 pub fn sign<F: SignBolt12InvoiceFn>(
675 $($self_mut)* $self: $self_type, sign: F
676 ) -> Result<Bolt12Invoice, SignError> {
677 let pubkey = $self.contents.fields().signing_pubkey;
678 let signature = merkle::sign_message(sign, &$self, pubkey)?;
679
680 let signature_tlv_stream = SignatureTlvStreamRef {
682 signature: Some(&signature),
683 };
684 signature_tlv_stream.write(&mut $self.bytes).unwrap();
685
686 $self.bytes.extend_from_slice(&$self.experimental_bytes);
688
689 let offer_id = match &$self.contents {
690 InvoiceContents::ForOffer { .. } => {
691 Some(OfferId::from_valid_bolt12_tlv_stream(&$self.bytes))
692 },
693 InvoiceContents::ForRefund { .. } => None,
694 };
695
696 Ok(Bolt12Invoice {
697 #[cfg(not(c_bindings))]
698 bytes: $self.bytes,
699 #[cfg(c_bindings)]
700 bytes: $self.bytes.clone(),
701 #[cfg(not(c_bindings))]
702 contents: $self.contents,
703 #[cfg(c_bindings)]
704 contents: $self.contents.clone(),
705 signature,
706 #[cfg(not(c_bindings))]
707 tagged_hash: $self.tagged_hash,
708 #[cfg(c_bindings)]
709 tagged_hash: $self.tagged_hash.clone(),
710 offer_id,
711 })
712 }
713} }
714
715#[cfg(not(c_bindings))]
716impl UnsignedBolt12Invoice {
717 unsigned_invoice_sign_method!(self, Self, mut);
718}
719
720#[cfg(c_bindings)]
721impl UnsignedBolt12Invoice {
722 unsigned_invoice_sign_method!(self, &mut Self);
723}
724
725impl AsRef<TaggedHash> for UnsignedBolt12Invoice {
726 fn as_ref(&self) -> &TaggedHash {
727 &self.tagged_hash
728 }
729}
730
731#[derive(Clone, Debug)]
740pub struct Bolt12Invoice {
741 bytes: Vec<u8>,
742 contents: InvoiceContents,
743 signature: Signature,
744 tagged_hash: TaggedHash,
745 offer_id: Option<OfferId>,
746}
747
748#[derive(Clone, Debug)]
753#[cfg_attr(test, derive(PartialEq))]
754enum InvoiceContents {
755 ForOffer { invoice_request: InvoiceRequestContents, fields: InvoiceFields },
759 ForRefund { refund: RefundContents, fields: InvoiceFields },
763}
764
765#[derive(Clone, Debug, PartialEq)]
767struct InvoiceFields {
768 payment_paths: Vec<BlindedPaymentPath>,
769 created_at: Duration,
770 relative_expiry: Option<Duration>,
771 payment_hash: PaymentHash,
772 amount_msats: u64,
773 fallbacks: Option<Vec<FallbackAddress>>,
774 features: Bolt12InvoiceFeatures,
775 signing_pubkey: PublicKey,
776 #[cfg(test)]
777 experimental_baz: Option<u64>,
778}
779
780macro_rules! invoice_accessors { ($self: ident, $contents: expr) => {
781 pub fn offer_chains(&$self) -> Option<Vec<ChainHash>> {
787 $contents.offer_chains()
788 }
789
790 pub fn chain(&$self) -> ChainHash {
798 $contents.chain()
799 }
800
801 pub fn metadata(&$self) -> Option<&Vec<u8>> {
809 $contents.metadata()
810 }
811
812 pub fn amount(&$self) -> Option<Amount> {
820 $contents.amount()
821 }
822
823 pub fn offer_features(&$self) -> Option<&OfferFeatures> {
831 $contents.offer_features()
832 }
833
834 pub fn description(&$self) -> Option<PrintableString<'_>> {
840 $contents.description()
841 }
842
843 pub fn absolute_expiry(&$self) -> Option<Duration> {
849 $contents.absolute_expiry()
850 }
851
852 pub fn issuer(&$self) -> Option<PrintableString<'_>> {
858 $contents.issuer()
859 }
860
861 pub fn message_paths(&$self) -> &[BlindedMessagePath] {
867 $contents.message_paths()
868 }
869
870 pub fn supported_quantity(&$self) -> Option<Quantity> {
877 $contents.supported_quantity()
878 }
879
880 pub fn issuer_signing_pubkey(&$self) -> Option<PublicKey> {
887 $contents.issuer_signing_pubkey()
888 }
889
890 pub fn payer_metadata(&$self) -> &[u8] {
894 $contents.payer_metadata()
895 }
896
897 pub fn invoice_request_features(&$self) -> &InvoiceRequestFeatures {
901 &$contents.invoice_request_features()
902 }
903
904 pub fn quantity(&$self) -> Option<u64> {
908 $contents.quantity()
909 }
910
911 pub fn payer_signing_pubkey(&$self) -> PublicKey {
916 $contents.payer_signing_pubkey()
917 }
918
919 pub fn payer_note(&$self) -> Option<PrintableString<'_>> {
923 $contents.payer_note()
924 }
925
926 pub fn payment_hash(&$self) -> PaymentHash {
928 $contents.payment_hash()
929 }
930
931 pub fn amount_msats(&$self) -> u64 {
933 $contents.amount_msats()
934 }
935} }
936
937macro_rules! invoice_accessors_signing_pubkey {
938 ($self: ident, $contents: expr, $invoice_type: ty) =>
939{
940 pub fn signing_pubkey(&$self) -> PublicKey {
954 $contents.signing_pubkey()
955 }
956} }
957
958impl UnsignedBolt12Invoice {
959 invoice_accessors_common!(self, self.contents, UnsignedBolt12Invoice);
960 invoice_accessors_signing_pubkey!(self, self.contents, UnsignedBolt12Invoice);
961 invoice_accessors!(self, self.contents);
962}
963
964impl Bolt12Invoice {
965 invoice_accessors_common!(self, self.contents, Bolt12Invoice);
966 invoice_accessors_signing_pubkey!(self, self.contents, Bolt12Invoice);
967 invoice_accessors!(self, self.contents);
968
969 pub fn signature(&self) -> Signature {
971 self.signature
972 }
973
974 pub fn signable_hash(&self) -> [u8; 32] {
976 self.tagged_hash.as_digest().as_ref().clone()
977 }
978
979 pub fn offer_id(&self) -> Option<OfferId> {
983 self.offer_id
984 }
985
986 pub fn verify_using_metadata<T: secp256k1::Signing>(
991 &self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>,
992 ) -> Result<PaymentId, ()> {
993 let (metadata, iv_bytes) = match &self.contents {
994 InvoiceContents::ForOffer { invoice_request, .. } => {
995 (&invoice_request.inner.payer.0, INVOICE_REQUEST_IV_BYTES)
996 },
997 InvoiceContents::ForRefund { refund, .. } => {
998 (&refund.payer.0, REFUND_IV_BYTES_WITH_METADATA)
999 },
1000 };
1001 self.contents.verify(&self.bytes, metadata, key, iv_bytes, secp_ctx)
1002 }
1003
1004 pub fn verify_using_payer_data<T: secp256k1::Signing>(
1008 &self, payment_id: PaymentId, nonce: Nonce, key: &ExpandedKey, secp_ctx: &Secp256k1<T>,
1009 ) -> Result<PaymentId, ()> {
1010 let metadata = Metadata::payer_data(payment_id, nonce, key);
1011 let iv_bytes = match &self.contents {
1012 InvoiceContents::ForOffer { .. } => INVOICE_REQUEST_IV_BYTES,
1013 InvoiceContents::ForRefund { .. } => REFUND_IV_BYTES_WITHOUT_METADATA,
1014 };
1015 self.contents.verify(&self.bytes, &metadata, key, iv_bytes, secp_ctx).and_then(
1016 |extracted_payment_id| {
1017 (payment_id == extracted_payment_id).then(|| payment_id).ok_or(())
1018 },
1019 )
1020 }
1021
1022 pub(crate) fn as_tlv_stream(&self) -> FullInvoiceTlvStreamRef<'_> {
1023 let (
1024 payer_tlv_stream,
1025 offer_tlv_stream,
1026 invoice_request_tlv_stream,
1027 invoice_tlv_stream,
1028 experimental_offer_tlv_stream,
1029 experimental_invoice_request_tlv_stream,
1030 experimental_invoice_tlv_stream,
1031 ) = self.contents.as_tlv_stream();
1032 let signature_tlv_stream = SignatureTlvStreamRef { signature: Some(&self.signature) };
1033 (
1034 payer_tlv_stream,
1035 offer_tlv_stream,
1036 invoice_request_tlv_stream,
1037 invoice_tlv_stream,
1038 signature_tlv_stream,
1039 experimental_offer_tlv_stream,
1040 experimental_invoice_request_tlv_stream,
1041 experimental_invoice_tlv_stream,
1042 )
1043 }
1044
1045 pub(crate) fn is_for_refund_without_paths(&self) -> bool {
1046 match self.contents {
1047 InvoiceContents::ForOffer { .. } => false,
1048 InvoiceContents::ForRefund { .. } => self.message_paths().is_empty(),
1049 }
1050 }
1051
1052 pub fn tagged_hash(&self) -> &TaggedHash {
1054 &self.tagged_hash
1055 }
1056}
1057
1058impl PartialEq for Bolt12Invoice {
1059 fn eq(&self, other: &Self) -> bool {
1060 self.bytes.eq(&other.bytes)
1061 }
1062}
1063
1064impl Eq for Bolt12Invoice {}
1065
1066impl Hash for Bolt12Invoice {
1067 fn hash<H: Hasher>(&self, state: &mut H) {
1068 self.bytes.hash(state);
1069 }
1070}
1071
1072impl InvoiceContents {
1073 #[cfg(feature = "std")]
1075 fn is_offer_or_refund_expired(&self) -> bool {
1076 match self {
1077 InvoiceContents::ForOffer { invoice_request, .. } => {
1078 invoice_request.inner.offer.is_expired()
1079 },
1080 InvoiceContents::ForRefund { refund, .. } => refund.is_expired(),
1081 }
1082 }
1083
1084 #[cfg(not(feature = "std"))]
1085 fn is_offer_or_refund_expired_no_std(&self, duration_since_epoch: Duration) -> bool {
1086 match self {
1087 InvoiceContents::ForOffer { invoice_request, .. } => {
1088 invoice_request.inner.offer.is_expired_no_std(duration_since_epoch)
1089 },
1090 InvoiceContents::ForRefund { refund, .. } => {
1091 refund.is_expired_no_std(duration_since_epoch)
1092 },
1093 }
1094 }
1095
1096 fn offer_chains(&self) -> Option<Vec<ChainHash>> {
1097 match self {
1098 InvoiceContents::ForOffer { invoice_request, .. } => {
1099 Some(invoice_request.inner.offer.chains())
1100 },
1101 InvoiceContents::ForRefund { .. } => None,
1102 }
1103 }
1104
1105 fn chain(&self) -> ChainHash {
1106 match self {
1107 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.chain(),
1108 InvoiceContents::ForRefund { refund, .. } => refund.chain(),
1109 }
1110 }
1111
1112 fn metadata(&self) -> Option<&Vec<u8>> {
1113 match self {
1114 InvoiceContents::ForOffer { invoice_request, .. } => {
1115 invoice_request.inner.offer.metadata()
1116 },
1117 InvoiceContents::ForRefund { .. } => None,
1118 }
1119 }
1120
1121 fn amount(&self) -> Option<Amount> {
1122 match self {
1123 InvoiceContents::ForOffer { invoice_request, .. } => {
1124 invoice_request.inner.offer.amount()
1125 },
1126 InvoiceContents::ForRefund { .. } => None,
1127 }
1128 }
1129
1130 fn description(&self) -> Option<PrintableString<'_>> {
1131 match self {
1132 InvoiceContents::ForOffer { invoice_request, .. } => {
1133 invoice_request.inner.offer.description()
1134 },
1135 InvoiceContents::ForRefund { refund, .. } => Some(refund.description()),
1136 }
1137 }
1138
1139 fn offer_features(&self) -> Option<&OfferFeatures> {
1140 match self {
1141 InvoiceContents::ForOffer { invoice_request, .. } => {
1142 Some(invoice_request.inner.offer.features())
1143 },
1144 InvoiceContents::ForRefund { .. } => None,
1145 }
1146 }
1147
1148 fn absolute_expiry(&self) -> Option<Duration> {
1149 match self {
1150 InvoiceContents::ForOffer { invoice_request, .. } => {
1151 invoice_request.inner.offer.absolute_expiry()
1152 },
1153 InvoiceContents::ForRefund { refund, .. } => refund.absolute_expiry(),
1154 }
1155 }
1156
1157 fn issuer(&self) -> Option<PrintableString<'_>> {
1158 match self {
1159 InvoiceContents::ForOffer { invoice_request, .. } => {
1160 invoice_request.inner.offer.issuer()
1161 },
1162 InvoiceContents::ForRefund { refund, .. } => refund.issuer(),
1163 }
1164 }
1165
1166 fn message_paths(&self) -> &[BlindedMessagePath] {
1167 match self {
1168 InvoiceContents::ForOffer { invoice_request, .. } => {
1169 invoice_request.inner.offer.paths()
1170 },
1171 InvoiceContents::ForRefund { refund, .. } => refund.paths(),
1172 }
1173 }
1174
1175 fn supported_quantity(&self) -> Option<Quantity> {
1176 match self {
1177 InvoiceContents::ForOffer { invoice_request, .. } => {
1178 Some(invoice_request.inner.offer.supported_quantity())
1179 },
1180 InvoiceContents::ForRefund { .. } => None,
1181 }
1182 }
1183
1184 fn issuer_signing_pubkey(&self) -> Option<PublicKey> {
1185 match self {
1186 InvoiceContents::ForOffer { invoice_request, .. } => {
1187 invoice_request.inner.offer.issuer_signing_pubkey()
1188 },
1189 InvoiceContents::ForRefund { .. } => None,
1190 }
1191 }
1192
1193 fn payer_metadata(&self) -> &[u8] {
1194 match self {
1195 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.metadata(),
1196 InvoiceContents::ForRefund { refund, .. } => refund.metadata(),
1197 }
1198 }
1199
1200 fn invoice_request_features(&self) -> &InvoiceRequestFeatures {
1201 match self {
1202 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.features(),
1203 InvoiceContents::ForRefund { refund, .. } => refund.features(),
1204 }
1205 }
1206
1207 fn quantity(&self) -> Option<u64> {
1208 match self {
1209 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.quantity(),
1210 InvoiceContents::ForRefund { refund, .. } => refund.quantity(),
1211 }
1212 }
1213
1214 fn payer_signing_pubkey(&self) -> PublicKey {
1215 match self {
1216 InvoiceContents::ForOffer { invoice_request, .. } => {
1217 invoice_request.payer_signing_pubkey()
1218 },
1219 InvoiceContents::ForRefund { refund, .. } => refund.payer_signing_pubkey(),
1220 }
1221 }
1222
1223 fn payer_note(&self) -> Option<PrintableString<'_>> {
1224 match self {
1225 InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.payer_note(),
1226 InvoiceContents::ForRefund { refund, .. } => refund.payer_note(),
1227 }
1228 }
1229
1230 fn payment_paths(&self) -> &[BlindedPaymentPath] {
1231 &self.fields().payment_paths[..]
1232 }
1233
1234 fn created_at(&self) -> Duration {
1235 self.fields().created_at
1236 }
1237
1238 fn relative_expiry(&self) -> Duration {
1239 self.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
1240 }
1241
1242 #[cfg(feature = "std")]
1243 fn is_expired(&self) -> bool {
1244 is_expired(self.created_at(), self.relative_expiry())
1245 }
1246
1247 fn is_expired_no_std(&self, duration_since_epoch: Duration) -> bool {
1248 self.created_at().saturating_add(self.relative_expiry()) < duration_since_epoch
1249 }
1250
1251 fn payment_hash(&self) -> PaymentHash {
1252 self.fields().payment_hash
1253 }
1254
1255 fn amount_msats(&self) -> u64 {
1256 self.fields().amount_msats
1257 }
1258
1259 fn fallbacks(&self) -> Vec<Address> {
1260 self.fields()
1261 .fallbacks
1262 .as_ref()
1263 .map(|fallbacks| filter_fallbacks(self.chain(), fallbacks))
1264 .unwrap_or_default()
1265 }
1266
1267 fn features(&self) -> &Bolt12InvoiceFeatures {
1268 &self.fields().features
1269 }
1270
1271 fn signing_pubkey(&self) -> PublicKey {
1272 self.fields().signing_pubkey
1273 }
1274
1275 fn fields(&self) -> &InvoiceFields {
1276 match self {
1277 InvoiceContents::ForOffer { fields, .. } => fields,
1278 InvoiceContents::ForRefund { fields, .. } => fields,
1279 }
1280 }
1281
1282 fn fields_mut(&mut self) -> &mut InvoiceFields {
1283 match self {
1284 InvoiceContents::ForOffer { fields, .. } => fields,
1285 InvoiceContents::ForRefund { fields, .. } => fields,
1286 }
1287 }
1288
1289 fn verify<T: secp256k1::Signing>(
1290 &self, bytes: &[u8], metadata: &Metadata, key: &ExpandedKey, iv_bytes: &[u8; IV_LEN],
1291 secp_ctx: &Secp256k1<T>,
1292 ) -> Result<PaymentId, ()> {
1293 const EXPERIMENTAL_TYPES: core::ops::Range<u64> =
1294 EXPERIMENTAL_OFFER_TYPES.start..EXPERIMENTAL_INVOICE_REQUEST_TYPES.end;
1295
1296 let offer_records = TlvStream::new(bytes).range(OFFER_TYPES);
1297 let invreq_records = TlvStream::new(bytes).range(INVOICE_REQUEST_TYPES).filter(|record| {
1298 match record.r#type {
1299 PAYER_METADATA_TYPE => false, INVOICE_REQUEST_PAYER_ID_TYPE => !metadata.derives_payer_keys(),
1301 _ => true,
1302 }
1303 });
1304 let experimental_records = TlvStream::new(bytes).range(EXPERIMENTAL_TYPES);
1305 let tlv_stream = offer_records.chain(invreq_records).chain(experimental_records);
1306
1307 let signing_pubkey = self.payer_signing_pubkey();
1308 signer::verify_payer_metadata(
1309 metadata.as_ref(),
1310 key,
1311 iv_bytes,
1312 signing_pubkey,
1313 tlv_stream,
1314 secp_ctx,
1315 )
1316 }
1317
1318 fn as_tlv_stream(&self) -> PartialInvoiceTlvStreamRef<'_> {
1319 let (payer, offer, invoice_request, experimental_offer, experimental_invoice_request) =
1320 match self {
1321 InvoiceContents::ForOffer { invoice_request, .. } => {
1322 invoice_request.as_tlv_stream()
1323 },
1324 InvoiceContents::ForRefund { refund, .. } => refund.as_tlv_stream(),
1325 };
1326 let (invoice, experimental_invoice) = self.fields().as_tlv_stream();
1327
1328 (
1329 payer,
1330 offer,
1331 invoice_request,
1332 invoice,
1333 experimental_offer,
1334 experimental_invoice_request,
1335 experimental_invoice,
1336 )
1337 }
1338}
1339
1340#[cfg(feature = "std")]
1341pub(super) fn is_expired(created_at: Duration, relative_expiry: Duration) -> bool {
1342 let absolute_expiry = created_at.checked_add(relative_expiry);
1343 match absolute_expiry {
1344 Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
1345 Ok(elapsed) => elapsed > seconds_from_epoch,
1346 Err(_) => false,
1347 },
1348 None => false,
1349 }
1350}
1351
1352pub(super) fn filter_fallbacks(chain: ChainHash, fallbacks: &Vec<FallbackAddress>) -> Vec<Address> {
1353 let network = if chain == ChainHash::using_genesis_block(Network::Bitcoin) {
1354 Network::Bitcoin
1355 } else if chain == ChainHash::using_genesis_block(Network::Testnet) {
1356 Network::Testnet
1357 } else if chain == ChainHash::using_genesis_block(Network::Signet) {
1358 Network::Signet
1359 } else if chain == ChainHash::using_genesis_block(Network::Regtest) {
1360 Network::Regtest
1361 } else {
1362 return Vec::new();
1363 };
1364
1365 let to_valid_address = |address: &FallbackAddress| {
1366 let version = match WitnessVersion::try_from(address.version) {
1367 Ok(version) => version,
1368 Err(_) => return None,
1369 };
1370
1371 let witness_program = match WitnessProgram::new(version, &address.program) {
1372 Ok(witness_program) => witness_program,
1373 Err(_) => return None,
1374 };
1375 Some(Address::from_witness_program(witness_program, network))
1376 };
1377
1378 fallbacks.iter().filter_map(to_valid_address).collect()
1379}
1380
1381impl InvoiceFields {
1382 fn as_tlv_stream(&self) -> (InvoiceTlvStreamRef<'_>, ExperimentalInvoiceTlvStreamRef) {
1383 let features = {
1384 if self.features == Bolt12InvoiceFeatures::empty() {
1385 None
1386 } else {
1387 Some(&self.features)
1388 }
1389 };
1390
1391 (
1392 InvoiceTlvStreamRef {
1393 paths: Some(Iterable(
1394 self.payment_paths.iter().map(|path| path.inner_blinded_path()),
1395 )),
1396 blindedpay: Some(Iterable(self.payment_paths.iter().map(|path| &path.payinfo))),
1397 created_at: Some(self.created_at.as_secs()),
1398 relative_expiry: self.relative_expiry.map(|duration| duration.as_secs() as u32),
1399 payment_hash: Some(&self.payment_hash),
1400 amount: Some(self.amount_msats),
1401 fallbacks: self.fallbacks.as_ref(),
1402 features,
1403 node_id: Some(&self.signing_pubkey),
1404 message_paths: None,
1405 },
1406 ExperimentalInvoiceTlvStreamRef {
1407 #[cfg(test)]
1408 experimental_baz: self.experimental_baz,
1409 },
1410 )
1411 }
1412}
1413
1414impl Writeable for UnsignedBolt12Invoice {
1415 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1416 WithoutLength(&self.bytes).write(writer)
1417 }
1418}
1419
1420impl Writeable for Bolt12Invoice {
1421 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1422 WithoutLength(&self.bytes).write(writer)
1423 }
1424}
1425
1426impl LengthReadable for Bolt12Invoice {
1427 fn read_from_fixed_length_buffer<R: LengthLimitedRead>(
1428 reader: &mut R,
1429 ) -> Result<Self, DecodeError> {
1430 let bytes: WithoutLength<Vec<u8>> = LengthReadable::read_from_fixed_length_buffer(reader)?;
1431 Self::try_from(bytes.0).map_err(|e| match e {
1432 Bolt12ParseError::Decode(e) => e,
1433 _ => DecodeError::InvalidValue,
1434 })
1435 }
1436}
1437
1438impl Writeable for InvoiceContents {
1439 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1440 self.as_tlv_stream().write(writer)
1441 }
1442}
1443
1444impl TryFrom<Vec<u8>> for UnsignedBolt12Invoice {
1445 type Error = Bolt12ParseError;
1446
1447 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1448 let invoice = ParsedMessage::<PartialInvoiceTlvStream>::try_from(bytes)?;
1449 let ParsedMessage { mut bytes, tlv_stream } = invoice;
1450 let contents = InvoiceContents::try_from(tlv_stream)?;
1451
1452 let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
1453
1454 let offset = TlvStream::new(&bytes)
1455 .range(0..INVOICE_TYPES.end)
1456 .last()
1457 .map_or(0, |last_record| last_record.end);
1458 let experimental_bytes = bytes.split_off(offset);
1459
1460 Ok(UnsignedBolt12Invoice { bytes, experimental_bytes, contents, tagged_hash })
1461 }
1462}
1463
1464impl TryFrom<Vec<u8>> for Bolt12Invoice {
1465 type Error = Bolt12ParseError;
1466
1467 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1468 let parsed_invoice = ParsedMessage::<FullInvoiceTlvStream>::try_from(bytes)?;
1469 Bolt12Invoice::try_from(parsed_invoice)
1470 }
1471}
1472
1473pub(super) const INVOICE_TYPES: core::ops::Range<u64> = 160..240;
1475
1476tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef<'a>, INVOICE_TYPES, {
1477 (160, paths: (Vec<BlindedPath>, WithoutLength, Iterable<'a, BlindedPathIter<'a>, BlindedPath>)),
1478 (162, blindedpay: (Vec<BlindedPayInfo>, WithoutLength, Iterable<'a, BlindedPayInfoIter<'a>, BlindedPayInfo>)),
1479 (164, created_at: (u64, HighZeroBytesDroppedBigSize)),
1480 (166, relative_expiry: (u32, HighZeroBytesDroppedBigSize)),
1481 (168, payment_hash: PaymentHash),
1482 (170, amount: (u64, HighZeroBytesDroppedBigSize)),
1483 (172, fallbacks: (Vec<FallbackAddress>, WithoutLength)),
1484 (174, features: (Bolt12InvoiceFeatures, WithoutLength)),
1485 (176, node_id: PublicKey),
1486 (236, message_paths: (Vec<BlindedMessagePath>, WithoutLength)),
1488});
1489
1490pub(super) const EXPERIMENTAL_INVOICE_TYPES: core::ops::RangeFrom<u64> = 3_000_000_000..;
1492
1493#[cfg(not(test))]
1494tlv_stream!(
1495 ExperimentalInvoiceTlvStream,
1496 ExperimentalInvoiceTlvStreamRef,
1497 EXPERIMENTAL_INVOICE_TYPES,
1498 {
1499 }
1503);
1504
1505#[cfg(test)]
1506tlv_stream!(
1507 ExperimentalInvoiceTlvStream, ExperimentalInvoiceTlvStreamRef, EXPERIMENTAL_INVOICE_TYPES, {
1508 (3_999_999_999, experimental_baz: (u64, HighZeroBytesDroppedBigSize)),
1509 }
1510);
1511
1512pub(super) type BlindedPathIter<'a> = core::iter::Map<
1513 core::slice::Iter<'a, BlindedPaymentPath>,
1514 for<'r> fn(&'r BlindedPaymentPath) -> &'r BlindedPath,
1515>;
1516
1517pub(super) type BlindedPayInfoIter<'a> = core::iter::Map<
1518 core::slice::Iter<'a, BlindedPaymentPath>,
1519 for<'r> fn(&'r BlindedPaymentPath) -> &'r BlindedPayInfo,
1520>;
1521
1522#[derive(Clone, Debug, PartialEq)]
1524pub(super) struct FallbackAddress {
1525 pub(super) version: u8,
1526 pub(super) program: Vec<u8>,
1527}
1528
1529impl_writeable!(FallbackAddress, { version, program });
1530
1531type FullInvoiceTlvStream = (
1532 PayerTlvStream,
1533 OfferTlvStream,
1534 InvoiceRequestTlvStream,
1535 InvoiceTlvStream,
1536 SignatureTlvStream,
1537 ExperimentalOfferTlvStream,
1538 ExperimentalInvoiceRequestTlvStream,
1539 ExperimentalInvoiceTlvStream,
1540);
1541
1542type FullInvoiceTlvStreamRef<'a> = (
1543 PayerTlvStreamRef<'a>,
1544 OfferTlvStreamRef<'a>,
1545 InvoiceRequestTlvStreamRef<'a>,
1546 InvoiceTlvStreamRef<'a>,
1547 SignatureTlvStreamRef<'a>,
1548 ExperimentalOfferTlvStreamRef,
1549 ExperimentalInvoiceRequestTlvStreamRef,
1550 ExperimentalInvoiceTlvStreamRef,
1551);
1552
1553impl CursorReadable for FullInvoiceTlvStream {
1554 fn read<R: AsRef<[u8]>>(r: &mut io::Cursor<R>) -> Result<Self, DecodeError> {
1555 let payer = CursorReadable::read(r)?;
1556 let offer = CursorReadable::read(r)?;
1557 let invoice_request = CursorReadable::read(r)?;
1558 let invoice = CursorReadable::read(r)?;
1559 let signature = CursorReadable::read(r)?;
1560 let experimental_offer = CursorReadable::read(r)?;
1561 let experimental_invoice_request = CursorReadable::read(r)?;
1562 let experimental_invoice = CursorReadable::read(r)?;
1563
1564 Ok((
1565 payer,
1566 offer,
1567 invoice_request,
1568 invoice,
1569 signature,
1570 experimental_offer,
1571 experimental_invoice_request,
1572 experimental_invoice,
1573 ))
1574 }
1575}
1576
1577type PartialInvoiceTlvStream = (
1578 PayerTlvStream,
1579 OfferTlvStream,
1580 InvoiceRequestTlvStream,
1581 InvoiceTlvStream,
1582 ExperimentalOfferTlvStream,
1583 ExperimentalInvoiceRequestTlvStream,
1584 ExperimentalInvoiceTlvStream,
1585);
1586
1587type PartialInvoiceTlvStreamRef<'a> = (
1588 PayerTlvStreamRef<'a>,
1589 OfferTlvStreamRef<'a>,
1590 InvoiceRequestTlvStreamRef<'a>,
1591 InvoiceTlvStreamRef<'a>,
1592 ExperimentalOfferTlvStreamRef,
1593 ExperimentalInvoiceRequestTlvStreamRef,
1594 ExperimentalInvoiceTlvStreamRef,
1595);
1596
1597impl CursorReadable for PartialInvoiceTlvStream {
1598 fn read<R: AsRef<[u8]>>(r: &mut io::Cursor<R>) -> Result<Self, DecodeError> {
1599 let payer = CursorReadable::read(r)?;
1600 let offer = CursorReadable::read(r)?;
1601 let invoice_request = CursorReadable::read(r)?;
1602 let invoice = CursorReadable::read(r)?;
1603 let experimental_offer = CursorReadable::read(r)?;
1604 let experimental_invoice_request = CursorReadable::read(r)?;
1605 let experimental_invoice = CursorReadable::read(r)?;
1606
1607 Ok((
1608 payer,
1609 offer,
1610 invoice_request,
1611 invoice,
1612 experimental_offer,
1613 experimental_invoice_request,
1614 experimental_invoice,
1615 ))
1616 }
1617}
1618
1619impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Bolt12Invoice {
1620 type Error = Bolt12ParseError;
1621
1622 fn try_from(invoice: ParsedMessage<FullInvoiceTlvStream>) -> Result<Self, Self::Error> {
1623 let ParsedMessage { bytes, tlv_stream } = invoice;
1624 let (
1625 payer_tlv_stream,
1626 offer_tlv_stream,
1627 invoice_request_tlv_stream,
1628 invoice_tlv_stream,
1629 SignatureTlvStream { signature },
1630 experimental_offer_tlv_stream,
1631 experimental_invoice_request_tlv_stream,
1632 experimental_invoice_tlv_stream,
1633 ) = tlv_stream;
1634 let contents = InvoiceContents::try_from((
1635 payer_tlv_stream,
1636 offer_tlv_stream,
1637 invoice_request_tlv_stream,
1638 invoice_tlv_stream,
1639 experimental_offer_tlv_stream,
1640 experimental_invoice_request_tlv_stream,
1641 experimental_invoice_tlv_stream,
1642 ))?;
1643
1644 let signature = signature
1645 .ok_or(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature))?;
1646 let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
1647 let pubkey = contents.fields().signing_pubkey;
1648 merkle::verify_signature(&signature, &tagged_hash, pubkey)?;
1649
1650 let offer_id = match &contents {
1651 InvoiceContents::ForOffer { .. } => Some(OfferId::from_valid_bolt12_tlv_stream(&bytes)),
1652 InvoiceContents::ForRefund { .. } => None,
1653 };
1654 Ok(Bolt12Invoice { bytes, contents, signature, tagged_hash, offer_id })
1655 }
1656}
1657
1658impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
1659 type Error = Bolt12SemanticError;
1660
1661 fn try_from(tlv_stream: PartialInvoiceTlvStream) -> Result<Self, Self::Error> {
1662 let (
1663 payer_tlv_stream,
1664 offer_tlv_stream,
1665 invoice_request_tlv_stream,
1666 InvoiceTlvStream {
1667 paths,
1668 blindedpay,
1669 created_at,
1670 relative_expiry,
1671 payment_hash,
1672 amount,
1673 fallbacks,
1674 features,
1675 node_id,
1676 message_paths,
1677 },
1678 experimental_offer_tlv_stream,
1679 experimental_invoice_request_tlv_stream,
1680 ExperimentalInvoiceTlvStream {
1681 #[cfg(test)]
1682 experimental_baz,
1683 },
1684 ) = tlv_stream;
1685
1686 if message_paths.is_some() {
1687 return Err(Bolt12SemanticError::UnexpectedPaths);
1688 }
1689
1690 let payment_paths = construct_payment_paths(blindedpay, paths)?;
1691
1692 let created_at = match created_at {
1693 None => return Err(Bolt12SemanticError::MissingCreationTime),
1694 Some(timestamp) => Duration::from_secs(timestamp),
1695 };
1696
1697 let relative_expiry = relative_expiry.map(Into::<u64>::into).map(Duration::from_secs);
1698
1699 let payment_hash = payment_hash.ok_or(Bolt12SemanticError::MissingPaymentHash)?;
1700
1701 let amount_msats = amount.ok_or(Bolt12SemanticError::MissingAmount)?;
1702
1703 let features = features.unwrap_or_else(Bolt12InvoiceFeatures::empty);
1704
1705 let signing_pubkey = node_id.ok_or(Bolt12SemanticError::MissingSigningPubkey)?;
1706
1707 let fields = InvoiceFields {
1708 payment_paths,
1709 created_at,
1710 relative_expiry,
1711 payment_hash,
1712 amount_msats,
1713 fallbacks,
1714 features,
1715 signing_pubkey,
1716 #[cfg(test)]
1717 experimental_baz,
1718 };
1719
1720 check_invoice_signing_pubkey(&fields.signing_pubkey, &offer_tlv_stream)?;
1721
1722 if offer_tlv_stream.issuer_id.is_none() && offer_tlv_stream.paths.is_none() {
1723 let refund = RefundContents::try_from((
1724 payer_tlv_stream,
1725 offer_tlv_stream,
1726 invoice_request_tlv_stream,
1727 experimental_offer_tlv_stream,
1728 experimental_invoice_request_tlv_stream,
1729 ))?;
1730
1731 if amount_msats != refund.amount_msats() {
1732 return Err(Bolt12SemanticError::InvalidAmount);
1733 }
1734
1735 Ok(InvoiceContents::ForRefund { refund, fields })
1736 } else {
1737 let invoice_request = InvoiceRequestContents::try_from((
1738 payer_tlv_stream,
1739 offer_tlv_stream,
1740 invoice_request_tlv_stream,
1741 experimental_offer_tlv_stream,
1742 experimental_invoice_request_tlv_stream,
1743 ))?;
1744
1745 if let Some(requested_amount_msats) = invoice_request.amount_msats() {
1746 if amount_msats != requested_amount_msats {
1747 return Err(Bolt12SemanticError::InvalidAmount);
1748 }
1749 }
1750
1751 Ok(InvoiceContents::ForOffer { invoice_request, fields })
1752 }
1753 }
1754}
1755
1756pub(super) fn construct_payment_paths(
1757 blinded_payinfos: Option<Vec<BlindedPayInfo>>, blinded_paths: Option<Vec<BlindedPath>>,
1758) -> Result<Vec<BlindedPaymentPath>, Bolt12SemanticError> {
1759 match (blinded_payinfos, blinded_paths) {
1760 (_, None) => Err(Bolt12SemanticError::MissingPaths),
1761 (None, _) => Err(Bolt12SemanticError::InvalidPayInfo),
1762 (_, Some(paths)) if paths.is_empty() => Err(Bolt12SemanticError::MissingPaths),
1763 (Some(blindedpay), Some(paths)) if paths.len() != blindedpay.len() => {
1764 Err(Bolt12SemanticError::InvalidPayInfo)
1765 },
1766 (Some(blindedpay), Some(paths)) => Ok(blindedpay
1767 .into_iter()
1768 .zip(paths.into_iter())
1769 .map(|(payinfo, path)| BlindedPaymentPath::from_parts(path, payinfo))
1770 .collect::<Vec<_>>()),
1771 }
1772}
1773
1774pub(super) fn check_invoice_signing_pubkey(
1775 invoice_signing_pubkey: &PublicKey, offer_tlv_stream: &OfferTlvStream,
1776) -> Result<(), Bolt12SemanticError> {
1777 match (&offer_tlv_stream.issuer_id, &offer_tlv_stream.paths) {
1778 (Some(issuer_signing_pubkey), _) => {
1779 if invoice_signing_pubkey != issuer_signing_pubkey {
1780 return Err(Bolt12SemanticError::InvalidSigningPubkey);
1781 }
1782 },
1783 (None, Some(paths)) => {
1784 if !paths
1785 .iter()
1786 .filter_map(|path| path.blinded_hops().last())
1787 .any(|last_hop| invoice_signing_pubkey == &last_hop.blinded_node_id)
1788 {
1789 return Err(Bolt12SemanticError::InvalidSigningPubkey);
1790 }
1791 },
1792 _ => {},
1793 }
1794 Ok(())
1795}
1796
1797#[cfg(test)]
1798mod tests {
1799 use super::{
1800 Bolt12Invoice, ExperimentalInvoiceTlvStreamRef, FallbackAddress, FullInvoiceTlvStreamRef,
1801 InvoiceTlvStreamRef, UnsignedBolt12Invoice, DEFAULT_RELATIVE_EXPIRY,
1802 EXPERIMENTAL_INVOICE_TYPES, INVOICE_TYPES, SIGNATURE_TAG,
1803 };
1804
1805 use bitcoin::address::Address;
1806 use bitcoin::constants::ChainHash;
1807 use bitcoin::hashes::Hash;
1808 use bitcoin::key::TweakedPublicKey;
1809 use bitcoin::network::Network;
1810 use bitcoin::script::ScriptBuf;
1811 use bitcoin::secp256k1::{self, Keypair, Message, Secp256k1, SecretKey, XOnlyPublicKey};
1812 use bitcoin::{CompressedPublicKey, WitnessProgram, WitnessVersion};
1813 use core::time::Duration;
1814
1815 use crate::blinded_path::message::BlindedMessagePath;
1816 use crate::blinded_path::BlindedHop;
1817 use crate::ln::channelmanager::PaymentId;
1818 use crate::ln::inbound_payment::ExpandedKey;
1819 use crate::ln::msgs::DecodeError;
1820 use crate::offers::invoice_request::{
1821 ExperimentalInvoiceRequestTlvStreamRef, InvoiceRequestTlvStreamRef,
1822 };
1823 use crate::offers::merkle::{self, SignError, SignatureTlvStreamRef, TaggedHash, TlvStream};
1824 use crate::offers::nonce::Nonce;
1825 use crate::offers::offer::{
1826 Amount, ExperimentalOfferTlvStreamRef, OfferTlvStreamRef, Quantity,
1827 };
1828 use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
1829 use crate::offers::payer::PayerTlvStreamRef;
1830 use crate::offers::test_utils::*;
1831 use crate::prelude::*;
1832 use crate::types::features::{Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
1833 use crate::types::string::PrintableString;
1834 use crate::util::ser::{BigSize, Iterable, Writeable};
1835 #[cfg(not(c_bindings))]
1836 use {crate::offers::offer::OfferBuilder, crate::offers::refund::RefundBuilder};
1837 #[cfg(c_bindings)]
1838 use {
1839 crate::offers::offer::OfferWithExplicitMetadataBuilder as OfferBuilder,
1840 crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder as RefundBuilder,
1841 };
1842
1843 trait ToBytes {
1844 fn to_bytes(&self) -> Vec<u8>;
1845 }
1846
1847 impl<'a> ToBytes for FullInvoiceTlvStreamRef<'a> {
1848 fn to_bytes(&self) -> Vec<u8> {
1849 let mut buffer = Vec::new();
1850 self.0.write(&mut buffer).unwrap();
1851 self.1.write(&mut buffer).unwrap();
1852 self.2.write(&mut buffer).unwrap();
1853 self.3.write(&mut buffer).unwrap();
1854 self.4.write(&mut buffer).unwrap();
1855 buffer
1856 }
1857 }
1858
1859 #[test]
1860 fn builds_invoice_for_offer_with_defaults() {
1861 let expanded_key = ExpandedKey::new([42; 32]);
1862 let entropy = FixedEntropy {};
1863 let nonce = Nonce::from_entropy_source(&entropy);
1864 let secp_ctx = Secp256k1::new();
1865 let payment_id = PaymentId([1; 32]);
1866 let encrypted_payment_id = expanded_key.crypt_for_offer(payment_id.0, nonce);
1867
1868 let payment_paths = payment_paths();
1869 let payment_hash = payment_hash();
1870 let now = now();
1871 let unsigned_invoice = OfferBuilder::new(recipient_pubkey())
1872 .amount_msats(1000)
1873 .build()
1874 .unwrap()
1875 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
1876 .unwrap()
1877 .build_and_sign()
1878 .unwrap()
1879 .respond_with_no_std(payment_paths.clone(), payment_hash, now)
1880 .unwrap()
1881 .build()
1882 .unwrap();
1883
1884 let mut buffer = Vec::new();
1885 unsigned_invoice.write(&mut buffer).unwrap();
1886
1887 assert_eq!(unsigned_invoice.bytes, buffer.as_slice());
1888 assert_eq!(unsigned_invoice.payer_metadata(), &encrypted_payment_id);
1889 assert_eq!(
1890 unsigned_invoice.offer_chains(),
1891 Some(vec![ChainHash::using_genesis_block(Network::Bitcoin)])
1892 );
1893 assert_eq!(unsigned_invoice.metadata(), None);
1894 assert_eq!(unsigned_invoice.amount(), Some(Amount::Bitcoin { amount_msats: 1000 }));
1895 assert_eq!(unsigned_invoice.description(), Some(PrintableString("")));
1896 assert_eq!(unsigned_invoice.offer_features(), Some(&OfferFeatures::empty()));
1897 assert_eq!(unsigned_invoice.absolute_expiry(), None);
1898 assert_eq!(unsigned_invoice.message_paths(), &[]);
1899 assert_eq!(unsigned_invoice.issuer(), None);
1900 assert_eq!(unsigned_invoice.supported_quantity(), Some(Quantity::One));
1901 assert_eq!(unsigned_invoice.signing_pubkey(), recipient_pubkey());
1902 assert_eq!(unsigned_invoice.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
1903 assert_eq!(unsigned_invoice.amount_msats(), 1000);
1904 assert_eq!(unsigned_invoice.invoice_request_features(), &InvoiceRequestFeatures::empty());
1905 assert_eq!(unsigned_invoice.quantity(), None);
1906 assert_eq!(unsigned_invoice.payer_note(), None);
1907 assert_eq!(unsigned_invoice.payment_paths(), payment_paths.as_slice());
1908 assert_eq!(unsigned_invoice.created_at(), now);
1909 assert_eq!(unsigned_invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
1910 #[cfg(feature = "std")]
1911 assert!(!unsigned_invoice.is_expired());
1912 assert_eq!(unsigned_invoice.payment_hash(), payment_hash);
1913 assert!(unsigned_invoice.fallbacks().is_empty());
1914 assert_eq!(unsigned_invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
1915
1916 match UnsignedBolt12Invoice::try_from(buffer) {
1917 Err(e) => panic!("error parsing unsigned invoice: {:?}", e),
1918 Ok(parsed) => {
1919 assert_eq!(parsed.bytes, unsigned_invoice.bytes);
1920 assert_eq!(parsed.tagged_hash, unsigned_invoice.tagged_hash);
1921 },
1922 }
1923
1924 #[cfg(c_bindings)]
1925 let mut unsigned_invoice = unsigned_invoice;
1926 let invoice = unsigned_invoice.sign(recipient_sign).unwrap();
1927
1928 let mut buffer = Vec::new();
1929 invoice.write(&mut buffer).unwrap();
1930
1931 assert_eq!(invoice.bytes, buffer.as_slice());
1932 assert_eq!(invoice.payer_metadata(), &encrypted_payment_id);
1933 assert_eq!(
1934 invoice.offer_chains(),
1935 Some(vec![ChainHash::using_genesis_block(Network::Bitcoin)])
1936 );
1937 assert_eq!(invoice.metadata(), None);
1938 assert_eq!(invoice.amount(), Some(Amount::Bitcoin { amount_msats: 1000 }));
1939 assert_eq!(invoice.description(), Some(PrintableString("")));
1940 assert_eq!(invoice.offer_features(), Some(&OfferFeatures::empty()));
1941 assert_eq!(invoice.absolute_expiry(), None);
1942 assert_eq!(invoice.message_paths(), &[]);
1943 assert_eq!(invoice.issuer(), None);
1944 assert_eq!(invoice.supported_quantity(), Some(Quantity::One));
1945 assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
1946 assert_eq!(invoice.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
1947 assert_eq!(invoice.amount_msats(), 1000);
1948 assert_eq!(invoice.invoice_request_features(), &InvoiceRequestFeatures::empty());
1949 assert_eq!(invoice.quantity(), None);
1950 assert_eq!(
1951 invoice.verify_using_payer_data(payment_id, nonce, &expanded_key, &secp_ctx),
1952 Ok(payment_id),
1953 );
1954 assert_eq!(invoice.payer_note(), None);
1955 assert_eq!(invoice.payment_paths(), payment_paths.as_slice());
1956 assert_eq!(invoice.created_at(), now);
1957 assert_eq!(invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
1958 #[cfg(feature = "std")]
1959 assert!(!invoice.is_expired());
1960 assert_eq!(invoice.payment_hash(), payment_hash);
1961 assert!(invoice.fallbacks().is_empty());
1962 assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
1963 assert!(!invoice.is_for_refund_without_paths());
1964
1965 let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice.bytes);
1966 assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
1967
1968 let digest = Message::from_digest(invoice.signable_hash());
1969 let pubkey = recipient_pubkey().into();
1970 let secp_ctx = Secp256k1::verification_only();
1971 assert!(secp_ctx.verify_schnorr(&invoice.signature, &digest, &pubkey).is_ok());
1972
1973 assert_eq!(
1974 invoice.as_tlv_stream(),
1975 (
1976 PayerTlvStreamRef { metadata: Some(&encrypted_payment_id.to_vec()) },
1977 OfferTlvStreamRef {
1978 chains: None,
1979 metadata: None,
1980 currency: None,
1981 amount: Some(1000),
1982 description: Some(&String::from("")),
1983 features: None,
1984 absolute_expiry: None,
1985 paths: None,
1986 issuer: None,
1987 quantity_max: None,
1988 issuer_id: Some(&recipient_pubkey()),
1989 },
1990 InvoiceRequestTlvStreamRef {
1991 chain: None,
1992 amount: None,
1993 features: None,
1994 quantity: None,
1995 payer_id: Some(&invoice.payer_signing_pubkey()),
1996 payer_note: None,
1997 paths: None,
1998 offer_from_hrn: None,
1999 },
2000 InvoiceTlvStreamRef {
2001 paths: Some(Iterable(
2002 payment_paths.iter().map(|path| path.inner_blinded_path())
2003 )),
2004 blindedpay: Some(Iterable(payment_paths.iter().map(|path| &path.payinfo))),
2005 created_at: Some(now.as_secs()),
2006 relative_expiry: None,
2007 payment_hash: Some(&payment_hash),
2008 amount: Some(1000),
2009 fallbacks: None,
2010 features: None,
2011 node_id: Some(&recipient_pubkey()),
2012 message_paths: None,
2013 },
2014 SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
2015 ExperimentalOfferTlvStreamRef { experimental_foo: None },
2016 ExperimentalInvoiceRequestTlvStreamRef { experimental_bar: None },
2017 ExperimentalInvoiceTlvStreamRef { experimental_baz: None },
2018 ),
2019 );
2020
2021 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2022 panic!("error parsing invoice: {:?}", e);
2023 }
2024 }
2025
2026 #[test]
2027 fn builds_invoice_for_refund_with_defaults() {
2028 let payment_paths = payment_paths();
2029 let payment_hash = payment_hash();
2030 let now = now();
2031 let invoice = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000)
2032 .unwrap()
2033 .build()
2034 .unwrap()
2035 .respond_with_no_std(payment_paths.clone(), payment_hash, recipient_pubkey(), now)
2036 .unwrap()
2037 .build()
2038 .unwrap()
2039 .sign(recipient_sign)
2040 .unwrap();
2041
2042 let mut buffer = Vec::new();
2043 invoice.write(&mut buffer).unwrap();
2044
2045 assert_eq!(invoice.bytes, buffer.as_slice());
2046 assert_eq!(invoice.payer_metadata(), &[1; 32]);
2047 assert_eq!(invoice.offer_chains(), None);
2048 assert_eq!(invoice.metadata(), None);
2049 assert_eq!(invoice.amount(), None);
2050 assert_eq!(invoice.description(), Some(PrintableString("")));
2051 assert_eq!(invoice.offer_features(), None);
2052 assert_eq!(invoice.absolute_expiry(), None);
2053 assert_eq!(invoice.message_paths(), &[]);
2054 assert_eq!(invoice.issuer(), None);
2055 assert_eq!(invoice.supported_quantity(), None);
2056 assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
2057 assert_eq!(invoice.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
2058 assert_eq!(invoice.amount_msats(), 1000);
2059 assert_eq!(invoice.invoice_request_features(), &InvoiceRequestFeatures::empty());
2060 assert_eq!(invoice.quantity(), None);
2061 assert_eq!(invoice.payer_signing_pubkey(), payer_pubkey());
2062 assert_eq!(invoice.payer_note(), None);
2063 assert_eq!(invoice.payment_paths(), payment_paths.as_slice());
2064 assert_eq!(invoice.created_at(), now);
2065 assert_eq!(invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
2066 #[cfg(feature = "std")]
2067 assert!(!invoice.is_expired());
2068 assert_eq!(invoice.payment_hash(), payment_hash);
2069 assert!(invoice.fallbacks().is_empty());
2070 assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
2071 assert!(invoice.is_for_refund_without_paths());
2072
2073 let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice.bytes);
2074 assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
2075
2076 assert_eq!(
2077 invoice.as_tlv_stream(),
2078 (
2079 PayerTlvStreamRef { metadata: Some(&vec![1; 32]) },
2080 OfferTlvStreamRef {
2081 chains: None,
2082 metadata: None,
2083 currency: None,
2084 amount: None,
2085 description: Some(&String::from("")),
2086 features: None,
2087 absolute_expiry: None,
2088 paths: None,
2089 issuer: None,
2090 quantity_max: None,
2091 issuer_id: None,
2092 },
2093 InvoiceRequestTlvStreamRef {
2094 chain: None,
2095 amount: Some(1000),
2096 features: None,
2097 quantity: None,
2098 payer_id: Some(&payer_pubkey()),
2099 payer_note: None,
2100 paths: None,
2101 offer_from_hrn: None,
2102 },
2103 InvoiceTlvStreamRef {
2104 paths: Some(Iterable(
2105 payment_paths.iter().map(|path| path.inner_blinded_path())
2106 )),
2107 blindedpay: Some(Iterable(payment_paths.iter().map(|path| &path.payinfo))),
2108 created_at: Some(now.as_secs()),
2109 relative_expiry: None,
2110 payment_hash: Some(&payment_hash),
2111 amount: Some(1000),
2112 fallbacks: None,
2113 features: None,
2114 node_id: Some(&recipient_pubkey()),
2115 message_paths: None,
2116 },
2117 SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
2118 ExperimentalOfferTlvStreamRef { experimental_foo: None },
2119 ExperimentalInvoiceRequestTlvStreamRef { experimental_bar: None },
2120 ExperimentalInvoiceTlvStreamRef { experimental_baz: None },
2121 ),
2122 );
2123
2124 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2125 panic!("error parsing invoice: {:?}", e);
2126 }
2127 }
2128
2129 #[cfg(feature = "std")]
2130 #[test]
2131 fn builds_invoice_from_offer_with_expiration() {
2132 let expanded_key = ExpandedKey::new([42; 32]);
2133 let entropy = FixedEntropy {};
2134 let nonce = Nonce::from_entropy_source(&entropy);
2135 let secp_ctx = Secp256k1::new();
2136 let payment_id = PaymentId([1; 32]);
2137
2138 let future_expiry = Duration::from_secs(u64::max_value());
2139 let past_expiry = Duration::from_secs(0);
2140
2141 if let Err(e) = OfferBuilder::new(recipient_pubkey())
2142 .amount_msats(1000)
2143 .absolute_expiry(future_expiry)
2144 .build()
2145 .unwrap()
2146 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2147 .unwrap()
2148 .build_and_sign()
2149 .unwrap()
2150 .respond_with(payment_paths(), payment_hash())
2151 .unwrap()
2152 .build()
2153 {
2154 panic!("error building invoice: {:?}", e);
2155 }
2156
2157 match OfferBuilder::new(recipient_pubkey())
2158 .amount_msats(1000)
2159 .absolute_expiry(past_expiry)
2160 .build()
2161 .unwrap()
2162 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2163 .unwrap()
2164 .build_unchecked_and_sign()
2165 .respond_with(payment_paths(), payment_hash())
2166 .unwrap()
2167 .build()
2168 {
2169 Ok(_) => panic!("expected error"),
2170 Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
2171 }
2172 }
2173
2174 #[cfg(feature = "std")]
2175 #[test]
2176 fn builds_invoice_from_refund_with_expiration() {
2177 let future_expiry = Duration::from_secs(u64::max_value());
2178 let past_expiry = Duration::from_secs(0);
2179
2180 if let Err(e) = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000)
2181 .unwrap()
2182 .absolute_expiry(future_expiry)
2183 .build()
2184 .unwrap()
2185 .respond_with(payment_paths(), payment_hash(), recipient_pubkey())
2186 .unwrap()
2187 .build()
2188 {
2189 panic!("error building invoice: {:?}", e);
2190 }
2191
2192 match RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000)
2193 .unwrap()
2194 .absolute_expiry(past_expiry)
2195 .build()
2196 .unwrap()
2197 .respond_with(payment_paths(), payment_hash(), recipient_pubkey())
2198 .unwrap()
2199 .build()
2200 {
2201 Ok(_) => panic!("expected error"),
2202 Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
2203 }
2204 }
2205
2206 #[test]
2207 fn builds_invoice_from_offer_using_derived_keys() {
2208 let node_id = recipient_pubkey();
2209 let expanded_key = ExpandedKey::new([42; 32]);
2210 let entropy = FixedEntropy {};
2211 let nonce = Nonce::from_entropy_source(&entropy);
2212 let secp_ctx = Secp256k1::new();
2213 let payment_id = PaymentId([1; 32]);
2214
2215 let blinded_path = BlindedMessagePath::from_blinded_path(
2216 pubkey(40),
2217 pubkey(41),
2218 vec![
2219 BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
2220 BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
2221 ],
2222 );
2223
2224 #[cfg(c_bindings)]
2225 use crate::offers::offer::OfferWithDerivedMetadataBuilder as OfferBuilder;
2226 let invoice_request =
2227 OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
2228 .amount_msats(1000)
2229 .path(blinded_path)
2230 .experimental_foo(42)
2231 .build()
2232 .unwrap()
2233 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2234 .unwrap()
2235 .build_and_sign()
2236 .unwrap();
2237
2238 if let Err(e) = invoice_request
2239 .clone()
2240 .verify_using_recipient_data(nonce, &expanded_key, &secp_ctx)
2241 .unwrap()
2242 .respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now())
2243 .unwrap()
2244 .build_and_sign(&secp_ctx)
2245 {
2246 panic!("error building invoice: {:?}", e);
2247 }
2248
2249 let expanded_key = ExpandedKey::new([41; 32]);
2250 assert!(invoice_request
2251 .verify_using_recipient_data(nonce, &expanded_key, &secp_ctx)
2252 .is_err());
2253
2254 let invoice_request =
2255 OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
2256 .amount_msats(1000)
2257 .experimental_foo(42)
2259 .build()
2260 .unwrap()
2261 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2262 .unwrap()
2263 .build_and_sign()
2264 .unwrap();
2265
2266 match invoice_request
2267 .verify_using_metadata(&expanded_key, &secp_ctx)
2268 .unwrap()
2269 .respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now())
2270 {
2271 Ok(_) => panic!("expected error"),
2272 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
2273 }
2274 }
2275
2276 #[test]
2277 fn builds_invoice_from_refund_using_derived_keys() {
2278 let expanded_key = ExpandedKey::new([42; 32]);
2279 let entropy = FixedEntropy {};
2280 let secp_ctx = Secp256k1::new();
2281
2282 let refund = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000)
2283 .unwrap()
2284 .experimental_foo(42)
2285 .build()
2286 .unwrap();
2287
2288 if let Err(e) = refund
2289 .respond_using_derived_keys_no_std(
2290 payment_paths(),
2291 payment_hash(),
2292 now(),
2293 &expanded_key,
2294 &entropy,
2295 )
2296 .unwrap()
2297 .build_and_sign(&secp_ctx)
2298 {
2299 panic!("error building invoice: {:?}", e);
2300 }
2301 }
2302
2303 #[test]
2304 fn builds_invoice_from_refund_with_path() {
2305 let node_id = payer_pubkey();
2306 let expanded_key = ExpandedKey::new([42; 32]);
2307 let entropy = FixedEntropy {};
2308 let secp_ctx = Secp256k1::new();
2309
2310 let blinded_path = BlindedMessagePath::from_blinded_path(
2311 pubkey(40),
2312 pubkey(41),
2313 vec![
2314 BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
2315 BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
2316 ],
2317 );
2318
2319 let refund = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000)
2320 .unwrap()
2321 .path(blinded_path)
2322 .build()
2323 .unwrap();
2324
2325 let invoice = refund
2326 .respond_using_derived_keys_no_std(
2327 payment_paths(),
2328 payment_hash(),
2329 now(),
2330 &expanded_key,
2331 &entropy,
2332 )
2333 .unwrap()
2334 .build_and_sign(&secp_ctx)
2335 .unwrap();
2336 assert!(!invoice.message_paths().is_empty());
2337 assert!(!invoice.is_for_refund_without_paths());
2338 }
2339
2340 #[test]
2341 fn builds_invoice_with_relative_expiry() {
2342 let expanded_key = ExpandedKey::new([42; 32]);
2343 let entropy = FixedEntropy {};
2344 let nonce = Nonce::from_entropy_source(&entropy);
2345 let secp_ctx = Secp256k1::new();
2346 let payment_id = PaymentId([1; 32]);
2347
2348 let now = now();
2349 let one_hour = Duration::from_secs(3600);
2350
2351 let invoice = OfferBuilder::new(recipient_pubkey())
2352 .amount_msats(1000)
2353 .build()
2354 .unwrap()
2355 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2356 .unwrap()
2357 .build_and_sign()
2358 .unwrap()
2359 .respond_with_no_std(payment_paths(), payment_hash(), now)
2360 .unwrap()
2361 .relative_expiry(one_hour.as_secs() as u32)
2362 .build()
2363 .unwrap()
2364 .sign(recipient_sign)
2365 .unwrap();
2366 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2367 #[cfg(feature = "std")]
2368 assert!(!invoice.is_expired());
2369 assert_eq!(invoice.relative_expiry(), one_hour);
2370 assert_eq!(tlv_stream.relative_expiry, Some(one_hour.as_secs() as u32));
2371
2372 let invoice = OfferBuilder::new(recipient_pubkey())
2373 .amount_msats(1000)
2374 .build()
2375 .unwrap()
2376 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2377 .unwrap()
2378 .build_and_sign()
2379 .unwrap()
2380 .respond_with_no_std(payment_paths(), payment_hash(), now - one_hour)
2381 .unwrap()
2382 .relative_expiry(one_hour.as_secs() as u32 - 1)
2383 .build()
2384 .unwrap()
2385 .sign(recipient_sign)
2386 .unwrap();
2387 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2388 #[cfg(feature = "std")]
2389 assert!(invoice.is_expired());
2390 assert_eq!(invoice.relative_expiry(), one_hour - Duration::from_secs(1));
2391 assert_eq!(tlv_stream.relative_expiry, Some(one_hour.as_secs() as u32 - 1));
2392 }
2393
2394 #[test]
2395 fn builds_invoice_with_amount_from_request() {
2396 let expanded_key = ExpandedKey::new([42; 32]);
2397 let entropy = FixedEntropy {};
2398 let nonce = Nonce::from_entropy_source(&entropy);
2399 let secp_ctx = Secp256k1::new();
2400 let payment_id = PaymentId([1; 32]);
2401
2402 let invoice = OfferBuilder::new(recipient_pubkey())
2403 .amount_msats(1000)
2404 .build()
2405 .unwrap()
2406 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2407 .unwrap()
2408 .amount_msats(1001)
2409 .unwrap()
2410 .build_and_sign()
2411 .unwrap()
2412 .respond_with_no_std(payment_paths(), payment_hash(), now())
2413 .unwrap()
2414 .build()
2415 .unwrap()
2416 .sign(recipient_sign)
2417 .unwrap();
2418 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2419 assert_eq!(invoice.amount_msats(), 1001);
2420 assert_eq!(tlv_stream.amount, Some(1001));
2421 }
2422
2423 #[test]
2424 fn builds_invoice_with_quantity_from_request() {
2425 let expanded_key = ExpandedKey::new([42; 32]);
2426 let entropy = FixedEntropy {};
2427 let nonce = Nonce::from_entropy_source(&entropy);
2428 let secp_ctx = Secp256k1::new();
2429 let payment_id = PaymentId([1; 32]);
2430
2431 let invoice = OfferBuilder::new(recipient_pubkey())
2432 .amount_msats(1000)
2433 .supported_quantity(Quantity::Unbounded)
2434 .build()
2435 .unwrap()
2436 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2437 .unwrap()
2438 .quantity(2)
2439 .unwrap()
2440 .build_and_sign()
2441 .unwrap()
2442 .respond_with_no_std(payment_paths(), payment_hash(), now())
2443 .unwrap()
2444 .build()
2445 .unwrap()
2446 .sign(recipient_sign)
2447 .unwrap();
2448 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2449 assert_eq!(invoice.amount_msats(), 2000);
2450 assert_eq!(tlv_stream.amount, Some(2000));
2451
2452 match OfferBuilder::new(recipient_pubkey())
2453 .amount_msats(1000)
2454 .supported_quantity(Quantity::Unbounded)
2455 .build()
2456 .unwrap()
2457 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2458 .unwrap()
2459 .quantity(u64::max_value())
2460 .unwrap()
2461 .build_unchecked_and_sign()
2462 .respond_with_no_std(payment_paths(), payment_hash(), now())
2463 {
2464 Ok(_) => panic!("expected error"),
2465 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
2466 }
2467 }
2468
2469 #[test]
2470 fn builds_invoice_with_fallback_address() {
2471 let expanded_key = ExpandedKey::new([42; 32]);
2472 let entropy = FixedEntropy {};
2473 let nonce = Nonce::from_entropy_source(&entropy);
2474 let secp_ctx = Secp256k1::new();
2475 let payment_id = PaymentId([1; 32]);
2476
2477 let script = ScriptBuf::new();
2478 let pubkey = bitcoin::key::PublicKey::new(recipient_pubkey());
2479 let x_only_pubkey = XOnlyPublicKey::from_keypair(&recipient_keys()).0;
2480 let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(x_only_pubkey);
2481
2482 let invoice = OfferBuilder::new(recipient_pubkey())
2483 .amount_msats(1000)
2484 .build()
2485 .unwrap()
2486 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2487 .unwrap()
2488 .build_and_sign()
2489 .unwrap()
2490 .respond_with_no_std(payment_paths(), payment_hash(), now())
2491 .unwrap()
2492 .fallback_v0_p2wsh(&script.wscript_hash())
2493 .fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
2494 .fallback_v1_p2tr_tweaked(&tweaked_pubkey)
2495 .build()
2496 .unwrap()
2497 .sign(recipient_sign)
2498 .unwrap();
2499 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2500 assert_eq!(
2501 invoice.fallbacks(),
2502 vec![
2503 Address::p2wsh(&script, Network::Bitcoin),
2504 Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin),
2505 Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
2506 ],
2507 );
2508 assert_eq!(
2509 tlv_stream.fallbacks,
2510 Some(&vec![
2511 FallbackAddress {
2512 version: WitnessVersion::V0.to_num(),
2513 program: Vec::from(script.wscript_hash().to_byte_array()),
2514 },
2515 FallbackAddress {
2516 version: WitnessVersion::V0.to_num(),
2517 program: Vec::from(pubkey.wpubkey_hash().unwrap().to_byte_array()),
2518 },
2519 FallbackAddress {
2520 version: WitnessVersion::V1.to_num(),
2521 program: Vec::from(&tweaked_pubkey.serialize()[..]),
2522 },
2523 ])
2524 );
2525 }
2526
2527 #[test]
2528 fn builds_invoice_with_allow_mpp() {
2529 let expanded_key = ExpandedKey::new([42; 32]);
2530 let entropy = FixedEntropy {};
2531 let nonce = Nonce::from_entropy_source(&entropy);
2532 let secp_ctx = Secp256k1::new();
2533 let payment_id = PaymentId([1; 32]);
2534
2535 let mut features = Bolt12InvoiceFeatures::empty();
2536 features.set_basic_mpp_optional();
2537
2538 let invoice = OfferBuilder::new(recipient_pubkey())
2539 .amount_msats(1000)
2540 .build()
2541 .unwrap()
2542 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2543 .unwrap()
2544 .build_and_sign()
2545 .unwrap()
2546 .respond_with_no_std(payment_paths(), payment_hash(), now())
2547 .unwrap()
2548 .allow_mpp()
2549 .build()
2550 .unwrap()
2551 .sign(recipient_sign)
2552 .unwrap();
2553 let (_, _, _, tlv_stream, _, _, _, _) = invoice.as_tlv_stream();
2554 assert_eq!(invoice.invoice_features(), &features);
2555 assert_eq!(tlv_stream.features, Some(&features));
2556 }
2557
2558 #[test]
2559 fn fails_signing_invoice() {
2560 let expanded_key = ExpandedKey::new([42; 32]);
2561 let entropy = FixedEntropy {};
2562 let nonce = Nonce::from_entropy_source(&entropy);
2563 let secp_ctx = Secp256k1::new();
2564 let payment_id = PaymentId([1; 32]);
2565
2566 match OfferBuilder::new(recipient_pubkey())
2567 .amount_msats(1000)
2568 .build()
2569 .unwrap()
2570 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2571 .unwrap()
2572 .build_and_sign()
2573 .unwrap()
2574 .respond_with_no_std(payment_paths(), payment_hash(), now())
2575 .unwrap()
2576 .build()
2577 .unwrap()
2578 .sign(fail_sign)
2579 {
2580 Ok(_) => panic!("expected error"),
2581 Err(e) => assert_eq!(e, SignError::Signing),
2582 }
2583
2584 match OfferBuilder::new(recipient_pubkey())
2585 .amount_msats(1000)
2586 .build()
2587 .unwrap()
2588 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2589 .unwrap()
2590 .build_and_sign()
2591 .unwrap()
2592 .respond_with_no_std(payment_paths(), payment_hash(), now())
2593 .unwrap()
2594 .build()
2595 .unwrap()
2596 .sign(payer_sign)
2597 {
2598 Ok(_) => panic!("expected error"),
2599 Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::IncorrectSignature)),
2600 }
2601 }
2602
2603 #[test]
2604 fn parses_invoice_with_payment_paths() {
2605 let expanded_key = ExpandedKey::new([42; 32]);
2606 let entropy = FixedEntropy {};
2607 let nonce = Nonce::from_entropy_source(&entropy);
2608 let secp_ctx = Secp256k1::new();
2609 let payment_id = PaymentId([1; 32]);
2610
2611 let invoice = OfferBuilder::new(recipient_pubkey())
2612 .amount_msats(1000)
2613 .build()
2614 .unwrap()
2615 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2616 .unwrap()
2617 .build_and_sign()
2618 .unwrap()
2619 .respond_with_no_std(payment_paths(), payment_hash(), now())
2620 .unwrap()
2621 .build()
2622 .unwrap()
2623 .sign(recipient_sign)
2624 .unwrap();
2625
2626 let mut buffer = Vec::new();
2627 invoice.write(&mut buffer).unwrap();
2628
2629 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2630 panic!("error parsing invoice: {:?}", e);
2631 }
2632
2633 let mut tlv_stream = invoice.as_tlv_stream();
2634 tlv_stream.3.paths = None;
2635
2636 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2637 Ok(_) => panic!("expected error"),
2638 Err(e) => {
2639 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths))
2640 },
2641 }
2642
2643 let mut tlv_stream = invoice.as_tlv_stream();
2644 tlv_stream.3.blindedpay = None;
2645
2646 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2647 Ok(_) => panic!("expected error"),
2648 Err(e) => assert_eq!(
2649 e,
2650 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)
2651 ),
2652 }
2653
2654 let empty_payment_paths = [];
2655 let mut tlv_stream = invoice.as_tlv_stream();
2656 tlv_stream.3.paths =
2657 Some(Iterable(empty_payment_paths.iter().map(|path| path.inner_blinded_path())));
2658
2659 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2660 Ok(_) => panic!("expected error"),
2661 Err(e) => {
2662 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths))
2663 },
2664 }
2665
2666 let mut payment_paths = payment_paths();
2667 payment_paths.pop();
2668 let mut tlv_stream = invoice.as_tlv_stream();
2669 tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|path| &path.payinfo)));
2670
2671 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2672 Ok(_) => panic!("expected error"),
2673 Err(e) => assert_eq!(
2674 e,
2675 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)
2676 ),
2677 }
2678 }
2679
2680 #[test]
2681 fn parses_invoice_with_created_at() {
2682 let expanded_key = ExpandedKey::new([42; 32]);
2683 let entropy = FixedEntropy {};
2684 let nonce = Nonce::from_entropy_source(&entropy);
2685 let secp_ctx = Secp256k1::new();
2686 let payment_id = PaymentId([1; 32]);
2687
2688 let invoice = OfferBuilder::new(recipient_pubkey())
2689 .amount_msats(1000)
2690 .build()
2691 .unwrap()
2692 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2693 .unwrap()
2694 .build_and_sign()
2695 .unwrap()
2696 .respond_with_no_std(payment_paths(), payment_hash(), now())
2697 .unwrap()
2698 .build()
2699 .unwrap()
2700 .sign(recipient_sign)
2701 .unwrap();
2702
2703 let mut buffer = Vec::new();
2704 invoice.write(&mut buffer).unwrap();
2705
2706 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2707 panic!("error parsing invoice: {:?}", e);
2708 }
2709
2710 let mut tlv_stream = invoice.as_tlv_stream();
2711 tlv_stream.3.created_at = None;
2712
2713 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2714 Ok(_) => panic!("expected error"),
2715 Err(e) => {
2716 assert_eq!(
2717 e,
2718 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingCreationTime)
2719 );
2720 },
2721 }
2722 }
2723
2724 #[test]
2725 fn parses_invoice_with_relative_expiry() {
2726 let expanded_key = ExpandedKey::new([42; 32]);
2727 let entropy = FixedEntropy {};
2728 let nonce = Nonce::from_entropy_source(&entropy);
2729 let secp_ctx = Secp256k1::new();
2730 let payment_id = PaymentId([1; 32]);
2731
2732 let invoice = OfferBuilder::new(recipient_pubkey())
2733 .amount_msats(1000)
2734 .build()
2735 .unwrap()
2736 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2737 .unwrap()
2738 .build_and_sign()
2739 .unwrap()
2740 .respond_with_no_std(payment_paths(), payment_hash(), now())
2741 .unwrap()
2742 .relative_expiry(3600)
2743 .build()
2744 .unwrap()
2745 .sign(recipient_sign)
2746 .unwrap();
2747
2748 let mut buffer = Vec::new();
2749 invoice.write(&mut buffer).unwrap();
2750
2751 match Bolt12Invoice::try_from(buffer) {
2752 Ok(invoice) => assert_eq!(invoice.relative_expiry(), Duration::from_secs(3600)),
2753 Err(e) => panic!("error parsing invoice: {:?}", e),
2754 }
2755 }
2756
2757 #[test]
2758 fn parses_invoice_with_payment_hash() {
2759 let expanded_key = ExpandedKey::new([42; 32]);
2760 let entropy = FixedEntropy {};
2761 let nonce = Nonce::from_entropy_source(&entropy);
2762 let secp_ctx = Secp256k1::new();
2763 let payment_id = PaymentId([1; 32]);
2764
2765 let invoice = OfferBuilder::new(recipient_pubkey())
2766 .amount_msats(1000)
2767 .build()
2768 .unwrap()
2769 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2770 .unwrap()
2771 .build_and_sign()
2772 .unwrap()
2773 .respond_with_no_std(payment_paths(), payment_hash(), now())
2774 .unwrap()
2775 .build()
2776 .unwrap()
2777 .sign(recipient_sign)
2778 .unwrap();
2779
2780 let mut buffer = Vec::new();
2781 invoice.write(&mut buffer).unwrap();
2782
2783 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2784 panic!("error parsing invoice: {:?}", e);
2785 }
2786
2787 let mut tlv_stream = invoice.as_tlv_stream();
2788 tlv_stream.3.payment_hash = None;
2789
2790 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2791 Ok(_) => panic!("expected error"),
2792 Err(e) => {
2793 assert_eq!(
2794 e,
2795 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaymentHash)
2796 );
2797 },
2798 }
2799 }
2800
2801 #[test]
2802 fn parses_invoice_with_amount() {
2803 let expanded_key = ExpandedKey::new([42; 32]);
2804 let entropy = FixedEntropy {};
2805 let nonce = Nonce::from_entropy_source(&entropy);
2806 let secp_ctx = Secp256k1::new();
2807 let payment_id = PaymentId([1; 32]);
2808
2809 let invoice = OfferBuilder::new(recipient_pubkey())
2810 .amount_msats(1000)
2811 .build()
2812 .unwrap()
2813 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2814 .unwrap()
2815 .build_and_sign()
2816 .unwrap()
2817 .respond_with_no_std(payment_paths(), payment_hash(), now())
2818 .unwrap()
2819 .build()
2820 .unwrap()
2821 .sign(recipient_sign)
2822 .unwrap();
2823
2824 let mut buffer = Vec::new();
2825 invoice.write(&mut buffer).unwrap();
2826
2827 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2828 panic!("error parsing invoice: {:?}", e);
2829 }
2830
2831 let mut tlv_stream = invoice.as_tlv_stream();
2832 tlv_stream.3.amount = None;
2833
2834 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2835 Ok(_) => panic!("expected error"),
2836 Err(e) => assert_eq!(
2837 e,
2838 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)
2839 ),
2840 }
2841 }
2842
2843 #[test]
2844 fn parses_invoice_with_allow_mpp() {
2845 let expanded_key = ExpandedKey::new([42; 32]);
2846 let entropy = FixedEntropy {};
2847 let nonce = Nonce::from_entropy_source(&entropy);
2848 let secp_ctx = Secp256k1::new();
2849 let payment_id = PaymentId([1; 32]);
2850
2851 let invoice = OfferBuilder::new(recipient_pubkey())
2852 .amount_msats(1000)
2853 .build()
2854 .unwrap()
2855 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2856 .unwrap()
2857 .build_and_sign()
2858 .unwrap()
2859 .respond_with_no_std(payment_paths(), payment_hash(), now())
2860 .unwrap()
2861 .allow_mpp()
2862 .build()
2863 .unwrap()
2864 .sign(recipient_sign)
2865 .unwrap();
2866
2867 let mut buffer = Vec::new();
2868 invoice.write(&mut buffer).unwrap();
2869
2870 match Bolt12Invoice::try_from(buffer) {
2871 Ok(invoice) => {
2872 let mut features = Bolt12InvoiceFeatures::empty();
2873 features.set_basic_mpp_optional();
2874 assert_eq!(invoice.invoice_features(), &features);
2875 },
2876 Err(e) => panic!("error parsing invoice: {:?}", e),
2877 }
2878 }
2879
2880 #[test]
2881 fn parses_invoice_with_fallback_address() {
2882 let expanded_key = ExpandedKey::new([42; 32]);
2883 let entropy = FixedEntropy {};
2884 let nonce = Nonce::from_entropy_source(&entropy);
2885 let secp_ctx = Secp256k1::new();
2886 let payment_id = PaymentId([1; 32]);
2887
2888 let script = ScriptBuf::new();
2889 let pubkey = bitcoin::key::PublicKey::new(recipient_pubkey());
2890 let x_only_pubkey = XOnlyPublicKey::from_keypair(&recipient_keys()).0;
2891 let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(x_only_pubkey);
2892
2893 let invoice_request = OfferBuilder::new(recipient_pubkey())
2894 .amount_msats(1000)
2895 .build()
2896 .unwrap()
2897 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2898 .unwrap()
2899 .build_and_sign()
2900 .unwrap();
2901 #[cfg(not(c_bindings))]
2902 let invoice_builder =
2903 invoice_request.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap();
2904 #[cfg(c_bindings)]
2905 let mut invoice_builder =
2906 invoice_request.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap();
2907 let invoice_builder = invoice_builder
2908 .fallback_v0_p2wsh(&script.wscript_hash())
2909 .fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
2910 .fallback_v1_p2tr_tweaked(&tweaked_pubkey);
2911 #[cfg(not(c_bindings))]
2912 let mut invoice_builder = invoice_builder;
2913
2914 let fallbacks = invoice_builder.invoice.fields_mut().fallbacks.as_mut().unwrap();
2916 fallbacks.push(FallbackAddress { version: 1, program: vec![0u8; 41] });
2918 fallbacks.push(FallbackAddress { version: 2, program: vec![0u8; 1] });
2919 fallbacks.push(FallbackAddress { version: 17, program: vec![0u8; 40] });
2920 fallbacks.push(FallbackAddress { version: 1, program: vec![0u8; 33] });
2922 fallbacks.push(FallbackAddress { version: 2, program: vec![0u8; 40] });
2923
2924 let invoice = invoice_builder.build().unwrap().sign(recipient_sign).unwrap();
2925 let mut buffer = Vec::new();
2926 invoice.write(&mut buffer).unwrap();
2927
2928 match Bolt12Invoice::try_from(buffer) {
2929 Ok(invoice) => {
2930 let v1_witness_program =
2931 WitnessProgram::new(WitnessVersion::V1, &[0u8; 33]).unwrap();
2932 let v2_witness_program =
2933 WitnessProgram::new(WitnessVersion::V2, &[0u8; 40]).unwrap();
2934 assert_eq!(
2935 invoice.fallbacks(),
2936 vec![
2937 Address::p2wsh(&script, Network::Bitcoin),
2938 Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin),
2939 Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
2940 Address::from_witness_program(v1_witness_program, Network::Bitcoin),
2941 Address::from_witness_program(v2_witness_program, Network::Bitcoin),
2942 ],
2943 );
2944 },
2945 Err(e) => panic!("error parsing invoice: {:?}", e),
2946 }
2947 }
2948
2949 #[test]
2950 fn parses_invoice_with_node_id() {
2951 let expanded_key = ExpandedKey::new([42; 32]);
2952 let entropy = FixedEntropy {};
2953 let nonce = Nonce::from_entropy_source(&entropy);
2954 let secp_ctx = Secp256k1::new();
2955 let payment_id = PaymentId([1; 32]);
2956
2957 let invoice = OfferBuilder::new(recipient_pubkey())
2958 .amount_msats(1000)
2959 .build()
2960 .unwrap()
2961 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2962 .unwrap()
2963 .build_and_sign()
2964 .unwrap()
2965 .respond_with_no_std(payment_paths(), payment_hash(), now())
2966 .unwrap()
2967 .build()
2968 .unwrap()
2969 .sign(recipient_sign)
2970 .unwrap();
2971
2972 let mut buffer = Vec::new();
2973 invoice.write(&mut buffer).unwrap();
2974
2975 if let Err(e) = Bolt12Invoice::try_from(buffer) {
2976 panic!("error parsing invoice: {:?}", e);
2977 }
2978
2979 let mut tlv_stream = invoice.as_tlv_stream();
2980 tlv_stream.3.node_id = None;
2981
2982 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2983 Ok(_) => panic!("expected error"),
2984 Err(e) => {
2985 assert_eq!(
2986 e,
2987 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey)
2988 );
2989 },
2990 }
2991
2992 let invalid_pubkey = payer_pubkey();
2993 let mut tlv_stream = invoice.as_tlv_stream();
2994 tlv_stream.3.node_id = Some(&invalid_pubkey);
2995
2996 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
2997 Ok(_) => panic!("expected error"),
2998 Err(e) => {
2999 assert_eq!(
3000 e,
3001 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey)
3002 );
3003 },
3004 }
3005 }
3006
3007 #[test]
3008 fn parses_invoice_with_node_id_from_blinded_path() {
3009 let expanded_key = ExpandedKey::new([42; 32]);
3010 let entropy = FixedEntropy {};
3011 let nonce = Nonce::from_entropy_source(&entropy);
3012 let secp_ctx = Secp256k1::new();
3013 let payment_id = PaymentId([1; 32]);
3014
3015 let paths = [
3016 BlindedMessagePath::from_blinded_path(
3017 pubkey(40),
3018 pubkey(41),
3019 vec![
3020 BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
3021 BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
3022 ],
3023 ),
3024 BlindedMessagePath::from_blinded_path(
3025 pubkey(40),
3026 pubkey(41),
3027 vec![
3028 BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
3029 BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
3030 ],
3031 ),
3032 ];
3033
3034 let blinded_node_id_sign = |message: &UnsignedBolt12Invoice| {
3035 let secp_ctx = Secp256k1::new();
3036 let keys =
3037 Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[46; 32]).unwrap());
3038 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3039 };
3040
3041 let invoice = OfferBuilder::new(recipient_pubkey())
3042 .clear_issuer_signing_pubkey()
3043 .amount_msats(1000)
3044 .path(paths[0].clone())
3045 .path(paths[1].clone())
3046 .build()
3047 .unwrap()
3048 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3049 .unwrap()
3050 .build_and_sign()
3051 .unwrap()
3052 .respond_with_no_std_using_signing_pubkey(
3053 payment_paths(),
3054 payment_hash(),
3055 now(),
3056 pubkey(46),
3057 )
3058 .unwrap()
3059 .build()
3060 .unwrap()
3061 .sign(blinded_node_id_sign)
3062 .unwrap();
3063
3064 let mut buffer = Vec::new();
3065 invoice.write(&mut buffer).unwrap();
3066
3067 if let Err(e) = Bolt12Invoice::try_from(buffer) {
3068 panic!("error parsing invoice: {:?}", e);
3069 }
3070
3071 let invoice = OfferBuilder::new(recipient_pubkey())
3072 .clear_issuer_signing_pubkey()
3073 .amount_msats(1000)
3074 .path(paths[0].clone())
3075 .path(paths[1].clone())
3076 .build()
3077 .unwrap()
3078 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3079 .unwrap()
3080 .build_and_sign()
3081 .unwrap()
3082 .respond_with_no_std_using_signing_pubkey(
3083 payment_paths(),
3084 payment_hash(),
3085 now(),
3086 recipient_pubkey(),
3087 )
3088 .unwrap()
3089 .build()
3090 .unwrap()
3091 .sign(recipient_sign)
3092 .unwrap();
3093
3094 let mut buffer = Vec::new();
3095 invoice.write(&mut buffer).unwrap();
3096
3097 match Bolt12Invoice::try_from(buffer) {
3098 Ok(_) => panic!("expected error"),
3099 Err(e) => {
3100 assert_eq!(
3101 e,
3102 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey)
3103 );
3104 },
3105 }
3106 }
3107
3108 #[test]
3109 fn fails_parsing_invoice_with_wrong_amount() {
3110 let expanded_key = ExpandedKey::new([42; 32]);
3111 let entropy = FixedEntropy {};
3112 let nonce = Nonce::from_entropy_source(&entropy);
3113 let secp_ctx = Secp256k1::new();
3114 let payment_id = PaymentId([1; 32]);
3115
3116 let invoice = OfferBuilder::new(recipient_pubkey())
3117 .amount_msats(1000)
3118 .build()
3119 .unwrap()
3120 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3121 .unwrap()
3122 .build_and_sign()
3123 .unwrap()
3124 .respond_with_no_std(payment_paths(), payment_hash(), now())
3125 .unwrap()
3126 .amount_msats_unchecked(2000)
3127 .build()
3128 .unwrap()
3129 .sign(recipient_sign)
3130 .unwrap();
3131
3132 let mut buffer = Vec::new();
3133 invoice.write(&mut buffer).unwrap();
3134
3135 match Bolt12Invoice::try_from(buffer) {
3136 Ok(_) => panic!("expected error"),
3137 Err(e) => assert_eq!(
3138 e,
3139 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)
3140 ),
3141 }
3142
3143 let invoice = OfferBuilder::new(recipient_pubkey())
3144 .amount_msats(1000)
3145 .build()
3146 .unwrap()
3147 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3148 .unwrap()
3149 .amount_msats(1000)
3150 .unwrap()
3151 .build_and_sign()
3152 .unwrap()
3153 .respond_with_no_std(payment_paths(), payment_hash(), now())
3154 .unwrap()
3155 .amount_msats_unchecked(2000)
3156 .build()
3157 .unwrap()
3158 .sign(recipient_sign)
3159 .unwrap();
3160
3161 let mut buffer = Vec::new();
3162 invoice.write(&mut buffer).unwrap();
3163
3164 match Bolt12Invoice::try_from(buffer) {
3165 Ok(_) => panic!("expected error"),
3166 Err(e) => assert_eq!(
3167 e,
3168 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)
3169 ),
3170 }
3171
3172 let invoice = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000)
3173 .unwrap()
3174 .build()
3175 .unwrap()
3176 .respond_using_derived_keys_no_std(
3177 payment_paths(),
3178 payment_hash(),
3179 now(),
3180 &expanded_key,
3181 &entropy,
3182 )
3183 .unwrap()
3184 .amount_msats_unchecked(2000)
3185 .build_and_sign(&secp_ctx)
3186 .unwrap();
3187
3188 let mut buffer = Vec::new();
3189 invoice.write(&mut buffer).unwrap();
3190
3191 match Bolt12Invoice::try_from(buffer) {
3192 Ok(_) => panic!("expected error"),
3193 Err(e) => assert_eq!(
3194 e,
3195 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)
3196 ),
3197 }
3198 }
3199
3200 #[test]
3201 fn fails_parsing_invoice_without_signature() {
3202 let expanded_key = ExpandedKey::new([42; 32]);
3203 let entropy = FixedEntropy {};
3204 let nonce = Nonce::from_entropy_source(&entropy);
3205 let secp_ctx = Secp256k1::new();
3206 let payment_id = PaymentId([1; 32]);
3207
3208 let mut buffer = Vec::new();
3209 OfferBuilder::new(recipient_pubkey())
3210 .amount_msats(1000)
3211 .build()
3212 .unwrap()
3213 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3214 .unwrap()
3215 .build_and_sign()
3216 .unwrap()
3217 .respond_with_no_std(payment_paths(), payment_hash(), now())
3218 .unwrap()
3219 .build()
3220 .unwrap()
3221 .contents
3222 .write(&mut buffer)
3223 .unwrap();
3224
3225 match Bolt12Invoice::try_from(buffer) {
3226 Ok(_) => panic!("expected error"),
3227 Err(e) => assert_eq!(
3228 e,
3229 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)
3230 ),
3231 }
3232 }
3233
3234 #[test]
3235 fn fails_parsing_invoice_with_invalid_signature() {
3236 let expanded_key = ExpandedKey::new([42; 32]);
3237 let entropy = FixedEntropy {};
3238 let nonce = Nonce::from_entropy_source(&entropy);
3239 let secp_ctx = Secp256k1::new();
3240 let payment_id = PaymentId([1; 32]);
3241
3242 let mut invoice = OfferBuilder::new(recipient_pubkey())
3243 .amount_msats(1000)
3244 .build()
3245 .unwrap()
3246 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3247 .unwrap()
3248 .build_and_sign()
3249 .unwrap()
3250 .respond_with_no_std(payment_paths(), payment_hash(), now())
3251 .unwrap()
3252 .build()
3253 .unwrap()
3254 .sign(recipient_sign)
3255 .unwrap();
3256 let last_signature_byte = invoice.bytes.last_mut().unwrap();
3257 *last_signature_byte = last_signature_byte.wrapping_add(1);
3258
3259 let mut buffer = Vec::new();
3260 invoice.write(&mut buffer).unwrap();
3261
3262 match Bolt12Invoice::try_from(buffer) {
3263 Ok(_) => panic!("expected error"),
3264 Err(e) => {
3265 assert_eq!(
3266 e,
3267 Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature)
3268 );
3269 },
3270 }
3271 }
3272
3273 #[test]
3274 fn parses_invoice_with_unknown_tlv_records() {
3275 let expanded_key = ExpandedKey::new([42; 32]);
3276 let entropy = FixedEntropy {};
3277 let nonce = Nonce::from_entropy_source(&entropy);
3278 let payment_id = PaymentId([1; 32]);
3279
3280 const UNKNOWN_ODD_TYPE: u64 = INVOICE_TYPES.end - 1;
3281 assert!(UNKNOWN_ODD_TYPE % 2 == 1);
3282
3283 let secp_ctx = Secp256k1::new();
3284 let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
3285 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
3286 .amount_msats(1000)
3287 .build()
3288 .unwrap()
3289 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3290 .unwrap()
3291 .build_and_sign()
3292 .unwrap()
3293 .respond_with_no_std(payment_paths(), payment_hash(), now())
3294 .unwrap()
3295 .build()
3296 .unwrap();
3297
3298 let mut unknown_bytes = Vec::new();
3299 BigSize(UNKNOWN_ODD_TYPE).write(&mut unknown_bytes).unwrap();
3300 BigSize(32).write(&mut unknown_bytes).unwrap();
3301 [42u8; 32].write(&mut unknown_bytes).unwrap();
3302
3303 unsigned_invoice.bytes.extend_from_slice(&unknown_bytes);
3304 unsigned_invoice.tagged_hash =
3305 TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &unsigned_invoice.bytes);
3306
3307 let invoice = unsigned_invoice
3308 .sign(|message: &UnsignedBolt12Invoice| {
3309 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3310 })
3311 .unwrap();
3312
3313 let mut encoded_invoice = Vec::new();
3314 invoice.write(&mut encoded_invoice).unwrap();
3315
3316 match Bolt12Invoice::try_from(encoded_invoice.clone()) {
3317 Ok(invoice) => assert_eq!(invoice.bytes, encoded_invoice),
3318 Err(e) => panic!("error parsing invoice: {:?}", e),
3319 }
3320
3321 const UNKNOWN_EVEN_TYPE: u64 = INVOICE_TYPES.end - 2;
3322 assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
3323
3324 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
3325 .amount_msats(1000)
3326 .build()
3327 .unwrap()
3328 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3329 .unwrap()
3330 .build_and_sign()
3331 .unwrap()
3332 .respond_with_no_std(payment_paths(), payment_hash(), now())
3333 .unwrap()
3334 .build()
3335 .unwrap();
3336
3337 let mut unknown_bytes = Vec::new();
3338 BigSize(UNKNOWN_EVEN_TYPE).write(&mut unknown_bytes).unwrap();
3339 BigSize(32).write(&mut unknown_bytes).unwrap();
3340 [42u8; 32].write(&mut unknown_bytes).unwrap();
3341
3342 unsigned_invoice.bytes.extend_from_slice(&unknown_bytes);
3343 unsigned_invoice.tagged_hash =
3344 TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &unsigned_invoice.bytes);
3345
3346 let invoice = unsigned_invoice
3347 .sign(|message: &UnsignedBolt12Invoice| {
3348 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3349 })
3350 .unwrap();
3351
3352 let mut encoded_invoice = Vec::new();
3353 invoice.write(&mut encoded_invoice).unwrap();
3354
3355 match Bolt12Invoice::try_from(encoded_invoice) {
3356 Ok(_) => panic!("expected error"),
3357 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
3358 }
3359 }
3360
3361 #[test]
3362 fn parses_invoice_with_experimental_tlv_records() {
3363 let expanded_key = ExpandedKey::new([42; 32]);
3364 let entropy = FixedEntropy {};
3365 let nonce = Nonce::from_entropy_source(&entropy);
3366 let payment_id = PaymentId([1; 32]);
3367
3368 let secp_ctx = Secp256k1::new();
3369 let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
3370 let invoice = OfferBuilder::new(keys.public_key())
3371 .amount_msats(1000)
3372 .build()
3373 .unwrap()
3374 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3375 .unwrap()
3376 .build_and_sign()
3377 .unwrap()
3378 .respond_with_no_std(payment_paths(), payment_hash(), now())
3379 .unwrap()
3380 .experimental_baz(42)
3381 .build()
3382 .unwrap()
3383 .sign(|message: &UnsignedBolt12Invoice| {
3384 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3385 })
3386 .unwrap();
3387
3388 let mut encoded_invoice = Vec::new();
3389 invoice.write(&mut encoded_invoice).unwrap();
3390
3391 assert!(Bolt12Invoice::try_from(encoded_invoice).is_ok());
3392
3393 const UNKNOWN_ODD_TYPE: u64 = EXPERIMENTAL_INVOICE_TYPES.start + 1;
3394 assert!(UNKNOWN_ODD_TYPE % 2 == 1);
3395
3396 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
3397 .amount_msats(1000)
3398 .build()
3399 .unwrap()
3400 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3401 .unwrap()
3402 .build_and_sign()
3403 .unwrap()
3404 .respond_with_no_std(payment_paths(), payment_hash(), now())
3405 .unwrap()
3406 .build()
3407 .unwrap();
3408
3409 let mut unknown_bytes = Vec::new();
3410 BigSize(UNKNOWN_ODD_TYPE).write(&mut unknown_bytes).unwrap();
3411 BigSize(32).write(&mut unknown_bytes).unwrap();
3412 [42u8; 32].write(&mut unknown_bytes).unwrap();
3413
3414 unsigned_invoice.experimental_bytes.extend_from_slice(&unknown_bytes);
3415
3416 let tlv_stream = TlvStream::new(&unsigned_invoice.bytes)
3417 .chain(TlvStream::new(&unsigned_invoice.experimental_bytes));
3418 unsigned_invoice.tagged_hash = TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
3419
3420 let invoice = unsigned_invoice
3421 .sign(|message: &UnsignedBolt12Invoice| {
3422 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3423 })
3424 .unwrap();
3425
3426 let mut encoded_invoice = Vec::new();
3427 invoice.write(&mut encoded_invoice).unwrap();
3428
3429 match Bolt12Invoice::try_from(encoded_invoice.clone()) {
3430 Ok(invoice) => assert_eq!(invoice.bytes, encoded_invoice),
3431 Err(e) => panic!("error parsing invoice: {:?}", e),
3432 }
3433
3434 const UNKNOWN_EVEN_TYPE: u64 = EXPERIMENTAL_INVOICE_TYPES.start;
3435 assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
3436
3437 let mut unsigned_invoice = OfferBuilder::new(keys.public_key())
3438 .amount_msats(1000)
3439 .build()
3440 .unwrap()
3441 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3442 .unwrap()
3443 .build_and_sign()
3444 .unwrap()
3445 .respond_with_no_std(payment_paths(), payment_hash(), now())
3446 .unwrap()
3447 .build()
3448 .unwrap();
3449
3450 let mut unknown_bytes = Vec::new();
3451 BigSize(UNKNOWN_EVEN_TYPE).write(&mut unknown_bytes).unwrap();
3452 BigSize(32).write(&mut unknown_bytes).unwrap();
3453 [42u8; 32].write(&mut unknown_bytes).unwrap();
3454
3455 unsigned_invoice.experimental_bytes.extend_from_slice(&unknown_bytes);
3456
3457 let tlv_stream = TlvStream::new(&unsigned_invoice.bytes)
3458 .chain(TlvStream::new(&unsigned_invoice.experimental_bytes));
3459 unsigned_invoice.tagged_hash = TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
3460
3461 let invoice = unsigned_invoice
3462 .sign(|message: &UnsignedBolt12Invoice| {
3463 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3464 })
3465 .unwrap();
3466
3467 let mut encoded_invoice = Vec::new();
3468 invoice.write(&mut encoded_invoice).unwrap();
3469
3470 match Bolt12Invoice::try_from(encoded_invoice) {
3471 Ok(_) => panic!("expected error"),
3472 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
3473 }
3474
3475 let invoice = OfferBuilder::new(keys.public_key())
3476 .amount_msats(1000)
3477 .build()
3478 .unwrap()
3479 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3480 .unwrap()
3481 .build_and_sign()
3482 .unwrap()
3483 .respond_with_no_std(payment_paths(), payment_hash(), now())
3484 .unwrap()
3485 .build()
3486 .unwrap()
3487 .sign(|message: &UnsignedBolt12Invoice| {
3488 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
3489 })
3490 .unwrap();
3491
3492 let mut encoded_invoice = Vec::new();
3493 invoice.write(&mut encoded_invoice).unwrap();
3494
3495 BigSize(UNKNOWN_ODD_TYPE).write(&mut encoded_invoice).unwrap();
3496 BigSize(32).write(&mut encoded_invoice).unwrap();
3497 [42u8; 32].write(&mut encoded_invoice).unwrap();
3498
3499 match Bolt12Invoice::try_from(encoded_invoice) {
3500 Ok(_) => panic!("expected error"),
3501 Err(e) => assert_eq!(
3502 e,
3503 Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature)
3504 ),
3505 }
3506 }
3507
3508 #[test]
3509 fn fails_parsing_invoice_with_out_of_range_tlv_records() {
3510 let expanded_key = ExpandedKey::new([42; 32]);
3511 let entropy = FixedEntropy {};
3512 let nonce = Nonce::from_entropy_source(&entropy);
3513 let secp_ctx = Secp256k1::new();
3514 let payment_id = PaymentId([1; 32]);
3515
3516 let invoice = OfferBuilder::new(recipient_pubkey())
3517 .amount_msats(1000)
3518 .build()
3519 .unwrap()
3520 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3521 .unwrap()
3522 .build_and_sign()
3523 .unwrap()
3524 .respond_with_no_std(payment_paths(), payment_hash(), now())
3525 .unwrap()
3526 .build()
3527 .unwrap()
3528 .sign(recipient_sign)
3529 .unwrap();
3530
3531 let mut encoded_invoice = Vec::new();
3532 invoice.write(&mut encoded_invoice).unwrap();
3533 BigSize(1002).write(&mut encoded_invoice).unwrap();
3534 BigSize(32).write(&mut encoded_invoice).unwrap();
3535 [42u8; 32].write(&mut encoded_invoice).unwrap();
3536
3537 match Bolt12Invoice::try_from(encoded_invoice) {
3538 Ok(_) => panic!("expected error"),
3539 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
3540 }
3541 }
3542
3543 #[test]
3544 fn fails_parsing_invoice_with_message_paths() {
3545 let expanded_key = ExpandedKey::new([42; 32]);
3546 let entropy = FixedEntropy {};
3547 let nonce = Nonce::from_entropy_source(&entropy);
3548 let secp_ctx = Secp256k1::new();
3549 let payment_id = PaymentId([1; 32]);
3550
3551 let invoice = OfferBuilder::new(recipient_pubkey())
3552 .amount_msats(1000)
3553 .build()
3554 .unwrap()
3555 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3556 .unwrap()
3557 .build_and_sign()
3558 .unwrap()
3559 .respond_with_no_std(payment_paths(), payment_hash(), now())
3560 .unwrap()
3561 .build()
3562 .unwrap()
3563 .sign(recipient_sign)
3564 .unwrap();
3565
3566 let blinded_path = BlindedMessagePath::from_blinded_path(
3567 pubkey(40),
3568 pubkey(41),
3569 vec![
3570 BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
3571 BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 44] },
3572 ],
3573 );
3574
3575 let mut tlv_stream = invoice.as_tlv_stream();
3576 let message_paths = vec![blinded_path];
3577 tlv_stream.3.message_paths = Some(&message_paths);
3578
3579 match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
3580 Ok(_) => panic!("expected error"),
3581 Err(e) => assert_eq!(
3582 e,
3583 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedPaths)
3584 ),
3585 }
3586 }
3587
3588 #[test]
3589 fn invoice_offer_id_matches_offer_id() {
3590 let expanded_key = ExpandedKey::new([42; 32]);
3591 let entropy = FixedEntropy {};
3592 let nonce = Nonce::from_entropy_source(&entropy);
3593 let secp_ctx = Secp256k1::new();
3594 let payment_id = PaymentId([1; 32]);
3595
3596 let offer = OfferBuilder::new(recipient_pubkey()).amount_msats(1000).build().unwrap();
3597
3598 let offer_id = offer.id();
3599
3600 let invoice_request = offer
3601 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3602 .unwrap()
3603 .build_and_sign()
3604 .unwrap();
3605
3606 let invoice = invoice_request
3607 .respond_with_no_std(payment_paths(), payment_hash(), now())
3608 .unwrap()
3609 .build()
3610 .unwrap()
3611 .sign(recipient_sign)
3612 .unwrap();
3613
3614 assert_eq!(invoice.offer_id(), Some(offer_id));
3615 }
3616
3617 #[test]
3618 fn refund_invoice_has_no_offer_id() {
3619 let refund =
3620 RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap().build().unwrap();
3621
3622 let invoice = refund
3623 .respond_with_no_std(payment_paths(), payment_hash(), recipient_pubkey(), now())
3624 .unwrap()
3625 .build()
3626 .unwrap()
3627 .sign(recipient_sign)
3628 .unwrap();
3629
3630 assert_eq!(invoice.offer_id(), None);
3631 }
3632
3633 #[test]
3634 fn verifies_invoice_signature_with_tagged_hash() {
3635 let secp_ctx = Secp256k1::new();
3636 let expanded_key = ExpandedKey::new([42; 32]);
3637 let entropy = FixedEntropy {};
3638 let nonce = Nonce::from_entropy_source(&entropy);
3639 let node_id = recipient_pubkey();
3640 let payment_paths = payment_paths();
3641 let now = Duration::from_secs(123456);
3642 let payment_id = PaymentId([1; 32]);
3643
3644 let offer = OfferBuilder::new(node_id).amount_msats(1000).build().unwrap();
3645
3646 let invoice_request = offer
3647 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3648 .unwrap()
3649 .build_and_sign()
3650 .unwrap();
3651
3652 let invoice = invoice_request
3653 .respond_with_no_std(payment_paths, payment_hash(), now)
3654 .unwrap()
3655 .build()
3656 .unwrap()
3657 .sign(recipient_sign)
3658 .unwrap();
3659
3660 let issuer_sign_pubkey = offer.issuer_signing_pubkey().unwrap();
3661 let tagged_hash = invoice.tagged_hash();
3662 let signature = invoice.signature();
3663 assert!(merkle::verify_signature(&signature, tagged_hash, issuer_sign_pubkey).is_ok());
3664 }
3665}