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