Implement non-strict forwarding
[rust-lightning] / lightning / src / offers / static_invoice.rs
1 // This file is Copyright its original authors, visible in version control
2 // history.
3 //
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
8 // licenses.
9
10 //! Data structures and encoding for static BOLT 12 invoices.
11
12 use crate::blinded_path::BlindedPath;
13 use crate::io;
14 use crate::ln::features::{Bolt12InvoiceFeatures, OfferFeatures};
15 use crate::ln::inbound_payment::ExpandedKey;
16 use crate::ln::msgs::DecodeError;
17 use crate::offers::invoice::{
18         check_invoice_signing_pubkey, construct_payment_paths, filter_fallbacks, BlindedPathIter,
19         BlindedPayInfo, BlindedPayInfoIter, FallbackAddress, InvoiceTlvStream, InvoiceTlvStreamRef,
20 };
21 use crate::offers::invoice_macros::{invoice_accessors_common, invoice_builder_methods_common};
22 use crate::offers::merkle::{
23         self, SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash,
24 };
25 use crate::offers::offer::{
26         Amount, Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef, Quantity,
27 };
28 use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage};
29 use crate::util::ser::{
30         HighZeroBytesDroppedBigSize, Iterable, SeekReadable, WithoutLength, Writeable, Writer,
31 };
32 use crate::util::string::PrintableString;
33 use bitcoin::address::Address;
34 use bitcoin::blockdata::constants::ChainHash;
35 use bitcoin::secp256k1::schnorr::Signature;
36 use bitcoin::secp256k1::{self, Keypair, PublicKey, Secp256k1};
37 use core::time::Duration;
38
39 #[cfg(feature = "std")]
40 use crate::offers::invoice::is_expired;
41
42 #[allow(unused_imports)]
43 use crate::prelude::*;
44
45 /// Static invoices default to expiring after 2 weeks.
46 const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(3600 * 24 * 14);
47
48 /// Tag for the hash function used when signing a [`StaticInvoice`]'s merkle root.
49 pub const SIGNATURE_TAG: &'static str = concat!("lightning", "static_invoice", "signature");
50
51 /// A `StaticInvoice` is a reusable payment request corresponding to an [`Offer`].
52 ///
53 /// A static invoice may be sent in response to an [`InvoiceRequest`] and includes all the
54 /// information needed to pay the recipient. However, unlike [`Bolt12Invoice`]s, static invoices do
55 /// not provide proof-of-payment. Therefore, [`Bolt12Invoice`]s should be preferred when the
56 /// recipient is online to provide one.
57 ///
58 /// [`Offer`]: crate::offers::offer::Offer
59 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
60 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
61 #[derive(Clone, Debug)]
62 pub struct StaticInvoice {
63         bytes: Vec<u8>,
64         contents: InvoiceContents,
65         signature: Signature,
66 }
67
68 /// The contents of a [`StaticInvoice`] for responding to an [`Offer`].
69 ///
70 /// [`Offer`]: crate::offers::offer::Offer
71 #[derive(Clone, Debug)]
72 struct InvoiceContents {
73         offer: OfferContents,
74         payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
75         created_at: Duration,
76         relative_expiry: Option<Duration>,
77         fallbacks: Option<Vec<FallbackAddress>>,
78         features: Bolt12InvoiceFeatures,
79         signing_pubkey: PublicKey,
80         message_paths: Vec<BlindedPath>,
81 }
82
83 /// Builds a [`StaticInvoice`] from an [`Offer`].
84 ///
85 /// [`Offer`]: crate::offers::offer::Offer
86 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
87 // TODO: add module-level docs and link here
88 pub struct StaticInvoiceBuilder<'a> {
89         offer_bytes: &'a Vec<u8>,
90         invoice: InvoiceContents,
91         keys: Keypair,
92 }
93
94 impl<'a> StaticInvoiceBuilder<'a> {
95         /// Initialize a [`StaticInvoiceBuilder`] from the given [`Offer`].
96         ///
97         /// Unless [`StaticInvoiceBuilder::relative_expiry`] is set, the invoice will expire 24 hours
98         /// after `created_at`.
99         pub fn for_offer_using_derived_keys<T: secp256k1::Signing>(
100                 offer: &'a Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
101                 message_paths: Vec<BlindedPath>, created_at: Duration, expanded_key: &ExpandedKey,
102                 secp_ctx: &Secp256k1<T>,
103         ) -> Result<Self, Bolt12SemanticError> {
104                 if offer.chains().len() > 1 {
105                         return Err(Bolt12SemanticError::UnexpectedChain);
106                 }
107
108                 if payment_paths.is_empty() || message_paths.is_empty() || offer.paths().is_empty() {
109                         return Err(Bolt12SemanticError::MissingPaths);
110                 }
111
112                 let offer_signing_pubkey =
113                         offer.signing_pubkey().ok_or(Bolt12SemanticError::MissingSigningPubkey)?;
114
115                 let keys = offer
116                         .verify(&expanded_key, &secp_ctx)
117                         .map_err(|()| Bolt12SemanticError::InvalidMetadata)?
118                         .1
119                         .ok_or(Bolt12SemanticError::MissingSigningPubkey)?;
120
121                 let signing_pubkey = keys.public_key();
122                 if signing_pubkey != offer_signing_pubkey {
123                         return Err(Bolt12SemanticError::InvalidSigningPubkey);
124                 }
125
126                 let invoice =
127                         InvoiceContents::new(offer, payment_paths, message_paths, created_at, signing_pubkey);
128
129                 Ok(Self { offer_bytes: &offer.bytes, invoice, keys })
130         }
131
132         /// Builds a signed [`StaticInvoice`] after checking for valid semantics.
133         pub fn build_and_sign<T: secp256k1::Signing>(
134                 self, secp_ctx: &Secp256k1<T>,
135         ) -> Result<StaticInvoice, Bolt12SemanticError> {
136                 #[cfg(feature = "std")]
137                 {
138                         if self.invoice.is_offer_expired() {
139                                 return Err(Bolt12SemanticError::AlreadyExpired);
140                         }
141                 }
142
143                 #[cfg(not(feature = "std"))]
144                 {
145                         if self.invoice.is_offer_expired_no_std(self.invoice.created_at()) {
146                                 return Err(Bolt12SemanticError::AlreadyExpired);
147                         }
148                 }
149
150                 let Self { offer_bytes, invoice, keys } = self;
151                 let unsigned_invoice = UnsignedStaticInvoice::new(&offer_bytes, invoice);
152                 let invoice = unsigned_invoice
153                         .sign(|message: &UnsignedStaticInvoice| {
154                                 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.tagged_hash.as_digest(), &keys))
155                         })
156                         .unwrap();
157                 Ok(invoice)
158         }
159
160         invoice_builder_methods_common!(self, Self, self.invoice, Self, self, S, StaticInvoice, mut);
161 }
162
163 /// A semantically valid [`StaticInvoice`] that hasn't been signed.
164 pub struct UnsignedStaticInvoice {
165         bytes: Vec<u8>,
166         contents: InvoiceContents,
167         tagged_hash: TaggedHash,
168 }
169
170 macro_rules! invoice_accessors { ($self: ident, $contents: expr) => {
171         /// The chain that must be used when paying the invoice. [`StaticInvoice`]s currently can only be
172         /// created from offers that support a single chain.
173         pub fn chain(&$self) -> ChainHash {
174                 $contents.chain()
175         }
176
177         /// Opaque bytes set by the originating [`Offer::metadata`].
178         ///
179         /// [`Offer::metadata`]: crate::offers::offer::Offer::metadata
180         pub fn metadata(&$self) -> Option<&Vec<u8>> {
181                 $contents.metadata()
182         }
183
184         /// The minimum amount required for a successful payment of a single item.
185         ///
186         /// From [`Offer::amount`].
187         ///
188         /// [`Offer::amount`]: crate::offers::offer::Offer::amount
189         pub fn amount(&$self) -> Option<Amount> {
190                 $contents.amount()
191         }
192
193         /// Features pertaining to the originating [`Offer`], from [`Offer::offer_features`].
194         ///
195         /// [`Offer`]: crate::offers::offer::Offer
196         /// [`Offer::offer_features`]: crate::offers::offer::Offer::offer_features
197         pub fn offer_features(&$self) -> &OfferFeatures {
198                 $contents.offer_features()
199         }
200
201         /// A complete description of the purpose of the originating offer, from [`Offer::description`].
202         ///
203         /// [`Offer::description`]: crate::offers::offer::Offer::description
204         pub fn description(&$self) -> Option<PrintableString> {
205                 $contents.description()
206         }
207
208         /// Duration since the Unix epoch when an invoice should no longer be requested, from
209         /// [`Offer::absolute_expiry`].
210         ///
211         /// [`Offer::absolute_expiry`]: crate::offers::offer::Offer::absolute_expiry
212         pub fn absolute_expiry(&$self) -> Option<Duration> {
213                 $contents.absolute_expiry()
214         }
215
216         /// The issuer of the offer, from [`Offer::issuer`].
217         ///
218         /// [`Offer::issuer`]: crate::offers::offer::Offer::issuer
219         pub fn issuer(&$self) -> Option<PrintableString> {
220                 $contents.issuer()
221         }
222
223         /// Paths to the node that may supply the invoice on the recipient's behalf, originating from
224         /// publicly reachable nodes. Taken from [`Offer::paths`].
225         ///
226         /// [`Offer::paths`]: crate::offers::offer::Offer::paths
227         pub fn offer_message_paths(&$self) -> &[BlindedPath] {
228                 $contents.offer_message_paths()
229         }
230
231         /// Paths to the recipient for indicating that a held HTLC is available to claim when they next
232         /// come online.
233         pub fn message_paths(&$self) -> &[BlindedPath] {
234                 $contents.message_paths()
235         }
236
237         /// The quantity of items supported, from [`Offer::supported_quantity`].
238         ///
239         /// [`Offer::supported_quantity`]: crate::offers::offer::Offer::supported_quantity
240         pub fn supported_quantity(&$self) -> Quantity {
241                 $contents.supported_quantity()
242         }
243 } }
244
245 impl UnsignedStaticInvoice {
246         fn new(offer_bytes: &Vec<u8>, contents: InvoiceContents) -> Self {
247                 let (_, invoice_tlv_stream) = contents.as_tlv_stream();
248                 let offer_bytes = WithoutLength(offer_bytes);
249                 let unsigned_tlv_stream = (offer_bytes, invoice_tlv_stream);
250
251                 let mut bytes = Vec::new();
252                 unsigned_tlv_stream.write(&mut bytes).unwrap();
253
254                 let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
255
256                 Self { contents, tagged_hash, bytes }
257         }
258
259         /// Signs the [`TaggedHash`] of the invoice using the given function.
260         ///
261         /// Note: The hash computation may have included unknown, odd TLV records.
262         pub fn sign<F: SignStaticInvoiceFn>(mut self, sign: F) -> Result<StaticInvoice, SignError> {
263                 let pubkey = self.contents.signing_pubkey;
264                 let signature = merkle::sign_message(sign, &self, pubkey)?;
265
266                 // Append the signature TLV record to the bytes.
267                 let signature_tlv_stream = SignatureTlvStreamRef { signature: Some(&signature) };
268                 signature_tlv_stream.write(&mut self.bytes).unwrap();
269
270                 Ok(StaticInvoice { bytes: self.bytes, contents: self.contents, signature })
271         }
272
273         invoice_accessors_common!(self, self.contents, StaticInvoice);
274         invoice_accessors!(self, self.contents);
275 }
276
277 impl AsRef<TaggedHash> for UnsignedStaticInvoice {
278         fn as_ref(&self) -> &TaggedHash {
279                 &self.tagged_hash
280         }
281 }
282
283 /// A function for signing an [`UnsignedStaticInvoice`].
284 pub trait SignStaticInvoiceFn {
285         /// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
286         fn sign_invoice(&self, message: &UnsignedStaticInvoice) -> Result<Signature, ()>;
287 }
288
289 impl<F> SignStaticInvoiceFn for F
290 where
291         F: Fn(&UnsignedStaticInvoice) -> Result<Signature, ()>,
292 {
293         fn sign_invoice(&self, message: &UnsignedStaticInvoice) -> Result<Signature, ()> {
294                 self(message)
295         }
296 }
297
298 impl<F> SignFn<UnsignedStaticInvoice> for F
299 where
300         F: SignStaticInvoiceFn,
301 {
302         fn sign(&self, message: &UnsignedStaticInvoice) -> Result<Signature, ()> {
303                 self.sign_invoice(message)
304         }
305 }
306
307 impl StaticInvoice {
308         invoice_accessors_common!(self, self.contents, StaticInvoice);
309         invoice_accessors!(self, self.contents);
310
311         /// Signature of the invoice verified using [`StaticInvoice::signing_pubkey`].
312         pub fn signature(&self) -> Signature {
313                 self.signature
314         }
315 }
316
317 impl InvoiceContents {
318         #[cfg(feature = "std")]
319         fn is_offer_expired(&self) -> bool {
320                 self.offer.is_expired()
321         }
322
323         #[cfg(not(feature = "std"))]
324         fn is_offer_expired_no_std(&self, duration_since_epoch: Duration) -> bool {
325                 self.offer.is_expired_no_std(duration_since_epoch)
326         }
327
328         fn new(
329                 offer: &Offer, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
330                 message_paths: Vec<BlindedPath>, created_at: Duration, signing_pubkey: PublicKey,
331         ) -> Self {
332                 Self {
333                         offer: offer.contents.clone(),
334                         payment_paths,
335                         message_paths,
336                         created_at,
337                         relative_expiry: None,
338                         fallbacks: None,
339                         features: Bolt12InvoiceFeatures::empty(),
340                         signing_pubkey,
341                 }
342         }
343
344         fn as_tlv_stream(&self) -> PartialInvoiceTlvStreamRef {
345                 let features = {
346                         if self.features == Bolt12InvoiceFeatures::empty() {
347                                 None
348                         } else {
349                                 Some(&self.features)
350                         }
351                 };
352
353                 let invoice = InvoiceTlvStreamRef {
354                         paths: Some(Iterable(self.payment_paths.iter().map(|(_, path)| path))),
355                         message_paths: Some(self.message_paths.as_ref()),
356                         blindedpay: Some(Iterable(self.payment_paths.iter().map(|(payinfo, _)| payinfo))),
357                         created_at: Some(self.created_at.as_secs()),
358                         relative_expiry: self.relative_expiry.map(|duration| duration.as_secs() as u32),
359                         fallbacks: self.fallbacks.as_ref(),
360                         features,
361                         node_id: Some(&self.signing_pubkey),
362                         amount: None,
363                         payment_hash: None,
364                 };
365
366                 (self.offer.as_tlv_stream(), invoice)
367         }
368
369         fn chain(&self) -> ChainHash {
370                 debug_assert_eq!(self.offer.chains().len(), 1);
371                 self.offer.chains().first().cloned().unwrap_or_else(|| self.offer.implied_chain())
372         }
373
374         fn metadata(&self) -> Option<&Vec<u8>> {
375                 self.offer.metadata()
376         }
377
378         fn amount(&self) -> Option<Amount> {
379                 self.offer.amount()
380         }
381
382         fn offer_features(&self) -> &OfferFeatures {
383                 self.offer.features()
384         }
385
386         fn description(&self) -> Option<PrintableString> {
387                 self.offer.description()
388         }
389
390         fn absolute_expiry(&self) -> Option<Duration> {
391                 self.offer.absolute_expiry()
392         }
393
394         fn issuer(&self) -> Option<PrintableString> {
395                 self.offer.issuer()
396         }
397
398         fn offer_message_paths(&self) -> &[BlindedPath] {
399                 self.offer.paths()
400         }
401
402         fn message_paths(&self) -> &[BlindedPath] {
403                 &self.message_paths[..]
404         }
405
406         fn supported_quantity(&self) -> Quantity {
407                 self.offer.supported_quantity()
408         }
409
410         fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
411                 &self.payment_paths[..]
412         }
413
414         fn created_at(&self) -> Duration {
415                 self.created_at
416         }
417
418         fn relative_expiry(&self) -> Duration {
419                 self.relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
420         }
421
422         #[cfg(feature = "std")]
423         fn is_expired(&self) -> bool {
424                 is_expired(self.created_at(), self.relative_expiry())
425         }
426
427         fn fallbacks(&self) -> Vec<Address> {
428                 let chain = self.chain();
429                 self.fallbacks
430                         .as_ref()
431                         .map(|fallbacks| filter_fallbacks(chain, fallbacks))
432                         .unwrap_or_else(Vec::new)
433         }
434
435         fn features(&self) -> &Bolt12InvoiceFeatures {
436                 &self.features
437         }
438
439         fn signing_pubkey(&self) -> PublicKey {
440                 self.signing_pubkey
441         }
442 }
443
444 impl Writeable for StaticInvoice {
445         fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
446                 WithoutLength(&self.bytes).write(writer)
447         }
448 }
449
450 impl TryFrom<Vec<u8>> for StaticInvoice {
451         type Error = Bolt12ParseError;
452
453         fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
454                 let parsed_invoice = ParsedMessage::<FullInvoiceTlvStream>::try_from(bytes)?;
455                 StaticInvoice::try_from(parsed_invoice)
456         }
457 }
458
459 type FullInvoiceTlvStream = (OfferTlvStream, InvoiceTlvStream, SignatureTlvStream);
460
461 impl SeekReadable for FullInvoiceTlvStream {
462         fn read<R: io::Read + io::Seek>(r: &mut R) -> Result<Self, DecodeError> {
463                 let offer = SeekReadable::read(r)?;
464                 let invoice = SeekReadable::read(r)?;
465                 let signature = SeekReadable::read(r)?;
466
467                 Ok((offer, invoice, signature))
468         }
469 }
470
471 type PartialInvoiceTlvStream = (OfferTlvStream, InvoiceTlvStream);
472
473 type PartialInvoiceTlvStreamRef<'a> = (OfferTlvStreamRef<'a>, InvoiceTlvStreamRef<'a>);
474
475 impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for StaticInvoice {
476         type Error = Bolt12ParseError;
477
478         fn try_from(invoice: ParsedMessage<FullInvoiceTlvStream>) -> Result<Self, Self::Error> {
479                 let ParsedMessage { bytes, tlv_stream } = invoice;
480                 let (offer_tlv_stream, invoice_tlv_stream, SignatureTlvStream { signature }) = tlv_stream;
481                 let contents = InvoiceContents::try_from((offer_tlv_stream, invoice_tlv_stream))?;
482
483                 let signature = match signature {
484                         None => {
485                                 return Err(Bolt12ParseError::InvalidSemantics(
486                                         Bolt12SemanticError::MissingSignature,
487                                 ))
488                         },
489                         Some(signature) => signature,
490                 };
491                 let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
492                 let pubkey = contents.signing_pubkey;
493                 merkle::verify_signature(&signature, &tagged_hash, pubkey)?;
494
495                 Ok(StaticInvoice { bytes, contents, signature })
496         }
497 }
498
499 impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
500         type Error = Bolt12SemanticError;
501
502         fn try_from(tlv_stream: PartialInvoiceTlvStream) -> Result<Self, Self::Error> {
503                 let (
504                         offer_tlv_stream,
505                         InvoiceTlvStream {
506                                 paths,
507                                 blindedpay,
508                                 created_at,
509                                 relative_expiry,
510                                 fallbacks,
511                                 features,
512                                 node_id,
513                                 message_paths,
514                                 payment_hash,
515                                 amount,
516                         },
517                 ) = tlv_stream;
518
519                 if payment_hash.is_some() {
520                         return Err(Bolt12SemanticError::UnexpectedPaymentHash);
521                 }
522                 if amount.is_some() {
523                         return Err(Bolt12SemanticError::UnexpectedAmount);
524                 }
525
526                 let payment_paths = construct_payment_paths(blindedpay, paths)?;
527                 let message_paths = message_paths.ok_or(Bolt12SemanticError::MissingPaths)?;
528
529                 let created_at = match created_at {
530                         None => return Err(Bolt12SemanticError::MissingCreationTime),
531                         Some(timestamp) => Duration::from_secs(timestamp),
532                 };
533
534                 let relative_expiry = relative_expiry.map(Into::<u64>::into).map(Duration::from_secs);
535
536                 let features = features.unwrap_or_else(Bolt12InvoiceFeatures::empty);
537
538                 let signing_pubkey = node_id.ok_or(Bolt12SemanticError::MissingSigningPubkey)?;
539                 check_invoice_signing_pubkey(&signing_pubkey, &offer_tlv_stream)?;
540
541                 if offer_tlv_stream.paths.is_none() {
542                         return Err(Bolt12SemanticError::MissingPaths);
543                 }
544                 if offer_tlv_stream.chains.as_ref().map_or(0, |chains| chains.len()) > 1 {
545                         return Err(Bolt12SemanticError::UnexpectedChain);
546                 }
547
548                 Ok(InvoiceContents {
549                         offer: OfferContents::try_from(offer_tlv_stream)?,
550                         payment_paths,
551                         message_paths,
552                         created_at,
553                         relative_expiry,
554                         fallbacks,
555                         features,
556                         signing_pubkey,
557                 })
558         }
559 }
560
561 #[cfg(test)]
562 mod tests {
563         use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
564         use crate::ln::features::{Bolt12InvoiceFeatures, OfferFeatures};
565         use crate::ln::inbound_payment::ExpandedKey;
566         use crate::ln::msgs::DecodeError;
567         use crate::offers::invoice::InvoiceTlvStreamRef;
568         use crate::offers::merkle;
569         use crate::offers::merkle::{SignatureTlvStreamRef, TaggedHash};
570         use crate::offers::offer::{Offer, OfferBuilder, OfferTlvStreamRef, Quantity};
571         use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
572         use crate::offers::static_invoice::{
573                 StaticInvoice, StaticInvoiceBuilder, DEFAULT_RELATIVE_EXPIRY, SIGNATURE_TAG,
574         };
575         use crate::offers::test_utils::*;
576         use crate::sign::KeyMaterial;
577         use crate::util::ser::{BigSize, Iterable, Writeable};
578         use bitcoin::blockdata::constants::ChainHash;
579         use bitcoin::secp256k1::{self, Secp256k1};
580         use bitcoin::Network;
581         use core::time::Duration;
582
583         type FullInvoiceTlvStreamRef<'a> =
584                 (OfferTlvStreamRef<'a>, InvoiceTlvStreamRef<'a>, SignatureTlvStreamRef<'a>);
585
586         impl StaticInvoice {
587                 fn as_tlv_stream(&self) -> FullInvoiceTlvStreamRef {
588                         let (offer_tlv_stream, invoice_tlv_stream) = self.contents.as_tlv_stream();
589                         (
590                                 offer_tlv_stream,
591                                 invoice_tlv_stream,
592                                 SignatureTlvStreamRef { signature: Some(&self.signature) },
593                         )
594                 }
595         }
596
597         fn tlv_stream_to_bytes(
598                 tlv_stream: &(OfferTlvStreamRef, InvoiceTlvStreamRef, SignatureTlvStreamRef),
599         ) -> Vec<u8> {
600                 let mut buffer = Vec::new();
601                 tlv_stream.0.write(&mut buffer).unwrap();
602                 tlv_stream.1.write(&mut buffer).unwrap();
603                 tlv_stream.2.write(&mut buffer).unwrap();
604                 buffer
605         }
606
607         fn invoice() -> StaticInvoice {
608                 let node_id = recipient_pubkey();
609                 let payment_paths = payment_paths();
610                 let now = now();
611                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
612                 let entropy = FixedEntropy {};
613                 let secp_ctx = Secp256k1::new();
614
615                 let offer =
616                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
617                                 .path(blinded_path())
618                                 .build()
619                                 .unwrap();
620
621                 StaticInvoiceBuilder::for_offer_using_derived_keys(
622                         &offer,
623                         payment_paths.clone(),
624                         vec![blinded_path()],
625                         now,
626                         &expanded_key,
627                         &secp_ctx,
628                 )
629                 .unwrap()
630                 .build_and_sign(&secp_ctx)
631                 .unwrap()
632         }
633
634         fn blinded_path() -> BlindedPath {
635                 BlindedPath {
636                         introduction_node: IntroductionNode::NodeId(pubkey(40)),
637                         blinding_point: pubkey(41),
638                         blinded_hops: vec![
639                                 BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
640                                 BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 44] },
641                         ],
642                 }
643         }
644
645         #[test]
646         fn builds_invoice_for_offer_with_defaults() {
647                 let node_id = recipient_pubkey();
648                 let payment_paths = payment_paths();
649                 let now = now();
650                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
651                 let entropy = FixedEntropy {};
652                 let secp_ctx = Secp256k1::new();
653
654                 let offer =
655                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
656                                 .path(blinded_path())
657                                 .build()
658                                 .unwrap();
659
660                 let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
661                         &offer,
662                         payment_paths.clone(),
663                         vec![blinded_path()],
664                         now,
665                         &expanded_key,
666                         &secp_ctx,
667                 )
668                 .unwrap()
669                 .build_and_sign(&secp_ctx)
670                 .unwrap();
671
672                 let mut buffer = Vec::new();
673                 invoice.write(&mut buffer).unwrap();
674
675                 assert_eq!(invoice.bytes, buffer.as_slice());
676                 assert!(invoice.metadata().is_some());
677                 assert_eq!(invoice.amount(), None);
678                 assert_eq!(invoice.description(), None);
679                 assert_eq!(invoice.offer_features(), &OfferFeatures::empty());
680                 assert_eq!(invoice.absolute_expiry(), None);
681                 assert_eq!(invoice.offer_message_paths(), &[blinded_path()]);
682                 assert_eq!(invoice.message_paths(), &[blinded_path()]);
683                 assert_eq!(invoice.issuer(), None);
684                 assert_eq!(invoice.supported_quantity(), Quantity::One);
685                 assert_ne!(invoice.signing_pubkey(), recipient_pubkey());
686                 assert_eq!(invoice.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
687                 assert_eq!(invoice.payment_paths(), payment_paths.as_slice());
688                 assert_eq!(invoice.created_at(), now);
689                 assert_eq!(invoice.relative_expiry(), DEFAULT_RELATIVE_EXPIRY);
690                 #[cfg(feature = "std")]
691                 assert!(!invoice.is_expired());
692                 assert!(invoice.fallbacks().is_empty());
693                 assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
694
695                 let offer_signing_pubkey = offer.signing_pubkey().unwrap();
696                 let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice.bytes);
697                 assert!(
698                         merkle::verify_signature(&invoice.signature, &message, offer_signing_pubkey).is_ok()
699                 );
700
701                 let paths = vec![blinded_path()];
702                 let metadata = vec![42; 16];
703                 assert_eq!(
704                         invoice.as_tlv_stream(),
705                         (
706                                 OfferTlvStreamRef {
707                                         chains: None,
708                                         metadata: Some(&metadata),
709                                         currency: None,
710                                         amount: None,
711                                         description: None,
712                                         features: None,
713                                         absolute_expiry: None,
714                                         paths: Some(&paths),
715                                         issuer: None,
716                                         quantity_max: None,
717                                         node_id: Some(&offer_signing_pubkey),
718                                 },
719                                 InvoiceTlvStreamRef {
720                                         paths: Some(Iterable(payment_paths.iter().map(|(_, path)| path))),
721                                         blindedpay: Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo))),
722                                         created_at: Some(now.as_secs()),
723                                         relative_expiry: None,
724                                         payment_hash: None,
725                                         amount: None,
726                                         fallbacks: None,
727                                         features: None,
728                                         node_id: Some(&offer_signing_pubkey),
729                                         message_paths: Some(&paths),
730                                 },
731                                 SignatureTlvStreamRef { signature: Some(&invoice.signature()) },
732                         )
733                 );
734
735                 if let Err(e) = StaticInvoice::try_from(buffer) {
736                         panic!("error parsing invoice: {:?}", e);
737                 }
738         }
739
740         #[cfg(feature = "std")]
741         #[test]
742         fn builds_invoice_from_offer_with_expiration() {
743                 let node_id = recipient_pubkey();
744                 let now = now();
745                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
746                 let entropy = FixedEntropy {};
747                 let secp_ctx = Secp256k1::new();
748
749                 let future_expiry = Duration::from_secs(u64::max_value());
750                 let past_expiry = Duration::from_secs(0);
751
752                 let valid_offer =
753                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
754                                 .path(blinded_path())
755                                 .absolute_expiry(future_expiry)
756                                 .build()
757                                 .unwrap();
758
759                 let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
760                         &valid_offer,
761                         payment_paths(),
762                         vec![blinded_path()],
763                         now,
764                         &expanded_key,
765                         &secp_ctx,
766                 )
767                 .unwrap()
768                 .build_and_sign(&secp_ctx)
769                 .unwrap();
770                 assert!(!invoice.is_expired());
771                 assert_eq!(invoice.absolute_expiry(), Some(future_expiry));
772
773                 let expired_offer =
774                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
775                                 .path(blinded_path())
776                                 .absolute_expiry(past_expiry)
777                                 .build()
778                                 .unwrap();
779                 if let Err(e) = StaticInvoiceBuilder::for_offer_using_derived_keys(
780                         &expired_offer,
781                         payment_paths(),
782                         vec![blinded_path()],
783                         now,
784                         &expanded_key,
785                         &secp_ctx,
786                 )
787                 .unwrap()
788                 .build_and_sign(&secp_ctx)
789                 {
790                         assert_eq!(e, Bolt12SemanticError::AlreadyExpired);
791                 } else {
792                         panic!("expected error")
793                 }
794         }
795
796         #[test]
797         fn fails_build_with_missing_paths() {
798                 let node_id = recipient_pubkey();
799                 let now = now();
800                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
801                 let entropy = FixedEntropy {};
802                 let secp_ctx = Secp256k1::new();
803
804                 let valid_offer =
805                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
806                                 .path(blinded_path())
807                                 .build()
808                                 .unwrap();
809
810                 // Error if payment paths are missing.
811                 if let Err(e) = StaticInvoiceBuilder::for_offer_using_derived_keys(
812                         &valid_offer,
813                         Vec::new(),
814                         vec![blinded_path()],
815                         now,
816                         &expanded_key,
817                         &secp_ctx,
818                 ) {
819                         assert_eq!(e, Bolt12SemanticError::MissingPaths);
820                 } else {
821                         panic!("expected error")
822                 }
823
824                 // Error if message paths are missing.
825                 if let Err(e) = StaticInvoiceBuilder::for_offer_using_derived_keys(
826                         &valid_offer,
827                         payment_paths(),
828                         Vec::new(),
829                         now,
830                         &expanded_key,
831                         &secp_ctx,
832                 ) {
833                         assert_eq!(e, Bolt12SemanticError::MissingPaths);
834                 } else {
835                         panic!("expected error")
836                 }
837
838                 // Error if offer paths are missing.
839                 let mut offer_without_paths = valid_offer.clone();
840                 let mut offer_tlv_stream = offer_without_paths.as_tlv_stream();
841                 offer_tlv_stream.paths.take();
842                 let mut buffer = Vec::new();
843                 offer_tlv_stream.write(&mut buffer).unwrap();
844                 offer_without_paths = Offer::try_from(buffer).unwrap();
845                 if let Err(e) = StaticInvoiceBuilder::for_offer_using_derived_keys(
846                         &offer_without_paths,
847                         payment_paths(),
848                         vec![blinded_path()],
849                         now,
850                         &expanded_key,
851                         &secp_ctx,
852                 ) {
853                         assert_eq!(e, Bolt12SemanticError::MissingPaths);
854                 } else {
855                         panic!("expected error")
856                 }
857         }
858
859         #[test]
860         fn fails_build_offer_signing_pubkey() {
861                 let node_id = recipient_pubkey();
862                 let now = now();
863                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
864                 let entropy = FixedEntropy {};
865                 let secp_ctx = Secp256k1::new();
866
867                 let valid_offer =
868                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
869                                 .path(blinded_path())
870                                 .build()
871                                 .unwrap();
872
873                 // Error if offer signing pubkey is missing.
874                 let mut offer_missing_signing_pubkey = valid_offer.clone();
875                 let mut offer_tlv_stream = offer_missing_signing_pubkey.as_tlv_stream();
876                 offer_tlv_stream.node_id.take();
877                 let mut buffer = Vec::new();
878                 offer_tlv_stream.write(&mut buffer).unwrap();
879                 offer_missing_signing_pubkey = Offer::try_from(buffer).unwrap();
880
881                 if let Err(e) = StaticInvoiceBuilder::for_offer_using_derived_keys(
882                         &offer_missing_signing_pubkey,
883                         payment_paths(),
884                         vec![blinded_path()],
885                         now,
886                         &expanded_key,
887                         &secp_ctx,
888                 ) {
889                         assert_eq!(e, Bolt12SemanticError::MissingSigningPubkey);
890                 } else {
891                         panic!("expected error")
892                 }
893
894                 // Error if the offer's metadata cannot be verified.
895                 let offer = OfferBuilder::new(recipient_pubkey())
896                         .path(blinded_path())
897                         .metadata(vec![42; 32])
898                         .unwrap()
899                         .build()
900                         .unwrap();
901                 if let Err(e) = StaticInvoiceBuilder::for_offer_using_derived_keys(
902                         &offer,
903                         payment_paths(),
904                         vec![blinded_path()],
905                         now,
906                         &expanded_key,
907                         &secp_ctx,
908                 ) {
909                         assert_eq!(e, Bolt12SemanticError::InvalidMetadata);
910                 } else {
911                         panic!("expected error")
912                 }
913         }
914
915         #[test]
916         fn fails_building_with_extra_offer_chains() {
917                 let node_id = recipient_pubkey();
918                 let now = now();
919                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
920                 let entropy = FixedEntropy {};
921                 let secp_ctx = Secp256k1::new();
922
923                 let offer_with_extra_chain =
924                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
925                                 .path(blinded_path())
926                                 .chain(Network::Bitcoin)
927                                 .chain(Network::Testnet)
928                                 .build()
929                                 .unwrap();
930
931                 if let Err(e) = StaticInvoiceBuilder::for_offer_using_derived_keys(
932                         &offer_with_extra_chain,
933                         payment_paths(),
934                         vec![blinded_path()],
935                         now,
936                         &expanded_key,
937                         &secp_ctx,
938                 ) {
939                         assert_eq!(e, Bolt12SemanticError::UnexpectedChain);
940                 } else {
941                         panic!("expected error")
942                 }
943         }
944
945         #[test]
946         fn parses_invoice_with_relative_expiry() {
947                 let node_id = recipient_pubkey();
948                 let payment_paths = payment_paths();
949                 let now = now();
950                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
951                 let entropy = FixedEntropy {};
952                 let secp_ctx = Secp256k1::new();
953
954                 let offer =
955                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
956                                 .path(blinded_path())
957                                 .build()
958                                 .unwrap();
959
960                 const TEST_RELATIVE_EXPIRY: u32 = 3600;
961                 let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
962                         &offer,
963                         payment_paths.clone(),
964                         vec![blinded_path()],
965                         now,
966                         &expanded_key,
967                         &secp_ctx,
968                 )
969                 .unwrap()
970                 .relative_expiry(TEST_RELATIVE_EXPIRY)
971                 .build_and_sign(&secp_ctx)
972                 .unwrap();
973
974                 let mut buffer = Vec::new();
975                 invoice.write(&mut buffer).unwrap();
976
977                 match StaticInvoice::try_from(buffer) {
978                         Ok(invoice) => assert_eq!(
979                                 invoice.relative_expiry(),
980                                 Duration::from_secs(TEST_RELATIVE_EXPIRY as u64)
981                         ),
982                         Err(e) => panic!("error parsing invoice: {:?}", e),
983                 }
984         }
985
986         #[test]
987         fn parses_invoice_with_allow_mpp() {
988                 let node_id = recipient_pubkey();
989                 let payment_paths = payment_paths();
990                 let now = now();
991                 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
992                 let entropy = FixedEntropy {};
993                 let secp_ctx = Secp256k1::new();
994
995                 let offer =
996                         OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, &entropy, &secp_ctx)
997                                 .path(blinded_path())
998                                 .build()
999                                 .unwrap();
1000
1001                 let invoice = StaticInvoiceBuilder::for_offer_using_derived_keys(
1002                         &offer,
1003                         payment_paths.clone(),
1004                         vec![blinded_path()],
1005                         now,
1006                         &expanded_key,
1007                         &secp_ctx,
1008                 )
1009                 .unwrap()
1010                 .allow_mpp()
1011                 .build_and_sign(&secp_ctx)
1012                 .unwrap();
1013
1014                 let mut buffer = Vec::new();
1015                 invoice.write(&mut buffer).unwrap();
1016
1017                 match StaticInvoice::try_from(buffer) {
1018                         Ok(invoice) => {
1019                                 let mut features = Bolt12InvoiceFeatures::empty();
1020                                 features.set_basic_mpp_optional();
1021                                 assert_eq!(invoice.invoice_features(), &features);
1022                         },
1023                         Err(e) => panic!("error parsing invoice: {:?}", e),
1024                 }
1025         }
1026
1027         #[test]
1028         fn fails_parsing_missing_invoice_fields() {
1029                 // Error if `created_at` is missing.
1030                 let missing_created_at_invoice = invoice();
1031                 let mut tlv_stream = missing_created_at_invoice.as_tlv_stream();
1032                 tlv_stream.1.created_at = None;
1033                 match StaticInvoice::try_from(tlv_stream_to_bytes(&tlv_stream)) {
1034                         Ok(_) => panic!("expected error"),
1035                         Err(e) => {
1036                                 assert_eq!(
1037                                         e,
1038                                         Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingCreationTime)
1039                                 );
1040                         },
1041                 }
1042
1043                 // Error if `node_id` is missing.
1044                 let missing_node_id_invoice = invoice();
1045                 let mut tlv_stream = missing_node_id_invoice.as_tlv_stream();
1046                 tlv_stream.1.node_id = None;
1047                 match StaticInvoice::try_from(tlv_stream_to_bytes(&tlv_stream)) {
1048                         Ok(_) => panic!("expected error"),
1049                         Err(e) => {
1050                                 assert_eq!(
1051                                         e,
1052                                         Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey)
1053                                 );
1054                         },
1055                 }
1056
1057                 // Error if message paths are missing.
1058                 let missing_message_paths_invoice = invoice();
1059                 let mut tlv_stream = missing_message_paths_invoice.as_tlv_stream();
1060                 tlv_stream.1.message_paths = None;
1061                 match StaticInvoice::try_from(tlv_stream_to_bytes(&tlv_stream)) {
1062                         Ok(_) => panic!("expected error"),
1063                         Err(e) => {
1064                                 assert_eq!(
1065                                         e,
1066                                         Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)
1067                                 );
1068                         },
1069                 }
1070
1071                 // Error if signature is missing.
1072                 let invoice = invoice();
1073                 let mut buffer = Vec::new();
1074                 invoice.contents.as_tlv_stream().write(&mut buffer).unwrap();
1075                 match StaticInvoice::try_from(buffer) {
1076                         Ok(_) => panic!("expected error"),
1077                         Err(e) => assert_eq!(
1078                                 e,
1079                                 Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)
1080                         ),
1081                 }
1082         }
1083
1084         #[test]
1085         fn fails_parsing_invalid_signing_pubkey() {
1086                 let invoice = invoice();
1087                 let invalid_pubkey = payer_pubkey();
1088                 let mut tlv_stream = invoice.as_tlv_stream();
1089                 tlv_stream.1.node_id = Some(&invalid_pubkey);
1090
1091                 match StaticInvoice::try_from(tlv_stream_to_bytes(&tlv_stream)) {
1092                         Ok(_) => panic!("expected error"),
1093                         Err(e) => {
1094                                 assert_eq!(
1095                                         e,
1096                                         Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey)
1097                                 );
1098                         },
1099                 }
1100         }
1101
1102         #[test]
1103         fn fails_parsing_invoice_with_invalid_signature() {
1104                 let mut invoice = invoice();
1105                 let last_signature_byte = invoice.bytes.last_mut().unwrap();
1106                 *last_signature_byte = last_signature_byte.wrapping_add(1);
1107
1108                 let mut buffer = Vec::new();
1109                 invoice.write(&mut buffer).unwrap();
1110
1111                 match StaticInvoice::try_from(buffer) {
1112                         Ok(_) => panic!("expected error"),
1113                         Err(e) => {
1114                                 assert_eq!(
1115                                         e,
1116                                         Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature)
1117                                 );
1118                         },
1119                 }
1120         }
1121
1122         #[test]
1123         fn fails_parsing_invoice_with_extra_tlv_records() {
1124                 let invoice = invoice();
1125                 let mut encoded_invoice = Vec::new();
1126                 invoice.write(&mut encoded_invoice).unwrap();
1127                 BigSize(1002).write(&mut encoded_invoice).unwrap();
1128                 BigSize(32).write(&mut encoded_invoice).unwrap();
1129                 [42u8; 32].write(&mut encoded_invoice).unwrap();
1130
1131                 match StaticInvoice::try_from(encoded_invoice) {
1132                         Ok(_) => panic!("expected error"),
1133                         Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
1134                 }
1135         }
1136
1137         #[test]
1138         fn fails_parsing_invoice_with_invalid_offer_fields() {
1139                 // Error if the offer is missing paths.
1140                 let missing_offer_paths_invoice = invoice();
1141                 let mut tlv_stream = missing_offer_paths_invoice.as_tlv_stream();
1142                 tlv_stream.0.paths = None;
1143                 match StaticInvoice::try_from(tlv_stream_to_bytes(&tlv_stream)) {
1144                         Ok(_) => panic!("expected error"),
1145                         Err(e) => {
1146                                 assert_eq!(
1147                                         e,
1148                                         Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)
1149                                 );
1150                         },
1151                 }
1152
1153                 // Error if the offer has more than one chain.
1154                 let invalid_offer_chains_invoice = invoice();
1155                 let mut tlv_stream = invalid_offer_chains_invoice.as_tlv_stream();
1156                 let invalid_chains = vec![
1157                         ChainHash::using_genesis_block(Network::Bitcoin),
1158                         ChainHash::using_genesis_block(Network::Testnet),
1159                 ];
1160                 tlv_stream.0.chains = Some(&invalid_chains);
1161                 match StaticInvoice::try_from(tlv_stream_to_bytes(&tlv_stream)) {
1162                         Ok(_) => panic!("expected error"),
1163                         Err(e) => {
1164                                 assert_eq!(
1165                                         e,
1166                                         Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedChain)
1167                                 );
1168                         },
1169                 }
1170         }
1171 }