X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fcli.rs;h=7d865158e6e7e786a93b52ff99a513d766f50b08;hb=8984205acf1d328837d0f33798e89e479aea1882;hp=bf2f7929434de90f1fe9d9fd5f9f7fe9fb59a8df;hpb=1c40f4960a63501e28fb7cb77b9d294d357395b3;p=ldk-sample diff --git a/src/cli.rs b/src/cli.rs index bf2f792..7d86515 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,8 +1,8 @@ use crate::disk; use crate::hex_utils; use crate::{ - ChannelManager, HTLCStatus, InvoicePayer, MillisatAmount, NetworkGraph, NodeAlias, PaymentInfo, - PaymentInfoStorage, PeerManager, + ChannelManager, HTLCStatus, InvoicePayer, MillisatAmount, NetworkGraph, OnionMessenger, + PaymentInfo, PaymentInfoStorage, PeerManager, }; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; @@ -11,14 +11,15 @@ use bitcoin::secp256k1::PublicKey; use lightning::chain::keysinterface::{KeysInterface, KeysManager, Recipient}; use lightning::ln::msgs::NetAddress; use lightning::ln::{PaymentHash, PaymentPreimage}; +use lightning::onion_message::Destination; use lightning::routing::gossip::NodeId; -use lightning::util::config::{ChannelConfig, ChannelHandshakeLimits, UserConfig}; +use lightning::util::config::{ChannelHandshakeConfig, ChannelHandshakeLimits, UserConfig}; use lightning::util::events::EventHandler; use lightning_invoice::payment::PaymentError; use lightning_invoice::{utils, Currency, Invoice}; use std::env; use std::io; -use std::io::{BufRead, Write}; +use std::io::Write; use std::net::{IpAddr, SocketAddr, ToSocketAddrs}; use std::ops::Deref; use std::path::Path; @@ -142,21 +143,21 @@ pub(crate) fn parse_startup_args() -> Result { pub(crate) async fn poll_for_user_input( invoice_payer: Arc>, peer_manager: Arc, channel_manager: Arc, keys_manager: Arc, - network_graph: Arc, inbound_payments: PaymentInfoStorage, - outbound_payments: PaymentInfoStorage, ldk_data_dir: String, network: Network, + network_graph: Arc, onion_messenger: Arc, + inbound_payments: PaymentInfoStorage, outbound_payments: PaymentInfoStorage, + ldk_data_dir: String, network: Network, ) { println!("LDK startup successful. To view available commands: \"help\"."); println!("LDK logs are available at /.ldk/logs"); println!("Local Node ID is {}.", channel_manager.get_our_node_id()); - let stdin = io::stdin(); - let mut line_reader = stdin.lock().lines(); loop { print!("> "); io::stdout().flush().unwrap(); // Without flushing, the `>` doesn't print - let line = match line_reader.next() { - Some(l) => l.unwrap(), - None => break, - }; + let mut line = String::new(); + if let Err(e) = io::stdin().read_line(&mut line) { + break println!("ERROR: {e:#}"); + } + let mut words = line.split_whitespace(); if let Some(word) = words.next() { match word { @@ -416,6 +417,48 @@ pub(crate) async fn poll_for_user_input( ) ); } + "sendonionmessage" => { + let path_pks_str = words.next(); + if path_pks_str.is_none() { + println!( + "ERROR: sendonionmessage requires at least one node id for the path" + ); + continue; + } + let mut node_pks = Vec::new(); + let mut errored = false; + for pk_str in path_pks_str.unwrap().split(",") { + let node_pubkey_vec = match hex_utils::to_vec(pk_str) { + Some(peer_pubkey_vec) => peer_pubkey_vec, + None => { + println!("ERROR: couldn't parse peer_pubkey"); + errored = true; + break; + } + }; + let node_pubkey = match PublicKey::from_slice(&node_pubkey_vec) { + Ok(peer_pubkey) => peer_pubkey, + Err(_) => { + println!("ERROR: couldn't parse peer_pubkey"); + errored = true; + break; + } + }; + node_pks.push(node_pubkey); + } + if errored { + continue; + } + let destination_pk = node_pks.pop().unwrap(); + match onion_messenger.send_onion_message( + &node_pks, + Destination::Node(destination_pk), + None, + ) { + Ok(()) => println!("SUCCESS: forwarded onion message to first hop"), + Err(e) => println!("ERROR: failed to send onion message: {:?}", e), + } + } _ => println!("Unknown command. See `\"help\" for available commands."), } } @@ -423,7 +466,7 @@ pub(crate) async fn poll_for_user_input( } fn help() { - println!("openchannel pubkey@host:port "); + println!("openchannel pubkey@host:port [--public]"); println!("sendpayment "); println!("keysend "); println!("getinvoice "); @@ -435,6 +478,7 @@ fn help() { println!("nodeinfo"); println!("listpeers"); println!("signmessage "); + println!("sendonionmessage "); } fn node_info(channel_manager: &Arc, peer_manager: &Arc) { @@ -477,7 +521,7 @@ fn list_channels(channel_manager: &Arc, network_graph: &Arc, ) -> Result<(), ()> { let config = UserConfig { - peer_channel_config_limits: ChannelHandshakeLimits { + channel_handshake_limits: ChannelHandshakeLimits { // lnd's max to_self_delay is 2016, so we want to be compatible. their_to_self_delay: 2016, ..Default::default() }, - channel_options: ChannelConfig { announced_channel, ..Default::default() }, + channel_handshake_config: ChannelHandshakeConfig { + announced_channel, + ..Default::default() + }, ..Default::default() }; @@ -747,7 +794,7 @@ fn close_channel( 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) { + match channel_manager.force_close_broadcasting_latest_txn(&channel_id, &counterparty_node_id) { Ok(()) => println!("EVENT: initiating channel force-close"), Err(e) => println!("ERROR: failed to force-close channel: {:?}", e), } @@ -759,7 +806,7 @@ pub(crate) fn parse_peer_info( let mut pubkey_and_addr = peer_pubkey_and_ip_addr.split("@"); let pubkey = pubkey_and_addr.next(); let peer_addr_str = pubkey_and_addr.next(); - if peer_addr_str.is_none() || peer_addr_str.is_none() { + if peer_addr_str.is_none() { return Err(std::io::Error::new( std::io::ErrorKind::Other, "ERROR: incorrectly formatted peer info. Should be formatted as: `pubkey@host:port`",