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