solagent_plugin_birdeye/
lib.rs1use anyhow::Result;
2use solagent_core::{IWallet, SolanaAgentKit};
3
4mod primitive;
5pub use primitive::*;
6
7pub async fn get_token_overview<W: IWallet>(agent: &SolanaAgentKit<W>, address: &str) -> Result<TokenOverviewResponse> {
19 let api_key = agent
20 .config
21 .birdeye_api_key
22 .as_ref()
23 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
24
25 let client = reqwest::Client::new();
26 let url = format!("{}/defi/token_overview", BIRDEYE_URL);
27
28 let resp = client
29 .get(url)
30 .query(&[("address", address)])
31 .header("X-API-KEY", api_key)
32 .header("accept", "application/json")
33 .header("x-chain", "solana")
34 .send()
35 .await?
36 .json::<TokenOverviewResponse>()
37 .await?;
38
39 Ok(resp)
40}
41
42pub async fn get_market_data<W: IWallet>(agent: &SolanaAgentKit<W>, address: &str) -> Result<MarketDataResponse> {
54 let api_key = agent
55 .config
56 .birdeye_api_key
57 .as_ref()
58 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
59
60 let client = reqwest::Client::new();
61 let url = format!("{}/defi/v3/token/market-data", BIRDEYE_URL);
62
63 let resp = client
64 .get(url)
65 .query(&[("address", address)])
66 .header("X-API-KEY", api_key)
67 .header("accept", "application/json")
68 .header("x-chain", "solana")
69 .send()
70 .await?
71 .json::<MarketDataResponse>()
72 .await?;
73
74 Ok(resp)
75}
76
77pub async fn get_wallet_portfolio<W: IWallet>(
89 agent: &SolanaAgentKit<W>,
90 wallet_address: &str,
91) -> Result<WalletPortfolioResponse> {
92 let api_key = agent
93 .config
94 .birdeye_api_key
95 .as_ref()
96 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
97
98 let client = reqwest::Client::new();
99 let url = format!("{}/v1/wallet/token_list", BIRDEYE_URL);
100
101 let response = client
102 .get(&url)
103 .query(&[("wallet", wallet_address)])
104 .header("accept", "application/json")
105 .header("X-API-KEY", api_key)
106 .header("x-chain", "solana")
107 .send()
108 .await?
109 .json::<WalletPortfolioResponse>()
110 .await?;
111
112 Ok(response)
113}
114
115pub async fn get_token_holders<W: IWallet>(
127 agent: &SolanaAgentKit<W>,
128 query_params: TokenHolderQueryParams,
129) -> Result<TokenHolderResponse> {
130 let api_key = agent
131 .config
132 .birdeye_api_key
133 .as_ref()
134 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
135
136 let client = reqwest::Client::new();
137 let url = format!("{}/defi/v3/token/holder", BIRDEYE_URL);
138
139 let address = query_params.address;
140 let offset = query_params.offset.unwrap_or(0);
141 let limit = query_params.limit.unwrap_or(100);
142
143 let resp = client
144 .get(url)
145 .query(&[("address", address), ("offset", offset.to_string()), ("limit", limit.to_string())])
146 .header("X-API-KEY", api_key)
147 .header("accept", "application/json")
148 .header("x-chain", "solana")
149 .send()
150 .await?
151 .json::<TokenHolderResponse>()
152 .await?;
153
154 Ok(resp)
155}
156
157pub async fn get_token_metadata<W: IWallet>(agent: &SolanaAgentKit<W>, address: &str) -> Result<TokenMetadataResponse> {
169 let api_key = agent
170 .config
171 .birdeye_api_key
172 .as_ref()
173 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
174
175 let client = reqwest::Client::new();
176 let url = format!("{}/defi/v3/token/meta-data/single", BIRDEYE_URL);
177
178 let resp = client
179 .get(url)
180 .query(&[("address", address)])
181 .header("X-API-KEY", api_key)
182 .header("accept", "application/json")
183 .header("x-chain", "solana")
184 .send()
185 .await?
186 .json::<TokenMetadataResponse>()
187 .await?;
188
189 Ok(resp)
190}
191
192pub async fn get_token_price<W: IWallet>(agent: &SolanaAgentKit<W>, address: &str) -> Result<TokenPriceResponse> {
204 let api_key = agent
205 .config
206 .birdeye_api_key
207 .as_ref()
208 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
209
210 let client = reqwest::Client::new();
211 let url = format!("{}/defi/price", BIRDEYE_URL);
212
213 let resp = client
214 .get(url)
215 .query(&[("address", address)])
216 .header("X-API-KEY", api_key)
217 .header("accept", "application/json")
218 .header("x-chain", "solana")
219 .send()
220 .await?
221 .json::<TokenPriceResponse>()
222 .await?;
223
224 Ok(resp)
225}
226
227pub async fn get_token_price_volume<W: IWallet>(
239 agent: &SolanaAgentKit<W>,
240 query_params: TokenPriceVolumeQueryParams,
241) -> Result<TokenPriceVolumeResponse> {
242 let api_key = agent
243 .config
244 .birdeye_api_key
245 .as_ref()
246 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
247
248 let client = reqwest::Client::new();
249 let url = format!("{}/defi/price_volume/single", BIRDEYE_URL);
250
251 let address = query_params.address;
252 let vh = query_params.vh;
253
254 let resp = client
255 .get(url)
256 .query(&[("address", address), ("type", vh)])
257 .header("X-API-KEY", api_key)
258 .header("accept", "application/json")
259 .header("x-chain", "solana")
260 .send()
261 .await?
262 .json::<TokenPriceVolumeResponse>()
263 .await?;
264
265 Ok(resp)
266}
267
268pub async fn get_token_trending<W: IWallet>(
280 agent: &SolanaAgentKit<W>,
281 query_params: TokenTrendingQueryParams,
282) -> Result<TokenTrendingResponse> {
283 let api_key = agent
284 .config
285 .birdeye_api_key
286 .as_ref()
287 .ok_or_else(|| anyhow::anyhow!("Missing Birdeye API key in agent.config.birdeye_api_key"))?;
288
289 let client = reqwest::Client::new();
290 let url = format!("{}/defi/token_trending", BIRDEYE_URL);
291
292 let sort_by = query_params.sort_by;
293 let sort_type = query_params.sort_type;
294 let offset = query_params.offset.unwrap_or(0);
295 let limit = query_params.limit.unwrap_or(20);
296
297 let resp = client
298 .get(url)
299 .query(&[
300 ("sort_by", sort_by),
301 ("sort_type", sort_type),
302 ("offset", offset.to_string()),
303 ("limit", limit.to_string()),
304 ])
305 .header("X-API-KEY", api_key)
306 .header("accept", "application/json")
307 .header("x-chain", "solana")
308 .send()
309 .await?
310 .json::<TokenTrendingResponse>()
311 .await?;
312
313 Ok(resp)
314}