1 // This file is Copyright its original authors, visible in version control
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
10 //! Data structures and encoding for `invoice_request` messages.
12 //! An [`InvoiceRequest`] can be built from a parsed [`Offer`] as an "offer to be paid". It is
13 //! typically constructed by a customer and sent to the merchant who had published the corresponding
14 //! offer. The recipient of the request responds with a [`Bolt12Invoice`].
16 //! For an "offer for money" (e.g., refund, ATM withdrawal), where an offer doesn't exist as a
17 //! precursor, see [`Refund`].
19 //! [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
20 //! [`Refund`]: crate::offers::refund::Refund
23 //! extern crate bitcoin;
24 //! extern crate lightning;
26 //! use bitcoin::network::constants::Network;
27 //! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
28 //! use core::convert::Infallible;
29 //! use lightning::ln::features::OfferFeatures;
30 //! use lightning::offers::offer::Offer;
31 //! use lightning::util::ser::Writeable;
33 //! # fn parse() -> Result<(), lightning::offers::parse::Bolt12ParseError> {
34 //! let secp_ctx = Secp256k1::new();
35 //! let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32])?);
36 //! let pubkey = PublicKey::from(keys);
37 //! let mut buffer = Vec::new();
40 //! .parse::<Offer>()?
41 //! .request_invoice(vec![42; 64], pubkey)?
42 //! .chain(Network::Testnet)?
43 //! .amount_msats(1000)?
45 //! .payer_note("foo".to_string())
47 //! .sign::<_, Infallible>(
48 //! |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
50 //! .expect("failed verifying signature")
51 //! .write(&mut buffer)
57 use bitcoin::blockdata::constants::ChainHash;
58 use bitcoin::network::constants::Network;
59 use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, self};
60 use bitcoin::secp256k1::schnorr::Signature;
61 use core::convert::{AsRef, Infallible, TryFrom};
63 use crate::sign::EntropySource;
65 use crate::blinded_path::BlindedPath;
66 use crate::ln::PaymentHash;
67 use crate::ln::features::InvoiceRequestFeatures;
68 use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce};
69 use crate::ln::msgs::DecodeError;
70 use crate::offers::invoice::{BlindedPayInfo, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder};
71 use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, self};
72 use crate::offers::offer::{Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef};
73 use crate::offers::parse::{Bolt12ParseError, ParsedMessage, Bolt12SemanticError};
74 use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
75 use crate::offers::signer::{Metadata, MetadataMaterial};
76 use crate::util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer};
77 use crate::util::string::PrintableString;
79 use crate::prelude::*;
81 /// Tag for the hash function used when signing an [`InvoiceRequest`]'s merkle root.
82 pub const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice_request", "signature");
84 pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Invreq ~~~~~";
86 /// Builds an [`InvoiceRequest`] from an [`Offer`] for the "offer to be paid" flow.
88 /// See [module-level documentation] for usage.
90 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
92 /// [module-level documentation]: self
93 pub struct InvoiceRequestBuilder<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> {
95 invoice_request: InvoiceRequestContentsWithoutPayerId,
96 payer_id: Option<PublicKey>,
97 payer_id_strategy: core::marker::PhantomData<P>,
98 secp_ctx: Option<&'b Secp256k1<T>>,
101 /// Indicates how [`InvoiceRequest::payer_id`] will be set.
103 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
104 pub trait PayerIdStrategy {}
106 /// [`InvoiceRequest::payer_id`] will be explicitly set.
108 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
109 pub struct ExplicitPayerId {}
111 /// [`InvoiceRequest::payer_id`] will be derived.
113 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
114 pub struct DerivedPayerId {}
116 impl PayerIdStrategy for ExplicitPayerId {}
117 impl PayerIdStrategy for DerivedPayerId {}
119 impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, ExplicitPayerId, T> {
120 pub(super) fn new(offer: &'a Offer, metadata: Vec<u8>, payer_id: PublicKey) -> Self {
123 invoice_request: Self::create_contents(offer, Metadata::Bytes(metadata)),
124 payer_id: Some(payer_id),
125 payer_id_strategy: core::marker::PhantomData,
130 pub(super) fn deriving_metadata<ES: Deref>(
131 offer: &'a Offer, payer_id: PublicKey, expanded_key: &ExpandedKey, entropy_source: ES
132 ) -> Self where ES::Target: EntropySource {
133 let nonce = Nonce::from_entropy_source(entropy_source);
134 let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES);
135 let metadata = Metadata::Derived(derivation_material);
138 invoice_request: Self::create_contents(offer, metadata),
139 payer_id: Some(payer_id),
140 payer_id_strategy: core::marker::PhantomData,
146 impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, DerivedPayerId, T> {
147 pub(super) fn deriving_payer_id<ES: Deref>(
148 offer: &'a Offer, expanded_key: &ExpandedKey, entropy_source: ES, secp_ctx: &'b Secp256k1<T>
149 ) -> Self where ES::Target: EntropySource {
150 let nonce = Nonce::from_entropy_source(entropy_source);
151 let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES);
152 let metadata = Metadata::DerivedSigningPubkey(derivation_material);
155 invoice_request: Self::create_contents(offer, metadata),
157 payer_id_strategy: core::marker::PhantomData,
158 secp_ctx: Some(secp_ctx),
163 impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, P, T> {
164 fn create_contents(offer: &Offer, metadata: Metadata) -> InvoiceRequestContentsWithoutPayerId {
165 let offer = offer.contents.clone();
166 InvoiceRequestContentsWithoutPayerId {
167 payer: PayerContents(metadata), offer, chain: None, amount_msats: None,
168 features: InvoiceRequestFeatures::empty(), quantity: None, payer_note: None,
172 /// Sets the [`InvoiceRequest::chain`] of the given [`Network`] for paying an invoice. If not
173 /// called, [`Network::Bitcoin`] is assumed. Errors if the chain for `network` is not supported
176 /// Successive calls to this method will override the previous setting.
177 pub fn chain(mut self, network: Network) -> Result<Self, Bolt12SemanticError> {
178 let chain = ChainHash::using_genesis_block(network);
179 if !self.offer.supports_chain(chain) {
180 return Err(Bolt12SemanticError::UnsupportedChain);
183 self.invoice_request.chain = Some(chain);
187 /// Sets the [`InvoiceRequest::amount_msats`] for paying an invoice. Errors if `amount_msats` is
188 /// not at least the expected invoice amount (i.e., [`Offer::amount`] times [`quantity`]).
190 /// Successive calls to this method will override the previous setting.
192 /// [`quantity`]: Self::quantity
193 pub fn amount_msats(mut self, amount_msats: u64) -> Result<Self, Bolt12SemanticError> {
194 self.invoice_request.offer.check_amount_msats_for_quantity(
195 Some(amount_msats), self.invoice_request.quantity
197 self.invoice_request.amount_msats = Some(amount_msats);
201 /// Sets [`InvoiceRequest::quantity`] of items. If not set, `1` is assumed. Errors if `quantity`
202 /// does not conform to [`Offer::is_valid_quantity`].
204 /// Successive calls to this method will override the previous setting.
205 pub fn quantity(mut self, quantity: u64) -> Result<Self, Bolt12SemanticError> {
206 self.invoice_request.offer.check_quantity(Some(quantity))?;
207 self.invoice_request.quantity = Some(quantity);
211 /// Sets the [`InvoiceRequest::payer_note`].
213 /// Successive calls to this method will override the previous setting.
214 pub fn payer_note(mut self, payer_note: String) -> Self {
215 self.invoice_request.payer_note = Some(payer_note);
219 fn build_with_checks(mut self) -> Result<
220 (UnsignedInvoiceRequest, Option<KeyPair>, Option<&'b Secp256k1<T>>),
223 #[cfg(feature = "std")] {
224 if self.offer.is_expired() {
225 return Err(Bolt12SemanticError::AlreadyExpired);
229 let chain = self.invoice_request.chain();
230 if !self.offer.supports_chain(chain) {
231 return Err(Bolt12SemanticError::UnsupportedChain);
234 if chain == self.offer.implied_chain() {
235 self.invoice_request.chain = None;
238 if self.offer.amount().is_none() && self.invoice_request.amount_msats.is_none() {
239 return Err(Bolt12SemanticError::MissingAmount);
242 self.invoice_request.offer.check_quantity(self.invoice_request.quantity)?;
243 self.invoice_request.offer.check_amount_msats_for_quantity(
244 self.invoice_request.amount_msats, self.invoice_request.quantity
247 Ok(self.build_without_checks())
250 fn build_without_checks(mut self) ->
251 (UnsignedInvoiceRequest, Option<KeyPair>, Option<&'b Secp256k1<T>>)
253 // Create the metadata for stateless verification of a Bolt12Invoice.
255 let secp_ctx = self.secp_ctx.clone();
256 if self.invoice_request.payer.0.has_derivation_material() {
257 let mut metadata = core::mem::take(&mut self.invoice_request.payer.0);
259 let mut tlv_stream = self.invoice_request.as_tlv_stream();
260 debug_assert!(tlv_stream.2.payer_id.is_none());
261 tlv_stream.0.metadata = None;
262 if !metadata.derives_keys() {
263 tlv_stream.2.payer_id = self.payer_id.as_ref();
266 let (derived_metadata, derived_keys) = metadata.derive_from(tlv_stream, self.secp_ctx);
267 metadata = derived_metadata;
269 if let Some(keys) = keys {
270 debug_assert!(self.payer_id.is_none());
271 self.payer_id = Some(keys.public_key());
274 self.invoice_request.payer.0 = metadata;
277 debug_assert!(self.invoice_request.payer.0.as_bytes().is_some());
278 debug_assert!(self.payer_id.is_some());
279 let payer_id = self.payer_id.unwrap();
281 let invoice_request = InvoiceRequestContents {
282 inner: self.invoice_request,
285 let unsigned_invoice_request = UnsignedInvoiceRequest::new(self.offer, invoice_request);
287 (unsigned_invoice_request, keys, secp_ctx)
291 impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, ExplicitPayerId, T> {
292 /// Builds an unsigned [`InvoiceRequest`] after checking for valid semantics. It can be signed
293 /// by [`UnsignedInvoiceRequest::sign`].
294 pub fn build(self) -> Result<UnsignedInvoiceRequest, Bolt12SemanticError> {
295 let (unsigned_invoice_request, keys, _) = self.build_with_checks()?;
296 debug_assert!(keys.is_none());
297 Ok(unsigned_invoice_request)
301 impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, DerivedPayerId, T> {
302 /// Builds a signed [`InvoiceRequest`] after checking for valid semantics.
303 pub fn build_and_sign(self) -> Result<InvoiceRequest, Bolt12SemanticError> {
304 let (unsigned_invoice_request, keys, secp_ctx) = self.build_with_checks()?;
305 debug_assert!(keys.is_some());
307 let secp_ctx = secp_ctx.unwrap();
308 let keys = keys.unwrap();
309 let invoice_request = unsigned_invoice_request
310 .sign::<_, Infallible>(
311 |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
319 impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, P, T> {
320 fn chain_unchecked(mut self, network: Network) -> Self {
321 let chain = ChainHash::using_genesis_block(network);
322 self.invoice_request.chain = Some(chain);
326 fn amount_msats_unchecked(mut self, amount_msats: u64) -> Self {
327 self.invoice_request.amount_msats = Some(amount_msats);
331 fn features_unchecked(mut self, features: InvoiceRequestFeatures) -> Self {
332 self.invoice_request.features = features;
336 fn quantity_unchecked(mut self, quantity: u64) -> Self {
337 self.invoice_request.quantity = Some(quantity);
341 pub(super) fn build_unchecked(self) -> UnsignedInvoiceRequest {
342 self.build_without_checks().0
346 /// A semantically valid [`InvoiceRequest`] that hasn't been signed.
350 /// This is serialized as a TLV stream, which includes TLV records from the originating message. As
351 /// such, it may include unknown, odd TLV records.
352 pub struct UnsignedInvoiceRequest {
354 contents: InvoiceRequestContents,
355 tagged_hash: TaggedHash,
358 impl UnsignedInvoiceRequest {
359 fn new(offer: &Offer, contents: InvoiceRequestContents) -> Self {
360 // Use the offer bytes instead of the offer TLV stream as the offer may have contained
361 // unknown TLV records, which are not stored in `OfferContents`.
362 let (payer_tlv_stream, _offer_tlv_stream, invoice_request_tlv_stream) =
363 contents.as_tlv_stream();
364 let offer_bytes = WithoutLength(&offer.bytes);
365 let unsigned_tlv_stream = (payer_tlv_stream, offer_bytes, invoice_request_tlv_stream);
367 let mut bytes = Vec::new();
368 unsigned_tlv_stream.write(&mut bytes).unwrap();
370 let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
372 Self { bytes, contents, tagged_hash }
375 /// Returns the [`TaggedHash`] of the invoice to sign.
376 pub fn tagged_hash(&self) -> &TaggedHash {
380 /// Signs the [`TaggedHash`] of the invoice request using the given function.
382 /// Note: The hash computation may have included unknown, odd TLV records.
384 /// This is not exported to bindings users as functions are not yet mapped.
385 pub fn sign<F, E>(mut self, sign: F) -> Result<InvoiceRequest, SignError<E>>
387 F: FnOnce(&Self) -> Result<Signature, E>
389 let pubkey = self.contents.payer_id;
390 let signature = merkle::sign_message(sign, &self, pubkey)?;
392 // Append the signature TLV record to the bytes.
393 let signature_tlv_stream = SignatureTlvStreamRef {
394 signature: Some(&signature),
396 signature_tlv_stream.write(&mut self.bytes).unwrap();
400 contents: self.contents,
406 impl AsRef<TaggedHash> for UnsignedInvoiceRequest {
407 fn as_ref(&self) -> &TaggedHash {
412 /// An `InvoiceRequest` is a request for a [`Bolt12Invoice`] formulated from an [`Offer`].
414 /// An offer may provide choices such as quantity, amount, chain, features, etc. An invoice request
415 /// specifies these such that its recipient can send an invoice for payment.
417 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
418 /// [`Offer`]: crate::offers::offer::Offer
419 #[derive(Clone, Debug)]
420 #[cfg_attr(test, derive(PartialEq))]
421 pub struct InvoiceRequest {
422 pub(super) bytes: Vec<u8>,
423 pub(super) contents: InvoiceRequestContents,
424 signature: Signature,
427 /// An [`InvoiceRequest`] that has been verified by [`InvoiceRequest::verify`] and exposes different
428 /// ways to respond depending on whether the signing keys were derived.
429 #[derive(Clone, Debug)]
430 pub struct VerifiedInvoiceRequest {
431 /// The verified request.
432 inner: InvoiceRequest,
434 /// Keys used for signing a [`Bolt12Invoice`] if they can be derived.
436 /// If `Some`, must call [`respond_using_derived_keys`] when responding. Otherwise, call
437 /// [`respond_with`].
439 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
440 /// [`respond_using_derived_keys`]: Self::respond_using_derived_keys
441 /// [`respond_with`]: Self::respond_with
442 pub keys: Option<KeyPair>,
445 /// The contents of an [`InvoiceRequest`], which may be shared with an [`Bolt12Invoice`].
447 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
448 #[derive(Clone, Debug)]
449 #[cfg_attr(test, derive(PartialEq))]
450 pub(super) struct InvoiceRequestContents {
451 pub(super) inner: InvoiceRequestContentsWithoutPayerId,
455 #[derive(Clone, Debug)]
456 #[cfg_attr(test, derive(PartialEq))]
457 pub(super) struct InvoiceRequestContentsWithoutPayerId {
458 payer: PayerContents,
459 pub(super) offer: OfferContents,
460 chain: Option<ChainHash>,
461 amount_msats: Option<u64>,
462 features: InvoiceRequestFeatures,
463 quantity: Option<u64>,
464 payer_note: Option<String>,
467 macro_rules! invoice_request_accessors { ($self: ident, $contents: expr) => {
468 /// An unpredictable series of bytes, typically containing information about the derivation of
471 /// [`payer_id`]: Self::payer_id
472 pub fn payer_metadata(&$self) -> &[u8] {
476 /// A chain from [`Offer::chains`] that the offer is valid for.
477 pub fn chain(&$self) -> ChainHash {
481 /// The amount to pay in msats (i.e., the minimum lightning-payable unit for [`chain`]), which
482 /// must be greater than or equal to [`Offer::amount`], converted if necessary.
484 /// [`chain`]: Self::chain
485 pub fn amount_msats(&$self) -> Option<u64> {
486 $contents.amount_msats()
489 /// Features pertaining to requesting an invoice.
490 pub fn invoice_request_features(&$self) -> &InvoiceRequestFeatures {
491 &$contents.features()
494 /// The quantity of the offer's item conforming to [`Offer::is_valid_quantity`].
495 pub fn quantity(&$self) -> Option<u64> {
499 /// A possibly transient pubkey used to sign the invoice request.
500 pub fn payer_id(&$self) -> PublicKey {
504 /// A payer-provided note which will be seen by the recipient and reflected back in the invoice
506 pub fn payer_note(&$self) -> Option<PrintableString> {
507 $contents.payer_note()
511 impl UnsignedInvoiceRequest {
512 offer_accessors!(self, self.contents.inner.offer);
513 invoice_request_accessors!(self, self.contents);
516 impl InvoiceRequest {
517 offer_accessors!(self, self.contents.inner.offer);
518 invoice_request_accessors!(self, self.contents);
520 /// Signature of the invoice request using [`payer_id`].
522 /// [`payer_id`]: Self::payer_id
523 pub fn signature(&self) -> Signature {
527 /// Creates an [`InvoiceBuilder`] for the request with the given required fields and using the
528 /// [`Duration`] since [`std::time::SystemTime::UNIX_EPOCH`] as the creation time.
530 /// See [`InvoiceRequest::respond_with_no_std`] for further details where the aforementioned
531 /// creation time is used for the `created_at` parameter.
533 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
535 /// [`Duration`]: core::time::Duration
536 #[cfg(feature = "std")]
538 &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash
539 ) -> Result<InvoiceBuilder<ExplicitSigningPubkey>, Bolt12SemanticError> {
540 let created_at = std::time::SystemTime::now()
541 .duration_since(std::time::SystemTime::UNIX_EPOCH)
542 .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
544 self.respond_with_no_std(payment_paths, payment_hash, created_at)
547 /// Creates an [`InvoiceBuilder`] for the request with the given required fields.
549 /// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after
550 /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. Useful for `no-std` builds
551 /// where [`std::time::SystemTime`] is not available.
553 /// The caller is expected to remember the preimage of `payment_hash` in order to claim a payment
556 /// The `payment_paths` parameter is useful for maintaining the payment recipient's privacy. It
557 /// must contain one or more elements ordered from most-preferred to least-preferred, if there's
558 /// a preference. Note, however, that any privacy is lost if a public node id was used for
559 /// [`Offer::signing_pubkey`].
561 /// Errors if the request contains unknown required features.
565 /// If the originating [`Offer`] was created using [`OfferBuilder::deriving_signing_pubkey`],
566 /// then use [`InvoiceRequest::verify`] and [`VerifiedInvoiceRequest`] methods instead.
568 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
570 /// [`Bolt12Invoice::created_at`]: crate::offers::invoice::Bolt12Invoice::created_at
571 /// [`OfferBuilder::deriving_signing_pubkey`]: crate::offers::offer::OfferBuilder::deriving_signing_pubkey
572 pub fn respond_with_no_std(
573 &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
574 created_at: core::time::Duration
575 ) -> Result<InvoiceBuilder<ExplicitSigningPubkey>, Bolt12SemanticError> {
576 if self.invoice_request_features().requires_unknown_bits() {
577 return Err(Bolt12SemanticError::UnknownRequiredFeatures);
580 InvoiceBuilder::for_offer(self, payment_paths, created_at, payment_hash)
583 /// Verifies that the request was for an offer created using the given key. Returns the verified
584 /// request which contains the derived keys needed to sign a [`Bolt12Invoice`] for the request
585 /// if they could be extracted from the metadata.
587 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
588 pub fn verify<T: secp256k1::Signing>(
589 self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
590 ) -> Result<VerifiedInvoiceRequest, ()> {
591 let keys = self.contents.inner.offer.verify(&self.bytes, key, secp_ctx)?;
592 Ok(VerifiedInvoiceRequest {
599 fn as_tlv_stream(&self) -> FullInvoiceRequestTlvStreamRef {
600 let (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream) =
601 self.contents.as_tlv_stream();
602 let signature_tlv_stream = SignatureTlvStreamRef {
603 signature: Some(&self.signature),
605 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, signature_tlv_stream)
609 impl VerifiedInvoiceRequest {
610 offer_accessors!(self, self.inner.contents.inner.offer);
611 invoice_request_accessors!(self, self.inner.contents);
613 /// Creates an [`InvoiceBuilder`] for the request with the given required fields and using the
614 /// [`Duration`] since [`std::time::SystemTime::UNIX_EPOCH`] as the creation time.
616 /// See [`InvoiceRequest::respond_with_no_std`] for further details.
618 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
620 /// [`Duration`]: core::time::Duration
621 #[cfg(feature = "std")]
623 &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash
624 ) -> Result<InvoiceBuilder<ExplicitSigningPubkey>, Bolt12SemanticError> {
625 self.inner.respond_with(payment_paths, payment_hash)
628 /// Creates an [`InvoiceBuilder`] for the request with the given required fields.
630 /// See [`InvoiceRequest::respond_with_no_std`] for further details.
632 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
633 pub fn respond_with_no_std(
634 &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
635 created_at: core::time::Duration
636 ) -> Result<InvoiceBuilder<ExplicitSigningPubkey>, Bolt12SemanticError> {
637 self.inner.respond_with_no_std(payment_paths, payment_hash, created_at)
640 /// Creates an [`InvoiceBuilder`] for the request using the given required fields and that uses
641 /// derived signing keys from the originating [`Offer`] to sign the [`Bolt12Invoice`]. Must use
642 /// the same [`ExpandedKey`] as the one used to create the offer.
644 /// See [`InvoiceRequest::respond_with`] for further details.
646 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
648 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
649 #[cfg(feature = "std")]
650 pub fn respond_using_derived_keys(
651 &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash
652 ) -> Result<InvoiceBuilder<DerivedSigningPubkey>, Bolt12SemanticError> {
653 let created_at = std::time::SystemTime::now()
654 .duration_since(std::time::SystemTime::UNIX_EPOCH)
655 .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
657 self.respond_using_derived_keys_no_std(payment_paths, payment_hash, created_at)
660 /// Creates an [`InvoiceBuilder`] for the request using the given required fields and that uses
661 /// derived signing keys from the originating [`Offer`] to sign the [`Bolt12Invoice`]. Must use
662 /// the same [`ExpandedKey`] as the one used to create the offer.
664 /// See [`InvoiceRequest::respond_with_no_std`] for further details.
666 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
668 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
669 pub fn respond_using_derived_keys_no_std(
670 &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash,
671 created_at: core::time::Duration
672 ) -> Result<InvoiceBuilder<DerivedSigningPubkey>, Bolt12SemanticError> {
673 if self.inner.invoice_request_features().requires_unknown_bits() {
674 return Err(Bolt12SemanticError::UnknownRequiredFeatures);
677 let keys = match self.keys {
678 None => return Err(Bolt12SemanticError::InvalidMetadata),
682 InvoiceBuilder::for_offer_using_keys(
683 &self.inner, payment_paths, created_at, payment_hash, keys
688 impl InvoiceRequestContents {
689 pub(super) fn metadata(&self) -> &[u8] {
690 self.inner.metadata()
693 pub(super) fn derives_keys(&self) -> bool {
694 self.inner.payer.0.derives_keys()
697 pub(super) fn chain(&self) -> ChainHash {
701 pub(super) fn amount_msats(&self) -> Option<u64> {
702 self.inner.amount_msats
705 pub(super) fn features(&self) -> &InvoiceRequestFeatures {
709 pub(super) fn quantity(&self) -> Option<u64> {
713 pub(super) fn payer_id(&self) -> PublicKey {
717 pub(super) fn payer_note(&self) -> Option<PrintableString> {
718 self.inner.payer_note.as_ref()
719 .map(|payer_note| PrintableString(payer_note.as_str()))
722 pub(super) fn as_tlv_stream(&self) -> PartialInvoiceRequestTlvStreamRef {
723 let (payer, offer, mut invoice_request) = self.inner.as_tlv_stream();
724 invoice_request.payer_id = Some(&self.payer_id);
725 (payer, offer, invoice_request)
729 impl InvoiceRequestContentsWithoutPayerId {
730 pub(super) fn metadata(&self) -> &[u8] {
731 self.payer.0.as_bytes().map(|bytes| bytes.as_slice()).unwrap_or(&[])
734 pub(super) fn chain(&self) -> ChainHash {
735 self.chain.unwrap_or_else(|| self.offer.implied_chain())
738 pub(super) fn as_tlv_stream(&self) -> PartialInvoiceRequestTlvStreamRef {
739 let payer = PayerTlvStreamRef {
740 metadata: self.payer.0.as_bytes(),
743 let offer = self.offer.as_tlv_stream();
746 if self.features == InvoiceRequestFeatures::empty() { None }
747 else { Some(&self.features) }
750 let invoice_request = InvoiceRequestTlvStreamRef {
751 chain: self.chain.as_ref(),
752 amount: self.amount_msats,
754 quantity: self.quantity,
756 payer_note: self.payer_note.as_ref(),
759 (payer, offer, invoice_request)
763 impl Writeable for UnsignedInvoiceRequest {
764 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
765 WithoutLength(&self.bytes).write(writer)
769 impl Writeable for InvoiceRequest {
770 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
771 WithoutLength(&self.bytes).write(writer)
775 impl Writeable for InvoiceRequestContents {
776 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
777 self.as_tlv_stream().write(writer)
781 /// Valid type range for invoice_request TLV records.
782 pub(super) const INVOICE_REQUEST_TYPES: core::ops::Range<u64> = 80..160;
784 /// TLV record type for [`InvoiceRequest::payer_id`] and [`Refund::payer_id`].
786 /// [`Refund::payer_id`]: crate::offers::refund::Refund::payer_id
787 pub(super) const INVOICE_REQUEST_PAYER_ID_TYPE: u64 = 88;
789 tlv_stream!(InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, {
790 (80, chain: ChainHash),
791 (82, amount: (u64, HighZeroBytesDroppedBigSize)),
792 (84, features: (InvoiceRequestFeatures, WithoutLength)),
793 (86, quantity: (u64, HighZeroBytesDroppedBigSize)),
794 (INVOICE_REQUEST_PAYER_ID_TYPE, payer_id: PublicKey),
795 (89, payer_note: (String, WithoutLength)),
798 type FullInvoiceRequestTlvStream =
799 (PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, SignatureTlvStream);
802 type FullInvoiceRequestTlvStreamRef<'a> = (
803 PayerTlvStreamRef<'a>,
804 OfferTlvStreamRef<'a>,
805 InvoiceRequestTlvStreamRef<'a>,
806 SignatureTlvStreamRef<'a>,
809 impl SeekReadable for FullInvoiceRequestTlvStream {
810 fn read<R: io::Read + io::Seek>(r: &mut R) -> Result<Self, DecodeError> {
811 let payer = SeekReadable::read(r)?;
812 let offer = SeekReadable::read(r)?;
813 let invoice_request = SeekReadable::read(r)?;
814 let signature = SeekReadable::read(r)?;
816 Ok((payer, offer, invoice_request, signature))
820 type PartialInvoiceRequestTlvStream = (PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream);
822 type PartialInvoiceRequestTlvStreamRef<'a> = (
823 PayerTlvStreamRef<'a>,
824 OfferTlvStreamRef<'a>,
825 InvoiceRequestTlvStreamRef<'a>,
828 impl TryFrom<Vec<u8>> for UnsignedInvoiceRequest {
829 type Error = Bolt12ParseError;
831 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
832 let invoice_request = ParsedMessage::<PartialInvoiceRequestTlvStream>::try_from(bytes)?;
833 let ParsedMessage { bytes, tlv_stream } = invoice_request;
835 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
837 let contents = InvoiceRequestContents::try_from(
838 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
841 let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
843 Ok(UnsignedInvoiceRequest { bytes, contents, tagged_hash })
847 impl TryFrom<Vec<u8>> for InvoiceRequest {
848 type Error = Bolt12ParseError;
850 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
851 let invoice_request = ParsedMessage::<FullInvoiceRequestTlvStream>::try_from(bytes)?;
852 let ParsedMessage { bytes, tlv_stream } = invoice_request;
854 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
855 SignatureTlvStream { signature },
857 let contents = InvoiceRequestContents::try_from(
858 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
861 let signature = match signature {
862 None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
863 Some(signature) => signature,
865 let message = TaggedHash::new(SIGNATURE_TAG, &bytes);
866 merkle::verify_signature(&signature, message, contents.payer_id)?;
868 Ok(InvoiceRequest { bytes, contents, signature })
872 impl TryFrom<PartialInvoiceRequestTlvStream> for InvoiceRequestContents {
873 type Error = Bolt12SemanticError;
875 fn try_from(tlv_stream: PartialInvoiceRequestTlvStream) -> Result<Self, Self::Error> {
877 PayerTlvStream { metadata },
879 InvoiceRequestTlvStream { chain, amount, features, quantity, payer_id, payer_note },
882 let payer = match metadata {
883 None => return Err(Bolt12SemanticError::MissingPayerMetadata),
884 Some(metadata) => PayerContents(Metadata::Bytes(metadata)),
886 let offer = OfferContents::try_from(offer_tlv_stream)?;
888 if !offer.supports_chain(chain.unwrap_or_else(|| offer.implied_chain())) {
889 return Err(Bolt12SemanticError::UnsupportedChain);
892 if offer.amount().is_none() && amount.is_none() {
893 return Err(Bolt12SemanticError::MissingAmount);
896 offer.check_quantity(quantity)?;
897 offer.check_amount_msats_for_quantity(amount, quantity)?;
899 let features = features.unwrap_or_else(InvoiceRequestFeatures::empty);
901 let payer_id = match payer_id {
902 None => return Err(Bolt12SemanticError::MissingPayerId),
903 Some(payer_id) => payer_id,
906 Ok(InvoiceRequestContents {
907 inner: InvoiceRequestContentsWithoutPayerId {
908 payer, offer, chain, amount_msats: amount, features, quantity, payer_note,
917 use super::{InvoiceRequest, InvoiceRequestTlvStreamRef, SIGNATURE_TAG, UnsignedInvoiceRequest};
919 use bitcoin::blockdata::constants::ChainHash;
920 use bitcoin::network::constants::Network;
921 use bitcoin::secp256k1::{KeyPair, Secp256k1, SecretKey, self};
922 use core::convert::{Infallible, TryFrom};
923 use core::num::NonZeroU64;
924 #[cfg(feature = "std")]
925 use core::time::Duration;
926 use crate::sign::KeyMaterial;
927 use crate::ln::features::{InvoiceRequestFeatures, OfferFeatures};
928 use crate::ln::inbound_payment::ExpandedKey;
929 use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
930 use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG};
931 use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self};
932 use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity};
933 use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
934 use crate::offers::payer::PayerTlvStreamRef;
935 use crate::offers::test_utils::*;
936 use crate::util::ser::{BigSize, Writeable};
937 use crate::util::string::PrintableString;
940 fn builds_invoice_request_with_defaults() {
941 let unsigned_invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
944 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
947 let mut buffer = Vec::new();
948 unsigned_invoice_request.write(&mut buffer).unwrap();
950 assert_eq!(unsigned_invoice_request.bytes, buffer.as_slice());
951 assert_eq!(unsigned_invoice_request.payer_metadata(), &[1; 32]);
952 assert_eq!(unsigned_invoice_request.chains(), vec![ChainHash::using_genesis_block(Network::Bitcoin)]);
953 assert_eq!(unsigned_invoice_request.metadata(), None);
954 assert_eq!(unsigned_invoice_request.amount(), Some(&Amount::Bitcoin { amount_msats: 1000 }));
955 assert_eq!(unsigned_invoice_request.description(), PrintableString("foo"));
956 assert_eq!(unsigned_invoice_request.offer_features(), &OfferFeatures::empty());
957 assert_eq!(unsigned_invoice_request.absolute_expiry(), None);
958 assert_eq!(unsigned_invoice_request.paths(), &[]);
959 assert_eq!(unsigned_invoice_request.issuer(), None);
960 assert_eq!(unsigned_invoice_request.supported_quantity(), Quantity::One);
961 assert_eq!(unsigned_invoice_request.signing_pubkey(), recipient_pubkey());
962 assert_eq!(unsigned_invoice_request.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
963 assert_eq!(unsigned_invoice_request.amount_msats(), None);
964 assert_eq!(unsigned_invoice_request.invoice_request_features(), &InvoiceRequestFeatures::empty());
965 assert_eq!(unsigned_invoice_request.quantity(), None);
966 assert_eq!(unsigned_invoice_request.payer_id(), payer_pubkey());
967 assert_eq!(unsigned_invoice_request.payer_note(), None);
969 match UnsignedInvoiceRequest::try_from(buffer) {
970 Err(e) => panic!("error parsing unsigned invoice request: {:?}", e),
972 assert_eq!(parsed.bytes, unsigned_invoice_request.bytes);
973 assert_eq!(parsed.tagged_hash, unsigned_invoice_request.tagged_hash);
977 let invoice_request = unsigned_invoice_request.sign(payer_sign).unwrap();
979 let mut buffer = Vec::new();
980 invoice_request.write(&mut buffer).unwrap();
982 assert_eq!(invoice_request.bytes, buffer.as_slice());
983 assert_eq!(invoice_request.payer_metadata(), &[1; 32]);
984 assert_eq!(invoice_request.chains(), vec![ChainHash::using_genesis_block(Network::Bitcoin)]);
985 assert_eq!(invoice_request.metadata(), None);
986 assert_eq!(invoice_request.amount(), Some(&Amount::Bitcoin { amount_msats: 1000 }));
987 assert_eq!(invoice_request.description(), PrintableString("foo"));
988 assert_eq!(invoice_request.offer_features(), &OfferFeatures::empty());
989 assert_eq!(invoice_request.absolute_expiry(), None);
990 assert_eq!(invoice_request.paths(), &[]);
991 assert_eq!(invoice_request.issuer(), None);
992 assert_eq!(invoice_request.supported_quantity(), Quantity::One);
993 assert_eq!(invoice_request.signing_pubkey(), recipient_pubkey());
994 assert_eq!(invoice_request.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
995 assert_eq!(invoice_request.amount_msats(), None);
996 assert_eq!(invoice_request.invoice_request_features(), &InvoiceRequestFeatures::empty());
997 assert_eq!(invoice_request.quantity(), None);
998 assert_eq!(invoice_request.payer_id(), payer_pubkey());
999 assert_eq!(invoice_request.payer_note(), None);
1001 let message = TaggedHash::new(SIGNATURE_TAG, &invoice_request.bytes);
1002 assert!(merkle::verify_signature(&invoice_request.signature, message, payer_pubkey()).is_ok());
1005 invoice_request.as_tlv_stream(),
1007 PayerTlvStreamRef { metadata: Some(&vec![1; 32]) },
1013 description: Some(&String::from("foo")),
1015 absolute_expiry: None,
1019 node_id: Some(&recipient_pubkey()),
1021 InvoiceRequestTlvStreamRef {
1026 payer_id: Some(&payer_pubkey()),
1029 SignatureTlvStreamRef { signature: Some(&invoice_request.signature()) },
1033 if let Err(e) = InvoiceRequest::try_from(buffer) {
1034 panic!("error parsing invoice request: {:?}", e);
1038 #[cfg(feature = "std")]
1040 fn builds_invoice_request_from_offer_with_expiration() {
1041 let future_expiry = Duration::from_secs(u64::max_value());
1042 let past_expiry = Duration::from_secs(0);
1044 if let Err(e) = OfferBuilder::new("foo".into(), recipient_pubkey())
1046 .absolute_expiry(future_expiry)
1048 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1051 panic!("error building invoice_request: {:?}", e);
1054 match OfferBuilder::new("foo".into(), recipient_pubkey())
1056 .absolute_expiry(past_expiry)
1058 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1061 Ok(_) => panic!("expected error"),
1062 Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
1067 fn builds_invoice_request_with_derived_metadata() {
1068 let payer_id = payer_pubkey();
1069 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
1070 let entropy = FixedEntropy {};
1071 let secp_ctx = Secp256k1::new();
1073 let offer = OfferBuilder::new("foo".into(), recipient_pubkey())
1076 let invoice_request = offer
1077 .request_invoice_deriving_metadata(payer_id, &expanded_key, &entropy)
1080 .sign(payer_sign).unwrap();
1081 assert_eq!(invoice_request.payer_id(), payer_pubkey());
1083 let invoice = invoice_request.respond_with_no_std(payment_paths(), payment_hash(), now())
1086 .sign(recipient_sign).unwrap();
1087 assert!(invoice.verify(&expanded_key, &secp_ctx));
1089 // Fails verification with altered fields
1091 payer_tlv_stream, offer_tlv_stream, mut invoice_request_tlv_stream,
1092 mut invoice_tlv_stream, mut signature_tlv_stream
1093 ) = invoice.as_tlv_stream();
1094 invoice_request_tlv_stream.amount = Some(2000);
1095 invoice_tlv_stream.amount = Some(2000);
1098 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream);
1099 let mut bytes = Vec::new();
1100 tlv_stream.write(&mut bytes).unwrap();
1102 let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1103 let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
1104 signature_tlv_stream.signature = Some(&signature);
1106 let mut encoded_invoice = bytes;
1107 signature_tlv_stream.write(&mut encoded_invoice).unwrap();
1109 let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap();
1110 assert!(!invoice.verify(&expanded_key, &secp_ctx));
1112 // Fails verification with altered metadata
1114 mut payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
1115 mut signature_tlv_stream
1116 ) = invoice.as_tlv_stream();
1117 let metadata = payer_tlv_stream.metadata.unwrap().iter().copied().rev().collect();
1118 payer_tlv_stream.metadata = Some(&metadata);
1121 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream);
1122 let mut bytes = Vec::new();
1123 tlv_stream.write(&mut bytes).unwrap();
1125 let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1126 let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
1127 signature_tlv_stream.signature = Some(&signature);
1129 let mut encoded_invoice = bytes;
1130 signature_tlv_stream.write(&mut encoded_invoice).unwrap();
1132 let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap();
1133 assert!(!invoice.verify(&expanded_key, &secp_ctx));
1137 fn builds_invoice_request_with_derived_payer_id() {
1138 let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
1139 let entropy = FixedEntropy {};
1140 let secp_ctx = Secp256k1::new();
1142 let offer = OfferBuilder::new("foo".into(), recipient_pubkey())
1145 let invoice_request = offer
1146 .request_invoice_deriving_payer_id(&expanded_key, &entropy, &secp_ctx)
1151 let invoice = invoice_request.respond_with_no_std(payment_paths(), payment_hash(), now())
1154 .sign(recipient_sign).unwrap();
1155 assert!(invoice.verify(&expanded_key, &secp_ctx));
1157 // Fails verification with altered fields
1159 payer_tlv_stream, offer_tlv_stream, mut invoice_request_tlv_stream,
1160 mut invoice_tlv_stream, mut signature_tlv_stream
1161 ) = invoice.as_tlv_stream();
1162 invoice_request_tlv_stream.amount = Some(2000);
1163 invoice_tlv_stream.amount = Some(2000);
1166 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream);
1167 let mut bytes = Vec::new();
1168 tlv_stream.write(&mut bytes).unwrap();
1170 let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1171 let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
1172 signature_tlv_stream.signature = Some(&signature);
1174 let mut encoded_invoice = bytes;
1175 signature_tlv_stream.write(&mut encoded_invoice).unwrap();
1177 let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap();
1178 assert!(!invoice.verify(&expanded_key, &secp_ctx));
1180 // Fails verification with altered payer id
1182 payer_tlv_stream, offer_tlv_stream, mut invoice_request_tlv_stream, invoice_tlv_stream,
1183 mut signature_tlv_stream
1184 ) = invoice.as_tlv_stream();
1185 let payer_id = pubkey(1);
1186 invoice_request_tlv_stream.payer_id = Some(&payer_id);
1189 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream);
1190 let mut bytes = Vec::new();
1191 tlv_stream.write(&mut bytes).unwrap();
1193 let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1194 let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
1195 signature_tlv_stream.signature = Some(&signature);
1197 let mut encoded_invoice = bytes;
1198 signature_tlv_stream.write(&mut encoded_invoice).unwrap();
1200 let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap();
1201 assert!(!invoice.verify(&expanded_key, &secp_ctx));
1205 fn builds_invoice_request_with_chain() {
1206 let mainnet = ChainHash::using_genesis_block(Network::Bitcoin);
1207 let testnet = ChainHash::using_genesis_block(Network::Testnet);
1209 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1212 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1213 .chain(Network::Bitcoin).unwrap()
1215 .sign(payer_sign).unwrap();
1216 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1217 assert_eq!(invoice_request.chain(), mainnet);
1218 assert_eq!(tlv_stream.chain, None);
1220 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1222 .chain(Network::Testnet)
1224 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1225 .chain(Network::Testnet).unwrap()
1227 .sign(payer_sign).unwrap();
1228 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1229 assert_eq!(invoice_request.chain(), testnet);
1230 assert_eq!(tlv_stream.chain, Some(&testnet));
1232 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1234 .chain(Network::Bitcoin)
1235 .chain(Network::Testnet)
1237 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1238 .chain(Network::Bitcoin).unwrap()
1240 .sign(payer_sign).unwrap();
1241 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1242 assert_eq!(invoice_request.chain(), mainnet);
1243 assert_eq!(tlv_stream.chain, None);
1245 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1247 .chain(Network::Bitcoin)
1248 .chain(Network::Testnet)
1250 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1251 .chain(Network::Bitcoin).unwrap()
1252 .chain(Network::Testnet).unwrap()
1254 .sign(payer_sign).unwrap();
1255 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1256 assert_eq!(invoice_request.chain(), testnet);
1257 assert_eq!(tlv_stream.chain, Some(&testnet));
1259 match OfferBuilder::new("foo".into(), recipient_pubkey())
1261 .chain(Network::Testnet)
1263 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1264 .chain(Network::Bitcoin)
1266 Ok(_) => panic!("expected error"),
1267 Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
1270 match OfferBuilder::new("foo".into(), recipient_pubkey())
1272 .chain(Network::Testnet)
1274 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1277 Ok(_) => panic!("expected error"),
1278 Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
1283 fn builds_invoice_request_with_amount() {
1284 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1287 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1288 .amount_msats(1000).unwrap()
1290 .sign(payer_sign).unwrap();
1291 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1292 assert_eq!(invoice_request.amount_msats(), Some(1000));
1293 assert_eq!(tlv_stream.amount, Some(1000));
1295 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1298 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1299 .amount_msats(1001).unwrap()
1300 .amount_msats(1000).unwrap()
1302 .sign(payer_sign).unwrap();
1303 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1304 assert_eq!(invoice_request.amount_msats(), Some(1000));
1305 assert_eq!(tlv_stream.amount, Some(1000));
1307 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1310 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1311 .amount_msats(1001).unwrap()
1313 .sign(payer_sign).unwrap();
1314 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1315 assert_eq!(invoice_request.amount_msats(), Some(1001));
1316 assert_eq!(tlv_stream.amount, Some(1001));
1318 match OfferBuilder::new("foo".into(), recipient_pubkey())
1321 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1324 Ok(_) => panic!("expected error"),
1325 Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount),
1328 match OfferBuilder::new("foo".into(), recipient_pubkey())
1330 .supported_quantity(Quantity::Unbounded)
1332 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1333 .quantity(2).unwrap()
1336 Ok(_) => panic!("expected error"),
1337 Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount),
1340 match OfferBuilder::new("foo".into(), recipient_pubkey())
1343 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1344 .amount_msats(MAX_VALUE_MSAT + 1)
1346 Ok(_) => panic!("expected error"),
1347 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
1350 match OfferBuilder::new("foo".into(), recipient_pubkey())
1352 .supported_quantity(Quantity::Unbounded)
1354 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1355 .amount_msats(1000).unwrap()
1356 .quantity(2).unwrap()
1359 Ok(_) => panic!("expected error"),
1360 Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount),
1363 match OfferBuilder::new("foo".into(), recipient_pubkey())
1365 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1368 Ok(_) => panic!("expected error"),
1369 Err(e) => assert_eq!(e, Bolt12SemanticError::MissingAmount),
1372 match OfferBuilder::new("foo".into(), recipient_pubkey())
1374 .supported_quantity(Quantity::Unbounded)
1376 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1377 .quantity(u64::max_value()).unwrap()
1380 Ok(_) => panic!("expected error"),
1381 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
1386 fn builds_invoice_request_with_features() {
1387 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1390 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1391 .features_unchecked(InvoiceRequestFeatures::unknown())
1393 .sign(payer_sign).unwrap();
1394 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1395 assert_eq!(invoice_request.invoice_request_features(), &InvoiceRequestFeatures::unknown());
1396 assert_eq!(tlv_stream.features, Some(&InvoiceRequestFeatures::unknown()));
1398 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1401 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1402 .features_unchecked(InvoiceRequestFeatures::unknown())
1403 .features_unchecked(InvoiceRequestFeatures::empty())
1405 .sign(payer_sign).unwrap();
1406 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1407 assert_eq!(invoice_request.invoice_request_features(), &InvoiceRequestFeatures::empty());
1408 assert_eq!(tlv_stream.features, None);
1412 fn builds_invoice_request_with_quantity() {
1413 let one = NonZeroU64::new(1).unwrap();
1414 let ten = NonZeroU64::new(10).unwrap();
1416 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1418 .supported_quantity(Quantity::One)
1420 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1422 .sign(payer_sign).unwrap();
1423 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1424 assert_eq!(invoice_request.quantity(), None);
1425 assert_eq!(tlv_stream.quantity, None);
1427 match OfferBuilder::new("foo".into(), recipient_pubkey())
1429 .supported_quantity(Quantity::One)
1431 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1432 .amount_msats(2_000).unwrap()
1435 Ok(_) => panic!("expected error"),
1436 Err(e) => assert_eq!(e, Bolt12SemanticError::UnexpectedQuantity),
1439 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1441 .supported_quantity(Quantity::Bounded(ten))
1443 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1444 .amount_msats(10_000).unwrap()
1445 .quantity(10).unwrap()
1447 .sign(payer_sign).unwrap();
1448 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1449 assert_eq!(invoice_request.amount_msats(), Some(10_000));
1450 assert_eq!(tlv_stream.amount, Some(10_000));
1452 match OfferBuilder::new("foo".into(), recipient_pubkey())
1454 .supported_quantity(Quantity::Bounded(ten))
1456 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1457 .amount_msats(11_000).unwrap()
1460 Ok(_) => panic!("expected error"),
1461 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidQuantity),
1464 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1466 .supported_quantity(Quantity::Unbounded)
1468 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1469 .amount_msats(2_000).unwrap()
1470 .quantity(2).unwrap()
1472 .sign(payer_sign).unwrap();
1473 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1474 assert_eq!(invoice_request.amount_msats(), Some(2_000));
1475 assert_eq!(tlv_stream.amount, Some(2_000));
1477 match OfferBuilder::new("foo".into(), recipient_pubkey())
1479 .supported_quantity(Quantity::Unbounded)
1481 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1484 Ok(_) => panic!("expected error"),
1485 Err(e) => assert_eq!(e, Bolt12SemanticError::MissingQuantity),
1488 match OfferBuilder::new("foo".into(), recipient_pubkey())
1490 .supported_quantity(Quantity::Bounded(one))
1492 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1495 Ok(_) => panic!("expected error"),
1496 Err(e) => assert_eq!(e, Bolt12SemanticError::MissingQuantity),
1501 fn builds_invoice_request_with_payer_note() {
1502 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1505 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1506 .payer_note("bar".into())
1508 .sign(payer_sign).unwrap();
1509 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1510 assert_eq!(invoice_request.payer_note(), Some(PrintableString("bar")));
1511 assert_eq!(tlv_stream.payer_note, Some(&String::from("bar")));
1513 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1516 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1517 .payer_note("bar".into())
1518 .payer_note("baz".into())
1520 .sign(payer_sign).unwrap();
1521 let (_, _, tlv_stream, _) = invoice_request.as_tlv_stream();
1522 assert_eq!(invoice_request.payer_note(), Some(PrintableString("baz")));
1523 assert_eq!(tlv_stream.payer_note, Some(&String::from("baz")));
1527 fn fails_signing_invoice_request() {
1528 match OfferBuilder::new("foo".into(), recipient_pubkey())
1531 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1535 Ok(_) => panic!("expected error"),
1536 Err(e) => assert_eq!(e, SignError::Signing(())),
1539 match OfferBuilder::new("foo".into(), recipient_pubkey())
1542 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1544 .sign(recipient_sign)
1546 Ok(_) => panic!("expected error"),
1547 Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::InvalidSignature)),
1552 fn fails_responding_with_unknown_required_features() {
1553 match OfferBuilder::new("foo".into(), recipient_pubkey())
1556 .request_invoice(vec![42; 32], payer_pubkey()).unwrap()
1557 .features_unchecked(InvoiceRequestFeatures::unknown())
1559 .sign(payer_sign).unwrap()
1560 .respond_with_no_std(payment_paths(), payment_hash(), now())
1562 Ok(_) => panic!("expected error"),
1563 Err(e) => assert_eq!(e, Bolt12SemanticError::UnknownRequiredFeatures),
1568 fn parses_invoice_request_with_metadata() {
1569 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1572 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1574 .sign(payer_sign).unwrap();
1576 let mut buffer = Vec::new();
1577 invoice_request.write(&mut buffer).unwrap();
1579 if let Err(e) = InvoiceRequest::try_from(buffer) {
1580 panic!("error parsing invoice_request: {:?}", e);
1585 fn parses_invoice_request_with_chain() {
1586 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1589 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1590 .chain(Network::Bitcoin).unwrap()
1592 .sign(payer_sign).unwrap();
1594 let mut buffer = Vec::new();
1595 invoice_request.write(&mut buffer).unwrap();
1597 if let Err(e) = InvoiceRequest::try_from(buffer) {
1598 panic!("error parsing invoice_request: {:?}", e);
1601 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1604 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1605 .chain_unchecked(Network::Testnet)
1607 .sign(payer_sign).unwrap();
1609 let mut buffer = Vec::new();
1610 invoice_request.write(&mut buffer).unwrap();
1612 match InvoiceRequest::try_from(buffer) {
1613 Ok(_) => panic!("expected error"),
1614 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
1619 fn parses_invoice_request_with_amount() {
1620 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1623 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1625 .sign(payer_sign).unwrap();
1627 let mut buffer = Vec::new();
1628 invoice_request.write(&mut buffer).unwrap();
1630 if let Err(e) = InvoiceRequest::try_from(buffer) {
1631 panic!("error parsing invoice_request: {:?}", e);
1634 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1636 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1637 .amount_msats(1000).unwrap()
1639 .sign(payer_sign).unwrap();
1641 let mut buffer = Vec::new();
1642 invoice_request.write(&mut buffer).unwrap();
1644 if let Err(e) = InvoiceRequest::try_from(buffer) {
1645 panic!("error parsing invoice_request: {:?}", e);
1648 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1650 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1652 .sign(payer_sign).unwrap();
1654 let mut buffer = Vec::new();
1655 invoice_request.write(&mut buffer).unwrap();
1657 match InvoiceRequest::try_from(buffer) {
1658 Ok(_) => panic!("expected error"),
1659 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)),
1662 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1665 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1666 .amount_msats_unchecked(999)
1668 .sign(payer_sign).unwrap();
1670 let mut buffer = Vec::new();
1671 invoice_request.write(&mut buffer).unwrap();
1673 match InvoiceRequest::try_from(buffer) {
1674 Ok(_) => panic!("expected error"),
1675 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InsufficientAmount)),
1678 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1679 .amount(Amount::Currency { iso4217_code: *b"USD", amount: 1000 })
1681 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1683 .sign(payer_sign).unwrap();
1685 let mut buffer = Vec::new();
1686 invoice_request.write(&mut buffer).unwrap();
1688 match InvoiceRequest::try_from(buffer) {
1689 Ok(_) => panic!("expected error"),
1691 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnsupportedCurrency));
1695 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1697 .supported_quantity(Quantity::Unbounded)
1699 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1700 .quantity(u64::max_value()).unwrap()
1702 .sign(payer_sign).unwrap();
1704 let mut buffer = Vec::new();
1705 invoice_request.write(&mut buffer).unwrap();
1707 match InvoiceRequest::try_from(buffer) {
1708 Ok(_) => panic!("expected error"),
1709 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)),
1714 fn parses_invoice_request_with_quantity() {
1715 let one = NonZeroU64::new(1).unwrap();
1716 let ten = NonZeroU64::new(10).unwrap();
1718 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1720 .supported_quantity(Quantity::One)
1722 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1724 .sign(payer_sign).unwrap();
1726 let mut buffer = Vec::new();
1727 invoice_request.write(&mut buffer).unwrap();
1729 if let Err(e) = InvoiceRequest::try_from(buffer) {
1730 panic!("error parsing invoice_request: {:?}", e);
1733 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1735 .supported_quantity(Quantity::One)
1737 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1738 .amount_msats(2_000).unwrap()
1739 .quantity_unchecked(2)
1741 .sign(payer_sign).unwrap();
1743 let mut buffer = Vec::new();
1744 invoice_request.write(&mut buffer).unwrap();
1746 match InvoiceRequest::try_from(buffer) {
1747 Ok(_) => panic!("expected error"),
1749 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedQuantity));
1753 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1755 .supported_quantity(Quantity::Bounded(ten))
1757 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1758 .amount_msats(10_000).unwrap()
1759 .quantity(10).unwrap()
1761 .sign(payer_sign).unwrap();
1763 let mut buffer = Vec::new();
1764 invoice_request.write(&mut buffer).unwrap();
1766 if let Err(e) = InvoiceRequest::try_from(buffer) {
1767 panic!("error parsing invoice_request: {:?}", e);
1770 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1772 .supported_quantity(Quantity::Bounded(ten))
1774 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1775 .amount_msats(11_000).unwrap()
1776 .quantity_unchecked(11)
1778 .sign(payer_sign).unwrap();
1780 let mut buffer = Vec::new();
1781 invoice_request.write(&mut buffer).unwrap();
1783 match InvoiceRequest::try_from(buffer) {
1784 Ok(_) => panic!("expected error"),
1785 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidQuantity)),
1788 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1790 .supported_quantity(Quantity::Unbounded)
1792 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1793 .amount_msats(2_000).unwrap()
1794 .quantity(2).unwrap()
1796 .sign(payer_sign).unwrap();
1798 let mut buffer = Vec::new();
1799 invoice_request.write(&mut buffer).unwrap();
1801 if let Err(e) = InvoiceRequest::try_from(buffer) {
1802 panic!("error parsing invoice_request: {:?}", e);
1805 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1807 .supported_quantity(Quantity::Unbounded)
1809 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1811 .sign(payer_sign).unwrap();
1813 let mut buffer = Vec::new();
1814 invoice_request.write(&mut buffer).unwrap();
1816 match InvoiceRequest::try_from(buffer) {
1817 Ok(_) => panic!("expected error"),
1818 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingQuantity)),
1821 let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1823 .supported_quantity(Quantity::Bounded(one))
1825 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1827 .sign(payer_sign).unwrap();
1829 let mut buffer = Vec::new();
1830 invoice_request.write(&mut buffer).unwrap();
1832 match InvoiceRequest::try_from(buffer) {
1833 Ok(_) => panic!("expected error"),
1834 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingQuantity)),
1839 fn fails_parsing_invoice_request_without_metadata() {
1840 let offer = OfferBuilder::new("foo".into(), recipient_pubkey())
1843 let unsigned_invoice_request = offer.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1845 let mut tlv_stream = unsigned_invoice_request.contents.as_tlv_stream();
1846 tlv_stream.0.metadata = None;
1848 let mut buffer = Vec::new();
1849 tlv_stream.write(&mut buffer).unwrap();
1851 match InvoiceRequest::try_from(buffer) {
1852 Ok(_) => panic!("expected error"),
1854 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerMetadata));
1860 fn fails_parsing_invoice_request_without_payer_id() {
1861 let offer = OfferBuilder::new("foo".into(), recipient_pubkey())
1864 let unsigned_invoice_request = offer.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1866 let mut tlv_stream = unsigned_invoice_request.contents.as_tlv_stream();
1867 tlv_stream.2.payer_id = None;
1869 let mut buffer = Vec::new();
1870 tlv_stream.write(&mut buffer).unwrap();
1872 match InvoiceRequest::try_from(buffer) {
1873 Ok(_) => panic!("expected error"),
1874 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerId)),
1879 fn fails_parsing_invoice_request_without_node_id() {
1880 let offer = OfferBuilder::new("foo".into(), recipient_pubkey())
1883 let unsigned_invoice_request = offer.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1885 let mut tlv_stream = unsigned_invoice_request.contents.as_tlv_stream();
1886 tlv_stream.1.node_id = None;
1888 let mut buffer = Vec::new();
1889 tlv_stream.write(&mut buffer).unwrap();
1891 match InvoiceRequest::try_from(buffer) {
1892 Ok(_) => panic!("expected error"),
1894 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey));
1900 fn fails_parsing_invoice_request_without_signature() {
1901 let mut buffer = Vec::new();
1902 OfferBuilder::new("foo".into(), recipient_pubkey())
1905 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1908 .write(&mut buffer).unwrap();
1910 match InvoiceRequest::try_from(buffer) {
1911 Ok(_) => panic!("expected error"),
1912 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
1917 fn fails_parsing_invoice_request_with_invalid_signature() {
1918 let mut invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey())
1921 .request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1923 .sign(payer_sign).unwrap();
1924 let last_signature_byte = invoice_request.bytes.last_mut().unwrap();
1925 *last_signature_byte = last_signature_byte.wrapping_add(1);
1927 let mut buffer = Vec::new();
1928 invoice_request.write(&mut buffer).unwrap();
1930 match InvoiceRequest::try_from(buffer) {
1931 Ok(_) => panic!("expected error"),
1933 assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
1939 fn fails_parsing_invoice_request_with_extra_tlv_records() {
1940 let secp_ctx = Secp256k1::new();
1941 let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
1942 let invoice_request = OfferBuilder::new("foo".into(), keys.public_key())
1945 .request_invoice(vec![1; 32], keys.public_key()).unwrap()
1947 .sign::<_, Infallible>(
1948 |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
1952 let mut encoded_invoice_request = Vec::new();
1953 invoice_request.write(&mut encoded_invoice_request).unwrap();
1954 BigSize(1002).write(&mut encoded_invoice_request).unwrap();
1955 BigSize(32).write(&mut encoded_invoice_request).unwrap();
1956 [42u8; 32].write(&mut encoded_invoice_request).unwrap();
1958 match InvoiceRequest::try_from(encoded_invoice_request) {
1959 Ok(_) => panic!("expected error"),
1960 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),