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