1dd7123a486d1077f1295b7655b1fac497cfb57f
[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(docsrs, feature(doc_auto_cfg))]
9
10 #![cfg_attr(feature = "strict", deny(warnings))]
11 #![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
12
13 //! This crate provides data structures to represent
14 //! [lightning BOLT11](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md)
15 //! invoices and functions to create, encode and decode these. If you just want to use the standard
16 //! en-/decoding functionality this should get you started:
17 //!
18 //!   * For parsing use `str::parse::<Invoice>(&self)` (see the docs of `impl FromStr for Invoice`)
19 //!   * For constructing invoices use the `InvoiceBuilder`
20 //!   * For serializing invoices use the `Display`/`ToString` traits
21
22 #[cfg(not(any(feature = "std", feature = "no-std")))]
23 compile_error!("at least one of the `std` or `no-std` features must be enabled");
24
25 pub mod payment;
26 pub mod utils;
27
28 extern crate bech32;
29 extern crate bitcoin_hashes;
30 #[macro_use] extern crate lightning;
31 extern crate num_traits;
32 extern crate secp256k1;
33 extern crate alloc;
34 #[cfg(any(test, feature = "std"))]
35 extern crate core;
36
37 #[cfg(feature = "std")]
38 use std::time::SystemTime;
39
40 use bech32::u5;
41 use bitcoin_hashes::Hash;
42 use bitcoin_hashes::sha256;
43 use lightning::ln::PaymentSecret;
44 use lightning::ln::features::InvoiceFeatures;
45 #[cfg(any(doc, test))]
46 use lightning::routing::network_graph::RoutingFees;
47 use lightning::routing::router::RouteHint;
48 use lightning::util::invoice::construct_invoice_preimage;
49
50 use secp256k1::key::PublicKey;
51 use secp256k1::{Message, Secp256k1};
52 use secp256k1::recovery::RecoverableSignature;
53
54 use core::fmt::{Display, Formatter, self};
55 use core::iter::FilterMap;
56 use core::ops::Deref;
57 use core::slice::Iter;
58 use core::time::Duration;
59
60 mod de;
61 mod ser;
62 mod tb;
63
64 mod prelude {
65         #[cfg(feature = "hashbrown")]
66         extern crate hashbrown;
67
68         pub use alloc::{vec, vec::Vec, string::String, collections::VecDeque, boxed::Box};
69         #[cfg(not(feature = "hashbrown"))]
70         pub use std::collections::{HashMap, HashSet, hash_map};
71         #[cfg(feature = "hashbrown")]
72         pub use self::hashbrown::{HashMap, HashSet, hash_map};
73
74         pub use alloc::string::ToString;
75 }
76
77 use prelude::*;
78
79 /// Sync compat for std/no_std
80 #[cfg(feature = "std")]
81 mod sync {
82         pub use ::std::sync::{Mutex, MutexGuard};
83 }
84
85 /// Sync compat for std/no_std
86 #[cfg(not(feature = "std"))]
87 mod sync;
88
89 pub use de::{ParseError, ParseOrSemanticError};
90
91 /// The number of bits used to represent timestamps as defined in BOLT 11.
92 const TIMESTAMP_BITS: usize = 35;
93
94 /// The maximum timestamp as [`Duration::as_secs`] since the Unix epoch allowed by [`BOLT 11`].
95 ///
96 /// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
97 pub const MAX_TIMESTAMP: u64 = (1 << TIMESTAMP_BITS) - 1;
98
99 /// Default expiry time as defined by [BOLT 11].
100 ///
101 /// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
102 pub const DEFAULT_EXPIRY_TIME: u64 = 3600;
103
104 /// Default minimum final CLTV expiry as defined by [BOLT 11].
105 ///
106 /// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry, which is
107 /// provided in [`MIN_FINAL_CLTV_EXPIRY`].
108 ///
109 /// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
110 /// [`MIN_FINAL_CLTV_EXPIRY`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY
111 pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
112
113 /// Builder for `Invoice`s. It's the most convenient and advised way to use this library. It ensures
114 /// that only a semantically and syntactically correct Invoice can be built using it.
115 ///
116 /// ```
117 /// extern crate secp256k1;
118 /// extern crate lightning;
119 /// extern crate lightning_invoice;
120 /// extern crate bitcoin_hashes;
121 ///
122 /// use bitcoin_hashes::Hash;
123 /// use bitcoin_hashes::sha256;
124 ///
125 /// use secp256k1::Secp256k1;
126 /// use secp256k1::key::SecretKey;
127 ///
128 /// use lightning::ln::PaymentSecret;
129 ///
130 /// use lightning_invoice::{Currency, InvoiceBuilder};
131 ///
132 /// # #[cfg(not(feature = "std"))]
133 /// # fn main() {}
134 /// # #[cfg(feature = "std")]
135 /// # fn main() {
136 /// let private_key = SecretKey::from_slice(
137 ///             &[
138 ///                     0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f,
139 ///                     0xe2, 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04,
140 ///             0xa8, 0xca, 0x3b, 0x2d, 0xb7, 0x34
141 ///     ][..]
142 ///     ).unwrap();
143 ///
144 /// let payment_hash = sha256::Hash::from_slice(&[0; 32][..]).unwrap();
145 /// let payment_secret = PaymentSecret([42u8; 32]);
146 ///
147 /// let invoice = InvoiceBuilder::new(Currency::Bitcoin)
148 ///     .description("Coins pls!".into())
149 ///     .payment_hash(payment_hash)
150 ///     .payment_secret(payment_secret)
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: core::marker::PhantomData<D>,
180         phantom_h: core::marker::PhantomData<H>,
181         phantom_t: core::marker::PhantomData<T>,
182         phantom_c: core::marker::PhantomData<C>,
183         phantom_s: core::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.
274 ///
275 /// # Invariants
276 ///
277 /// The Unix timestamp representing the stored time has to be positive and no greater than
278 /// [`MAX_TIMESTAMP`].
279 #[derive(Eq, PartialEq, Debug, Clone)]
280 pub struct PositiveTimestamp(Duration);
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(Clone, Debug, Hash, Eq, PartialEq)]
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
332         Simnet,
333
334         /// Bitcoin signet
335         Signet,
336 }
337
338 /// Tagged field which may have an unknown tag
339 ///
340 /// (C-not exported) as we don't currently support TaggedField
341 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
342 pub enum RawTaggedField {
343         /// Parsed tagged field with known tag
344         KnownSemantics(TaggedField),
345         /// tagged field which was not parsed due to an unknown tag or undefined field semantics
346         UnknownSemantics(Vec<u5>),
347 }
348
349 /// Tagged field with known tag
350 ///
351 /// For descriptions of the enum values please refer to the enclosed type's docs.
352 ///
353 /// (C-not exported) As we don't yet support enum variants with the same name the struct contained
354 /// in the variant.
355 #[allow(missing_docs)]
356 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
357 pub enum TaggedField {
358         PaymentHash(Sha256),
359         Description(Description),
360         PayeePubKey(PayeePubKey),
361         DescriptionHash(Sha256),
362         ExpiryTime(ExpiryTime),
363         MinFinalCltvExpiry(MinFinalCltvExpiry),
364         Fallback(Fallback),
365         PrivateRoute(PrivateRoute),
366         PaymentSecret(PaymentSecret),
367         Features(InvoiceFeatures),
368 }
369
370 /// SHA-256 hash
371 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
372 pub struct Sha256(/// (C-not exported) as the native hash types are not currently mapped
373         pub sha256::Hash);
374
375 /// Description string
376 ///
377 /// # Invariants
378 /// The description can be at most 639 __bytes__ long
379 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
380 pub struct Description(String);
381
382 /// Payee public key
383 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
384 pub struct PayeePubKey(pub PublicKey);
385
386 /// Positive duration that defines when (relatively to the timestamp) in the future the invoice
387 /// expires
388 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
389 pub struct ExpiryTime(Duration);
390
391 /// `min_final_cltv_expiry` to use for the last HTLC in the route
392 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
393 pub struct MinFinalCltvExpiry(pub u64);
394
395 // TODO: better types instead onf byte arrays
396 /// Fallback address in case no LN payment is possible
397 #[allow(missing_docs)]
398 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
399 pub enum Fallback {
400         SegWitProgram {
401                 version: u5,
402                 program: Vec<u8>,
403         },
404         PubKeyHash([u8; 20]),
405         ScriptHash([u8; 20]),
406 }
407
408 /// Recoverable signature
409 #[derive(Clone, Debug, Eq, PartialEq)]
410 pub struct InvoiceSignature(pub RecoverableSignature);
411
412 /// Private routing information
413 ///
414 /// # Invariants
415 /// The encoded route has to be <1024 5bit characters long (<=639 bytes or <=12 hops)
416 ///
417 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
418 pub struct PrivateRoute(RouteHint);
419
420 /// Tag constants as specified in BOLT11
421 #[allow(missing_docs)]
422 pub mod constants {
423         pub const TAG_PAYMENT_HASH: u8 = 1;
424         pub const TAG_DESCRIPTION: u8 = 13;
425         pub const TAG_PAYEE_PUB_KEY: u8 = 19;
426         pub const TAG_DESCRIPTION_HASH: u8 = 23;
427         pub const TAG_EXPIRY_TIME: u8 = 6;
428         pub const TAG_MIN_FINAL_CLTV_EXPIRY: u8 = 24;
429         pub const TAG_FALLBACK: u8 = 9;
430         pub const TAG_PRIVATE_ROUTE: u8 = 3;
431         pub const TAG_PAYMENT_SECRET: u8 = 16;
432         pub const TAG_FEATURES: u8 = 5;
433 }
434
435 impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False> {
436         /// Construct new, empty `InvoiceBuilder`. All necessary fields have to be filled first before
437         /// `InvoiceBuilder::build(self)` becomes available.
438         pub fn new(currrency: Currency) -> Self {
439                 InvoiceBuilder {
440                         currency: currrency,
441                         amount: None,
442                         si_prefix: None,
443                         timestamp: None,
444                         tagged_fields: Vec::new(),
445                         error: None,
446
447                         phantom_d: core::marker::PhantomData,
448                         phantom_h: core::marker::PhantomData,
449                         phantom_t: core::marker::PhantomData,
450                         phantom_c: core::marker::PhantomData,
451                         phantom_s: core::marker::PhantomData,
452                 }
453         }
454 }
455
456 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T, C, S> {
457         /// Helper function to set the completeness flags.
458         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> {
459                 InvoiceBuilder::<DN, HN, TN, CN, SN> {
460                         currency: self.currency,
461                         amount: self.amount,
462                         si_prefix: self.si_prefix,
463                         timestamp: self.timestamp,
464                         tagged_fields: self.tagged_fields,
465                         error: self.error,
466
467                         phantom_d: core::marker::PhantomData,
468                         phantom_h: core::marker::PhantomData,
469                         phantom_t: core::marker::PhantomData,
470                         phantom_c: core::marker::PhantomData,
471                         phantom_s: core::marker::PhantomData,
472                 }
473         }
474
475         /// Sets the amount in millisatoshis. The optimal SI prefix is chosen automatically.
476         pub fn amount_milli_satoshis(mut self, amount_msat: u64) -> Self {
477                 let amount = amount_msat * 10; // Invoices are denominated in "pico BTC"
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                 self.tagged_fields.push(TaggedField::ExpiryTime(ExpiryTime::from_duration(expiry_time)));
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 private_route(mut self, hint: RouteHint) -> Self {
507                 match PrivateRoute::new(hint) {
508                         Ok(r) => self.tagged_fields.push(TaggedField::PrivateRoute(r)),
509                         Err(e) => self.error = Some(e),
510                 }
511                 self
512         }
513 }
514
515 impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb::True, C, S> {
516         /// Builds a `RawInvoice` if no `CreationError` occurred while construction any of the fields.
517         pub fn build_raw(self) -> Result<RawInvoice, CreationError> {
518
519                 // If an error occurred at any time before, return it now
520                 if let Some(e) = self.error {
521                         return Err(e);
522                 }
523
524                 let hrp = RawHrp {
525                         currency: self.currency,
526                         raw_amount: self.amount,
527                         si_prefix: self.si_prefix,
528                 };
529
530                 let timestamp = self.timestamp.expect("ensured to be Some(t) by type T");
531
532                 let tagged_fields = self.tagged_fields.into_iter().map(|tf| {
533                         RawTaggedField::KnownSemantics(tf)
534                 }).collect::<Vec<_>>();
535
536                 let data = RawDataPart {
537                         timestamp: timestamp,
538                         tagged_fields: tagged_fields,
539                 };
540
541                 Ok(RawInvoice {
542                         hrp: hrp,
543                         data: data,
544                 })
545         }
546 }
547
548 impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<tb::False, H, T, C, S> {
549         /// Set the description. This function is only available if no description (hash) was set.
550         pub fn description(mut self, description: String) -> InvoiceBuilder<tb::True, H, T, C, S> {
551                 match Description::new(description) {
552                         Ok(d) => self.tagged_fields.push(TaggedField::Description(d)),
553                         Err(e) => self.error = Some(e),
554                 }
555                 self.set_flags()
556         }
557
558         /// Set the description hash. This function is only available if no description (hash) was set.
559         pub fn description_hash(mut self, description_hash: sha256::Hash) -> InvoiceBuilder<tb::True, H, T, C, S> {
560                 self.tagged_fields.push(TaggedField::DescriptionHash(Sha256(description_hash)));
561                 self.set_flags()
562         }
563 }
564
565 impl<D: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, tb::False, T, C, S> {
566         /// Set the payment hash. This function is only available if no payment hash was set.
567         pub fn payment_hash(mut self, hash: sha256::Hash) -> InvoiceBuilder<D, tb::True, T, C, S> {
568                 self.tagged_fields.push(TaggedField::PaymentHash(Sha256(hash)));
569                 self.set_flags()
570         }
571 }
572
573 impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb::False, C, S> {
574         /// Sets the timestamp to a specific [`SystemTime`].
575         #[cfg(feature = "std")]
576         pub fn timestamp(mut self, time: SystemTime) -> InvoiceBuilder<D, H, tb::True, C, S> {
577                 match PositiveTimestamp::from_system_time(time) {
578                         Ok(t) => self.timestamp = Some(t),
579                         Err(e) => self.error = Some(e),
580                 }
581
582                 self.set_flags()
583         }
584
585         /// Sets the timestamp to a duration since the Unix epoch.
586         pub fn duration_since_epoch(mut self, time: Duration) -> InvoiceBuilder<D, H, tb::True, C, S> {
587                 match PositiveTimestamp::from_duration_since_epoch(time) {
588                         Ok(t) => self.timestamp = Some(t),
589                         Err(e) => self.error = Some(e),
590                 }
591
592                 self.set_flags()
593         }
594
595         /// Sets the timestamp to the current system time.
596         #[cfg(feature = "std")]
597         pub fn current_timestamp(mut self) -> InvoiceBuilder<D, H, tb::True, C, S> {
598                 let now = PositiveTimestamp::from_system_time(SystemTime::now());
599                 self.timestamp = Some(now.expect("for the foreseeable future this shouldn't happen"));
600                 self.set_flags()
601         }
602 }
603
604 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T, tb::False, S> {
605         /// Sets `min_final_cltv_expiry`.
606         pub fn min_final_cltv_expiry(mut self, min_final_cltv_expiry: u64) -> InvoiceBuilder<D, H, T, tb::True, S> {
607                 self.tagged_fields.push(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry(min_final_cltv_expiry)));
608                 self.set_flags()
609         }
610 }
611
612 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T, C, tb::False> {
613         /// Sets the payment secret and relevant features.
614         pub fn payment_secret(mut self, payment_secret: PaymentSecret) -> InvoiceBuilder<D, H, T, C, tb::True> {
615                 let mut features = InvoiceFeatures::empty();
616                 features.set_variable_length_onion_required();
617                 features.set_payment_secret_required();
618                 self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret));
619                 self.tagged_fields.push(TaggedField::Features(features));
620                 self.set_flags()
621         }
622 }
623
624 impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T, C, tb::True> {
625         /// Sets the `basic_mpp` feature as optional.
626         pub fn basic_mpp(mut self) -> Self {
627                 for field in self.tagged_fields.iter_mut() {
628                         if let TaggedField::Features(f) = field {
629                                 f.set_basic_mpp_optional();
630                         }
631                 }
632                 self
633         }
634 }
635
636 impl InvoiceBuilder<tb::True, tb::True, tb::True, tb::True, tb::True> {
637         /// Builds and signs an invoice using the supplied `sign_function`. This function MAY NOT fail
638         /// and MUST produce a recoverable signature valid for the given hash and if applicable also for
639         /// the included payee public key.
640         pub fn build_signed<F>(self, sign_function: F) -> Result<Invoice, CreationError>
641                 where F: FnOnce(&Message) -> RecoverableSignature
642         {
643                 let invoice = self.try_build_signed::<_, ()>(|hash| {
644                         Ok(sign_function(hash))
645                 });
646
647                 match invoice {
648                         Ok(i) => Ok(i),
649                         Err(SignOrCreationError::CreationError(e)) => Err(e),
650                         Err(SignOrCreationError::SignError(())) => unreachable!(),
651                 }
652         }
653
654         /// Builds and signs an invoice using the supplied `sign_function`. This function MAY fail with
655         /// an error of type `E` and MUST produce a recoverable signature valid for the given hash and
656         /// if applicable also for the included payee public key.
657         pub fn try_build_signed<F, E>(self, sign_function: F) -> Result<Invoice, SignOrCreationError<E>>
658                 where F: FnOnce(&Message) -> Result<RecoverableSignature, E>
659         {
660                 let raw = match self.build_raw() {
661                         Ok(r) => r,
662                         Err(e) => return Err(SignOrCreationError::CreationError(e)),
663                 };
664
665                 let signed = match raw.sign(sign_function) {
666                         Ok(s) => s,
667                         Err(e) => return Err(SignOrCreationError::SignError(e)),
668                 };
669
670                 let invoice = Invoice {
671                         signed_invoice: signed,
672                 };
673
674                 invoice.check_field_counts().expect("should be ensured by type signature of builder");
675                 invoice.check_feature_bits().expect("should be ensured by type signature of builder");
676                 invoice.check_amount().expect("should be ensured by type signature of builder");
677
678                 Ok(invoice)
679         }
680 }
681
682
683 impl SignedRawInvoice {
684         /// Disassembles the `SignedRawInvoice` into its three parts:
685         ///  1. raw invoice
686         ///  2. hash of the raw invoice
687         ///  3. signature
688         pub fn into_parts(self) -> (RawInvoice, [u8; 32], InvoiceSignature) {
689                 (self.raw_invoice, self.hash, self.signature)
690         }
691
692         /// The `RawInvoice` which was signed.
693         pub fn raw_invoice(&self) -> &RawInvoice {
694                 &self.raw_invoice
695         }
696
697         /// The hash of the `RawInvoice` that was signed.
698         pub fn hash(&self) -> &[u8; 32] {
699                 &self.hash
700         }
701
702         /// InvoiceSignature for the invoice.
703         pub fn signature(&self) -> &InvoiceSignature {
704                 &self.signature
705         }
706
707         /// Recovers the public key used for signing the invoice from the recoverable signature.
708         pub fn recover_payee_pub_key(&self) -> Result<PayeePubKey, secp256k1::Error> {
709                 let hash = Message::from_slice(&self.hash[..])
710                         .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
711
712                 Ok(PayeePubKey(Secp256k1::new().recover(
713                         &hash,
714                         &self.signature
715                 )?))
716         }
717
718         /// Checks if the signature is valid for the included payee public key or if none exists if it's
719         /// valid for the recovered signature (which should always be true?).
720         pub fn check_signature(&self) -> bool {
721                 let included_pub_key = self.raw_invoice.payee_pub_key();
722
723                 let mut recovered_pub_key = Option::None;
724                 if recovered_pub_key.is_none() {
725                         let recovered = match self.recover_payee_pub_key() {
726                                 Ok(pk) => pk,
727                                 Err(_) => return false,
728                         };
729                         recovered_pub_key = Some(recovered);
730                 }
731
732                 let pub_key = included_pub_key.or_else(|| recovered_pub_key.as_ref())
733                         .expect("One is always present");
734
735                 let hash = Message::from_slice(&self.hash[..])
736                         .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
737
738                 let secp_context = Secp256k1::new();
739                 let verification_result = secp_context.verify(
740                         &hash,
741                         &self.signature.to_standard(),
742                         pub_key
743                 );
744
745                 match verification_result {
746                         Ok(()) => true,
747                         Err(_) => false,
748                 }
749         }
750 }
751
752 /// Finds the first element of an enum stream of a given variant and extracts one member of the
753 /// variant. If no element was found `None` gets returned.
754 ///
755 /// The following example would extract the first B.
756 /// ```
757 /// use Enum::*
758 ///
759 /// enum Enum {
760 ///     A(u8),
761 ///     B(u16)
762 /// }
763 ///
764 /// let elements = vec![A(1), A(2), B(3), A(4)]
765 ///
766 /// assert_eq!(find_extract!(elements.iter(), Enum::B(ref x), x), Some(3u16))
767 /// ```
768 macro_rules! find_extract {
769         ($iter:expr, $enm:pat, $enm_var:ident) => {
770                 find_all_extract!($iter, $enm, $enm_var).next()
771         };
772 }
773
774 /// Finds the all elements of an enum stream of a given variant and extracts one member of the
775 /// variant through an iterator.
776 ///
777 /// The following example would extract all A.
778 /// ```
779 /// use Enum::*
780 ///
781 /// enum Enum {
782 ///     A(u8),
783 ///     B(u16)
784 /// }
785 ///
786 /// let elements = vec![A(1), A(2), B(3), A(4)]
787 ///
788 /// assert_eq!(
789 ///     find_all_extract!(elements.iter(), Enum::A(ref x), x).collect::<Vec<u8>>(),
790 ///     vec![1u8, 2u8, 4u8])
791 /// ```
792 macro_rules! find_all_extract {
793         ($iter:expr, $enm:pat, $enm_var:ident) => {
794                 $iter.filter_map(|tf| match *tf {
795                         $enm => Some($enm_var),
796                         _ => None,
797                 })
798         };
799 }
800
801 #[allow(missing_docs)]
802 impl RawInvoice {
803         /// Hash the HRP as bytes and signatureless data part.
804         fn hash_from_parts(hrp_bytes: &[u8], data_without_signature: &[u5]) -> [u8; 32] {
805                 let preimage = construct_invoice_preimage(hrp_bytes, data_without_signature);
806                 let mut hash: [u8; 32] = Default::default();
807                 hash.copy_from_slice(&sha256::Hash::hash(&preimage)[..]);
808                 hash
809         }
810
811         /// Calculate the hash of the encoded `RawInvoice`
812         pub fn hash(&self) -> [u8; 32] {
813                 use bech32::ToBase32;
814
815                 RawInvoice::hash_from_parts(
816                         self.hrp.to_string().as_bytes(),
817                         &self.data.to_base32()
818                 )
819         }
820
821         /// Signs the invoice using the supplied `sign_function`. This function MAY fail with an error
822         /// of type `E`. Since the signature of a `SignedRawInvoice` is not required to be valid there
823         /// are no constraints regarding the validity of the produced signature.
824         ///
825         /// (C-not exported) As we don't currently support passing function pointers into methods
826         /// explicitly.
827         pub fn sign<F, E>(self, sign_method: F) -> Result<SignedRawInvoice, E>
828                 where F: FnOnce(&Message) -> Result<RecoverableSignature, E>
829         {
830                 let raw_hash = self.hash();
831                 let hash = Message::from_slice(&raw_hash[..])
832                         .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
833                 let signature = sign_method(&hash)?;
834
835                 Ok(SignedRawInvoice {
836                         raw_invoice: self,
837                         hash: raw_hash,
838                         signature: InvoiceSignature(signature),
839                 })
840         }
841
842         /// Returns an iterator over all tagged fields with known semantics.
843         ///
844         /// (C-not exported) As there is not yet a manual mapping for a FilterMap
845         pub fn known_tagged_fields(&self)
846                 -> FilterMap<Iter<RawTaggedField>, fn(&RawTaggedField) -> Option<&TaggedField>>
847         {
848                 // For 1.14.0 compatibility: closures' types can't be written an fn()->() in the
849                 // function's type signature.
850                 // TODO: refactor once impl Trait is available
851                 fn match_raw(raw: &RawTaggedField) -> Option<&TaggedField> {
852                         match *raw {
853                                 RawTaggedField::KnownSemantics(ref tf) => Some(tf),
854                                 _ => None,
855                         }
856                 }
857
858                 self.data.tagged_fields.iter().filter_map(match_raw )
859         }
860
861         pub fn payment_hash(&self) -> Option<&Sha256> {
862                 find_extract!(self.known_tagged_fields(), TaggedField::PaymentHash(ref x), x)
863         }
864
865         pub fn description(&self) -> Option<&Description> {
866                 find_extract!(self.known_tagged_fields(), TaggedField::Description(ref x), x)
867         }
868
869         pub fn payee_pub_key(&self) -> Option<&PayeePubKey> {
870                 find_extract!(self.known_tagged_fields(), TaggedField::PayeePubKey(ref x), x)
871         }
872
873         pub fn description_hash(&self) -> Option<&Sha256> {
874                 find_extract!(self.known_tagged_fields(), TaggedField::DescriptionHash(ref x), x)
875         }
876
877         pub fn expiry_time(&self) -> Option<&ExpiryTime> {
878                 find_extract!(self.known_tagged_fields(), TaggedField::ExpiryTime(ref x), x)
879         }
880
881         pub fn min_final_cltv_expiry(&self) -> Option<&MinFinalCltvExpiry> {
882                 find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiry(ref x), x)
883         }
884
885         pub fn payment_secret(&self) -> Option<&PaymentSecret> {
886                 find_extract!(self.known_tagged_fields(), TaggedField::PaymentSecret(ref x), x)
887         }
888
889         pub fn features(&self) -> Option<&InvoiceFeatures> {
890                 find_extract!(self.known_tagged_fields(), TaggedField::Features(ref x), x)
891         }
892
893         /// (C-not exported) as we don't support Vec<&NonOpaqueType>
894         pub fn fallbacks(&self) -> Vec<&Fallback> {
895                 find_all_extract!(self.known_tagged_fields(), TaggedField::Fallback(ref x), x).collect()
896         }
897
898         pub fn private_routes(&self) -> Vec<&PrivateRoute> {
899                 find_all_extract!(self.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x).collect()
900         }
901
902         pub fn amount_pico_btc(&self) -> Option<u64> {
903                 self.hrp.raw_amount.map(|v| {
904                         v * self.hrp.si_prefix.as_ref().map_or(1_000_000_000_000, |si| { si.multiplier() })
905                 })
906         }
907
908         pub fn currency(&self) -> Currency {
909                 self.hrp.currency.clone()
910         }
911 }
912
913 impl PositiveTimestamp {
914         /// Creates a `PositiveTimestamp` from a Unix timestamp in the range `0..=MAX_TIMESTAMP`.
915         ///
916         /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
917         pub fn from_unix_timestamp(unix_seconds: u64) -> Result<Self, CreationError> {
918                 Self::from_duration_since_epoch(Duration::from_secs(unix_seconds))
919         }
920
921         /// Creates a `PositiveTimestamp` from a [`SystemTime`] with a corresponding Unix timestamp in
922         /// the range `0..=MAX_TIMESTAMP`.
923         ///
924         /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
925         #[cfg(feature = "std")]
926         pub fn from_system_time(time: SystemTime) -> Result<Self, CreationError> {
927                 time.duration_since(SystemTime::UNIX_EPOCH)
928                         .map(Self::from_duration_since_epoch)
929                         .unwrap_or(Err(CreationError::TimestampOutOfBounds))
930         }
931
932         /// Creates a `PositiveTimestamp` from a [`Duration`] since the Unix epoch in the range
933         /// `0..=MAX_TIMESTAMP`.
934         ///
935         /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
936         pub fn from_duration_since_epoch(duration: Duration) -> Result<Self, CreationError> {
937                 if duration.as_secs() <= MAX_TIMESTAMP {
938                         Ok(PositiveTimestamp(duration))
939                 } else {
940                         Err(CreationError::TimestampOutOfBounds)
941                 }
942         }
943
944         /// Returns the Unix timestamp representing the stored time
945         pub fn as_unix_timestamp(&self) -> u64 {
946                 self.0.as_secs()
947         }
948
949         /// Returns the duration of the stored time since the Unix epoch
950         pub fn as_duration_since_epoch(&self) -> Duration {
951                 self.0
952         }
953
954         /// Returns the [`SystemTime`] representing the stored time
955         #[cfg(feature = "std")]
956         pub fn as_time(&self) -> SystemTime {
957                 SystemTime::UNIX_EPOCH + self.0
958         }
959 }
960
961 #[cfg(feature = "std")]
962 impl Into<SystemTime> for PositiveTimestamp {
963         fn into(self) -> SystemTime {
964                 SystemTime::UNIX_EPOCH + self.0
965         }
966 }
967
968 impl Invoice {
969         /// Transform the `Invoice` into it's unchecked version
970         pub fn into_signed_raw(self) -> SignedRawInvoice {
971                 self.signed_invoice
972         }
973
974         /// Check that all mandatory fields are present
975         fn check_field_counts(&self) -> Result<(), SemanticError> {
976                 // "A writer MUST include exactly one p field […]."
977                 let payment_hash_cnt = self.tagged_fields().filter(|&tf| match *tf {
978                         TaggedField::PaymentHash(_) => true,
979                         _ => false,
980                 }).count();
981                 if payment_hash_cnt < 1 {
982                         return Err(SemanticError::NoPaymentHash);
983                 } else if payment_hash_cnt > 1 {
984                         return Err(SemanticError::MultiplePaymentHashes);
985                 }
986
987                 // "A writer MUST include either exactly one d or exactly one h field."
988                 let description_cnt = self.tagged_fields().filter(|&tf| match *tf {
989                         TaggedField::Description(_) | TaggedField::DescriptionHash(_) => true,
990                         _ => false,
991                 }).count();
992                 if  description_cnt < 1 {
993                         return Err(SemanticError::NoDescription);
994                 } else if description_cnt > 1 {
995                         return  Err(SemanticError::MultipleDescriptions);
996                 }
997
998                 self.check_payment_secret()?;
999
1000                 Ok(())
1001         }
1002
1003         /// Checks that there is exactly one payment secret field
1004         fn check_payment_secret(&self) -> Result<(), SemanticError> {
1005                 // "A writer MUST include exactly one `s` field."
1006                 let payment_secret_count = self.tagged_fields().filter(|&tf| match *tf {
1007                         TaggedField::PaymentSecret(_) => true,
1008                         _ => false,
1009                 }).count();
1010                 if payment_secret_count < 1 {
1011                         return Err(SemanticError::NoPaymentSecret);
1012                 } else if payment_secret_count > 1 {
1013                         return Err(SemanticError::MultiplePaymentSecrets);
1014                 }
1015
1016                 Ok(())
1017         }
1018
1019         /// Check that amount is a whole number of millisatoshis
1020         fn check_amount(&self) -> Result<(), SemanticError> {
1021                 if let Some(amount_pico_btc) = self.amount_pico_btc() {
1022                         if amount_pico_btc % 10 != 0 {
1023                                 return Err(SemanticError::ImpreciseAmount);
1024                         }
1025                 }
1026                 Ok(())
1027         }
1028
1029         /// Check that feature bits are set as required
1030         fn check_feature_bits(&self) -> Result<(), SemanticError> {
1031                 self.check_payment_secret()?;
1032
1033                 // "A writer MUST set an s field if and only if the payment_secret feature is set."
1034                 // (this requirement has been since removed, and we now require the payment secret
1035                 // feature bit always).
1036                 let features = self.tagged_fields().find(|&tf| match *tf {
1037                         TaggedField::Features(_) => true,
1038                         _ => false,
1039                 });
1040                 match features {
1041                         None => Err(SemanticError::InvalidFeatures),
1042                         Some(TaggedField::Features(features)) => {
1043                                 if features.requires_unknown_bits() {
1044                                         Err(SemanticError::InvalidFeatures)
1045                                 } else if !features.supports_payment_secret() {
1046                                         Err(SemanticError::InvalidFeatures)
1047                                 } else {
1048                                         Ok(())
1049                                 }
1050                         },
1051                         Some(_) => unreachable!(),
1052                 }
1053         }
1054
1055         /// Check that the invoice is signed correctly and that key recovery works
1056         pub fn check_signature(&self) -> Result<(), SemanticError> {
1057                 match self.signed_invoice.recover_payee_pub_key() {
1058                         Err(secp256k1::Error::InvalidRecoveryId) =>
1059                                 return Err(SemanticError::InvalidRecoveryId),
1060                         Err(secp256k1::Error::InvalidSignature) =>
1061                                 return Err(SemanticError::InvalidSignature),
1062                         Err(e) => panic!("no other error may occur, got {:?}", e),
1063                         Ok(_) => {},
1064                 }
1065
1066                 if !self.signed_invoice.check_signature() {
1067                         return Err(SemanticError::InvalidSignature);
1068                 }
1069
1070                 Ok(())
1071         }
1072
1073         /// Constructs an `Invoice` from a `SignedRawInvoice` by checking all its invariants.
1074         /// ```
1075         /// use lightning_invoice::*;
1076         ///
1077         /// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
1078         /// h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
1079         /// 5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
1080         /// h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
1081         /// j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
1082         /// ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
1083         /// guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
1084         /// ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
1085         /// p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
1086         /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
1087         /// j5r6drg6k6zcqj0fcwg";
1088         ///
1089         /// let signed = invoice.parse::<SignedRawInvoice>().unwrap();
1090         ///
1091         /// assert!(Invoice::from_signed(signed).is_ok());
1092         /// ```
1093         pub fn from_signed(signed_invoice: SignedRawInvoice) -> Result<Self, SemanticError> {
1094                 let invoice = Invoice {
1095                         signed_invoice: signed_invoice,
1096                 };
1097                 invoice.check_field_counts()?;
1098                 invoice.check_feature_bits()?;
1099                 invoice.check_signature()?;
1100                 invoice.check_amount()?;
1101
1102                 Ok(invoice)
1103         }
1104
1105         /// Returns the `Invoice`'s timestamp (should equal its creation time)
1106         #[cfg(feature = "std")]
1107         pub fn timestamp(&self) -> SystemTime {
1108                 self.signed_invoice.raw_invoice().data.timestamp.as_time()
1109         }
1110
1111         /// Returns the `Invoice`'s timestamp as a duration since the Unix epoch
1112         pub fn duration_since_epoch(&self) -> Duration {
1113                 self.signed_invoice.raw_invoice().data.timestamp.0
1114         }
1115
1116         /// Returns an iterator over all tagged fields of this Invoice.
1117         ///
1118         /// (C-not exported) As there is not yet a manual mapping for a FilterMap
1119         pub fn tagged_fields(&self)
1120                 -> FilterMap<Iter<RawTaggedField>, fn(&RawTaggedField) -> Option<&TaggedField>> {
1121                 self.signed_invoice.raw_invoice().known_tagged_fields()
1122         }
1123
1124         /// Returns the hash to which we will receive the preimage on completion of the payment
1125         pub fn payment_hash(&self) -> &sha256::Hash {
1126                 &self.signed_invoice.payment_hash().expect("checked by constructor").0
1127         }
1128
1129         /// Return the description or a hash of it for longer ones
1130         ///
1131         /// (C-not exported) because we don't yet export InvoiceDescription
1132         pub fn description(&self) -> InvoiceDescription {
1133                 if let Some(ref direct) = self.signed_invoice.description() {
1134                         return InvoiceDescription::Direct(direct);
1135                 } else if let Some(ref hash) = self.signed_invoice.description_hash() {
1136                         return InvoiceDescription::Hash(hash);
1137                 }
1138                 unreachable!("ensured by constructor");
1139         }
1140
1141         /// Get the payee's public key if one was included in the invoice
1142         pub fn payee_pub_key(&self) -> Option<&PublicKey> {
1143                 self.signed_invoice.payee_pub_key().map(|x| &x.0)
1144         }
1145
1146         /// Get the payment secret if one was included in the invoice
1147         pub fn payment_secret(&self) -> &PaymentSecret {
1148                 self.signed_invoice.payment_secret().expect("was checked by constructor")
1149         }
1150
1151         /// Get the invoice features if they were included in the invoice
1152         pub fn features(&self) -> Option<&InvoiceFeatures> {
1153                 self.signed_invoice.features()
1154         }
1155
1156         /// Recover the payee's public key (only to be used if none was included in the invoice)
1157         pub fn recover_payee_pub_key(&self) -> PublicKey {
1158                 self.signed_invoice.recover_payee_pub_key().expect("was checked by constructor").0
1159         }
1160
1161         /// Returns the invoice's expiry time, if present, otherwise [`DEFAULT_EXPIRY_TIME`].
1162         pub fn expiry_time(&self) -> Duration {
1163                 self.signed_invoice.expiry_time()
1164                         .map(|x| x.0)
1165                         .unwrap_or(Duration::from_secs(DEFAULT_EXPIRY_TIME))
1166         }
1167
1168         /// Returns whether the invoice has expired.
1169         #[cfg(feature = "std")]
1170         pub fn is_expired(&self) -> bool {
1171                 Self::is_expired_from_epoch(&self.timestamp(), self.expiry_time())
1172         }
1173
1174         /// Returns whether the expiry time from the given epoch has passed.
1175         #[cfg(feature = "std")]
1176         pub(crate) fn is_expired_from_epoch(epoch: &SystemTime, expiry_time: Duration) -> bool {
1177                 match epoch.elapsed() {
1178                         Ok(elapsed) => elapsed > expiry_time,
1179                         Err(_) => false,
1180                 }
1181         }
1182
1183         /// Returns whether the expiry time would pass at the given point in time.
1184         /// `at_time` is the timestamp as a duration since the Unix epoch.
1185         pub fn would_expire(&self, at_time: Duration) -> bool {
1186                 self.duration_since_epoch()
1187                         .checked_add(self.expiry_time())
1188                         .unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1)) < at_time
1189         }
1190
1191         /// Returns the invoice's `min_final_cltv_expiry` time, if present, otherwise
1192         /// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY`].
1193         pub fn min_final_cltv_expiry(&self) -> u64 {
1194                 self.signed_invoice.min_final_cltv_expiry()
1195                         .map(|x| x.0)
1196                         .unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY)
1197         }
1198
1199         /// Returns a list of all fallback addresses
1200         ///
1201         /// (C-not exported) as we don't support Vec<&NonOpaqueType>
1202         pub fn fallbacks(&self) -> Vec<&Fallback> {
1203                 self.signed_invoice.fallbacks()
1204         }
1205
1206         /// Returns a list of all routes included in the invoice
1207         pub fn private_routes(&self) -> Vec<&PrivateRoute> {
1208                 self.signed_invoice.private_routes()
1209         }
1210
1211         /// Returns a list of all routes included in the invoice as the underlying hints
1212         pub fn route_hints(&self) -> Vec<RouteHint> {
1213                 find_all_extract!(
1214                         self.signed_invoice.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x
1215                 ).map(|route| (**route).clone()).collect()
1216         }
1217
1218         /// Returns the currency for which the invoice was issued
1219         pub fn currency(&self) -> Currency {
1220                 self.signed_invoice.currency()
1221         }
1222
1223         /// Returns the amount if specified in the invoice as millisatoshis.
1224         pub fn amount_milli_satoshis(&self) -> Option<u64> {
1225                 self.signed_invoice.amount_pico_btc().map(|v| v / 10)
1226         }
1227
1228         /// Returns the amount if specified in the invoice as pico <currency>.
1229         fn amount_pico_btc(&self) -> Option<u64> {
1230                 self.signed_invoice.amount_pico_btc()
1231         }
1232 }
1233
1234 impl From<TaggedField> for RawTaggedField {
1235         fn from(tf: TaggedField) -> Self {
1236                 RawTaggedField::KnownSemantics(tf)
1237         }
1238 }
1239
1240 impl TaggedField {
1241         /// Numeric representation of the field's tag
1242         pub fn tag(&self) -> u5 {
1243                 let tag = match *self {
1244                         TaggedField::PaymentHash(_) => constants::TAG_PAYMENT_HASH,
1245                         TaggedField::Description(_) => constants::TAG_DESCRIPTION,
1246                         TaggedField::PayeePubKey(_) => constants::TAG_PAYEE_PUB_KEY,
1247                         TaggedField::DescriptionHash(_) => constants::TAG_DESCRIPTION_HASH,
1248                         TaggedField::ExpiryTime(_) => constants::TAG_EXPIRY_TIME,
1249                         TaggedField::MinFinalCltvExpiry(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY,
1250                         TaggedField::Fallback(_) => constants::TAG_FALLBACK,
1251                         TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE,
1252                         TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
1253                         TaggedField::Features(_) => constants::TAG_FEATURES,
1254                 };
1255
1256                 u5::try_from_u8(tag).expect("all tags defined are <32")
1257         }
1258 }
1259
1260 impl Description {
1261
1262         /// Creates a new `Description` if `description` is at most 1023 __bytes__ long,
1263         /// returns `CreationError::DescriptionTooLong` otherwise
1264         ///
1265         /// Please note that single characters may use more than one byte due to UTF8 encoding.
1266         pub fn new(description: String) -> Result<Description, CreationError> {
1267                 if description.len() > 639 {
1268                         Err(CreationError::DescriptionTooLong)
1269                 } else {
1270                         Ok(Description(description))
1271                 }
1272         }
1273
1274         /// Returns the underlying description `String`
1275         pub fn into_inner(self) -> String {
1276                 self.0
1277         }
1278 }
1279
1280 impl Into<String> for Description {
1281         fn into(self) -> String {
1282                 self.into_inner()
1283         }
1284 }
1285
1286 impl Deref for Description {
1287         type Target = str;
1288
1289         fn deref(&self) -> &str {
1290                 &self.0
1291         }
1292 }
1293
1294 impl From<PublicKey> for PayeePubKey {
1295         fn from(pk: PublicKey) -> Self {
1296                 PayeePubKey(pk)
1297         }
1298 }
1299
1300 impl Deref for PayeePubKey {
1301         type Target = PublicKey;
1302
1303         fn deref(&self) -> &PublicKey {
1304                 &self.0
1305         }
1306 }
1307
1308 impl ExpiryTime {
1309         /// Construct an `ExpiryTime` from seconds.
1310         pub fn from_seconds(seconds: u64) -> ExpiryTime {
1311                 ExpiryTime(Duration::from_secs(seconds))
1312         }
1313
1314         /// Construct an `ExpiryTime` from a `Duration`.
1315         pub fn from_duration(duration: Duration) -> ExpiryTime {
1316                 ExpiryTime(duration)
1317         }
1318
1319         /// Returns the expiry time in seconds
1320         pub fn as_seconds(&self) -> u64 {
1321                 self.0.as_secs()
1322         }
1323
1324         /// Returns a reference to the underlying `Duration` (=expiry time)
1325         pub fn as_duration(&self) -> &Duration {
1326                 &self.0
1327         }
1328 }
1329
1330 impl PrivateRoute {
1331         /// Creates a new (partial) route from a list of hops
1332         pub fn new(hops: RouteHint) -> Result<PrivateRoute, CreationError> {
1333                 if hops.0.len() <= 12 {
1334                         Ok(PrivateRoute(hops))
1335                 } else {
1336                         Err(CreationError::RouteTooLong)
1337                 }
1338         }
1339
1340         /// Returns the underlying list of hops
1341         pub fn into_inner(self) -> RouteHint {
1342                 self.0
1343         }
1344 }
1345
1346 impl Into<RouteHint> for PrivateRoute {
1347         fn into(self) -> RouteHint {
1348                 self.into_inner()
1349         }
1350 }
1351
1352 impl Deref for PrivateRoute {
1353         type Target = RouteHint;
1354
1355         fn deref(&self) -> &RouteHint {
1356                 &self.0
1357         }
1358 }
1359
1360 impl Deref for InvoiceSignature {
1361         type Target = RecoverableSignature;
1362
1363         fn deref(&self) -> &RecoverableSignature {
1364                 &self.0
1365         }
1366 }
1367
1368 impl Deref for SignedRawInvoice {
1369         type Target = RawInvoice;
1370
1371         fn deref(&self) -> &RawInvoice {
1372                 &self.raw_invoice
1373         }
1374 }
1375
1376 /// Errors that may occur when constructing a new `RawInvoice` or `Invoice`
1377 #[derive(Eq, PartialEq, Debug, Clone)]
1378 pub enum CreationError {
1379         /// The supplied description string was longer than 639 __bytes__ (see [`Description::new(…)`](./struct.Description.html#method.new))
1380         DescriptionTooLong,
1381
1382         /// The specified route has too many hops and can't be encoded
1383         RouteTooLong,
1384
1385         /// The Unix timestamp of the supplied date is less than zero or greater than 35-bits
1386         TimestampOutOfBounds,
1387
1388         /// The supplied millisatoshi amount was greater than the total bitcoin supply.
1389         InvalidAmount,
1390
1391         /// Route hints were required for this invoice and were missing. Applies to
1392         /// [phantom invoices].
1393         ///
1394         /// [phantom invoices]: crate::utils::create_phantom_invoice
1395         MissingRouteHints,
1396 }
1397
1398 impl Display for CreationError {
1399         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1400                 match self {
1401                         CreationError::DescriptionTooLong => f.write_str("The supplied description string was longer than 639 bytes"),
1402                         CreationError::RouteTooLong => f.write_str("The specified route has too many hops and can't be encoded"),
1403                         CreationError::TimestampOutOfBounds => f.write_str("The Unix timestamp of the supplied date is less than zero or greater than 35-bits"),
1404                         CreationError::InvalidAmount => f.write_str("The supplied millisatoshi amount was greater than the total bitcoin supply"),
1405                         CreationError::MissingRouteHints => f.write_str("The invoice required route hints and they weren't provided"),
1406                 }
1407         }
1408 }
1409
1410 #[cfg(feature = "std")]
1411 impl std::error::Error for CreationError { }
1412
1413 /// Errors that may occur when converting a `RawInvoice` to an `Invoice`. They relate to the
1414 /// requirements sections in BOLT #11
1415 #[derive(Eq, PartialEq, Debug, Clone)]
1416 pub enum SemanticError {
1417         /// The invoice is missing the mandatory payment hash
1418         NoPaymentHash,
1419
1420         /// The invoice has multiple payment hashes which isn't allowed
1421         MultiplePaymentHashes,
1422
1423         /// No description or description hash are part of the invoice
1424         NoDescription,
1425
1426         /// The invoice contains multiple descriptions and/or description hashes which isn't allowed
1427         MultipleDescriptions,
1428
1429         /// The invoice is missing the mandatory payment secret, which all modern lightning nodes
1430         /// should provide.
1431         NoPaymentSecret,
1432
1433         /// The invoice contains multiple payment secrets
1434         MultiplePaymentSecrets,
1435
1436         /// The invoice's features are invalid
1437         InvalidFeatures,
1438
1439         /// The recovery id doesn't fit the signature/pub key
1440         InvalidRecoveryId,
1441
1442         /// The invoice's signature is invalid
1443         InvalidSignature,
1444
1445         /// The invoice's amount was not a whole number of millisatoshis
1446         ImpreciseAmount,
1447 }
1448
1449 impl Display for SemanticError {
1450         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1451                 match self {
1452                         SemanticError::NoPaymentHash => f.write_str("The invoice is missing the mandatory payment hash"),
1453                         SemanticError::MultiplePaymentHashes => f.write_str("The invoice has multiple payment hashes which isn't allowed"),
1454                         SemanticError::NoDescription => f.write_str("No description or description hash are part of the invoice"),
1455                         SemanticError::MultipleDescriptions => f.write_str("The invoice contains multiple descriptions and/or description hashes which isn't allowed"),
1456                         SemanticError::NoPaymentSecret => f.write_str("The invoice is missing the mandatory payment secret"),
1457                         SemanticError::MultiplePaymentSecrets => f.write_str("The invoice contains multiple payment secrets"),
1458                         SemanticError::InvalidFeatures => f.write_str("The invoice's features are invalid"),
1459                         SemanticError::InvalidRecoveryId => f.write_str("The recovery id doesn't fit the signature/pub key"),
1460                         SemanticError::InvalidSignature => f.write_str("The invoice's signature is invalid"),
1461                         SemanticError::ImpreciseAmount => f.write_str("The invoice's amount was not a whole number of millisatoshis"),
1462                 }
1463         }
1464 }
1465
1466 #[cfg(feature = "std")]
1467 impl std::error::Error for SemanticError { }
1468
1469 /// When signing using a fallible method either an user-supplied `SignError` or a `CreationError`
1470 /// may occur.
1471 #[derive(Eq, PartialEq, Debug, Clone)]
1472 pub enum SignOrCreationError<S = ()> {
1473         /// An error occurred during signing
1474         SignError(S),
1475
1476         /// An error occurred while building the transaction
1477         CreationError(CreationError),
1478 }
1479
1480 impl<S> Display for SignOrCreationError<S> {
1481         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1482                 match self {
1483                         SignOrCreationError::SignError(_) => f.write_str("An error occurred during signing"),
1484                         SignOrCreationError::CreationError(err) => err.fmt(f),
1485                 }
1486         }
1487 }
1488
1489 #[cfg(test)]
1490 mod test {
1491         use bitcoin_hashes::hex::FromHex;
1492         use bitcoin_hashes::sha256;
1493
1494         #[test]
1495         fn test_system_time_bounds_assumptions() {
1496                 assert_eq!(
1497                         ::PositiveTimestamp::from_unix_timestamp(::MAX_TIMESTAMP + 1),
1498                         Err(::CreationError::TimestampOutOfBounds)
1499                 );
1500         }
1501
1502         #[test]
1503         fn test_calc_invoice_hash() {
1504                 use ::{RawInvoice, RawHrp, RawDataPart, Currency, PositiveTimestamp};
1505                 use ::TaggedField::*;
1506
1507                 let invoice = RawInvoice {
1508                         hrp: RawHrp {
1509                                 currency: Currency::Bitcoin,
1510                                 raw_amount: None,
1511                                 si_prefix: None,
1512                         },
1513                         data: RawDataPart {
1514                                 timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1515                                 tagged_fields: vec![
1516                                         PaymentHash(::Sha256(sha256::Hash::from_hex(
1517                                                 "0001020304050607080900010203040506070809000102030405060708090102"
1518                                         ).unwrap())).into(),
1519                                         Description(::Description::new(
1520                                                 "Please consider supporting this project".to_owned()
1521                                         ).unwrap()).into(),
1522                                 ],
1523                         },
1524                 };
1525
1526                 let expected_hash = [
1527                         0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b, 0x1d,
1528                         0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, 0xb2, 0xec,
1529                         0xd5, 0x18, 0xe1, 0xc9
1530                 ];
1531
1532                 assert_eq!(invoice.hash(), expected_hash)
1533         }
1534
1535         #[test]
1536         fn test_check_signature() {
1537                 use TaggedField::*;
1538                 use secp256k1::Secp256k1;
1539                 use secp256k1::recovery::{RecoveryId, RecoverableSignature};
1540                 use secp256k1::key::{SecretKey, PublicKey};
1541                 use {SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
1542                          PositiveTimestamp};
1543
1544                 let invoice = SignedRawInvoice {
1545                         raw_invoice: RawInvoice {
1546                                 hrp: RawHrp {
1547                                         currency: Currency::Bitcoin,
1548                                         raw_amount: None,
1549                                         si_prefix: None,
1550                                 },
1551                                 data: RawDataPart {
1552                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1553                                         tagged_fields: vec ! [
1554                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
1555                                                         "0001020304050607080900010203040506070809000102030405060708090102"
1556                                                 ).unwrap())).into(),
1557                                                 Description(
1558                                                         ::Description::new(
1559                                                                 "Please consider supporting this project".to_owned()
1560                                                         ).unwrap()
1561                                                 ).into(),
1562                                         ],
1563                                 },
1564                         },
1565                         hash: [
1566                                 0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27,
1567                                 0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7,
1568                                 0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9
1569                         ],
1570                         signature: InvoiceSignature(RecoverableSignature::from_compact(
1571                                 & [
1572                                         0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a,
1573                                         0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43,
1574                                         0x4e, 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f,
1575                                         0x42, 0x5f, 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad,
1576                                         0x0d, 0x6e, 0x35, 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9,
1577                                         0xaa, 0xb1, 0x5e, 0x57, 0x38, 0xb1, 0x1f, 0x12, 0x7f
1578                                 ],
1579                                 RecoveryId::from_i32(0).unwrap()
1580                         ).unwrap()),
1581                 };
1582
1583                 assert!(invoice.check_signature());
1584
1585                 let private_key = SecretKey::from_slice(
1586                         &[
1587                                 0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2,
1588                                 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca,
1589                                 0x3b, 0x2d, 0xb7, 0x34
1590                         ][..]
1591                 ).unwrap();
1592                 let public_key = PublicKey::from_secret_key(&Secp256k1::new(), &private_key);
1593
1594                 assert_eq!(invoice.recover_payee_pub_key(), Ok(::PayeePubKey(public_key)));
1595
1596                 let (raw_invoice, _, _) = invoice.into_parts();
1597                 let new_signed = raw_invoice.sign::<_, ()>(|hash| {
1598                         Ok(Secp256k1::new().sign_recoverable(hash, &private_key))
1599                 }).unwrap();
1600
1601                 assert!(new_signed.check_signature());
1602         }
1603
1604         #[test]
1605         fn test_check_feature_bits() {
1606                 use TaggedField::*;
1607                 use lightning::ln::features::InvoiceFeatures;
1608                 use secp256k1::Secp256k1;
1609                 use secp256k1::key::SecretKey;
1610                 use {RawInvoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, Invoice,
1611                          SemanticError};
1612
1613                 let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
1614                 let payment_secret = lightning::ln::PaymentSecret([21; 32]);
1615                 let invoice_template = RawInvoice {
1616                         hrp: RawHrp {
1617                                 currency: Currency::Bitcoin,
1618                                 raw_amount: None,
1619                                 si_prefix: None,
1620                         },
1621                         data: RawDataPart {
1622                                 timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1623                                 tagged_fields: vec ! [
1624                                         PaymentHash(Sha256(sha256::Hash::from_hex(
1625                                                 "0001020304050607080900010203040506070809000102030405060708090102"
1626                                         ).unwrap())).into(),
1627                                         Description(
1628                                                 ::Description::new(
1629                                                         "Please consider supporting this project".to_owned()
1630                                                 ).unwrap()
1631                                         ).into(),
1632                                 ],
1633                         },
1634                 };
1635
1636                 // Missing features
1637                 let invoice = {
1638                         let mut invoice = invoice_template.clone();
1639                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1640                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1641                 }.unwrap();
1642                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
1643
1644                 // Missing feature bits
1645                 let invoice = {
1646                         let mut invoice = invoice_template.clone();
1647                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1648                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
1649                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1650                 }.unwrap();
1651                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
1652
1653                 // Including payment secret and feature bits
1654                 let invoice = {
1655                         let mut invoice = invoice_template.clone();
1656                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1657                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::known()).into());
1658                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1659                 }.unwrap();
1660                 assert!(Invoice::from_signed(invoice).is_ok());
1661
1662                 // No payment secret or features
1663                 let invoice = {
1664                         let invoice = invoice_template.clone();
1665                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1666                 }.unwrap();
1667                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1668
1669                 // No payment secret or feature bits
1670                 let invoice = {
1671                         let mut invoice = invoice_template.clone();
1672                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
1673                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1674                 }.unwrap();
1675                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1676
1677                 // Missing payment secret
1678                 let invoice = {
1679                         let mut invoice = invoice_template.clone();
1680                         invoice.data.tagged_fields.push(Features(InvoiceFeatures::known()).into());
1681                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1682                 }.unwrap();
1683                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1684
1685                 // Multiple payment secrets
1686                 let invoice = {
1687                         let mut invoice = invoice_template.clone();
1688                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1689                         invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
1690                         invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
1691                 }.unwrap();
1692                 assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::MultiplePaymentSecrets));
1693         }
1694
1695         #[test]
1696         fn test_builder_amount() {
1697                 use ::*;
1698
1699                 let builder = InvoiceBuilder::new(Currency::Bitcoin)
1700                         .description("Test".into())
1701                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1702                         .duration_since_epoch(Duration::from_secs(1234567));
1703
1704                 let invoice = builder.clone()
1705                         .amount_milli_satoshis(1500)
1706                         .build_raw()
1707                         .unwrap();
1708
1709                 assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Nano));
1710                 assert_eq!(invoice.hrp.raw_amount, Some(15));
1711
1712
1713                 let invoice = builder.clone()
1714                         .amount_milli_satoshis(150)
1715                         .build_raw()
1716                         .unwrap();
1717
1718                 assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Pico));
1719                 assert_eq!(invoice.hrp.raw_amount, Some(1500));
1720         }
1721
1722         #[test]
1723         fn test_builder_fail() {
1724                 use ::*;
1725                 use lightning::routing::router::RouteHintHop;
1726                 use std::iter::FromIterator;
1727                 use secp256k1::key::PublicKey;
1728
1729                 let builder = InvoiceBuilder::new(Currency::Bitcoin)
1730                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1731                         .duration_since_epoch(Duration::from_secs(1234567))
1732                         .min_final_cltv_expiry(144);
1733
1734                 let too_long_string = String::from_iter(
1735                         (0..1024).map(|_| '?')
1736                 );
1737
1738                 let long_desc_res = builder.clone()
1739                         .description(too_long_string)
1740                         .build_raw();
1741                 assert_eq!(long_desc_res, Err(CreationError::DescriptionTooLong));
1742
1743                 let route_hop = RouteHintHop {
1744                         src_node_id: PublicKey::from_slice(
1745                                         &[
1746                                                 0x03, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4,
1747                                                 0x3c, 0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a,
1748                                                 0x95, 0xc3, 0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
1749                                         ][..]
1750                                 ).unwrap(),
1751                         short_channel_id: 0,
1752                         fees: RoutingFees {
1753                                 base_msat: 0,
1754                                 proportional_millionths: 0,
1755                         },
1756                         cltv_expiry_delta: 0,
1757                         htlc_minimum_msat: None,
1758                         htlc_maximum_msat: None,
1759                 };
1760                 let too_long_route = RouteHint(vec![route_hop; 13]);
1761                 let long_route_res = builder.clone()
1762                         .description("Test".into())
1763                         .private_route(too_long_route)
1764                         .build_raw();
1765                 assert_eq!(long_route_res, Err(CreationError::RouteTooLong));
1766
1767                 let sign_error_res = builder.clone()
1768                         .description("Test".into())
1769                         .payment_secret(PaymentSecret([0; 32]))
1770                         .try_build_signed(|_| {
1771                                 Err("ImaginaryError")
1772                         });
1773                 assert_eq!(sign_error_res, Err(SignOrCreationError::SignError("ImaginaryError")));
1774         }
1775
1776         #[test]
1777         fn test_builder_ok() {
1778                 use ::*;
1779                 use lightning::routing::router::RouteHintHop;
1780                 use secp256k1::Secp256k1;
1781                 use secp256k1::key::{SecretKey, PublicKey};
1782                 use std::time::{UNIX_EPOCH, Duration};
1783
1784                 let secp_ctx = Secp256k1::new();
1785
1786                 let private_key = SecretKey::from_slice(
1787                         &[
1788                                 0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2,
1789                                 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca,
1790                                 0x3b, 0x2d, 0xb7, 0x34
1791                         ][..]
1792                 ).unwrap();
1793                 let public_key = PublicKey::from_secret_key(&secp_ctx, &private_key);
1794
1795                 let route_1 = RouteHint(vec![
1796                         RouteHintHop {
1797                                 src_node_id: public_key.clone(),
1798                                 short_channel_id: de::parse_int_be(&[123; 8], 256).expect("short chan ID slice too big?"),
1799                                 fees: RoutingFees {
1800                                         base_msat: 2,
1801                                         proportional_millionths: 1,
1802                                 },
1803                                 cltv_expiry_delta: 145,
1804                                 htlc_minimum_msat: None,
1805                                 htlc_maximum_msat: None,
1806                         },
1807                         RouteHintHop {
1808                                 src_node_id: public_key.clone(),
1809                                 short_channel_id: de::parse_int_be(&[42; 8], 256).expect("short chan ID slice too big?"),
1810                                 fees: RoutingFees {
1811                                         base_msat: 3,
1812                                         proportional_millionths: 2,
1813                                 },
1814                                 cltv_expiry_delta: 146,
1815                                 htlc_minimum_msat: None,
1816                                 htlc_maximum_msat: None,
1817                         }
1818                 ]);
1819
1820                 let route_2 = RouteHint(vec![
1821                         RouteHintHop {
1822                                 src_node_id: public_key.clone(),
1823                                 short_channel_id: 0,
1824                                 fees: RoutingFees {
1825                                         base_msat: 4,
1826                                         proportional_millionths: 3,
1827                                 },
1828                                 cltv_expiry_delta: 147,
1829                                 htlc_minimum_msat: None,
1830                                 htlc_maximum_msat: None,
1831                         },
1832                         RouteHintHop {
1833                                 src_node_id: public_key.clone(),
1834                                 short_channel_id: de::parse_int_be(&[1; 8], 256).expect("short chan ID slice too big?"),
1835                                 fees: RoutingFees {
1836                                         base_msat: 5,
1837                                         proportional_millionths: 4,
1838                                 },
1839                                 cltv_expiry_delta: 148,
1840                                 htlc_minimum_msat: None,
1841                                 htlc_maximum_msat: None,
1842                         }
1843                 ]);
1844
1845                 let builder = InvoiceBuilder::new(Currency::BitcoinTestnet)
1846                         .amount_milli_satoshis(123)
1847                         .duration_since_epoch(Duration::from_secs(1234567))
1848                         .payee_pub_key(public_key.clone())
1849                         .expiry_time(Duration::from_secs(54321))
1850                         .min_final_cltv_expiry(144)
1851                         .fallback(Fallback::PubKeyHash([0;20]))
1852                         .private_route(route_1.clone())
1853                         .private_route(route_2.clone())
1854                         .description_hash(sha256::Hash::from_slice(&[3;32][..]).unwrap())
1855                         .payment_hash(sha256::Hash::from_slice(&[21;32][..]).unwrap())
1856                         .payment_secret(PaymentSecret([42; 32]))
1857                         .basic_mpp();
1858
1859                 let invoice = builder.clone().build_signed(|hash| {
1860                         secp_ctx.sign_recoverable(hash, &private_key)
1861                 }).unwrap();
1862
1863                 assert!(invoice.check_signature().is_ok());
1864                 assert_eq!(invoice.tagged_fields().count(), 10);
1865
1866                 assert_eq!(invoice.amount_milli_satoshis(), Some(123));
1867                 assert_eq!(invoice.amount_pico_btc(), Some(1230));
1868                 assert_eq!(invoice.currency(), Currency::BitcoinTestnet);
1869                 #[cfg(feature = "std")]
1870                 assert_eq!(
1871                         invoice.timestamp().duration_since(UNIX_EPOCH).unwrap().as_secs(),
1872                         1234567
1873                 );
1874                 assert_eq!(invoice.payee_pub_key(), Some(&public_key));
1875                 assert_eq!(invoice.expiry_time(), Duration::from_secs(54321));
1876                 assert_eq!(invoice.min_final_cltv_expiry(), 144);
1877                 assert_eq!(invoice.fallbacks(), vec![&Fallback::PubKeyHash([0;20])]);
1878                 assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]);
1879                 assert_eq!(
1880                         invoice.description(),
1881                         InvoiceDescription::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap()))
1882                 );
1883                 assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&[21;32][..]).unwrap());
1884                 assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32]));
1885                 assert_eq!(invoice.features(), Some(&InvoiceFeatures::known()));
1886
1887                 let raw_invoice = builder.build_raw().unwrap();
1888                 assert_eq!(raw_invoice, *invoice.into_signed_raw().raw_invoice())
1889         }
1890
1891         #[test]
1892         fn test_default_values() {
1893                 use ::*;
1894                 use secp256k1::Secp256k1;
1895                 use secp256k1::key::SecretKey;
1896
1897                 let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
1898                         .description("Test".into())
1899                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1900                         .payment_secret(PaymentSecret([0; 32]))
1901                         .duration_since_epoch(Duration::from_secs(1234567))
1902                         .build_raw()
1903                         .unwrap()
1904                         .sign::<_, ()>(|hash| {
1905                                 let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
1906                                 let secp_ctx = Secp256k1::new();
1907                                 Ok(secp_ctx.sign_recoverable(hash, &privkey))
1908                         })
1909                         .unwrap();
1910                 let invoice = Invoice::from_signed(signed_invoice).unwrap();
1911
1912                 assert_eq!(invoice.min_final_cltv_expiry(), DEFAULT_MIN_FINAL_CLTV_EXPIRY);
1913                 assert_eq!(invoice.expiry_time(), Duration::from_secs(DEFAULT_EXPIRY_TIME));
1914                 assert!(!invoice.would_expire(Duration::from_secs(1234568)));
1915         }
1916
1917         #[test]
1918         fn test_expiration() {
1919                 use ::*;
1920                 use secp256k1::Secp256k1;
1921                 use secp256k1::key::SecretKey;
1922
1923                 let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
1924                         .description("Test".into())
1925                         .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
1926                         .payment_secret(PaymentSecret([0; 32]))
1927                         .duration_since_epoch(Duration::from_secs(1234567))
1928                         .build_raw()
1929                         .unwrap()
1930                         .sign::<_, ()>(|hash| {
1931                                 let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
1932                                 let secp_ctx = Secp256k1::new();
1933                                 Ok(secp_ctx.sign_recoverable(hash, &privkey))
1934                         })
1935                         .unwrap();
1936                 let invoice = Invoice::from_signed(signed_invoice).unwrap();
1937
1938                 assert!(invoice.would_expire(Duration::from_secs(1234567 + DEFAULT_EXPIRY_TIME + 1)));
1939         }
1940 }