Skip to content

Commit 3e30347

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 9b7584b commit 3e30347

File tree

6 files changed

+88
-7
lines changed

6 files changed

+88
-7
lines changed

bindings/ldk_node.udl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ interface Bolt12Payment {
203203
[Throws=NodeError]
204204
PaymentId send([ByRef]Offer offer, u64? quantity, string? payer_note);
205205
[Throws=NodeError]
206-
PaymentId send_using_amount([ByRef]Offer offer, u64 amount_msat, u64? quantity, string? payer_note);
206+
PaymentId send_using_amount([ByRef]Offer offer, u64 amount_msat, u64? quantity, string? payer_note, HumanReadableName? hrn);
207207
[Throws=NodeError]
208208
Offer receive(u64 amount_msat, [ByRef]string description, u32? expiry_secs, u64? quantity);
209209
[Throws=NodeError]
@@ -322,6 +322,7 @@ enum NodeError {
322322
"LiquidityFeeTooHigh",
323323
"InvalidBlindedPaths",
324324
"AsyncPaymentServicesDisabled",
325+
"HrnParsingFailed",
325326
};
326327

327328
dictionary NodeStatus {
@@ -783,6 +784,13 @@ interface Offer {
783784
PublicKey? issuer_signing_pubkey();
784785
};
785786

787+
interface HumanReadableName {
788+
[Throws=NodeError, Name=from_encoded]
789+
constructor([ByRef] string encoded);
790+
string user();
791+
string domain();
792+
};
793+
786794
[Traits=(Debug, Display, Eq)]
787795
interface Refund {
788796
[Throws=NodeError, Name=from_str]

src/error.rs

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

130132
impl fmt::Display for Error {
@@ -202,6 +204,9 @@ impl fmt::Display for Error {
202204
Self::AsyncPaymentServicesDisabled => {
203205
write!(f, "Asynchronous payment services are disabled.")
204206
},
207+
Self::HrnParsingFailed => {
208+
write!(f, "Failed to parse a human-readable name.")
209+
},
205210
}
206211
}
207212
}

src/ffi/types.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,58 @@ impl std::fmt::Display for Offer {
270270
}
271271
}
272272

273+
pub struct HumanReadableName {
274+
pub(crate) inner: LdkHumanReadableName,
275+
}
276+
277+
impl HumanReadableName {
278+
pub fn into_inner(&self) -> LdkHumanReadableName {
279+
self.inner.clone()
280+
}
281+
282+
pub fn from_encoded(encoded: &str) -> Result<Self, Error> {
283+
let hrn = match LdkHumanReadableName::from_encoded(encoded) {
284+
Ok(hrn) => Ok(hrn),
285+
Err(_) => Err(Error::HrnParsingFailed),
286+
}?;
287+
288+
Ok(Self { inner: hrn })
289+
}
290+
291+
pub fn user(&self) -> String {
292+
self.inner.user().to_string()
293+
}
294+
295+
pub fn domain(&self) -> String {
296+
self.inner.domain().to_string()
297+
}
298+
}
299+
300+
impl From<LdkHumanReadableName> for HumanReadableName {
301+
fn from(ldk_hrn: LdkHumanReadableName) -> Self {
302+
HumanReadableName { inner: ldk_hrn }
303+
}
304+
}
305+
306+
impl From<HumanReadableName> for LdkHumanReadableName {
307+
fn from(wrapper: HumanReadableName) -> Self {
308+
wrapper.into_inner()
309+
}
310+
}
311+
312+
impl Deref for HumanReadableName {
313+
type Target = LdkHumanReadableName;
314+
fn deref(&self) -> &Self::Target {
315+
&self.inner
316+
}
317+
}
318+
319+
impl AsRef<LdkHumanReadableName> for HumanReadableName {
320+
fn as_ref(&self) -> &LdkHumanReadableName {
321+
self.deref()
322+
}
323+
}
324+
273325
/// A `Refund` is a request to send an [`Bolt12Invoice`] without a preceding [`Offer`].
274326
///
275327
/// 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
@@ -15,7 +15,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
1515

1616
use lightning::blinded_path::message::BlindedMessagePath;
1717
use 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};
1919
use lightning::offers::parse::Bolt12SemanticError;
2020
use lightning::routing::router::RouteParametersConfig;
2121
#[cfg(feature = "uniffi")]
@@ -45,6 +45,11 @@ type Refund = lightning::offers::refund::Refund;
4545
#[cfg(feature = "uniffi")]
4646
type 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`].
@@ -183,6 +188,7 @@ impl Bolt12Payment {
183188
/// response.
184189
pub fn send_using_amount(
185190
&self, offer: &Offer, amount_msat: u64, quantity: Option<u64>, payer_note: Option<String>,
191+
hrn: Option<HumanReadableName>,
186192
) -> Result<PaymentId, Error> {
187193
if !*self.is_running.read().unwrap() {
188194
return Err(Error::NotRunning);
@@ -217,7 +223,11 @@ impl Bolt12Payment {
217223
retry_strategy,
218224
route_params_config,
219225
};
220-
let res = if let Some(quantity) = quantity {
226+
let res = if let Some(hrn) = hrn {
227+
let hrn = maybe_deref(&hrn);
228+
let offer = OfferFromHrn { offer: offer.clone(), hrn: *hrn };
229+
self.channel_manager.pay_for_offer_from_hrn(&offer, amount_msat, payment_id, params)
230+
} else if let Some(quantity) = quantity {
221231
self.channel_manager.pay_for_offer_with_quantity(
222232
&offer,
223233
Some(amount_msat),

src/payment/unified.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::vec::IntoIter;
2525

2626
use lightning::ln::channelmanager::PaymentId;
2727
use lightning::offers::offer::Offer;
28+
use lightning::onion_message::dns_resolution::HumanReadableName;
2829
use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, Description};
2930

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

tests/integration_tests_rust.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ async fn simple_bolt12_send_receive() {
10231023
let expected_payer_note = Some("Test".to_string());
10241024
assert!(node_a
10251025
.bolt12_payment()
1026-
.send_using_amount(&offer, less_than_offer_amount, None, None)
1026+
.send_using_amount(&offer, less_than_offer_amount, None, None, None)
10271027
.is_err());
10281028
let payment_id = node_a
10291029
.bolt12_payment()
@@ -1032,6 +1032,7 @@ async fn simple_bolt12_send_receive() {
10321032
expected_amount_msat,
10331033
expected_quantity,
10341034
expected_payer_note.clone(),
1035+
None,
10351036
)
10361037
.unwrap();
10371038

@@ -1275,7 +1276,7 @@ async fn async_payment() {
12751276
node_receiver.stop().unwrap();
12761277

12771278
let payment_id =
1278-
node_sender.bolt12_payment().send_using_amount(&offer, 5_000, None, None).unwrap();
1279+
node_sender.bolt12_payment().send_using_amount(&offer, 5_000, None, None, None).unwrap();
12791280

12801281
// Sleep to allow the payment reach a state where the htlc is held and waiting for the receiver to come online.
12811282
tokio::time::sleep(std::time::Duration::from_millis(3000)).await;

0 commit comments

Comments
 (0)