53f6b83da5fdf00fdd33fcf51c4f0502b32d0fa2
[rust-lightning] / lightning-invoice / src / de.rs
1 #[cfg(feature = "std")]
2 use std::error;
3 use core::fmt;
4 use core::fmt::{Display, Formatter};
5 use core::num::ParseIntError;
6 use core::str;
7 use core::str::FromStr;
8
9 use bech32;
10 use bech32::{u5, FromBase32};
11
12 use bitcoin_hashes::Hash;
13 use bitcoin_hashes::sha256;
14 use crate::prelude::*;
15 use lightning::ln::PaymentSecret;
16 use lightning::routing::network_graph::RoutingFees;
17 use lightning::routing::router::{RouteHint, RouteHintHop};
18
19 use num_traits::{CheckedAdd, CheckedMul};
20
21 use secp256k1;
22 use secp256k1::recovery::{RecoveryId, RecoverableSignature};
23 use secp256k1::key::PublicKey;
24
25 use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
26         SemanticError, PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice, constants, SignedRawInvoice,
27         RawDataPart, CreationError, InvoiceFeatures};
28
29 use self::hrp_sm::parse_hrp;
30
31 /// State machine to parse the hrp
32 mod hrp_sm {
33         use core::ops::Range;
34
35         #[derive(PartialEq, Eq, Debug)]
36         enum States {
37                 Start,
38                 ParseL,
39                 ParseN,
40                 ParseCurrencyPrefix,
41                 ParseAmountNumber,
42                 ParseAmountSiPrefix,
43         }
44
45         impl States {
46                 fn next_state(&self, read_symbol: char) -> Result<States, super::ParseError> {
47                         match *self {
48                                 States::Start => {
49                                         if read_symbol == 'l' {
50                                                 Ok(States::ParseL)
51                                         } else {
52                                                 Err(super::ParseError::MalformedHRP)
53                                         }
54                                 }
55                                 States::ParseL => {
56                                         if read_symbol == 'n' {
57                                                 Ok(States::ParseN)
58                                         } else {
59                                                 Err(super::ParseError::MalformedHRP)
60                                         }
61                                 },
62                                 States::ParseN => {
63                                         if !read_symbol.is_numeric() {
64                                                 Ok(States::ParseCurrencyPrefix)
65                                         } else {
66                                                 Ok(States::ParseAmountNumber)
67                                         }
68                                 },
69                                 States::ParseCurrencyPrefix => {
70                                         if !read_symbol.is_numeric() {
71                                                 Ok(States::ParseCurrencyPrefix)
72                                         } else {
73                                                 Ok(States::ParseAmountNumber)
74                                         }
75                                 },
76                                 States::ParseAmountNumber => {
77                                         if read_symbol.is_numeric() {
78                                                 Ok(States::ParseAmountNumber)
79                                         } else if ['m', 'u', 'n', 'p'].contains(&read_symbol) {
80                                                 Ok(States::ParseAmountSiPrefix)
81                                         } else {
82                                                 Err(super::ParseError::UnknownSiPrefix)
83                                         }
84                                 },
85                                 States::ParseAmountSiPrefix => Err(super::ParseError::MalformedHRP),
86                         }
87                 }
88
89                 fn is_final(&self) -> bool {
90                         !(*self == States::ParseL || *self == States::ParseN)
91                 }
92         }
93
94
95         struct StateMachine {
96                 state: States,
97                 position: usize,
98                 currency_prefix: Option<Range<usize>>,
99                 amount_number: Option<Range<usize>>,
100                 amount_si_prefix: Option<Range<usize>>,
101         }
102
103         impl StateMachine {
104                 fn new() -> StateMachine {
105                         StateMachine {
106                                 state: States::Start,
107                                 position: 0,
108                                 currency_prefix: None,
109                                 amount_number: None,
110                                 amount_si_prefix: None,
111                         }
112                 }
113
114                 fn update_range(range: &mut Option<Range<usize>>, position: usize) {
115                         let new_range = match *range {
116                                 None => Range {start: position, end: position + 1},
117                                 Some(ref r) => Range {start: r.start, end: r.end + 1},
118                         };
119                         *range = Some(new_range);
120                 }
121
122                 fn step(&mut self, c: char) -> Result<(), super::ParseError> {
123                         let next_state = self.state.next_state(c)?;
124                         match next_state {
125                                 States::ParseCurrencyPrefix => {
126                                         StateMachine::update_range(&mut self.currency_prefix, self.position)
127                                 }
128                                 States::ParseAmountNumber => {
129                                         StateMachine::update_range(&mut self.amount_number, self.position)
130                                 },
131                                 States::ParseAmountSiPrefix => {
132                                         StateMachine::update_range(&mut self.amount_si_prefix, self.position)
133                                 },
134                                 _ => {}
135                         }
136
137                         self.position += 1;
138                         self.state = next_state;
139                         Ok(())
140                 }
141
142                 fn is_final(&self) -> bool {
143                         self.state.is_final()
144                 }
145
146                 fn currency_prefix(&self) -> &Option<Range<usize>> {
147                         &self.currency_prefix
148                 }
149
150                 fn amount_number(&self) -> &Option<Range<usize>> {
151                         &self.amount_number
152                 }
153
154                 fn amount_si_prefix(&self) -> &Option<Range<usize>> {
155                         &self.amount_si_prefix
156                 }
157         }
158
159         pub fn parse_hrp(input: &str) -> Result<(&str, &str, &str), super::ParseError> {
160                 let mut sm = StateMachine::new();
161                 for c in input.chars() {
162                         sm.step(c)?;
163                 }
164
165                 if !sm.is_final() {
166                         return Err(super::ParseError::MalformedHRP);
167                 }
168
169                 let currency = sm.currency_prefix().clone()
170                         .map(|r| &input[r]).unwrap_or("");
171                 let amount = sm.amount_number().clone()
172                         .map(|r| &input[r]).unwrap_or("");
173                 let si = sm.amount_si_prefix().clone()
174                         .map(|r| &input[r]).unwrap_or("");
175
176                 Ok((currency, amount, si))
177         }
178 }
179
180
181 impl FromStr for super::Currency {
182         type Err = ParseError;
183
184         fn from_str(currency_prefix: &str) -> Result<Self, ParseError> {
185                 match currency_prefix {
186                         "bc" => Ok(Currency::Bitcoin),
187                         "tb" => Ok(Currency::BitcoinTestnet),
188                         "bcrt" => Ok(Currency::Regtest),
189                         "sb" => Ok(Currency::Simnet),
190                         "tbs" => Ok(Currency::Signet),
191                         _ => Err(ParseError::UnknownCurrency)
192                 }
193         }
194 }
195
196 impl FromStr for SiPrefix {
197         type Err = ParseError;
198
199         fn from_str(currency_prefix: &str) -> Result<Self, ParseError> {
200                 use SiPrefix::*;
201                 match currency_prefix {
202                         "m" => Ok(Milli),
203                         "u" => Ok(Micro),
204                         "n" => Ok(Nano),
205                         "p" => Ok(Pico),
206                         _ => Err(ParseError::UnknownSiPrefix)
207                 }
208         }
209 }
210
211 /// ```
212 /// use lightning_invoice::Invoice;
213 ///
214 ///
215 /// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
216 /// h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
217 /// 5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
218 /// h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
219 /// j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
220 /// ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
221 /// guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
222 /// ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
223 /// p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
224 /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
225 /// j5r6drg6k6zcqj0fcwg";
226 ///
227 /// assert!(invoice.parse::<Invoice>().is_ok());
228 /// ```
229 impl FromStr for Invoice {
230         type Err = ParseOrSemanticError;
231
232         fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
233                 let signed = s.parse::<SignedRawInvoice>()?;
234                 Ok(Invoice::from_signed(signed)?)
235         }
236 }
237
238 /// ```
239 /// use lightning_invoice::*;
240 ///
241 /// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
242 /// h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
243 /// 5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
244 /// h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
245 /// j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
246 /// ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
247 /// guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
248 /// ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
249 /// p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
250 /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
251 /// j5r6drg6k6zcqj0fcwg";
252 ///
253 /// let parsed_1 = invoice.parse::<Invoice>();
254 ///
255 /// let parsed_2 = match invoice.parse::<SignedRawInvoice>() {
256 ///     Ok(signed) => match Invoice::from_signed(signed) {
257 ///             Ok(invoice) => Ok(invoice),
258 ///             Err(e) => Err(ParseOrSemanticError::SemanticError(e)),
259 ///     },
260 ///     Err(e) => Err(ParseOrSemanticError::ParseError(e)),
261 /// };
262 ///
263 /// assert!(parsed_1.is_ok());
264 /// assert_eq!(parsed_1, parsed_2);
265 /// ```
266 impl FromStr for SignedRawInvoice {
267         type Err = ParseError;
268
269         fn from_str(s: &str) -> Result<Self, Self::Err> {
270                 let (hrp, data, var) = bech32::decode(s)?;
271
272                 if var == bech32::Variant::Bech32m {
273                         // Consider Bech32m addresses to be "Invalid Checksum", since that is what we'd get if
274                         // we didn't support Bech32m (which lightning does not use).
275                         return Err(ParseError::Bech32Error(bech32::Error::InvalidChecksum));
276                 }
277
278                 if data.len() < 104 {
279                         return Err(ParseError::TooShortDataPart);
280                 }
281
282                 let raw_hrp: RawHrp = hrp.parse()?;
283                 let data_part = RawDataPart::from_base32(&data[..data.len()-104])?;
284
285                 Ok(SignedRawInvoice {
286                         raw_invoice: RawInvoice {
287                                 hrp: raw_hrp,
288                                 data: data_part,
289                         },
290                         hash: RawInvoice::hash_from_parts(
291                                 hrp.as_bytes(),
292                                 &data[..data.len()-104]
293                         ),
294                         signature: InvoiceSignature::from_base32(&data[data.len()-104..])?,
295                 })
296         }
297 }
298
299 impl FromStr for RawHrp {
300         type Err = ParseError;
301
302         fn from_str(hrp: &str) -> Result<Self, <Self as FromStr>::Err> {
303                 let parts = parse_hrp(hrp)?;
304
305                 let currency = parts.0.parse::<Currency>()?;
306
307                 let amount = if !parts.1.is_empty() {
308                         Some(parts.1.parse::<u64>()?)
309                 } else {
310                         None
311                 };
312
313                 let si_prefix: Option<SiPrefix> = if parts.2.is_empty() {
314                         None
315                 } else {
316                         let si: SiPrefix = parts.2.parse()?;
317                         if let Some(amt) = amount {
318                                 if amt.checked_mul(si.multiplier()).is_none() {
319                                         return Err(ParseError::IntegerOverflowError);
320                                 }
321                         }
322                         Some(si)
323                 };
324
325                 Ok(RawHrp {
326                         currency: currency,
327                         raw_amount: amount,
328                         si_prefix: si_prefix,
329                 })
330         }
331 }
332
333 impl FromBase32 for RawDataPart {
334         type Err = ParseError;
335
336         fn from_base32(data: &[u5]) -> Result<Self, Self::Err> {
337                 if data.len() < 7 { // timestamp length
338                         return Err(ParseError::TooShortDataPart);
339                 }
340
341                 let timestamp = PositiveTimestamp::from_base32(&data[0..7])?;
342                 let tagged = parse_tagged_parts(&data[7..])?;
343
344                 Ok(RawDataPart {
345                         timestamp: timestamp,
346                         tagged_fields: tagged,
347                 })
348         }
349 }
350
351 impl FromBase32 for PositiveTimestamp {
352         type Err = ParseError;
353
354         fn from_base32(b32: &[u5]) -> Result<Self, Self::Err> {
355                 if b32.len() != 7 {
356                         return Err(ParseError::InvalidSliceLength("PositiveTimestamp::from_base32()".into()));
357                 }
358                 let timestamp: u64 = parse_int_be(b32, 32)
359                         .expect("7*5bit < 64bit, no overflow possible");
360                 match PositiveTimestamp::from_unix_timestamp(timestamp) {
361                         Ok(t) => Ok(t),
362                         Err(CreationError::TimestampOutOfBounds) => Err(ParseError::TimestampOverflow),
363                         Err(_) => unreachable!(),
364                 }
365         }
366 }
367
368 impl FromBase32 for InvoiceSignature {
369         type Err = ParseError;
370         fn from_base32(signature: &[u5]) -> Result<Self, Self::Err> {
371                 if signature.len() != 104 {
372                         return Err(ParseError::InvalidSliceLength("InvoiceSignature::from_base32()".into()));
373                 }
374                 let recoverable_signature_bytes = Vec::<u8>::from_base32(signature)?;
375                 let signature = &recoverable_signature_bytes[0..64];
376                 let recovery_id = RecoveryId::from_i32(recoverable_signature_bytes[64] as i32)?;
377
378                 Ok(InvoiceSignature(RecoverableSignature::from_compact(
379                         signature,
380                         recovery_id
381                 )?))
382         }
383 }
384
385 pub(crate) fn parse_int_be<T, U>(digits: &[U], base: T) -> Option<T>
386         where T: CheckedAdd + CheckedMul + From<u8> + Default,
387               U: Into<u8> + Copy
388 {
389         digits.iter().fold(Some(Default::default()), |acc, b|
390                 acc
391                         .and_then(|x| x.checked_mul(&base))
392                         .and_then(|x| x.checked_add(&(Into::<u8>::into(*b)).into()))
393         )
394 }
395
396 fn parse_tagged_parts(data: &[u5]) -> Result<Vec<RawTaggedField>, ParseError> {
397         let mut parts = Vec::<RawTaggedField>::new();
398         let mut data = data;
399
400         while !data.is_empty() {
401                 if data.len() < 3 {
402                         return Err(ParseError::UnexpectedEndOfTaggedFields);
403                 }
404
405                 // Ignore tag at data[0], it will be handled in the TaggedField parsers and
406                 // parse the length to find the end of the tagged field's data
407                 let len = parse_int_be(&data[1..3], 32).expect("can't overflow");
408                 let last_element = 3 + len;
409
410                 if data.len() < last_element {
411                         return Err(ParseError::UnexpectedEndOfTaggedFields);
412                 }
413
414                 // Get the tagged field's data slice
415                 let field = &data[0..last_element];
416
417                 // Set data slice to remaining data
418                 data = &data[last_element..];
419
420                 match TaggedField::from_base32(field) {
421                         Ok(field) => {
422                                 parts.push(RawTaggedField::KnownSemantics(field))
423                         },
424                         Err(ParseError::Skip)|Err(ParseError::Bech32Error(bech32::Error::InvalidLength)) => {
425                                 parts.push(RawTaggedField::UnknownSemantics(field.into()))
426                         },
427                         Err(e) => {return Err(e)}
428                 }
429         }
430         Ok(parts)
431 }
432
433 impl FromBase32 for TaggedField {
434         type Err = ParseError;
435
436         fn from_base32(field: &[u5]) -> Result<TaggedField, ParseError> {
437                 if field.len() < 3 {
438                         return Err(ParseError::UnexpectedEndOfTaggedFields);
439                 }
440
441                 let tag = field[0];
442                 let field_data =  &field[3..];
443
444                 match tag.to_u8() {
445                         constants::TAG_PAYMENT_HASH =>
446                                 Ok(TaggedField::PaymentHash(Sha256::from_base32(field_data)?)),
447                         constants::TAG_DESCRIPTION =>
448                                 Ok(TaggedField::Description(Description::from_base32(field_data)?)),
449                         constants::TAG_PAYEE_PUB_KEY =>
450                                 Ok(TaggedField::PayeePubKey(PayeePubKey::from_base32(field_data)?)),
451                         constants::TAG_DESCRIPTION_HASH =>
452                                 Ok(TaggedField::DescriptionHash(Sha256::from_base32(field_data)?)),
453                         constants::TAG_EXPIRY_TIME =>
454                                 Ok(TaggedField::ExpiryTime(ExpiryTime::from_base32(field_data)?)),
455                         constants::TAG_MIN_FINAL_CLTV_EXPIRY =>
456                                 Ok(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry::from_base32(field_data)?)),
457                         constants::TAG_FALLBACK =>
458                                 Ok(TaggedField::Fallback(Fallback::from_base32(field_data)?)),
459                         constants::TAG_PRIVATE_ROUTE =>
460                                 Ok(TaggedField::PrivateRoute(PrivateRoute::from_base32(field_data)?)),
461                         constants::TAG_PAYMENT_SECRET =>
462                                 Ok(TaggedField::PaymentSecret(PaymentSecret::from_base32(field_data)?)),
463                         constants::TAG_FEATURES =>
464                                 Ok(TaggedField::Features(InvoiceFeatures::from_base32(field_data)?)),
465                         _ => {
466                                 // "A reader MUST skip over unknown fields"
467                                 Err(ParseError::Skip)
468                         }
469                 }
470         }
471 }
472
473 impl FromBase32 for Sha256 {
474         type Err = ParseError;
475
476         fn from_base32(field_data: &[u5]) -> Result<Sha256, ParseError> {
477                 if field_data.len() != 52 {
478                         // "A reader MUST skip over […] a p, [or] h […] field that does not have data_length 52 […]."
479                         Err(ParseError::Skip)
480                 } else {
481                         Ok(Sha256(sha256::Hash::from_slice(&Vec::<u8>::from_base32(field_data)?)
482                                 .expect("length was checked before (52 u5 -> 32 u8)")))
483                 }
484         }
485 }
486
487 impl FromBase32 for Description {
488         type Err = ParseError;
489
490         fn from_base32(field_data: &[u5]) -> Result<Description, ParseError> {
491                 let bytes = Vec::<u8>::from_base32(field_data)?;
492                 let description = String::from(str::from_utf8(&bytes)?);
493                 Ok(Description::new(description).expect(
494                         "Max len is 639=floor(1023*5/8) since the len field is only 10bits long"
495                 ))
496         }
497 }
498
499 impl FromBase32 for PayeePubKey {
500         type Err = ParseError;
501
502         fn from_base32(field_data: &[u5]) -> Result<PayeePubKey, ParseError> {
503                 if field_data.len() != 53 {
504                         // "A reader MUST skip over […] a n […] field that does not have data_length 53 […]."
505                         Err(ParseError::Skip)
506                 } else {
507                         let data_bytes = Vec::<u8>::from_base32(field_data)?;
508                         let pub_key = PublicKey::from_slice(&data_bytes)?;
509                         Ok(pub_key.into())
510                 }
511         }
512 }
513
514 impl FromBase32 for ExpiryTime {
515         type Err = ParseError;
516
517         fn from_base32(field_data: &[u5]) -> Result<ExpiryTime, ParseError> {
518                 match parse_int_be::<u64, u5>(field_data, 32)
519                         .and_then(|t| ExpiryTime::from_seconds(t).ok()) // ok, since the only error is out of bounds
520                 {
521                         Some(t) => Ok(t),
522                         None => Err(ParseError::IntegerOverflowError),
523                 }
524         }
525 }
526
527 impl FromBase32 for MinFinalCltvExpiry {
528         type Err = ParseError;
529
530         fn from_base32(field_data: &[u5]) -> Result<MinFinalCltvExpiry, ParseError> {
531                 let expiry = parse_int_be::<u64, u5>(field_data, 32);
532                 if let Some(expiry) = expiry {
533                         Ok(MinFinalCltvExpiry(expiry))
534                 } else {
535                         Err(ParseError::IntegerOverflowError)
536                 }
537         }
538 }
539
540 impl FromBase32 for Fallback {
541         type Err = ParseError;
542
543         fn from_base32(field_data: &[u5]) -> Result<Fallback, ParseError> {
544                 if field_data.len() < 1 {
545                         return Err(ParseError::UnexpectedEndOfTaggedFields);
546                 }
547
548                 let version = field_data[0];
549                 let bytes = Vec::<u8>::from_base32(&field_data[1..])?;
550
551                 match version.to_u8() {
552                         0..=16 => {
553                                 if bytes.len() < 2 || bytes.len() > 40 {
554                                         return Err(ParseError::InvalidSegWitProgramLength);
555                                 }
556
557                                 Ok(Fallback::SegWitProgram {
558                                         version: version,
559                                         program: bytes
560                                 })
561                         },
562                         17 => {
563                                 if bytes.len() != 20 {
564                                         return Err(ParseError::InvalidPubKeyHashLength);
565                                 }
566                                 //TODO: refactor once const generics are available
567                                 let mut pkh = [0u8; 20];
568                                 pkh.copy_from_slice(&bytes);
569                                 Ok(Fallback::PubKeyHash(pkh))
570                         }
571                         18 => {
572                                 if bytes.len() != 20 {
573                                         return Err(ParseError::InvalidScriptHashLength);
574                                 }
575                                 let mut sh = [0u8; 20];
576                                 sh.copy_from_slice(&bytes);
577                                 Ok(Fallback::ScriptHash(sh))
578                         }
579                         _ => Err(ParseError::Skip)
580                 }
581         }
582 }
583
584 impl FromBase32 for PrivateRoute {
585         type Err = ParseError;
586
587         fn from_base32(field_data: &[u5]) -> Result<PrivateRoute, ParseError> {
588                 let bytes = Vec::<u8>::from_base32(field_data)?;
589
590                 if bytes.len() % 51 != 0 {
591                         return Err(ParseError::UnexpectedEndOfTaggedFields);
592                 }
593
594                 let mut route_hops = Vec::<RouteHintHop>::new();
595
596                 let mut bytes = bytes.as_slice();
597                 while !bytes.is_empty() {
598                         let hop_bytes = &bytes[0..51];
599                         bytes = &bytes[51..];
600
601                         let mut channel_id: [u8; 8] = Default::default();
602                         channel_id.copy_from_slice(&hop_bytes[33..41]);
603
604                         let hop = RouteHintHop {
605                                 src_node_id: PublicKey::from_slice(&hop_bytes[0..33])?,
606                                 short_channel_id: parse_int_be(&channel_id, 256).expect("short chan ID slice too big?"),
607                                 fees: RoutingFees {
608                                         base_msat: parse_int_be(&hop_bytes[41..45], 256).expect("slice too big?"),
609                                         proportional_millionths: parse_int_be(&hop_bytes[45..49], 256).expect("slice too big?"),
610                                 },
611                                 cltv_expiry_delta: parse_int_be(&hop_bytes[49..51], 256).expect("slice too big?"),
612                                 htlc_minimum_msat: None,
613                                 htlc_maximum_msat: None,
614                         };
615
616                         route_hops.push(hop);
617                 }
618
619                 Ok(PrivateRoute(RouteHint(route_hops)))
620         }
621 }
622
623 /// Errors that indicate what is wrong with the invoice. They have some granularity for debug
624 /// reasons, but should generally result in an "invalid BOLT11 invoice" message for the user.
625 #[allow(missing_docs)]
626 #[derive(PartialEq, Debug, Clone)]
627 pub enum ParseError {
628         Bech32Error(bech32::Error),
629         ParseAmountError(ParseIntError),
630         MalformedSignature(secp256k1::Error),
631         BadPrefix,
632         UnknownCurrency,
633         UnknownSiPrefix,
634         MalformedHRP,
635         TooShortDataPart,
636         UnexpectedEndOfTaggedFields,
637         DescriptionDecodeError(str::Utf8Error),
638         PaddingError,
639         IntegerOverflowError,
640         InvalidSegWitProgramLength,
641         InvalidPubKeyHashLength,
642         InvalidScriptHashLength,
643         InvalidRecoveryId,
644         InvalidSliceLength(String),
645
646         /// Not an error, but used internally to signal that a part of the invoice should be ignored
647         /// according to BOLT11
648         Skip,
649         TimestampOverflow,
650 }
651
652 /// Indicates that something went wrong while parsing or validating the invoice. Parsing errors
653 /// should be mostly seen as opaque and are only there for debugging reasons. Semantic errors
654 /// like wrong signatures, missing fields etc. could mean that someone tampered with the invoice.
655 #[derive(PartialEq, Debug, Clone)]
656 pub enum ParseOrSemanticError {
657         /// The invoice couldn't be decoded
658         ParseError(ParseError),
659
660         /// The invoice could be decoded but violates the BOLT11 standard
661         SemanticError(::SemanticError),
662 }
663
664 impl Display for ParseError {
665         fn fmt(&self, f: &mut Formatter) -> fmt::Result {
666                 match *self {
667                         // TODO: find a way to combine the first three arms (e as error::Error?)
668                         ParseError::Bech32Error(ref e) => {
669                                 write!(f, "Invalid bech32: {}", e)
670                         }
671                         ParseError::ParseAmountError(ref e) => {
672                                 write!(f, "Invalid amount in hrp ({})", e)
673                         }
674                         ParseError::MalformedSignature(ref e) => {
675                                 write!(f, "Invalid secp256k1 signature: {}", e)
676                         }
677                         ParseError::DescriptionDecodeError(ref e) => {
678                                 write!(f, "Description is not a valid utf-8 string: {}", e)
679                         }
680                         ParseError::InvalidSliceLength(ref function) => {
681                                 write!(f, "Slice in function {} had the wrong length", function)
682                         }
683                         ParseError::BadPrefix => f.write_str("did not begin with 'ln'"),
684                         ParseError::UnknownCurrency => f.write_str("currency code unknown"),
685                         ParseError::UnknownSiPrefix => f.write_str("unknown SI prefix"),
686                         ParseError::MalformedHRP => f.write_str("malformed human readable part"),
687                         ParseError::TooShortDataPart => {
688                                 f.write_str("data part too short (should be at least 111 bech32 chars long)")
689                         },
690                         ParseError::UnexpectedEndOfTaggedFields => {
691                                 f.write_str("tagged fields part ended unexpectedly")
692                         },
693                         ParseError::PaddingError => f.write_str("some data field had bad padding"),
694                         ParseError::IntegerOverflowError => {
695                                 f.write_str("parsed integer doesn't fit into receiving type")
696                         },
697                         ParseError::InvalidSegWitProgramLength => {
698                                 f.write_str("fallback SegWit program is too long or too short")
699                         },
700                         ParseError::InvalidPubKeyHashLength => {
701                                 f.write_str("fallback public key hash has a length unequal 20 bytes")
702                         },
703                         ParseError::InvalidScriptHashLength => {
704                                 f.write_str("fallback script hash has a length unequal 32 bytes")
705                         },
706                         ParseError::InvalidRecoveryId => {
707                                 f.write_str("recovery id is out of range (should be in [0,3])")
708                         },
709                         ParseError::Skip => {
710                                 f.write_str("the tagged field has to be skipped because of an unexpected, but allowed property")
711                         },
712                         ParseError::TimestampOverflow => {
713                 f.write_str("the invoice's timestamp could not be represented as SystemTime")
714             },
715                 }
716         }
717 }
718
719 impl Display for ParseOrSemanticError {
720         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
721                 match self {
722                         ParseOrSemanticError::ParseError(err) => err.fmt(f),
723                         ParseOrSemanticError::SemanticError(err) => err.fmt(f),
724                 }
725         }
726 }
727
728 #[cfg(feature = "std")]
729 impl error::Error for ParseError {}
730
731 #[cfg(feature = "std")]
732 impl error::Error for ParseOrSemanticError {}
733
734 macro_rules! from_error {
735     ($my_error:expr, $extern_error:ty) => {
736         impl From<$extern_error> for ParseError {
737             fn from(e: $extern_error) -> Self {
738                 $my_error(e)
739             }
740         }
741     }
742 }
743
744 from_error!(ParseError::MalformedSignature, secp256k1::Error);
745 from_error!(ParseError::ParseAmountError, ParseIntError);
746 from_error!(ParseError::DescriptionDecodeError, str::Utf8Error);
747
748 impl From<bech32::Error> for ParseError {
749         fn from(e: bech32::Error) -> Self {
750                 match e {
751                         bech32::Error::InvalidPadding => ParseError::PaddingError,
752                         _ => ParseError::Bech32Error(e)
753                 }
754         }
755 }
756
757 impl From<ParseError> for ParseOrSemanticError {
758         fn from(e: ParseError) -> Self {
759                 ParseOrSemanticError::ParseError(e)
760         }
761 }
762
763 impl From<::SemanticError> for ParseOrSemanticError {
764         fn from(e: SemanticError) -> Self {
765                 ParseOrSemanticError::SemanticError(e)
766         }
767 }
768
769 #[cfg(test)]
770 mod test {
771         use de::ParseError;
772         use secp256k1::PublicKey;
773         use bech32::u5;
774         use bitcoin_hashes::hex::FromHex;
775         use bitcoin_hashes::sha256;
776
777         const CHARSET_REV: [i8; 128] = [
778                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
779                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
780                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
781                 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
782                 -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
783                 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
784                 -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
785                 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
786         ];
787
788         fn from_bech32(bytes_5b: &[u8]) -> Vec<u5> {
789                 bytes_5b
790                         .iter()
791                         .map(|c| u5::try_from_u8(CHARSET_REV[*c as usize] as u8).unwrap())
792                         .collect()
793         }
794
795         #[test]
796         fn test_parse_currency_prefix() {
797                 use Currency;
798
799                 assert_eq!("bc".parse::<Currency>(), Ok(Currency::Bitcoin));
800                 assert_eq!("tb".parse::<Currency>(), Ok(Currency::BitcoinTestnet));
801                 assert_eq!("bcrt".parse::<Currency>(), Ok(Currency::Regtest));
802                 assert_eq!("sb".parse::<Currency>(), Ok(Currency::Simnet));
803                 assert_eq!("tbs".parse::<Currency>(), Ok(Currency::Signet));
804                 assert_eq!("something_else".parse::<Currency>(), Err(ParseError::UnknownCurrency))
805         }
806
807         #[test]
808         fn test_parse_int_from_bytes_be() {
809                 use de::parse_int_be;
810
811                 assert_eq!(parse_int_be::<u32, u8>(&[1, 2, 3, 4], 256), Some(16909060));
812                 assert_eq!(parse_int_be::<u32, u8>(&[1, 3], 32), Some(35));
813                 assert_eq!(parse_int_be::<u32, u8>(&[255, 255, 255, 255], 256), Some(4294967295));
814                 assert_eq!(parse_int_be::<u32, u8>(&[1, 0, 0, 0, 0], 256), None);
815         }
816
817         #[test]
818         fn test_parse_sha256_hash() {
819                 use Sha256;
820                 use bech32::FromBase32;
821
822                 let input = from_bech32(
823                         "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq".as_bytes()
824                 );
825
826                 let hash = sha256::Hash::from_hex(
827                         "0001020304050607080900010203040506070809000102030405060708090102"
828                 ).unwrap();
829                 let expected = Ok(Sha256(hash));
830
831                 assert_eq!(Sha256::from_base32(&input), expected);
832
833                 // make sure hashes of unknown length get skipped
834                 let input_unexpected_length = from_bech32(
835                         "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypyq".as_bytes()
836                 );
837                 assert_eq!(Sha256::from_base32(&input_unexpected_length), Err(ParseError::Skip));
838         }
839
840         #[test]
841         fn test_parse_description() {
842                 use ::Description;
843                 use bech32::FromBase32;
844
845                 let input = from_bech32("xysxxatsyp3k7enxv4js".as_bytes());
846                 let expected = Ok(Description::new("1 cup coffee".to_owned()).unwrap());
847                 assert_eq!(Description::from_base32(&input), expected);
848         }
849
850         #[test]
851         fn test_parse_payee_pub_key() {
852                 use ::PayeePubKey;
853                 use bech32::FromBase32;
854
855                 let input = from_bech32("q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66".as_bytes());
856                 let pk_bytes = [
857                         0x03, 0xe7, 0x15, 0x6a, 0xe3, 0x3b, 0x0a, 0x20, 0x8d, 0x07, 0x44, 0x19, 0x91, 0x63,
858                         0x17, 0x7e, 0x90, 0x9e, 0x80, 0x17, 0x6e, 0x55, 0xd9, 0x7a, 0x2f, 0x22, 0x1e, 0xde,
859                         0x0f, 0x93, 0x4d, 0xd9, 0xad
860                 ];
861                 let expected = Ok(PayeePubKey(
862                         PublicKey::from_slice(&pk_bytes[..]).unwrap()
863                 ));
864
865                 assert_eq!(PayeePubKey::from_base32(&input), expected);
866
867                 // expects 33 bytes
868                 let input_unexpected_length = from_bech32(
869                         "q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhvq".as_bytes()
870                 );
871                 assert_eq!(PayeePubKey::from_base32(&input_unexpected_length), Err(ParseError::Skip));
872         }
873
874         #[test]
875         fn test_parse_expiry_time() {
876                 use ::ExpiryTime;
877                 use bech32::FromBase32;
878
879                 let input = from_bech32("pu".as_bytes());
880                 let expected = Ok(ExpiryTime::from_seconds(60).unwrap());
881                 assert_eq!(ExpiryTime::from_base32(&input), expected);
882
883                 let input_too_large = from_bech32("sqqqqqqqqqqqq".as_bytes());
884                 assert_eq!(ExpiryTime::from_base32(&input_too_large), Err(ParseError::IntegerOverflowError));
885         }
886
887         #[test]
888         fn test_parse_min_final_cltv_expiry() {
889                 use ::MinFinalCltvExpiry;
890                 use bech32::FromBase32;
891
892                 let input = from_bech32("pr".as_bytes());
893                 let expected = Ok(MinFinalCltvExpiry(35));
894
895                 assert_eq!(MinFinalCltvExpiry::from_base32(&input), expected);
896         }
897
898         #[test]
899         fn test_parse_fallback() {
900                 use Fallback;
901                 use bech32::FromBase32;
902
903                 let cases = vec![
904                         (
905                                 from_bech32("3x9et2e20v6pu37c5d9vax37wxq72un98".as_bytes()),
906                                 Ok(Fallback::PubKeyHash([
907                                         0x31, 0x72, 0xb5, 0x65, 0x4f, 0x66, 0x83, 0xc8, 0xfb, 0x14, 0x69, 0x59, 0xd3,
908                                         0x47, 0xce, 0x30, 0x3c, 0xae, 0x4c, 0xa7
909                                 ]))
910                         ),
911                         (
912                                 from_bech32("j3a24vwu6r8ejrss3axul8rxldph2q7z9".as_bytes()),
913                                 Ok(Fallback::ScriptHash([
914                                         0x8f, 0x55, 0x56, 0x3b, 0x9a, 0x19, 0xf3, 0x21, 0xc2, 0x11, 0xe9, 0xb9, 0xf3,
915                                         0x8c, 0xdf, 0x68, 0x6e, 0xa0, 0x78, 0x45
916                                 ]))
917                         ),
918                         (
919                                 from_bech32("qw508d6qejxtdg4y5r3zarvary0c5xw7k".as_bytes()),
920                                 Ok(Fallback::SegWitProgram {
921                                         version: u5::try_from_u8(0).unwrap(),
922                                         program: Vec::from(&[
923                                                 0x75u8, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c, 0x45,
924                                                 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
925                                         ][..])
926                                 })
927                         ),
928                         (
929                                 vec![u5::try_from_u8(21).unwrap(); 41],
930                                 Err(ParseError::Skip)
931                         ),
932                         (
933                                 vec![],
934                                 Err(ParseError::UnexpectedEndOfTaggedFields)
935                         ),
936                         (
937                                 vec![u5::try_from_u8(1).unwrap(); 81],
938                                 Err(ParseError::InvalidSegWitProgramLength)
939                         ),
940                         (
941                                 vec![u5::try_from_u8(17).unwrap(); 1],
942                                 Err(ParseError::InvalidPubKeyHashLength)
943                         ),
944                         (
945                                 vec![u5::try_from_u8(18).unwrap(); 1],
946                                 Err(ParseError::InvalidScriptHashLength)
947                         )
948                 ];
949
950                 for (input, expected) in cases.into_iter() {
951                         assert_eq!(Fallback::from_base32(&input), expected);
952                 }
953         }
954
955         #[test]
956         fn test_parse_route() {
957                 use lightning::routing::network_graph::RoutingFees;
958                 use lightning::routing::router::{RouteHint, RouteHintHop};
959                 use ::PrivateRoute;
960                 use bech32::FromBase32;
961                 use de::parse_int_be;
962
963                 let input = from_bech32(
964                         "q20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqa\
965                         fqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzq".as_bytes()
966                 );
967
968                 let mut expected = Vec::<RouteHintHop>::new();
969                 expected.push(RouteHintHop {
970                         src_node_id: PublicKey::from_slice(
971                                 &[
972                                         0x02u8, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c,
973                                         0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3,
974                                         0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
975                                 ][..]
976                         ).unwrap(),
977                         short_channel_id: parse_int_be(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08], 256).expect("short chan ID slice too big?"),
978                         fees: RoutingFees {
979                                 base_msat: 1,
980                                 proportional_millionths: 20,
981                         },
982                         cltv_expiry_delta: 3,
983                         htlc_minimum_msat: None,
984                         htlc_maximum_msat: None
985                 });
986                 expected.push(RouteHintHop {
987                         src_node_id: PublicKey::from_slice(
988                                 &[
989                                         0x03u8, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c,
990                                         0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3,
991                                         0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
992                                 ][..]
993                         ).unwrap(),
994                         short_channel_id: parse_int_be(&[0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a], 256).expect("short chan ID slice too big?"),
995                         fees: RoutingFees {
996                                 base_msat: 2,
997                                 proportional_millionths: 30,
998                         },
999                         cltv_expiry_delta: 4,
1000                         htlc_minimum_msat: None,
1001                         htlc_maximum_msat: None
1002                 });
1003
1004                 assert_eq!(PrivateRoute::from_base32(&input), Ok(PrivateRoute(RouteHint(expected))));
1005
1006                 assert_eq!(
1007                         PrivateRoute::from_base32(&[u5::try_from_u8(0).unwrap(); 40][..]),
1008                         Err(ParseError::UnexpectedEndOfTaggedFields)
1009                 );
1010         }
1011
1012         #[test]
1013         fn test_payment_secret_and_features_de_and_ser() {
1014                 use lightning::ln::features::InvoiceFeatures;
1015                 use secp256k1::recovery::{RecoveryId, RecoverableSignature};
1016                 use TaggedField::*;
1017                 use {SiPrefix, SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart,
1018                                  Currency, Sha256, PositiveTimestamp};
1019
1020                 // Feature bits 9, 15, and 99 are set.
1021                 let expected_features = InvoiceFeatures::from_le_bytes(vec![0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8]);
1022                 let invoice_str = "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqpqsq67gye39hfg3zd8rgc80k32tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgptq44qu";
1023                 let invoice = SignedRawInvoice {
1024                                         raw_invoice: RawInvoice {
1025                                                 hrp: RawHrp {
1026                                                         currency: Currency::Bitcoin,
1027                                                         raw_amount: Some(25),
1028                                                         si_prefix: Some(SiPrefix::Milli)
1029                                                 },
1030                                                 data: RawDataPart {
1031                                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1032                                                         tagged_fields: vec ! [
1033                                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
1034                                                                         "0001020304050607080900010203040506070809000102030405060708090102"
1035                                                                 ).unwrap())).into(),
1036                                                                 Description(::Description::new("coffee beans".to_owned()).unwrap()).into(),
1037                                                                 PaymentSecret(::PaymentSecret([17; 32])).into(),
1038                                                                 Features(expected_features).into()]}
1039                                                                 },
1040                                         hash: [0xb1, 0x96, 0x46, 0xc3, 0xbc, 0x56, 0x76, 0x1d, 0x20, 0x65, 0x6e, 0x0e, 0x32,
1041                                                                         0xec, 0xd2, 0x69, 0x27, 0xb7, 0x62, 0x6e, 0x2a, 0x8b, 0xe6, 0x97, 0x71, 0x9f,
1042                                                                         0xf8, 0x7e, 0x44, 0x54, 0x55, 0xb9],
1043                                         signature: InvoiceSignature(RecoverableSignature::from_compact(
1044                                                                                 &[0xd7, 0x90, 0x4c, 0xc4, 0xb7, 0x4a, 0x22, 0x26, 0x9c, 0x68, 0xc1, 0xdf, 0x68,
1045                                                                                         0xa9, 0x6c, 0x21, 0x4d, 0x65, 0x1b, 0x93, 0x76, 0xe9, 0xf1, 0x64, 0xd3, 0x60,
1046                                                                                         0x4d, 0xa4, 0xb7, 0xde, 0xcc, 0xce, 0x0e, 0x82, 0xaa, 0xab, 0x4c, 0x85, 0xd3,
1047                                                                                         0x58, 0xea, 0x14, 0xd0, 0xae, 0x34, 0x2d, 0xa3, 0x08, 0x12, 0xf9, 0x5d, 0x97,
1048                                                                                         0x60, 0x82, 0xea, 0xac, 0x81, 0x39, 0x11, 0xda, 0xe0, 0x1a, 0xf3, 0xc1],
1049                                                                                 RecoveryId::from_i32(1).unwrap()
1050                                                                 ).unwrap()),
1051                         };
1052                 assert_eq!(invoice_str, invoice.to_string());
1053                 assert_eq!(
1054                         invoice_str.parse(),
1055                         Ok(invoice)
1056                 );
1057         }
1058
1059         #[test]
1060         fn test_raw_signed_invoice_deserialization() {
1061                 use TaggedField::*;
1062                 use secp256k1::recovery::{RecoveryId, RecoverableSignature};
1063                 use {SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
1064                          PositiveTimestamp};
1065
1066                 assert_eq!(
1067                         "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmw\
1068                         wd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9\
1069                         ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w".parse(),
1070                         Ok(SignedRawInvoice {
1071                                 raw_invoice: RawInvoice {
1072                                         hrp: RawHrp {
1073                                                 currency: Currency::Bitcoin,
1074                                                 raw_amount: None,
1075                                                 si_prefix: None,
1076                                         },
1077                                         data: RawDataPart {
1078                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1079                                         tagged_fields: vec ! [
1080                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
1081                                                         "0001020304050607080900010203040506070809000102030405060708090102"
1082                                                 ).unwrap())).into(),
1083                                                 Description(
1084                                                         ::Description::new(
1085                                                                 "Please consider supporting this project".to_owned()
1086                                                         ).unwrap()
1087                                                 ).into(),
1088                                         ],
1089                                         },
1090                                         },
1091                                 hash: [
1092                                         0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27,
1093                                         0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7,
1094                                         0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9
1095                                 ],
1096                                 signature: InvoiceSignature(RecoverableSignature::from_compact(
1097                                         & [
1098                                                 0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a,
1099                                                 0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43,
1100                                                 0x4e, 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f,
1101                                                 0x42, 0x5f, 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad,
1102                                                 0x0d, 0x6e, 0x35, 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9,
1103                                                 0xaa, 0xb1, 0x5e, 0x57, 0x38, 0xb1, 0x1f, 0x12, 0x7f
1104                                         ],
1105                                         RecoveryId::from_i32(0).unwrap()
1106                                 ).unwrap()),
1107                                 }
1108                         )
1109                 )
1110         }
1111 }