diff --git a/warzone/Cargo.lock b/warzone/Cargo.lock index 33791ac..3132676 100644 --- a/warzone/Cargo.lock +++ b/warzone/Cargo.lock @@ -2789,7 +2789,7 @@ dependencies = [ [[package]] name = "warzone-client" -version = "0.0.16" +version = "0.0.17" dependencies = [ "anyhow", "argon2", @@ -2822,7 +2822,7 @@ dependencies = [ [[package]] name = "warzone-mule" -version = "0.0.16" +version = "0.0.17" dependencies = [ "anyhow", "clap", @@ -2831,7 +2831,7 @@ dependencies = [ [[package]] name = "warzone-protocol" -version = "0.0.16" +version = "0.0.17" dependencies = [ "base64", "bincode", @@ -2856,7 +2856,7 @@ dependencies = [ [[package]] name = "warzone-server" -version = "0.0.16" +version = "0.0.17" dependencies = [ "anyhow", "axum", @@ -2883,7 +2883,7 @@ dependencies = [ [[package]] name = "warzone-wasm" -version = "0.0.16" +version = "0.0.17" dependencies = [ "base64", "bincode", diff --git a/warzone/Cargo.toml b/warzone/Cargo.toml index 59bfe70..d22c4bc 100644 --- a/warzone/Cargo.toml +++ b/warzone/Cargo.toml @@ -9,7 +9,7 @@ members = [ ] [workspace.package] -version = "0.0.16" +version = "0.0.17" edition = "2021" license = "MIT" rust-version = "1.75" diff --git a/warzone/crates/warzone-client/src/keystore.rs b/warzone/crates/warzone-client/src/keystore.rs index af2cefa..66043dd 100644 --- a/warzone/crates/warzone-client/src/keystore.rs +++ b/warzone/crates/warzone-client/src/keystore.rs @@ -125,6 +125,12 @@ pub fn save_seed(seed: &Seed) -> anyhow::Result<()> { Ok(()) } +/// Load raw seed bytes (for deriving eth address etc). +pub fn load_seed_raw() -> anyhow::Result<[u8; 32]> { + let seed = load_seed()?; + Ok(seed.0) +} + /// Load seed, decrypting if necessary. pub fn load_seed() -> anyhow::Result { let path = seed_path(); diff --git a/warzone/crates/warzone-client/src/tui/app.rs b/warzone/crates/warzone-client/src/tui/app.rs index 0684ac8..aeb0d0e 100644 --- a/warzone/crates/warzone-client/src/tui/app.rs +++ b/warzone/crates/warzone-client/src/tui/app.rs @@ -52,7 +52,7 @@ pub struct App { pub peer_fp: Option, pub server_url: String, pub should_quit: bool, - pub last_dm_peer: Option, + pub last_dm_peer: Arc>>, /// Track receipt status for messages we sent, keyed by message ID. pub receipts: Arc>>, /// Pending incoming file transfers, keyed by file ID. @@ -112,7 +112,7 @@ impl App { peer_fp, server_url, should_quit: false, - last_dm_peer: None, + last_dm_peer: Arc::new(Mutex::new(None)), receipts: Arc::new(Mutex::new(HashMap::new())), pending_files: Arc::new(Mutex::new(HashMap::new())), } @@ -285,9 +285,17 @@ impl App { } return; } + if text == "/eth" { + // Show ethereum address from seed + if let Ok(seed) = crate::keystore::load_seed_raw() { + let eth = warzone_protocol::ethereum::derive_eth_identity(&seed); + self.add_message(ChatLine { sender: "system".into(), text: format!("ETH: {}", eth.address.to_checksum()), is_system: true, is_self: false, message_id: None }); + } + return; + } if text == "/r" || text == "/reply" { - // Just switch to last DM peer - if let Some(ref peer) = self.last_dm_peer.clone() { + let last = self.last_dm_peer.lock().unwrap().clone(); + if let Some(ref peer) = last { self.peer_fp = Some(peer.clone()); self.add_message(ChatLine { sender: "system".into(), text: format!("→ switched to {}", &peer[..peer.len().min(16)]), is_system: true, is_self: false, message_id: None }); } else { @@ -1109,9 +1117,10 @@ fn process_incoming( pending_files: &Arc>>, our_fp: &str, client: &ServerClient, + last_dm_peer: &Arc>>, ) { match bincode::deserialize::(raw) { - Ok(wire) => process_wire_message(wire, identity, db, messages, receipts, pending_files, our_fp, client), + Ok(wire) => process_wire_message(wire, identity, db, messages, receipts, pending_files, our_fp, client, last_dm_peer), Err(_) => {} } } @@ -1125,6 +1134,7 @@ fn process_wire_message( pending_files: &Arc>>, our_fp: &str, client: &ServerClient, + last_dm_peer: &Arc>>, ) { match wire { WireMessage::KeyExchange { @@ -1161,6 +1171,7 @@ fn process_wire_message( Ok(plaintext) => { let text = String::from_utf8_lossy(&plaintext).to_string(); let _ = db.save_session(&sender_fp, &state); + *last_dm_peer.lock().unwrap() = Some(sender_fingerprint.clone()); messages.lock().unwrap().push(ChatLine { sender: sender_fingerprint[..sender_fingerprint.len().min(12)].to_string(), text, @@ -1168,7 +1179,6 @@ fn process_wire_message( is_self: false, message_id: None, }); - // Send delivery receipt send_receipt(our_fp, &sender_fingerprint, &id, ReceiptType::Delivered, client); } Err(_) => {} @@ -1191,6 +1201,7 @@ fn process_wire_message( Ok(plaintext) => { let text = String::from_utf8_lossy(&plaintext).to_string(); let _ = db.save_session(&sender_fp, &state); + *last_dm_peer.lock().unwrap() = Some(sender_fingerprint.clone()); messages.lock().unwrap().push(ChatLine { sender: sender_fingerprint[..sender_fingerprint.len().min(12)].to_string(), text, @@ -1414,6 +1425,7 @@ pub async fn poll_loop( identity: IdentityKeyPair, db: Arc, client: ServerClient, + last_dm_peer: Arc>>, ) { let fp = normfp(&our_fp); @@ -1439,7 +1451,7 @@ pub async fn poll_loop( while let Some(Ok(msg)) = read.next().await { if let tokio_tungstenite::tungstenite::Message::Binary(data) = msg { - process_incoming(&data, &identity, &db, &messages, &receipts, &pending_files, &our_fp, &client); + process_incoming(&data, &identity, &db, &messages, &receipts, &pending_files, &our_fp, &client, &last_dm_peer); } } @@ -1460,7 +1472,7 @@ pub async fn poll_loop( Err(_) => continue, }; for raw in &raw_msgs { - process_incoming(raw, &identity, &db, &messages, &receipts, &pending_files, &our_fp, &client); + process_incoming(raw, &identity, &db, &messages, &receipts, &pending_files, &our_fp, &client, &last_dm_peer); } } } @@ -1487,12 +1499,13 @@ pub async fn run_tui( let poll_messages = app.messages.clone(); let poll_receipts = app.receipts.clone(); let poll_pending_files = app.pending_files.clone(); + let poll_last_dm = app.last_dm_peer.clone(); let poll_client = client.clone(); let poll_db = db.clone(); let poll_fp = our_fp.clone(); tokio::spawn(async move { - poll_loop(poll_messages, poll_receipts, poll_pending_files, poll_fp, poll_identity, poll_db, poll_client).await; + poll_loop(poll_messages, poll_receipts, poll_pending_files, poll_fp, poll_identity, poll_db, poll_client, poll_last_dm).await; }); loop { diff --git a/warzone/crates/warzone-server/src/routes/web.rs b/warzone/crates/warzone-server/src/routes/web.rs index 3defa87..8f2894b 100644 --- a/warzone/crates/warzone-server/src/routes/web.rs +++ b/warzone/crates/warzone-server/src/routes/web.rs @@ -237,7 +237,7 @@ let pollTimer = null; let ws = null; // WebSocket connection let wasmReady = false; -const VERSION = '0.0.16'; +const VERSION = '0.0.17'; let DEBUG = true; // toggle with /debug command // ── Receipt tracking ──