listen_kit/
price.rs

1use reqwest::Client;
2use serde::{Deserialize, Serialize};
3use serde_with::{serde_as, DisplayFromStr};
4use std::collections::HashMap;
5use std::error::Error;
6
7#[serde_with::skip_serializing_none]
8#[derive(Serialize, Deserialize, Debug)]
9#[serde(rename_all = "camelCase")]
10pub struct PriceResponse {
11    pub data: HashMap<String, PriceData>,
12    pub time_taken: f64,
13}
14
15#[serde_as]
16#[serde_with::skip_serializing_none]
17#[derive(Serialize, Deserialize, Debug)]
18pub struct PriceData {
19    pub id: String,
20    #[serde_as(as = "DisplayFromStr")]
21    pub price: f64,
22}
23
24pub async fn fetch_token_price(
25    mint: String,
26    client: &Client,
27) -> Result<f64, Box<dyn Error>> {
28    let url = format!("https://api.jup.ag/price/v2?ids={}", mint);
29    let res = client
30        .get(url)
31        .header("accept", "application/json")
32        .send()
33        .await?;
34    let data = res.json::<PriceResponse>().await?;
35    Ok(data.data.get(&mint).unwrap().price)
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[tokio::test]
43    pub async fn test_fetch_token_price() {
44        let res = fetch_token_price(
45            "Cn5Ne1vmR9ctMGY9z5NC71A3NYFvopjXNyxYtfVYpump".to_string(),
46            &reqwest::Client::new(),
47        )
48        .await;
49        println!("{:?}", res);
50        assert!(res.is_ok());
51    }
52}