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 println!("network {}", network);
44 println!("region {}", region);
45
46 let (base_url, secure) = match (network.as_str(), region.as_str()) {
47 ("LOCAL", _) => (LOCAL.to_string(), false),
48 ("TESTNET", _) => (TESTNET.to_string(), true),
49 ("MAINNET", "UK") => (MAINNET_UK.to_string(), true),
50 ("MAINNET", "NY") => (MAINNET_NY.to_string(), true),
51 ("MAINNET", "FRANKFURT") => (MAINNET_FRANKFURT.to_string(), true),
52 ("MAINNET", "LA") => (MAINNET_LA.to_string(), true),
53 ("MAINNET", "AMSTERDAM") => (MAINNET_AMSTERDAM.to_string(), true),
54 ("MAINNET", "TOKYO") => (MAINNET_TOKYO.to_string(), true),
55 ("MAINNET_PUMP", "NY") => (MAINNET_PUMP_NY.to_string(), true),
56 ("MAINNET_PUMP", "UK") => (MAINNET_PUMP_UK.to_string(), true),
57 _ => (MAINNET_NY.to_string(), false),
58 };
59
60 (base_url, secure)
61}
62
63pub struct BaseConfig {
64 pub auth_header: String,
65 pub keypair: Option<Keypair>,
66 pub public_key: Option<Pubkey>,
67}
68
69impl BaseConfig {
70 pub fn try_from_env() -> Result<Self> {
71 dotenv().ok();
72
73 let auth_header = env::var("AUTH_HEADER")
74 .map_err(|_| anyhow!("AUTH_HEADER environment variable not set"))?;
75
76 let public_key = env::var("PUBLIC_KEY").ok().and_then(|pk_str| {
77 Pubkey::from_str(&pk_str)
78 .map_err(|e| {
79 println!("Warning: Failed to parse public key: {}", e);
80 e
81 })
82 .ok()
83 });
84
85 let keypair = if let Ok(private_key) = env::var("PRIVATE_KEY") {
86 let mut output = [0; 64];
87 match decode(private_key).onto(&mut output) {
88 Ok(_) => match Keypair::from_bytes(&output) {
89 Ok(kp) => Some(kp),
90 Err(e) => {
91 println!("Warning: Failed to create keypair: {}", e);
92 None
93 }
94 },
95 Err(e) => {
96 println!("Warning: Failed to decode private key: {}", e);
97 None
98 }
99 }
100 } else {
101 None
102 };
103
104 Ok(Self {
105 keypair,
106 auth_header,
107 public_key,
108 })
109 }
110}