use anyhow::{Context, Result};
use crate::api::ApiClient;
use crate::config::{self, Credentials, NetworkConfig};
pub async fn login(network_name: &str) -> Result<()> {
let network = config::resolve_network(Some(network_name), None)?;
eprint!("Account ID: ");
let mut input = String::new();
std::io::stdin().read_line(&mut input)?;
let account_id = input.trim().to_string();
if account_id.is_empty() {
anyhow::bail!("Account ID is required");
}
eprint!("Private key (ed25519:...): ");
let mut input = String::new();
std::io::stdin().read_line(&mut input)?;
let secret_key = input.trim().to_string();
if secret_key.is_empty() {
anyhow::bail!("Private key is required");
}
let parsed: near_crypto::SecretKey = secret_key
.parse()
.context("Invalid private key format. Expected: ed25519:...")?;
let public_key = parsed.public_key().to_string();
let _use_keyring = config::save_private_key(&network.network_id, &account_id, &secret_key);
let creds = Credentials {
account_id: account_id.clone(),
public_key: public_key.clone(),
private_key: Some(secret_key),
contract_id: network.contract_id.clone(),
auth_type: "near_key".to_string(),
wallet_key: None,
};
config::save_credentials(&network, &creds)?;
config::save_default_network(&network.network_id);
eprintln!("Logged in as {account_id} ({network_name})");
eprintln!("Public key: {public_key}");
Ok(())
}
pub async fn login_wallet_key(network_name: &str, wallet_key: &str) -> Result<()> {
if !wallet_key.starts_with("wk_") {
anyhow::bail!("Invalid wallet key format. Expected: wk_...");
}
let network = config::resolve_network(Some(network_name), None)?;
let api = ApiClient::new(&network);
eprintln!("Authenticating with wallet key...");
let resp = api
.sign_message(wallet_key, "outlayer-cli-login", &network.contract_id, None)
.await
.context("Failed to authenticate wallet key. Check that the key is valid.")?;
let creds = Credentials {
account_id: resp.account_id.clone(),
public_key: resp.public_key.clone(),
private_key: None,
contract_id: network.contract_id.clone(),
auth_type: "wallet_key".to_string(),
wallet_key: Some(wallet_key.to_string()),
};
config::save_credentials(&network, &creds)?;
config::save_default_network(&network.network_id);
eprintln!("Logged in as {} ({network_name})", resp.account_id);
eprintln!("Public key: {}", resp.public_key);
eprintln!("Auth: wallet_key");
Ok(())
}
pub fn logout(network: &NetworkConfig) -> Result<()> {
config::delete_credentials(network)?;
eprintln!("Logged out from {}", network.network_id);
Ok(())
}
pub fn whoami(network: &NetworkConfig) -> Result<()> {
let creds = config::load_credentials(network)?;
println!("Account: {}", creds.account_id);
println!("Network: {}", network.network_id);
println!("Contract: {}", creds.contract_id);
println!("Key: {}", creds.public_key);
println!("Auth: {}", creds.auth_type);
Ok(())
}