1use bitcoin::constants::ChainHash;
69use bitcoin::network::Network;
70use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, self};
71use bitcoin::secp256k1::schnorr::Signature;
72use crate::io;
73use crate::blinded_path::message::BlindedMessagePath;
74use crate::blinded_path::payment::BlindedPaymentPath;
75use crate::types::payment::PaymentHash;
76use crate::ln::channelmanager::PaymentId;
77use crate::types::features::InvoiceRequestFeatures;
78use crate::ln::inbound_payment::{ExpandedKey, IV_LEN};
79use crate::ln::msgs::DecodeError;
80use crate::offers::merkle::{SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream, self};
81use crate::offers::nonce::Nonce;
82use crate::offers::offer::{Amount, EXPERIMENTAL_OFFER_TYPES, ExperimentalOfferTlvStream, ExperimentalOfferTlvStreamRef, OFFER_TYPES, Offer, OfferContents, OfferId, OfferTlvStream, OfferTlvStreamRef};
83use crate::offers::parse::{Bolt12ParseError, ParsedMessage, Bolt12SemanticError};
84use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
85use crate::offers::signer::{Metadata, MetadataMaterial};
86use crate::onion_message::dns_resolution::HumanReadableName;
87use crate::util::ser::{CursorReadable, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};
88use crate::util::string::{PrintableString, UntrustedString};
89
90#[cfg(not(c_bindings))]
91use {
92 crate::offers::invoice::{DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder},
93};
94#[cfg(c_bindings)]
95use {
96 crate::offers::invoice::{InvoiceWithDerivedSigningPubkeyBuilder, InvoiceWithExplicitSigningPubkeyBuilder},
97};
98
99#[allow(unused_imports)]
100use crate::prelude::*;
101
102pub const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice_request", "signature");
104
105pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Invreq ~~~~~";
106
107pub struct InvoiceRequestBuilder<'a, 'b, T: secp256k1::Signing> {
115 offer: &'a Offer,
116 invoice_request: InvoiceRequestContentsWithoutPayerSigningPubkey,
117 payer_signing_pubkey: Option<PublicKey>,
118 secp_ctx: Option<&'b Secp256k1<T>>,
119}
120
121#[cfg(c_bindings)]
127pub struct InvoiceRequestWithDerivedPayerSigningPubkeyBuilder<'a, 'b> {
128 offer: &'a Offer,
129 invoice_request: InvoiceRequestContentsWithoutPayerSigningPubkey,
130 payer_signing_pubkey: Option<PublicKey>,
131 secp_ctx: Option<&'b Secp256k1<secp256k1::All>>,
132}
133
134macro_rules! invoice_request_derived_payer_signing_pubkey_builder_methods { (
135 $self: ident, $self_type: ty, $secp_context: ty
136) => {
137 #[cfg_attr(c_bindings, allow(dead_code))]
138 pub(super) fn deriving_signing_pubkey(
139 offer: &'a Offer, expanded_key: &ExpandedKey, nonce: Nonce,
140 secp_ctx: &'b Secp256k1<$secp_context>, payment_id: PaymentId
141 ) -> Self {
142 let payment_id = Some(payment_id);
143 let derivation_material = MetadataMaterial::new(nonce, expanded_key, payment_id);
144 let metadata = Metadata::DerivedSigningPubkey(derivation_material);
145 Self {
146 offer,
147 invoice_request: Self::create_contents(offer, metadata),
148 payer_signing_pubkey: None,
149 secp_ctx: Some(secp_ctx),
150 }
151 }
152
153 pub fn build_and_sign($self: $self_type) -> Result<InvoiceRequest, Bolt12SemanticError> {
155 let (unsigned_invoice_request, keys, secp_ctx) = $self.build_with_checks()?;
156 #[cfg(c_bindings)]
157 let mut unsigned_invoice_request = unsigned_invoice_request;
158 debug_assert!(keys.is_some());
159
160 let secp_ctx = secp_ctx.unwrap();
161 let keys = keys.unwrap();
162 let invoice_request = unsigned_invoice_request
163 .sign(|message: &UnsignedInvoiceRequest|
164 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
165 )
166 .unwrap();
167 Ok(invoice_request)
168 }
169} }
170
171macro_rules! invoice_request_builder_methods { (
172 $self: ident, $self_type: ty, $return_type: ty, $return_value: expr, $secp_context: ty $(, $self_mut: tt)?
173) => {
174 #[cfg_attr(c_bindings, allow(dead_code))]
175 fn create_contents(offer: &Offer, metadata: Metadata) -> InvoiceRequestContentsWithoutPayerSigningPubkey {
176 let offer = offer.contents.clone();
177 InvoiceRequestContentsWithoutPayerSigningPubkey {
178 payer: PayerContents(metadata), offer, chain: None, amount_msats: None,
179 features: InvoiceRequestFeatures::empty(), quantity: None, payer_note: None,
180 offer_from_hrn: None,
181 #[cfg(test)]
182 experimental_bar: None,
183 }
184 }
185
186 pub fn chain($self: $self_type, network: Network) -> Result<$return_type, Bolt12SemanticError> {
192 $self.chain_hash(ChainHash::using_genesis_block(network))
193 }
194
195 pub(crate) fn chain_hash($($self_mut)* $self: $self_type, chain: ChainHash) -> Result<$return_type, Bolt12SemanticError> {
201 if !$self.offer.supports_chain(chain) {
202 return Err(Bolt12SemanticError::UnsupportedChain);
203 }
204
205 $self.invoice_request.chain = Some(chain);
206 Ok($return_value)
207 }
208
209 pub fn amount_msats($($self_mut)* $self: $self_type, amount_msats: u64) -> Result<$return_type, Bolt12SemanticError> {
216 $self.invoice_request.offer.check_amount_msats_for_quantity(
217 Some(amount_msats), $self.invoice_request.quantity
218 )?;
219 $self.invoice_request.amount_msats = Some(amount_msats);
220 Ok($return_value)
221 }
222
223 pub fn quantity($($self_mut)* $self: $self_type, quantity: u64) -> Result<$return_type, Bolt12SemanticError> {
228 $self.invoice_request.offer.check_quantity(Some(quantity))?;
229 $self.invoice_request.quantity = Some(quantity);
230 Ok($return_value)
231 }
232
233 pub fn payer_note($($self_mut)* $self: $self_type, payer_note: String) -> $return_type {
237 $self.invoice_request.payer_note = Some(payer_note);
238 $return_value
239 }
240
241 pub fn sourced_from_human_readable_name($($self_mut)* $self: $self_type, hrn: HumanReadableName) -> $return_type {
245 $self.invoice_request.offer_from_hrn = Some(hrn);
246 $return_value
247 }
248
249 fn build_with_checks($($self_mut)* $self: $self_type) -> Result<
250 (UnsignedInvoiceRequest, Option<Keypair>, Option<&'b Secp256k1<$secp_context>>),
251 Bolt12SemanticError
252 > {
253 #[cfg(feature = "std")] {
254 if $self.offer.is_expired() {
255 return Err(Bolt12SemanticError::AlreadyExpired);
256 }
257 }
258
259 let chain = $self.invoice_request.chain();
260 if !$self.offer.supports_chain(chain) {
261 return Err(Bolt12SemanticError::UnsupportedChain);
262 }
263
264 if chain == $self.offer.implied_chain() {
265 $self.invoice_request.chain = None;
266 }
267
268 if $self.offer.amount().is_none() && $self.invoice_request.amount_msats.is_none() {
269 return Err(Bolt12SemanticError::MissingAmount);
270 }
271
272 $self.invoice_request.offer.check_quantity($self.invoice_request.quantity)?;
273 $self.invoice_request.offer.check_amount_msats_for_quantity(
274 $self.invoice_request.amount_msats, $self.invoice_request.quantity
275 )?;
276
277 Ok($self.build_without_checks())
278 }
279
280 fn build_without_checks($($self_mut)* $self: $self_type) ->
281 (UnsignedInvoiceRequest, Option<Keypair>, Option<&'b Secp256k1<$secp_context>>)
282 {
283 let mut keys = None;
285 let secp_ctx = $self.secp_ctx.clone();
286 if $self.invoice_request.payer.0.has_derivation_material() {
287 let mut metadata = core::mem::take(&mut $self.invoice_request.payer.0);
288
289 let mut tlv_stream = $self.invoice_request.as_tlv_stream();
290 debug_assert!(tlv_stream.2.payer_id.is_none());
291 tlv_stream.0.metadata = None;
292 if !metadata.derives_payer_keys() {
293 tlv_stream.2.payer_id = $self.payer_signing_pubkey.as_ref();
294 }
295
296 let (derived_metadata, derived_keys) =
297 metadata.derive_from(IV_BYTES, tlv_stream, $self.secp_ctx);
298 metadata = derived_metadata;
299 keys = derived_keys;
300 if let Some(keys) = keys {
301 debug_assert!($self.payer_signing_pubkey.is_none());
302 $self.payer_signing_pubkey = Some(keys.public_key());
303 }
304
305 $self.invoice_request.payer.0 = metadata;
306 }
307
308 debug_assert!($self.invoice_request.payer.0.as_bytes().is_some());
309 debug_assert!($self.payer_signing_pubkey.is_some());
310 let payer_signing_pubkey = $self.payer_signing_pubkey.unwrap();
311
312 let invoice_request = InvoiceRequestContents {
313 #[cfg(not(c_bindings))]
314 inner: $self.invoice_request,
315 #[cfg(c_bindings)]
316 inner: $self.invoice_request.clone(),
317 payer_signing_pubkey,
318 };
319 let unsigned_invoice_request = UnsignedInvoiceRequest::new($self.offer, invoice_request);
320
321 (unsigned_invoice_request, keys, secp_ctx)
322 }
323} }
324
325#[cfg(test)]
326macro_rules! invoice_request_builder_test_methods { (
327 $self: ident, $self_type: ty, $return_type: ty, $return_value: expr $(, $self_mut: tt)?
328) => {
329 #[cfg_attr(c_bindings, allow(dead_code))]
330 pub(super) fn payer_metadata($($self_mut)* $self: $self_type, metadata: Metadata) -> $return_type {
331 $self.invoice_request.payer = PayerContents(metadata);
332 $return_value
333 }
334
335 #[cfg_attr(c_bindings, allow(dead_code))]
336 fn chain_unchecked($($self_mut)* $self: $self_type, network: Network) -> $return_type {
337 let chain = ChainHash::using_genesis_block(network);
338 $self.invoice_request.chain = Some(chain);
339 $return_value
340 }
341
342 #[cfg_attr(c_bindings, allow(dead_code))]
343 fn amount_msats_unchecked($($self_mut)* $self: $self_type, amount_msats: u64) -> $return_type {
344 $self.invoice_request.amount_msats = Some(amount_msats);
345 $return_value
346 }
347
348 #[cfg_attr(c_bindings, allow(dead_code))]
349 fn features_unchecked($($self_mut)* $self: $self_type, features: InvoiceRequestFeatures) -> $return_type {
350 $self.invoice_request.features = features;
351 $return_value
352 }
353
354 #[cfg_attr(c_bindings, allow(dead_code))]
355 fn quantity_unchecked($($self_mut)* $self: $self_type, quantity: u64) -> $return_type {
356 $self.invoice_request.quantity = Some(quantity);
357 $return_value
358 }
359
360 #[cfg_attr(c_bindings, allow(dead_code))]
361 pub(super) fn payer_signing_pubkey($($self_mut)* $self: $self_type, signing_pubkey: PublicKey) -> $return_type {
362 $self.payer_signing_pubkey = Some(signing_pubkey);
363 $return_value
364 }
365
366 #[cfg_attr(c_bindings, allow(dead_code))]
367 pub(super) fn experimental_bar($($self_mut)* $self: $self_type, experimental_bar: u64) -> $return_type {
368 $self.invoice_request.experimental_bar = Some(experimental_bar);
369 $return_value
370 }
371
372 #[cfg_attr(c_bindings, allow(dead_code))]
373 pub(super) fn build_unchecked($self: $self_type) -> UnsignedInvoiceRequest {
374 $self.build_without_checks().0
375 }
376
377 #[cfg_attr(c_bindings, allow(dead_code))]
378 pub(super) fn build_unchecked_and_sign($self: $self_type) -> InvoiceRequest {
379 let (unsigned_invoice_request, keys, secp_ctx) = $self.build_without_checks();
380 #[cfg(c_bindings)]
381 let mut unsigned_invoice_request = unsigned_invoice_request;
382 debug_assert!(keys.is_some());
383
384 let secp_ctx = secp_ctx.unwrap();
385 let keys = keys.unwrap();
386 unsigned_invoice_request
387 .sign(|message: &UnsignedInvoiceRequest|
388 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
389 )
390 .unwrap()
391 }
392} }
393
394impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, T> {
395 invoice_request_derived_payer_signing_pubkey_builder_methods!(self, Self, T);
396 invoice_request_builder_methods!(self, Self, Self, self, T, mut);
397
398 #[cfg(test)]
399 invoice_request_builder_test_methods!(self, Self, Self, self, mut);
400}
401
402#[cfg(all(c_bindings, not(test)))]
403impl<'a, 'b> InvoiceRequestWithDerivedPayerSigningPubkeyBuilder<'a, 'b> {
404 invoice_request_derived_payer_signing_pubkey_builder_methods!(self, &mut Self, secp256k1::All);
405 invoice_request_builder_methods!(self, &mut Self, (), (), secp256k1::All);
406}
407
408#[cfg(all(c_bindings, test))]
409impl<'a, 'b> InvoiceRequestWithDerivedPayerSigningPubkeyBuilder<'a, 'b> {
410 invoice_request_derived_payer_signing_pubkey_builder_methods!(self, &mut Self, secp256k1::All);
411 invoice_request_builder_methods!(self, &mut Self, &mut Self, self, secp256k1::All);
412 invoice_request_builder_test_methods!(self, &mut Self, &mut Self, self);
413}
414
415#[cfg(c_bindings)]
416impl<'a, 'b> From<InvoiceRequestWithDerivedPayerSigningPubkeyBuilder<'a, 'b>>
417for InvoiceRequestBuilder<'a, 'b, secp256k1::All> {
418 fn from(builder: InvoiceRequestWithDerivedPayerSigningPubkeyBuilder<'a, 'b>) -> Self {
419 let InvoiceRequestWithDerivedPayerSigningPubkeyBuilder {
420 offer, invoice_request, payer_signing_pubkey, secp_ctx,
421 } = builder;
422
423 Self {
424 offer, invoice_request, payer_signing_pubkey, secp_ctx,
425 }
426 }
427}
428
429#[derive(Clone)]
436pub struct UnsignedInvoiceRequest {
437 bytes: Vec<u8>,
438 experimental_bytes: Vec<u8>,
439 contents: InvoiceRequestContents,
440 tagged_hash: TaggedHash,
441}
442
443pub trait SignInvoiceRequestFn {
445 fn sign_invoice_request(&self, message: &UnsignedInvoiceRequest) -> Result<Signature, ()>;
447}
448
449impl<F> SignInvoiceRequestFn for F
450where
451 F: Fn(&UnsignedInvoiceRequest) -> Result<Signature, ()>,
452{
453 fn sign_invoice_request(&self, message: &UnsignedInvoiceRequest) -> Result<Signature, ()> {
454 self(message)
455 }
456}
457
458impl<F> SignFn<UnsignedInvoiceRequest> for F
459where
460 F: SignInvoiceRequestFn,
461{
462 fn sign(&self, message: &UnsignedInvoiceRequest) -> Result<Signature, ()> {
463 self.sign_invoice_request(message)
464 }
465}
466
467impl UnsignedInvoiceRequest {
468 fn new(offer: &Offer, contents: InvoiceRequestContents) -> Self {
469 let (
472 payer_tlv_stream, _offer_tlv_stream, invoice_request_tlv_stream,
473 _experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
474 ) = contents.as_tlv_stream();
475
476 const INVOICE_REQUEST_ALLOCATION_SIZE: usize = 512;
477 let mut bytes = Vec::with_capacity(INVOICE_REQUEST_ALLOCATION_SIZE);
478
479 payer_tlv_stream.write(&mut bytes).unwrap();
480
481 for record in TlvStream::new(&offer.bytes).range(OFFER_TYPES) {
482 record.write(&mut bytes).unwrap();
483 }
484
485 let remaining_bytes = &offer.bytes[bytes.len() - payer_tlv_stream.serialized_length()..];
486
487 invoice_request_tlv_stream.write(&mut bytes).unwrap();
488
489 const EXPERIMENTAL_TLV_ALLOCATION_SIZE: usize = 0;
490 let mut experimental_bytes = Vec::with_capacity(EXPERIMENTAL_TLV_ALLOCATION_SIZE);
491
492 let experimental_tlv_stream = TlvStream::new(remaining_bytes)
493 .range(EXPERIMENTAL_OFFER_TYPES);
494 for record in experimental_tlv_stream {
495 record.write(&mut experimental_bytes).unwrap();
496 }
497
498 experimental_invoice_request_tlv_stream.write(&mut experimental_bytes).unwrap();
499
500 let tlv_stream = TlvStream::new(&bytes).chain(TlvStream::new(&experimental_bytes));
501 let tagged_hash = TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
502
503 Self { bytes, experimental_bytes, contents, tagged_hash }
504 }
505
506 pub fn tagged_hash(&self) -> &TaggedHash {
508 &self.tagged_hash
509 }
510}
511
512macro_rules! unsigned_invoice_request_sign_method { (
513 $self: ident, $self_type: ty $(, $self_mut: tt)?
514) => {
515 pub fn sign<F: SignInvoiceRequestFn>(
519 $($self_mut)* $self: $self_type, sign: F
520 ) -> Result<InvoiceRequest, SignError> {
521 let pubkey = $self.contents.payer_signing_pubkey;
522 let signature = merkle::sign_message(sign, &$self, pubkey)?;
523
524 let signature_tlv_stream = SignatureTlvStreamRef {
526 signature: Some(&signature),
527 };
528 signature_tlv_stream.write(&mut $self.bytes).unwrap();
529
530 $self.bytes.extend_from_slice(&$self.experimental_bytes);
532
533 Ok(InvoiceRequest {
534 #[cfg(not(c_bindings))]
535 bytes: $self.bytes,
536 #[cfg(c_bindings)]
537 bytes: $self.bytes.clone(),
538 #[cfg(not(c_bindings))]
539 contents: $self.contents,
540 #[cfg(c_bindings)]
541 contents: $self.contents.clone(),
542 signature,
543 })
544 }
545} }
546
547#[cfg(not(c_bindings))]
548impl UnsignedInvoiceRequest {
549 unsigned_invoice_request_sign_method!(self, Self, mut);
550}
551
552#[cfg(c_bindings)]
553impl UnsignedInvoiceRequest {
554 unsigned_invoice_request_sign_method!(self, &mut Self);
555}
556
557impl AsRef<TaggedHash> for UnsignedInvoiceRequest {
558 fn as_ref(&self) -> &TaggedHash {
559 &self.tagged_hash
560 }
561}
562
563#[derive(Clone, Debug)]
571#[cfg_attr(test, derive(PartialEq))]
572pub struct InvoiceRequest {
573 pub(super) bytes: Vec<u8>,
574 pub(super) contents: InvoiceRequestContents,
575 signature: Signature,
576}
577
578#[derive(Clone, Debug)]
582pub struct VerifiedInvoiceRequest {
583 pub offer_id: OfferId,
585
586 pub(crate) inner: InvoiceRequest,
588
589 #[cfg_attr(feature = "std", doc = "If `Some`, must call [`respond_using_derived_keys`] when responding. Otherwise, call [`respond_with`].")]
592 #[cfg_attr(feature = "std", doc = "")]
593 #[cfg_attr(feature = "std", doc = "[`respond_using_derived_keys`]: Self::respond_using_derived_keys")]
595 #[cfg_attr(feature = "std", doc = "[`respond_with`]: Self::respond_with")]
596 pub keys: Option<Keypair>,
597}
598
599#[derive(Clone, Debug)]
603#[cfg_attr(test, derive(PartialEq))]
604pub(super) struct InvoiceRequestContents {
605 pub(super) inner: InvoiceRequestContentsWithoutPayerSigningPubkey,
606 payer_signing_pubkey: PublicKey,
607}
608
609#[derive(Clone, Debug)]
610#[cfg_attr(test, derive(PartialEq))]
611pub(super) struct InvoiceRequestContentsWithoutPayerSigningPubkey {
612 pub(super) payer: PayerContents,
613 pub(super) offer: OfferContents,
614 chain: Option<ChainHash>,
615 amount_msats: Option<u64>,
616 features: InvoiceRequestFeatures,
617 quantity: Option<u64>,
618 payer_note: Option<String>,
619 offer_from_hrn: Option<HumanReadableName>,
620 #[cfg(test)]
621 experimental_bar: Option<u64>,
622}
623
624macro_rules! invoice_request_accessors { ($self: ident, $contents: expr) => {
625 pub fn payer_metadata(&$self) -> &[u8] {
630 $contents.metadata()
631 }
632
633 pub fn chain(&$self) -> ChainHash {
635 $contents.chain()
636 }
637
638 pub fn amount_msats(&$self) -> Option<u64> {
643 $contents.amount_msats()
644 }
645
646 pub fn has_amount_msats(&$self) -> bool {
652 $contents.has_amount_msats()
653 }
654
655 pub fn invoice_request_features(&$self) -> &InvoiceRequestFeatures {
657 &$contents.features()
658 }
659
660 pub fn quantity(&$self) -> Option<u64> {
662 $contents.quantity()
663 }
664
665 pub fn payer_signing_pubkey(&$self) -> PublicKey {
667 $contents.payer_signing_pubkey()
668 }
669
670 pub fn payer_note(&$self) -> Option<PrintableString> {
673 $contents.payer_note()
674 }
675
676 pub fn offer_from_hrn(&$self) -> &Option<HumanReadableName> {
679 $contents.offer_from_hrn()
680 }
681} }
682
683impl UnsignedInvoiceRequest {
684 offer_accessors!(self, self.contents.inner.offer);
685 invoice_request_accessors!(self, self.contents);
686}
687
688macro_rules! invoice_request_respond_with_explicit_signing_pubkey_methods { (
689 $self: ident, $contents: expr, $builder: ty
690) => {
691 #[cfg(feature = "std")]
699 pub fn respond_with(
700 &$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash
701 ) -> Result<$builder, Bolt12SemanticError> {
702 let created_at = std::time::SystemTime::now()
703 .duration_since(std::time::SystemTime::UNIX_EPOCH)
704 .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
705
706 $contents.respond_with_no_std(payment_paths, payment_hash, created_at)
707 }
708
709 #[cfg_attr(feature = "std", doc = "Useful for non-`std` builds where [`std::time::SystemTime`] is not available.")]
714 pub fn respond_with_no_std(
735 &$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash,
736 created_at: core::time::Duration
737 ) -> Result<$builder, Bolt12SemanticError> {
738 if $contents.invoice_request_features().requires_unknown_bits() {
739 return Err(Bolt12SemanticError::UnknownRequiredFeatures);
740 }
741
742 let signing_pubkey = match $contents.contents.inner.offer.issuer_signing_pubkey() {
743 Some(signing_pubkey) => signing_pubkey,
744 None => return Err(Bolt12SemanticError::MissingIssuerSigningPubkey),
745 };
746
747 <$builder>::for_offer(&$contents, payment_paths, created_at, payment_hash, signing_pubkey)
748 }
749
750 #[cfg(test)]
751 #[allow(dead_code)]
752 pub(super) fn respond_with_no_std_using_signing_pubkey(
753 &$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash,
754 created_at: core::time::Duration, signing_pubkey: PublicKey
755 ) -> Result<$builder, Bolt12SemanticError> {
756 debug_assert!($contents.contents.inner.offer.issuer_signing_pubkey().is_none());
757
758 if $contents.invoice_request_features().requires_unknown_bits() {
759 return Err(Bolt12SemanticError::UnknownRequiredFeatures);
760 }
761
762 <$builder>::for_offer(&$contents, payment_paths, created_at, payment_hash, signing_pubkey)
763 }
764} }
765
766macro_rules! invoice_request_verify_method { ($self: ident, $self_type: ty) => {
767 pub fn verify_using_metadata<
775 #[cfg(not(c_bindings))]
776 T: secp256k1::Signing
777 >(
778 $self: $self_type, key: &ExpandedKey,
779 #[cfg(not(c_bindings))]
780 secp_ctx: &Secp256k1<T>,
781 #[cfg(c_bindings)]
782 secp_ctx: &Secp256k1<secp256k1::All>,
783 ) -> Result<VerifiedInvoiceRequest, ()> {
784 let (offer_id, keys) =
785 $self.contents.inner.offer.verify_using_metadata(&$self.bytes, key, secp_ctx)?;
786 Ok(VerifiedInvoiceRequest {
787 offer_id,
788 #[cfg(not(c_bindings))]
789 inner: $self,
790 #[cfg(c_bindings)]
791 inner: $self.clone(),
792 keys,
793 })
794 }
795
796 pub fn verify_using_recipient_data<
804 #[cfg(not(c_bindings))]
805 T: secp256k1::Signing
806 >(
807 $self: $self_type, nonce: Nonce, key: &ExpandedKey,
808 #[cfg(not(c_bindings))]
809 secp_ctx: &Secp256k1<T>,
810 #[cfg(c_bindings)]
811 secp_ctx: &Secp256k1<secp256k1::All>,
812 ) -> Result<VerifiedInvoiceRequest, ()> {
813 let (offer_id, keys) = $self.contents.inner.offer.verify_using_recipient_data(
814 &$self.bytes, nonce, key, secp_ctx
815 )?;
816 Ok(VerifiedInvoiceRequest {
817 offer_id,
818 #[cfg(not(c_bindings))]
819 inner: $self,
820 #[cfg(c_bindings)]
821 inner: $self.clone(),
822 keys,
823 })
824 }
825} }
826
827#[cfg(not(c_bindings))]
828impl InvoiceRequest {
829 offer_accessors!(self, self.contents.inner.offer);
830 invoice_request_accessors!(self, self.contents);
831 invoice_request_respond_with_explicit_signing_pubkey_methods!(self, self, InvoiceBuilder<ExplicitSigningPubkey>);
832 invoice_request_verify_method!(self, Self);
833
834 #[cfg(async_payments)]
835 pub(super) fn bytes(&self) -> &Vec<u8> {
836 &self.bytes
837 }
838}
839
840#[cfg(c_bindings)]
841impl InvoiceRequest {
842 offer_accessors!(self, self.contents.inner.offer);
843 invoice_request_accessors!(self, self.contents);
844 invoice_request_respond_with_explicit_signing_pubkey_methods!(self, self, InvoiceWithExplicitSigningPubkeyBuilder);
845 invoice_request_verify_method!(self, &Self);
846}
847
848impl InvoiceRequest {
849 pub fn signature(&self) -> Signature {
853 self.signature
854 }
855
856 pub(crate) fn as_tlv_stream(&self) -> FullInvoiceRequestTlvStreamRef {
857 let (
858 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
859 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
860 ) = self.contents.as_tlv_stream();
861 let signature_tlv_stream = SignatureTlvStreamRef {
862 signature: Some(&self.signature),
863 };
864 (
865 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
866 signature_tlv_stream, experimental_offer_tlv_stream,
867 experimental_invoice_request_tlv_stream,
868 )
869 }
870}
871
872macro_rules! invoice_request_respond_with_derived_signing_pubkey_methods { (
873 $self: ident, $contents: expr, $builder: ty
874) => {
875 #[cfg(feature = "std")]
883 pub fn respond_using_derived_keys(
884 &$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash
885 ) -> Result<$builder, Bolt12SemanticError> {
886 let created_at = std::time::SystemTime::now()
887 .duration_since(std::time::SystemTime::UNIX_EPOCH)
888 .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
889
890 $self.respond_using_derived_keys_no_std(payment_paths, payment_hash, created_at)
891 }
892
893 pub fn respond_using_derived_keys_no_std(
901 &$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash,
902 created_at: core::time::Duration
903 ) -> Result<$builder, Bolt12SemanticError> {
904 if $self.inner.invoice_request_features().requires_unknown_bits() {
905 return Err(Bolt12SemanticError::UnknownRequiredFeatures);
906 }
907
908 let keys = match $self.keys {
909 None => return Err(Bolt12SemanticError::InvalidMetadata),
910 Some(keys) => keys,
911 };
912
913 match $contents.contents.inner.offer.issuer_signing_pubkey() {
914 Some(signing_pubkey) => debug_assert_eq!(signing_pubkey, keys.public_key()),
915 None => return Err(Bolt12SemanticError::MissingIssuerSigningPubkey),
916 }
917
918 <$builder>::for_offer_using_keys(
919 &$self.inner, payment_paths, created_at, payment_hash, keys
920 )
921 }
922} }
923
924impl VerifiedInvoiceRequest {
925 offer_accessors!(self, self.inner.contents.inner.offer);
926 invoice_request_accessors!(self, self.inner.contents);
927 #[cfg(not(c_bindings))]
928 invoice_request_respond_with_explicit_signing_pubkey_methods!(self, self.inner, InvoiceBuilder<ExplicitSigningPubkey>);
929 #[cfg(c_bindings)]
930 invoice_request_respond_with_explicit_signing_pubkey_methods!(self, self.inner, InvoiceWithExplicitSigningPubkeyBuilder);
931 #[cfg(not(c_bindings))]
932 invoice_request_respond_with_derived_signing_pubkey_methods!(self, self.inner, InvoiceBuilder<DerivedSigningPubkey>);
933 #[cfg(c_bindings)]
934 invoice_request_respond_with_derived_signing_pubkey_methods!(self, self.inner, InvoiceWithDerivedSigningPubkeyBuilder);
935
936 pub fn fields(&self) -> InvoiceRequestFields {
944 let InvoiceRequestContents {
945 payer_signing_pubkey,
946 inner: InvoiceRequestContentsWithoutPayerSigningPubkey {
947 quantity, payer_note, ..
948 },
949 } = &self.inner.contents;
950
951 InvoiceRequestFields {
952 payer_signing_pubkey: *payer_signing_pubkey,
953 quantity: *quantity,
954 payer_note_truncated: payer_note
955 .clone()
956 .map(|s| UntrustedString(string_truncate_safe(s, PAYER_NOTE_LIMIT))),
959 human_readable_name: self.offer_from_hrn().clone(),
960 }
961 }
962}
963
964fn string_truncate_safe(mut s: String, new_len: usize) -> String {
973 let truncated_len = if new_len >= s.len() {
977 s.len()
978 } else {
979 (0..=new_len).rev().find(|idx| s.is_char_boundary(*idx)).unwrap_or(0)
980 };
981 s.truncate(truncated_len);
982 s
983}
984
985impl InvoiceRequestContents {
986 pub(super) fn metadata(&self) -> &[u8] {
987 self.inner.metadata()
988 }
989
990 pub(super) fn chain(&self) -> ChainHash {
991 self.inner.chain()
992 }
993
994 pub(super) fn amount_msats(&self) -> Option<u64> {
995 self.inner
996 .amount_msats()
997 .or_else(|| match self.inner.offer.amount() {
998 Some(Amount::Bitcoin { amount_msats }) => {
999 Some(amount_msats.saturating_mul(self.quantity().unwrap_or(1)))
1000 },
1001 Some(Amount::Currency { .. }) => None,
1002 None => { debug_assert!(false); None},
1003 })
1004 }
1005
1006 pub(super) fn has_amount_msats(&self) -> bool {
1007 self.inner.amount_msats().is_some()
1008 }
1009
1010 pub(super) fn features(&self) -> &InvoiceRequestFeatures {
1011 &self.inner.features
1012 }
1013
1014 pub(super) fn quantity(&self) -> Option<u64> {
1015 self.inner.quantity
1016 }
1017
1018 pub(super) fn payer_signing_pubkey(&self) -> PublicKey {
1019 self.payer_signing_pubkey
1020 }
1021
1022 pub(super) fn payer_note(&self) -> Option<PrintableString> {
1023 self.inner.payer_note.as_ref()
1024 .map(|payer_note| PrintableString(payer_note.as_str()))
1025 }
1026
1027 pub(super) fn offer_from_hrn(&self) -> &Option<HumanReadableName> {
1028 &self.inner.offer_from_hrn
1029 }
1030
1031 pub(super) fn as_tlv_stream(&self) -> PartialInvoiceRequestTlvStreamRef {
1032 let (payer, offer, mut invoice_request, experimental_offer, experimental_invoice_request) =
1033 self.inner.as_tlv_stream();
1034 invoice_request.payer_id = Some(&self.payer_signing_pubkey);
1035 (payer, offer, invoice_request, experimental_offer, experimental_invoice_request)
1036 }
1037}
1038
1039impl InvoiceRequestContentsWithoutPayerSigningPubkey {
1040 pub(super) fn metadata(&self) -> &[u8] {
1041 self.payer.0.as_bytes().map(|bytes| bytes.as_slice()).unwrap_or(&[])
1042 }
1043
1044 pub(super) fn chain(&self) -> ChainHash {
1045 self.chain.unwrap_or_else(|| self.offer.implied_chain())
1046 }
1047
1048 pub(super) fn amount_msats(&self) -> Option<u64> {
1049 self.amount_msats
1050 }
1051
1052 pub(super) fn as_tlv_stream(&self) -> PartialInvoiceRequestTlvStreamRef {
1053 let payer = PayerTlvStreamRef {
1054 metadata: self.payer.0.as_bytes(),
1055 };
1056
1057 let (offer, experimental_offer) = self.offer.as_tlv_stream();
1058
1059 let features = {
1060 if self.features == InvoiceRequestFeatures::empty() { None }
1061 else { Some(&self.features) }
1062 };
1063
1064 let invoice_request = InvoiceRequestTlvStreamRef {
1065 chain: self.chain.as_ref(),
1066 amount: self.amount_msats,
1067 features,
1068 quantity: self.quantity,
1069 payer_id: None,
1070 payer_note: self.payer_note.as_ref(),
1071 offer_from_hrn: self.offer_from_hrn.as_ref(),
1072 paths: None,
1073 };
1074
1075 let experimental_invoice_request = ExperimentalInvoiceRequestTlvStreamRef {
1076 #[cfg(test)]
1077 experimental_bar: self.experimental_bar,
1078 };
1079
1080 (payer, offer, invoice_request, experimental_offer, experimental_invoice_request)
1081 }
1082}
1083
1084impl Writeable for UnsignedInvoiceRequest {
1085 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1086 WithoutLength(&self.bytes).write(writer)
1087 }
1088}
1089
1090impl Writeable for InvoiceRequest {
1091 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1092 WithoutLength(&self.bytes).write(writer)
1093 }
1094}
1095
1096impl Writeable for InvoiceRequestContents {
1097 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1098 self.as_tlv_stream().write(writer)
1099 }
1100}
1101
1102impl Readable for InvoiceRequest {
1103 fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
1104 let bytes: WithoutLength<Vec<u8>> = Readable::read(reader)?;
1105 Self::try_from(bytes.0).map_err(|_| DecodeError::InvalidValue)
1106 }
1107}
1108
1109pub(super) const INVOICE_REQUEST_TYPES: core::ops::Range<u64> = 80..160;
1111
1112pub(super) const INVOICE_REQUEST_PAYER_ID_TYPE: u64 = 88;
1117
1118tlv_stream!(InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef<'a>, INVOICE_REQUEST_TYPES, {
1121 (80, chain: ChainHash),
1122 (82, amount: (u64, HighZeroBytesDroppedBigSize)),
1123 (84, features: (InvoiceRequestFeatures, WithoutLength)),
1124 (86, quantity: (u64, HighZeroBytesDroppedBigSize)),
1125 (INVOICE_REQUEST_PAYER_ID_TYPE, payer_id: PublicKey),
1126 (89, payer_note: (String, WithoutLength)),
1127 (90, paths: (Vec<BlindedMessagePath>, WithoutLength)),
1129 (91, offer_from_hrn: HumanReadableName),
1130});
1131
1132pub(super) const EXPERIMENTAL_INVOICE_REQUEST_TYPES: core::ops::Range<u64> =
1134 2_000_000_000..3_000_000_000;
1135
1136#[cfg(not(test))]
1137tlv_stream!(
1138 ExperimentalInvoiceRequestTlvStream, ExperimentalInvoiceRequestTlvStreamRef,
1139 EXPERIMENTAL_INVOICE_REQUEST_TYPES, {
1140 }
1143);
1144
1145#[cfg(test)]
1146tlv_stream!(
1147 ExperimentalInvoiceRequestTlvStream, ExperimentalInvoiceRequestTlvStreamRef,
1148 EXPERIMENTAL_INVOICE_REQUEST_TYPES, {
1149 (2_999_999_999, experimental_bar: (u64, HighZeroBytesDroppedBigSize)),
1150 }
1151);
1152
1153type FullInvoiceRequestTlvStream = (
1154 PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, SignatureTlvStream,
1155 ExperimentalOfferTlvStream, ExperimentalInvoiceRequestTlvStream,
1156);
1157
1158type FullInvoiceRequestTlvStreamRef<'a> = (
1159 PayerTlvStreamRef<'a>,
1160 OfferTlvStreamRef<'a>,
1161 InvoiceRequestTlvStreamRef<'a>,
1162 SignatureTlvStreamRef<'a>,
1163 ExperimentalOfferTlvStreamRef,
1164 ExperimentalInvoiceRequestTlvStreamRef,
1165);
1166
1167impl CursorReadable for FullInvoiceRequestTlvStream {
1168 fn read<R: AsRef<[u8]>>(r: &mut io::Cursor<R>) -> Result<Self, DecodeError> {
1169 let payer = CursorReadable::read(r)?;
1170 let offer = CursorReadable::read(r)?;
1171 let invoice_request = CursorReadable::read(r)?;
1172 let signature = CursorReadable::read(r)?;
1173 let experimental_offer = CursorReadable::read(r)?;
1174 let experimental_invoice_request = CursorReadable::read(r)?;
1175
1176 Ok(
1177 (
1178 payer, offer, invoice_request, signature, experimental_offer,
1179 experimental_invoice_request,
1180 )
1181 )
1182 }
1183}
1184
1185type PartialInvoiceRequestTlvStream = (
1186 PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, ExperimentalOfferTlvStream,
1187 ExperimentalInvoiceRequestTlvStream,
1188);
1189
1190type PartialInvoiceRequestTlvStreamRef<'a> = (
1191 PayerTlvStreamRef<'a>,
1192 OfferTlvStreamRef<'a>,
1193 InvoiceRequestTlvStreamRef<'a>,
1194 ExperimentalOfferTlvStreamRef,
1195 ExperimentalInvoiceRequestTlvStreamRef,
1196);
1197
1198impl TryFrom<Vec<u8>> for UnsignedInvoiceRequest {
1199 type Error = Bolt12ParseError;
1200
1201 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1202 let invoice_request = ParsedMessage::<PartialInvoiceRequestTlvStream>::try_from(bytes)?;
1203 let ParsedMessage { mut bytes, tlv_stream } = invoice_request;
1204
1205 let contents = InvoiceRequestContents::try_from(tlv_stream)?;
1206 let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
1207
1208 let offset = TlvStream::new(&bytes)
1209 .range(0..INVOICE_REQUEST_TYPES.end)
1210 .last()
1211 .map_or(0, |last_record| last_record.end);
1212 let experimental_bytes = bytes.split_off(offset);
1213
1214 Ok(UnsignedInvoiceRequest { bytes, experimental_bytes, contents, tagged_hash })
1215 }
1216}
1217
1218impl TryFrom<Vec<u8>> for InvoiceRequest {
1219 type Error = Bolt12ParseError;
1220
1221 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
1222 let invoice_request = ParsedMessage::<FullInvoiceRequestTlvStream>::try_from(bytes)?;
1223 let ParsedMessage { bytes, tlv_stream } = invoice_request;
1224 let (
1225 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
1226 SignatureTlvStream { signature },
1227 experimental_offer_tlv_stream,
1228 experimental_invoice_request_tlv_stream,
1229 ) = tlv_stream;
1230 let contents = InvoiceRequestContents::try_from(
1231 (
1232 payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream,
1233 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
1234 )
1235 )?;
1236
1237 let signature = match signature {
1238 None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
1239 Some(signature) => signature,
1240 };
1241 let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
1242 merkle::verify_signature(&signature, &message, contents.payer_signing_pubkey)?;
1243
1244 Ok(InvoiceRequest { bytes, contents, signature })
1245 }
1246}
1247
1248impl TryFrom<PartialInvoiceRequestTlvStream> for InvoiceRequestContents {
1249 type Error = Bolt12SemanticError;
1250
1251 fn try_from(tlv_stream: PartialInvoiceRequestTlvStream) -> Result<Self, Self::Error> {
1252 let (
1253 PayerTlvStream { metadata },
1254 offer_tlv_stream,
1255 InvoiceRequestTlvStream {
1256 chain, amount, features, quantity, payer_id, payer_note, paths,
1257 offer_from_hrn,
1258 },
1259 experimental_offer_tlv_stream,
1260 ExperimentalInvoiceRequestTlvStream {
1261 #[cfg(test)]
1262 experimental_bar,
1263 },
1264 ) = tlv_stream;
1265
1266 let payer = match metadata {
1267 None => return Err(Bolt12SemanticError::MissingPayerMetadata),
1268 Some(metadata) => PayerContents(Metadata::Bytes(metadata)),
1269 };
1270 let offer = OfferContents::try_from((offer_tlv_stream, experimental_offer_tlv_stream))?;
1271
1272 if !offer.supports_chain(chain.unwrap_or_else(|| offer.implied_chain())) {
1273 return Err(Bolt12SemanticError::UnsupportedChain);
1274 }
1275
1276 if offer.amount().is_none() && amount.is_none() {
1277 return Err(Bolt12SemanticError::MissingAmount);
1278 }
1279
1280 offer.check_quantity(quantity)?;
1281 offer.check_amount_msats_for_quantity(amount, quantity)?;
1282
1283 let features = features.unwrap_or_else(InvoiceRequestFeatures::empty);
1284
1285 let payer_signing_pubkey = match payer_id {
1286 None => return Err(Bolt12SemanticError::MissingPayerSigningPubkey),
1287 Some(payer_id) => payer_id,
1288 };
1289
1290 if paths.is_some() {
1291 return Err(Bolt12SemanticError::UnexpectedPaths);
1292 }
1293
1294 Ok(InvoiceRequestContents {
1295 inner: InvoiceRequestContentsWithoutPayerSigningPubkey {
1296 payer, offer, chain, amount_msats: amount, features, quantity, payer_note,
1297 offer_from_hrn,
1298 #[cfg(test)]
1299 experimental_bar,
1300 },
1301 payer_signing_pubkey,
1302 })
1303 }
1304}
1305
1306#[derive(Clone, Debug, Eq, PartialEq)]
1310pub struct InvoiceRequestFields {
1311 pub payer_signing_pubkey: PublicKey,
1313
1314 pub quantity: Option<u64>,
1316
1317 pub payer_note_truncated: Option<UntrustedString>,
1320
1321 pub human_readable_name: Option<HumanReadableName>,
1323}
1324
1325#[cfg(not(fuzzing))]
1327pub const PAYER_NOTE_LIMIT: usize = 512;
1328
1329#[cfg(fuzzing)]
1331pub const PAYER_NOTE_LIMIT: usize = 8;
1332
1333impl Writeable for InvoiceRequestFields {
1334 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1335 write_tlv_fields!(writer, {
1336 (0, self.payer_signing_pubkey, required),
1337 (1, self.human_readable_name, option),
1338 (2, self.quantity.map(|v| HighZeroBytesDroppedBigSize(v)), option),
1339 (4, self.payer_note_truncated.as_ref().map(|s| WithoutLength(&s.0)), option),
1340 });
1341 Ok(())
1342 }
1343}
1344
1345impl Readable for InvoiceRequestFields {
1346 fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
1347 _init_and_read_len_prefixed_tlv_fields!(reader, {
1348 (0, payer_signing_pubkey, required),
1349 (1, human_readable_name, option),
1350 (2, quantity, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
1351 (4, payer_note_truncated, (option, encoding: (String, WithoutLength))),
1352 });
1353
1354 Ok(InvoiceRequestFields {
1355 payer_signing_pubkey: payer_signing_pubkey.0.unwrap(),
1356 quantity,
1357 payer_note_truncated: payer_note_truncated.map(|s| UntrustedString(s)),
1358 human_readable_name,
1359 })
1360 }
1361}
1362
1363#[cfg(test)]
1364mod tests {
1365 use super::{EXPERIMENTAL_INVOICE_REQUEST_TYPES, ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, InvoiceRequest, InvoiceRequestFields, InvoiceRequestTlvStreamRef, PAYER_NOTE_LIMIT, SIGNATURE_TAG, UnsignedInvoiceRequest};
1366
1367 use bitcoin::constants::ChainHash;
1368 use bitcoin::network::Network;
1369 use bitcoin::secp256k1::{Keypair, Secp256k1, SecretKey, self};
1370 use core::num::NonZeroU64;
1371 #[cfg(feature = "std")]
1372 use core::time::Duration;
1373 use crate::ln::channelmanager::PaymentId;
1374 use crate::types::features::{InvoiceRequestFeatures, OfferFeatures};
1375 use crate::ln::inbound_payment::ExpandedKey;
1376 use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
1377 use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG};
1378 use crate::offers::invoice_request::string_truncate_safe;
1379 use crate::offers::merkle::{self, SignatureTlvStreamRef, TaggedHash, TlvStream};
1380 use crate::offers::nonce::Nonce;
1381 use crate::offers::offer::{Amount, ExperimentalOfferTlvStreamRef, OfferTlvStreamRef, Quantity};
1382 #[cfg(not(c_bindings))]
1383 use {
1384 crate::offers::offer::OfferBuilder,
1385 };
1386 #[cfg(c_bindings)]
1387 use {
1388 crate::offers::offer::OfferWithExplicitMetadataBuilder as OfferBuilder,
1389 };
1390 use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
1391 use crate::offers::payer::PayerTlvStreamRef;
1392 use crate::offers::test_utils::*;
1393 use crate::util::ser::{BigSize, Readable, Writeable};
1394 use crate::util::string::{PrintableString, UntrustedString};
1395
1396 #[test]
1397 fn builds_invoice_request_with_defaults() {
1398 let expanded_key = ExpandedKey::new([42; 32]);
1399 let entropy = FixedEntropy {};
1400 let nonce = Nonce::from_entropy_source(&entropy);
1401 let secp_ctx = Secp256k1::new();
1402 let payment_id = PaymentId([1; 32]);
1403 let encrypted_payment_id = expanded_key.crypt_for_offer(payment_id.0, nonce);
1404
1405 let invoice_request = OfferBuilder::new(recipient_pubkey())
1406 .amount_msats(1000)
1407 .build().unwrap()
1408 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1409 .build_and_sign().unwrap();
1410
1411 let mut buffer = Vec::new();
1412 invoice_request.write(&mut buffer).unwrap();
1413
1414 assert_eq!(invoice_request.bytes, buffer.as_slice());
1415 assert_eq!(invoice_request.payer_metadata(), &encrypted_payment_id);
1416 assert_eq!(invoice_request.chains(), vec![ChainHash::using_genesis_block(Network::Bitcoin)]);
1417 assert_eq!(invoice_request.metadata(), None);
1418 assert_eq!(invoice_request.amount(), Some(Amount::Bitcoin { amount_msats: 1000 }));
1419 assert_eq!(invoice_request.description(), Some(PrintableString("")));
1420 assert_eq!(invoice_request.offer_features(), &OfferFeatures::empty());
1421 assert_eq!(invoice_request.absolute_expiry(), None);
1422 assert_eq!(invoice_request.paths(), &[]);
1423 assert_eq!(invoice_request.issuer(), None);
1424 assert_eq!(invoice_request.supported_quantity(), Quantity::One);
1425 assert_eq!(invoice_request.issuer_signing_pubkey(), Some(recipient_pubkey()));
1426 assert_eq!(invoice_request.chain(), ChainHash::using_genesis_block(Network::Bitcoin));
1427 assert_eq!(invoice_request.amount_msats(), Some(1000));
1428 assert_eq!(invoice_request.invoice_request_features(), &InvoiceRequestFeatures::empty());
1429 assert_eq!(invoice_request.quantity(), None);
1430 assert_eq!(invoice_request.payer_note(), None);
1431
1432 let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice_request.bytes);
1433 assert!(
1434 merkle::verify_signature(
1435 &invoice_request.signature, &message, invoice_request.payer_signing_pubkey(),
1436 ).is_ok()
1437 );
1438
1439 assert_eq!(
1440 invoice_request.as_tlv_stream(),
1441 (
1442 PayerTlvStreamRef { metadata: Some(&encrypted_payment_id.to_vec()) },
1443 OfferTlvStreamRef {
1444 chains: None,
1445 metadata: None,
1446 currency: None,
1447 amount: Some(1000),
1448 description: Some(&String::from("")),
1449 features: None,
1450 absolute_expiry: None,
1451 paths: None,
1452 issuer: None,
1453 quantity_max: None,
1454 issuer_id: Some(&recipient_pubkey()),
1455 },
1456 InvoiceRequestTlvStreamRef {
1457 chain: None,
1458 amount: None,
1459 features: None,
1460 quantity: None,
1461 payer_id: Some(&invoice_request.payer_signing_pubkey()),
1462 payer_note: None,
1463 paths: None,
1464 offer_from_hrn: None,
1465 },
1466 SignatureTlvStreamRef { signature: Some(&invoice_request.signature()) },
1467 ExperimentalOfferTlvStreamRef {
1468 experimental_foo: None,
1469 },
1470 ExperimentalInvoiceRequestTlvStreamRef {
1471 experimental_bar: None,
1472 },
1473 ),
1474 );
1475
1476 if let Err(e) = InvoiceRequest::try_from(buffer) {
1477 panic!("error parsing invoice request: {:?}", e);
1478 }
1479 }
1480
1481 #[cfg(feature = "std")]
1482 #[test]
1483 fn builds_invoice_request_from_offer_with_expiration() {
1484 let expanded_key = ExpandedKey::new([42; 32]);
1485 let entropy = FixedEntropy {};
1486 let nonce = Nonce::from_entropy_source(&entropy);
1487 let secp_ctx = Secp256k1::new();
1488 let payment_id = PaymentId([1; 32]);
1489
1490 let future_expiry = Duration::from_secs(u64::max_value());
1491 let past_expiry = Duration::from_secs(0);
1492
1493 if let Err(e) = OfferBuilder::new(recipient_pubkey())
1494 .amount_msats(1000)
1495 .absolute_expiry(future_expiry)
1496 .build().unwrap()
1497 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1498 .build_and_sign()
1499 {
1500 panic!("error building invoice_request: {:?}", e);
1501 }
1502
1503 match OfferBuilder::new(recipient_pubkey())
1504 .amount_msats(1000)
1505 .absolute_expiry(past_expiry)
1506 .build().unwrap()
1507 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1508 .build_and_sign()
1509 {
1510 Ok(_) => panic!("expected error"),
1511 Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
1512 }
1513 }
1514
1515 #[test]
1516 fn builds_invoice_request_with_derived_payer_signing_pubkey() {
1517 let expanded_key = ExpandedKey::new([42; 32]);
1518 let entropy = FixedEntropy {};
1519 let nonce = Nonce::from_entropy_source(&entropy);
1520 let secp_ctx = Secp256k1::new();
1521 let payment_id = PaymentId([1; 32]);
1522
1523 let offer = OfferBuilder::new(recipient_pubkey())
1524 .amount_msats(1000)
1525 .experimental_foo(42)
1526 .build().unwrap();
1527 let invoice_request = offer
1528 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1529 .experimental_bar(42)
1530 .build_and_sign()
1531 .unwrap();
1532
1533 let invoice = invoice_request.respond_with_no_std(payment_paths(), payment_hash(), now())
1534 .unwrap()
1535 .experimental_baz(42)
1536 .build().unwrap()
1537 .sign(recipient_sign).unwrap();
1538 assert!(invoice.verify_using_metadata(&expanded_key, &secp_ctx).is_err());
1539 assert!(
1540 invoice.verify_using_payer_data(payment_id, nonce, &expanded_key, &secp_ctx).is_ok()
1541 );
1542
1543 let (
1545 payer_tlv_stream, offer_tlv_stream, mut invoice_request_tlv_stream,
1546 mut invoice_tlv_stream, mut signature_tlv_stream, experimental_offer_tlv_stream,
1547 experimental_invoice_request_tlv_stream, experimental_invoice_tlv_stream,
1548 ) = invoice.as_tlv_stream();
1549 invoice_request_tlv_stream.amount = Some(2000);
1550 invoice_tlv_stream.amount = Some(2000);
1551
1552 let tlv_stream =
1553 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream);
1554 let experimental_tlv_stream = (
1555 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
1556 experimental_invoice_tlv_stream,
1557 );
1558 let mut bytes = Vec::new();
1559 (&tlv_stream, &experimental_tlv_stream).write(&mut bytes).unwrap();
1560
1561 let message = TaggedHash::from_valid_tlv_stream_bytes(INVOICE_SIGNATURE_TAG, &bytes);
1562 let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
1563 signature_tlv_stream.signature = Some(&signature);
1564
1565 let mut encoded_invoice = Vec::new();
1566 (tlv_stream, signature_tlv_stream, experimental_tlv_stream)
1567 .write(&mut encoded_invoice)
1568 .unwrap();
1569
1570 let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap();
1571 assert!(
1572 invoice.verify_using_payer_data(payment_id, nonce, &expanded_key, &secp_ctx).is_err()
1573 );
1574
1575 let (
1577 payer_tlv_stream, offer_tlv_stream, mut invoice_request_tlv_stream, invoice_tlv_stream,
1578 mut signature_tlv_stream, experimental_offer_tlv_stream,
1579 experimental_invoice_request_tlv_stream, experimental_invoice_tlv_stream,
1580 ) = invoice.as_tlv_stream();
1581 let payer_id = pubkey(1);
1582 invoice_request_tlv_stream.payer_id = Some(&payer_id);
1583
1584 let tlv_stream =
1585 (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream);
1586 let experimental_tlv_stream = (
1587 experimental_offer_tlv_stream, experimental_invoice_request_tlv_stream,
1588 experimental_invoice_tlv_stream,
1589 );
1590 let mut bytes = Vec::new();
1591 (&tlv_stream, &experimental_tlv_stream).write(&mut bytes).unwrap();
1592
1593 let message = TaggedHash::from_valid_tlv_stream_bytes(INVOICE_SIGNATURE_TAG, &bytes);
1594 let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
1595 signature_tlv_stream.signature = Some(&signature);
1596
1597 let mut encoded_invoice = Vec::new();
1598 (tlv_stream, signature_tlv_stream, experimental_tlv_stream)
1599 .write(&mut encoded_invoice)
1600 .unwrap();
1601
1602 let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap();
1603 assert!(
1604 invoice.verify_using_payer_data(payment_id, nonce, &expanded_key, &secp_ctx).is_err()
1605 );
1606 }
1607
1608 #[test]
1609 fn builds_invoice_request_with_chain() {
1610 let expanded_key = ExpandedKey::new([42; 32]);
1611 let entropy = FixedEntropy {};
1612 let nonce = Nonce::from_entropy_source(&entropy);
1613 let secp_ctx = Secp256k1::new();
1614 let payment_id = PaymentId([1; 32]);
1615
1616 let mainnet = ChainHash::using_genesis_block(Network::Bitcoin);
1617 let testnet = ChainHash::using_genesis_block(Network::Testnet);
1618
1619 let invoice_request = OfferBuilder::new(recipient_pubkey())
1620 .amount_msats(1000)
1621 .build().unwrap()
1622 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1623 .chain(Network::Bitcoin).unwrap()
1624 .build_and_sign().unwrap();
1625 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1626 assert_eq!(invoice_request.chain(), mainnet);
1627 assert_eq!(tlv_stream.chain, None);
1628
1629 let invoice_request = OfferBuilder::new(recipient_pubkey())
1630 .amount_msats(1000)
1631 .chain(Network::Testnet)
1632 .build().unwrap()
1633 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1634 .chain(Network::Testnet).unwrap()
1635 .build_and_sign().unwrap();
1636 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1637 assert_eq!(invoice_request.chain(), testnet);
1638 assert_eq!(tlv_stream.chain, Some(&testnet));
1639
1640 let invoice_request = OfferBuilder::new(recipient_pubkey())
1641 .amount_msats(1000)
1642 .chain(Network::Bitcoin)
1643 .chain(Network::Testnet)
1644 .build().unwrap()
1645 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1646 .chain(Network::Bitcoin).unwrap()
1647 .build_and_sign().unwrap();
1648 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1649 assert_eq!(invoice_request.chain(), mainnet);
1650 assert_eq!(tlv_stream.chain, None);
1651
1652 let invoice_request = OfferBuilder::new(recipient_pubkey())
1653 .amount_msats(1000)
1654 .chain(Network::Bitcoin)
1655 .chain(Network::Testnet)
1656 .build().unwrap()
1657 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1658 .chain(Network::Bitcoin).unwrap()
1659 .chain(Network::Testnet).unwrap()
1660 .build_and_sign().unwrap();
1661 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1662 assert_eq!(invoice_request.chain(), testnet);
1663 assert_eq!(tlv_stream.chain, Some(&testnet));
1664
1665 match OfferBuilder::new(recipient_pubkey())
1666 .amount_msats(1000)
1667 .chain(Network::Testnet)
1668 .build().unwrap()
1669 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1670 .chain(Network::Bitcoin)
1671 {
1672 Ok(_) => panic!("expected error"),
1673 Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
1674 }
1675
1676 match OfferBuilder::new(recipient_pubkey())
1677 .amount_msats(1000)
1678 .chain(Network::Testnet)
1679 .build().unwrap()
1680 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1681 .build_and_sign()
1682 {
1683 Ok(_) => panic!("expected error"),
1684 Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain),
1685 }
1686 }
1687
1688 #[test]
1689 fn builds_invoice_request_with_amount() {
1690 let expanded_key = ExpandedKey::new([42; 32]);
1691 let entropy = FixedEntropy {};
1692 let nonce = Nonce::from_entropy_source(&entropy);
1693 let secp_ctx = Secp256k1::new();
1694 let payment_id = PaymentId([1; 32]);
1695
1696 let invoice_request = OfferBuilder::new(recipient_pubkey())
1697 .amount_msats(1000)
1698 .build().unwrap()
1699 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1700 .amount_msats(1000).unwrap()
1701 .build_and_sign().unwrap();
1702 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1703 assert!(invoice_request.has_amount_msats());
1704 assert_eq!(invoice_request.amount_msats(), Some(1000));
1705 assert_eq!(tlv_stream.amount, Some(1000));
1706
1707 let invoice_request = OfferBuilder::new(recipient_pubkey())
1708 .amount_msats(1000)
1709 .build().unwrap()
1710 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1711 .amount_msats(1001).unwrap()
1712 .amount_msats(1000).unwrap()
1713 .build_and_sign().unwrap();
1714 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1715 assert!(invoice_request.has_amount_msats());
1716 assert_eq!(invoice_request.amount_msats(), Some(1000));
1717 assert_eq!(tlv_stream.amount, Some(1000));
1718
1719 let invoice_request = OfferBuilder::new(recipient_pubkey())
1720 .amount_msats(1000)
1721 .build().unwrap()
1722 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1723 .amount_msats(1001).unwrap()
1724 .build_and_sign().unwrap();
1725 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1726 assert!(invoice_request.has_amount_msats());
1727 assert_eq!(invoice_request.amount_msats(), Some(1001));
1728 assert_eq!(tlv_stream.amount, Some(1001));
1729
1730 match OfferBuilder::new(recipient_pubkey())
1731 .amount_msats(1000)
1732 .build().unwrap()
1733 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1734 .amount_msats(999)
1735 {
1736 Ok(_) => panic!("expected error"),
1737 Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount),
1738 }
1739
1740 match OfferBuilder::new(recipient_pubkey())
1741 .amount_msats(1000)
1742 .supported_quantity(Quantity::Unbounded)
1743 .build().unwrap()
1744 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1745 .quantity(2).unwrap()
1746 .amount_msats(1000)
1747 {
1748 Ok(_) => panic!("expected error"),
1749 Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount),
1750 }
1751
1752 match OfferBuilder::new(recipient_pubkey())
1753 .amount_msats(1000)
1754 .build().unwrap()
1755 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1756 .amount_msats(MAX_VALUE_MSAT + 1)
1757 {
1758 Ok(_) => panic!("expected error"),
1759 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
1760 }
1761
1762 match OfferBuilder::new(recipient_pubkey())
1763 .amount_msats(1000)
1764 .supported_quantity(Quantity::Unbounded)
1765 .build().unwrap()
1766 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1767 .amount_msats(1000).unwrap()
1768 .quantity(2).unwrap()
1769 .build_and_sign()
1770 {
1771 Ok(_) => panic!("expected error"),
1772 Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount),
1773 }
1774
1775 match OfferBuilder::new(recipient_pubkey())
1776 .build().unwrap()
1777 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1778 .build_and_sign()
1779 {
1780 Ok(_) => panic!("expected error"),
1781 Err(e) => assert_eq!(e, Bolt12SemanticError::MissingAmount),
1782 }
1783
1784 match OfferBuilder::new(recipient_pubkey())
1785 .amount_msats(1000)
1786 .supported_quantity(Quantity::Unbounded)
1787 .build().unwrap()
1788 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1789 .quantity(u64::max_value()).unwrap()
1790 .build_and_sign()
1791 {
1792 Ok(_) => panic!("expected error"),
1793 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
1794 }
1795 }
1796
1797 #[test]
1798 fn builds_invoice_request_without_amount() {
1799 let expanded_key = ExpandedKey::new([42; 32]);
1800 let entropy = FixedEntropy {};
1801 let nonce = Nonce::from_entropy_source(&entropy);
1802 let secp_ctx = Secp256k1::new();
1803 let payment_id = PaymentId([1; 32]);
1804
1805 let invoice_request = OfferBuilder::new(recipient_pubkey())
1806 .amount_msats(1000)
1807 .build().unwrap()
1808 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1809 .build_and_sign().unwrap();
1810 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1811 assert!(!invoice_request.has_amount_msats());
1812 assert_eq!(invoice_request.amount_msats(), Some(1000));
1813 assert_eq!(tlv_stream.amount, None);
1814
1815 let invoice_request = OfferBuilder::new(recipient_pubkey())
1816 .amount_msats(1000)
1817 .supported_quantity(Quantity::Unbounded)
1818 .build().unwrap()
1819 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1820 .quantity(2).unwrap()
1821 .build_and_sign().unwrap();
1822 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1823 assert!(!invoice_request.has_amount_msats());
1824 assert_eq!(invoice_request.amount_msats(), Some(2000));
1825 assert_eq!(tlv_stream.amount, None);
1826
1827 let invoice_request = OfferBuilder::new(recipient_pubkey())
1828 .amount(Amount::Currency { iso4217_code: *b"USD", amount: 10 })
1829 .build_unchecked()
1830 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1831 .build_unchecked_and_sign();
1832 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1833 assert!(!invoice_request.has_amount_msats());
1834 assert_eq!(invoice_request.amount_msats(), None);
1835 assert_eq!(tlv_stream.amount, None);
1836 }
1837
1838 #[test]
1839 fn builds_invoice_request_with_features() {
1840 let expanded_key = ExpandedKey::new([42; 32]);
1841 let entropy = FixedEntropy {};
1842 let nonce = Nonce::from_entropy_source(&entropy);
1843 let secp_ctx = Secp256k1::new();
1844 let payment_id = PaymentId([1; 32]);
1845
1846 let invoice_request = OfferBuilder::new(recipient_pubkey())
1847 .amount_msats(1000)
1848 .build().unwrap()
1849 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1850 .features_unchecked(InvoiceRequestFeatures::unknown())
1851 .build_and_sign().unwrap();
1852 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1853 assert_eq!(invoice_request.invoice_request_features(), &InvoiceRequestFeatures::unknown());
1854 assert_eq!(tlv_stream.features, Some(&InvoiceRequestFeatures::unknown()));
1855
1856 let invoice_request = OfferBuilder::new(recipient_pubkey())
1857 .amount_msats(1000)
1858 .build().unwrap()
1859 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1860 .features_unchecked(InvoiceRequestFeatures::unknown())
1861 .features_unchecked(InvoiceRequestFeatures::empty())
1862 .build_and_sign().unwrap();
1863 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1864 assert_eq!(invoice_request.invoice_request_features(), &InvoiceRequestFeatures::empty());
1865 assert_eq!(tlv_stream.features, None);
1866 }
1867
1868 #[test]
1869 fn builds_invoice_request_with_quantity() {
1870 let expanded_key = ExpandedKey::new([42; 32]);
1871 let entropy = FixedEntropy {};
1872 let nonce = Nonce::from_entropy_source(&entropy);
1873 let secp_ctx = Secp256k1::new();
1874 let payment_id = PaymentId([1; 32]);
1875
1876 let one = NonZeroU64::new(1).unwrap();
1877 let ten = NonZeroU64::new(10).unwrap();
1878
1879 let invoice_request = OfferBuilder::new(recipient_pubkey())
1880 .amount_msats(1000)
1881 .supported_quantity(Quantity::One)
1882 .build().unwrap()
1883 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1884 .build_and_sign().unwrap();
1885 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1886 assert_eq!(invoice_request.quantity(), None);
1887 assert_eq!(tlv_stream.quantity, None);
1888
1889 match OfferBuilder::new(recipient_pubkey())
1890 .amount_msats(1000)
1891 .supported_quantity(Quantity::One)
1892 .build().unwrap()
1893 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1894 .amount_msats(2_000).unwrap()
1895 .quantity(2)
1896 {
1897 Ok(_) => panic!("expected error"),
1898 Err(e) => assert_eq!(e, Bolt12SemanticError::UnexpectedQuantity),
1899 }
1900
1901 let invoice_request = OfferBuilder::new(recipient_pubkey())
1902 .amount_msats(1000)
1903 .supported_quantity(Quantity::Bounded(ten))
1904 .build().unwrap()
1905 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1906 .amount_msats(10_000).unwrap()
1907 .quantity(10).unwrap()
1908 .build_and_sign().unwrap();
1909 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1910 assert_eq!(invoice_request.amount_msats(), Some(10_000));
1911 assert_eq!(tlv_stream.amount, Some(10_000));
1912
1913 match OfferBuilder::new(recipient_pubkey())
1914 .amount_msats(1000)
1915 .supported_quantity(Quantity::Bounded(ten))
1916 .build().unwrap()
1917 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1918 .amount_msats(11_000).unwrap()
1919 .quantity(11)
1920 {
1921 Ok(_) => panic!("expected error"),
1922 Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidQuantity),
1923 }
1924
1925 let invoice_request = OfferBuilder::new(recipient_pubkey())
1926 .amount_msats(1000)
1927 .supported_quantity(Quantity::Unbounded)
1928 .build().unwrap()
1929 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1930 .amount_msats(2_000).unwrap()
1931 .quantity(2).unwrap()
1932 .build_and_sign().unwrap();
1933 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1934 assert_eq!(invoice_request.amount_msats(), Some(2_000));
1935 assert_eq!(tlv_stream.amount, Some(2_000));
1936
1937 match OfferBuilder::new(recipient_pubkey())
1938 .amount_msats(1000)
1939 .supported_quantity(Quantity::Unbounded)
1940 .build().unwrap()
1941 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1942 .build_and_sign()
1943 {
1944 Ok(_) => panic!("expected error"),
1945 Err(e) => assert_eq!(e, Bolt12SemanticError::MissingQuantity),
1946 }
1947
1948 match OfferBuilder::new(recipient_pubkey())
1949 .amount_msats(1000)
1950 .supported_quantity(Quantity::Bounded(one))
1951 .build().unwrap()
1952 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1953 .build_and_sign()
1954 {
1955 Ok(_) => panic!("expected error"),
1956 Err(e) => assert_eq!(e, Bolt12SemanticError::MissingQuantity),
1957 }
1958 }
1959
1960 #[test]
1961 fn builds_invoice_request_with_payer_note() {
1962 let expanded_key = ExpandedKey::new([42; 32]);
1963 let entropy = FixedEntropy {};
1964 let nonce = Nonce::from_entropy_source(&entropy);
1965 let secp_ctx = Secp256k1::new();
1966 let payment_id = PaymentId([1; 32]);
1967
1968 let invoice_request = OfferBuilder::new(recipient_pubkey())
1969 .amount_msats(1000)
1970 .build().unwrap()
1971 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1972 .payer_note("bar".into())
1973 .build_and_sign().unwrap();
1974 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1975 assert_eq!(invoice_request.payer_note(), Some(PrintableString("bar")));
1976 assert_eq!(tlv_stream.payer_note, Some(&String::from("bar")));
1977
1978 let invoice_request = OfferBuilder::new(recipient_pubkey())
1979 .amount_msats(1000)
1980 .build().unwrap()
1981 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
1982 .payer_note("bar".into())
1983 .payer_note("baz".into())
1984 .build_and_sign().unwrap();
1985 let (_, _, tlv_stream, _, _, _) = invoice_request.as_tlv_stream();
1986 assert_eq!(invoice_request.payer_note(), Some(PrintableString("baz")));
1987 assert_eq!(tlv_stream.payer_note, Some(&String::from("baz")));
1988 }
1989
1990 #[test]
1991 fn fails_responding_with_unknown_required_features() {
1992 let expanded_key = ExpandedKey::new([42; 32]);
1993 let entropy = FixedEntropy {};
1994 let nonce = Nonce::from_entropy_source(&entropy);
1995 let secp_ctx = Secp256k1::new();
1996 let payment_id = PaymentId([1; 32]);
1997
1998 match OfferBuilder::new(recipient_pubkey())
1999 .amount_msats(1000)
2000 .build().unwrap()
2001 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2002 .features_unchecked(InvoiceRequestFeatures::unknown())
2003 .build_and_sign().unwrap()
2004 .respond_with_no_std(payment_paths(), payment_hash(), now())
2005 {
2006 Ok(_) => panic!("expected error"),
2007 Err(e) => assert_eq!(e, Bolt12SemanticError::UnknownRequiredFeatures),
2008 }
2009 }
2010
2011 #[test]
2012 fn parses_invoice_request_with_metadata() {
2013 let expanded_key = ExpandedKey::new([42; 32]);
2014 let entropy = FixedEntropy {};
2015 let nonce = Nonce::from_entropy_source(&entropy);
2016 let secp_ctx = Secp256k1::new();
2017 let payment_id = PaymentId([1; 32]);
2018
2019 let invoice_request = OfferBuilder::new(recipient_pubkey())
2020 .amount_msats(1000)
2021 .build().unwrap()
2022 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2023 .build_and_sign().unwrap();
2024
2025 let mut buffer = Vec::new();
2026 invoice_request.write(&mut buffer).unwrap();
2027
2028 if let Err(e) = InvoiceRequest::try_from(buffer) {
2029 panic!("error parsing invoice_request: {:?}", e);
2030 }
2031 }
2032
2033 #[test]
2034 fn parses_invoice_request_with_chain() {
2035 let expanded_key = ExpandedKey::new([42; 32]);
2036 let entropy = FixedEntropy {};
2037 let nonce = Nonce::from_entropy_source(&entropy);
2038 let secp_ctx = Secp256k1::new();
2039 let payment_id = PaymentId([1; 32]);
2040
2041 let invoice_request = OfferBuilder::new(recipient_pubkey())
2042 .amount_msats(1000)
2043 .build().unwrap()
2044 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2045 .chain(Network::Bitcoin).unwrap()
2046 .build_and_sign().unwrap();
2047
2048 let mut buffer = Vec::new();
2049 invoice_request.write(&mut buffer).unwrap();
2050
2051 if let Err(e) = InvoiceRequest::try_from(buffer) {
2052 panic!("error parsing invoice_request: {:?}", e);
2053 }
2054
2055 let invoice_request = OfferBuilder::new(recipient_pubkey())
2056 .amount_msats(1000)
2057 .build().unwrap()
2058 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2059 .chain_unchecked(Network::Testnet)
2060 .build_unchecked_and_sign();
2061
2062 let mut buffer = Vec::new();
2063 invoice_request.write(&mut buffer).unwrap();
2064
2065 match InvoiceRequest::try_from(buffer) {
2066 Ok(_) => panic!("expected error"),
2067 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)),
2068 }
2069 }
2070
2071 #[test]
2072 fn parses_invoice_request_with_amount() {
2073 let expanded_key = ExpandedKey::new([42; 32]);
2074 let entropy = FixedEntropy {};
2075 let nonce = Nonce::from_entropy_source(&entropy);
2076 let secp_ctx = Secp256k1::new();
2077 let payment_id = PaymentId([1; 32]);
2078
2079 let invoice_request = OfferBuilder::new(recipient_pubkey())
2080 .amount_msats(1000)
2081 .build().unwrap()
2082 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2083 .build_and_sign().unwrap();
2084
2085 let mut buffer = Vec::new();
2086 invoice_request.write(&mut buffer).unwrap();
2087
2088 if let Err(e) = InvoiceRequest::try_from(buffer) {
2089 panic!("error parsing invoice_request: {:?}", e);
2090 }
2091
2092 let invoice_request = OfferBuilder::new(recipient_pubkey())
2093 .build().unwrap()
2094 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2095 .amount_msats(1000).unwrap()
2096 .build_and_sign().unwrap();
2097
2098 let mut buffer = Vec::new();
2099 invoice_request.write(&mut buffer).unwrap();
2100
2101 if let Err(e) = InvoiceRequest::try_from(buffer) {
2102 panic!("error parsing invoice_request: {:?}", e);
2103 }
2104
2105 let invoice_request = OfferBuilder::new(recipient_pubkey())
2106 .build().unwrap()
2107 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2108 .build_unchecked_and_sign();
2109
2110 let mut buffer = Vec::new();
2111 invoice_request.write(&mut buffer).unwrap();
2112
2113 match InvoiceRequest::try_from(buffer) {
2114 Ok(_) => panic!("expected error"),
2115 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)),
2116 }
2117
2118 let invoice_request = OfferBuilder::new(recipient_pubkey())
2119 .amount_msats(1000)
2120 .build().unwrap()
2121 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2122 .amount_msats_unchecked(999)
2123 .build_unchecked_and_sign();
2124
2125 let mut buffer = Vec::new();
2126 invoice_request.write(&mut buffer).unwrap();
2127
2128 match InvoiceRequest::try_from(buffer) {
2129 Ok(_) => panic!("expected error"),
2130 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InsufficientAmount)),
2131 }
2132
2133 let invoice_request = OfferBuilder::new(recipient_pubkey())
2134 .description("foo".to_string())
2135 .amount(Amount::Currency { iso4217_code: *b"USD", amount: 1000 })
2136 .build_unchecked()
2137 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2138 .build_unchecked_and_sign();
2139
2140 let mut buffer = Vec::new();
2141 invoice_request.write(&mut buffer).unwrap();
2142
2143 match InvoiceRequest::try_from(buffer) {
2144 Ok(_) => panic!("expected error"),
2145 Err(e) => {
2146 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnsupportedCurrency));
2147 },
2148 }
2149
2150 let invoice_request = OfferBuilder::new(recipient_pubkey())
2151 .amount_msats(1000)
2152 .supported_quantity(Quantity::Unbounded)
2153 .build().unwrap()
2154 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2155 .quantity(u64::max_value()).unwrap()
2156 .build_unchecked_and_sign();
2157
2158 let mut buffer = Vec::new();
2159 invoice_request.write(&mut buffer).unwrap();
2160
2161 match InvoiceRequest::try_from(buffer) {
2162 Ok(_) => panic!("expected error"),
2163 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)),
2164 }
2165 }
2166
2167 #[test]
2168 fn parses_invoice_request_with_quantity() {
2169 let expanded_key = ExpandedKey::new([42; 32]);
2170 let entropy = FixedEntropy {};
2171 let nonce = Nonce::from_entropy_source(&entropy);
2172 let secp_ctx = Secp256k1::new();
2173 let payment_id = PaymentId([1; 32]);
2174
2175 let one = NonZeroU64::new(1).unwrap();
2176 let ten = NonZeroU64::new(10).unwrap();
2177
2178 let invoice_request = OfferBuilder::new(recipient_pubkey())
2179 .amount_msats(1000)
2180 .supported_quantity(Quantity::One)
2181 .build().unwrap()
2182 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2183 .build_and_sign().unwrap();
2184
2185 let mut buffer = Vec::new();
2186 invoice_request.write(&mut buffer).unwrap();
2187
2188 if let Err(e) = InvoiceRequest::try_from(buffer) {
2189 panic!("error parsing invoice_request: {:?}", e);
2190 }
2191
2192 let invoice_request = OfferBuilder::new(recipient_pubkey())
2193 .amount_msats(1000)
2194 .supported_quantity(Quantity::One)
2195 .build().unwrap()
2196 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2197 .amount_msats(2_000).unwrap()
2198 .quantity_unchecked(2)
2199 .build_unchecked_and_sign();
2200
2201 let mut buffer = Vec::new();
2202 invoice_request.write(&mut buffer).unwrap();
2203
2204 match InvoiceRequest::try_from(buffer) {
2205 Ok(_) => panic!("expected error"),
2206 Err(e) => {
2207 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedQuantity));
2208 },
2209 }
2210
2211 let invoice_request = OfferBuilder::new(recipient_pubkey())
2212 .amount_msats(1000)
2213 .supported_quantity(Quantity::Bounded(ten))
2214 .build().unwrap()
2215 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2216 .amount_msats(10_000).unwrap()
2217 .quantity(10).unwrap()
2218 .build_and_sign().unwrap();
2219
2220 let mut buffer = Vec::new();
2221 invoice_request.write(&mut buffer).unwrap();
2222
2223 if let Err(e) = InvoiceRequest::try_from(buffer) {
2224 panic!("error parsing invoice_request: {:?}", e);
2225 }
2226
2227 let invoice_request = OfferBuilder::new(recipient_pubkey())
2228 .amount_msats(1000)
2229 .supported_quantity(Quantity::Bounded(ten))
2230 .build().unwrap()
2231 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2232 .amount_msats(11_000).unwrap()
2233 .quantity_unchecked(11)
2234 .build_unchecked_and_sign();
2235
2236 let mut buffer = Vec::new();
2237 invoice_request.write(&mut buffer).unwrap();
2238
2239 match InvoiceRequest::try_from(buffer) {
2240 Ok(_) => panic!("expected error"),
2241 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidQuantity)),
2242 }
2243
2244 let invoice_request = OfferBuilder::new(recipient_pubkey())
2245 .amount_msats(1000)
2246 .supported_quantity(Quantity::Unbounded)
2247 .build().unwrap()
2248 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2249 .amount_msats(2_000).unwrap()
2250 .quantity(2).unwrap()
2251 .build_and_sign().unwrap();
2252
2253 let mut buffer = Vec::new();
2254 invoice_request.write(&mut buffer).unwrap();
2255
2256 if let Err(e) = InvoiceRequest::try_from(buffer) {
2257 panic!("error parsing invoice_request: {:?}", e);
2258 }
2259
2260 let invoice_request = OfferBuilder::new(recipient_pubkey())
2261 .amount_msats(1000)
2262 .supported_quantity(Quantity::Unbounded)
2263 .build().unwrap()
2264 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2265 .build_unchecked_and_sign();
2266
2267 let mut buffer = Vec::new();
2268 invoice_request.write(&mut buffer).unwrap();
2269
2270 match InvoiceRequest::try_from(buffer) {
2271 Ok(_) => panic!("expected error"),
2272 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingQuantity)),
2273 }
2274
2275 let invoice_request = OfferBuilder::new(recipient_pubkey())
2276 .amount_msats(1000)
2277 .supported_quantity(Quantity::Bounded(one))
2278 .build().unwrap()
2279 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2280 .build_unchecked_and_sign();
2281
2282 let mut buffer = Vec::new();
2283 invoice_request.write(&mut buffer).unwrap();
2284
2285 match InvoiceRequest::try_from(buffer) {
2286 Ok(_) => panic!("expected error"),
2287 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingQuantity)),
2288 }
2289 }
2290
2291 #[test]
2292 fn fails_parsing_invoice_request_without_metadata() {
2293 let expanded_key = ExpandedKey::new([42; 32]);
2294 let entropy = FixedEntropy {};
2295 let nonce = Nonce::from_entropy_source(&entropy);
2296 let secp_ctx = Secp256k1::new();
2297 let payment_id = PaymentId([1; 32]);
2298
2299 let unsigned_invoice_request = OfferBuilder::new(recipient_pubkey())
2300 .amount_msats(1000)
2301 .build().unwrap()
2302 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2303 .build_unchecked();
2304 let mut tlv_stream = unsigned_invoice_request.contents.as_tlv_stream();
2305 tlv_stream.0.metadata = None;
2306
2307 let mut buffer = Vec::new();
2308 tlv_stream.write(&mut buffer).unwrap();
2309
2310 match InvoiceRequest::try_from(buffer) {
2311 Ok(_) => panic!("expected error"),
2312 Err(e) => {
2313 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerMetadata));
2314 },
2315 }
2316 }
2317
2318 #[test]
2319 fn fails_parsing_invoice_request_without_payer_signing_pubkey() {
2320 let expanded_key = ExpandedKey::new([42; 32]);
2321 let entropy = FixedEntropy {};
2322 let nonce = Nonce::from_entropy_source(&entropy);
2323 let secp_ctx = Secp256k1::new();
2324 let payment_id = PaymentId([1; 32]);
2325
2326 let unsigned_invoice_request = OfferBuilder::new(recipient_pubkey())
2327 .amount_msats(1000)
2328 .build().unwrap()
2329 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2330 .build_unchecked();
2331 let mut tlv_stream = unsigned_invoice_request.contents.as_tlv_stream();
2332 tlv_stream.2.payer_id = None;
2333
2334 let mut buffer = Vec::new();
2335 tlv_stream.write(&mut buffer).unwrap();
2336
2337 match InvoiceRequest::try_from(buffer) {
2338 Ok(_) => panic!("expected error"),
2339 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerSigningPubkey)),
2340 }
2341 }
2342
2343 #[test]
2344 fn fails_parsing_invoice_request_without_issuer_id() {
2345 let expanded_key = ExpandedKey::new([42; 32]);
2346 let entropy = FixedEntropy {};
2347 let nonce = Nonce::from_entropy_source(&entropy);
2348 let secp_ctx = Secp256k1::new();
2349 let payment_id = PaymentId([1; 32]);
2350
2351 let unsigned_invoice_request = OfferBuilder::new(recipient_pubkey())
2352 .amount_msats(1000)
2353 .build().unwrap()
2354 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2355 .build_unchecked();
2356 let mut tlv_stream = unsigned_invoice_request.contents.as_tlv_stream();
2357 tlv_stream.1.issuer_id = None;
2358
2359 let mut buffer = Vec::new();
2360 tlv_stream.write(&mut buffer).unwrap();
2361
2362 match InvoiceRequest::try_from(buffer) {
2363 Ok(_) => panic!("expected error"),
2364 Err(e) => {
2365 assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingIssuerSigningPubkey));
2366 },
2367 }
2368 }
2369
2370 #[test]
2371 fn fails_parsing_invoice_request_without_signature() {
2372 let expanded_key = ExpandedKey::new([42; 32]);
2373 let entropy = FixedEntropy {};
2374 let nonce = Nonce::from_entropy_source(&entropy);
2375 let secp_ctx = Secp256k1::new();
2376 let payment_id = PaymentId([1; 32]);
2377
2378 let mut buffer = Vec::new();
2379 OfferBuilder::new(recipient_pubkey())
2380 .amount_msats(1000)
2381 .build().unwrap()
2382 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2383 .build_unchecked()
2384 .contents
2385 .write(&mut buffer).unwrap();
2386
2387 match InvoiceRequest::try_from(buffer) {
2388 Ok(_) => panic!("expected error"),
2389 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
2390 }
2391 }
2392
2393 #[test]
2394 fn fails_parsing_invoice_request_with_invalid_signature() {
2395 let expanded_key = ExpandedKey::new([42; 32]);
2396 let entropy = FixedEntropy {};
2397 let nonce = Nonce::from_entropy_source(&entropy);
2398 let secp_ctx = Secp256k1::new();
2399 let payment_id = PaymentId([1; 32]);
2400
2401 let mut invoice_request = OfferBuilder::new(recipient_pubkey())
2402 .amount_msats(1000)
2403 .build().unwrap()
2404 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2405 .build_and_sign().unwrap();
2406 let last_signature_byte = invoice_request.bytes.last_mut().unwrap();
2407 *last_signature_byte = last_signature_byte.wrapping_add(1);
2408
2409 let mut buffer = Vec::new();
2410 invoice_request.write(&mut buffer).unwrap();
2411
2412 match InvoiceRequest::try_from(buffer) {
2413 Ok(_) => panic!("expected error"),
2414 Err(e) => {
2415 assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature));
2416 },
2417 }
2418 }
2419
2420 #[test]
2421 fn parses_invoice_request_with_unknown_tlv_records() {
2422 let expanded_key = ExpandedKey::new([42; 32]);
2423 let entropy = FixedEntropy {};
2424 let nonce = Nonce::from_entropy_source(&entropy);
2425 let payment_id = PaymentId([1; 32]);
2426
2427 const UNKNOWN_ODD_TYPE: u64 = INVOICE_REQUEST_TYPES.end - 1;
2428 assert!(UNKNOWN_ODD_TYPE % 2 == 1);
2429
2430 let secp_ctx = Secp256k1::new();
2431 let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2432 let (mut unsigned_invoice_request, payer_keys, _) = OfferBuilder::new(keys.public_key())
2433 .amount_msats(1000)
2434 .build().unwrap()
2435 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2436 .build_without_checks();
2437
2438 let mut unknown_bytes = Vec::new();
2439 BigSize(UNKNOWN_ODD_TYPE).write(&mut unknown_bytes).unwrap();
2440 BigSize(32).write(&mut unknown_bytes).unwrap();
2441 [42u8; 32].write(&mut unknown_bytes).unwrap();
2442
2443 unsigned_invoice_request.bytes.extend_from_slice(&unknown_bytes);
2444 unsigned_invoice_request.tagged_hash =
2445 TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &unsigned_invoice_request.bytes);
2446
2447 let keys = payer_keys.unwrap();
2448 let invoice_request = unsigned_invoice_request
2449 .sign(|message: &UnsignedInvoiceRequest|
2450 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2451 )
2452 .unwrap();
2453
2454 let mut encoded_invoice_request = Vec::new();
2455 invoice_request.write(&mut encoded_invoice_request).unwrap();
2456
2457 match InvoiceRequest::try_from(encoded_invoice_request.clone()) {
2458 Ok(invoice_request) => assert_eq!(invoice_request.bytes, encoded_invoice_request),
2459 Err(e) => panic!("error parsing invoice_request: {:?}", e),
2460 }
2461
2462 const UNKNOWN_EVEN_TYPE: u64 = INVOICE_REQUEST_TYPES.end - 2;
2463 assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
2464
2465 let (mut unsigned_invoice_request, payer_keys, _) = OfferBuilder::new(keys.public_key())
2466 .amount_msats(1000)
2467 .build().unwrap()
2468 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2469 .build_without_checks();
2470
2471 let mut unknown_bytes = Vec::new();
2472 BigSize(UNKNOWN_EVEN_TYPE).write(&mut unknown_bytes).unwrap();
2473 BigSize(32).write(&mut unknown_bytes).unwrap();
2474 [42u8; 32].write(&mut unknown_bytes).unwrap();
2475
2476 unsigned_invoice_request.bytes.extend_from_slice(&unknown_bytes);
2477 unsigned_invoice_request.tagged_hash =
2478 TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &unsigned_invoice_request.bytes);
2479
2480 let keys = payer_keys.unwrap();
2481 let invoice_request = unsigned_invoice_request
2482 .sign(|message: &UnsignedInvoiceRequest|
2483 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2484 )
2485 .unwrap();
2486
2487 let mut encoded_invoice_request = Vec::new();
2488 invoice_request.write(&mut encoded_invoice_request).unwrap();
2489
2490 match InvoiceRequest::try_from(encoded_invoice_request) {
2491 Ok(_) => panic!("expected error"),
2492 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
2493 }
2494 }
2495
2496 #[test]
2497 fn parses_invoice_request_with_experimental_tlv_records() {
2498 let expanded_key = ExpandedKey::new([42; 32]);
2499 let entropy = FixedEntropy {};
2500 let nonce = Nonce::from_entropy_source(&entropy);
2501 let payment_id = PaymentId([1; 32]);
2502
2503 const UNKNOWN_ODD_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start + 1;
2504 assert!(UNKNOWN_ODD_TYPE % 2 == 1);
2505
2506 let secp_ctx = Secp256k1::new();
2507 let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2508 let (mut unsigned_invoice_request, payer_keys, _) = OfferBuilder::new(keys.public_key())
2509 .amount_msats(1000)
2510 .build().unwrap()
2511 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2512 .build_without_checks();
2513
2514 let mut unknown_bytes = Vec::new();
2515 BigSize(UNKNOWN_ODD_TYPE).write(&mut unknown_bytes).unwrap();
2516 BigSize(32).write(&mut unknown_bytes).unwrap();
2517 [42u8; 32].write(&mut unknown_bytes).unwrap();
2518
2519 unsigned_invoice_request.experimental_bytes.extend_from_slice(&unknown_bytes);
2520
2521 let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2522 .chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2523 unsigned_invoice_request.tagged_hash =
2524 TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2525
2526 let keys = payer_keys.unwrap();
2527 let invoice_request = unsigned_invoice_request
2528 .sign(|message: &UnsignedInvoiceRequest|
2529 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2530 )
2531 .unwrap();
2532
2533 let mut encoded_invoice_request = Vec::new();
2534 invoice_request.write(&mut encoded_invoice_request).unwrap();
2535
2536 match InvoiceRequest::try_from(encoded_invoice_request.clone()) {
2537 Ok(invoice_request) => assert_eq!(invoice_request.bytes, encoded_invoice_request),
2538 Err(e) => panic!("error parsing invoice_request: {:?}", e),
2539 }
2540
2541 const UNKNOWN_EVEN_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start;
2542 assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
2543
2544 let (mut unsigned_invoice_request, payer_keys, _) = OfferBuilder::new(keys.public_key())
2545 .amount_msats(1000)
2546 .build().unwrap()
2547 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2548 .build_without_checks();
2549
2550 let mut unknown_bytes = Vec::new();
2551 BigSize(UNKNOWN_EVEN_TYPE).write(&mut unknown_bytes).unwrap();
2552 BigSize(32).write(&mut unknown_bytes).unwrap();
2553 [42u8; 32].write(&mut unknown_bytes).unwrap();
2554
2555 unsigned_invoice_request.experimental_bytes.extend_from_slice(&unknown_bytes);
2556
2557 let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2558 .chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2559 unsigned_invoice_request.tagged_hash =
2560 TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2561
2562 let keys = payer_keys.unwrap();
2563 let invoice_request = unsigned_invoice_request
2564 .sign(|message: &UnsignedInvoiceRequest|
2565 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2566 )
2567 .unwrap();
2568
2569 let mut encoded_invoice_request = Vec::new();
2570 invoice_request.write(&mut encoded_invoice_request).unwrap();
2571
2572 match InvoiceRequest::try_from(encoded_invoice_request) {
2573 Ok(_) => panic!("expected error"),
2574 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
2575 }
2576
2577 let invoice_request = OfferBuilder::new(keys.public_key())
2578 .amount_msats(1000)
2579 .build().unwrap()
2580 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2581 .build_and_sign().unwrap();
2582
2583 let mut encoded_invoice_request = Vec::new();
2584 invoice_request.write(&mut encoded_invoice_request).unwrap();
2585
2586 BigSize(UNKNOWN_ODD_TYPE).write(&mut encoded_invoice_request).unwrap();
2587 BigSize(32).write(&mut encoded_invoice_request).unwrap();
2588 [42u8; 32].write(&mut encoded_invoice_request).unwrap();
2589
2590 match InvoiceRequest::try_from(encoded_invoice_request) {
2591 Ok(_) => panic!("expected error"),
2592 Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature)),
2593 }
2594 }
2595
2596 #[test]
2597 fn fails_parsing_invoice_request_with_out_of_range_tlv_records() {
2598 let expanded_key = ExpandedKey::new([42; 32]);
2599 let entropy = FixedEntropy {};
2600 let nonce = Nonce::from_entropy_source(&entropy);
2601 let secp_ctx = Secp256k1::new();
2602 let payment_id = PaymentId([1; 32]);
2603
2604 let invoice_request = OfferBuilder::new(recipient_pubkey())
2605 .amount_msats(1000)
2606 .build().unwrap()
2607 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id).unwrap()
2608 .build_and_sign().unwrap();
2609
2610 let mut encoded_invoice_request = Vec::new();
2611 invoice_request.write(&mut encoded_invoice_request).unwrap();
2612 BigSize(1002).write(&mut encoded_invoice_request).unwrap();
2613 BigSize(32).write(&mut encoded_invoice_request).unwrap();
2614 [42u8; 32].write(&mut encoded_invoice_request).unwrap();
2615
2616 match InvoiceRequest::try_from(encoded_invoice_request) {
2617 Ok(_) => panic!("expected error"),
2618 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
2619 }
2620
2621 let mut encoded_invoice_request = Vec::new();
2622 invoice_request.write(&mut encoded_invoice_request).unwrap();
2623 BigSize(EXPERIMENTAL_INVOICE_REQUEST_TYPES.end).write(&mut encoded_invoice_request).unwrap();
2624 BigSize(32).write(&mut encoded_invoice_request).unwrap();
2625 [42u8; 32].write(&mut encoded_invoice_request).unwrap();
2626
2627 match InvoiceRequest::try_from(encoded_invoice_request) {
2628 Ok(_) => panic!("expected error"),
2629 Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
2630 }
2631 }
2632
2633 #[test]
2634 fn copies_verified_invoice_request_fields() {
2635 let node_id = recipient_pubkey();
2636 let expanded_key = ExpandedKey::new([42; 32]);
2637 let entropy = FixedEntropy {};
2638 let nonce = Nonce::from_entropy_source(&entropy);
2639 let secp_ctx = Secp256k1::new();
2640 let payment_id = PaymentId([1; 32]);
2641
2642 #[cfg(c_bindings)]
2643 use crate::offers::offer::OfferWithDerivedMetadataBuilder as OfferBuilder;
2644 let offer = OfferBuilder::deriving_signing_pubkey(node_id, &expanded_key, nonce, &secp_ctx)
2645 .chain(Network::Testnet)
2646 .amount_msats(1000)
2647 .supported_quantity(Quantity::Unbounded)
2648 .build().unwrap();
2649 assert_eq!(offer.issuer_signing_pubkey(), Some(node_id));
2650
2651 let payer_note = "❤️".repeat(86);
2654 assert_eq!(payer_note.len(), PAYER_NOTE_LIMIT + 4);
2655 let expected_payer_note = "❤️".repeat(85);
2656
2657 let invoice_request = offer
2658 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
2659 .unwrap()
2660 .chain(Network::Testnet)
2661 .unwrap()
2662 .quantity(1)
2663 .unwrap()
2664 .payer_note(payer_note)
2665 .build_and_sign()
2666 .unwrap();
2667 match invoice_request.verify_using_metadata(&expanded_key, &secp_ctx) {
2668 Ok(invoice_request) => {
2669 let fields = invoice_request.fields();
2670 assert_eq!(invoice_request.offer_id, offer.id());
2671 assert_eq!(
2672 fields,
2673 InvoiceRequestFields {
2674 payer_signing_pubkey: invoice_request.payer_signing_pubkey(),
2675 quantity: Some(1),
2676 payer_note_truncated: Some(UntrustedString(expected_payer_note)),
2677 human_readable_name: None,
2678 }
2679 );
2680
2681 let mut buffer = Vec::new();
2682 fields.write(&mut buffer).unwrap();
2683
2684 let deserialized_fields: InvoiceRequestFields =
2685 Readable::read(&mut buffer.as_slice()).unwrap();
2686 assert_eq!(deserialized_fields, fields);
2687 },
2688 Err(_) => panic!("unexpected error"),
2689 }
2690 }
2691
2692 #[test]
2693 fn test_string_truncate_safe() {
2694 let s = String::from("❤️");
2698 assert_eq!(s.len(), 6);
2699 assert_eq!(s, string_truncate_safe(s.clone(), 7));
2700 assert_eq!(s, string_truncate_safe(s.clone(), 6));
2701 assert_eq!("❤", string_truncate_safe(s.clone(), 5));
2702 assert_eq!("❤", string_truncate_safe(s.clone(), 4));
2703 assert_eq!("❤", string_truncate_safe(s.clone(), 3));
2704 assert_eq!("", string_truncate_safe(s.clone(), 2));
2705 assert_eq!("", string_truncate_safe(s.clone(), 1));
2706 assert_eq!("", string_truncate_safe(s.clone(), 0));
2707
2708 let s = String::from("my ASCII string!");
2710 for new_len in 0..(s.len() + 5) {
2711 if new_len >= s.len() {
2712 assert_eq!(s, string_truncate_safe(s.clone(), new_len));
2713 } else {
2714 assert_eq!(s[..new_len], string_truncate_safe(s.clone(), new_len));
2715 }
2716 }
2717 }
2718}