Skip to content

Commit 71624c5

Browse files
committed
Use the pay_for_offer_from_hrn method from LDK upstream
This commit ensures that when using the unified API to send to a HRN, we use pay_for_offer_from_hrn
1 parent cc94f39 commit 71624c5

File tree

5 files changed

+86
-5
lines changed

5 files changed

+86
-5
lines changed

bindings/ldk_node.udl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ interface Bolt12Payment {
201201
[Throws=NodeError]
202202
PaymentId send([ByRef]Offer offer, u64? quantity, string? payer_note);
203203
[Throws=NodeError]
204-
PaymentId send_using_amount([ByRef]Offer offer, u64 amount_msat, u64? quantity, string? payer_note);
204+
PaymentId send_using_amount([ByRef]Offer offer, u64 amount_msat, u64? quantity, string? payer_note, HumanReadableName? hrn);
205205
[Throws=NodeError]
206206
Offer receive(u64 amount_msat, [ByRef]string description, u32? expiry_secs, u64? quantity);
207207
[Throws=NodeError]
@@ -320,6 +320,7 @@ enum NodeError {
320320
"LiquidityFeeTooHigh",
321321
"InvalidBlindedPaths",
322322
"AsyncPaymentServicesDisabled",
323+
"HrnParsingFailed",
323324
};
324325

325326
dictionary NodeStatus {
@@ -775,6 +776,13 @@ interface Offer {
775776
PublicKey? issuer_signing_pubkey();
776777
};
777778

779+
interface HumanReadableName {
780+
[Throws=NodeError, Name=from_encoded]
781+
constructor([ByRef] string encoded);
782+
string user();
783+
string domain();
784+
};
785+
778786
[Traits=(Debug, Display, Eq)]
779787
interface Refund {
780788
[Throws=NodeError, Name=from_str]

src/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ pub enum Error {
124124
InvalidBlindedPaths,
125125
/// Asynchronous payment services are disabled.
126126
AsyncPaymentServicesDisabled,
127+
/// Parsing a Human-Readable Name has failed.
128+
HrnParsingFailed,
127129
}
128130

129131
impl fmt::Display for Error {
@@ -201,6 +203,9 @@ impl fmt::Display for Error {
201203
Self::AsyncPaymentServicesDisabled => {
202204
write!(f, "Asynchronous payment services are disabled.")
203205
},
206+
Self::HrnParsingFailed => {
207+
write!(f, "Failed to parse a human-readable name.")
208+
},
204209
}
205210
}
206211
}

src/ffi/types.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub use lightning::ln::types::ChannelId;
2828
pub use lightning::offers::offer::OfferId;
2929
pub use lightning::routing::gossip::{NodeAlias, NodeId, RoutingFees};
3030
pub use lightning::routing::router::RouteParametersConfig;
31+
pub use lightning::onion_message::dns_resolution::HumanReadableName as LdkHumanReadableName;
3132
pub use lightning_types::string::UntrustedString;
3233

3334
pub use lightning_types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
@@ -278,6 +279,58 @@ impl std::fmt::Display for Offer {
278279
}
279280
}
280281

282+
pub struct HumanReadableName {
283+
pub(crate) inner: LdkHumanReadableName,
284+
}
285+
286+
impl HumanReadableName {
287+
pub fn into_inner(&self) -> LdkHumanReadableName {
288+
self.inner.clone()
289+
}
290+
291+
pub fn from_encoded(encoded: &str) -> Result<Self, Error> {
292+
let hrn = match LdkHumanReadableName::from_encoded(encoded) {
293+
Ok(hrn) => Ok(hrn),
294+
Err(_) => Err(Error::HrnParsingFailed),
295+
}?;
296+
297+
Ok(Self { inner: hrn })
298+
}
299+
300+
pub fn user(&self) -> String {
301+
self.inner.user().to_string()
302+
}
303+
304+
pub fn domain(&self) -> String {
305+
self.inner.domain().to_string()
306+
}
307+
}
308+
309+
impl From<LdkHumanReadableName> for HumanReadableName {
310+
fn from(ldk_hrn: LdkHumanReadableName) -> Self {
311+
HumanReadableName { inner: ldk_hrn }
312+
}
313+
}
314+
315+
impl From<HumanReadableName> for LdkHumanReadableName {
316+
fn from(wrapper: HumanReadableName) -> Self {
317+
wrapper.into_inner()
318+
}
319+
}
320+
321+
impl Deref for HumanReadableName {
322+
type Target = LdkHumanReadableName;
323+
fn deref(&self) -> &Self::Target {
324+
&self.inner
325+
}
326+
}
327+
328+
impl AsRef<LdkHumanReadableName> for HumanReadableName {
329+
fn as_ref(&self) -> &LdkHumanReadableName {
330+
self.deref()
331+
}
332+
}
333+
281334
/// A `Refund` is a request to send an [`Bolt12Invoice`] without a preceding [`Offer`].
282335
///
283336
/// Typically, after an invoice is paid, the recipient may publish a refund allowing the sender to

src/payment/bolt12.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::types::{ChannelManager, PaymentStore};
1818

1919
use lightning::blinded_path::message::BlindedMessagePath;
2020
use lightning::ln::channelmanager::{OptionalOfferPaymentParams, PaymentId, Retry};
21-
use lightning::offers::offer::{Amount, Offer as LdkOffer, Quantity};
21+
use lightning::offers::offer::{Amount, Offer as LdkOffer, OfferFromHrn, Quantity};
2222
use lightning::offers::parse::Bolt12SemanticError;
2323
use lightning::routing::router::RouteParametersConfig;
2424

@@ -47,6 +47,11 @@ type Refund = lightning::offers::refund::Refund;
4747
#[cfg(feature = "uniffi")]
4848
type Refund = Arc<crate::ffi::Refund>;
4949

50+
#[cfg(not(feature = "uniffi"))]
51+
type HumanReadableName = lightning::onion_message::dns_resolution::HumanReadableName;
52+
#[cfg(feature = "uniffi")]
53+
type HumanReadableName = Arc<crate::ffi::HumanReadableName>;
54+
5055
/// A payment handler allowing to create and pay [BOLT 12] offers and refunds.
5156
///
5257
/// Should be retrieved by calling [`Node::bolt12_payment`].
@@ -184,6 +189,7 @@ impl Bolt12Payment {
184189
/// response.
185190
pub fn send_using_amount(
186191
&self, offer: &Offer, amount_msat: u64, quantity: Option<u64>, payer_note: Option<String>,
192+
hrn: Option<HumanReadableName>,
187193
) -> Result<PaymentId, Error> {
188194
if !*self.is_running.read().unwrap() {
189195
return Err(Error::NotRunning);
@@ -218,7 +224,11 @@ impl Bolt12Payment {
218224
retry_strategy,
219225
route_params_config,
220226
};
221-
let res = if let Some(quantity) = quantity {
227+
let res = if let Some(hrn) = hrn {
228+
let hrn = maybe_deref(&hrn);
229+
let offer = OfferFromHrn { offer: offer.clone(), hrn: *hrn };
230+
self.channel_manager.pay_for_offer_from_hrn(&offer, amount_msat, payment_id, params)
231+
} else if let Some(quantity) = quantity {
222232
self.channel_manager.pay_for_offer_with_quantity(
223233
&offer,
224234
Some(amount_msat),

src/payment/unified.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::Config;
2323

2424
use lightning::ln::channelmanager::PaymentId;
2525
use lightning::offers::offer::Offer;
26+
use lightning::onion_message::dns_resolution::HumanReadableName;
2627
use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, Description};
2728

2829
use bip21::de::ParamKind;
@@ -199,8 +200,12 @@ impl UnifiedPayment {
199200
resolved.methods().iter().find(|m| matches!(m, PaymentMethod::LightningBolt12(_)))
200201
{
201202
let offer = maybe_wrap(offer.clone());
202-
let payment_result = if let Some(amount_msat) = amount_msat {
203-
self.bolt12_payment.send_using_amount(&offer, amount_msat, None, None)
203+
204+
let payment_result = if let Ok(hrn) = HumanReadableName::from_encoded(uri_str) {
205+
let hrn = maybe_wrap(hrn.clone());
206+
self.bolt12_payment.send_using_amount(&offer, amount_msat.unwrap_or(0), None, None, Some(hrn))
207+
} else if let Some(amount_msat) = amount_msat {
208+
self.bolt12_payment.send_using_amount(&offer, amount_msat, None, None, None)
204209
} else {
205210
self.bolt12_payment.send(&offer, None, None)
206211
}

0 commit comments

Comments
 (0)