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