Skip to main content

cielo_rs_sdk/api/
feed.rs

1//! This module provides functionality for interacting with the Cielo feed API.
2//!
3//! It includes structures and methods for querying and filtering feed data.
4
5use crate::{constants, models};
6use strum_macros::Display;
7
8use super::CieloApi;
9
10/// Filters for querying the feed.
11#[derive(Debug, Clone, Default)]
12pub struct Filters {
13    /// Filter the feed by a specific wallet address.
14    pub wallet: Option<String>,
15    /// Limit the number of transactions returned in the feed. The maximum limit is 100.
16    pub limit: Option<u32>,
17    /// Filter transactions by a specific List ID.
18    pub list_id: Option<u64>,
19    /// Filter transactions by specific blockchain chains (e.g., ethereum).
20    pub chains: Option<Vec<String>>,
21    /// Filter transactions by types (e.g., swap, nft_trade).
22    pub tx_types: Option<Vec<TxType>>,
23    /// Filter transactions by specific tokens, identified by either their address or symbol.
24    pub tokens: Option<Vec<String>>,
25    /// Set a minimum USD value for transactions. Default is 0.
26    pub min_usd: Option<u64>,
27    /// Filter transactions by new trades.
28    pub new_trades: Option<bool>,
29    /// Set value from response 'paging.next_object_id' to get the next page.
30    pub start_from: Option<String>,
31    /// Filter transactions from a specific UNIX timestamp.
32    pub from_timestamp: Option<u64>,
33    /// Filter transactions to a specific UNIX timestamp.
34    pub to_timestamp: Option<u64>,
35    /// Include marketcap in the response.
36    pub include_market_cap: Option<bool>,
37}
38
39/// Transaction types for filtering the feed.
40///
41/// This enum represents various types of transactions that can be used to filter the feed.
42/// Each variant corresponds to a specific type of transaction in the Cielo ecosystem.
43#[derive(Display, Debug, Clone)]
44#[strum(serialize_all = "snake_case")]
45pub enum TxType {
46    /// Bridge transaction between different chains or networks
47    Bridge,
48    /// Creation of a new smart contract
49    ContractCreation,
50    /// Interaction with an existing smart contract
51    ContractInteraction,
52    /// Flash loan transaction
53    Flashloan,
54    /// Lending or borrowing transaction
55    Lending,
56    /// Liquidity pool-related transaction
57    Lp,
58    /// NFT lending transaction
59    NftLending,
60    /// NFT liquidation transaction
61    NftLiquidation,
62    /// Minting of a new NFT
63    NftMint,
64    /// NFT sweep (bulk purchase) transaction
65    NftSweep,
66    /// NFT trade transaction
67    NftTrade,
68    /// NFT transfer transaction
69    NftTransfer,
70    /// Option-related transaction
71    Option,
72    /// Perpetual contract transaction
73    Perp,
74    /// Reward or yield farming transaction
75    Reward,
76    /// Staking transaction
77    Staking,
78    /// SudoPool-related transaction
79    SudoPool,
80    /// Token swap transaction
81    Swap,
82    /// Simple transfer of tokens or cryptocurrency
83    Transfer,
84    /// Wrapping or unwrapping of tokens (e.g., ETH to WETH)
85    Wrap,
86}
87
88impl CieloApi {
89    /// Fetches the feed based on the provided filters.
90    ///
91    /// This function sends a request to the feed endpoint with the specified filters and returns a list of feed items.
92    ///
93    /// # Arguments
94    ///
95    /// * `filters` - A Filters struct containing various filter options.
96    ///
97    /// # Errors
98    ///
99    /// This function returns a `crate::Error` if the request fails or the response status is not 200 OK.
100    ///
101    /// # Examples
102    ///
103    /// ```no_run
104    /// # use cielo_rs_sdk::{CieloApi, api};
105    /// # #[tokio::main]
106    /// # async fn main() {
107    /// # let api_key = "your_api_key";
108    /// # let cielo_api = CieloApi::new(api_key, None, None, None).unwrap();
109    ///     let filters = api::feed::Filters {
110    ///         wallet: Some("your_wallet_address".to_string()),
111    ///         limit: Some(10),
112    ///         list_id: None,
113    ///         chains: Some(vec!["solana".to_string()]),
114    ///         tx_types: Some(vec![api::feed::TxType::Swap]),
115    ///         tokens: None,
116    ///         min_usd: Some(100),
117    ///         new_trades: Some(true),
118    ///         start_from: None,
119    ///         from_timestamp: None,
120    ///         to_timestamp: None,
121    ///         include_market_cap: Some(true),
122    ///     };
123    ///     let feed = cielo_api.get_feed(filters).await.unwrap();
124    /// # }
125    /// ```
126    pub async fn get_feed(
127        &self,
128        filters: Filters,
129    ) -> Result<Vec<models::feed::Item>, crate::Error> {
130        let url = format!("{}feed", constants::URL);
131
132        let mut request = self.client.get(url);
133
134        // Apply filters to the request
135        if let Some(wallet) = filters.wallet {
136            request = request.query(&[("wallet", wallet)]);
137        }
138        if let Some(limit) = filters.limit {
139            request = request.query(&[("limit", limit.to_string())]);
140        }
141        if let Some(list_id) = filters.list_id {
142            request = request.query(&[("list", list_id.to_string())]);
143        }
144        if let Some(chains) = filters.chains {
145            request = request.query(&[("chains", chains.join(","))]);
146        }
147        if let Some(tx_types) = filters.tx_types {
148            let tx_types_str: Vec<String> = tx_types.iter().map(|tx| tx.to_string()).collect();
149            request = request.query(&[("txTypes", tx_types_str.join(","))]);
150        }
151        if let Some(tokens) = filters.tokens {
152            request = request.query(&[("tokens", tokens.join(","))]);
153        }
154        if let Some(min_usd) = filters.min_usd {
155            request = request.query(&[("minUSD", min_usd.to_string())]);
156        }
157        if let Some(new_trades) = filters.new_trades {
158            request = request.query(&[("newTrades", new_trades.to_string())]);
159        }
160        if let Some(start_from) = filters.start_from {
161            request = request.query(&[("startFrom", start_from)]);
162        }
163        if let Some(from_timestamp) = filters.from_timestamp {
164            request = request.query(&[("fromTimestamp", from_timestamp.to_string())]);
165        }
166        if let Some(to_timestamp) = filters.to_timestamp {
167            request = request.query(&[("toTimestamp", to_timestamp.to_string())]);
168        }
169
170        let response = request.send().await?;
171
172        // Check if the response status is not 200 OK
173        if !response.status().is_success() {
174            return Err(crate::Error::StatusNot200(response.text().await?));
175        }
176
177        // Parse the response JSON into the expected structure
178        let response_items = response
179            .json::<models::Response<models::feed::Item>>()
180            .await?
181            .data
182            .items;
183        Ok(response_items)
184    }
185}