@@ -733,6 +733,12 @@ impl InvoiceFields {
733
733
}
734
734
}
735
735
736
+ impl Writeable for UnsignedBolt12Invoice {
737
+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
738
+ WithoutLength ( & self . bytes ) . write ( writer)
739
+ }
740
+ }
741
+
736
742
impl Writeable for Bolt12Invoice {
737
743
fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
738
744
WithoutLength ( & self . bytes ) . write ( writer)
@@ -745,6 +751,25 @@ impl Writeable for InvoiceContents {
745
751
}
746
752
}
747
753
754
+ impl TryFrom < Vec < u8 > > for UnsignedBolt12Invoice {
755
+ type Error = Bolt12ParseError ;
756
+
757
+ fn try_from ( bytes : Vec < u8 > ) -> Result < Self , Self :: Error > {
758
+ let invoice = ParsedMessage :: < PartialInvoiceTlvStream > :: try_from ( bytes) ?;
759
+ let ParsedMessage { bytes, tlv_stream } = invoice;
760
+ let (
761
+ payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
762
+ ) = tlv_stream;
763
+ let contents = InvoiceContents :: try_from (
764
+ ( payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream)
765
+ ) ?;
766
+
767
+ let tagged_hash = TaggedHash :: new ( SIGNATURE_TAG , & bytes) ;
768
+
769
+ Ok ( UnsignedBolt12Invoice { bytes, contents, tagged_hash } )
770
+ }
771
+ }
772
+
748
773
impl TryFrom < Vec < u8 > > for Bolt12Invoice {
749
774
type Error = Bolt12ParseError ;
750
775
@@ -857,6 +882,17 @@ type PartialInvoiceTlvStreamRef<'a> = (
857
882
InvoiceTlvStreamRef < ' a > ,
858
883
) ;
859
884
885
+ impl SeekReadable for PartialInvoiceTlvStream {
886
+ fn read < R : io:: Read + io:: Seek > ( r : & mut R ) -> Result < Self , DecodeError > {
887
+ let payer = SeekReadable :: read ( r) ?;
888
+ let offer = SeekReadable :: read ( r) ?;
889
+ let invoice_request = SeekReadable :: read ( r) ?;
890
+ let invoice = SeekReadable :: read ( r) ?;
891
+
892
+ Ok ( ( payer, offer, invoice_request, invoice) )
893
+ }
894
+ }
895
+
860
896
impl TryFrom < ParsedMessage < FullInvoiceTlvStream > > for Bolt12Invoice {
861
897
type Error = Bolt12ParseError ;
862
898
@@ -961,7 +997,7 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
961
997
962
998
#[ cfg( test) ]
963
999
mod tests {
964
- use super :: { Bolt12Invoice , DEFAULT_RELATIVE_EXPIRY , FallbackAddress , FullInvoiceTlvStreamRef , InvoiceTlvStreamRef , SIGNATURE_TAG } ;
1000
+ use super :: { Bolt12Invoice , DEFAULT_RELATIVE_EXPIRY , FallbackAddress , FullInvoiceTlvStreamRef , InvoiceTlvStreamRef , SIGNATURE_TAG , UnsignedBolt12Invoice } ;
965
1001
966
1002
use bitcoin:: blockdata:: script:: Script ;
967
1003
use bitcoin:: hashes:: Hash ;
@@ -1007,15 +1043,27 @@ mod tests {
1007
1043
let payment_paths = payment_paths ( ) ;
1008
1044
let payment_hash = payment_hash ( ) ;
1009
1045
let now = now ( ) ;
1010
- let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1046
+ let unsigned_invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1011
1047
. amount_msats ( 1000 )
1012
1048
. build ( ) . unwrap ( )
1013
1049
. request_invoice ( vec ! [ 1 ; 32 ] , payer_pubkey ( ) ) . unwrap ( )
1014
1050
. build ( ) . unwrap ( )
1015
1051
. sign ( payer_sign) . unwrap ( )
1016
1052
. respond_with_no_std ( payment_paths. clone ( ) , payment_hash, now) . unwrap ( )
1017
- . build ( ) . unwrap ( )
1018
- . sign ( recipient_sign) . unwrap ( ) ;
1053
+ . build ( ) . unwrap ( ) ;
1054
+
1055
+ let mut buffer = Vec :: new ( ) ;
1056
+ unsigned_invoice. write ( & mut buffer) . unwrap ( ) ;
1057
+
1058
+ match UnsignedBolt12Invoice :: try_from ( buffer) {
1059
+ Err ( e) => panic ! ( "error parsing unsigned invoice: {:?}" , e) ,
1060
+ Ok ( parsed) => {
1061
+ assert_eq ! ( parsed. bytes, unsigned_invoice. bytes) ;
1062
+ assert_eq ! ( parsed. tagged_hash, unsigned_invoice. tagged_hash) ;
1063
+ } ,
1064
+ }
1065
+
1066
+ let invoice = unsigned_invoice. sign ( recipient_sign) . unwrap ( ) ;
1019
1067
1020
1068
let mut buffer = Vec :: new ( ) ;
1021
1069
invoice. write ( & mut buffer) . unwrap ( ) ;
0 commit comments