Skip to main content

solana_trader/
lib.rs

1pub mod account;
2pub mod dex;
3pub mod global;
4pub mod message;
5pub mod price;
6pub mod scan;
7pub mod tool;
8pub mod trade;
9pub mod types;
10pub mod wallet;
11
12use solana_client::{
13    nonblocking::rpc_client::RpcClient, rpc_client::GetConfirmedSignaturesForAddress2Config,
14};
15use solana_sdk::{epoch_info::EpochInfo, native_token::LAMPORTS_PER_SOL, pubkey::Pubkey};
16use std::{str::FromStr, sync::Arc};
17
18use crate::{
19    account::Account,
20    dex::raydium::{v2::RaydiumV2, v3::RaydiumV3},
21    global::{
22        SOLANA_ANKR_MAIN_NET_URL, SOLANA_DEV_NET_URL, SOLANA_OFFICIAL_MAIN_NET_URL,
23        SOLANA_SERUM_MAIN_NET_URL, SOLANA_TEST_NET_URL,
24    },
25    trade::Trade,
26    types::Mode,
27    wallet::Wallet,
28};
29
30/// solana client Abstraction
31pub struct Solana {
32    mode: Mode,
33    pub client: Option<Arc<RpcClient>>,
34}
35
36impl Solana {
37    /// create solana object
38    pub fn new(mode: Mode) -> Result<Solana, String> {
39        let mut url = String::new();
40        match mode {
41            Mode::MAIN => {
42                url = SOLANA_OFFICIAL_MAIN_NET_URL.to_string();
43            }
44            Mode::TEST => {
45                url = SOLANA_TEST_NET_URL.to_string();
46            }
47            Mode::DEV => {
48                url = SOLANA_DEV_NET_URL.to_string();
49            }
50            _ => {
51                return Err("create solana client mode does not meet requirements".to_string());
52            }
53        }
54        let client = RpcClient::new(url.clone());
55        Ok(Self {
56            mode,
57            client: Some(Arc::new(client)),
58        })
59    }
60    /// get client arc
61    /// Example
62    /// ```rust
63    /// let s = Solana::new(Mode::TEST);
64    /// let client = s.client_arc().await;
65    /// ```
66    pub fn client_arc(&self) -> Arc<RpcClient> {
67        Arc::clone(&self.client.as_ref().unwrap())
68    }
69    /// get solana core version
70    /// Example
71    /// ```rust
72    /// let s = Solana::new(Mode::TEST);
73    /// let client = s.core_version().await;
74    /// ```
75    pub async fn core_version(&self) -> Result<String, String> {
76        match self.client_arc().get_version().await {
77            Ok(version) => {
78                return Ok(version.solana_core);
79            }
80            Err(e) => {
81                return Err(format!("get core version error: {:?}", e));
82            }
83        }
84    }
85    /// get feature set
86    /// Example
87    /// ```rust
88    /// let s = Solana::new(Mode::TEST);
89    /// let client = s.feature_set().await;
90    /// ```
91    pub async fn feature_set(&self) -> Result<String, String> {
92        match self.client_arc().get_version().await {
93            Ok(version) => {
94                return Ok(version.feature_set.unwrap().to_string());
95            }
96            Err(e) => {
97                return Err(format!("get core version error: {:?}", e));
98            }
99        }
100    }
101    /// get block height
102    /// Example
103    /// ```rust
104    /// let s = Solana::new(Mode::TEST);
105    /// let client = s.block_height().await;
106    /// ```
107    pub async fn block_height(&self) -> Result<u64, String> {
108        match self.client_arc().get_block_height().await {
109            Ok(h) => {
110                return Ok(h);
111            }
112            Err(e) => {
113                return Err(format!("get core version error: {:?}", e));
114            }
115        }
116    }
117    /// last block hash
118    /// Example
119    /// ```rust
120    /// let s = Solana::new(Mode::TEST);
121    /// let client = s.last_block_hash().await;
122    /// ```
123    pub async fn last_block_hash(&self) -> Result<String, String> {
124        match self.client_arc().get_latest_blockhash().await {
125            Ok(h) => {
126                return Ok(h.to_string());
127            }
128            Err(e) => {
129                return Err(format!("get core version error: {:?}", e));
130            }
131        }
132    }
133    /// get current slot
134    /// Example
135    /// ```rust
136    /// let s = Solana::new(Mode::TEST);
137    /// let client = s.slot().await;
138    /// ```
139    pub async fn slot(&self) -> Result<u64, String> {
140        match self.client_arc().get_slot().await {
141            Ok(slot) => {
142                return Ok(slot);
143            }
144            Err(e) => {
145                return Err(format!("get core version error: {:?}", e));
146            }
147        }
148    }
149    /// get current epoch info
150    /// Example
151    /// ```rust
152    /// let s = Solana::new(Mode::TEST);
153    /// let client = s.epoch().await;
154    /// ```
155    pub async fn epoch(&self) -> Result<EpochInfo, String> {
156        match self.client_arc().get_epoch_info().await {
157            Ok(epoch) => {
158                return Ok(epoch);
159            }
160            Err(e) => {
161                return Err(format!("get core version error: {:?}", e));
162            }
163        }
164    }
165    /// get account
166    /// # Returns
167    /// * 0 solana balance
168    /// * 1 solana lamports balance
169    pub async fn get_account_balance(&self, public_key: &str) -> Result<(f64, u64), f64> {
170        match Pubkey::from_str(&public_key) {
171            Ok(pubkey) => match self.client_arc().get_balance(&pubkey).await {
172                Ok(balance) => {
173                    return Ok((balance as f64 / LAMPORTS_PER_SOL as f64, balance));
174                }
175                Err(_) => return Err(0.0),
176            },
177            Err(_) => return Err(0.0),
178        }
179    }
180    /// create account
181    pub fn create_account(&self) -> Account {
182        Account::new(self.client_arc())
183    }
184    /// create trade
185    pub fn create_trade(&self) -> Trade {
186        Trade::new(self.client_arc())
187    }
188    /// create raydium
189    pub fn create_raydium_v2(&self) -> RaydiumV2 {
190        RaydiumV2::new(self.client_arc())
191    }
192    pub fn create_raydium_v3(&self) -> RaydiumV3 {
193        RaydiumV3::new(self.client_arc())
194    }
195}