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