solana_trader_client_rust/common/
mod.rs

1pub mod constants;
2pub mod signing;
3
4use std::{env, str::FromStr};
5
6use anyhow::{anyhow, Result};
7use constants::{
8    LOCAL, MAINNET_AMSTERDAM, MAINNET_FRANKFURT, MAINNET_LA, MAINNET_NY, MAINNET_PUMP_NY,
9    MAINNET_PUMP_UK, MAINNET_TOKYO, MAINNET_UK, TESTNET,
10};
11use dotenv::dotenv;
12use solana_sdk::{bs58::decode, pubkey::Pubkey, signature::Keypair};
13
14pub fn http_endpoint(base_url: &str, secure: bool) -> String {
15    let prefix = if secure { "https" } else { "http" };
16    format!("{}://{}", prefix, base_url)
17}
18
19pub fn ws_endpoint(base_url: &str, secure: bool) -> String {
20    let prefix = if secure { "wss" } else { "ws" };
21    format!("{}://{}/ws", prefix, base_url)
22}
23
24pub fn grpc_endpoint(base_url: &str, secure: bool) -> String {
25    let prefix = if secure { "https" } else { "http" };
26    let port = if secure { ":443" } else { "" };
27    format!("{}://{}{}", prefix, base_url, port)
28}
29
30pub fn is_submit_only_endpoint(endpoint: &str) -> bool {
31    matches!(
32        endpoint,
33        MAINNET_FRANKFURT | MAINNET_LA | MAINNET_AMSTERDAM | MAINNET_TOKYO
34    ) && {
35        println!("\x1b[93m⚠️  WARNING\x1b[0m: Endpoint \x1b[96m{}\x1b[0m only supports transaction submission. Quotes, streams and other services are \x1b[91mnot available\x1b[0m.", endpoint);
36        true
37    }
38}
39
40pub fn get_base_url_from_env() -> (String, bool) {
41    let network = std::env::var("NETWORK").unwrap_or_else(|_| "mainnet".to_string());
42    let region = std::env::var("REGION").unwrap_or_else(|_| "NY".to_string());
43    let secure_env = std::env::var("SECURE")
44        .unwrap_or_else(|_| "false".to_string())
45        .to_lowercase();
46    let secure = matches!(secure_env.as_str(), "true" | "1" | "yes");
47
48    println!("network {}", network);
49    println!("region {}", region);
50    println!("secure {}", secure);
51
52    let base_url = match (network.as_str(), region.as_str()) {
53        ("LOCAL", _) => LOCAL.to_string(),
54        ("TESTNET", _) => TESTNET.to_string(),
55        ("MAINNET", "UK") => MAINNET_UK.to_string(),
56        ("MAINNET", "NY") => MAINNET_NY.to_string(),
57        ("MAINNET", "FRANKFURT") => MAINNET_FRANKFURT.to_string(),
58        ("MAINNET", "LA") => MAINNET_LA.to_string(),
59        ("MAINNET", "AMSTERDAM") => MAINNET_AMSTERDAM.to_string(),
60        ("MAINNET", "TOKYO") => MAINNET_TOKYO.to_string(),
61        ("MAINNET_PUMP", "NY") => MAINNET_PUMP_NY.to_string(),
62        ("MAINNET_PUMP", "UK") => MAINNET_PUMP_UK.to_string(),
63        _ => MAINNET_NY.to_string(),
64    };
65
66    (base_url, secure)
67}
68
69pub struct BaseConfig {
70    pub auth_header: String,
71    pub keypair: Option<Keypair>,
72    pub public_key: Option<Pubkey>,
73}
74
75impl BaseConfig {
76    pub fn try_from_env() -> Result<Self> {
77        dotenv().ok();
78
79        let auth_header = env::var("AUTH_HEADER")
80            .map_err(|_| anyhow!("AUTH_HEADER environment variable not set"))?;
81
82        let public_key = env::var("PUBLIC_KEY").ok().and_then(|pk_str| {
83            Pubkey::from_str(&pk_str)
84                .map_err(|e| {
85                    println!("Warning: Failed to parse public key: {}", e);
86                    e
87                })
88                .ok()
89        });
90
91        let keypair = if let Ok(private_key) = env::var("PRIVATE_KEY") {
92            let mut output = [0; 64];
93            match decode(private_key).onto(&mut output) {
94                Ok(_) => match Keypair::try_from(&output[..]) {
95                    Ok(kp) => Some(kp),
96                    Err(e) => {
97                        println!("Warning: Failed to create keypair: {}", e);
98                        None
99                    }
100                },
101                Err(e) => {
102                    println!("Warning: Failed to decode private key: {}", e);
103                    None
104                }
105            }
106        } else {
107            None
108        };
109
110        Ok(Self {
111            keypair,
112            auth_header,
113            public_key,
114        })
115    }
116}