X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fcli.rs;h=476ea81efd6803e393f237bd5965333767b00bc2;hb=e87a9e18f6739988b93b6bc38c1ae178c0bdaeb8;hp=b45de4221b95da49c5e9021b37f94728ded5ea57;hpb=90c12f0f24689326ae09637a9ad620f781d97e5c;p=ldk-sample diff --git a/src/cli.rs b/src/cli.rs index b45de42..476ea81 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -70,7 +70,10 @@ pub(crate) fn parse_startup_args() -> Result { let mut ldk_peer_port_set = true; let ldk_peer_listening_port: u16 = match env::args().skip(3).next().map(|p| p.parse()) { Some(Ok(p)) => p, - Some(Err(e)) => panic!("{}", e), + Some(Err(_)) => { + ldk_peer_port_set = false; + 9735 + } None => { ldk_peer_port_set = false; 9735 @@ -84,7 +87,9 @@ pub(crate) fn parse_startup_args() -> Result { let network: Network = match env::args().skip(arg_idx).next().as_ref().map(String::as_str) { Some("testnet") => Network::Testnet, Some("regtest") => Network::Regtest, - Some(_) => panic!("Unsupported network provided. Options are: `regtest`, `testnet`"), + Some(net) => { + panic!("Unsupported network provided. Options are: `regtest`, `testnet`. Got {}", net); + } None => Network::Testnet, }; @@ -267,6 +272,52 @@ pub(crate) async fn poll_for_user_input( logger.clone(), ); } + "keysend" => { + let dest_pubkey = match words.next() { + Some(dest) => match hex_utils::to_compressed_pubkey(dest) { + Some(pk) => pk, + None => { + println!("ERROR: couldn't parse destination pubkey"); + print!("> "); + io::stdout().flush().unwrap(); + continue; + } + }, + None => { + println!("ERROR: keysend requires a destination pubkey: `keysend `"); + print!("> "); + io::stdout().flush().unwrap(); + continue; + } + }; + let amt_msat_str = match words.next() { + Some(amt) => amt, + None => { + println!("ERROR: keysend requires an amount in millisatoshis: `keysend `"); + + print!("> "); + io::stdout().flush().unwrap(); + continue; + } + }; + let amt_msat: u64 = match amt_msat_str.parse() { + Ok(amt) => amt, + Err(e) => { + println!("ERROR: couldn't parse amount_msat: {}", e); + print!("> "); + io::stdout().flush().unwrap(); + continue; + } + }; + keysend( + dest_pubkey, + amt_msat, + router.clone(), + channel_manager.clone(), + outbound_payments.clone(), + logger.clone(), + ); + } "getinvoice" => { let amt_str = words.next(); if amt_str.is_none() { @@ -416,6 +467,11 @@ fn list_channels(channel_manager: Arc) { } println!("\t\tis_confirmed_onchain: {},", chan_info.is_funding_locked); println!("\t\tchannel_value_satoshis: {},", chan_info.channel_value_satoshis); + println!( + "\t\tlocal_balance_msat: {},", + chan_info.outbound_capacity_msat + + chan_info.unspendable_punishment_reserve.unwrap_or(0) * 1000 + ); if chan_info.is_usable { println!("\t\tavailable_balance_for_send_msat: {},", chan_info.outbound_capacity_msat); println!("\t\tavailable_balance_for_recv_msat: {},", chan_info.inbound_capacity_msat); @@ -580,6 +636,46 @@ fn send_payment( ); } +fn keysend( + payee: PublicKey, amt_msat: u64, + router: Arc, Arc>>, + channel_manager: Arc, payment_storage: PaymentInfoStorage, + logger: Arc, +) { + let network_graph = router.network_graph.read().unwrap(); + let first_hops = channel_manager.list_usable_channels(); + let payer_pubkey = channel_manager.get_our_node_id(); + + let route = match router::get_keysend_route( + &payer_pubkey, + &network_graph, + &payee, + Some(&first_hops.iter().collect::>()), + &vec![], + amt_msat, + 40, + logger, + ) { + Ok(r) => r, + Err(e) => { + println!("ERROR: failed to find route: {}", e.err); + return; + } + }; + + let mut payments = payment_storage.lock().unwrap(); + let payment_hash = channel_manager.send_spontaneous_payment(&route, None).unwrap(); + payments.insert( + payment_hash, + PaymentInfo { + preimage: None, + secret: None, + status: HTLCStatus::Pending, + amt_msat: MillisatAmount(Some(amt_msat)), + }, + ); +} + fn get_invoice( amt_msat: u64, payment_storage: PaymentInfoStorage, channel_manager: Arc, keys_manager: Arc, network: Network,