Skip to content

Commit c801ecf

Browse files
authored
Merge branch 'main' into bump-version-1.0.6
2 parents d953daa + f6fe450 commit c801ecf

File tree

7 files changed

+299
-133
lines changed

7 files changed

+299
-133
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/src/token.rs

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use jup_ag_sdk::{JupiterClient, types::TokenPriceRequest};
1+
use jup_ag_sdk::{JupiterClient, client};
22

33
pub async fn token_balances() {
44
let client = JupiterClient::new("https://lite-api.jup.ag");
@@ -31,48 +31,22 @@ pub async fn token_price() {
3131
"JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN".to_string(),
3232
];
3333

34-
let params = TokenPriceRequest::new(&token_mints);
35-
36-
let price = client
37-
.get_token_price(&params)
38-
.await
39-
.expect("Failed to get token price");
40-
41-
let sol_price = price
42-
.data
43-
.get(token_mints[0].as_str())
44-
.expect("SOL price not found");
45-
46-
println!("1 SOL price in USDC: {}", sol_price.price);
47-
48-
let jup_price = price
49-
.data
50-
.get(token_mints[1].as_str())
51-
.expect("Jup Token price not found");
52-
53-
println!("1 JUP price USDC: {}", jup_price.price);
54-
55-
let params = TokenPriceRequest::new(&token_mints)
56-
.with_vs_token("So11111111111111111111111111111111111111112");
57-
5834
let price = client
59-
.get_token_price(&params)
35+
.get_tokens_price(&token_mints)
6036
.await
6137
.expect("Failed to get token price");
6238

6339
let sol_price = price
64-
.data
6540
.get(token_mints[0].as_str())
6641
.expect("SOL price not found");
6742

68-
println!("1 SOL price in SOL: {}", sol_price.price);
43+
println!("1 SOL price in USDC: {}", sol_price.usd_price);
6944

7045
let jup_price = price
71-
.data
7246
.get(token_mints[1].as_str())
7347
.expect("Jup Token price not found");
7448

75-
println!("1 JUP price in SOL: {}", jup_price.price);
49+
println!("1 JUP price USDC: {}", jup_price.usd_price);
7650
}
7751

