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