@@ -17,6 +17,8 @@ use lightning::ln::channelmanager::{
1717use lightning:: ln:: msgs:: SocketAddress ;
1818use lightning:: ln:: types:: ChannelId ;
1919use lightning:: offers:: offer:: { self , Offer } ;
20+ use lightning:: onion_message:: dns_resolution:: HumanReadableName ;
21+ use lightning:: onion_message:: messenger:: Destination ;
2022use lightning:: routing:: gossip:: NodeId ;
2123use lightning:: routing:: router:: { PaymentParameters , RouteParameters } ;
2224use 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,77 @@ 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+ // Sadly, 31 nodes currently squat on the DNS Resolver feature bit
241+ // without speaking it.
242+ // Its unclear why they're doing so, but none of them currently
243+ // also have the onion messaging feature bit set, so here we check
244+ // for both.
245+ let supports_dns = info. features ( ) . supports_dns_resolution ( ) ;
246+ let supports_om = info. features ( ) . supports_onion_messages ( ) ;
247+ if supports_dns && supports_om {
248+ if let Ok ( pubkey) = node_id. as_pubkey ( ) {
249+ dns_resolvers. push ( Destination :: Node ( pubkey) ) ;
250+ }
251+ }
252+ }
253+ if dns_resolvers. len ( ) > 5 {
254+ break ;
255+ }
256+ }
257+ if dns_resolvers. is_empty ( ) {
258+ println ! (
259+ "Failed to find any DNS resolving nodes, check your network graph is synced"
260+ ) ;
261+ continue ;
262+ }
263+
264+ let amt_msat = user_provided_amt. unwrap ( ) ;
265+ outbound_payments. lock ( ) . unwrap ( ) . payments . insert (
266+ payment_id,
267+ PaymentInfo {
268+ preimage : None ,
269+ secret : None ,
270+ status : HTLCStatus :: Pending ,
271+ amt_msat : MillisatAmount ( Some ( amt_msat) ) ,
272+ } ,
273+ ) ;
274+ fs_store
275+ . write ( "" , "" , OUTBOUND_PAYMENTS_FNAME , & outbound_payments. encode ( ) )
276+ . unwrap ( ) ;
277+
278+ let retry = Retry :: Timeout ( Duration :: from_secs ( 10 ) ) ;
279+ let pay = |a, b, c, d, e, f| {
280+ channel_manager. pay_for_offer_from_human_readable_name ( a, b, c, d, e, f)
281+ } ;
282+ let pay = pay ( hrn, amt_msat, payment_id, retry, None , dns_resolvers) ;
283+ if pay. is_ok ( ) {
284+ println ! ( "Payment in flight" ) ;
285+ } else {
286+ println ! ( "ERROR: Failed to pay" ) ;
287+ }
219288 } else {
220- match Bolt11Invoice :: from_str ( invoice_str. unwrap ( ) ) {
289+ match Bolt11Invoice :: from_str ( invoice_str) {
221290 Ok ( invoice) => send_payment (
222291 & channel_manager,
223292 & invoice,
@@ -505,7 +574,7 @@ fn help() {
505574 println ! ( " disconnectpeer <peer_pubkey>" ) ;
506575 println ! ( " listpeers" ) ;
507576 println ! ( "\n Payments:" ) ;
508- println ! ( " sendpayment <invoice|offer> [<amount_msat>]" ) ;
577+ println ! ( " sendpayment <invoice|offer|human readable name > [<amount_msat>]" ) ;
509578 println ! ( " keysend <dest_pubkey> <amt_msats>" ) ;
510579 println ! ( " listpayments" ) ;
511580 println ! ( "\n Invoices:" ) ;
0 commit comments