18
18
//! extern crate core;
19
19
//! extern crate lightning;
20
20
//!
21
+ //! use core::convert::TryFrom;
21
22
//! use core::num::NonZeroU64;
22
23
//! use core::time::Duration;
23
24
//!
24
25
//! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
25
26
//! use lightning::offers::offer::{Amount, Offer, OfferBuilder};
26
27
//! use lightning::offers::parse::ParseError;
28
+ //! use lightning::util::ser::{Readable, Writeable};
27
29
//!
28
30
//! # use lightning::onion_message::BlindedPath;
29
31
//! # #[cfg(feature = "std")]
55
57
//!
56
58
//! // Parse from a bech32 string after scanning from a QR code.
57
59
//! let offer = encoded_offer.parse::<Offer>()?;
60
+ //!
61
+ //! // Encode offer as raw bytes.
62
+ //! let mut bytes = Vec::new();
63
+ //! offer.write(&mut bytes).unwrap();
64
+ //!
65
+ //! // Decode raw bytes into an offer.
66
+ //! let offer = Offer::try_from(bytes)?;
58
67
//! # Ok(())
59
68
//! # }
60
69
//! ```
@@ -72,7 +81,7 @@ use ln::features::OfferFeatures;
72
81
use ln:: msgs:: MAX_VALUE_MSAT ;
73
82
use offers:: parse:: { Bech32Encode , ParseError , SemanticError } ;
74
83
use onion_message:: BlindedPath ;
75
- use util:: ser:: { HighZeroBytesDroppedBigSize , WithoutLength , Writeable , Writer } ;
84
+ use util:: ser:: { HighZeroBytesDroppedBigSize , Readable , WithoutLength , Writeable , Writer } ;
76
85
use util:: string:: PrintableString ;
77
86
78
87
use prelude:: * ;
@@ -411,12 +420,27 @@ impl OfferContents {
411
420
}
412
421
}
413
422
423
+ impl Writeable for Offer {
424
+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
425
+ WithoutLength ( & self . bytes ) . write ( writer)
426
+ }
427
+ }
428
+
414
429
impl Writeable for OfferContents {
415
430
fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
416
431
self . as_tlv_stream ( ) . write ( writer)
417
432
}
418
433
}
419
434
435
+ impl TryFrom < Vec < u8 > > for Offer {
436
+ type Error = ParseError ;
437
+
438
+ fn try_from ( bytes : Vec < u8 > ) -> Result < Self , Self :: Error > {
439
+ let tlv_stream: OfferTlvStream = Readable :: read ( & mut & bytes[ ..] ) ?;
440
+ Offer :: try_from ( ( bytes, tlv_stream) )
441
+ }
442
+ }
443
+
420
444
/// The minimum amount required for an item in an [`Offer`], denominated in either bitcoin or
421
445
/// another currency.
422
446
#[ derive( Clone , Debug , PartialEq ) ]
@@ -467,6 +491,8 @@ impl Bech32Encode for Offer {
467
491
const BECH32_HRP : & ' static str = "lno" ;
468
492
}
469
493
494
+ type ParsedOffer = ( Vec < u8 > , OfferTlvStream ) ;
495
+
470
496
impl FromStr for Offer {
471
497
type Err = ParseError ;
472
498
@@ -475,6 +501,16 @@ impl FromStr for Offer {
475
501
}
476
502
}
477
503
504
+ impl TryFrom < ParsedOffer > for Offer {
505
+ type Error = ParseError ;
506
+
507
+ fn try_from ( offer : ParsedOffer ) -> Result < Self , Self :: Error > {
508
+ let ( bytes, tlv_stream) = offer;
509
+ let contents = OfferContents :: try_from ( tlv_stream) ?;
510
+ Ok ( Offer { bytes, contents } )
511
+ }
512
+ }
513
+
478
514
impl TryFrom < OfferTlvStream > for OfferContents {
479
515
type Error = SemanticError ;
480
516
@@ -543,11 +579,12 @@ impl core::fmt::Display for Offer {
543
579
544
580
#[ cfg( test) ]
545
581
mod tests {
546
- use super :: { Amount , OfferBuilder } ;
582
+ use super :: { Amount , Offer , OfferBuilder } ;
547
583
548
584
use bitcoin:: blockdata:: constants:: ChainHash ;
549
585
use bitcoin:: network:: constants:: Network ;
550
586
use bitcoin:: secp256k1:: { PublicKey , Secp256k1 , SecretKey } ;
587
+ use core:: convert:: TryFrom ;
551
588
use core:: num:: NonZeroU64 ;
552
589
use core:: time:: Duration ;
553
590
use ln:: features:: OfferFeatures ;
@@ -570,7 +607,7 @@ mod tests {
570
607
let offer = OfferBuilder :: new ( "foo" . into ( ) , pubkey ( 42 ) ) . build ( ) . unwrap ( ) ;
571
608
let tlv_stream = offer. as_tlv_stream ( ) ;
572
609
let mut buffer = Vec :: new ( ) ;
573
- offer. contents . write ( & mut buffer) . unwrap ( ) ;
610
+ offer. write ( & mut buffer) . unwrap ( ) ;
574
611
575
612
assert_eq ! ( offer. bytes, buffer. as_slice( ) ) ;
576
613
assert_eq ! ( offer. chains( ) , vec![ ChainHash :: using_genesis_block( Network :: Bitcoin ) ] ) ;
@@ -599,6 +636,10 @@ mod tests {
599
636
assert_eq ! ( tlv_stream. quantity_min, None ) ;
600
637
assert_eq ! ( tlv_stream. quantity_max, None ) ;
601
638
assert_eq ! ( tlv_stream. node_id, Some ( & pubkey( 42 ) ) ) ;
639
+
640
+ if let Err ( e) = Offer :: try_from ( buffer) {
641
+ panic ! ( "error parsing offer: {:?}" , e) ;
642
+ }
602
643
}
603
644
604
645
#[ test]
0 commit comments