@@ -61,6 +61,7 @@ use core::ops::{Bound, RangeBounds};
61
61
use core:: time:: Duration ;
62
62
use io;
63
63
use ln:: features:: OfferFeatures ;
64
+ use ln:: msgs:: MAX_VALUE_MSAT ;
64
65
use onion_message:: BlindedPath ;
65
66
use util:: ser:: { Writeable , Writer } ;
66
67
@@ -204,6 +205,14 @@ impl OfferBuilder {
204
205
205
206
/// Builds an [`Offer`] from the builder's settings.
206
207
pub fn build ( self ) -> Result < Offer , ( ) > {
208
+ if let Some ( Amount :: Currency { .. } ) = self . offer . amount {
209
+ return Err ( ( ) ) ;
210
+ }
211
+
212
+ if self . offer . amount_msats ( ) > MAX_VALUE_MSAT {
213
+ return Err ( ( ) ) ;
214
+ }
215
+
207
216
if self . offer . quantity_min ( ) > self . offer . quantity_max ( ) {
208
217
return Err ( ( ) ) ;
209
218
}
@@ -332,6 +341,10 @@ impl Offer {
332
341
}
333
342
334
343
impl OfferContents {
344
+ pub fn amount_msats ( & self ) -> u64 {
345
+ self . amount . as_ref ( ) . map ( Amount :: as_msats) . unwrap_or ( 0 )
346
+ }
347
+
335
348
pub fn quantity_min ( & self ) -> u64 {
336
349
self . quantity_min . unwrap_or ( 1 )
337
350
}
@@ -395,6 +408,16 @@ pub enum Amount {
395
408
} ,
396
409
}
397
410
411
+ impl Amount {
412
+ /// Returns the amount in millisatoshi.
413
+ pub fn as_msats ( & self ) -> u64 {
414
+ match self {
415
+ Amount :: Currency { .. } => unimplemented ! ( ) ,
416
+ Amount :: Bitcoin { amount_msats } => * amount_msats,
417
+ }
418
+ }
419
+ }
420
+
398
421
/// An ISO 4712 three-letter currency code (e.g., USD).
399
422
pub type CurrencyCode = [ u8 ; 3 ] ;
400
423
@@ -423,6 +446,7 @@ mod tests {
423
446
use core:: num:: NonZeroU64 ;
424
447
use core:: time:: Duration ;
425
448
use ln:: features:: OfferFeatures ;
449
+ use ln:: msgs:: MAX_VALUE_MSAT ;
426
450
use onion_message:: { BlindedHop , BlindedPath } ;
427
451
use util:: ser:: Writeable ;
428
452
@@ -535,14 +559,16 @@ mod tests {
535
559
assert_eq ! ( tlv_stream. amount, Some ( 1000 ) ) ;
536
560
assert_eq ! ( tlv_stream. currency, None ) ;
537
561
538
- let offer = OfferBuilder :: new ( "foo" . into ( ) , pubkey ( 42 ) )
539
- . amount ( currency_amount. clone ( ) )
540
- . build ( )
541
- . unwrap ( ) ;
542
- let tlv_stream = offer. as_tlv_stream ( ) ;
543
- assert_eq ! ( offer. amount( ) , Some ( & currency_amount) ) ;
562
+ let builder = OfferBuilder :: new ( "foo" . into ( ) , pubkey ( 42 ) )
563
+ . amount ( currency_amount. clone ( ) ) ;
564
+ let tlv_stream = builder. offer . as_tlv_stream ( ) ;
565
+ assert_eq ! ( builder. offer. amount. as_ref( ) , Some ( & currency_amount) ) ;
544
566
assert_eq ! ( tlv_stream. amount, Some ( 10 ) ) ;
545
567
assert_eq ! ( tlv_stream. currency, Some ( b"USD" ) ) ;
568
+ match builder. build ( ) {
569
+ Ok ( _) => panic ! ( "expected error" ) ,
570
+ Err ( e) => assert_eq ! ( e, ( ) ) ,
571
+ }
546
572
547
573
let offer = OfferBuilder :: new ( "foo" . into ( ) , pubkey ( 42 ) )
548
574
. amount ( currency_amount. clone ( ) )
@@ -552,6 +578,12 @@ mod tests {
552
578
let tlv_stream = offer. as_tlv_stream ( ) ;
553
579
assert_eq ! ( tlv_stream. amount, Some ( 1000 ) ) ;
554
580
assert_eq ! ( tlv_stream. currency, None ) ;
581
+
582
+ let invalid_amount = Amount :: Bitcoin { amount_msats : MAX_VALUE_MSAT + 1 } ;
583
+ match OfferBuilder :: new ( "foo" . into ( ) , pubkey ( 42 ) ) . amount ( invalid_amount) . build ( ) {
584
+ Ok ( _) => panic ! ( "expected error" ) ,
585
+ Err ( e) => assert_eq ! ( e, ( ) ) ,
586
+ }
555
587
}
556
588
557
589
#[ test]
0 commit comments