@@ -17,6 +17,8 @@ use lightning::ln::channelmanager::{
17
17
use lightning:: ln:: msgs:: SocketAddress ;
18
18
use lightning:: ln:: types:: ChannelId ;
19
19
use lightning:: offers:: offer:: { self , Offer } ;
20
+ use lightning:: onion_message:: dns_resolution:: HumanReadableName ;
21
+ use lightning:: onion_message:: messenger:: Destination ;
20
22
use lightning:: routing:: gossip:: NodeId ;
21
23
use lightning:: routing:: router:: { PaymentParameters , RouteParameters } ;
22
24
use lightning:: sign:: { EntropySource , KeysManager } ;
@@ -142,9 +144,10 @@ pub(crate) fn poll_for_user_input(
142
144
"sendpayment" => {
143
145
let invoice_str = words. next ( ) ;
144
146
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] `" ) ;
146
148
continue ;
147
149
}
150
+ let invoice_str = invoice_str. unwrap ( ) ;
148
151
149
152
let mut user_provided_amt: Option < u64 > = None ;
150
153
if let Some ( amt_msat_str) = words. next ( ) {
@@ -157,7 +160,7 @@ pub(crate) fn poll_for_user_input(
157
160
} ;
158
161
}
159
162
160
- if let Ok ( offer) = Offer :: from_str ( invoice_str. unwrap ( ) ) {
163
+ if let Ok ( offer) = Offer :: from_str ( invoice_str) {
161
164
let random_bytes = keys_manager. get_secure_random_bytes ( ) ;
162
165
let payment_id = PaymentId ( random_bytes) ;
163
166
@@ -213,11 +216,70 @@ pub(crate) fn poll_for_user_input(
213
216
let amt = Some ( amt_msat) ;
214
217
let pay = channel_manager
215
218
. 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 {
217
222
println ! ( "ERROR: Failed to pay: {:?}" , pay) ;
218
223
}
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
+ }
219
281
} else {
220
- match Bolt11Invoice :: from_str ( invoice_str. unwrap ( ) ) {
282
+ match Bolt11Invoice :: from_str ( invoice_str) {
221
283
Ok ( invoice) => send_payment (
222
284
& channel_manager,
223
285
& invoice,
0 commit comments