outlayer_cli/commands/
auth.rs1use anyhow::{Context, Result};
2
3use crate::api::ApiClient;
4use crate::config::{self, Credentials, NetworkConfig};
5
6pub async fn login(network_name: &str) -> Result<()> {
8 let network = config::resolve_network(Some(network_name), None)?;
9
10 eprint!("Account ID: ");
12 let mut input = String::new();
13 std::io::stdin().read_line(&mut input)?;
14 let account_id = input.trim().to_string();
15 if account_id.is_empty() {
16 anyhow::bail!("Account ID is required");
17 }
18
19 eprint!("Private key (ed25519:...): ");
21 let mut input = String::new();
22 std::io::stdin().read_line(&mut input)?;
23 let secret_key = input.trim().to_string();
24 if secret_key.is_empty() {
25 anyhow::bail!("Private key is required");
26 }
27
28 let parsed: near_crypto::SecretKey = secret_key
30 .parse()
31 .context("Invalid private key format. Expected: ed25519:...")?;
32 let public_key = parsed.public_key().to_string();
33
34 let _use_keyring = config::save_private_key(&network.network_id, &account_id, &secret_key);
36
37 let creds = Credentials {
38 account_id: account_id.clone(),
39 public_key: public_key.clone(),
40 private_key: Some(secret_key),
41 contract_id: network.contract_id.clone(),
42 auth_type: "near_key".to_string(),
43 wallet_key: None,
44 };
45
46 config::save_credentials(&network, &creds)?;
47 config::save_default_network(&network.network_id);
48
49 eprintln!("Logged in as {account_id} ({network_name})");
50 eprintln!("Public key: {public_key}");
51
52 Ok(())
53}
54
55pub async fn login_wallet_key(network_name: &str, wallet_key: &str) -> Result<()> {
57 if !wallet_key.starts_with("wk_") {
58 anyhow::bail!("Invalid wallet key format. Expected: wk_...");
59 }
60
61 let network = config::resolve_network(Some(network_name), None)?;
62 let api = ApiClient::new(&network);
63
64 eprintln!("Authenticating with wallet key...");
65
66 let resp = api
68 .sign_message(wallet_key, "outlayer-cli-login", &network.contract_id, None)
69 .await
70 .context("Failed to authenticate wallet key. Check that the key is valid.")?;
71
72 let creds = Credentials {
73 account_id: resp.account_id.clone(),
74 public_key: resp.public_key.clone(),
75 private_key: None,
76 contract_id: network.contract_id.clone(),
77 auth_type: "wallet_key".to_string(),
78 wallet_key: Some(wallet_key.to_string()),
79 };
80
81 config::save_credentials(&network, &creds)?;
82 config::save_default_network(&network.network_id);
83
84 eprintln!("Logged in as {} ({network_name})", resp.account_id);
85 eprintln!("Public key: {}", resp.public_key);
86 eprintln!("Auth: wallet_key");
87
88 Ok(())
89}
90
91pub fn logout(network: &NetworkConfig) -> Result<()> {
93 config::delete_credentials(network)?;
94 eprintln!("Logged out from {}", network.network_id);
95 Ok(())
96}
97
98pub fn whoami(network: &NetworkConfig) -> Result<()> {
100 let creds = config::load_credentials(network)?;
101 println!("Account: {}", creds.account_id);
102 println!("Network: {}", network.network_id);
103 println!("Contract: {}", creds.contract_id);
104 println!("Key: {}", creds.public_key);
105 println!("Auth: {}", creds.auth_type);
106 Ok(())
107}