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