@@ -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,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,
@@ -505,7 +567,7 @@ fn help() {
505567 println ! ( " disconnectpeer <peer_pubkey>" ) ;
506568 println ! ( " listpeers" ) ;
507569 println ! ( "\n Payments:" ) ;
508- println ! ( " sendpayment <invoice|offer> [<amount_msat>]" ) ;
570+ println ! ( " sendpayment <invoice|offer|human readable name > [<amount_msat>]" ) ;
509571 println ! ( " keysend <dest_pubkey> <amt_msats>" ) ;
510572 println ! ( " listpayments" ) ;
511573 println ! ( "\n Invoices:" ) ;
0 commit comments