c046d0cf6fe4771d0e7427b3c25c236a6ee112e5
[ldk-sample] / src / cli.rs
1 use bitcoin::secp256k1::key::PublicKey;
2 use crate::{FilesystemLogger, PeerManager, ChannelManager};
3 use crate::utils;
4 use std::io;
5 use std::io::{BufRead, Write};
6 use std::net::{SocketAddr, TcpStream};
7 use std::sync::Arc;
8 use std::thread;
9 use std::time::Duration;
10 // use tokio::runtime::Runtime;
11 use tokio::runtime::{Builder, Runtime};
12 use tokio::sync::mpsc;
13
14 pub fn poll_for_user_input(peer_manager: Arc<PeerManager>, channel_manager: Arc<ChannelManager>, event_notifier: mpsc::Sender<()>) {
15     println!("LDK startup successful. To view available commands: \"help\".\nLDK logs are available in the `logs` folder of the current directory.");
16     print!("> "); io::stdout().flush().unwrap(); // Without flushing, the `>` doesn't print
17     let stdin = io::stdin();
18     for line in stdin.lock().lines() {
19         let line = line.unwrap();
20         let mut words = line.split_whitespace();
21         if let Some(word) = words.next() {
22             match word {
23                 "help" => handle_help(),
24                 "openchannel" => {
25                     let peer_pubkey_and_ip_addr = words.next();
26                     let channel_value_sat = words.next();
27                     if peer_pubkey_and_ip_addr.is_none() || channel_value_sat.is_none() {
28                         println!("ERROR: openchannel takes 2 arguments: `openchannel pubkey@host:port channel_amt_satoshis`")
29                     } else {
30                         let peer_pubkey_and_ip_addr = peer_pubkey_and_ip_addr.unwrap();
31                         let channel_value_sat = channel_value_sat.unwrap();
32                         let mut pubkey_and_addr = peer_pubkey_and_ip_addr.split("@");
33                         let pubkey = pubkey_and_addr.next();
34                         let peer_addr_str = pubkey_and_addr.next();
35                         if peer_addr_str.is_none() || peer_addr_str.is_none() {
36                             println!("ERROR: incorrectly formatted peer info. Should be formatted as: `pubkey@host:port`");
37                         } else {
38                             let pubkey = pubkey.unwrap();
39                             let peer_addr_str = peer_addr_str.unwrap();
40                             let peer_addr_res: Result<SocketAddr, _> = peer_addr_str.parse();
41                             let chan_amt: Result<u64, _> = channel_value_sat.parse();
42                             if let Some(pk) = utils::hex_to_compressed_pubkey(pubkey) {
43                                 if let Ok(addr) = peer_addr_res {
44                                     if let Ok(amt) = chan_amt {
45                                         handle_open_channel(pk, addr, amt,
46                                                             peer_manager.clone(),
47                                                             channel_manager.clone(),
48                                                             event_notifier.clone());
49                                     } else {
50                                         println!("ERROR: channel amount must be a number");
51                                     }
52                                 } else {
53                                     println!("ERROR: couldn't parse
54                                     pubkey@host:port into a socket address");
55                                 }
56                             } else {
57                                 println!("ERROR: unable to parse given pubkey for node");
58                             }
59                         }
60                     }
61                 },
62                 _ => println!("hello")
63             }
64         }
65         print!("> "); io::stdout().flush().unwrap();
66
67     }
68 }
69
70 fn handle_help() {
71     println!("")
72 }
73
74 fn handle_open_channel(peer_pubkey: PublicKey, peer_socket: SocketAddr,
75                        channel_amt_sat: u64, peer_manager: Arc<PeerManager>,
76                        channel_manager: Arc<ChannelManager>, event_notifier:
77                        mpsc::Sender<()>)
78 {
79                 // let runtime = Runtime::new().expect("Unable to create a runtime").enable_all();
80                 let runtime = Builder::new_multi_thread()
81         .worker_threads(3)
82         .enable_all()
83         .build()
84         .unwrap();
85     match TcpStream::connect_timeout(&peer_socket, Duration::from_secs(10)) {
86         Ok(stream) => {
87             runtime.block_on(|| {
88                 lightning_net_tokio::setup_outbound(peer_manager,
89                                                     event_notifier,
90                                                     peer_pubkey,
91                                                     stream);
92             });
93             match channel_manager.create_channel(peer_pubkey, channel_amt_sat, 0, 0, None) {
94                 Ok(_) => println!("SUCCESS: channel created! Mine some blocks to open it."),
95                 Err(e) => println!("ERROR: failed to open channel: {:?}", e)
96             }
97         },
98         Err(e) => println!("ERROR: failed to connect to peer: {:?}", e)
99     }
100 }