use std::io::BufRead; use bft_json_crdt::json_crdt::{BaseCrdt, SignedOp}; use cli::{parse_args, Commands}; use crdt::TransactionList; use node::SideNode; use tokio::{sync::mpsc, task}; use websocket::WebSocketClient; pub(crate) mod cli; pub(crate) mod crdt; pub(crate) mod init; pub(crate) mod keys; pub(crate) mod node; pub(crate) mod utils; pub(crate) mod websocket; #[tokio::main] async fn main() { let args = parse_args(); match &args.command { Some(Commands::Init { name }) => { let config = init::config::SideNodeConfig { name: name.to_string(), }; let _ = init::init(utils::home(name), config); } Some(Commands::Run { name }) => { let mut node = setup(name).await; node.start().await; } None => println!("No command provided. Exiting. See --help for more information."), } } /// Wire everything up outside the application so we can test more easily later async fn setup(name: &String) -> SideNode { let side_dir = utils::home(name); let keys = keys::load_from_file(side_dir); let (incoming_sender, incoming_receiver) = mpsc::channel::(32); let (stdin_sender, stdin_receiver) = std::sync::mpsc::channel(); task::spawn(async move { stdin_input(stdin_sender); }); let crdt = BaseCrdt::::new(&keys); let node = SideNode::new(crdt, keys, incoming_receiver, stdin_receiver); tokio::spawn(async move { WebSocketClient::start(incoming_sender).await; }); println!("Node setup complete."); node } /// Wait for stdin terminal input and send it to the node if any arrives fn stdin_input(stdin_sender: std::sync::mpsc::Sender) { let stdin = std::io::stdin(); let lines = stdin.lock().lines(); for line in lines { println!("We're in stdin_input"); let line = line.unwrap(); stdin_sender.send(line).unwrap(); } }