@@ -15,7 +15,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
1515
1616use lightning:: blinded_path:: message:: BlindedMessagePath ;
1717use lightning:: ln:: channelmanager:: { OptionalOfferPaymentParams , PaymentId , Retry } ;
18- use lightning:: offers:: offer:: { Amount , Offer as LdkOffer , Quantity } ;
18+ use lightning:: offers:: offer:: { Amount , Offer as LdkOffer , OfferFromHrn , Quantity } ;
1919use lightning:: offers:: parse:: Bolt12SemanticError ;
2020use lightning:: routing:: router:: RouteParametersConfig ;
2121#[ cfg( feature = "uniffi" ) ]
@@ -45,6 +45,11 @@ type Refund = lightning::offers::refund::Refund;
4545#[ cfg( feature = "uniffi" ) ]
4646type Refund = Arc < crate :: ffi:: Refund > ;
4747
48+ #[ cfg( not( feature = "uniffi" ) ) ]
49+ type HumanReadableName = lightning:: onion_message:: dns_resolution:: HumanReadableName ;
50+ #[ cfg( feature = "uniffi" ) ]
51+ type HumanReadableName = Arc < crate :: ffi:: HumanReadableName > ;
52+
4853/// A payment handler allowing to create and pay [BOLT 12] offers and refunds.
4954///
5055/// Should be retrieved by calling [`Node::bolt12_payment`].
@@ -193,6 +198,37 @@ impl Bolt12Payment {
193198 pub fn send_using_amount (
194199 & self , offer : & Offer , amount_msat : u64 , quantity : Option < u64 > , payer_note : Option < String > ,
195200 route_parameters : Option < RouteParametersConfig > ,
201+ ) -> Result < PaymentId , Error > {
202+ let payment_id = self . send_using_amount_inner (
203+ offer,
204+ amount_msat,
205+ quantity,
206+ payer_note,
207+ route_parameters,
208+ None ,
209+ ) ?;
210+ Ok ( payment_id)
211+ }
212+
213+ /// Internal helper to send a BOLT12 offer payment given an offer
214+ /// and an amount in millisatoshi.
215+ ///
216+ /// This function contains the core payment logic and is called by
217+ /// [`Self::send_using_amount`] and other internal logic that resolves
218+ /// payment parameters (e.g. [`crate::UnifiedPayment::send`]).
219+ ///
220+ /// It wraps the core LDK `pay_for_offer` logic and handles necessary pre-checks,
221+ /// payment ID generation, and payment details storage.
222+ ///
223+ /// The amount validation logic ensures the provided `amount_msat` is sufficient
224+ /// based on the offer's required amount.
225+ ///
226+ /// If `hrn` is `Some`, the payment is initiated using [`ChannelManager::pay_for_offer_from_hrn`]
227+ /// for offers resolved from a Human-Readable Name ([`HumanReadableName`]).
228+ /// Otherwise, it falls back to the standard offer payment methods.
229+ pub ( crate ) fn send_using_amount_inner (
230+ & self , offer : & Offer , amount_msat : u64 , quantity : Option < u64 > , payer_note : Option < String > ,
231+ route_parameters : Option < RouteParametersConfig > , hrn : Option < HumanReadableName > ,
196232 ) -> Result < PaymentId , Error > {
197233 if !* self . is_running . read ( ) . unwrap ( ) {
198234 return Err ( Error :: NotRunning ) ;
@@ -228,7 +264,11 @@ impl Bolt12Payment {
228264 retry_strategy,
229265 route_params_config : route_parameters,
230266 } ;
231- let res = if let Some ( quantity) = quantity {
267+ let res = if let Some ( hrn) = hrn {
268+ let hrn = maybe_deref ( & hrn) ;
269+ let offer = OfferFromHrn { offer : offer. clone ( ) , hrn : * hrn } ;
270+ self . channel_manager . pay_for_offer_from_hrn ( & offer, amount_msat, payment_id, params)
271+ } else if let Some ( quantity) = quantity {
232272 self . channel_manager . pay_for_offer_with_quantity (
233273 & offer,
234274 Some ( amount_msat) ,
0 commit comments