Skip to content

Commit 276ad89

Browse files
committed
Add HRN-based payments to sendpayment
1 parent d6e65fa commit 276ad89

File tree

1 file changed

+66
-4
lines changed

1 file changed

+66
-4
lines changed

src/cli.rs

+66-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use lightning::ln::channelmanager::{
1717
use lightning::ln::msgs::SocketAddress;
1818
use lightning::ln::types::ChannelId;
1919
use lightning::offers::offer::{self, Offer};
20+
use lightning::onion_message::dns_resolution::HumanReadableName;
21+
use lightning::onion_message::messenger::Destination;
2022
use lightning::routing::gossip::NodeId;
2123
use lightning::routing::router::{PaymentParameters, RouteParameters};
2224
use lightning::sign::{EntropySource, KeysManager};
@@ -142,9 +144,10 @@ pub(crate) fn poll_for_user_input(
142144
"sendpayment" => {
143145
let invoice_str = words.next();
144146
if invoice_str.is_none() {
145-
println!("ERROR: sendpayment requires an invoice: `sendpayment <invoice>`");
147+
println!("ERROR: sendpayment requires an invoice: `sendpayment <invoice> [amount_msat]`");
146148
continue;
147149
}
150+
let invoice_str = invoice_str.unwrap();
148151

149152
let mut user_provided_amt: Option<u64> = None;
150153
if let Some(amt_msat_str) = words.next() {
@@ -157,7 +160,7 @@ pub(crate) fn poll_for_user_input(
157160
};
158161
}
159162

160-
if let Ok(offer) = Offer::from_str(invoice_str.unwrap()) {
163+
if let Ok(offer) = Offer::from_str(invoice_str) {
161164
let random_bytes = keys_manager.get_secure_random_bytes();
162165
let payment_id = PaymentId(random_bytes);
163166

@@ -213,11 +216,70 @@ pub(crate) fn poll_for_user_input(
213216
let amt = Some(amt_msat);
214217
let pay = channel_manager
215218
.pay_for_offer(&offer, None, amt, None, payment_id, retry, None);
216-
if pay.is_err() {
219+
if pay.is_ok() {
220+
println!("Payment in flight");
221+
} else {
217222
println!("ERROR: Failed to pay: {:?}", pay);
218223
}
224+
} else if let Ok(hrn) = HumanReadableName::from_encoded(invoice_str) {
225+
let random_bytes = keys_manager.get_secure_random_bytes();
226+
let payment_id = PaymentId(random_bytes);
227+
228+
if user_provided_amt.is_none() {
229+
println!("Can't pay to a human-readable-name without an amount");
230+
continue;
231+
}
232+
233+
// We need some nodes that will resolve DNS for us in order to pay a Human
234+
// Readable Name. They don't need to be trusted, but until onion message
235+
// forwarding is widespread we'll directly connect to them, revealing who
236+
// we intend to pay.
237+
let mut dns_resolvers = Vec::new();
238+
for (node_id, node) in network_graph.read_only().nodes().unordered_iter() {
239+
if let Some(info) = &node.announcement_info {
240+
if info.features().supports_dns_resolution() {
241+
if let Ok(pubkey) = node_id.as_pubkey() {
242+
dns_resolvers.push(Destination::Node(pubkey));
243+
}
244+
}
245+
}
246+
if dns_resolvers.len() > 5 {
247+
break;
248+
}
249+
}
250+
if dns_resolvers.is_empty() {
251+
println!(
252+
"Failed to find any DNS resolving nodes, check your network graph is synced"
253+
);
254+
continue;
255+
}
256+
257+
let amt_msat = user_provided_amt.unwrap();
258+
outbound_payments.lock().unwrap().payments.insert(
259+
payment_id,
260+
PaymentInfo {
261+
preimage: None,
262+
secret: None,
263+
status: HTLCStatus::Pending,
264+
amt_msat: MillisatAmount(Some(amt_msat)),
265+
},
266+
);
267+
fs_store
268+
.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound_payments.encode())
269+
.unwrap();
270+
271+
let retry = Retry::Timeout(Duration::from_secs(10));
272+
let pay = |a, b, c, d, e, f| {
273+
channel_manager.pay_for_offer_from_human_readable_name(a, b, c, d, e, f)
274+
};
275+
let pay = pay(hrn, amt_msat, payment_id, retry, None, dns_resolvers);
276+
if pay.is_ok() {
277+
println!("Payment in flight");
278+
} else {
279+
println!("ERROR: Failed to pay");
280+
}
219281
} else {
220-
match Bolt11Invoice::from_str(invoice_str.unwrap()) {
282+
match Bolt11Invoice::from_str(invoice_str) {
221283
Ok(invoice) => send_payment(
222284
&channel_manager,
223285
&invoice,

0 commit comments

Comments
 (0)