7852
pub async fn token_info() {
@@ -115,3 +89,18 @@ pub async fn get_tokens_from_tags() {
11589

11690
println!("mints: {}", mints.len())
11791
}
92+
93+
pub async fn get_trending_tokens() {
94+
let client = JupiterClient::new("https:://lite-api.jup.ag");
95+
96+
let tokens = client
97+
.get_tokens_by_category(
98+
jup_ag_sdk::types::Category::TopTrending,
99+
jup_ag_sdk::types::Interval::TwentyFourHours,
100+
Some(10),
101+
)
102+
.await
103+
.expect("failed to get trending tokens");
104+
105+
println!("trending tokens: {:?}", tokens.len());
106+
}

jup-ag-sdk/src/client/token_api.rs

Lines changed: 206 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,210 @@
1+
use std::collections::HashMap;
2+
13
use super::JupiterClient;
24
use crate::{
35
error::{JupiterClientError, handle_response},
4-
types::{NewTokens, TokenInfoResponse, TokenPriceRequest, TokenPriceResponse},
6+
types::{
7+
Category, Interval, NewTokens, Price, TokenInfo, TokenInfoResponse, TokenPriceRequest,
8+
TokenPriceResponse,
9+
},
510
};
611

712
impl JupiterClient {
13+
/// search for a token and its information by its symbol, name or mint address
14+
///
15+
/// Limit to 100 mint addresses in query
16+
/// Default to 20 mints in response when searching via symbol or name
17+
///
18+
/// # Arguments
19+
///
20+
/// * `mints` - A slice of mint addresses (`&[String]`) to inspect.
21+
///
22+
/// # Returns
23+
///
24+
/// * `Ok(Vec<TokenInfo>)` containing token safety metadata.
25+
/// * `Err` if the request or deserialization fails.
26+
///
27+
/// # Jupiter API Reference
28+
///
29+
/// - [Search Endpoint](https://dev.jup.ag/docs/api/ultra-api/search)
30+
///
31+
/// # Example
32+
///
33+
/// ```
34+
/// let mints = vec![
35+
/// String::from("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
36+
/// String::from("JUP")
37+
/// ];
38+
/// let token_info = client.token_search(&mints).await?;
39+
/// ```
40+
pub async fn token_search(
41+
&self,
42+
mints: &[String],
43+
) -> Result<Vec<TokenInfo>, JupiterClientError> {
44+
let query_params = vec![("query", mints.join(","))];
45+
46+
let response = match self
47+
.client
48+
.get(format!("{}/tokens/v2/search", self.base_url))
49+
.query(&query_params)
50+
.send()
51+
.await
52+
{
53+
Ok(resp) => resp,
54+
Err(e) => return Err(JupiterClientError::RequestError(e)),
55+
};
56+
57+
let response = handle_response(response).await?;
58+
59+
match response.json::<Vec<TokenInfo>>().await {
60+
Ok(data) => Ok(data),
61+
Err(e) => Err(JupiterClientError::DeserializationError(e.to_string())),
62+
}
63+
}
64+
65+
/// Returns a list of mints with specified tag(s) along with their metadata.
66+
/// tags: verified, lst, token-2022, etc
67+
/// ```
68+
///
69+
/// let tags = vec![String::from("verified")];
70+
/// let tagged = client
71+
/// .get_mints_by_tags(&tags)
72+
/// .await
73+
/// .expect("failed to get mints by tags");
74+
/// ```
75+
pub async fn get_mints_by_tags(
76+
&self,
77+
tags: &[String],
78+
) -> Result<Vec<TokenInfo>, JupiterClientError> {
79+
let query_params = vec![("query", tags.join(","))];
80+
81+
let response = match self
82+
.client
83+
.get(format!("{}/tokens/v2/tag", self.base_url))
84+
.query(&query_params)
85+
.send()
86+
.await
87+
{
88+
Ok(resp) => resp,
89+
Err(e) => return Err(JupiterClientError::RequestError(e)),
90+
};
91+
92+
let response = handle_response(response).await?;
93+
94+
match response.json::<Vec<TokenInfo>>().await {
95+
Ok(mints) => Ok(mints),
96+
Err(e) => Err(JupiterClientError::DeserializationError(e.to_string())),
97+
}
98+
}
99+
100+
/// Returns a list of mints and their information for the given category and time interval.
101+
///
102+
/// # Parameters
103+
/// - `category` (`Category`) — Required
104+
/// The token ranking category. Possible values:
105+
/// - `toporganicscore` — Top tokens by organic score
106+
/// - `toptraded` — Top traded tokens
107+
/// - `toptrending` — Top trending tokens
108+
///
109+
/// - `interval` (`Interval`) — Required
110+
/// Time interval for the ranking query. Possible values:
111+
/// - `5m` — Last 5 minutes
112+
/// - `1h` — Last 1 hour
113+
/// - `6h` — Last 6 hours
114+
/// - `24h` — Last 24 hours
115+
///
116+
/// - `limit` (`Option<u8>`) — Optional
117+
/// Maximum number of results to return (default is 50, maximum is 100).
118+
/// Must be between 1 and 100 inclusive if provided.
119+
/// ```
120+
/// let tokens = client
121+
/// .get_mints_by_category(Category::TopTrending, Interval::OneHour, None)
122+
/// .await.expect("failed to get tokens");
123+
/// ```
124+
pub async fn get_tokens_by_category(
125+
&self,
126+
category: Category,
127+
interval: Interval,
128+
limit: Option<u8>,
129+
) -> Result<Vec<TokenInfo>, JupiterClientError> {
130+
let url = format!("{}/tokens/v2/{}/{}", self.base_url, category, interval);
131+
132+
let mut request = self.client.get(url);
133+
134+
if let Some(limit) = limit {
135+
request = request.query(&[("limit", limit)]);
136+
}
137+
138+
let response = match request.send().await {
139+
Ok(resp) => resp,
140+
Err(e) => return Err(JupiterClientError::RequestError(e)),
141+
};
142+
143+
let response = handle_response(response).await?;
144+
145+
match response.json::<Vec<TokenInfo>>().await {
146+
Ok(mints) => Ok(mints),
147+
Err(e) => Err(JupiterClientError::DeserializationError(e.to_string())),
148+
}
149+
}
150+
151+
/// Returns an vec of mints that recently had their first created pool
152+
/// Default to 30 mints in response
153+
pub async fn get_recent_tokens(&self) -> Result<Vec<TokenInfo>, JupiterClientError> {
154+
let url = format!("{}/tokens/v2/recent", self.base_url);
155+
156+
let response = match self.client.get(&url).send().await {
157+
Ok(resp) => resp,
158+
Err(e) => return Err(JupiterClientError::RequestError(e)),
159+
};
160+
161+
let response = handle_response(response).await?;
162+
163+
match response.json::<Vec<TokenInfo>>().await {
164+
Ok(mints) => Ok(mints),
165+
Err(e) => Err(JupiterClientError::DeserializationError(e.to_string())),
166+
}
167+
}
168+
169+
/// Returns prices of specified tokens.
170+
///
171+
/// ```
172+
/// let client = JupiterClient::new("https://lite-api.jup.ag");
173+
///
174+
/// let mints = vec![
175+
/// String::from("So11111111111111111111111111111111111111112"),
176+
/// String::from("JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"),
177+
/// ];
178+
///
179+
/// let price = client.get_tokens_price(&mints).await.expect("failed to get token price");
180+
/// let jup_price = price.get(&mints[1]).expect("jup not found").usd_price;
181+
/// ```
182+
pub async fn get_tokens_price(
183+
&self,
184+
mints: &[String],
185+
) -> Result<HashMap<String, Price>, JupiterClientError> {
186+
let query_params = vec![("ids", mints.join(","))];
187+
188+
let response = match self
189+
.client
190+
.get(format!("{}/price/v3", self.base_url))
191+
.query(&query_params)
192+
.send()
193+
.await
194+
{
195+
Ok(resp) => resp,
196+
Err(e) => return Err(JupiterClientError::RequestError(e)),
197+
};
198+
199+
let response = handle_response(response).await?;
200+
201+
match response.json::<HashMap<String, Price>>().await {
202+
Ok(token_price) => Ok(token_price),
203+
Err(e) => Err(JupiterClientError::DeserializationError(e.to_string())),
204+
}
205+
}
206+
207+
#[deprecated(note = "This endpoint is deprecated. use `get_tokens_price` instead")]
8208
/// Returns prices of specified tokens.
9209
/// ```
10210
/// let client = JupiterClient::new("https://lite-api.jup.ag")
@@ -52,6 +252,7 @@ impl JupiterClient {
52252
}
53253
}
54254

255+
#[deprecated]
55256
/// Returns the specified mint address's token information and metadata.
56257
///
57258
/// ```
@@ -78,6 +279,7 @@ impl JupiterClient {
78279
}
79280
}
80281

