Skip to main content

lightning_invoice/
lib.rs

1#![deny(rustdoc::broken_intra_doc_links)]
2#![deny(rustdoc::private_intra_doc_links)]
3#![deny(missing_docs)]
4#![deny(non_upper_case_globals)]
5#![deny(non_camel_case_types)]
6#![deny(non_snake_case)]
7#![deny(unused_mut)]
8#![cfg_attr(docsrs, feature(doc_cfg))]
9#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
10
11//! This crate provides data structures to represent
12//! [lightning BOLT11](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md)
13//! invoices and functions to create, encode and decode these. If you just want to use the standard
14//! en-/decoding functionality this should get you started:
15//!
16//!   * For parsing use `str::parse::<Bolt11Invoice>(&self)` (see [`Bolt11Invoice::from_str`])
17//!   * For constructing invoices use the [`InvoiceBuilder`]
18//!   * For serializing invoices use the [`Display`]/[`ToString`] traits
19//!
20//! [`Bolt11Invoice::from_str`]: crate::Bolt11Invoice#impl-FromStr
21
22extern crate alloc;
23extern crate bech32;
24#[cfg(any(test, feature = "std"))]
25extern crate core;
26extern crate lightning_types;
27#[cfg(feature = "serde")]
28extern crate serde;
29
30#[cfg(feature = "std")]
31use std::time::SystemTime;
32
33use bech32::primitives::decode::CheckedHrpstringError;
34use bech32::{Checksum, Fe32};
35use bitcoin::hashes::{sha256, Hash};
36use bitcoin::{Address, Network, PubkeyHash, ScriptHash, WitnessProgram, WitnessVersion};
37use lightning_types::features::Bolt11InvoiceFeatures;
38
39use bitcoin::secp256k1::ecdsa::RecoverableSignature;
40use bitcoin::secp256k1::PublicKey;
41use bitcoin::secp256k1::{Message, Secp256k1};
42
43use alloc::boxed::Box;
44use alloc::string;
45use core::cmp::Ordering;
46use core::fmt::{self, Display, Formatter};
47use core::iter::FilterMap;
48use core::num::ParseIntError;
49use core::ops::Deref;
50use core::slice::Iter;
51use core::str::FromStr;
52use core::time::Duration;
53
54#[cfg(feature = "serde")]
55use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
56
57#[doc(no_inline)]
58pub use lightning_types::payment::PaymentSecret;
59#[doc(no_inline)]
60pub use lightning_types::routing::{RouteHint, RouteHintHop, RoutingFees};
61use lightning_types::string::UntrustedString;
62
63mod de;
64mod ser;
65mod tb;
66
67#[cfg(test)]
68mod test_ser_de;
69
70#[allow(unused_imports)]
71mod prelude {
72	pub use alloc::{string::String, vec, vec::Vec};
73
74	pub use alloc::string::ToString;
75}
76
77use crate::prelude::*;
78
79/// Re-export serialization traits
80#[cfg(fuzzing)]
81pub use crate::de::FromBase32;
82#[cfg(not(fuzzing))]
83use crate::de::FromBase32;
84#[cfg(fuzzing)]
85pub use crate::ser::Base32Iterable;
86#[cfg(not(fuzzing))]
87use crate::ser::Base32Iterable;
88
89/// Errors that indicate what is wrong with the invoice. They have some granularity for debug
90/// reasons, but should generally result in an "invalid BOLT11 invoice" message for the user.
91#[allow(missing_docs)]
92#[derive(PartialEq, Eq, Debug, Clone)]
93pub enum Bolt11ParseError {
94	Bech32Error(CheckedHrpstringError),
95	ParseAmountError(ParseIntError),
96	MalformedSignature(bitcoin::secp256k1::Error),
97	BadPrefix,
98	UnknownCurrency,
99	UnknownSiPrefix,
100	MalformedHRP,
101	TooShortDataPart,
102	UnexpectedEndOfTaggedFields,
103	DescriptionDecodeError(string::FromUtf8Error),
104	PaddingError,
105	IntegerOverflowError,
106	InvalidSegWitProgramLength,
107	InvalidPubKeyHashLength,
108	InvalidScriptHashLength,
109	InvalidRecoveryId,
110	// Invalid length, with actual length, expected length, and name of the element
111	InvalidSliceLength(usize, usize, &'static str),
112
113	/// Not an error, but used internally to signal that a part of the invoice should be ignored
114	/// according to BOLT11
115	Skip,
116}
117
118/// Indicates that something went wrong while parsing or validating the invoice. Parsing errors
119/// should be mostly seen as opaque and are only there for debugging reasons. Semantic errors
120/// like wrong signatures, missing fields etc. could mean that someone tampered with the invoice.
121#[derive(PartialEq, Eq, Debug, Clone)]
122pub enum ParseOrSemanticError {
123	/// The invoice couldn't be decoded
124	ParseError(Bolt11ParseError),
125
126	/// The invoice could be decoded but violates the BOLT11 standard
127	SemanticError(crate::Bolt11SemanticError),
128}
129
130/// The number of bits used to represent timestamps as defined in BOLT 11.
131const TIMESTAMP_BITS: usize = 35;
132
133/// The maximum timestamp as [`Duration::as_secs`] since the Unix epoch allowed by [`BOLT 11`].
134///
135/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
136pub const MAX_TIMESTAMP: u64 = (1 << TIMESTAMP_BITS) - 1;
137
138/// Default expiry time as defined by [BOLT 11].
139///
140/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
141pub const DEFAULT_EXPIRY_TIME: u64 = 3600;
142
143/// Default minimum final CLTV expiry as defined by [BOLT 11].
144///
145/// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry.
146///
147/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
148pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18;
149
150/// lightning-invoice will reject BOLT11 invoices that are longer than 7089 bytes.
151///
152/// ### Rationale
153///
154/// This value matches LND's implementation, which was chosen to be "the max number
155/// of bytes that can fit in a QR code". LND's rationale is technically incorrect
156/// as QR codes actually have a max capacity of 7089 _numeric_ characters and only
157/// support up to 4296 all-uppercase alphanumeric characters. However, ecosystem-wide
158/// consistency is more important.
159pub const MAX_LENGTH: usize = 7089;
160
161/// The [`bech32::Bech32`] checksum algorithm, with extended max length suitable
162/// for BOLT11 invoices.
163pub enum Bolt11Bech32 {}
164
165impl Checksum for Bolt11Bech32 {
166	/// Extend the max length from the 1023 bytes default.
167	const CODE_LENGTH: usize = MAX_LENGTH;
168
169	// Inherit the other fields from `bech32::Bech32`.
170	type MidstateRepr = <bech32::Bech32 as Checksum>::MidstateRepr;
171	const CHECKSUM_LENGTH: usize = bech32::Bech32::CHECKSUM_LENGTH;
172	const GENERATOR_SH: [Self::MidstateRepr; 5] = bech32::Bech32::GENERATOR_SH;
173	const TARGET_RESIDUE: Self::MidstateRepr = bech32::Bech32::TARGET_RESIDUE;
174}
175
176/// Builder for [`Bolt11Invoice`]s. It's the most convenient and advised way to use this library. It
177/// ensures that only a semantically and syntactically correct invoice can be built using it.
178///
179/// ```
180/// extern crate lightning_invoice;
181/// extern crate bitcoin;
182///
183/// use bitcoin::hashes::Hash;
184/// use bitcoin::hashes::sha256;
185///
186/// use bitcoin::secp256k1::Secp256k1;
187/// use bitcoin::secp256k1::SecretKey;
188///
189/// use lightning_types::payment::PaymentSecret;
190///
191/// use lightning_invoice::{Currency, InvoiceBuilder};
192///
193/// # #[cfg(not(feature = "std"))]
194/// # fn main() {}
195/// # #[cfg(feature = "std")]
196/// # fn main() {
197/// let private_key = SecretKey::from_slice(
198///		&[
199///			0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f,
200///			0xe2, 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04,
201/// 		0xa8, 0xca, 0x3b, 0x2d, 0xb7, 0x34
202/// 	][..]
203///	).unwrap();
204///
205/// let payment_hash = sha256::Hash::from_slice(&[0; 32][..]).unwrap();
206/// let payment_secret = PaymentSecret([42u8; 32]);
207///
208/// let invoice = InvoiceBuilder::new(Currency::Bitcoin)
209/// 	.description("Coins pls!".into())
210/// 	.payment_hash(payment_hash)
211/// 	.payment_secret(payment_secret)
212/// 	.current_timestamp()
213/// 	.min_final_cltv_expiry_delta(144)
214/// 	.build_signed(|hash| {
215/// 		Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
216/// 	})
217/// 	.unwrap();
218///
219/// assert!(invoice.to_string().starts_with("lnbc1"));
220/// # }
221/// ```
222///
223/// # Type parameters
224/// The two parameters `D` and `H` signal if the builder already contains the correct amount of the
225/// given field:
226///  * `D`: exactly one [`TaggedField::Description`] or [`TaggedField::DescriptionHash`]
227///  * `H`: exactly one [`TaggedField::PaymentHash`]
228///  * `T`: the timestamp is set
229///  * `C`: the CLTV expiry is set
230///  * `S`: the payment secret is set
231///  * `M`: payment metadata is set
232///
233/// This is not exported to bindings users as we likely need to manually select one set of boolean type parameters.
234#[derive(Eq, PartialEq, Debug, Clone)]
235pub struct InvoiceBuilder<
236	D: tb::Bool,
237	H: tb::Bool,
238	T: tb::Bool,
239	C: tb::Bool,
240	S: tb::Bool,
241	M: tb::Bool,
242> {
243	currency: Currency,
244	amount: Option<u64>,
245	si_prefix: Option<SiPrefix>,
246	timestamp: Option<PositiveTimestamp>,
247	tagged_fields: Vec<TaggedField>,
248	error: Option<CreationError>,
249
250	phantom_d: core::marker::PhantomData<D>,
251	phantom_h: core::marker::PhantomData<H>,
252	phantom_t: core::marker::PhantomData<T>,
253	phantom_c: core::marker::PhantomData<C>,
254	phantom_s: core::marker::PhantomData<S>,
255	phantom_m: core::marker::PhantomData<M>,
256}
257
258/// Represents a syntactically and semantically correct lightning BOLT11 invoice.
259///
260/// There are three ways to construct a `Bolt11Invoice`:
261///  1. using [`InvoiceBuilder`]
262///  2. using [`Bolt11Invoice::from_signed`]
263///  3. using `str::parse::<Bolt11Invoice>(&str)` (see [`Bolt11Invoice::from_str`])
264///
265/// [`Bolt11Invoice::from_str`]: crate::Bolt11Invoice#impl-FromStr
266#[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)]
267pub struct Bolt11Invoice {
268	signed_invoice: SignedRawBolt11Invoice,
269}
270
271/// Represents the description of an invoice which has to be either a directly included string or
272/// a hash of a description provided out of band.
273#[derive(Eq, PartialEq, Debug, Clone, Ord, PartialOrd)]
274pub enum Bolt11InvoiceDescription {
275	/// Description of what the invoice is for
276	Direct(Description),
277
278	/// Hash of the description of what the invoice is for
279	Hash(Sha256),
280}
281
282impl Display for Bolt11InvoiceDescription {
283	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
284		match self {
285			Bolt11InvoiceDescription::Direct(desc) => write!(f, "{}", desc.0),
286			Bolt11InvoiceDescription::Hash(hash) => write!(f, "{}", hash.0),
287		}
288	}
289}
290
291/// Represents the description of an invoice which has to be either a directly included string or
292/// a hash of a description provided out of band.
293///
294/// This is not exported to bindings users as we don't have a good way to map the reference lifetimes making this
295/// practically impossible to use safely in languages like C.
296#[derive(Eq, PartialEq, Debug, Clone, Copy, Ord, PartialOrd)]
297pub enum Bolt11InvoiceDescriptionRef<'f> {
298	/// Reference to the directly supplied description in the invoice
299	Direct(&'f Description),
300
301	/// Reference to the description's hash included in the invoice
302	Hash(&'f Sha256),
303}
304
305impl<'f> Display for Bolt11InvoiceDescriptionRef<'f> {
306	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
307		match self {
308			Bolt11InvoiceDescriptionRef::Direct(desc) => write!(f, "{}", desc.0),
309			Bolt11InvoiceDescriptionRef::Hash(hash) => write!(f, "{}", hash.0),
310		}
311	}
312}
313
314/// Represents a signed [`RawBolt11Invoice`] with cached hash. The signature is not checked and may be
315/// invalid.
316///
317/// # Invariants
318/// The hash has to be either from the deserialized invoice or from the serialized [`RawBolt11Invoice`].
319#[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)]
320pub struct SignedRawBolt11Invoice {
321	/// The raw invoice that the signature belongs to
322	raw_invoice: RawBolt11Invoice,
323
324	/// Hash of the [`RawBolt11Invoice`] that will be used to check the signature.
325	///
326	/// * if the `SignedRawBolt11Invoice` was deserialized the hash is of from the original encoded form,
327	/// since it's not guaranteed that encoding it again will lead to the same result since integers
328	/// could have been encoded with leading zeroes etc.
329	/// * if the `SignedRawBolt11Invoice` was constructed manually the hash will be the calculated hash
330	/// from the [`RawBolt11Invoice`]
331	hash: [u8; 32],
332
333	/// signature of the payment request
334	signature: Bolt11InvoiceSignature,
335}
336
337/// Represents an syntactically correct [`Bolt11Invoice`] for a payment on the lightning network,
338/// but without the signature information.
339/// Decoding and encoding should not lead to information loss but may lead to different hashes.
340///
341/// For methods without docs see the corresponding methods in [`Bolt11Invoice`].
342#[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)]
343pub struct RawBolt11Invoice {
344	/// human readable part
345	pub hrp: RawHrp,
346
347	/// data part
348	pub data: RawDataPart,
349}
350
351/// Data of the [`RawBolt11Invoice`] that is encoded in the human readable part.
352///
353/// This is not exported to bindings users as we don't yet support `Option<Enum>`
354#[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)]
355pub struct RawHrp {
356	/// The currency deferred from the 3rd and 4th character of the bech32 transaction
357	pub currency: Currency,
358
359	/// The amount that, multiplied by the SI prefix, has to be payed
360	pub raw_amount: Option<u64>,
361
362	/// SI prefix that gets multiplied with the `raw_amount`
363	pub si_prefix: Option<SiPrefix>,
364}
365
366impl RawHrp {
367	/// Convert to bech32::Hrp
368	pub fn to_hrp(&self) -> bech32::Hrp {
369		let hrp_str = self.to_string();
370		let s = core::str::from_utf8(&hrp_str.as_bytes()).expect("HRP bytes should be ASCII");
371		debug_assert!(bech32::Hrp::parse(s).is_ok(), "We should always build BIP 173-valid HRPs");
372		bech32::Hrp::parse_unchecked(s)
373	}
374}
375
376/// Data of the [`RawBolt11Invoice`] that is encoded in the data part
377#[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)]
378pub struct RawDataPart {
379	/// generation time of the invoice
380	pub timestamp: PositiveTimestamp,
381
382	/// tagged fields of the payment request
383	pub tagged_fields: Vec<RawTaggedField>,
384}
385
386/// A timestamp that refers to a date after 1 January 1970.
387///
388/// # Invariants
389///
390/// The Unix timestamp representing the stored time has to be positive and no greater than
391/// [`MAX_TIMESTAMP`].
392#[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)]
393pub struct PositiveTimestamp(Duration);
394
395/// SI prefixes for the human readable part
396#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash, Ord, PartialOrd)]
397pub enum SiPrefix {
398	/// 10^-3
399	Milli,
400	/// 10^-6
401	Micro,
402	/// 10^-9
403	Nano,
404	/// 10^-12
405	Pico,
406}
407
408impl SiPrefix {
409	/// Returns the multiplier to go from a BTC value to picoBTC implied by this SiPrefix.
410	/// This is effectively 10^12 * the prefix multiplier
411	pub fn multiplier(&self) -> u64 {
412		match *self {
413			SiPrefix::Milli => 1_000_000_000,
414			SiPrefix::Micro => 1_000_000,
415			SiPrefix::Nano => 1_000,
416			SiPrefix::Pico => 1,
417		}
418	}
419
420	/// Returns all enum variants of `SiPrefix` sorted in descending order of their associated
421	/// multiplier.
422	///
423	/// This is not exported to bindings users as we don't yet support a slice of enums, and also because this function
424	/// isn't the most critical to expose.
425	pub fn values_desc() -> &'static [SiPrefix] {
426		use crate::SiPrefix::*;
427		static VALUES: [SiPrefix; 4] = [Milli, Micro, Nano, Pico];
428		&VALUES
429	}
430}
431
432/// Enum representing the crypto currencies (or networks) supported by this library
433#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
434pub enum Currency {
435	/// Bitcoin mainnet
436	Bitcoin,
437
438	/// Bitcoin testnet
439	BitcoinTestnet,
440
441	/// Bitcoin regtest
442	Regtest,
443
444	/// Bitcoin simnet
445	Simnet,
446
447	/// Bitcoin signet
448	Signet,
449}
450
451impl From<Network> for Currency {
452	fn from(network: Network) -> Self {
453		match network {
454			Network::Bitcoin => Currency::Bitcoin,
455			Network::Testnet => Currency::BitcoinTestnet,
456			Network::Regtest => Currency::Regtest,
457			Network::Signet => Currency::Signet,
458			_ => {
459				debug_assert!(false, "Need to handle new rust-bitcoin network type");
460				Currency::Regtest
461			},
462		}
463	}
464}
465
466impl From<Currency> for Network {
467	fn from(currency: Currency) -> Self {
468		match currency {
469			Currency::Bitcoin => Network::Bitcoin,
470			Currency::BitcoinTestnet => Network::Testnet,
471			Currency::Regtest => Network::Regtest,
472			Currency::Simnet => Network::Regtest,
473			Currency::Signet => Network::Signet,
474		}
475	}
476}
477
478/// Tagged field which may have an unknown tag
479///
480/// This is not exported to bindings users as we don't currently support TaggedField
481#[derive(Clone, Debug, Hash, Eq, PartialEq)]
482pub enum RawTaggedField {
483	/// Parsed tagged field with known tag
484	KnownSemantics(TaggedField),
485	/// tagged field which was not parsed due to an unknown tag or undefined field semantics
486	UnknownSemantics(Vec<Fe32>),
487}
488
489impl PartialOrd for RawTaggedField {
490	fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
491		Some(self.cmp(other))
492	}
493}
494
495/// Note: `Ord `cannot be simply derived because of `Fe32`.
496impl Ord for RawTaggedField {
497	fn cmp(&self, other: &Self) -> core::cmp::Ordering {
498		match (self, other) {
499			(RawTaggedField::KnownSemantics(ref a), RawTaggedField::KnownSemantics(ref b)) => {
500				a.cmp(b)
501			},
502			(RawTaggedField::UnknownSemantics(ref a), RawTaggedField::UnknownSemantics(ref b)) => {
503				a.iter().map(|a| a.to_u8()).cmp(b.iter().map(|b| b.to_u8()))
504			},
505			(RawTaggedField::KnownSemantics(..), RawTaggedField::UnknownSemantics(..)) => {
506				core::cmp::Ordering::Less
507			},
508			(RawTaggedField::UnknownSemantics(..), RawTaggedField::KnownSemantics(..)) => {
509				core::cmp::Ordering::Greater
510			},
511		}
512	}
513}
514
515/// Tagged field with known tag
516///
517/// For descriptions of the enum values please refer to the enclosed type's docs.
518///
519/// This is not exported to bindings users as we don't yet support enum variants with the same name the struct contained
520/// in the variant.
521#[allow(missing_docs)]
522#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
523pub enum TaggedField {
524	PaymentHash(Sha256),
525	Description(Description),
526	PayeePubKey(PayeePubKey),
527	DescriptionHash(Sha256),
528	ExpiryTime(ExpiryTime),
529	MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta),
530	Fallback(Fallback),
531	PrivateRoute(PrivateRoute),
532	PaymentSecret(PaymentSecret),
533	PaymentMetadata(Vec<u8>),
534	Features(Bolt11InvoiceFeatures),
535}
536
537/// SHA-256 hash
538#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
539pub struct Sha256(
540	/// This is not exported to bindings users as the native hash types are not currently mapped
541	pub sha256::Hash,
542);
543
544impl Sha256 {
545	/// Constructs a new [`Sha256`] from the given bytes, which are assumed to be the output of a
546	/// single sha256 hash.
547	#[cfg(c_bindings)]
548	pub fn from_bytes(bytes: &[u8; 32]) -> Self {
549		Self(sha256::Hash::from_slice(bytes).expect("from_slice only fails if len is not 32"))
550	}
551}
552
553/// Description string
554///
555/// # Invariants
556/// The description can be at most 639 __bytes__ long
557#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Default)]
558pub struct Description(UntrustedString);
559
560/// Payee public key
561#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
562pub struct PayeePubKey(pub PublicKey);
563
564/// Positive duration that defines when (relatively to the timestamp) in the future the invoice
565/// expires
566#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
567pub struct ExpiryTime(Duration);
568
569/// `min_final_cltv_expiry_delta` to use for the last HTLC in the route
570#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
571pub struct MinFinalCltvExpiryDelta(pub u64);
572
573/// Fallback address in case no LN payment is possible
574#[allow(missing_docs)]
575#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
576pub enum Fallback {
577	SegWitProgram { version: WitnessVersion, program: Vec<u8> },
578	PubKeyHash(PubkeyHash),
579	ScriptHash(ScriptHash),
580}
581
582/// Recoverable signature
583#[derive(Clone, Debug, Hash, Eq, PartialEq)]
584pub struct Bolt11InvoiceSignature(pub RecoverableSignature);
585
586impl PartialOrd for Bolt11InvoiceSignature {
587	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
588		Some(self.cmp(other))
589	}
590}
591
592impl Ord for Bolt11InvoiceSignature {
593	fn cmp(&self, other: &Self) -> Ordering {
594		self.0.serialize_compact().1.cmp(&other.0.serialize_compact().1)
595	}
596}
597
598/// Private routing information
599///
600/// # Invariants
601/// The encoded route has to be <1024 5bit characters long (<=639 bytes or <=12 hops)
602///
603#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
604pub struct PrivateRoute(RouteHint);
605
606/// Tag constants as specified in BOLT11
607#[allow(missing_docs)]
608pub mod constants {
609	pub const TAG_PAYMENT_HASH: u8 = 1;
610	pub const TAG_DESCRIPTION: u8 = 13;
611	pub const TAG_PAYEE_PUB_KEY: u8 = 19;
612	pub const TAG_DESCRIPTION_HASH: u8 = 23;
613	pub const TAG_EXPIRY_TIME: u8 = 6;
614	pub const TAG_MIN_FINAL_CLTV_EXPIRY_DELTA: u8 = 24;
615	pub const TAG_FALLBACK: u8 = 9;
616	pub const TAG_PRIVATE_ROUTE: u8 = 3;
617	pub const TAG_PAYMENT_SECRET: u8 = 16;
618	pub const TAG_PAYMENT_METADATA: u8 = 27;
619	pub const TAG_FEATURES: u8 = 5;
620}
621
622impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False, tb::False> {
623	/// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
624	/// `InvoiceBuilder::build(self)` becomes available.
625	pub fn new(currency: Currency) -> Self {
626		InvoiceBuilder {
627			currency,
628			amount: None,
629			si_prefix: None,
630			timestamp: None,
631			tagged_fields: Vec::with_capacity(8),
632			error: None,
633
634			phantom_d: core::marker::PhantomData,
635			phantom_h: core::marker::PhantomData,
636			phantom_t: core::marker::PhantomData,
637			phantom_c: core::marker::PhantomData,
638			phantom_s: core::marker::PhantomData,
639			phantom_m: core::marker::PhantomData,
640		}
641	}
642}
643
644impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool>
645	InvoiceBuilder<D, H, T, C, S, M>
646{
647	/// Helper function to set the completeness flags.
648	fn set_flags<
649		DN: tb::Bool,
650		HN: tb::Bool,
651		TN: tb::Bool,
652		CN: tb::Bool,
653		SN: tb::Bool,
654		MN: tb::Bool,
655	>(
656		self,
657	) -> InvoiceBuilder<DN, HN, TN, CN, SN, MN> {
658		InvoiceBuilder::<DN, HN, TN, CN, SN, MN> {
659			currency: self.currency,
660			amount: self.amount,
661			si_prefix: self.si_prefix,
662			timestamp: self.timestamp,
663			tagged_fields: self.tagged_fields,
664			error: self.error,
665
666			phantom_d: core::marker::PhantomData,
667			phantom_h: core::marker::PhantomData,
668			phantom_t: core::marker::PhantomData,
669			phantom_c: core::marker::PhantomData,
670			phantom_s: core::marker::PhantomData,
671			phantom_m: core::marker::PhantomData,
672		}
673	}
674
675	/// Sets the amount in millisatoshis. The optimal SI prefix is chosen automatically.
676	pub fn amount_milli_satoshis(mut self, amount_msat: u64) -> Self {
677		// Invoices are denominated in "pico BTC"
678		let amount = match amount_msat.checked_mul(10) {
679			Some(amt) => amt,
680			None => {
681				self.error = Some(CreationError::InvalidAmount);
682				return self;
683			},
684		};
685		let biggest_possible_si_prefix = SiPrefix::values_desc()
686			.iter()
687			.find(|prefix| amount % prefix.multiplier() == 0)
688			.expect("Pico should always match");
689		self.amount = Some(amount / biggest_possible_si_prefix.multiplier());
690		self.si_prefix = Some(*biggest_possible_si_prefix);
691		self
692	}
693
694	/// Sets the payee's public key.
695	pub fn payee_pub_key(mut self, pub_key: PublicKey) -> Self {
696		self.tagged_fields.push(TaggedField::PayeePubKey(PayeePubKey(pub_key)));
697		self
698	}
699
700	/// Sets the expiry time, dropping the subsecond part (which is not representable in BOLT 11
701	/// invoices).
702	pub fn expiry_time(mut self, expiry_time: Duration) -> Self {
703		self.tagged_fields.push(TaggedField::ExpiryTime(ExpiryTime::from_duration(expiry_time)));
704		self
705	}
706
707	/// Adds a fallback address.
708	pub fn fallback(mut self, fallback: Fallback) -> Self {
709		self.tagged_fields.push(TaggedField::Fallback(fallback));
710		self
711	}
712
713	/// Adds a private route.
714	pub fn private_route(mut self, hint: RouteHint) -> Self {
715		match PrivateRoute::new(hint) {
716			Ok(r) => self.tagged_fields.push(TaggedField::PrivateRoute(r)),
717			Err(e) => self.error = Some(e),
718		}
719		self
720	}
721}
722
723impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool>
724	InvoiceBuilder<D, H, tb::True, C, S, M>
725{
726	/// Builds a [`RawBolt11Invoice`] if no [`CreationError`] occurred while construction any of the
727	/// fields.
728	pub fn build_raw(self) -> Result<RawBolt11Invoice, CreationError> {
729		// If an error occurred at any time before, return it now
730		if let Some(e) = self.error {
731			return Err(e);
732		}
733
734		let hrp =
735			RawHrp { currency: self.currency, raw_amount: self.amount, si_prefix: self.si_prefix };
736
737		let timestamp = self.timestamp.expect("ensured to be Some(t) by type T");
738
739		let tagged_fields = self
740			.tagged_fields
741			.into_iter()
742			.map(|tf| RawTaggedField::KnownSemantics(tf))
743			.collect::<Vec<_>>();
744
745		let data = RawDataPart { timestamp, tagged_fields };
746
747		Ok(RawBolt11Invoice { hrp, data })
748	}
749}
750
751impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool>
752	InvoiceBuilder<tb::False, H, T, C, S, M>
753{
754	/// Set the description. This function is only available if no description (hash) was set.
755	pub fn description(mut self, description: String) -> InvoiceBuilder<tb::True, H, T, C, S, M> {
756		match Description::new(description) {
757			Ok(d) => self.tagged_fields.push(TaggedField::Description(d)),
758			Err(e) => self.error = Some(e),
759		}
760		self.set_flags()
761	}
762
763	/// Set the description hash. This function is only available if no description (hash) was set.
764	pub fn description_hash(
765		mut self, description_hash: sha256::Hash,
766	) -> InvoiceBuilder<tb::True, H, T, C, S, M> {
767		self.tagged_fields.push(TaggedField::DescriptionHash(Sha256(description_hash)));
768		self.set_flags()
769	}
770
771	/// Set the description or description hash. This function is only available if no description (hash) was set.
772	pub fn invoice_description(
773		self, description: Bolt11InvoiceDescription,
774	) -> InvoiceBuilder<tb::True, H, T, C, S, M> {
775		match description {
776			Bolt11InvoiceDescription::Direct(desc) => self.description(desc.0 .0),
777			Bolt11InvoiceDescription::Hash(hash) => self.description_hash(hash.0),
778		}
779	}
780}
781
782impl<D: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool>
783	InvoiceBuilder<D, tb::False, T, C, S, M>
784{
785	/// Set the payment hash. This function is only available if no payment hash was set.
786	pub fn payment_hash(mut self, hash: sha256::Hash) -> InvoiceBuilder<D, tb::True, T, C, S, M> {
787		self.tagged_fields.push(TaggedField::PaymentHash(Sha256(hash)));
788		self.set_flags()
789	}
790}
791
792impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool>
793	InvoiceBuilder<D, H, tb::False, C, S, M>
794{
795	/// Sets the timestamp to a specific [`SystemTime`].
796	#[cfg(feature = "std")]
797	pub fn timestamp(mut self, time: SystemTime) -> InvoiceBuilder<D, H, tb::True, C, S, M> {
798		match PositiveTimestamp::from_system_time(time) {
799			Ok(t) => self.timestamp = Some(t),
800			Err(e) => self.error = Some(e),
801		}
802
803		self.set_flags()
804	}
805
806	/// Sets the timestamp to a duration since the Unix epoch, dropping the subsecond part (which
807	/// is not representable in BOLT 11 invoices).
808	pub fn duration_since_epoch(
809		mut self, time: Duration,
810	) -> InvoiceBuilder<D, H, tb::True, C, S, M> {
811		match PositiveTimestamp::from_duration_since_epoch(time) {
812			Ok(t) => self.timestamp = Some(t),
813			Err(e) => self.error = Some(e),
814		}
815
816		self.set_flags()
817	}
818
819	/// Sets the timestamp to the current system time.
820	#[cfg(feature = "std")]
821	pub fn current_timestamp(mut self) -> InvoiceBuilder<D, H, tb::True, C, S, M> {
822		let now = PositiveTimestamp::from_system_time(SystemTime::now());
823		self.timestamp = Some(now.expect("for the foreseeable future this shouldn't happen"));
824		self.set_flags()
825	}
826}
827
828impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, S: tb::Bool, M: tb::Bool>
829	InvoiceBuilder<D, H, T, tb::False, S, M>
830{
831	/// Sets `min_final_cltv_expiry_delta`.
832	pub fn min_final_cltv_expiry_delta(
833		mut self, min_final_cltv_expiry_delta: u64,
834	) -> InvoiceBuilder<D, H, T, tb::True, S, M> {
835		self.tagged_fields.push(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta(
836			min_final_cltv_expiry_delta,
837		)));
838		self.set_flags()
839	}
840}
841
842impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, M: tb::Bool>
843	InvoiceBuilder<D, H, T, C, tb::False, M>
844{
845	/// Sets the payment secret and relevant features.
846	pub fn payment_secret(
847		mut self, payment_secret: PaymentSecret,
848	) -> InvoiceBuilder<D, H, T, C, tb::True, M> {
849		let mut found_features = false;
850		for field in self.tagged_fields.iter_mut() {
851			if let TaggedField::Features(f) = field {
852				found_features = true;
853				f.set_variable_length_onion_required();
854				f.set_payment_secret_required();
855			}
856		}
857		self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret));
858		if !found_features {
859			let mut features = Bolt11InvoiceFeatures::empty();
860			features.set_variable_length_onion_required();
861			features.set_payment_secret_required();
862			self.tagged_fields.push(TaggedField::Features(features));
863		}
864		self.set_flags()
865	}
866}
867
868impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool>
869	InvoiceBuilder<D, H, T, C, S, tb::False>
870{
871	/// Sets the payment metadata.
872	///
873	/// By default features are set to *optionally* allow the sender to include the payment metadata.
874	/// If you wish to require that the sender include the metadata (and fail to parse the invoice if
875	/// they don't support payment metadata fields), you need to call
876	/// [`InvoiceBuilder::require_payment_metadata`] after this.
877	pub fn payment_metadata(
878		mut self, payment_metadata: Vec<u8>,
879	) -> InvoiceBuilder<D, H, T, C, S, tb::True> {
880		self.tagged_fields.push(TaggedField::PaymentMetadata(payment_metadata));
881		let mut found_features = false;
882		for field in self.tagged_fields.iter_mut() {
883			if let TaggedField::Features(f) = field {
884				found_features = true;
885				f.set_payment_metadata_optional();
886			}
887		}
888		if !found_features {
889			let mut features = Bolt11InvoiceFeatures::empty();
890			features.set_payment_metadata_optional();
891			self.tagged_fields.push(TaggedField::Features(features));
892		}
893		self.set_flags()
894	}
895}
896
897impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool>
898	InvoiceBuilder<D, H, T, C, S, tb::True>
899{
900	/// Sets forwarding of payment metadata as required. A reader of the invoice which does not
901	/// support sending payment metadata will fail to read the invoice.
902	pub fn require_payment_metadata(mut self) -> InvoiceBuilder<D, H, T, C, S, tb::True> {
903		for field in self.tagged_fields.iter_mut() {
904			if let TaggedField::Features(f) = field {
905				f.set_payment_metadata_required();
906			}
907		}
908		self
909	}
910}
911
912impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, M: tb::Bool>
913	InvoiceBuilder<D, H, T, C, tb::True, M>
914{
915	/// Sets the `basic_mpp` feature as optional.
916	pub fn basic_mpp(mut self) -> Self {
917		for field in self.tagged_fields.iter_mut() {
918			if let TaggedField::Features(f) = field {
919				f.set_basic_mpp_optional();
920			}
921		}
922		self
923	}
924}
925
926impl<M: tb::Bool> InvoiceBuilder<tb::True, tb::True, tb::True, tb::True, tb::True, M> {
927	/// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
928	/// and MUST produce a recoverable signature valid for the given hash and if applicable also for
929	/// the included payee public key.
930	pub fn build_signed<F>(self, sign_function: F) -> Result<Bolt11Invoice, CreationError>
931	where
932		F: FnOnce(&Message) -> RecoverableSignature,
933	{
934		let invoice = self.try_build_signed::<_, ()>(|hash| Ok(sign_function(hash)));
935
936		match invoice {
937			Ok(i) => Ok(i),
938			Err(SignOrCreationError::CreationError(e)) => Err(e),
939			Err(SignOrCreationError::SignError(())) => unreachable!(),
940		}
941	}
942
943	/// Builds and signs an invoice using the supplied `sign_function`. This function MAY fail with
944	/// an error of type `E` and MUST produce a recoverable signature valid for the given hash and
945	/// if applicable also for the included payee public key.
946	pub fn try_build_signed<F, E>(
947		self, sign_function: F,
948	) -> Result<Bolt11Invoice, SignOrCreationError<E>>
949	where
950		F: FnOnce(&Message) -> Result<RecoverableSignature, E>,
951	{
952		let raw = match self.build_raw() {
953			Ok(r) => r,
954			Err(e) => return Err(SignOrCreationError::CreationError(e)),
955		};
956
957		let signed = match raw.sign(sign_function) {
958			Ok(s) => s,
959			Err(e) => return Err(SignOrCreationError::SignError(e)),
960		};
961
962		let invoice = Bolt11Invoice { signed_invoice: signed };
963
964		invoice.check_field_counts().expect("should be ensured by type signature of builder");
965		invoice.check_feature_bits().expect("should be ensured by type signature of builder");
966		invoice.check_amount().expect("should be ensured by type signature of builder");
967
968		Ok(invoice)
969	}
970}
971
972impl SignedRawBolt11Invoice {
973	/// Disassembles the `SignedRawBolt11Invoice` into its three parts:
974	///  1. raw invoice
975	///  2. hash of the raw invoice
976	///  3. signature
977	pub fn into_parts(self) -> (RawBolt11Invoice, [u8; 32], Bolt11InvoiceSignature) {
978		(self.raw_invoice, self.hash, self.signature)
979	}
980
981	/// The [`RawBolt11Invoice`] which was signed.
982	pub fn raw_invoice(&self) -> &RawBolt11Invoice {
983		&self.raw_invoice
984	}
985
986	/// The hash of the [`RawBolt11Invoice`] that was signed.
987	pub fn signable_hash(&self) -> &[u8; 32] {
988		&self.hash
989	}
990
991	/// Signature for the invoice.
992	pub fn signature(&self) -> &Bolt11InvoiceSignature {
993		&self.signature
994	}
995
996	/// Recovers the public key used for signing the invoice from the recoverable signature.
997	pub fn recover_payee_pub_key(&self) -> Result<PayeePubKey, bitcoin::secp256k1::Error> {
998		let hash = Message::from_digest(self.hash);
999
1000		Ok(PayeePubKey(Secp256k1::new().recover_ecdsa(&hash, &self.signature)?))
1001	}
1002
1003	/// Checks if the signature is valid for the included payee public key or if none exists if it's
1004	/// valid for the recovered signature (which should always be true?).
1005	pub fn check_signature(&self) -> bool {
1006		let included_pub_key = self.raw_invoice.payee_pub_key();
1007
1008		let mut recovered_pub_key = Option::None;
1009		if recovered_pub_key.is_none() {
1010			let recovered = match self.recover_payee_pub_key() {
1011				Ok(pk) => pk,
1012				Err(_) => return false,
1013			};
1014			recovered_pub_key = Some(recovered);
1015		}
1016
1017		let pub_key =
1018			included_pub_key.or(recovered_pub_key.as_ref()).expect("One is always present");
1019
1020		let hash = Message::from_digest(self.hash);
1021
1022		let secp_context = Secp256k1::new();
1023		let verification_result =
1024			secp_context.verify_ecdsa(&hash, &self.signature.to_standard(), pub_key);
1025
1026		match verification_result {
1027			Ok(()) => true,
1028			Err(_) => false,
1029		}
1030	}
1031}
1032
1033/// Finds the first element of an enum stream of a given variant and extracts one member of the
1034/// variant. If no element was found `None` gets returned.
1035///
1036/// The following example would extract the first B.
1037///
1038/// ```ignore
1039/// enum Enum {
1040/// 	A(u8),
1041/// 	B(u16)
1042/// }
1043///
1044/// let elements = vec![Enum::A(1), Enum::A(2), Enum::B(3), Enum::A(4)];
1045///
1046/// assert_eq!(find_extract!(elements.iter(), Enum::B(x), x), Some(3u16));
1047/// ```
1048macro_rules! find_extract {
1049	($iter:expr, $enm:pat, $enm_var:ident) => {
1050		find_all_extract!($iter, $enm, $enm_var).next()
1051	};
1052}
1053
1054/// Finds the all elements of an enum stream of a given variant and extracts one member of the
1055/// variant through an iterator.
1056///
1057/// The following example would extract all A.
1058///
1059/// ```ignore
1060/// enum Enum {
1061/// 	A(u8),
1062/// 	B(u16)
1063/// }
1064///
1065/// let elements = vec![Enum::A(1), Enum::A(2), Enum::B(3), Enum::A(4)];
1066///
1067/// assert_eq!(
1068/// 	find_all_extract!(elements.iter(), Enum::A(x), x).collect::<Vec<u8>>(),
1069/// 	vec![1u8, 2u8, 4u8]
1070/// );
1071/// ```
1072macro_rules! find_all_extract {
1073	($iter:expr, $enm:pat, $enm_var:ident) => {
1074		$iter.filter_map(|tf| match *tf {
1075			$enm => Some($enm_var),
1076			_ => None,
1077		})
1078	};
1079}
1080
1081#[allow(missing_docs)]
1082impl RawBolt11Invoice {
1083	/// Hash the HRP (as bytes) and signatureless data part (as Fe32 iterator)
1084	fn hash_from_parts<'s>(
1085		hrp_bytes: &[u8], data_without_signature: Box<dyn Iterator<Item = Fe32> + 's>,
1086	) -> [u8; 32] {
1087		use crate::bech32::Fe32IterExt;
1088		use bitcoin::hashes::HashEngine;
1089
1090		let mut data_part = data_without_signature.collect::<Vec<Fe32>>();
1091
1092		// Need to pad before from_base32 conversion
1093		let overhang = (data_part.len() * 5) % 8;
1094		if overhang > 0 {
1095			// add padding if data does not end at a byte boundary
1096			data_part.push(Fe32::try_from(0).unwrap());
1097
1098			// if overhang is in (1..3) we need to add Fe32(0) padding two times
1099			if overhang < 3 {
1100				data_part.push(Fe32::try_from(0).unwrap());
1101			}
1102		}
1103
1104		// Hash bytes and data part sequentially
1105		let mut engine = sha256::Hash::engine();
1106		engine.input(hrp_bytes);
1107		// Iterate over data
1108		// Note: if it was not for padding, this could go on the supplied original iterator
1109		//  (see https://github.com/rust-bitcoin/rust-bech32/issues/198)
1110		data_part.into_iter().fes_to_bytes().for_each(|v| engine.input(&[v]));
1111		let raw_hash = sha256::Hash::from_engine(engine);
1112
1113		let mut hash: [u8; 32] = Default::default();
1114		hash.copy_from_slice(raw_hash.as_ref());
1115		hash
1116	}
1117
1118	/// Calculate the hash of the encoded `RawBolt11Invoice` which should be signed.
1119	pub fn signable_hash(&self) -> [u8; 32] {
1120		Self::hash_from_parts(self.hrp.to_string().as_bytes(), self.data.fe_iter())
1121	}
1122
1123	/// Signs the invoice using the supplied `sign_method`. This function MAY fail with an error of
1124	/// type `E`. Since the signature of a [`SignedRawBolt11Invoice`] is not required to be valid there
1125	/// are no constraints regarding the validity of the produced signature.
1126	///
1127	/// This is not exported to bindings users as we don't currently support passing function pointers into methods
1128	/// explicitly.
1129	pub fn sign<F, E>(self, sign_method: F) -> Result<SignedRawBolt11Invoice, E>
1130	where
1131		F: FnOnce(&Message) -> Result<RecoverableSignature, E>,
1132	{
1133		let raw_hash = self.signable_hash();
1134		let hash = Message::from_digest(raw_hash);
1135		let signature = sign_method(&hash)?;
1136
1137		Ok(SignedRawBolt11Invoice {
1138			raw_invoice: self,
1139			hash: raw_hash,
1140			signature: Bolt11InvoiceSignature(signature),
1141		})
1142	}
1143
1144	/// Returns an iterator over all tagged fields with known semantics.
1145	///
1146	/// This is not exported to bindings users as there is not yet a manual mapping for a FilterMap
1147	pub fn known_tagged_fields(
1148		&self,
1149	) -> FilterMap<Iter<RawTaggedField>, fn(&RawTaggedField) -> Option<&TaggedField>> {
1150		// For 1.14.0 compatibility: closures' types can't be written an fn()->() in the
1151		// function's type signature.
1152		// TODO: refactor once impl Trait is available
1153		fn match_raw(raw: &RawTaggedField) -> Option<&TaggedField> {
1154			match *raw {
1155				RawTaggedField::KnownSemantics(ref tf) => Some(tf),
1156				_ => None,
1157			}
1158		}
1159
1160		self.data.tagged_fields.iter().filter_map(match_raw)
1161	}
1162
1163	pub fn payment_hash(&self) -> Option<&Sha256> {
1164		find_extract!(self.known_tagged_fields(), TaggedField::PaymentHash(ref x), x)
1165	}
1166
1167	pub fn description(&self) -> Option<&Description> {
1168		find_extract!(self.known_tagged_fields(), TaggedField::Description(ref x), x)
1169	}
1170
1171	pub fn payee_pub_key(&self) -> Option<&PayeePubKey> {
1172		find_extract!(self.known_tagged_fields(), TaggedField::PayeePubKey(ref x), x)
1173	}
1174
1175	pub fn description_hash(&self) -> Option<&Sha256> {
1176		find_extract!(self.known_tagged_fields(), TaggedField::DescriptionHash(ref x), x)
1177	}
1178
1179	pub fn expiry_time(&self) -> Option<&ExpiryTime> {
1180		find_extract!(self.known_tagged_fields(), TaggedField::ExpiryTime(ref x), x)
1181	}
1182
1183	pub fn min_final_cltv_expiry_delta(&self) -> Option<&MinFinalCltvExpiryDelta> {
1184		find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiryDelta(ref x), x)
1185	}
1186
1187	pub fn payment_secret(&self) -> Option<&PaymentSecret> {
1188		find_extract!(self.known_tagged_fields(), TaggedField::PaymentSecret(ref x), x)
1189	}
1190
1191	pub fn payment_metadata(&self) -> Option<&Vec<u8>> {
1192		find_extract!(self.known_tagged_fields(), TaggedField::PaymentMetadata(ref x), x)
1193	}
1194
1195	pub fn features(&self) -> Option<&Bolt11InvoiceFeatures> {
1196		find_extract!(self.known_tagged_fields(), TaggedField::Features(ref x), x)
1197	}
1198
1199	/// This is not exported to bindings users as we don't support Vec<&NonOpaqueType>
1200	pub fn fallbacks(&self) -> Vec<&Fallback> {
1201		find_all_extract!(self.known_tagged_fields(), TaggedField::Fallback(ref x), x).collect()
1202	}
1203
1204	pub fn private_routes(&self) -> Vec<&PrivateRoute> {
1205		find_all_extract!(self.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x).collect()
1206	}
1207
1208	/// Returns `None` if no amount is set or on overflow.
1209	pub fn amount_pico_btc(&self) -> Option<u64> {
1210		self.hrp.raw_amount.and_then(|v| {
1211			v.checked_mul(
1212				self.hrp.si_prefix.as_ref().map_or(1_000_000_000_000, |si| si.multiplier()),
1213			)
1214		})
1215	}
1216
1217	pub fn currency(&self) -> Currency {
1218		self.hrp.currency.clone()
1219	}
1220
1221	/// Convert to HRP prefix and Fe32 encoded data part.
1222	/// Can be used to transmit unsigned invoices for remote signing.
1223	pub fn to_raw(&self) -> (String, Vec<Fe32>) {
1224		(self.hrp.to_string(), self.data.fe_iter().collect())
1225	}
1226
1227	/// Convert from HRP prefix and Fe32 encoded data part.
1228	/// Can be used to receive unsigned invoices for remote signing.
1229	pub fn from_raw(hrp: &str, data: &[Fe32]) -> Result<Self, Bolt11ParseError> {
1230		let raw_hrp: RawHrp = RawHrp::from_str(hrp)?;
1231		let data_part = RawDataPart::from_base32(data)?;
1232
1233		Ok(Self { hrp: raw_hrp, data: data_part })
1234	}
1235}
1236
1237impl PositiveTimestamp {
1238	/// Creates a `PositiveTimestamp` from a Unix timestamp in the range `0..=MAX_TIMESTAMP`.
1239	///
1240	/// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
1241	pub fn from_unix_timestamp(unix_seconds: u64) -> Result<Self, CreationError> {
1242		if unix_seconds <= MAX_TIMESTAMP {
1243			Ok(Self(Duration::from_secs(unix_seconds)))
1244		} else {
1245			Err(CreationError::TimestampOutOfBounds)
1246		}
1247	}
1248
1249	/// Creates a `PositiveTimestamp` from a [`SystemTime`] with a corresponding Unix timestamp in
1250	/// the range `0..=MAX_TIMESTAMP`.
1251	///
1252	/// Note that the subsecond part is dropped as it is not representable in BOLT 11 invoices.
1253	///
1254	/// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
1255	#[cfg(feature = "std")]
1256	pub fn from_system_time(time: SystemTime) -> Result<Self, CreationError> {
1257		time.duration_since(SystemTime::UNIX_EPOCH)
1258			.map(Self::from_duration_since_epoch)
1259			.unwrap_or(Err(CreationError::TimestampOutOfBounds))
1260	}
1261
1262	/// Creates a `PositiveTimestamp` from a [`Duration`] since the Unix epoch in the range
1263	/// `0..=MAX_TIMESTAMP`.
1264	///
1265	/// Note that the subsecond part is dropped as it is not representable in BOLT 11 invoices.
1266	///
1267	/// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
1268	pub fn from_duration_since_epoch(duration: Duration) -> Result<Self, CreationError> {
1269		Self::from_unix_timestamp(duration.as_secs())
1270	}
1271
1272	/// Returns the Unix timestamp representing the stored time
1273	pub fn as_unix_timestamp(&self) -> u64 {
1274		self.0.as_secs()
1275	}
1276
1277	/// Returns the duration of the stored time since the Unix epoch
1278	pub fn as_duration_since_epoch(&self) -> Duration {
1279		self.0
1280	}
1281
1282	/// Returns the [`SystemTime`] representing the stored time
1283	#[cfg(feature = "std")]
1284	pub fn as_time(&self) -> SystemTime {
1285		SystemTime::UNIX_EPOCH + self.0
1286	}
1287}
1288
1289impl From<PositiveTimestamp> for Duration {
1290	fn from(val: PositiveTimestamp) -> Self {
1291		val.0
1292	}
1293}
1294
1295#[cfg(feature = "std")]
1296impl From<PositiveTimestamp> for SystemTime {
1297	fn from(val: PositiveTimestamp) -> Self {
1298		SystemTime::UNIX_EPOCH + val.0
1299	}
1300}
1301
1302impl Bolt11Invoice {
1303	/// The hash of the [`RawBolt11Invoice`] that was signed.
1304	pub fn signable_hash(&self) -> [u8; 32] {
1305		self.signed_invoice.hash
1306	}
1307
1308	/// Transform the `Bolt11Invoice` into its unchecked version.
1309	pub fn into_signed_raw(self) -> SignedRawBolt11Invoice {
1310		self.signed_invoice
1311	}
1312
1313	/// Check that all mandatory fields are present
1314	fn check_field_counts(&self) -> Result<(), Bolt11SemanticError> {
1315		// "A writer MUST include exactly one p field […]."
1316		let payment_hash_cnt = self
1317			.tagged_fields()
1318			.filter(|&tf| match *tf {
1319				TaggedField::PaymentHash(_) => true,
1320				_ => false,
1321			})
1322			.count();
1323		if payment_hash_cnt < 1 {
1324			return Err(Bolt11SemanticError::NoPaymentHash);
1325		} else if payment_hash_cnt > 1 {
1326			return Err(Bolt11SemanticError::MultiplePaymentHashes);
1327		}
1328
1329		// "A writer MUST include either exactly one d or exactly one h field."
1330		let description_cnt = self
1331			.tagged_fields()
1332			.filter(|&tf| match *tf {
1333				TaggedField::Description(_) | TaggedField::DescriptionHash(_) => true,
1334				_ => false,
1335			})
1336			.count();
1337		if description_cnt < 1 {
1338			return Err(Bolt11SemanticError::NoDescription);
1339		} else if description_cnt > 1 {
1340			return Err(Bolt11SemanticError::MultipleDescriptions);
1341		}
1342
1343		self.check_payment_secret()?;
1344
1345		Ok(())
1346	}
1347
1348	/// Checks that there is exactly one payment secret field
1349	fn check_payment_secret(&self) -> Result<(), Bolt11SemanticError> {
1350		// "A writer MUST include exactly one `s` field."
1351		let payment_secret_count = self
1352			.tagged_fields()
1353			.filter(|&tf| match *tf {
1354				TaggedField::PaymentSecret(_) => true,
1355				_ => false,
1356			})
1357			.count();
1358		if payment_secret_count < 1 {
1359			return Err(Bolt11SemanticError::NoPaymentSecret);
1360		} else if payment_secret_count > 1 {
1361			return Err(Bolt11SemanticError::MultiplePaymentSecrets);
1362		}
1363
1364		Ok(())
1365	}
1366
1367	/// Check that amount is a whole number of millisatoshis
1368	fn check_amount(&self) -> Result<(), Bolt11SemanticError> {
1369		if let Some(amount_pico_btc) = self.amount_pico_btc() {
1370			if amount_pico_btc % 10 != 0 {
1371				return Err(Bolt11SemanticError::ImpreciseAmount);
1372			}
1373		}
1374		Ok(())
1375	}
1376
1377	/// Check that feature bits are set as required
1378	fn check_feature_bits(&self) -> Result<(), Bolt11SemanticError> {
1379		self.check_payment_secret()?;
1380
1381		// "A writer MUST set an s field if and only if the payment_secret feature is set."
1382		// (this requirement has been since removed, and we now require the payment secret
1383		// feature bit always).
1384		let features = self.tagged_fields().find(|&tf| match *tf {
1385			TaggedField::Features(_) => true,
1386			_ => false,
1387		});
1388		match features {
1389			None => Err(Bolt11SemanticError::InvalidFeatures),
1390			Some(TaggedField::Features(features)) => {
1391				if features.requires_unknown_bits() {
1392					Err(Bolt11SemanticError::InvalidFeatures)
1393				} else if !features.supports_payment_secret() {
1394					Err(Bolt11SemanticError::InvalidFeatures)
1395				} else {
1396					Ok(())
1397				}
1398			},
1399			Some(_) => unreachable!(),
1400		}
1401	}
1402
1403	/// Check that the invoice is signed correctly and that key recovery works
1404	pub fn check_signature(&self) -> Result<(), Bolt11SemanticError> {
1405		match self.signed_invoice.recover_payee_pub_key() {
1406			Err(bitcoin::secp256k1::Error::InvalidRecoveryId) => {
1407				return Err(Bolt11SemanticError::InvalidRecoveryId)
1408			},
1409			Err(bitcoin::secp256k1::Error::InvalidSignature) => {
1410				return Err(Bolt11SemanticError::InvalidSignature)
1411			},
1412			Err(e) => panic!("no other error may occur, got {:?}", e),
1413			Ok(_) => {},
1414		}
1415
1416		if !self.signed_invoice.check_signature() {
1417			return Err(Bolt11SemanticError::InvalidSignature);
1418		}
1419
1420		Ok(())
1421	}
1422
1423	/// Constructs a `Bolt11Invoice` from a [`SignedRawBolt11Invoice`] by checking all its invariants.
1424	/// ```
1425	/// use lightning_invoice::*;
1426	///
1427	/// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
1428	/// h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
1429	/// 5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
1430	/// h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
1431	/// j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
1432	/// ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
1433	/// guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
1434	/// ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
1435	/// p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
1436	/// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
1437	/// j5r6drg6k6zcqj0fcwg";
1438	///
1439	/// let signed = invoice.parse::<SignedRawBolt11Invoice>().unwrap();
1440	///
1441	/// assert!(Bolt11Invoice::from_signed(signed).is_ok());
1442	/// ```
1443	pub fn from_signed(
1444		signed_invoice: SignedRawBolt11Invoice,
1445	) -> Result<Self, Bolt11SemanticError> {
1446		let invoice = Bolt11Invoice { signed_invoice };
1447		invoice.check_field_counts()?;
1448		invoice.check_feature_bits()?;
1449		invoice.check_signature()?;
1450		invoice.check_amount()?;
1451
1452		Ok(invoice)
1453	}
1454
1455	/// Returns the `Bolt11Invoice`'s timestamp (should equal its creation time)
1456	#[cfg(feature = "std")]
1457	pub fn timestamp(&self) -> SystemTime {
1458		self.signed_invoice.raw_invoice().data.timestamp.as_time()
1459	}
1460
1461	/// Returns the `Bolt11Invoice`'s timestamp as a duration since the Unix epoch
1462	pub fn duration_since_epoch(&self) -> Duration {
1463		self.signed_invoice.raw_invoice().data.timestamp.0
1464	}
1465
1466	/// Returns an iterator over all tagged fields of this `Bolt11Invoice`.
1467	///
1468	/// This is not exported to bindings users as there is not yet a manual mapping for a FilterMap
1469	pub fn tagged_fields(
1470		&self,
1471	) -> FilterMap<Iter<RawTaggedField>, fn(&RawTaggedField) -> Option<&TaggedField>> {
1472		self.signed_invoice.raw_invoice().known_tagged_fields()
1473	}
1474
1475	/// Returns the hash to which we will receive the preimage on completion of the payment
1476	pub fn payment_hash(&self) -> &sha256::Hash {
1477		&self.signed_invoice.payment_hash().expect("checked by constructor").0
1478	}
1479
1480	/// Return the description or a hash of it for longer ones
1481	///
1482	/// This is not exported to bindings users because we don't yet export Bolt11InvoiceDescription
1483	pub fn description(&self) -> Bolt11InvoiceDescriptionRef {
1484		if let Some(direct) = self.signed_invoice.description() {
1485			return Bolt11InvoiceDescriptionRef::Direct(direct);
1486		} else if let Some(hash) = self.signed_invoice.description_hash() {
1487			return Bolt11InvoiceDescriptionRef::Hash(hash);
1488		}
1489		unreachable!("ensured by constructor");
1490	}
1491
1492	/// Get the payee's public key if one was included in the invoice
1493	pub fn payee_pub_key(&self) -> Option<&PublicKey> {
1494		self.signed_invoice.payee_pub_key().map(|x| &x.0)
1495	}
1496
1497	/// Get the payment secret if one was included in the invoice
1498	pub fn payment_secret(&self) -> &PaymentSecret {
1499		self.signed_invoice.payment_secret().expect("was checked by constructor")
1500	}
1501
1502	/// Get the payment metadata blob if one was included in the invoice
1503	pub fn payment_metadata(&self) -> Option<&Vec<u8>> {
1504		self.signed_invoice.payment_metadata()
1505	}
1506
1507	/// Get the invoice features if they were included in the invoice
1508	pub fn features(&self) -> Option<&Bolt11InvoiceFeatures> {
1509		self.signed_invoice.features()
1510	}
1511
1512	/// Get the invoice's payee public key.
1513	///
1514	/// This uses the explicitly included payee public key, if present, otherwise it recovers the
1515	/// payee public key from the signature. Prefer [`Self::get_payee_pub_key`] for clarity.
1516	pub fn recover_payee_pub_key(&self) -> PublicKey {
1517		self.get_payee_pub_key()
1518	}
1519
1520	/// Get the invoice's payee public key, preferring an explicitly included payee public key and
1521	/// falling back to recovering the key from the signature.
1522	pub fn get_payee_pub_key(&self) -> PublicKey {
1523		match self.payee_pub_key() {
1524			Some(pk) => *pk,
1525			None => {
1526				self.signed_invoice.recover_payee_pub_key().expect("was checked by constructor").0
1527			},
1528		}
1529	}
1530
1531	/// Returns the Duration since the Unix epoch at which the invoice expires.
1532	/// Returning None if overflow occurred.
1533	pub fn expires_at(&self) -> Option<Duration> {
1534		self.duration_since_epoch().checked_add(self.expiry_time())
1535	}
1536
1537	/// Returns the invoice's expiry time, if present, otherwise [`DEFAULT_EXPIRY_TIME`].
1538	pub fn expiry_time(&self) -> Duration {
1539		self.signed_invoice
1540			.expiry_time()
1541			.map(|x| x.0)
1542			.unwrap_or(Duration::from_secs(DEFAULT_EXPIRY_TIME))
1543	}
1544
1545	/// Returns whether the invoice has expired.
1546	#[cfg(feature = "std")]
1547	pub fn is_expired(&self) -> bool {
1548		Self::is_expired_from_epoch(&self.timestamp(), self.expiry_time())
1549	}
1550
1551	/// Returns whether the expiry time from the given epoch has passed.
1552	#[cfg(feature = "std")]
1553	pub(crate) fn is_expired_from_epoch(epoch: &SystemTime, expiry_time: Duration) -> bool {
1554		match epoch.elapsed() {
1555			Ok(elapsed) => elapsed > expiry_time,
1556			Err(_) => false,
1557		}
1558	}
1559
1560	/// Returns the Duration remaining until the invoice expires.
1561	#[cfg(feature = "std")]
1562	pub fn duration_until_expiry(&self) -> Duration {
1563		SystemTime::now()
1564			.duration_since(SystemTime::UNIX_EPOCH)
1565			.map(|now| self.expiration_remaining_from_epoch(now))
1566			.unwrap_or(Duration::from_nanos(0))
1567	}
1568
1569	/// Returns the Duration remaining until the invoice expires given the current time.
1570	/// `time` is the timestamp as a duration since the Unix epoch.
1571	pub fn expiration_remaining_from_epoch(&self, time: Duration) -> Duration {
1572		self.expires_at().map(|x| x.checked_sub(time)).flatten().unwrap_or(Duration::from_nanos(0))
1573	}
1574
1575	/// Returns whether the expiry time would pass at the given point in time.
1576	/// `at_time` is the timestamp as a duration since the Unix epoch.
1577	pub fn would_expire(&self, at_time: Duration) -> bool {
1578		self.duration_since_epoch()
1579			.checked_add(self.expiry_time())
1580			.unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1))
1581			< at_time
1582	}
1583
1584	/// Returns the invoice's `min_final_cltv_expiry_delta` time, if present, otherwise
1585	/// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA`].
1586	pub fn min_final_cltv_expiry_delta(&self) -> u64 {
1587		self.signed_invoice
1588			.min_final_cltv_expiry_delta()
1589			.map(|x| x.0)
1590			.unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA)
1591	}
1592
1593	/// Returns a list of all fallback addresses
1594	///
1595	/// This is not exported to bindings users as we don't support Vec<&NonOpaqueType>
1596	pub fn fallbacks(&self) -> Vec<&Fallback> {
1597		self.signed_invoice.fallbacks()
1598	}
1599
1600	/// Returns a list of all fallback addresses as [`Address`]es
1601	pub fn fallback_addresses(&self) -> Vec<Address> {
1602		let filter_fn = |fallback: &&Fallback| {
1603			let address = match fallback {
1604				Fallback::SegWitProgram { version, program } => {
1605					match WitnessProgram::new(*version, &program) {
1606						Ok(witness_program) => {
1607							Address::from_witness_program(witness_program, self.network())
1608						},
1609						Err(_) => return None,
1610					}
1611				},
1612				Fallback::PubKeyHash(pkh) => Address::p2pkh(*pkh, self.network()),
1613				Fallback::ScriptHash(sh) => Address::p2sh_from_hash(*sh, self.network()),
1614			};
1615
1616			Some(address)
1617		};
1618		self.fallbacks().iter().filter_map(filter_fn).collect()
1619	}
1620
1621	/// Returns a list of all routes included in the invoice
1622	pub fn private_routes(&self) -> Vec<&PrivateRoute> {
1623		self.signed_invoice.private_routes()
1624	}
1625
1626	/// Returns a list of all routes included in the invoice as the underlying hints
1627	pub fn route_hints(&self) -> Vec<RouteHint> {
1628		find_all_extract!(
1629			self.signed_invoice.known_tagged_fields(),
1630			TaggedField::PrivateRoute(ref x),
1631			x
1632		)
1633		.map(|route| (**route).clone())
1634		.collect()
1635	}
1636
1637	/// Returns the currency for which the invoice was issued
1638	pub fn currency(&self) -> Currency {
1639		self.signed_invoice.currency()
1640	}
1641
1642	/// Returns the network for which the invoice was issued
1643	///
1644	/// This is not exported to bindings users, see [`Self::currency`] instead.
1645	pub fn network(&self) -> Network {
1646		self.signed_invoice.currency().into()
1647	}
1648
1649	/// Returns the amount if specified in the invoice as millisatoshis.
1650	pub fn amount_milli_satoshis(&self) -> Option<u64> {
1651		self.signed_invoice.amount_pico_btc().map(|v| v / 10)
1652	}
1653
1654	/// Returns the amount if specified in the invoice as pico BTC.
1655	fn amount_pico_btc(&self) -> Option<u64> {
1656		self.signed_invoice.amount_pico_btc()
1657	}
1658}
1659
1660impl From<TaggedField> for RawTaggedField {
1661	fn from(tf: TaggedField) -> Self {
1662		RawTaggedField::KnownSemantics(tf)
1663	}
1664}
1665
1666impl TaggedField {
1667	/// Numeric representation of the field's tag
1668	pub fn tag(&self) -> Fe32 {
1669		let tag = match *self {
1670			TaggedField::PaymentHash(_) => constants::TAG_PAYMENT_HASH,
1671			TaggedField::Description(_) => constants::TAG_DESCRIPTION,
1672			TaggedField::PayeePubKey(_) => constants::TAG_PAYEE_PUB_KEY,
1673			TaggedField::DescriptionHash(_) => constants::TAG_DESCRIPTION_HASH,
1674			TaggedField::ExpiryTime(_) => constants::TAG_EXPIRY_TIME,
1675			TaggedField::MinFinalCltvExpiryDelta(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA,
1676			TaggedField::Fallback(_) => constants::TAG_FALLBACK,
1677			TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE,
1678			TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
1679			TaggedField::PaymentMetadata(_) => constants::TAG_PAYMENT_METADATA,
1680			TaggedField::Features(_) => constants::TAG_FEATURES,
1681		};
1682
1683		Fe32::try_from(tag).expect("all tags defined are <32")
1684	}
1685}
1686
1687impl Description {
1688	/// Creates a new `Description` if `description` is at most 1023 * 5 bits (i.e., 639 bytes)
1689	/// long, and returns [`CreationError::DescriptionTooLong`] otherwise.
1690	///
1691	/// Please note that single characters may use more than one byte due to UTF8 encoding.
1692	pub fn new(description: String) -> Result<Description, CreationError> {
1693		if description.len() > 639 {
1694			Err(CreationError::DescriptionTooLong)
1695		} else {
1696			Ok(Description(UntrustedString(description)))
1697		}
1698	}
1699
1700	/// Creates an empty `Description`.
1701	pub fn empty() -> Self {
1702		Description(UntrustedString(String::new()))
1703	}
1704
1705	/// Returns the underlying description [`UntrustedString`]
1706	pub fn into_inner(self) -> UntrustedString {
1707		self.0
1708	}
1709
1710	/// Get a reference to the underlying description [`UntrustedString`]
1711	pub fn as_inner(&self) -> &UntrustedString {
1712		&self.0
1713	}
1714}
1715
1716impl Display for Description {
1717	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1718		write!(f, "{}", self.0)
1719	}
1720}
1721
1722impl From<PublicKey> for PayeePubKey {
1723	fn from(pk: PublicKey) -> Self {
1724		PayeePubKey(pk)
1725	}
1726}
1727
1728impl Deref for PayeePubKey {
1729	type Target = PublicKey;
1730
1731	fn deref(&self) -> &PublicKey {
1732		&self.0
1733	}
1734}
1735
1736impl ExpiryTime {
1737	/// Construct an `ExpiryTime` from seconds.
1738	pub fn from_seconds(seconds: u64) -> ExpiryTime {
1739		ExpiryTime(Duration::from_secs(seconds))
1740	}
1741
1742	/// Construct an `ExpiryTime` from a [`Duration`], dropping the sub-second part.
1743	pub fn from_duration(duration: Duration) -> ExpiryTime {
1744		Self::from_seconds(duration.as_secs())
1745	}
1746
1747	/// Returns the expiry time in seconds
1748	pub fn as_seconds(&self) -> u64 {
1749		self.0.as_secs()
1750	}
1751
1752	/// Returns a reference to the underlying [`Duration`] (=expiry time)
1753	pub fn as_duration(&self) -> &Duration {
1754		&self.0
1755	}
1756}
1757
1758impl PrivateRoute {
1759	/// Creates a new (partial) route from a list of hops
1760	pub fn new(hops: RouteHint) -> Result<PrivateRoute, CreationError> {
1761		if hops.0.len() <= 12 {
1762			Ok(PrivateRoute(hops))
1763		} else {
1764			Err(CreationError::RouteTooLong)
1765		}
1766	}
1767
1768	/// Returns the underlying list of hops
1769	pub fn into_inner(self) -> RouteHint {
1770		self.0
1771	}
1772}
1773
1774impl From<PrivateRoute> for RouteHint {
1775	fn from(val: PrivateRoute) -> Self {
1776		val.into_inner()
1777	}
1778}
1779
1780impl Deref for PrivateRoute {
1781	type Target = RouteHint;
1782
1783	fn deref(&self) -> &RouteHint {
1784		&self.0
1785	}
1786}
1787
1788impl Deref for Bolt11InvoiceSignature {
1789	type Target = RecoverableSignature;
1790
1791	fn deref(&self) -> &RecoverableSignature {
1792		&self.0
1793	}
1794}
1795
1796impl Deref for SignedRawBolt11Invoice {
1797	type Target = RawBolt11Invoice;
1798
1799	fn deref(&self) -> &RawBolt11Invoice {
1800		&self.raw_invoice
1801	}
1802}
1803
1804/// Errors that may occur when constructing a new [`RawBolt11Invoice`] or [`Bolt11Invoice`]
1805#[derive(Eq, PartialEq, Debug, Clone)]
1806pub enum CreationError {
1807	/// The supplied description string was longer than 639 __bytes__ (see [`Description::new`])
1808	DescriptionTooLong,
1809
1810	/// The specified route has too many hops and can't be encoded
1811	RouteTooLong,
1812
1813	/// The Unix timestamp of the supplied date is less than zero or greater than 35-bits
1814	TimestampOutOfBounds,
1815
1816	/// The supplied millisatoshi amount was greater than the total bitcoin supply.
1817	InvalidAmount,
1818
1819	// TODO: These two errors are really errors with things in the `lightning` crate and thus
1820	// shouldn't live here.
1821	/// Route hints were required for this invoice and were missing.
1822	MissingRouteHints,
1823
1824	/// The provided `min_final_cltv_expiry_delta` was less than rust-lightning's minimum.
1825	MinFinalCltvExpiryDeltaTooShort,
1826}
1827
1828impl Display for CreationError {
1829	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1830		match self {
1831			CreationError::DescriptionTooLong => f.write_str("The supplied description string was longer than 639 bytes"),
1832			CreationError::RouteTooLong => f.write_str("The specified route has too many hops and can't be encoded"),
1833			CreationError::TimestampOutOfBounds => f.write_str("The Unix timestamp of the supplied date is less than zero or greater than 35-bits"),
1834			CreationError::InvalidAmount => f.write_str("The supplied millisatoshi amount was greater than the total bitcoin supply"),
1835			CreationError::MissingRouteHints => f.write_str("The invoice required route hints and they weren't provided"),
1836			CreationError::MinFinalCltvExpiryDeltaTooShort => f.write_str(
1837				"The supplied final CLTV expiry delta was less than LDK's `MIN_FINAL_CLTV_EXPIRY_DELTA`"),
1838		}
1839	}
1840}
1841
1842#[cfg(feature = "std")]
1843impl std::error::Error for CreationError {}
1844
1845/// Errors that may occur when converting a [`RawBolt11Invoice`] to a [`Bolt11Invoice`]. They relate to
1846/// the requirements sections in BOLT #11
1847#[derive(Eq, PartialEq, Debug, Clone)]
1848pub enum Bolt11SemanticError {
1849	/// The invoice is missing the mandatory payment hash
1850	NoPaymentHash,
1851
1852	/// The invoice has multiple payment hashes which isn't allowed
1853	MultiplePaymentHashes,
1854
1855	/// No description or description hash are part of the invoice
1856	NoDescription,
1857
1858	/// The invoice contains multiple descriptions and/or description hashes which isn't allowed
1859	MultipleDescriptions,
1860
1861	/// The invoice is missing the mandatory payment secret, which all modern lightning nodes
1862	/// should provide.
1863	NoPaymentSecret,
1864
1865	/// The invoice contains multiple payment secrets
1866	MultiplePaymentSecrets,
1867
1868	/// The invoice's features are invalid
1869	InvalidFeatures,
1870
1871	/// The recovery id doesn't fit the signature/pub key
1872	InvalidRecoveryId,
1873
1874	/// The invoice's signature is invalid
1875	InvalidSignature,
1876
1877	/// The invoice's amount was not a whole number of millisatoshis
1878	ImpreciseAmount,
1879}
1880
1881impl Display for Bolt11SemanticError {
1882	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1883		match self {
1884			Bolt11SemanticError::NoPaymentHash => f.write_str("The invoice is missing the mandatory payment hash"),
1885			Bolt11SemanticError::MultiplePaymentHashes => f.write_str("The invoice has multiple payment hashes which isn't allowed"),
1886			Bolt11SemanticError::NoDescription => f.write_str("No description or description hash are part of the invoice"),
1887			Bolt11SemanticError::MultipleDescriptions => f.write_str("The invoice contains multiple descriptions and/or description hashes which isn't allowed"),
1888			Bolt11SemanticError::NoPaymentSecret => f.write_str("The invoice is missing the mandatory payment secret"),
1889			Bolt11SemanticError::MultiplePaymentSecrets => f.write_str("The invoice contains multiple payment secrets"),
1890			Bolt11SemanticError::InvalidFeatures => f.write_str("The invoice's features are invalid"),
1891			Bolt11SemanticError::InvalidRecoveryId => f.write_str("The recovery id doesn't fit the signature/pub key"),
1892			Bolt11SemanticError::InvalidSignature => f.write_str("The invoice's signature is invalid"),
1893			Bolt11SemanticError::ImpreciseAmount => f.write_str("The invoice's amount was not a whole number of millisatoshis"),
1894		}
1895	}
1896}
1897
1898#[cfg(feature = "std")]
1899impl std::error::Error for Bolt11SemanticError {}
1900
1901/// When signing using a fallible method either an user-supplied `SignError` or a [`CreationError`]
1902/// may occur.
1903#[derive(Eq, PartialEq, Debug, Clone)]
1904pub enum SignOrCreationError<S = ()> {
1905	/// An error occurred during signing
1906	SignError(S),
1907
1908	/// An error occurred while building the transaction
1909	CreationError(CreationError),
1910}
1911
1912impl<S> Display for SignOrCreationError<S> {
1913	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1914		match self {
1915			SignOrCreationError::SignError(_) => f.write_str("An error occurred during signing"),
1916			SignOrCreationError::CreationError(err) => err.fmt(f),
1917		}
1918	}
1919}
1920
1921#[cfg(feature = "serde")]
1922impl Serialize for Bolt11Invoice {
1923	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1924	where
1925		S: Serializer,
1926	{
1927		serializer.serialize_str(self.to_string().as_str())
1928	}
1929}
1930#[cfg(feature = "serde")]
1931impl<'de> Deserialize<'de> for Bolt11Invoice {
1932	fn deserialize<D>(deserializer: D) -> Result<Bolt11Invoice, D::Error>
1933	where
1934		D: Deserializer<'de>,
1935	{
1936		let bolt11 = String::deserialize(deserializer)?
1937			.parse::<Bolt11Invoice>()
1938			.map_err(|e| D::Error::custom(format_args!("{:?}", e)))?;
1939
1940		Ok(bolt11)
1941	}
1942}
1943
1944#[cfg(test)]
1945mod test {
1946	use bitcoin::hashes::sha256;
1947	use bitcoin::ScriptBuf;
1948	use std::str::FromStr;
1949
1950	#[test]
1951	fn test_system_time_bounds_assumptions() {
1952		assert_eq!(
1953			crate::PositiveTimestamp::from_unix_timestamp(crate::MAX_TIMESTAMP + 1),
1954			Err(crate::CreationError::TimestampOutOfBounds)
1955		);
1956	}
1957
1958	#[test]
1959	fn test_calc_invoice_hash() {
1960		use crate::TaggedField::*;
1961		use crate::{Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart, RawHrp};
1962
1963		let invoice = RawBolt11Invoice {
1964			hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None },
1965			data: RawDataPart {
1966				timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1967				tagged_fields: vec![
1968					PaymentHash(crate::Sha256(
1969						sha256::Hash::from_str(
1970							"0001020304050607080900010203040506070809000102030405060708090102",
1971						)
1972						.unwrap(),
1973					))
1974					.into(),
1975					Description(
1976						crate::Description::new(
1977							"Please consider supporting this project".to_owned(),
1978						)
1979						.unwrap(),
1980					)
1981					.into(),
1982				],
1983			},
1984		};
1985
1986		let expected_hash = [
1987			0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b, 0x1d,
1988			0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, 0xb2, 0xec,
1989			0xd5, 0x18, 0xe1, 0xc9,
1990		];
1991
1992		assert_eq!(invoice.signable_hash(), expected_hash)
1993	}
1994
1995	#[test]
1996	fn test_check_signature() {
1997		use crate::TaggedField::*;
1998		use crate::{
1999			Bolt11InvoiceSignature, Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart,
2000			RawHrp, Sha256, SignedRawBolt11Invoice,
2001		};
2002		use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
2003		use bitcoin::secp256k1::Secp256k1;
2004		use bitcoin::secp256k1::{PublicKey, SecretKey};
2005
2006		let invoice =
2007			SignedRawBolt11Invoice {
2008				raw_invoice: RawBolt11Invoice {
2009					hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None },
2010					data: RawDataPart {
2011						timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
2012						tagged_fields: vec ! [
2013						PaymentHash(Sha256(sha256::Hash::from_str(
2014							"0001020304050607080900010203040506070809000102030405060708090102"
2015						).unwrap())).into(),
2016						Description(
2017							crate::Description::new(
2018								"Please consider supporting this project".to_owned()
2019							).unwrap()
2020						).into(),
2021					],
2022					},
2023				},
2024				hash: [
2025					0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b,
2026					0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d,
2027					0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9,
2028				],
2029				signature: Bolt11InvoiceSignature(
2030					RecoverableSignature::from_compact(
2031						&[
2032							0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a,
2033							0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43, 0x4e,
2034							0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f, 0x42, 0x5f,
2035							0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad, 0x0d, 0x6e, 0x35,
2036							0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9, 0xaa, 0xb1, 0x5e, 0x57,
2037							0x38, 0xb1, 0x1f, 0x12, 0x7f,
2038						],
2039						RecoveryId::from_i32(0).unwrap(),
2040					)
2041					.unwrap(),
2042				),
2043			};
2044
2045		assert!(invoice.check_signature());
2046
2047		let private_key = SecretKey::from_slice(
2048			&[
2049				0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2,
2050				0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca,
2051				0x3b, 0x2d, 0xb7, 0x34,
2052			][..],
2053		)
2054		.unwrap();
2055		let public_key = PublicKey::from_secret_key(&Secp256k1::new(), &private_key);
2056
2057		assert_eq!(invoice.recover_payee_pub_key(), Ok(crate::PayeePubKey(public_key)));
2058
2059		let (raw_invoice, _, _) = invoice.into_parts();
2060		let new_signed = raw_invoice
2061			.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
2062			.unwrap();
2063
2064		assert!(new_signed.check_signature());
2065	}
2066
2067	#[test]
2068	fn recover_payee_pub_key_uses_included_payee_pub_key() {
2069		use crate::*;
2070		use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
2071		use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
2072		use core::time::Duration;
2073
2074		let secp_ctx = Secp256k1::new();
2075		let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
2076		let public_key = PublicKey::from_secret_key(&secp_ctx, &private_key);
2077
2078		let invoice = InvoiceBuilder::new(Currency::Bitcoin)
2079			.description("Test".to_string())
2080			.payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
2081			.payment_secret(PaymentSecret([21; 32]))
2082			.payee_pub_key(public_key)
2083			.min_final_cltv_expiry_delta(144)
2084			.duration_since_epoch(Duration::from_secs(1234567))
2085			.build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &private_key))
2086			.unwrap();
2087
2088		let signed_raw = invoice.into_signed_raw();
2089		let (raw_invoice, hash, signature) = signed_raw.into_parts();
2090		let (_orig_rid, sig_bytes) = signature.0.serialize_compact();
2091		let bad_rid = RecoveryId::from_i32(2).unwrap();
2092		let bad_sig = RecoverableSignature::from_compact(&sig_bytes, bad_rid).unwrap();
2093		let bad_signed_raw = SignedRawBolt11Invoice {
2094			raw_invoice,
2095			hash,
2096			signature: Bolt11InvoiceSignature(bad_sig),
2097		};
2098		assert!(bad_signed_raw.recover_payee_pub_key().is_err());
2099		assert_eq!(Bolt11Invoice::from_signed(bad_signed_raw), Err(Bolt11SemanticError::InvalidSignature));
2100	}
2101
2102	#[test]
2103	fn test_check_feature_bits() {
2104		use crate::TaggedField::*;
2105		use crate::{
2106			Bolt11Invoice, Bolt11SemanticError, Currency, PositiveTimestamp, RawBolt11Invoice,
2107			RawDataPart, RawHrp, Sha256,
2108		};
2109		use bitcoin::secp256k1::Secp256k1;
2110		use bitcoin::secp256k1::SecretKey;
2111		use lightning_types::features::Bolt11InvoiceFeatures;
2112
2113		let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
2114		let payment_secret = lightning_types::payment::PaymentSecret([21; 32]);
2115		let invoice_template = RawBolt11Invoice {
2116			hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None },
2117			data: RawDataPart {
2118				timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
2119				tagged_fields: vec![
2120					PaymentHash(Sha256(
2121						sha256::Hash::from_str(
2122							"0001020304050607080900010203040506070809000102030405060708090102",
2123						)
2124						.unwrap(),
2125					))
2126					.into(),
2127					Description(
2128						crate::Description::new(
2129							"Please consider supporting this project".to_owned(),
2130						)
2131						.unwrap(),
2132					)
2133					.into(),
2134				],
2135			},
2136		};
2137
2138		// Missing features
2139		let invoice = {
2140			let mut invoice = invoice_template.clone();
2141			invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
2142			invoice.sign::<_, ()>(|hash| {
2143				Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
2144			})
2145		}
2146		.unwrap();
2147		assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures));
2148
2149		// Missing feature bits
2150		let invoice = {
2151			let mut invoice = invoice_template.clone();
2152			invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
2153			invoice.data.tagged_fields.push(Features(Bolt11InvoiceFeatures::empty()).into());
2154			invoice.sign::<_, ()>(|hash| {
2155				Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
2156			})
2157		}
2158		.unwrap();
2159		assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures));
2160
2161		let mut payment_secret_features = Bolt11InvoiceFeatures::empty();
2162		payment_secret_features.set_payment_secret_required();
2163
2164		// Including payment secret and feature bits
2165		let invoice = {
2166			let mut invoice = invoice_template.clone();
2167			invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
2168			invoice.data.tagged_fields.push(Features(payment_secret_features.clone()).into());
2169			invoice.sign::<_, ()>(|hash| {
2170				Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
2171			})
2172		}
2173		.unwrap();
2174		assert!(Bolt11Invoice::from_signed(invoice).is_ok());
2175
2176		// No payment secret or features
2177		let invoice = {
2178			let invoice = invoice_template.clone();
2179			invoice.sign::<_, ()>(|hash| {
2180				Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
2181			})
2182		}
2183		.unwrap();
2184		assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret));
2185
2186		// No payment secret or feature bits
2187		let invoice = {
2188			let mut invoice = invoice_template.clone();
2189			invoice.data.tagged_fields.push(Features(Bolt11InvoiceFeatures::empty()).into());
2190			invoice.sign::<_, ()>(|hash| {
2191				Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
2192			})
2193		}
2194		.unwrap();
2195		assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret));
2196
2197		// Missing payment secret
2198		let invoice = {
2199			let mut invoice = invoice_template.clone();
2200			invoice.data.tagged_fields.push(Features(payment_secret_features).into());
2201			invoice.sign::<_, ()>(|hash| {
2202				Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
2203			})
2204		}
2205		.unwrap();
2206		assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret));
2207
2208		// Multiple payment secrets
2209		let invoice = {
2210			let mut invoice = invoice_template;
2211			invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
2212			invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
2213			invoice.sign::<_, ()>(|hash| {
2214				Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
2215			})
2216		}
2217		.unwrap();
2218		assert_eq!(
2219			Bolt11Invoice::from_signed(invoice),
2220			Err(Bolt11SemanticError::MultiplePaymentSecrets)
2221		);
2222	}
2223
2224	#[test]
2225	fn test_builder_amount() {
2226		use crate::*;
2227
2228		let builder = InvoiceBuilder::new(Currency::Bitcoin)
2229			.description("Test".into())
2230			.payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
2231			.duration_since_epoch(Duration::from_secs(1234567));
2232
2233		let invoice = builder.clone().amount_milli_satoshis(1500).build_raw().unwrap();
2234
2235		assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Nano));
2236		assert_eq!(invoice.hrp.raw_amount, Some(15));
2237
2238		let invoice = builder.amount_milli_satoshis(150).build_raw().unwrap();
2239
2240		assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Pico));
2241		assert_eq!(invoice.hrp.raw_amount, Some(1500));
2242	}
2243
2244	#[test]
2245	fn test_builder_fail() {
2246		use crate::*;
2247		use bitcoin::secp256k1::PublicKey;
2248		use lightning_types::routing::RouteHintHop;
2249		use std::iter::FromIterator;
2250
2251		let builder = InvoiceBuilder::new(Currency::Bitcoin)
2252			.payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
2253			.duration_since_epoch(Duration::from_secs(1234567))
2254			.min_final_cltv_expiry_delta(144);
2255
2256		let too_long_string = String::from_iter((0..1024).map(|_| '?'));
2257
2258		let long_desc_res = builder.clone().description(too_long_string).build_raw();
2259		assert_eq!(long_desc_res, Err(CreationError::DescriptionTooLong));
2260
2261		let route_hop = RouteHintHop {
2262			src_node_id: PublicKey::from_slice(
2263				&[
2264					0x03, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c,
2265					0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3,
2266					0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55,
2267				][..],
2268			)
2269			.unwrap(),
2270			short_channel_id: 0,
2271			fees: RoutingFees { base_msat: 0, proportional_millionths: 0 },
2272			cltv_expiry_delta: 0,
2273			htlc_minimum_msat: None,
2274			htlc_maximum_msat: None,
2275		};
2276		let too_long_route = RouteHint(vec![route_hop; 13]);
2277		let long_route_res =
2278			builder.clone().description("Test".into()).private_route(too_long_route).build_raw();
2279		assert_eq!(long_route_res, Err(CreationError::RouteTooLong));
2280
2281		let sign_error_res = builder
2282			.description("Test".into())
2283			.payment_secret(PaymentSecret([0; 32]))
2284			.try_build_signed(|_| Err("ImaginaryError"));
2285		assert_eq!(sign_error_res, Err(SignOrCreationError::SignError("ImaginaryError")));
2286	}
2287
2288	#[test]
2289	fn test_builder_ok() {
2290		use crate::*;
2291		use bitcoin::secp256k1::Secp256k1;
2292		use bitcoin::secp256k1::{PublicKey, SecretKey};
2293		use lightning_types::routing::RouteHintHop;
2294		use std::time::Duration;
2295
2296		let secp_ctx = Secp256k1::new();
2297
2298		let private_key = SecretKey::from_slice(
2299			&[
2300				0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2,
2301				0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca,
2302				0x3b, 0x2d, 0xb7, 0x34,
2303			][..],
2304		)
2305		.unwrap();
2306		let public_key = PublicKey::from_secret_key(&secp_ctx, &private_key);
2307
2308		let route_1 = RouteHint(vec![
2309			RouteHintHop {
2310				src_node_id: public_key,
2311				short_channel_id: u64::from_be_bytes([123; 8]),
2312				fees: RoutingFees { base_msat: 2, proportional_millionths: 1 },
2313				cltv_expiry_delta: 145,
2314				htlc_minimum_msat: None,
2315				htlc_maximum_msat: None,
2316			},
2317			RouteHintHop {
2318				src_node_id: public_key,
2319				short_channel_id: u64::from_be_bytes([42; 8]),
2320				fees: RoutingFees { base_msat: 3, proportional_millionths: 2 },
2321				cltv_expiry_delta: 146,
2322				htlc_minimum_msat: None,
2323				htlc_maximum_msat: None,
2324			},
2325		]);
2326
2327		let route_2 = RouteHint(vec![
2328			RouteHintHop {
2329				src_node_id: public_key,
2330				short_channel_id: 0,
2331				fees: RoutingFees { base_msat: 4, proportional_millionths: 3 },
2332				cltv_expiry_delta: 147,
2333				htlc_minimum_msat: None,
2334				htlc_maximum_msat: None,
2335			},
2336			RouteHintHop {
2337				src_node_id: public_key,
2338				short_channel_id: u64::from_be_bytes([1; 8]),
2339				fees: RoutingFees { base_msat: 5, proportional_millionths: 4 },
2340				cltv_expiry_delta: 148,
2341				htlc_minimum_msat: None,
2342				htlc_maximum_msat: None,
2343			},
2344		]);
2345
2346		let builder = InvoiceBuilder::new(Currency::BitcoinTestnet)
2347			.amount_milli_satoshis(123)
2348			.duration_since_epoch(Duration::from_secs(1234567))
2349			.payee_pub_key(public_key)
2350			.expiry_time(Duration::from_secs(54321))
2351			.min_final_cltv_expiry_delta(144)
2352			.fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[0; 20]).unwrap()))
2353			.private_route(route_1.clone())
2354			.private_route(route_2.clone())
2355			.description_hash(sha256::Hash::from_slice(&[3; 32][..]).unwrap())
2356			.payment_hash(sha256::Hash::from_slice(&[21; 32][..]).unwrap())
2357			.payment_secret(PaymentSecret([42; 32]))
2358			.basic_mpp();
2359
2360		let invoice = builder
2361			.clone()
2362			.build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &private_key))
2363			.unwrap();
2364
2365		assert!(invoice.check_signature().is_ok());
2366		assert_eq!(invoice.tagged_fields().count(), 10);
2367
2368		assert_eq!(invoice.amount_milli_satoshis(), Some(123));
2369		assert_eq!(invoice.amount_pico_btc(), Some(1230));
2370		assert_eq!(invoice.currency(), Currency::BitcoinTestnet);
2371		#[cfg(feature = "std")]
2372		assert_eq!(
2373			invoice.timestamp().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(),
2374			1234567
2375		);
2376		assert_eq!(invoice.payee_pub_key(), Some(&public_key));
2377		assert_eq!(invoice.expiry_time(), Duration::from_secs(54321));
2378		assert_eq!(invoice.min_final_cltv_expiry_delta(), 144);
2379		assert_eq!(
2380			invoice.fallbacks(),
2381			vec![&Fallback::PubKeyHash(PubkeyHash::from_slice(&[0; 20]).unwrap())]
2382		);
2383		let address = Address::from_script(
2384			&ScriptBuf::new_p2pkh(&PubkeyHash::from_slice(&[0; 20]).unwrap()),
2385			Network::Testnet,
2386		)
2387		.unwrap();
2388		assert_eq!(invoice.fallback_addresses(), vec![address]);
2389		assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]);
2390		assert_eq!(
2391			invoice.description(),
2392			Bolt11InvoiceDescriptionRef::Hash(&Sha256(
2393				sha256::Hash::from_slice(&[3; 32][..]).unwrap()
2394			))
2395		);
2396		assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&[21; 32][..]).unwrap());
2397		assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32]));
2398
2399		let mut expected_features = Bolt11InvoiceFeatures::empty();
2400		expected_features.set_variable_length_onion_required();
2401		expected_features.set_payment_secret_required();
2402		expected_features.set_basic_mpp_optional();
2403		assert_eq!(invoice.features(), Some(&expected_features));
2404
2405		let raw_invoice = builder.build_raw().unwrap();
2406		assert_eq!(raw_invoice, *invoice.into_signed_raw().raw_invoice())
2407	}
2408
2409	#[test]
2410	fn test_default_values() {
2411		use crate::*;
2412		use bitcoin::secp256k1::Secp256k1;
2413		use bitcoin::secp256k1::SecretKey;
2414
2415		let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
2416			.description("Test".into())
2417			.payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
2418			.payment_secret(PaymentSecret([0; 32]))
2419			.duration_since_epoch(Duration::from_secs(1234567))
2420			.build_raw()
2421			.unwrap()
2422			.sign::<_, ()>(|hash| {
2423				let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
2424				let secp_ctx = Secp256k1::new();
2425				Ok(secp_ctx.sign_ecdsa_recoverable(hash, &privkey))
2426			})
2427			.unwrap();
2428		let invoice = Bolt11Invoice::from_signed(signed_invoice).unwrap();
2429
2430		assert_eq!(invoice.min_final_cltv_expiry_delta(), DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA);
2431		assert_eq!(invoice.expiry_time(), Duration::from_secs(DEFAULT_EXPIRY_TIME));
2432		assert!(!invoice.would_expire(Duration::from_secs(1234568)));
2433	}
2434
2435	#[test]
2436	fn test_expiration() {
2437		use crate::*;
2438		use bitcoin::secp256k1::Secp256k1;
2439		use bitcoin::secp256k1::SecretKey;
2440
2441		let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
2442			.description("Test".into())
2443			.payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
2444			.payment_secret(PaymentSecret([0; 32]))
2445			.duration_since_epoch(Duration::from_secs(1234567))
2446			.build_raw()
2447			.unwrap()
2448			.sign::<_, ()>(|hash| {
2449				let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
2450				let secp_ctx = Secp256k1::new();
2451				Ok(secp_ctx.sign_ecdsa_recoverable(hash, &privkey))
2452			})
2453			.unwrap();
2454		let invoice = Bolt11Invoice::from_signed(signed_invoice).unwrap();
2455
2456		assert!(invoice.would_expire(Duration::from_secs(1234567 + DEFAULT_EXPIRY_TIME + 1)));
2457	}
2458
2459	#[cfg(feature = "serde")]
2460	#[test]
2461	fn test_serde() {
2462		let invoice_str = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
2463			h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
2464			5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
2465			h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
2466			j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
2467			ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
2468			guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
2469			ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
2470			p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
2471			8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
2472			j5r6drg6k6zcqj0fcwg";
2473		let invoice = invoice_str.parse::<super::Bolt11Invoice>().unwrap();
2474		let serialized_invoice = serde_json::to_string(&invoice).unwrap();
2475		let deserialized_invoice: super::Bolt11Invoice =
2476			serde_json::from_str(serialized_invoice.as_str()).unwrap();
2477		assert_eq!(invoice, deserialized_invoice);
2478		assert_eq!(invoice_str, deserialized_invoice.to_string().as_str());
2479		assert_eq!(invoice_str, serialized_invoice.as_str().trim_matches('\"'));
2480	}
2481
2482	#[test]
2483	fn raw_tagged_field_ordering() {
2484		use crate::{
2485			sha256, Description, Fe32, RawTaggedField, Sha256, TaggedField, UntrustedString,
2486		};
2487
2488		let field10 = RawTaggedField::KnownSemantics(TaggedField::PaymentHash(Sha256(
2489			sha256::Hash::from_str(
2490				"0001020304050607080900010203040506070809000102030405060708090102",
2491			)
2492			.unwrap(),
2493		)));
2494		let field11 = RawTaggedField::KnownSemantics(TaggedField::Description(Description(
2495			UntrustedString("Description".to_string()),
2496		)));
2497		let field20 = RawTaggedField::UnknownSemantics(vec![Fe32::Q]);
2498		let field21 = RawTaggedField::UnknownSemantics(vec![Fe32::R]);
2499
2500		assert!(field10 < field20);
2501		assert!(field20 > field10);
2502		assert_eq!(field10.cmp(&field20), std::cmp::Ordering::Less);
2503		assert_eq!(field20.cmp(&field10), std::cmp::Ordering::Greater);
2504		assert_eq!(field10.cmp(&field10), std::cmp::Ordering::Equal);
2505		assert_eq!(field20.cmp(&field20), std::cmp::Ordering::Equal);
2506		assert_eq!(field10.partial_cmp(&field20).unwrap(), std::cmp::Ordering::Less);
2507		assert_eq!(field20.partial_cmp(&field10).unwrap(), std::cmp::Ordering::Greater);
2508
2509		assert_eq!(field10.partial_cmp(&field11).unwrap(), std::cmp::Ordering::Less);
2510		assert_eq!(field20.partial_cmp(&field21).unwrap(), std::cmp::Ordering::Less);
2511	}
2512}