@@ -270,6 +270,72 @@ impl Bolt12Payment {
270
270
}
271
271
}
272
272
273
+ /// Send a payment to an offer resolved from a human-readable name [BIP 353].
274
+ ///
275
+ /// Paying to human-readable names makes it more intuitive to make payments for offers
276
+ /// as users can simply send payments to HRNs such as `user@example.com`.
277
+ ///
278
+ /// This can be used to pay so-called "zero-amount" offers, i.e., an offer that leaves the
279
+ /// amount paid to be determined by the user.
280
+ ///
281
+ /// `dns_resolvers` should be a list of node Destinations that are configured for dns resolution (as outlined in bLIP 32).
282
+ /// These nodes can be found by running a search through the `NetworkGraph` to find nodes that announce the
283
+ /// `dns_resolver` feature flag.
284
+ pub fn send_to_human_readable_name (
285
+ & self , name : & str , amount_msat : u64 , dns_resolvers : Vec < Destination > ,
286
+ ) -> Result < PaymentId , Error > {
287
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
288
+ if rt_lock. is_none ( ) {
289
+ return Err ( Error :: NotRunning ) ;
290
+ }
291
+
292
+ let hrn = HumanReadableName :: from_encoded ( & name) . map_err ( |_| Error :: HrnParsingFailed ) ?;
293
+
294
+ let mut random_bytes = [ 0u8 ; 32 ] ;
295
+ rand:: thread_rng ( ) . fill_bytes ( & mut random_bytes) ;
296
+ let payment_id = PaymentId ( random_bytes) ;
297
+ let retry_strategy = Retry :: Timeout ( LDK_PAYMENT_RETRY_TIMEOUT ) ;
298
+ let max_total_routing_fee_msat = None ;
299
+
300
+ match self . channel_manager . pay_for_offer_from_human_readable_name (
301
+ hrn. clone ( ) ,
302
+ amount_msat,
303
+ payment_id,
304
+ retry_strategy,
305
+ max_total_routing_fee_msat,
306
+ dns_resolvers,
307
+ ) {
308
+ Ok ( ( ) ) => {
309
+ log_info ! ( self . logger, "Initiated sending {} msats to {}" , amount_msat, name) ;
310
+ let kind = PaymentKind :: HrnBolt12Offer { hrn } ;
311
+ let payment = PaymentDetails :: new (
312
+ payment_id,
313
+ kind,
314
+ Some ( amount_msat) ,
315
+ None ,
316
+ PaymentDirection :: Outbound ,
317
+ PaymentStatus :: Pending ,
318
+ ) ;
319
+ self . payment_store . insert ( payment) ?;
320
+ Ok ( payment_id)
321
+ } ,
322
+ Err ( ( ) ) => {
323
+ log_error ! ( self . logger, "Failed to send payment to {}" , name) ;
324
+ let kind = PaymentKind :: HrnBolt12Offer { hrn } ;
325
+ let payment = PaymentDetails :: new (
326
+ payment_id,
327
+ kind,
328
+ Some ( amount_msat) ,
329
+ None ,
330
+ PaymentDirection :: Outbound ,
331
+ PaymentStatus :: Pending ,
332
+ ) ;
333
+ self . payment_store . insert ( payment) ?;
334
+ Err ( Error :: PaymentSendingFailed )
335
+ } ,
336
+ }
337
+ }
338
+
273
339
pub ( crate ) fn receive_inner (
274
340
& self , amount_msat : u64 , description : & str , expiry_secs : Option < u32 > , quantity : Option < u64 > ,
275
341
) -> Result < LdkOffer , Error > {
0 commit comments