282+
#[deprecated]
81283
/// Returns the mints involved in a market.
82284
pub async fn get_market_mints(
83285
&self,
@@ -100,6 +302,7 @@ impl JupiterClient {
100302
}
101303
}
102304

305+
#[deprecated]
103306
/// Returns a list of all mints tradable via Jupiter routing.
104307
/// This endpoint returns greater than 32MB amount of data. May take a while to complete.
105308
pub async fn get_tradable_mints(&self) -> Result<Vec<String>, JupiterClientError> {
@@ -117,34 +320,7 @@ impl JupiterClient {
117320
}
118321
}
119322

120-
/// Returns a list of mints with specified tag(s) along with their metadata.
121-
/// tags: verified, lst, token-2022, etc
122-
/// ```
123-
///
124-
/// let tags = vec![String::from("verified")];
125-
/// let tagged = client
126-
/// .get_mints_by_tags(&tags)
127-
/// .await
128-
/// .expect("failed to get mints by tags");
129-
/// ```
130-
pub async fn get_mints_by_tags(
131-
&self,
132-
tags: &[String],
133-
) -> Result<Vec<TokenInfoResponse>, JupiterClientError> {
134-
let url = format!("{}/tokens/v1/tagged/{}", self.base_url, tags.join(","));
135-
let response = match self.client.get(&url).send().await {
136-
Ok(resp) => resp,
137-
Err(e) => return Err(JupiterClientError::RequestError(e)),
138-
};
139-
140-
let response = handle_response(response).await?;
141-
142-
match response.json::<Vec<TokenInfoResponse>>().await {
143-
Ok(mints) => Ok(mints),
144-
Err(e) => Err(JupiterClientError::DeserializationError(e.to_string())),
145-
}
146-
}
147-
323+
#[deprecated(note = "This fn is deprecated. Use `get_recent_tokens` instead.")]
148324
/// get new tokens with metadata, created at timestamp and markets.
149325
pub async fn get_new_tokens(
150326
&self,
@@ -175,6 +351,7 @@ impl JupiterClient {
175351
}
176352
}
177353

354+
#[deprecated]
178355
/// Returns all tokens with all metadata.
179356
/// Do note that calling this endpoint's resource will return a large payload of 300+MB, which would introduce some latency in the call.
180357
/// Please use carefully and intentionally, else utilize the other endpoints.

0 commit comments

Comments
 (0)