X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fcli.rs;h=b392f0f355019a9b42cae0230afdc7b92c76af33;hb=479964a45b965cbdbd4a0ca8e43cbd307ddc989b;hp=6904180ddcc3d0e48f48787b00184aaaaec40f45;hpb=c0a722430b8fbcb30310d64487a32aae839da3e8;p=ldk-sample diff --git a/src/cli.rs b/src/cli.rs index 6904180..b392f0f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,17 +1,17 @@ use crate::disk; use crate::hex_utils; use crate::{ - ChannelManager, HTLCStatus, InvoicePayer, MillisatAmount, PaymentInfo, PaymentInfoStorage, - PeerManager, + ChannelManager, HTLCStatus, InvoicePayer, MillisatAmount, NetworkGraph, PaymentInfo, + PaymentInfoStorage, PeerManager, }; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; use bitcoin::network::constants::Network; -use bitcoin::secp256k1::key::PublicKey; +use bitcoin::secp256k1::PublicKey; use lightning::chain::keysinterface::{KeysInterface, KeysManager, Recipient}; use lightning::ln::msgs::NetAddress; use lightning::ln::{PaymentHash, PaymentPreimage}; -use lightning::routing::network_graph::{NetworkGraph, NodeId}; +use lightning::routing::gossip::NodeId; use lightning::util::config::{ChannelConfig, ChannelHandshakeLimits, UserConfig}; use lightning::util::events::EventHandler; use lightning_invoice::payment::PaymentError; @@ -281,12 +281,26 @@ pub(crate) async fn poll_for_user_input( println!("ERROR: getinvoice provided payment amount was not a number"); continue; } + + let expiry_secs_str = words.next(); + if expiry_secs_str.is_none() { + println!("ERROR: getinvoice requires an expiry in seconds"); + continue; + } + + let expiry_secs: Result = expiry_secs_str.unwrap().parse(); + if expiry_secs.is_err() { + println!("ERROR: getinvoice provided expiry was not a number"); + continue; + } + get_invoice( amt_msat.unwrap(), inbound_payments.clone(), channel_manager.clone(), keys_manager.clone(), network, + expiry_secs.unwrap(), ); } "connectpeer" => { @@ -317,7 +331,7 @@ pub(crate) async fn poll_for_user_input( "closechannel" => { let channel_id_str = words.next(); if channel_id_str.is_none() { - println!("ERROR: closechannel requires a channel ID: `closechannel `"); + println!("ERROR: closechannel requires a channel ID: `closechannel `"); continue; } let channel_id_vec = hex_utils::to_vec(channel_id_str.unwrap()); @@ -327,12 +341,33 @@ pub(crate) async fn poll_for_user_input( } let mut channel_id = [0; 32]; channel_id.copy_from_slice(&channel_id_vec.unwrap()); - close_channel(channel_id, channel_manager.clone()); + + let peer_pubkey_str = words.next(); + if peer_pubkey_str.is_none() { + println!("ERROR: closechannel requires a peer pubkey: `closechannel `"); + continue; + } + let peer_pubkey_vec = match hex_utils::to_vec(peer_pubkey_str.unwrap()) { + Some(peer_pubkey_vec) => peer_pubkey_vec, + None => { + println!("ERROR: couldn't parse peer_pubkey"); + continue; + } + }; + let peer_pubkey = match PublicKey::from_slice(&peer_pubkey_vec) { + Ok(peer_pubkey) => peer_pubkey, + Err(_) => { + println!("ERROR: couldn't parse peer_pubkey"); + continue; + } + }; + + close_channel(channel_id, peer_pubkey, channel_manager.clone()); } "forceclosechannel" => { let channel_id_str = words.next(); if channel_id_str.is_none() { - println!("ERROR: forceclosechannel requires a channel ID: `forceclosechannel `"); + println!("ERROR: forceclosechannel requires a channel ID: `forceclosechannel `"); continue; } let channel_id_vec = hex_utils::to_vec(channel_id_str.unwrap()); @@ -342,7 +377,28 @@ pub(crate) async fn poll_for_user_input( } let mut channel_id = [0; 32]; channel_id.copy_from_slice(&channel_id_vec.unwrap()); - force_close_channel(channel_id, channel_manager.clone()); + + let peer_pubkey_str = words.next(); + if peer_pubkey_str.is_none() { + println!("ERROR: forceclosechannel requires a peer pubkey: `forceclosechannel `"); + continue; + } + let peer_pubkey_vec = match hex_utils::to_vec(peer_pubkey_str.unwrap()) { + Some(peer_pubkey_vec) => peer_pubkey_vec, + None => { + println!("ERROR: couldn't parse peer_pubkey"); + continue; + } + }; + let peer_pubkey = match PublicKey::from_slice(&peer_pubkey_vec) { + Ok(peer_pubkey) => peer_pubkey, + Err(_) => { + println!("ERROR: couldn't parse peer_pubkey"); + continue; + } + }; + + force_close_channel(channel_id, peer_pubkey, channel_manager.clone()); } "nodeinfo" => node_info(&channel_manager, &peer_manager), "listpeers" => list_peers(peer_manager.clone()), @@ -369,13 +425,13 @@ pub(crate) async fn poll_for_user_input( fn help() { println!("openchannel pubkey@host:port "); println!("sendpayment "); - println!("keysend "); - println!("getinvoice "); + println!("keysend "); + println!("getinvoice "); println!("connectpeer pubkey@host:port"); println!("listchannels"); println!("listpayments"); - println!("closechannel "); - println!("forceclosechannel "); + println!("closechannel "); + println!("forceclosechannel "); println!("nodeinfo"); println!("listpeers"); println!("signmessage "); @@ -441,7 +497,7 @@ fn list_channels(channel_manager: &Arc, network_graph: &Arc( fn get_invoice( amt_msat: u64, payment_storage: PaymentInfoStorage, channel_manager: Arc, - keys_manager: Arc, network: Network, + keys_manager: Arc, network: Network, expiry_secs: u32, ) { let mut payments = payment_storage.lock().unwrap(); let currency = match network { @@ -668,6 +724,7 @@ fn get_invoice( currency, Some(amt_msat), "ldk-tutorial-node".to_string(), + expiry_secs, ) { Ok(inv) => { println!("SUCCESS: generated invoice: {}", inv); @@ -691,15 +748,19 @@ fn get_invoice( ); } -fn close_channel(channel_id: [u8; 32], channel_manager: Arc) { - match channel_manager.close_channel(&channel_id) { +fn close_channel( + channel_id: [u8; 32], counterparty_node_id: PublicKey, channel_manager: Arc, +) { + match channel_manager.close_channel(&channel_id, &counterparty_node_id) { Ok(()) => println!("EVENT: initiating channel close"), Err(e) => println!("ERROR: failed to close channel: {:?}", e), } } -fn force_close_channel(channel_id: [u8; 32], channel_manager: Arc) { - match channel_manager.force_close_channel(&channel_id) { +fn force_close_channel( + channel_id: [u8; 32], counterparty_node_id: PublicKey, channel_manager: Arc, +) { + match channel_manager.force_close_channel(&channel_id, &counterparty_node_id) { Ok(()) => println!("EVENT: initiating channel force-close"), Err(e) => println!("ERROR: failed to force-close channel: {:?}", e), }