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