@@ -148,7 +148,8 @@ impl<'a> InvoiceBuilder<'a> {
148
148
Some ( amount_msats) => amount_msats,
149
149
None => match invoice_request. contents . offer . amount ( ) {
150
150
Some ( Amount :: Bitcoin { amount_msats } ) => {
151
- amount_msats * invoice_request. quantity ( ) . unwrap_or ( 1 )
151
+ amount_msats. checked_mul ( invoice_request. quantity ( ) . unwrap_or ( 1 ) )
152
+ . ok_or ( SemanticError :: InvalidAmount ) ?
152
153
} ,
153
154
Some ( Amount :: Currency { .. } ) => return Err ( SemanticError :: UnsupportedCurrency ) ,
154
155
None => return Err ( SemanticError :: MissingAmount ) ,
@@ -787,7 +788,7 @@ mod tests {
787
788
use crate :: ln:: features:: { BlindedHopFeatures , Bolt12InvoiceFeatures } ;
788
789
use crate :: offers:: invoice_request:: InvoiceRequestTlvStreamRef ;
789
790
use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , self } ;
790
- use crate :: offers:: offer:: { OfferBuilder , OfferTlvStreamRef } ;
791
+ use crate :: offers:: offer:: { OfferBuilder , OfferTlvStreamRef , Quantity } ;
791
792
use crate :: offers:: parse:: { ParseError , SemanticError } ;
792
793
use crate :: offers:: payer:: PayerTlvStreamRef ;
793
794
use crate :: offers:: refund:: RefundBuilder ;
@@ -1177,6 +1178,38 @@ mod tests {
1177
1178
assert_eq ! ( tlv_stream. amount, Some ( 1001 ) ) ;
1178
1179
}
1179
1180
1181
+ #[ test]
1182
+ fn builds_invoice_with_quantity_from_request ( ) {
1183
+ let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1184
+ . amount_msats ( 1000 )
1185
+ . supported_quantity ( Quantity :: Unbounded )
1186
+ . build ( ) . unwrap ( )
1187
+ . request_invoice ( vec ! [ 1 ; 32 ] , payer_pubkey ( ) ) . unwrap ( )
1188
+ . quantity ( 2 ) . unwrap ( )
1189
+ . build ( ) . unwrap ( )
1190
+ . sign ( payer_sign) . unwrap ( )
1191
+ . respond_with_no_std ( payment_paths ( ) , payment_hash ( ) , now ( ) ) . unwrap ( )
1192
+ . build ( ) . unwrap ( )
1193
+ . sign ( recipient_sign) . unwrap ( ) ;
1194
+ let ( _, _, _, tlv_stream, _) = invoice. as_tlv_stream ( ) ;
1195
+ assert_eq ! ( invoice. amount_msats( ) , 2000 ) ;
1196
+ assert_eq ! ( tlv_stream. amount, Some ( 2000 ) ) ;
1197
+
1198
+ match OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1199
+ . amount_msats ( 1000 )
1200
+ . supported_quantity ( Quantity :: Unbounded )
1201
+ . build ( ) . unwrap ( )
1202
+ . request_invoice ( vec ! [ 1 ; 32 ] , payer_pubkey ( ) ) . unwrap ( )
1203
+ . quantity ( u64:: max_value ( ) ) . unwrap ( )
1204
+ . build_unchecked ( )
1205
+ . sign ( payer_sign) . unwrap ( )
1206
+ . respond_with_no_std ( payment_paths ( ) , payment_hash ( ) , now ( ) )
1207
+ {
1208
+ Ok ( _) => panic ! ( "expected error" ) ,
1209
+ Err ( e) => assert_eq ! ( e, SemanticError :: InvalidAmount ) ,
1210
+ }
1211
+ }
1212
+
1180
1213
#[ test]
1181
1214
fn builds_invoice_with_fallback_address ( ) {
1182
1215
let script = Script :: new ( ) ;
0 commit comments