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