solana_trader_client_rust/common/
mod.rs1pub 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}