Skip to main content

stynx_code_auth/application/
resolve_credential.rs

1use stynx_code_errors::{AppError, AppResult};
2
3use crate::domain::Credential;
4use crate::infrastructure::{resolve_file_oauth, resolve_keychain_oauth, resolve_settings_json};
5
6pub fn resolve_credential() -> AppResult<Credential> {
7    if let Ok(key) = std::env::var("ANTHROPIC_API_KEY") {
8        tracing::info!("using Anthropic API key");
9        return Ok(Credential::ApiKey {
10            api_key: key,
11            base_url: "https://api.anthropic.com".to_string(),
12        });
13    }
14
15    match resolve_keychain_oauth() {
16        Ok(cred) => {
17            tracing::info!("using Claude Code OAuth from macOS Keychain");
18            return Ok(cred);
19        }
20        Err(e) => {
21            tracing::debug!("keychain OAuth not available: {e}");
22        }
23    }
24
25    match resolve_file_oauth() {
26        Ok(cred) => {
27            tracing::info!("using Claude Code OAuth from credentials file");
28            return Ok(cred);
29        }
30        Err(e) => {
31            tracing::debug!("file OAuth not available: {e}");
32        }
33    }
34
35    match resolve_settings_json() {
36        Ok(cred) => {
37            tracing::info!("using Claude Code auth from settings.json");
38            return Ok(cred);
39        }
40        Err(e) => {
41            tracing::debug!("settings.json not available: {e}");
42        }
43    }
44
45    if let Ok(key) = std::env::var("OPENROUTER_API_KEY") {
46        tracing::info!("using OpenRouter");
47        return Ok(Credential::ApiKey {
48            api_key: key,
49            base_url: "https://openrouter.ai/api".to_string(),
50        });
51    }
52
53    Err(AppError::Provider(
54        "no credentials found. Set ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN (from settings.json), OPENROUTER_API_KEY, or log in with `claude`"
55            .to_string(),
56    ))
57}