Generate docs with features for docs.rs
[rust-lightning] / lightning-invoice / src / lib.rs
1 #![deny(missing_docs)]
2 #![deny(non_upper_case_globals)]
3 #![deny(non_camel_case_types)]
4 #![deny(non_snake_case)]
5 #![deny(unused_mut)]
6 #![deny(broken_intra_doc_links)]
7
8 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
9
10 #![cfg_attr(feature = "strict", deny(warnings))]
11 #![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
12
13 //! This crate provides data structures to represent
14 //! [lightning BOLT11](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md)
15 //! invoices and functions to create, encode and decode these. If you just want to use the standard
16 //! en-/decoding functionality this should get you started:
17 //!
18 //!   * For parsing use `str::parse::<Invoice>(&self)` (see the docs of `impl FromStr for Invoice`)
19 //!   * For constructing invoices use the `InvoiceBuilder`
20 //!   * For serializing invoices use the `Display`/`ToString` traits
21
22 #[cfg(not(any(feature = "std", feature = "no-std")))]
23 compile_error!("at least one of the `std` or `no-std` features must be enabled");
24
25 pub mod payment;
26 pub mod utils;
27
28 extern crate bech32;
29 extern crate bitcoin_hashes;
30 #[macro_use] extern crate lightning;
31 extern crate num_traits;
32 extern crate secp256k1;
33 extern crate alloc;
34 #[cfg(any(test, feature = "std"))]
35 extern crate core;
36
37 #[cfg(feature = "std")]
38 use std::time::SystemTime;
39
40 use bech32::u5;
41 use bitcoin_hashes::Hash;
42 use bitcoin_hashes::sha256;
43 use lightning::ln::PaymentSecret;
44 use lightning::ln::features::InvoiceFeatures;
45 #[cfg(any(doc, test))]
46 use lightning::routing::network_graph::RoutingFees;
47 use lightning::routing::router::RouteHint;
48 use lightning::util::invoice::construct_invoice_preimage;
49
50 use secp256k1::key::PublicKey;
51 use secp256k1::{Message, Secp256k1};
52 use secp256k1::recovery::RecoverableSignature;
53
54 use core::fmt::{Display, Formatter, self};
55 use core::iter::FilterMap;
56 use core::ops::Deref;
57 use core::slice::Iter;
58 use core::time::Duration;
59
60 mod de;
61 mod ser;
62 mod tb;
63
64 mod prelude {
65         #[cfg(feature = "hashbrown")]
66         extern crate hashbrown;
67
68         pub use alloc::{vec, vec::Vec, string::String, collections::VecDeque, boxed::Box};
69         #[cfg(not(feature = "hashbrown"))]
70         pub use std::collections::{HashMap, HashSet, hash_map};
71         #[cfg(feature = "hashbrown")]
72         pub use self::hashbrown::{HashMap, HashSet, hash_map};
73
74         pub use alloc::string::ToString;
75 }
76
77 use prelude::*;
78
79 /// Sync compat for std/no_std
80 #[cfg(feature = "std")]
81 mod sync {
82         pub use ::std::sync::{Mutex, MutexGuard};
83 }
84
85 /// Sync compat for std/no_std
86 #[cfg(not(feature = "std"))]
87 mod sync;
88
89 pub use de::{ParseError, ParseOrSemanticError};
90
91 /// The number of bits used to represent timestamps as defined in BOLT 11.
92 const TIMESTAMP_BITS: usize = 35;
93
94 /// The maximum timestamp as [`Duration::as_secs`] since the Unix epoch allowed by [`BOLT 11`].
95 ///
96 /// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
97 pub const MAX_TIMESTAMP: u64 = (1 << TIMESTAMP_BITS) - 1;
98
99 /// Default expiry time as defined by [BOLT 11].
100 ///
101 /// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
102 pub const DEFAULT_EXPIRY_TIME: u64 = 3600;
103
104 /// Default minimum final CLTV expiry as defined by [BOLT 11].
105 ///
106 /// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry, which is
107 /// provided in [`MIN_FINAL_CLTV_EXPIRY`].
108 ///
109 /// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
110 /// [`MIN_FINAL_CLTV_EXPIRY`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY
111 pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
112
113 /// Builder for `Invoice`s. It's the most convenient and advised way to use this library. It ensures
114 /// that only a semantically and syntactically correct Invoice can be built using it.
115 ///
116 /// ```
117 /// extern crate secp256k1;
118 /// extern crate lightning;
119 /// extern crate lightning_invoice;
120 /// extern crate bitcoin_hashes;
121 ///
122 /// use bitcoin_hashes::Hash;
123 /// use bitcoin_hashes::sha256;
124 ///
125 /// use secp256k1::Secp256k1;
126 /// use secp256k1::key::SecretKey;
127 ///
128 /// use lightning::ln::PaymentSecret;
129 ///
130 /// use lightning_invoice::{Currency, InvoiceBuilder};
131 ///
132 /// # #[cfg(not(feature = "std"))]
133 /// # fn main() {}
134 /// # #[cfg(feature = "std")]
135 /// # fn main() {
136 /// let private_key = SecretKey::from_slice(
137 ///             &[
138 ///                     0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f,
139 ///                     0xe2, 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04,
140 ///             0xa8, 0xca, 0x3b, 0x2d, 0xb7, 0x34
141 ///     ][..]
142 ///     ).unwrap();
143 ///
144 /// let payment_hash = sha256::Hash::from_slice(&[0; 32][..]).unwrap();
145 /// let payment_secret = PaymentSecret([42u8; 32]);
146 ///
147 /// let invoice = InvoiceBuilder::new(Currency::Bitcoin)
148 ///     .description("Coins pls!".into())
149 ///     .payment_hash(payment_hash)
150 ///     .payment_secret(payment_secret)
151 ///     .current_timestamp()
152 ///     .min_final_cltv_expiry(144)
153 ///     .build_signed(|hash| {
154 ///             Secp256k1::new().sign_recoverable(hash, &private_key)
155 ///     })
156 ///     .unwrap();
157 ///
158 /// assert!(invoice.to_string().starts_with("lnbc1"));
159 /// # }
160 /// ```
161 ///
162 /// # Type parameters
163 /// The two parameters `D` and `H` signal if the builder already contains the correct amount of the
164 /// given field:
165 ///  * `D`: exactly one `Description` or `DescriptionHash`
166 ///  * `H`: exactly one `PaymentHash`
167 ///  * `T`: the timestamp is set
168 ///
169 /// (C-not exported) as we likely need to manually select one set of boolean type parameters.
170 #[derive(Eq, PartialEq, Debug, Clone)]
171 pub struct InvoiceBuilder<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> {
172         currency: Currency,
173         amount: Option<u64>,
174         si_prefix: Option<SiPrefix>,
175         timestamp: Option<PositiveTimestamp>,
176         tagged_fields: Vec<TaggedField>,
177         error: Option<CreationError>,
178
179         phantom_d: core::marker::PhantomData<D>,
180         phantom_h: core::marker::PhantomData<H>,
181         phantom_t: core::marker::PhantomData<T>,
182         phantom_c: core::marker::PhantomData<C>,
183         phantom_s: core::marker::PhantomData<S>,
184 }
185
186 /// Represents a syntactically and semantically correct lightning BOLT11 invoice.
187 ///
188 /// There are three ways to construct an `Invoice`:
189 ///  1. using `InvoiceBuilder`
190 ///  2. using `Invoice::from_signed(SignedRawInvoice)`
191 ///  3. using `str::parse::<Invoice>(&str)`
192 #[derive(Eq, PartialEq, Debug, Clone)]
193 pub struct Invoice {
194         signed_invoice: SignedRawInvoice,
195 }
196
197 /// Represents the description of an invoice which has to be either a directly included string or
198 /// a hash of a description provided out of band.
199 ///
200 /// (C-not exported) As we don't have a good way to map the reference lifetimes making this
201 /// practically impossible to use safely in languages like C.
202 #[derive(Eq, PartialEq, Debug, Clone)]
203 pub enum InvoiceDescription<'f> {
204         /// Reference to the directly supplied description in the invoice
205         Direct(&'f Description),
206
207         /// Reference to the description's hash included in the invoice
208         Hash(&'f Sha256),
209 }
210
211 /// Represents a signed `RawInvoice` with cached hash. The signature is not checked and may be
212 /// invalid.
213 ///
214 /// # Invariants
215 /// The hash has to be either from the deserialized invoice or from the serialized `raw_invoice`.
216 #[derive(Eq, PartialEq, Debug, Clone)]
217 pub struct SignedRawInvoice {
218         /// The rawInvoice that the signature belongs to
219         raw_invoice: RawInvoice,
220
221         /// Hash of the `RawInvoice` that will be used to check the signature.
222         ///
223         /// * if the `SignedRawInvoice` was deserialized the hash is of from the original encoded form,
224         /// since it's not guaranteed that encoding it again will lead to the same result since integers
225         /// could have been encoded with leading zeroes etc.
226         /// * if the `SignedRawInvoice` was constructed manually the hash will be the calculated hash
227         /// from the `RawInvoice`
228         hash: [u8; 32],
229
230         /// signature of the payment request
231         signature: InvoiceSignature,
232 }
233
234 /// Represents an syntactically correct Invoice for a payment on the lightning network,
235 /// but without the signature information.
236 /// De- and encoding should not lead to information loss but may lead to different hashes.
237 ///
238 /// For methods without docs see the corresponding methods in `Invoice`.
239 #[derive(Eq, PartialEq, Debug, Clone)]
240 pub struct RawInvoice {
241         /// human readable part
242         pub hrp: RawHrp,
243
244         /// data part
245         pub data: RawDataPart,
246 }
247
248 /// Data of the `RawInvoice` that is encoded in the human readable part
249 ///
250 /// (C-not exported) As we don't yet support Option<Enum>
251 #[derive(Eq, PartialEq, Debug, Clone)]
252 pub struct RawHrp {
253         /// The currency deferred from the 3rd and 4th character of the bech32 transaction
254         pub currency: Currency,
255
256         /// The amount that, multiplied by the SI prefix, has to be payed
257         pub raw_amount: Option<u64>,
258
259         /// SI prefix that gets multiplied with the `raw_amount`
260         pub si_prefix: Option<SiPrefix>,
261 }
262
263 /// Data of the `RawInvoice` that is encoded in the data part
264 #[derive(Eq, PartialEq, Debug, Clone)]
265 pub struct RawDataPart {
266         /// generation time of the invoice
267         pub timestamp: PositiveTimestamp,
268
269         /// tagged fields of the payment request
270         pub tagged_fields: Vec<RawTaggedField>,
271 }
272
273 /// A timestamp that refers to a date after 1 January 1970.
274 ///
275 /// # Invariants
276 ///
277 /// The Unix timestamp representing the stored time has to be positive and no greater than
278 /// [`MAX_TIMESTAMP`].
279 #[derive(Eq, PartialEq, Debug, Clone)]
280 pub struct PositiveTimestamp(Duration);
281
282 /// SI prefixes for the human readable part
283 #[derive(Eq, PartialEq, Debug, Clone, Copy)]
284 pub enum SiPrefix {
285         /// 10^-3
286         Milli,
287         /// 10^-6
288         Micro,
289         /// 10^-9
290         Nano,
291         /// 10^-12
292         Pico,
293 }
294
295 impl SiPrefix {
296         /// Returns the multiplier to go from a BTC value to picoBTC implied by this SiPrefix.
297         /// This is effectively 10^12 * the prefix multiplier
298         pub fn multiplier(&self) -> u64 {
299                 match *self {
300                         SiPrefix::Milli => 1_000_000_000,
301                         SiPrefix::Micro => 1_000_000,
302                         SiPrefix::Nano => 1_000,
303                         SiPrefix::Pico => 1,
304                 }
305         }
306
307         /// Returns all enum variants of `SiPrefix` sorted in descending order of their associated
308         /// multiplier.
309         ///
310         /// (C-not exported) As we don't yet support a slice of enums, and also because this function
311         /// isn't the most critical to expose.
312         pub fn values_desc() -> &'static [SiPrefix] {
313                 use SiPrefix::*;
314                 static VALUES: [SiPrefix; 4] = [Milli, Micro, Nano, Pico];
315                 &VALUES
316         }
317 }
318
319 /// Enum representing the crypto currencies (or networks) supported by this library
320 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
321 pub enum Currency {
322         /// Bitcoin mainnet
323         Bitcoin,
324
325         /// Bitcoin testnet
326         BitcoinTestnet,
327
328         /// Bitcoin regtest
329         Regtest,
330
331         /// Bitcoin simnet
332         Simnet,
333
334         /// Bitcoin signet
335         Signet,
336 }
337
338 /// Tagged field which may have an unknown tag
339 ///
340 /// (C-not exported) as we don't currently support TaggedField
341 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
342 pub enum RawTaggedField {
343         /// Parsed tagged field with known tag
344         KnownSemantics(TaggedField),
345         /// tagged field which was not parsed due to an unknown tag or undefined field semantics
346         UnknownSemantics(Vec<u5>),
347 }
348
349 /// Tagged field with known tag
350 ///
351 /// For descriptions of the enum values please refer to the enclosed type's docs.
352 ///
353 /// (C-not exported) As we don't yet support enum variants with the same name the struct contained
354 /// in the variant.
355 #[allow(missing_docs)]
356 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
357 pub enum TaggedField {
358         PaymentHash(Sha256),
359         Description(Description),
360         PayeePubKey(PayeePubKey),
361         DescriptionHash(Sha256),
362         ExpiryTime(ExpiryTime),
363         MinFinalCltvExpiry(MinFinalCltvExpiry),
364         Fallback(Fallback),
365         PrivateRoute(PrivateRoute),
366         PaymentSecret(PaymentSecret),
367         Features(InvoiceFeatures),
368 }
369
370 /// SHA-256 hash
371 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
372 pub struct Sha256(/// (C-not exported) as the native hash types are not currently mapped
373         pub sha256::Hash);
374
375 /// Description string
376 ///
377 /// # Invariants
378 /// The description can be at most 639 __bytes__ long
379 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
380 pub struct Description(String);
381
382 /// Payee public key
383 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
384 pub struct PayeePubKey(pub PublicKey);
385
386 /// Positive duration that defines when (relatively to the timestamp) in the future the invoice
387 /// expires
388 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
389 pub struct ExpiryTime(Duration);
390
391 /// `min_final_cltv_expiry` to use for the last HTLC in the route
392 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
393 pub struct MinFinalCltvExpiry(pub u64);
394
395 // TODO: better types instead onf byte arrays
396 /// Fallback address in case no LN payment is possible
397 #[allow(missing_docs)]
398 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
399 pub enum Fallback {
400         SegWitProgram {
401                 version: u5,
402                 program: Vec<u8>,
403         },
404         PubKeyHash([u8; 20]),
405         ScriptHash([u8; 20]),
406 }
407
408 /// Recoverable signature
409 #[derive(Clone, Debug, Eq, PartialEq)]
410 pub struct InvoiceSignature(pub RecoverableSignature);
411
412 /// Private routing information
413 ///
414 /// # Invariants
415 /// The encoded route has to be <1024 5bit characters long (<=639 bytes or <=12 hops)
416 ///
417 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
418 pub struct PrivateRoute(RouteHint);
419
420 /// Tag constants as specified in BOLT11
421 #[allow(missing_docs)]
422 pub mod constants {
423         pub const TAG_PAYMENT_HASH: u8 = 1;
424         pub const TAG_DESCRIPTION: u8 = 13;
425         pub const TAG_PAYEE_PUB_KEY: u8 = 19;
426         pub const TAG_DESCRIPTION_HASH: u8 = 23;
427         pub const TAG_EXPIRY_TIME: u8 = 6;
428         pub const TAG_MIN_FINAL_CLTV_EXPIRY: u8 = 24;
429         pub const TAG_FALLBACK: u8 = 9;
430         pub const TAG_PRIVATE_ROUTE: u8 = 3;
431         pub const TAG_PAYMENT_SECRET: u8 = 16;
432         pub const TAG_FEATURES: u8 = 5;
433 }
434
435 impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
436         /// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
437         /// `InvoiceBuilder::build(self)` becomes available.
438         pub fn new(currrency: Currency) -> Self {
439                 InvoiceBuilder {
440                         currency: currrency,
441                         amount: None,
442                         si_prefix: None,
443                         timestamp: None,
444                         tagged_fields: Vec::new(),
445                         error: None,
446
447                         phantom_d: core::marker::PhantomData,
448                         phantom_h: core::marker::PhantomData,
449                         phantom_t: core::marker::PhantomData,
450                         phantom_c: core::marker::PhantomData,
451                         phantom_s: core::marker::PhantomData,
452                 }
453         }
454 }
455
456 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T, C, S> {
457         /// Helper function to set the completeness flags.
458         fn set_flags<DN: tb::Bool, HN: tb::Bool, TN: tb::Bool, CN: tb::Bool, SN: tb::Bool>(self) -> InvoiceBuilder<DN, HN, TN, CN, SN> {
459                 InvoiceBuilder::<DN, HN, TN, CN, SN> {
460                         currency: self.currency,
461                         amount: self.amount,
462                         si_prefix: self.si_prefix,
463                         timestamp: self.timestamp,
464                         tagged_fields: self.tagged_fields,
465                         error: self.error,
466
467                         phantom_d: core::marker::PhantomData,
468                         phantom_h: core::marker::PhantomData,
469                         phantom_t: core::marker::PhantomData,
470                         phantom_c: core::marker::PhantomData,
471                         phantom_s: core::marker::PhantomData,
472                 }
473         }
474
475         /// Sets the amount in millisatoshis. The optimal SI prefix is chosen automatically.
476         pub fn amount_milli_satoshis(mut self, amount_msat: u64) -> Self {
477                 let amount = amount_msat * 10; // Invoices are denominated in "pico BTC"
478                 let biggest_possible_si_prefix = SiPrefix::values_desc()
479                         .iter()
480                         .find(|prefix| amount % prefix.multiplier() == 0)
481                         .expect("Pico should always match");
482                 self.amount = Some(amount / biggest_possible_si_prefix.multiplier());
483                 self.si_prefix = Some(*biggest_possible_si_prefix);
484                 self
485         }
486
487         /// Sets the payee's public key.
488         pub fn payee_pub_key(mut self, pub_key: PublicKey) -> Self {
489                 self.tagged_fields.push(TaggedField::PayeePubKey(PayeePubKey(pub_key)));
490                 self
491         }
492
493         /// Sets the expiry time
494         pub fn expiry_time(mut self, expiry_time: Duration) -> Self {
495                 self.tagged_fields.push(TaggedField::ExpiryTime(ExpiryTime::from_duration(expiry_time)));
496                 self
497         }
498
499         /// Adds a fallback address.
500         pub fn fallback(mut self, fallback: Fallback) -> Self {
501                 self.tagged_fields.push(TaggedField::Fallback(fallback));
502                 self
503         }
504
505         /// Adds a private route.
506         pub fn private_route(mut self, hint: RouteHint) -> Self {
507                 match PrivateRoute::new(hint) {
508                         Ok(r) => self.tagged_fields.push(TaggedField::PrivateRoute(r)),
509                         Err(e) => self.error = Some(e),
510                 }
511                 self
512         }
513 }
514
515 impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb::True, C, S> {
516         /// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields.
517         pub fn build_raw(self) -> Result<RawInvoice, CreationError> {
518
519                 // If an error occurred at any time before, return it now
520                 if let Some(e) = self.error {
521                         return Err(e);
522                 }
523
524                 let hrp = RawHrp {
525                         currency: self.currency,
526                         raw_amount: self.amount,
527                         si_prefix: self.si_prefix,
528                 };
529
530                 let timestamp = self.timestamp.expect("ensured to be Some(t) by type T");
531
532                 let tagged_fields = self.tagged_fields.into_iter().map(|tf| {
533                         RawTaggedField::KnownSemantics(tf)
534                 }).collect::<Vec<_>>();
535
536                 let data = RawDataPart {
537                         timestamp: timestamp,
538                         tagged_fields: tagged_fields,
539                 };
540
541                 Ok(RawInvoice {
542                         hrp: hrp,
543                         data: data,
544                 })
545         }
546 }
547
548 impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::False, H, T, C, S> {
549         /// Set the description. This function is only available if no description (hash) was set.
550         pub fn description(mut self, description: String) -> InvoiceBuilder<tb::True, H, T, C, S> {
551                 match Description::new(description) {
552                         Ok(d) => self.tagged_fields.push(TaggedField::Description(d)),
553                         Err(e) => self.error = Some(e),
554                 }
555                 self.set_flags()
556         }
557
558         /// Set the description hash. This function is only available if no description (hash) was set.
559         pub fn description_hash(mut self, description_hash: sha256::Hash) -> InvoiceBuilder<tb::True, H, T, C, S> {
560                 self.tagged_fields.push(TaggedField::DescriptionHash(Sha256(description_hash)));
561                 self.set_flags()
562         }
563 }
564
565 impl<D: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, tb::False, T, C, S> {
566         /// Set the payment hash. This function is only available if no payment hash was set.
567         pub fn payment_hash(mut self, hash: sha256::Hash) -> InvoiceBuilder<D, tb::True, T, C, S> {
568                 self.tagged_fields.push(TaggedField::PaymentHash(Sha256(hash)));
569                 self.set_flags()
570         }
571 }
572
573 impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb::False, C, S> {
574         /// Sets the timestamp to a specific [`SystemTime`].
575         #[cfg(feature = "std")]
576         pub fn timestamp(mut self, time: SystemTime) -> InvoiceBuilder<D, H, tb::True, C, S> {
577                 match PositiveTimestamp::from_system_time(time) {
578                         Ok(t) => self.timestamp = Some(t),
579                         Err(e) => self.error = Some(e),
580                 }
581
582                 self.set_flags()
583         }
584
585         /// Sets the timestamp to a duration since the Unix epoch.
586         pub fn duration_since_epoch(mut self, time: Duration) -> InvoiceBuilder<D, H, tb::True, C, S> {
587                 match PositiveTimestamp::from_duration_since_epoch(time) {
588                         Ok(t) => self.timestamp = Some(t),
589                         Err(e) => self.error = Some(e),
590                 }
591
592                 self.set_flags()
593         }
594
595         /// Sets the timestamp to the current system time.
596         #[cfg(feature = "std")]
597         pub fn current_timestamp(mut self) -> InvoiceBuilder<D, H, tb::True, C, S> {
598                 let now = PositiveTimestamp::from_system_time(SystemTime::now());
599                 self.timestamp = Some(now.expect("for the foreseeable future this shouldn't happen"));
600                 self.set_flags()
601         }
602 }
603
604 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T, tb::False, S> {
605         /// Sets `min_final_cltv_expiry`.
606         pub fn min_final_cltv_expiry(mut self, min_final_cltv_expiry: u64) -> InvoiceBuilder<D, H, T, tb::True, S> {
607                 self.tagged_fields.push(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry(min_final_cltv_expiry)));
608                 self.set_flags()
609         }
610 }
611
612 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T, C, tb::False> {
613         /// Sets the payment secret and relevant features.
614         pub fn payment_secret(mut self, payment_secret: PaymentSecret) -> InvoiceBuilder<D, H, T, C, tb::True> {
615                 let features = InvoiceFeatures::empty()
616                         .set_variable_length_onion_required()
617                         .set_payment_secret_required();
618                 self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret));
619                 self.tagged_fields.push(TaggedField::Features(features));
620                 self.set_flags()
621         }
622 }
623
624 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T, C, tb::True> {
625         /// Sets the `basic_mpp` feature as optional.
626         pub fn basic_mpp(mut self) -> Self {
627                 self.tagged_fields = self.tagged_fields
628                         .drain(..)
629                         .map(|field| match field {
630                                 TaggedField::Features(f) => TaggedField::Features(f.set_basic_mpp_optional()),
631                                 _ => field,
632                         })
633                         .collect();
634                 self
635         }
636 }
637
638 impl InvoiceBuilder<tb::True, tb::True, tb::True, tb::True, tb::True> {
639         /// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
640         /// and MUST produce a recoverable signature valid for the given hash and if applicable also for
641         /// the included payee public key.
642         pub fn build_signed<F>(self, sign_function: F) -> Result<Invoice, CreationError>
643                 where F: FnOnce(&Message) -> RecoverableSignature
644         {
645                 let invoice = self.try_build_signed::<_, ()>(|hash| {
646                         Ok(sign_function(hash))
647                 });
648
649                 match invoice {
650                         Ok(i) => Ok(i),
651                         Err(SignOrCreationError::CreationError(e)) => Err(e),
652                         Err(SignOrCreationError::SignError(())) => unreachable!(),
653                 }
654         }
655
656         /// Builds and signs an invoice using the supplied `sign_function`. This function MAY fail with
657         /// an error of type `E` and MUST produce a recoverable signature valid for the given hash and
658         /// if applicable also for the included payee public key.
659         pub fn try_build_signed<F, E>(self, sign_function: F) -> Result<Invoice, SignOrCreationError<E>>
660                 where F: FnOnce(&Message) -> Result<RecoverableSignature, E>
661         {
662                 let raw = match self.build_raw() {
663                         Ok(r) => r,
664                         Err(e) => return Err(SignOrCreationError::CreationError(e)),
665                 };
666
667                 let signed = match raw.sign(sign_function) {
668                         Ok(s) => s,
669                         Err(e) => return Err(SignOrCreationError::SignError(e)),
670                 };
671
672                 let invoice = Invoice {
673                         signed_invoice: signed,
674                 };
675
676                 invoice.check_field_counts().expect("should be ensured by type signature of builder");
677                 invoice.check_feature_bits().expect("should be ensured by type signature of builder");
678                 invoice.check_amount().expect("should be ensured by type signature of builder");
679
680                 Ok(invoice)
681         }
682 }
683
684
685 impl SignedRawInvoice {
686         /// Disassembles the `SignedRawInvoice` into its three parts:
687         ///  1. raw invoice
688         ///  2. hash of the raw invoice
689         ///  3. signature
690         pub fn into_parts(self) -> (RawInvoice, [u8; 32], InvoiceSignature) {
691                 (self.raw_invoice, self.hash, self.signature)
692         }
693
694         /// The `RawInvoice` which was signed.
695         pub fn raw_invoice(&self) -> &RawInvoice {
696                 &self.raw_invoice
697         }
698
699         /// The hash of the `RawInvoice` that was signed.
700         pub fn hash(&self) -> &[u8; 32] {
701                 &self.hash
702         }
703
704         /// InvoiceSignature for the invoice.
705         pub fn signature(&self) -> &InvoiceSignature {
706                 &self.signature
707         }
708
709         /// Recovers the public key used for signing the invoice from the recoverable signature.
710         pub fn recover_payee_pub_key(&self) -> Result<PayeePubKey, secp256k1::Error> {
711                 let hash = Message::from_slice(&self.hash[..])
712                         .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
713
714                 Ok(PayeePubKey(Secp256k1::new().recover(
715                         &hash,
716                         &self.signature
717                 )?))
718         }
719
720         /// Checks if the signature is valid for the included payee public key or if none exists if it's
721         /// valid for the recovered signature (which should always be true?).
722         pub fn check_signature(&self) -> bool {
723                 let included_pub_key = self.raw_invoice.payee_pub_key();
724
725                 let mut recovered_pub_key = Option::None;
726                 if recovered_pub_key.is_none() {
727                         let recovered = match self.recover_payee_pub_key() {
728                                 Ok(pk) => pk,
729                                 Err(_) => return false,
730                         };
731                         recovered_pub_key = Some(recovered);
732                 }
733
734                 let pub_key = included_pub_key.or_else(|| recovered_pub_key.as_ref())
735                         .expect("One is always present");
736
737                 let hash = Message::from_slice(&self.hash[..])
738                         .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
739
740                 let secp_context = Secp256k1::new();
741                 let verification_result = secp_context.verify(
742                         &hash,
743                         &self.signature.to_standard(),
744                         pub_key
745                 );
746
747                 match verification_result {
748                         Ok(()) => true,
749                         Err(_) => false,
750                 }
751         }
752 }
753
754 /// Finds the first element of an enum stream of a given variant and extracts one member of the
755 /// variant. If no element was found `None` gets returned.
756 ///
757 /// The following example would extract the first B.
758 /// ```
759 /// use Enum::*
760 ///
761 /// enum Enum {
762 ///     A(u8),
763 ///     B(u16)
764 /// }
765 ///
766 /// let elements = vec![A(1), A(2), B(3), A(4)]
767 ///
768 /// assert_eq!(find_extract!(elements.iter(), Enum::B(ref x), x), Some(3u16))
769 /// ```
770 macro_rules! find_extract {
771         ($iter:expr, $enm:pat, $enm_var:ident) => {
772                 find_all_extract!($iter, $enm, $enm_var).next()
773         };
774 }
775
776 /// Finds the all elements of an enum stream of a given variant and extracts one member of the
777 /// variant through an iterator.
778 ///
779 /// The following example would extract all A.
780 /// ```
781 /// use Enum::*
782 ///
783 /// enum Enum {
784 ///     A(u8),
785 ///     B(u16)
786 /// }
787 ///
788 /// let elements = vec![A(1), A(2), B(3), A(4)]
789 ///
790 /// assert_eq!(
791 ///     find_all_extract!(elements.iter(), Enum::A(ref x), x).collect::<Vec<u8>>(),
792 ///     vec![1u8, 2u8, 4u8])
793 /// ```
794 macro_rules! find_all_extract {
795         ($iter:expr, $enm:pat, $enm_var:ident) => {
796                 $iter.filter_map(|tf| match *tf {
797                         $enm => Some($enm_var),
798                         _ => None,
799                 })
800         };
801 }
802
803 #[allow(missing_docs)]
804 impl RawInvoice {
805         /// Hash the HRP as bytes and signatureless data part.
806         fn hash_from_parts(hrp_bytes: &[u8], data_without_signature: &[u5]) -> [u8; 32] {
807                 let preimage = construct_invoice_preimage(hrp_bytes, data_without_signature);
808                 let mut hash: [u8; 32] = Default::default();
809                 hash.copy_from_slice(&sha256::Hash::hash(&preimage)[..]);
810                 hash
811         }
812
813         /// Calculate the hash of the encoded `RawInvoice`
814         pub fn hash(&self) -> [u8; 32] {
815                 use bech32::ToBase32;
816
817                 RawInvoice::hash_from_parts(
818                         self.hrp.to_string().as_bytes(),
819                         &self.data.to_base32()
820                 )
821         }
822
823         /// Signs the invoice using the supplied `sign_function`. This function MAY fail with an error
824         /// of type `E`. Since the signature of a `SignedRawInvoice` is not required to be valid there
825         /// are no constraints regarding the validity of the produced signature.
826         ///
827         /// (C-not exported) As we don't currently support passing function pointers into methods
828         /// explicitly.
829         pub fn sign<F, E>(self, sign_method: F) -> Result<SignedRawInvoice, E>
830                 where F: FnOnce(&Message) -> Result<RecoverableSignature, E>
831         {
832                 let raw_hash = self.hash();
833                 let hash = Message::from_slice(&raw_hash[..])
834                         .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
835                 let signature = sign_method(&hash)?;
836
837                 Ok(SignedRawInvoice {
838                         raw_invoice: self,
839                         hash: raw_hash,
840                         signature: InvoiceSignature(signature),
841                 })
842         }
843
844         /// Returns an iterator over all tagged fields with known semantics.
845         ///
846         /// (C-not exported) As there is not yet a manual mapping for a FilterMap
847         pub fn known_tagged_fields(&self)
848                 -> FilterMap<Iter<RawTaggedField>, fn(&RawTaggedField) -> Option<&TaggedField>>
849         {
850                 // For 1.14.0 compatibility: closures' types can't be written an fn()->() in the
851                 // function's type signature.
852                 // TODO: refactor once impl Trait is available
853                 fn match_raw(raw: &RawTaggedField) -> Option<&TaggedField> {
854                         match *raw {
855                                 RawTaggedField::KnownSemantics(ref tf) => Some(tf),
856                                 _ => None,
857                         }
858                 }
859
860                 self.data.tagged_fields.iter().filter_map(match_raw )
861         }
862
863         pub fn payment_hash(&self) -> Option<&Sha256> {
864                 find_extract!(self.known_tagged_fields(), TaggedField::PaymentHash(ref x), x)
865         }
866
867         pub fn description(&self) -> Option<&Description> {
868                 find_extract!(self.known_tagged_fields(), TaggedField::Description(ref x), x)
869         }
870
871         pub fn payee_pub_key(&self) -> Option<&PayeePubKey> {
872                 find_extract!(self.known_tagged_fields(), TaggedField::PayeePubKey(ref x), x)
873         }
874
875         pub fn description_hash(&self) -> Option<&Sha256> {
876                 find_extract!(self.known_tagged_fields(), TaggedField::DescriptionHash(ref x), x)
877         }
878
879         pub fn expiry_time(&self) -> Option<&ExpiryTime> {
880                 find_extract!(self.known_tagged_fields(), TaggedField::ExpiryTime(ref x), x)
881         }
882
883         pub fn min_final_cltv_expiry(&self) -> Option<&MinFinalCltvExpiry> {
884                 find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiry(ref x), x)
885         }
886
887         pub fn payment_secret(&self) -> Option<&PaymentSecret> {
888                 find_extract!(self.known_tagged_fields(), TaggedField::PaymentSecret(ref x), x)
889         }
890
891         pub fn features(&self) -> Option<&InvoiceFeatures> {
892                 find_extract!(self.known_tagged_fields(), TaggedField::Features(ref x), x)
893         }
894
895         /// (C-not exported) as we don't support Vec<&NonOpaqueType>
896         pub fn fallbacks(&self) -> Vec<&Fallback> {
897                 find_all_extract!(self.known_tagged_fields(), TaggedField::Fallback(ref x), x).collect()
898         }
899
900         pub fn private_routes(&self) -> Vec<&PrivateRoute> {
901                 find_all_extract!(self.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x).collect()
902         }
903
904         pub fn amount_pico_btc(&self) -> Option<u64> {
905                 self.hrp.raw_amount.map(|v| {
906                         v * self.hrp.si_prefix.as_ref().map_or(1_000_000_000_000, |si| { si.multiplier() })
907                 })
908         }
909
910         pub fn currency(&self) -> Currency {
911                 self.hrp.currency.clone()
912         }
913 }
914
915 impl PositiveTimestamp {
916         /// Creates a `PositiveTimestamp` from a Unix timestamp in the range `0..=MAX_TIMESTAMP`.
917         ///
918         /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
919         pub fn from_unix_timestamp(unix_seconds: u64) -> Result<Self, CreationError> {
920                 Self::from_duration_since_epoch(Duration::from_secs(unix_seconds))
921         }
922
923         /// Creates a `PositiveTimestamp` from a [`SystemTime`] with a corresponding Unix timestamp in
924         /// the range `0..=MAX_TIMESTAMP`.
925         ///
926         /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
927         #[cfg(feature = "std")]
928         pub fn from_system_time(time: SystemTime) -> Result<Self, CreationError> {
929                 time.duration_since(SystemTime::UNIX_EPOCH)
930                         .map(Self::from_duration_since_epoch)
931                         .unwrap_or(Err(CreationError::TimestampOutOfBounds))
932         }
933
934         /// Creates a `PositiveTimestamp` from a [`Duration`] since the Unix epoch in the range
935         /// `0..=MAX_TIMESTAMP`.
936         ///
937         /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
938         pub fn from_duration_since_epoch(duration: Duration) -> Result<Self, CreationError> {
939                 if duration.as_secs() <= MAX_TIMESTAMP {
940                         Ok(PositiveTimestamp(duration))
941                 } else {
942                         Err(CreationError::TimestampOutOfBounds)
943                 }
944         }
945
946         /// Returns the Unix timestamp representing the stored time
947         pub fn as_unix_timestamp(&self) -> u64 {
948                 self.0.as_secs()
949         }
950
951         /// Returns the duration of the stored time since the Unix epoch
952         pub fn as_duration_since_epoch(&self) -> Duration {
953                 self.0
954         }
955
956         /// Returns the [`SystemTime`] representing the stored time
957         #[cfg(feature = "std")]
958         pub fn as_time(&self) -> SystemTime {
959                 SystemTime::UNIX_EPOCH + self.0
960         }
961 }
962
963 #[cfg(feature = "std")]
964 impl Into<SystemTime> for PositiveTimestamp {
965         fn into(self) -> SystemTime {
966                 SystemTime::UNIX_EPOCH + self.0
967         }
968 }
969
970 impl Invoice {
971         /// Transform the `Invoice` into it's unchecked version
972         pub fn into_signed_raw(self) -> SignedRawInvoice {
973                 self.signed_invoice
974         }
975
976         /// Check that all mandatory fields are present
977         fn check_field_counts(&self) -> Result<(), SemanticError> {
978                 // "A writer MUST include exactly one p field […]."
979                 let payment_hash_cnt = self.tagged_fields().filter(|&tf| match *tf {
980                         TaggedField::PaymentHash(_) => true,
981                         _ => false,
982                 }).count();
983                 if payment_hash_cnt < 1 {
984                         return Err(SemanticError::NoPaymentHash);
985                 } else if payment_hash_cnt > 1 {
986                         return Err(SemanticError::MultiplePaymentHashes);
987                 }
988
989                 // "A writer MUST include either exactly one d or exactly one h field."
990                 let description_cnt = self.tagged_fields().filter(|&tf| match *tf {
991                         TaggedField::Description(_) | TaggedField::DescriptionHash(_) => true,
992                         _ => false,
993                 }).count();
994                 if  description_cnt < 1 {
995                         return Err(SemanticError::NoDescription);
996                 } else if description_cnt > 1 {
997                         return  Err(SemanticError::MultipleDescriptions);
998                 }
999
1000                 self.check_payment_secret()?;
1001
1002                 Ok(())
1003         }
1004
1005         /// Checks that there is exactly one payment secret field
1006         fn check_payment_secret(&self) -> Result<(), SemanticError> {
1007                 // "A writer MUST include exactly one `s` field."
1008                 let payment_secret_count = self.tagged_fields().filter(|&tf| match *tf {
1009                         TaggedField::PaymentSecret(_) => true,
1010                         _ => false,
1011                 }).count();
1012                 if payment_secret_count < 1 {
1013                         return Err(SemanticError::NoPaymentSecret);
1014                 } else if payment_secret_count > 1 {
1015                         return Err(SemanticError::MultiplePaymentSecrets);
1016                 }
1017
1018                 Ok(())
1019         }
1020
1021         /// Check that amount is a whole number of millisatoshis
1022         fn check_amount(&self) -> Result<(), SemanticError> {
1023                 if let Some(amount_pico_btc) = self.amount_pico_btc() {
1024                         if amount_pico_btc % 10 != 0 {
1025                                 return Err(SemanticError::ImpreciseAmount);
1026                         }
1027                 }
1028                 Ok(())
1029         }
1030
1031         /// Check that feature bits are set as required
1032         fn check_feature_bits(&self) -> Result<(), SemanticError> {
1033                 self.check_payment_secret()?;
1034
1035                 // "A writer MUST set an s field if and only if the payment_secret feature is set."
1036                 // (this requirement has been since removed, and we now require the payment secret
1037                 // feature bit always).
1038                 let features = self.tagged_fields().find(|&tf| match *tf {
1039                         TaggedField::Features(_) => true,
1040                         _ => false,
1041                 });
1042                 match features {
1043                         None => Err(SemanticError::InvalidFeatures),
1044                         Some(TaggedField::Features(features)) => {
1045                                 if features.requires_unknown_bits() {
1046                                         Err(SemanticError::InvalidFeatures)
1047                                 } else if !features.supports_payment_secret() {
1048                                         Err(SemanticError::InvalidFeatures)
1049                                 } else {
1050                                         Ok(())
1051                                 }
1052                         },
1053                         Some(_) => unreachable!(),
1054                 }
1055         }
1056
1057         /// Check that the invoice is signed correctly and that key recovery works
1058         pub fn check_signature(&self) -> Result<(), SemanticError> {
1059                 match self.signed_invoice.recover_payee_pub_key() {
1060                         Err(secp256k1::Error::InvalidRecoveryId) =>
1061                                 return Err(SemanticError::InvalidRecoveryId),
1062                         Err(secp256k1::Error::InvalidSignature) =>
1063                                 return Err(SemanticError::InvalidSignature),
1064                         Err(e) => panic!("no other error may occur, got {:?}", e),
1065                         Ok(_) => {},
1066                 }
1067
1068                 if !self.signed_invoice.check_signature() {
1069                         return Err(SemanticError::InvalidSignature);
1070                 }
1071
1072                 Ok(())
1073         }
1074
1075         /// Constructs an `Invoice` from a `SignedRawInvoice` by checking all its invariants.
1076         /// ```
1077         /// use lightning_invoice::*;
1078         ///
1079         /// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
1080         /// h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
1081         /// 5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
1082         /// h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
1083         /// j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
1084         /// ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
1085         /// guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
1086         /// ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
1087         /// p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
1088         /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
1089         /// j5r6drg6k6zcqj0fcwg";
1090         ///
1091         /// let signed = invoice.parse::<SignedRawInvoice>().unwrap();
1092         ///
1093         /// assert!(Invoice::from_signed(signed).is_ok());
1094         /// ```
1095         pub fn from_signed(signed_invoice: SignedRawInvoice) -> Result<Self, SemanticError> {
1096                 let invoice = Invoice {
1097                         signed_invoice: signed_invoice,
1098                 };
1099                 invoice.check_field_counts()?;
1100                 invoice.check_feature_bits()?;
1101                 invoice.check_signature()?;
1102                 invoice.check_amount()?;
1103
1104                 Ok(invoice)
1105         }
1106
1107         /// Returns the `Invoice`'s timestamp (should equal its creation time)
1108         #[cfg(feature = "std")]
1109         pub fn timestamp(&self) -> SystemTime {
1110                 self.signed_invoice.raw_invoice().data.timestamp.as_time()
1111         }
1112
1113         /// Returns the `Invoice`'s timestamp as a duration since the Unix epoch
1114         pub fn duration_since_epoch(&self) -> Duration {
1115                 self.signed_invoice.raw_invoice().data.timestamp.0
1116         }
1117
1118         /// Returns an iterator over all tagged fields of this Invoice.
1119         ///
1120         /// (C-not exported) As there is not yet a manual mapping for a FilterMap
1121         pub fn tagged_fields(&self)
1122                 -> FilterMap<Iter<RawTaggedField>, fn(&RawTaggedField) -> Option<&TaggedField>> {
1123                 self.signed_invoice.raw_invoice().known_tagged_fields()
1124         }
1125
1126         /// Returns the hash to which we will receive the preimage on completion of the payment
1127         pub fn payment_hash(&self) -> &sha256::Hash {
1128                 &self.signed_invoice.payment_hash().expect("checked by constructor").0
1129         }
1130
1131         /// Return the description or a hash of it for longer ones
1132         ///
1133         /// (C-not exported) because we don't yet export InvoiceDescription
1134         pub fn description(&self) -> InvoiceDescription {
1135                 if let Some(ref direct) = self.signed_invoice.description() {
1136                         return InvoiceDescription::Direct(direct);
1137                 } else if let Some(ref hash) = self.signed_invoice.description_hash() {
1138                         return InvoiceDescription::Hash(hash);
1139                 }
1140                 unreachable!("ensured by constructor");
1141         }
1142
1143         /// Get the payee's public key if one was included in the invoice
1144         pub fn payee_pub_key(&self) -> Option<&PublicKey> {
1145                 self.signed_invoice.payee_pub_key().map(|x| &x.0)
1146         }
1147
1148         /// Get the payment secret if one was included in the invoice
1149         pub fn payment_secret(&self) -> &PaymentSecret {
1150                 self.signed_invoice.payment_secret().expect("was checked by constructor")
1151         }
1152
1153         /// Get the invoice features if they were included in the invoice
1154         pub fn features(&self) -> Option<&InvoiceFeatures> {
1155                 self.signed_invoice.features()
1156         }
1157
1158         /// Recover the payee's public key (only to be used if none was included in the invoice)
1159         pub fn recover_payee_pub_key(&self) -> PublicKey {
1160                 self.signed_invoice.recover_payee_pub_key().expect("was checked by constructor").0
1161         }
1162
1163         /// Returns the invoice's expiry time, if present, otherwise [`DEFAULT_EXPIRY_TIME`].
1164         pub fn expiry_time(&self) -> Duration {
1165                 self.signed_invoice.expiry_time()
1166                         .map(|x| x.0)
1167                         .unwrap_or(Duration::from_secs(DEFAULT_EXPIRY_TIME))
1168         }
1169
1170         /// Returns whether the invoice has expired.
1171         #[cfg(feature = "std")]
1172         pub fn is_expired(&self) -> bool {
1173                 Self::is_expired_from_epoch(&self.timestamp(), self.expiry_time())
1174         }
1175
1176         /// Returns whether the expiry time from the given epoch has passed.
1177         #[cfg(feature = "std")]
1178         pub(crate) fn is_expired_from_epoch(epoch: &SystemTime, expiry_time: Duration) -> bool {
1179                 match epoch.elapsed() {
1180                         Ok(elapsed) => elapsed > expiry_time,
1181                         Err(_) => false,
1182                 }
1183         }
1184
1185         /// Returns whether the expiry time would pass at the given point in time.
1186         /// `at_time` is the timestamp as a duration since the Unix epoch.
1187         pub fn would_expire(&self, at_time: Duration) -> bool {
1188                 self.duration_since_epoch()
1189                         .checked_add(self.expiry_time())
1190                         .unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1)) < at_time
1191         }
1192
1193         /// Returns the invoice's `min_final_cltv_expiry` time, if present, otherwise
1194         /// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY`].
1195         pub fn min_final_cltv_expiry(&self) -> u64 {
1196                 self.signed_invoice.min_final_cltv_expiry()
1197                         .map(|x| x.0)
1198                         .unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY)
1199         }
1200
1201         /// Returns a list of all fallback addresses
1202         ///
1203         /// (C-not exported) as we don't support Vec<&NonOpaqueType>
1204         pub fn fallbacks(&self) -> Vec<&Fallback> {
1205                 self.signed_invoice.fallbacks()
1206         }
1207
1208         /// Returns a list of all routes included in the invoice
1209         pub fn private_routes(&self) -> Vec<&PrivateRoute> {
1210                 self.signed_invoice.private_routes()
1211         }
1212
1213         /// Returns a list of all routes included in the invoice as the underlying hints
1214         pub fn route_hints(&self) -> Vec<RouteHint> {
1215                 find_all_extract!(
1216                         self.signed_invoice.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x
1217                 ).map(|route| (**route).clone()).collect()
1218         }
1219
1220         /// Returns the currency for which the invoice was issued
1221         pub fn currency(&self) -> Currency {
1222                 self.signed_invoice.currency()
1223         }
1224
1225         /// Returns the amount if specified in the invoice as millisatoshis.
1226         pub fn amount_milli_satoshis(&self) -> Option<u64> {
1227                 self.signed_invoice.amount_pico_btc().map(|v| v / 10)
1228         }
1229
1230         /// Returns the amount if specified in the invoice as pico <currency>.
1231         fn amount_pico_btc(&self) -> Option<u64> {
1232                 self.signed_invoice.amount_pico_btc()
1233         }
1234 }
1235
1236 impl From<TaggedField> for RawTaggedField {
1237         fn from(tf: TaggedField) -> Self {
1238                 RawTaggedField::KnownSemantics(tf)
1239         }
1240 }
1241
1242 impl TaggedField {
1243         /// Numeric representation of the field's tag
1244         pub fn tag(&self) -> u5 {
1245                 let tag = match *self {
1246                         TaggedField::PaymentHash(_) => constants::TAG_PAYMENT_HASH,
1247                         TaggedField::Description(_) => constants::TAG_DESCRIPTION,
1248                         TaggedField::PayeePubKey(_) => constants::TAG_PAYEE_PUB_KEY,
1249                         TaggedField::DescriptionHash(_) => constants::TAG_DESCRIPTION_HASH,
1250                         TaggedField::ExpiryTime(_) => constants::TAG_EXPIRY_TIME,
1251                         TaggedField::MinFinalCltvExpiry(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY,
1252                         TaggedField::Fallback(_) => constants::TAG_FALLBACK,
1253                         TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE,
1254                         TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
1255                         TaggedField::Features(_) => constants::TAG_FEATURES,
1256                 };
1257
1258                 u5::try_from_u8(tag).expect("all tags defined are <32")
1259         }
1260 }
1261
1262 impl Description {
1263
1264         /// Creates a new `Description` if `description` is at most 1023 __bytes__ long,
1265         /// returns `CreationError::DescriptionTooLong` otherwise
1266         ///
1267         /// Please note that single characters may use more than one byte due to UTF8 encoding.
1268         pub fn new(description: String) -> Result<Description, CreationError> {
1269                 if description.len() > 639 {
1270                         Err(CreationError::DescriptionTooLong)
1271                 } else {
1272                         Ok(Description(description))
1273                 }
1274         }
1275
1276         /// Returns the underlying description `String`
1277         pub fn into_inner(self) -> String {
1278                 self.0
1279         }
1280 }
1281
1282 impl Into<String> for Description {
1283         fn into(self) -> String {
1284                 self.into_inner()
1285         }
1286 }
1287
1288 impl Deref for Description {
1289         type Target = str;
1290
1291         fn deref(&self) -> &str {
1292                 &self.0
1293         }
1294 }
1295
1296 impl From<PublicKey> for PayeePubKey {
1297         fn from(pk: PublicKey) -> Self {
1298                 PayeePubKey(pk)
1299         }
1300 }
1301
1302 impl Deref for PayeePubKey {
1303         type Target = PublicKey;
1304
1305         fn deref(&self) -> &PublicKey {
1306                 &self.0
1307         }
1308 }
1309
1310 impl ExpiryTime {
1311         /// Construct an `ExpiryTime` from seconds.
1312         pub fn from_seconds(seconds: u64) -> ExpiryTime {
1313                 ExpiryTime(Duration::from_secs(seconds))
1314         }
1315
1316         /// Construct an `ExpiryTime` from a `Duration`.
1317         pub fn from_duration(duration: Duration) -> ExpiryTime {
1318                 ExpiryTime(duration)
1319         }
1320
1321         /// Returns the expiry time in seconds
1322         pub fn as_seconds(&self) -> u64 {
1323                 self.0.as_secs()
1324         }
1325
1326         /// Returns a reference to the underlying `Duration` (=expiry time)
1327         pub fn as_duration(&self) -> &Duration {
1328                 &self.0
1329         }
1330 }
1331
1332 impl PrivateRoute {
1333         /// Creates a new (partial) route from a list of hops
1334         pub fn new(hops: RouteHint) -> Result<PrivateRoute, CreationError> {
1335                 if hops.0.len() <= 12 {
1336                         Ok(PrivateRoute(hops))
1337                 } else {
1338                         Err(CreationError::RouteTooLong)
1339                 }
1340         }
1341
1342         /// Returns the underlying list of hops
1343         pub fn into_inner(self) -> RouteHint {
1344                 self.0
1345         }
1346 }
1347
1348 impl Into<RouteHint> for PrivateRoute {
1349         fn into(self) -> RouteHint {
1350                 self.into_inner()
1351         }
1352 }
1353
1354 impl Deref for PrivateRoute {
1355         type Target = RouteHint;
1356
1357         fn deref(&self) -> &RouteHint {
1358                 &self.0
1359         }
1360 }
1361
1362 impl Deref for InvoiceSignature {
1363         type Target = RecoverableSignature;
1364
1365         fn deref(&self) -> &RecoverableSignature {
1366                 &self.0
1367         }
1368 }
1369
1370 impl Deref for SignedRawInvoice {
1371         type Target = RawInvoice;
1372
1373         fn deref(&self) -> &RawInvoice {
1374                 &self.raw_invoice
1375         }
1376 }
1377
1378 /// Errors that may occur when constructing a new `RawInvoice` or `Invoice`
1379 #[derive(Eq, PartialEq, Debug, Clone)]
1380 pub enum CreationError {
1381         /// The supplied description string was longer than 639 __bytes__ (see [`Description::new(…)`](./struct.Description.html#method.new))
1382         DescriptionTooLong,
1383
1384         /// The specified route has too many hops and can't be encoded
1385         RouteTooLong,
1386
1387         /// The Unix timestamp of the supplied date is less than zero or greater than 35-bits
1388         TimestampOutOfBounds,
1389
1390         /// The supplied millisatoshi amount was greater than the total bitcoin supply.
1391         InvalidAmount,
1392
1393         /// Route hints were required for this invoice and were missing. Applies to
1394         /// [phantom invoices].
1395         ///
1396         /// [phantom invoices]: crate::utils::create_phantom_invoice
1397         MissingRouteHints,
1398 }
1399
1400 impl Display for CreationError {
1401         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1402                 match self {
1403                         CreationError::DescriptionTooLong => f.write_str("The supplied description string was longer than 639 bytes"),
1404                         CreationError::RouteTooLong => f.write_str("The specified route has too many hops and can't be encoded"),
1405                         CreationError::TimestampOutOfBounds => f.write_str("The Unix timestamp of the supplied date is less than zero or greater than 35-bits"),
1406                         CreationError::InvalidAmount => f.write_str("The supplied millisatoshi amount was greater than the total bitcoin supply"),
1407                         CreationError::MissingRouteHints => f.write_str("The invoice required route hints and they weren't provided"),
1408                 }
1409         }
1410 }
1411
1412 #[cfg(feature = "std")]
1413 impl std::error::Error for CreationError { }
1414
1415 /// Errors that may occur when converting a `RawInvoice` to an `Invoice`. They relate to the
1416 /// requirements sections in BOLT #11
1417 #[derive(Eq, PartialEq, Debug, Clone)]
1418 pub enum SemanticError {
1419         /// The invoice is missing the mandatory payment hash
1420         NoPaymentHash,
1421
1422         /// The invoice has multiple payment hashes which isn't allowed
1423         MultiplePaymentHashes,
1424
1425         /// No description or description hash are part of the invoice
1426         NoDescription,
1427
1428         /// The invoice contains multiple descriptions and/or description hashes which isn't allowed
1429         MultipleDescriptions,
1430
1431         /// The invoice is missing the mandatory payment secret, which all modern lightning nodes
1432         /// should provide.
1433         NoPaymentSecret,
1434
1435         /// The invoice contains multiple payment secrets
1436         MultiplePaymentSecrets,
1437
1438         /// The invoice's features are invalid
1439         InvalidFeatures,
1440
1441         /// The recovery id doesn't fit the signature/pub key
1442         InvalidRecoveryId,
1443
1444         /// The invoice's signature is invalid
1445         InvalidSignature,
1446
1447         /// The invoice's amount was not a whole number of millisatoshis
1448         ImpreciseAmount,
1449 }
1450
1451 impl Display for SemanticError {
1452         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1453                 match self {
1454                         SemanticError::NoPaymentHash => f.write_str("The invoice is missing the mandatory payment hash"),
1455                         SemanticError::MultiplePaymentHashes => f.write_str("The invoice has multiple payment hashes which isn't allowed"),
1456                         SemanticError::NoDescription => f.write_str("No description or description hash are part of the invoice"),
1457                         SemanticError::MultipleDescriptions => f.write_str("The invoice contains multiple descriptions and/or description hashes which isn't allowed"),
1458                         SemanticError::NoPaymentSecret => f.write_str("The invoice is missing the mandatory payment secret"),
1459                         SemanticError::MultiplePaymentSecrets => f.write_str("The invoice contains multiple payment secrets"),
1460                         SemanticError::InvalidFeatures => f.write_str("The invoice's features are invalid"),
1461                         SemanticError::InvalidRecoveryId => f.write_str("The recovery id doesn't fit the signature/pub key"),
1462                         SemanticError::InvalidSignature => f.write_str("The invoice's signature is invalid"),
1463                         SemanticError::ImpreciseAmount => f.write_str("The invoice's amount was not a whole number of millisatoshis"),
1464                 }
1465         }
1466 }
1467
1468 #[cfg(feature = "std")]
1469 impl std::error::Error for SemanticError { }
1470
1471 /// When signing using a fallible method either an user-supplied `SignError` or a `CreationError`
1472 /// may occur.
1473 #[derive(Eq, PartialEq, Debug, Clone)]
1474 pub enum SignOrCreationError<S = ()> {
1475         /// An error occurred during signing
1476         SignError(S),
1477
1478         /// An error occurred while building the transaction
1479         CreationError(CreationError),
1480 }
1481
1482 impl<S> Display for SignOrCreationError<S> {
1483         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1484                 match self {
1485                         SignOrCreationError::SignError(_) => f.write_str("An error occurred during signing"),
1486                         SignOrCreationError::CreationError(err) => err.fmt(f),
1487                 }
1488         }
1489 }
1490
1491 #[cfg(test)]
1492 mod test {
1493         use bitcoin_hashes::hex::FromHex;
1494         use bitcoin_hashes::sha256;
1495
1496         #[test]
1497         fn test_system_time_bounds_assumptions() {
1498                 assert_eq!(
1499                         ::PositiveTimestamp::from_unix_timestamp(::MAX_TIMESTAMP + 1),
1500                         Err(::CreationError::TimestampOutOfBounds)
1501                 );
1502         }
1503
1504         #[test]
1505         fn test_calc_invoice_hash() {
1506                 use ::{RawInvoice, RawHrp, RawDataPart, Currency, PositiveTimestamp};
1507                 use ::TaggedField::*;
1508
1509                 let invoice = RawInvoice {
1510                         hrp: RawHrp {
1511                                 currency: Currency::Bitcoin,
1512                                 raw_amount: None,
1513                                 si_prefix: None,
1514                         },
1515                         data: RawDataPart {
1516                                 timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1517                                 tagged_fields: vec![
1518                                         PaymentHash(::Sha256(sha256::Hash::from_hex(
1519                                                 "0001020304050607080900010203040506070809000102030405060708090102"
1520                                         ).unwrap())).into(),
1521                                         Description(::Description::new(
1522                                                 "Please consider supporting this project".to_owned()
1523                                         ).unwrap()).into(),
1524                                 ],
1525                         },
1526                 };
1527
1528                 let expected_hash = [
1529                         0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b, 0x1d,
1530                         0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, 0xb2, 0xec,
1531                         0xd5, 0x18, 0xe1, 0xc9
1532                 ];
1533
1534                 assert_eq!(invoice.hash(), expected_hash)
1535         }
1536
1537         #[test]
1538         fn test_check_signature() {
1539                 use TaggedField::*;
1540                 use secp256k1::Secp256k1;
1541                 use secp256k1::recovery::{RecoveryId, RecoverableSignature};
1542                 use secp256k1::key::{SecretKey, PublicKey};
1543                 use {SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
1544                          PositiveTimestamp};
1545
1546                 let invoice = SignedRawInvoice {
1547                         raw_invoice: RawInvoice {
1548                                 hrp: RawHrp {
1549                                         currency: Currency::Bitcoin,
1550                                         raw_amount: None,
1551                                         si_prefix: None,
1552                                 },
1553                                 data: RawDataPart {
1554                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1555                                         tagged_fields: vec ! [
1556                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
1557                                                         "0001020304050607080900010203040506070809000102030405060708090102"
1558                                                 ).unwrap())).into(),
1559                                                 Description(
1560                                                         ::Description::new(
1561                                                                 "Please consider supporting this project".to_owned()
1562                                                         ).unwrap()
1563                                                 ).into(),
1564                                         ],
1565                                 },
1566                         },
1567                         hash: [
1568                                 0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27,
1569                                 0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7,
1570                                 0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9
1571                         ],
1572                         signature: InvoiceSignature(RecoverableSignature::from_compact(
1573                                 & [
1574                                         0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a,
1575                                         0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43,
1576                                         0x4e, 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f,
1577                                         0x42, 0x5f, 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad,
1578                                         0x0d, 0x6e, 0x35, 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9,
1579                                         0xaa, 0xb1, 0x5e, 0x57, 0x38, 0xb1, 0x1f, 0x12, 0x7f
1580                                 ],
1581                                 RecoveryId::from_i32(0).unwrap()
1582                         ).unwrap()),
1583                 };
1584
1585                 assert!(invoice.check_signature());
1586
1587                 let private_key = SecretKey::from_slice(
1588                         &[
1589                                 0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2,
1590                                 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca,
1591                                 0x3b, 0x2d, 0xb7, 0x34
1592                         ][..]
1593                 ).unwrap();
1594                 let public_key = PublicKey::from_secret_key(&Secp256k1::new(), &private_key);
1595
1596                 assert_eq!(invoice.recover_payee_pub_key(), Ok(::PayeePubKey(public_key)));
1597
1598                 let (raw_invoice, _, _) = invoice.into_parts();
1599                 let new_signed = raw_invoice.sign::<_, ()>(|hash| {
1600                         Ok(Secp256k1::new().sign_recoverable(hash, &private_key))
1601                 }).unwrap();
1602
1603                 assert!(new_signed.check_signature());
1604         }
1605
1606         #[test]
1607         fn test_check_feature_bits() {
1608                 use TaggedField::*;
1609                 use lightning::ln::features::InvoiceFeatures;
1610                 use secp256k1::Secp256k1;
1611                 use secp256k1::key::SecretKey;
1612                 use {RawInvoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, Invoice,
1613                          SemanticError};
1614
1615                 let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
1616                 let payment_secret = lightning::ln::PaymentSecret([21; 32]);
1617                 let invoice_template = RawInvoice {
1618                         hrp: RawHrp {
1619                                 currency: Currency::Bitcoin,
1620                                 raw_amount: None,
1621                                 si_prefix: None,
1622                         },
1623                         data: RawDataPart {
1624                                 timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1625                                 tagged_fields: vec ! [
1626                                         PaymentHash(Sha256(sha256::Hash::from_hex(
1627                                                 "0001020304050607080900010203040506070809000102030405060708090102"
1628                                         ).unwrap())).into(),
1629                                         Description(
1630                                                 ::Description::new(
1631                                                         "Please consider supporting this project".to_owned()
1632                                                 ).unwrap()
1633                                         ).into(),
1634                                 ],
1635                         },
1636                 };
1637
1638                 // Missing features
1639                 let invoice = {
1640                         let mut invoice = invoice_template.clone();
1641                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1642                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1643                 }.unwrap();
1644                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
1645
1646                 // Missing feature bits
1647                 let invoice = {
1648                         let mut invoice = invoice_template.clone();
1649                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1650                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
1651                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1652                 }.unwrap();
1653                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
1654
1655                 // Including payment secret and feature bits
1656                 let invoice = {
1657                         let mut invoice = invoice_template.clone();
1658                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1659                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::known()).into());
1660                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1661                 }.unwrap();
1662                 assert!(Invoice::from_signed(invoice).is_ok());
1663
1664                 // No payment secret or features
1665                 let invoice = {
1666                         let invoice = invoice_template.clone();
1667                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1668                 }.unwrap();
1669                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1670
1671                 // No payment secret or feature bits
1672                 let invoice = {
1673                         let mut invoice = invoice_template.clone();
1674                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
1675                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1676                 }.unwrap();
1677                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1678
1679                 // Missing payment secret
1680                 let invoice = {
1681                         let mut invoice = invoice_template.clone();
1682                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::known()).into());
1683                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1684                 }.unwrap();
1685                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1686
1687                 // Multiple payment secrets
1688                 let invoice = {
1689                         let mut invoice = invoice_template.clone();
1690                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1691                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1692                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1693                 }.unwrap();
1694                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::MultiplePaymentSecrets));
1695         }
1696
1697         #[test]
1698         fn test_builder_amount() {
1699                 use ::*;
1700
1701                 let builder = InvoiceBuilder::new(Currency::Bitcoin)
1702                         .description("Test".into())
1703                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1704                         .duration_since_epoch(Duration::from_secs(1234567));
1705
1706                 let invoice = builder.clone()
1707                         .amount_milli_satoshis(1500)
1708                         .build_raw()
1709                         .unwrap();
1710
1711                 assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Nano));
1712                 assert_eq!(invoice.hrp.raw_amount, Some(15));
1713
1714
1715                 let invoice = builder.clone()
1716                         .amount_milli_satoshis(150)
1717                         .build_raw()
1718                         .unwrap();
1719
1720                 assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Pico));
1721                 assert_eq!(invoice.hrp.raw_amount, Some(1500));
1722         }
1723
1724         #[test]
1725         fn test_builder_fail() {
1726                 use ::*;
1727                 use lightning::routing::router::RouteHintHop;
1728                 use std::iter::FromIterator;
1729                 use secp256k1::key::PublicKey;
1730
1731                 let builder = InvoiceBuilder::new(Currency::Bitcoin)
1732                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1733                         .duration_since_epoch(Duration::from_secs(1234567))
1734                         .min_final_cltv_expiry(144);
1735
1736                 let too_long_string = String::from_iter(
1737                         (0..1024).map(|_| '?')
1738                 );
1739
1740                 let long_desc_res = builder.clone()
1741                         .description(too_long_string)
1742                         .build_raw();
1743                 assert_eq!(long_desc_res, Err(CreationError::DescriptionTooLong));
1744
1745                 let route_hop = RouteHintHop {
1746                         src_node_id: PublicKey::from_slice(
1747                                         &[
1748                                                 0x03, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4,
1749                                                 0x3c, 0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a,
1750                                                 0x95, 0xc3, 0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
1751                                         ][..]
1752                                 ).unwrap(),
1753                         short_channel_id: 0,
1754                         fees: RoutingFees {
1755                                 base_msat: 0,
1756                                 proportional_millionths: 0,
1757                         },
1758                         cltv_expiry_delta: 0,
1759                         htlc_minimum_msat: None,
1760                         htlc_maximum_msat: None,
1761                 };
1762                 let too_long_route = RouteHint(vec![route_hop; 13]);
1763                 let long_route_res = builder.clone()
1764                         .description("Test".into())
1765                         .private_route(too_long_route)
1766                         .build_raw();
1767                 assert_eq!(long_route_res, Err(CreationError::RouteTooLong));
1768
1769                 let sign_error_res = builder.clone()
1770                         .description("Test".into())
1771                         .payment_secret(PaymentSecret([0; 32]))
1772                         .try_build_signed(|_| {
1773                                 Err("ImaginaryError")
1774                         });
1775                 assert_eq!(sign_error_res, Err(SignOrCreationError::SignError("ImaginaryError")));
1776         }
1777
1778         #[test]
1779         fn test_builder_ok() {
1780                 use ::*;
1781                 use lightning::routing::router::RouteHintHop;
1782                 use secp256k1::Secp256k1;
1783                 use secp256k1::key::{SecretKey, PublicKey};
1784                 use std::time::{UNIX_EPOCH, Duration};
1785
1786                 let secp_ctx = Secp256k1::new();
1787
1788                 let private_key = SecretKey::from_slice(
1789                         &[
1790                                 0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2,
1791                                 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca,
1792                                 0x3b, 0x2d, 0xb7, 0x34
1793                         ][..]
1794                 ).unwrap();
1795                 let public_key = PublicKey::from_secret_key(&secp_ctx, &private_key);
1796
1797                 let route_1 = RouteHint(vec![
1798                         RouteHintHop {
1799                                 src_node_id: public_key.clone(),
1800                                 short_channel_id: de::parse_int_be(&[123; 8], 256).expect("short chan ID slice too big?"),
1801                                 fees: RoutingFees {
1802                                         base_msat: 2,
1803                                         proportional_millionths: 1,
1804                                 },
1805                                 cltv_expiry_delta: 145,
1806                                 htlc_minimum_msat: None,
1807                                 htlc_maximum_msat: None,
1808                         },
1809                         RouteHintHop {
1810                                 src_node_id: public_key.clone(),
1811                                 short_channel_id: de::parse_int_be(&[42; 8], 256).expect("short chan ID slice too big?"),
1812                                 fees: RoutingFees {
1813                                         base_msat: 3,
1814                                         proportional_millionths: 2,
1815                                 },
1816                                 cltv_expiry_delta: 146,
1817                                 htlc_minimum_msat: None,
1818                                 htlc_maximum_msat: None,
1819                         }
1820                 ]);
1821
1822                 let route_2 = RouteHint(vec![
1823                         RouteHintHop {
1824                                 src_node_id: public_key.clone(),
1825                                 short_channel_id: 0,
1826                                 fees: RoutingFees {
1827                                         base_msat: 4,
1828                                         proportional_millionths: 3,
1829                                 },
1830                                 cltv_expiry_delta: 147,
1831                                 htlc_minimum_msat: None,
1832                                 htlc_maximum_msat: None,
1833                         },
1834                         RouteHintHop {
1835                                 src_node_id: public_key.clone(),
1836                                 short_channel_id: de::parse_int_be(&[1; 8], 256).expect("short chan ID slice too big?"),
1837                                 fees: RoutingFees {
1838                                         base_msat: 5,
1839                                         proportional_millionths: 4,
1840                                 },
1841                                 cltv_expiry_delta: 148,
1842                                 htlc_minimum_msat: None,
1843                                 htlc_maximum_msat: None,
1844                         }
1845                 ]);
1846
1847                 let builder = InvoiceBuilder::new(Currency::BitcoinTestnet)
1848                         .amount_milli_satoshis(123)
1849                         .duration_since_epoch(Duration::from_secs(1234567))
1850                         .payee_pub_key(public_key.clone())
1851                         .expiry_time(Duration::from_secs(54321))
1852                         .min_final_cltv_expiry(144)
1853                         .fallback(Fallback::PubKeyHash([0;20]))
1854                         .private_route(route_1.clone())
1855                         .private_route(route_2.clone())
1856                         .description_hash(sha256::Hash::from_slice(&[3;32][..]).unwrap())
1857                         .payment_hash(sha256::Hash::from_slice(&[21;32][..]).unwrap())
1858                         .payment_secret(PaymentSecret([42; 32]))
1859                         .basic_mpp();
1860
1861                 let invoice = builder.clone().build_signed(|hash| {
1862                         secp_ctx.sign_recoverable(hash, &private_key)
1863                 }).unwrap();
1864
1865                 assert!(invoice.check_signature().is_ok());
1866                 assert_eq!(invoice.tagged_fields().count(), 10);
1867
1868                 assert_eq!(invoice.amount_milli_satoshis(), Some(123));
1869                 assert_eq!(invoice.amount_pico_btc(), Some(1230));
1870                 assert_eq!(invoice.currency(), Currency::BitcoinTestnet);
1871                 #[cfg(feature = "std")]
1872                 assert_eq!(
1873                         invoice.timestamp().duration_since(UNIX_EPOCH).unwrap().as_secs(),
1874                         1234567
1875                 );
1876                 assert_eq!(invoice.payee_pub_key(), Some(&public_key));
1877                 assert_eq!(invoice.expiry_time(), Duration::from_secs(54321));
1878                 assert_eq!(invoice.min_final_cltv_expiry(), 144);
1879                 assert_eq!(invoice.fallbacks(), vec![&Fallback::PubKeyHash([0;20])]);
1880                 assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]);
1881                 assert_eq!(
1882                         invoice.description(),
1883                         InvoiceDescription::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap()))
1884                 );
1885                 assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&[21;32][..]).unwrap());
1886                 assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32]));
1887                 assert_eq!(invoice.features(), Some(&InvoiceFeatures::known()));
1888
1889                 let raw_invoice = builder.build_raw().unwrap();
1890                 assert_eq!(raw_invoice, *invoice.into_signed_raw().raw_invoice())
1891         }
1892
1893         #[test]
1894         fn test_default_values() {
1895                 use ::*;
1896                 use secp256k1::Secp256k1;
1897                 use secp256k1::key::SecretKey;
1898
1899                 let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
1900                         .description("Test".into())
1901                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1902                         .payment_secret(PaymentSecret([0; 32]))
1903                         .duration_since_epoch(Duration::from_secs(1234567))
1904                         .build_raw()
1905                         .unwrap()
1906                         .sign::<_, ()>(|hash| {
1907                                 let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
1908                                 let secp_ctx = Secp256k1::new();
1909                                 Ok(secp_ctx.sign_recoverable(hash, &privkey))
1910                         })
1911                         .unwrap();
1912                 let invoice = Invoice::from_signed(signed_invoice).unwrap();
1913
1914                 assert_eq!(invoice.min_final_cltv_expiry(), DEFAULT_MIN_FINAL_CLTV_EXPIRY);
1915                 assert_eq!(invoice.expiry_time(), Duration::from_secs(DEFAULT_EXPIRY_TIME));
1916                 assert!(!invoice.would_expire(Duration::from_secs(1234568)));
1917         }
1918
1919         #[test]
1920         fn test_expiration() {
1921                 use ::*;
1922                 use secp256k1::Secp256k1;
1923                 use secp256k1::key::SecretKey;
1924
1925                 let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
1926                         .description("Test".into())
1927                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1928                         .payment_secret(PaymentSecret([0; 32]))
1929                         .duration_since_epoch(Duration::from_secs(1234567))
1930                         .build_raw()
1931                         .unwrap()
1932                         .sign::<_, ()>(|hash| {
1933                                 let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
1934                                 let secp_ctx = Secp256k1::new();
1935                                 Ok(secp_ctx.sign_recoverable(hash, &privkey))
1936                         })
1937                         .unwrap();
1938                 let invoice = Invoice::from_signed(signed_invoice).unwrap();
1939
1940                 assert!(invoice.would_expire(Duration::from_secs(1234567 + DEFAULT_EXPIRY_TIME + 1)));
1941         }
1942 }