@@ -11,12 +11,15 @@ use crate::payment::store::{
11
11
use crate :: types:: ChannelManager ;
12
12
13
13
use lightning:: ln:: channelmanager:: { PaymentId , Retry } ;
14
+ use lightning:: offers:: invoice:: Bolt12Invoice ;
14
15
use lightning:: offers:: offer:: { Amount , Offer } ;
15
16
use lightning:: offers:: parse:: Bolt12SemanticError ;
17
+ use lightning:: offers:: refund:: Refund ;
16
18
17
19
use rand:: RngCore ;
18
20
19
21
use std:: sync:: { Arc , RwLock } ;
22
+ use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
20
23
21
24
/// A payment handler allowing to create and pay [BOLT 12] offers and refunds.
22
25
///
@@ -264,4 +267,62 @@ impl Bolt12Payment {
264
267
265
268
Ok ( offer)
266
269
}
270
+
271
+ /// Requests a refund payment for the given [`Refund`].
272
+ ///
273
+ /// The returned [`Bolt12Invoice`] is for informational purposes only (i.e., isn't needed to
274
+ /// retrieve the refund).
275
+ pub fn request_refund ( & self , refund : & Refund ) -> Result < Bolt12Invoice , Error > {
276
+ self . channel_manager . request_refund_payment ( refund) . map_err ( |e| {
277
+ log_error ! ( self . logger, "Failed to request refund payment: {:?}" , e) ;
278
+ Error :: InvalidRefund
279
+ } )
280
+ }
281
+
282
+ /// Returns a [`Refund`] that can be used to offer a refund payment of the amount given.
283
+ pub fn offer_refund ( & self , amount_msat : u64 , expiry_secs : u32 ) -> Result < Refund , Error > {
284
+ let mut random_bytes = [ 0u8 ; 32 ] ;
285
+ rand:: thread_rng ( ) . fill_bytes ( & mut random_bytes) ;
286
+ let payment_id = PaymentId ( random_bytes) ;
287
+
288
+ let expiration = ( SystemTime :: now ( ) + Duration :: from_secs ( expiry_secs as u64 ) )
289
+ . duration_since ( UNIX_EPOCH )
290
+ . unwrap ( ) ;
291
+ let retry_strategy = Retry :: Timeout ( LDK_PAYMENT_RETRY_TIMEOUT ) ;
292
+ let max_total_routing_fee_msat = None ;
293
+
294
+ let refund_builder = self
295
+ . channel_manager
296
+ . create_refund_builder (
297
+ amount_msat,
298
+ expiration,
299
+ payment_id,
300
+ retry_strategy,
301
+ max_total_routing_fee_msat,
302
+ )
303
+ . map_err ( |e| {
304
+ log_error ! ( self . logger, "Failed to create refund builder: {:?}" , e) ;
305
+ Error :: RefundCreationFailed
306
+ } ) ?;
307
+ let refund = refund_builder. build ( ) . map_err ( |e| {
308
+ log_error ! ( self . logger, "Failed to create refund: {:?}" , e) ;
309
+ Error :: RefundCreationFailed
310
+ } ) ?;
311
+
312
+ log_info ! ( self . logger, "Offering refund of {}msat" , amount_msat) ;
313
+
314
+ let kind = PaymentKind :: Bolt12Refund { hash : None , preimage : None , secret : None } ;
315
+
316
+ let payment = PaymentDetails {
317
+ id : payment_id,
318
+ kind,
319
+ amount_msat : Some ( amount_msat) ,
320
+ direction : PaymentDirection :: Outbound ,
321
+ status : PaymentStatus :: Pending ,
322
+ } ;
323
+
324
+ self . payment_store . insert ( payment) ?;
325
+
326
+ Ok ( refund)
327
+ }
267
328
}
0 commit comments