Unlock seed once at startup, pass identity to all commands
- main.rs unlocks seed once, prompts passphrase once per app launch - Identity passed as parameter to send, recv, register, chat - No more redundant load_seed() calls (was prompting passphrase multiple times) - info command uses pre-unlocked identity directly Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1 @@
|
|||||||
use crate::keystore;
|
// Info is now handled directly in main.rs with the pre-unlocked identity.
|
||||||
|
|
||||||
pub fn run() -> anyhow::Result<()> {
|
|
||||||
let seed = keystore::load_seed()?;
|
|
||||||
let identity = seed.derive_identity();
|
|
||||||
let pub_id = identity.public_identity();
|
|
||||||
|
|
||||||
println!("Fingerprint: {}", pub_id.fingerprint);
|
|
||||||
println!("Signing key: {}", hex::encode(pub_id.signing.as_bytes()));
|
|
||||||
println!(
|
|
||||||
"Encryption key: {}",
|
|
||||||
hex::encode(pub_id.encryption.as_bytes())
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -71,10 +71,11 @@ pub fn run() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register the local bundle with a server. Called automatically before first send.
|
/// Register the local bundle with a server using an already-unlocked identity.
|
||||||
pub async fn register_with_server(server_url: &str) -> Result<()> {
|
pub async fn register_with_server_identity(
|
||||||
let seed = keystore::load_seed()?;
|
server_url: &str,
|
||||||
let identity = seed.derive_identity();
|
identity: &warzone_protocol::identity::IdentityKeyPair,
|
||||||
|
) -> Result<()> {
|
||||||
let pub_id = identity.public_identity();
|
let pub_id = identity.public_identity();
|
||||||
let fp = pub_id.fingerprint.to_string();
|
let fp = pub_id.fingerprint.to_string();
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
use warzone_protocol::identity::IdentityKeyPair;
|
||||||
use warzone_protocol::ratchet::RatchetState;
|
use warzone_protocol::ratchet::RatchetState;
|
||||||
use warzone_protocol::types::Fingerprint;
|
use warzone_protocol::types::Fingerprint;
|
||||||
use warzone_protocol::x3dh;
|
use warzone_protocol::x3dh;
|
||||||
use x25519_dalek::PublicKey;
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
use crate::cli::send::WireMessage;
|
use crate::cli::send::WireMessage;
|
||||||
use crate::keystore;
|
|
||||||
use crate::net::ServerClient;
|
use crate::net::ServerClient;
|
||||||
use crate::storage::LocalDb;
|
use crate::storage::LocalDb;
|
||||||
|
|
||||||
pub async fn run(server_url: &str) -> Result<()> {
|
pub async fn run(server_url: &str, identity: &IdentityKeyPair) -> Result<()> {
|
||||||
let seed = keystore::load_seed()?;
|
|
||||||
let identity = seed.derive_identity();
|
|
||||||
let our_pub = identity.public_identity();
|
let our_pub = identity.public_identity();
|
||||||
let our_fp = our_pub.fingerprint.to_string();
|
let our_fp = our_pub.fingerprint.to_string();
|
||||||
let db = LocalDb::open()?;
|
let db = LocalDb::open()?;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
use warzone_protocol::identity::IdentityKeyPair;
|
||||||
use warzone_protocol::ratchet::{RatchetMessage, RatchetState};
|
use warzone_protocol::ratchet::{RatchetMessage, RatchetState};
|
||||||
use warzone_protocol::types::Fingerprint;
|
use warzone_protocol::types::Fingerprint;
|
||||||
use warzone_protocol::x3dh;
|
use warzone_protocol::x3dh;
|
||||||
use x25519_dalek::PublicKey;
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
use crate::keystore;
|
|
||||||
use crate::net::ServerClient;
|
use crate::net::ServerClient;
|
||||||
use crate::storage::LocalDb;
|
use crate::storage::LocalDb;
|
||||||
|
|
||||||
@@ -26,9 +26,7 @@ pub enum WireMessage {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(recipient_fp: &str, message: &str, server_url: &str) -> Result<()> {
|
pub async fn run(recipient_fp: &str, message: &str, server_url: &str, identity: &IdentityKeyPair) -> Result<()> {
|
||||||
let seed = keystore::load_seed()?;
|
|
||||||
let identity = seed.derive_identity();
|
|
||||||
let our_pub = identity.public_identity();
|
let our_pub = identity.public_identity();
|
||||||
let db = LocalDb::open()?;
|
let db = LocalDb::open()?;
|
||||||
let client = ServerClient::new(server_url);
|
let client = ServerClient::new(server_url);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ enum Commands {
|
|||||||
},
|
},
|
||||||
/// Send an encrypted message
|
/// Send an encrypted message
|
||||||
Send {
|
Send {
|
||||||
/// Recipient fingerprint (e.g. a3f8:c912:44be:7d01)
|
/// Recipient fingerprint (e.g. a3f8:c912:...) or @alias
|
||||||
recipient: String,
|
recipient: String,
|
||||||
/// Message text
|
/// Message text
|
||||||
message: String,
|
message: String,
|
||||||
@@ -49,7 +49,7 @@ enum Commands {
|
|||||||
},
|
},
|
||||||
/// Launch interactive TUI chat
|
/// Launch interactive TUI chat
|
||||||
Chat {
|
Chat {
|
||||||
/// Peer fingerprint to chat with (optional, can set with /peer in TUI)
|
/// Peer fingerprint or @alias (optional)
|
||||||
peer: Option<String>,
|
peer: Option<String>,
|
||||||
/// Server URL
|
/// Server URL
|
||||||
#[arg(short, long, default_value = "http://localhost:7700")]
|
#[arg(short, long, default_value = "http://localhost:7700")]
|
||||||
@@ -62,35 +62,42 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::Init => cli::init::run()?,
|
// These don't need an existing identity
|
||||||
Commands::Recover { words } => cli::recover::run(&words.join(" "))?,
|
Commands::Init => return cli::init::run(),
|
||||||
Commands::Info => cli::info::run()?,
|
Commands::Recover { words } => return cli::recover::run(&words.join(" ")),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All other commands need the seed — unlock once here
|
||||||
|
let seed = keystore::load_seed()?;
|
||||||
|
let identity = seed.derive_identity();
|
||||||
|
let our_fp = identity.public_identity().fingerprint.to_string();
|
||||||
|
|
||||||
|
match cli.command {
|
||||||
|
Commands::Init | Commands::Recover { .. } => unreachable!(),
|
||||||
|
Commands::Info => {
|
||||||
|
let pub_id = identity.public_identity();
|
||||||
|
println!("Fingerprint: {}", pub_id.fingerprint);
|
||||||
|
println!("Signing key: {}", hex::encode(pub_id.signing.as_bytes()));
|
||||||
|
println!("Encryption key: {}", hex::encode(pub_id.encryption.as_bytes()));
|
||||||
|
}
|
||||||
Commands::Register { server } => {
|
Commands::Register { server } => {
|
||||||
cli::init::register_with_server(&server).await?;
|
cli::init::register_with_server_identity(&server, &identity).await?;
|
||||||
}
|
}
|
||||||
Commands::Send {
|
Commands::Send {
|
||||||
recipient,
|
recipient,
|
||||||
message,
|
message,
|
||||||
server,
|
server,
|
||||||
} => {
|
} => {
|
||||||
// Auto-register bundle on first send
|
let _ = cli::init::register_with_server_identity(&server, &identity).await;
|
||||||
if let Err(_) = cli::init::register_with_server(&server).await {
|
cli::send::run(&recipient, &message, &server, &identity).await?;
|
||||||
eprintln!("Warning: failed to register bundle with server");
|
|
||||||
}
|
|
||||||
cli::send::run(&recipient, &message, &server).await?;
|
|
||||||
}
|
}
|
||||||
Commands::Recv { server } => {
|
Commands::Recv { server } => {
|
||||||
cli::recv::run(&server).await?;
|
cli::recv::run(&server, &identity).await?;
|
||||||
}
|
}
|
||||||
Commands::Chat { peer, server } => {
|
Commands::Chat { peer, server } => {
|
||||||
// Auto-register
|
let _ = cli::init::register_with_server_identity(&server, &identity).await;
|
||||||
let _ = cli::init::register_with_server(&server).await;
|
|
||||||
|
|
||||||
let seed = keystore::load_seed()?;
|
|
||||||
let identity = seed.derive_identity();
|
|
||||||
let our_fp = identity.public_identity().fingerprint.to_string();
|
|
||||||
let db = storage::LocalDb::open()?;
|
let db = storage::LocalDb::open()?;
|
||||||
|
|
||||||
tui::run_tui(our_fp, peer, server, identity, db).await?;
|
tui::run_tui(our_fp, peer, server, identity, db).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user