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