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