Skip to main content

ccdata_api/
lib.rs

1//! # CoinDesk API Wrapper
2//!
3//! `ccdata-api` is a wrapper for CoinDesk REST API endpoints (Formerly CCData). This crate supports non-exhausitve list of CoinDesk endpoints,
4//! you can check what endpoints are supported by checking the variants of the enum `CCAPIEndpoint` - it contains all
5//! supported endpoint URLs.
6//!
7//! For documentation on CoinDesk REST API endpoints visit CoinDesk online documentation:
8//! - API Documentation: <https://developers.coindesk.com/documentation/data-api/introduction>
9//! - Legacy API Documentation: <https://developers.coindesk.com/documentation/legacy/Price/SingleSymbolPriceEndpoint>
10//!
11//! **Disclaimer:** This crate is an unofficial CoinDesk REST API wrapper, the maintainers of the crate are independent developers.
12//! The developers of the crate do not accept any responsibility or liability for the accuracy, security, or completeness of the code,
13//! or the information provided within the crate.
14//!
15//! # Errors
16//!
17//! The REST API functions in the crate will error if the data received does not fit into the pre-defined schemas provided
18//! in the crate. If you encounter any errors, please open an issue on GitHub with the parameters that you have used (e.g., asset symbol,
19//! timestamp, limit, etc.). **Do not provide your API key or any personal data!**
20//! 
21//! # Deprecated API Endpoints
22//! 
23//! Some API endpoints have been deprecated by CoinDesk, who strongly recommend migrating to newer alternatives suggested in their API documentation.
24//! 
25//! # Features
26//! - `debug`: If this feature is enabled, you can set `CCDATA_API_DEBUG` environment variable to `true`, which will print the response body
27//! for every request to the command line.
28//!
29//! # Examples
30//!
31//! To start making the REST API requests, define a data collection backend. This can be done by either directly passing an
32//! API key to the data collection backend, or by defining a `.env` file with an API key as an environment variable (Preferred
33//! method).
34//!
35//! ## Build Backend Explicitly Stating API Key (May expose API key)
36//!
37//! ```rust
38//! use ccdata_api::CCData;
39//!
40//! let mut backend: CCData = CCData::new();
41//!
42//! let api_key: String = String::from("xxxxxxx");
43//! backend.update_api_key(api_key);
44//!
45//! assert_eq!(backend.api_key().unwrap(), "xxxxxxx");
46//! ```
47//!
48//! ## Build Backend Using .env File (Preferred method)
49//!
50//! ```rust
51//! use ccdata_api::CCData;
52//!
53//! let mut backend: CCData = CCData::new();
54//! // Provide API key as the environment variable called API_KEY
55//! backend.build(&"API_KEY").unwrap();
56//!
57//! println!("{}", backend.api_key().unwrap());
58//! ```
59//!
60//! ## Making First API Call
61//!
62//! After the backend has been build, you can make API requests using the methods provided in the backend. For example, to
63//! get a daily spot OHLCV data for Bitcoin you can do the following (note that the calls use Rust's `async` functionality):
64//!
65//! ```rust
66//!
67//! use ccdata_api::{CCData, CCUnit, CCSpotMarket};
68//!
69//! #[tokio::main]
70//! async fn main() -> () {
71//!
72//!     let mut backend: CCData = CCData::new();
73//!     // Provide API key as the environment variable called API_KEY
74//!     backend.build(&"API_KEY").unwrap();
75//!
76//!     // Define the API parameters
77//!     let market: CCSpotMarket = CCSpotMarket::KRAKEN;
78//!     let limit: usize = 2000;
79//!     let to_timestamp: Option<i64> = Some(1728860400);
80//!
81//!     // Make the API call
82//!     let ohlcv = backend.get_spot_ohlcv("BTC-USD", to_timestamp, Some(limit), market, CCUnit::Day).await.unwrap();
83//!     assert_eq!(ohlcv.data.unwrap().len(), limit);
84//!
85//! }
86//! ```
87//!
88//! # General information
89//! If you would like to add a commit or an issue, please do so using the GitHub link to the project:
90//! - <https://github.com/rsadykhov/ccdata-api>
91
92
93// Re-Exports
94pub use self::backend::CCData;
95// Min-API Re-Exports
96pub use self::schemas::{CCMinResponse, CCMinWrapper, CCRateLimit, CCMaxCalls, CCCallsMade};
97pub use self::schemas::min_api::{CCAvailableCoinList, CCHistoricalDaily, CCBalanceDistribution, CCSupplyBand};
98// Data-API Re-Exports
99pub use self::schemas::{CCDataResponse, CCError, CCErrorOtherInfo};
100pub use self::schemas::data_api::indices_and_reference_rates::{CCIndicesMarket, CCIndicesOHLCV};
101pub use self::schemas::data_api::spot::{CCSpotMarket, CCSpotInstrumentStatus, CCSpotOHLCV, CCSpotInstrumentMetdata, CCSpotMarkets, CCSpotMarketsInstruments};
102pub use self::schemas::data_api::futures::{CCFuturesMarket, CCFuturesOHLCV, CCFuturesMarkets};
103pub use self::schemas::data_api::options::{CCOptionsMarket, CCOptionsOHLCV, CCOptionsMarkets};
104pub use self::schemas::data_api::derivatives_indices::{CCDerIndicesMarket, CCDerIndicesOHLCV, CCDerIndicesMarkets};
105pub use self::schemas::data_api::on_chain_dex::{CCOCDEXMarket, CCOCDEXOHLCV, CCOCDEXMarkets};
106pub use self::schemas::data_api::on_chain_core::{CCOCCoreETHBlock, CCOCCoreAssetByChain, CCOCCoreAssetByAddress, CCOCCoreSupply};
107pub use self::schemas::data_api::asset::{CCAssetMetadata, CCAssetEvent, CCAssetCodeRepoMetrics, CCAssetDiscord, CCAssetReddit, CCAssetTelegram, CCAssetTwitter};
108pub use self::schemas::data_api::news::{CCNewsStatus, CCNewsLang, CCNewsSourceID, CCNewsLatestArticle, CCNewsSourceType, CCNewsSource, CCNewsCategory};
109pub use self::schemas::data_api::overview::CCOverviewMktCapOHLCV;
110
111
112pub mod error;
113pub mod schemas;
114pub mod utils;
115pub mod backend;
116
117
118/// Unit of the interval between successive data points.
119pub enum CCUnit {
120    /// Daily data interval
121    Day,
122    /// Hourly data interval
123    Hour,
124    /// Minutely data interval
125    Minute,
126    /// Used for API endpoints that do not have a specified unit for data or where unit is unapplicable
127    NA,
128}
129
130
131/// All supported API endpoints.
132pub enum CCAPIEndpoint {
133    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
134    // Min-API
135    /// Min-API Endpoint
136    ///
137    /// Description: Returns a list of all coins for which CoinDesk currently gets the blockchain data
138    ///
139    /// URL: https://min-api.cryptocompare.com/data/blockchain/list
140    AvailableCoinList,
141    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
142    /// Min-API Endpoint
143    ///
144    /// Description: Retrieves the daily aggregated blockchain data for the requested coin
145    ///
146    /// URL: https://min-api.cryptocompare.com/data/blockchain/histo/day
147    HistoricalDaily,
148    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
149    /// Min-API Endpoint
150    ///
151    /// Description: Retrieves the balance distribution for a specified asset over a specified time range at a daily interval
152    ///
153    /// Note: Only data for BTC (Bitcoin) is currently available
154    ///
155    /// URL: https://min-api.cryptocompare.com/data/blockchain/balancedistribution/histo/day
156    BalanceDistribution,
157    // Data-API
158    // Indices & Reference Rates
159    /// Data-API Endpoint
160    ///
161    /// Description: Provides historical candlestick data for various indices
162    ///
163    /// URL: https://data-api.coindesk.com/index/cc/v1/historical
164    IndicesOHLCV,
165    // Spot
166    /// Data-API Endpoint
167    ///
168    /// Description: Provides candlestick data for specific cryptocurrency instruments across selected exchanges
169    ///
170    /// URL: https://data-api.coindesk.com/spot/v1/historical
171    SpotOHLCV,
172    /// Data-API Endpoint
173    ///
174    /// Description: Delivers vital metadata about financial instruments traded on specified exchanges, focusing solely on non-price related information
175    ///
176    /// URL: https://data-api.coindesk.com/spot/v1/latest/instrument/metadata
177    SpotInstrumentMetadata,
178    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
179    /// Data-API Endpoint
180    ///
181    /// Description: Provides comprehensive information about various cryptocurrency spot markets
182    ///
183    /// URL: https://data-api.coindesk.com/spot/v1/markets
184    SpotMarkets,
185    /// Data-API Endpoint
186    ///
187    /// Description: Retrieves a comprehensive dictionary of mapped instruments across one or more spot markets, filtered by a specified state or status
188    ///
189    /// URL: https://data-api.coindesk.com/spot/v1/markets/instruments
190    SpotMarketsInstruments,
191    // Futures
192    /// Data-API Endpoint
193    ///
194    /// Description: Provides aggregated candlestick data for specific futures instruments on designated exchanges
195    ///
196    /// URL: https://data-api.coindesk.com/futures/v1/historical
197    FuturesOHLCV,
198    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
199    /// Data-API Endpoint
200    ///
201    /// Description: Provides comprehensive information about various cryptocurrency futures markets
202    ///
203    /// URL: https://data-api.coindesk.com/futures/v1/markets
204    FuturesMarkets,
205    // Options
206    /// Data-API Endpoint
207    ///
208    /// Description: Provides historical OHLCV (open, high, low, close, volume) data for specified options instruments on a chosen exchange
209    ///
210    /// URL: https://data-api.coindesk.com/options/v1/historical
211    OptionsOHLCV,
212    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
213    /// Data-API Endpoint
214    ///
215    /// Description: Provides comprehensive information about the various options markets integrated by our platform
216    ///
217    /// URL: https://data-api.coindesk.com/options/v1/markets
218    OptionsMarkets,
219    // Derivatives Indices
220    /// Data-API Endpoint
221    ///
222    /// Description: Provides historical OHLC (open, high, low, close) data for specified index instruments on a selected market
223    ///
224    /// URL: https://data-api.coindesk.com/index/v1/historical
225    DerIndicesOHLCV,
226    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
227    /// Data-API Endpoint
228    ///
229    /// Description: Provides comprehensive information about various derivatives index markets
230    ///
231    /// URL: https://data-api.coindesk.com/index/v1/markets
232    DerIndicesMarkets,
233    // On-Chain DEX
234    /// Data-API Endpoint
235    ///
236    /// Description: Retrieves aggregated candlestick data for AMM swap transactions
237    ///
238    /// URL: https://data-api.coindesk.com/onchain/v1/amm/historical/swap
239    OCDEXOHLCV,
240    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
241    /// Data-API Endpoint
242    ///
243    /// Description: Provides comprehensive information about various decentralized exchange (DEX) markets within the blockchain ecosystem
244    ///
245    /// URL: https://data-api.coindesk.com/onchain/v1/amm/markets
246    OCDEXMarkets,
247    // On-Chain Core
248    /// Data-API Endpoint
249    ///
250    /// Description: Delivers exhaustive details on a specific Ethereum block in a meticulously processed format, complete with detailed explanations for each field
251    ///
252    /// URL: https://data-api.coindesk.com/onchain/v1/block/2
253    OCCoreETHBlocks,
254    /// Data-API Endpoint
255    ///
256    /// Description: Retrieves a comprehensive summary of chain asset information for a specified blockchain, identified by its chain symbol
257    ///
258    /// URL: https://data-api.coindesk.com/onchain/v3/summary/by/chain
259    OCCoreAssetsByChain,
260    /// Data-API Endpoint
261    ///
262    /// Description: Retrieves comprehensive asset information for a specific asset identified by its smart contract address and associated blockchain asset
263    ///
264    /// URL: https://data-api.coindesk.com/onchain/v2/data/by/address
265    OCCoreAssetByAddress,
266    /// Data-API Endpoint
267    ///
268    /// Description: Retrieves comprehensive historical supply data for various digital assets identified by either their CoinDesk asset ID or unique asset symbol
269    ///
270    /// URL: https://data-api.coindesk.com/onchain/v2/historical/supply/days
271    OCCoreSupply,
272    #[deprecated(since="1.0.6", note="Deprecated by CoinDesk")]
273    // Asset
274    /// Data-API Endpoint
275    ///
276    /// Description: Returns an object that provides detailed and comprehensive information about multiple cryptocurrency assets in response to a request
277    ///
278    /// URL: https://data-api.coindesk.com/asset/v1/metadata
279    AssetMetadata,
280    /// Data-API Endpoint
281    /// 
282    /// Descriptions: Returns an object that provides detailed and comprehensive information about multiple cryptocurrency assets in response to a request
283    /// 
284    /// URL: https://data-api.coindesk.com/asset/v2/metadata
285    AssetMetadataV2,
286    /// Data-API Endpoint
287    ///
288    /// Description: Retrieves an array of significant events related to digital assets, such as security incidents, rebrandings, blockchain forks, and other impactful developments
289    ///
290    /// URL: https://data-api.coindesk.com/asset/v1/events
291    AssetEvents,
292    /// Data-API Endpoint
293    ///
294    /// Description: Provides an in-depth, daily snapshot of a digital asset's code repositories
295    ///
296    /// URL: https://data-api.coindesk.com/asset/v1/historical/code-repository/days
297    AssetCodeRepo,
298    /// Data-API Endpoint
299    ///
300    /// Description: Aggregates detailed daily metrics from all Discord servers related to a specific digital asset, offering a multifaceted view into community engagement and the asset's standing within Discord communities
301    ///
302    /// URL: https://data-api.coindesk.com/asset/v1/historical/discord/days
303    AssetDiscord,
304    /// Data-API Endpoint
305    ///
306    /// Description: Aggregates key performance indicators from all the subreddits related to a specific digital asset, providing a comprehensive understanding of the asset's footprint on Reddit
307    ///
308    /// URL: https://data-api.coindesk.com/asset/v1/historical/reddit/days
309    AssetReddit,
310    /// Data-API Endpoint
311    ///
312    /// Description: Collates essential data points across all Telegram groups affiliated with a particular cryptocurrency asset
313    ///
314    /// URL: https://data-api.coindesk.com/asset/v1/historical/telegram/days
315    AssetTelegram,
316    /// Data-API Endpoint
317    ///
318    /// Description: Aggregates essential metrics from all X (Twitter) accounts associated with a specific cryptocurrency asset
319    ///
320    /// URL: https://data-api.coindesk.com/asset/v1/historical/twitter/days
321    AssetTwitter,
322    // News
323    /// Data-API Endpoint
324    ///
325    /// Description: Serves as the pulse of the crypto news landscape, providing users with instant access to the most recent articles across the industry
326    ///
327    /// URL: https://data-api.coindesk.com/news/v1/article/list
328    NewsLatestArticles,
329    /// Data-API Endpoint
330    ///
331    /// Description: Offers a comprehensive listing of all news sources available through CoinDesk API
332    ///
333    /// URL: https://data-api.coindesk.com/news/v1/source/list
334    NewsSources,
335    /// Data-API Endpoint
336    ///
337    /// Description: Provide a straightforward listing of all news categories available through CoinDesk API
338    ///
339    /// URL: https://data-api.coindesk.com/news/v1/category/list
340    NewsCategories,
341    // Overview
342    /// Data-API Endpoint
343    ///
344    /// Description: Presents a thorough historical daily overview of market capitalisation for digital assets that meet the volume and listing criteria
345    ///
346    /// URL: https://data-api.coindesk.com/overview/v1/historical/marketcap/all/assets/days
347    OverviewMktCapOHLCV,
348}
349
350impl CCAPIEndpoint {
351    fn resolve_url(&self) -> String {
352        match self {
353            // Min-API
354            Self::AvailableCoinList => String::from("https://min-api.cryptocompare.com/data/blockchain/list"),
355            Self::HistoricalDaily => String::from("https://min-api.cryptocompare.com/data/blockchain/histo/day"),
356            Self::BalanceDistribution => String::from("https://min-api.cryptocompare.com/data/blockchain/balancedistribution/histo/day"),
357            // Data-API
358            // Indices & Reference Rates
359            Self::IndicesOHLCV => String::from("https://data-api.coindesk.com/index/cc/v1/historical"),
360            // Spot
361            Self::SpotOHLCV => String::from("https://data-api.coindesk.com/spot/v1/historical"),
362            Self::SpotInstrumentMetadata => String::from("https://data-api.coindesk.com/spot/v1/latest/instrument/metadata"),
363            Self::SpotMarkets => String::from("https://data-api.coindesk.com/spot/v1/markets"),
364            Self::SpotMarketsInstruments => String::from("https://data-api.coindesk.com/spot/v1/markets/instruments"),
365            // Futures
366            Self::FuturesOHLCV => String::from("https://data-api.coindesk.com/futures/v1/historical"),
367            Self::FuturesMarkets => String::from("https://data-api.coindesk.com/futures/v1/markets"),
368            // Options
369            Self::OptionsOHLCV => String::from("https://data-api.coindesk.com/options/v1/historical"),
370            Self::OptionsMarkets => String::from("https://data-api.coindesk.com/options/v1/markets"),
371            // Derivatives Indices
372            Self::DerIndicesOHLCV => String::from("https://data-api.coindesk.com/index/v1/historical"),
373            Self::DerIndicesMarkets => String::from("https://data-api.coindesk.com/index/v1/markets"),
374            // On-Chain DEX
375            Self::OCDEXOHLCV => String::from("https://data-api.coindesk.com/onchain/v1/amm/historical/swap"),
376            Self::OCDEXMarkets => String::from("https://data-api.coindesk.com/onchain/v1/amm/markets"),
377            // On-Chain Core
378            Self::OCCoreETHBlocks => String::from("https://data-api.coindesk.com/onchain/v1/block/2"),
379            Self::OCCoreAssetsByChain => String::from("https://data-api.coindesk.com/onchain/v3/summary/by/chain"),
380            Self::OCCoreAssetByAddress => String::from("https://data-api.coindesk.com/onchain/v2/data/by/address"),
381            Self::OCCoreSupply => String::from("https://data-api.coindesk.com/onchain/v2/historical/supply/days"),
382            // Asset
383            Self::AssetMetadata => String::from("https://data-api.coindesk.com/asset/v1/metadata"),
384            Self::AssetMetadataV2 => String::from("https://data-api.coindesk.com/asset/v2/metadata"),
385            Self::AssetEvents => String::from("https://data-api.coindesk.com/asset/v1/events"),
386            Self::AssetCodeRepo => String::from("https://data-api.coindesk.com/asset/v1/historical/code-repository/days"),
387            Self::AssetDiscord => String::from("https://data-api.coindesk.com/asset/v1/historical/discord/days"),
388            Self::AssetReddit => String::from("https://data-api.coindesk.com/asset/v1/historical/reddit/days"),
389            Self::AssetTelegram => String::from("https://data-api.coindesk.com/asset/v1/historical/telegram/days"),
390            Self::AssetTwitter => String::from("https://data-api.coindesk.com/asset/v1/historical/twitter/days"),
391            // News
392            Self::NewsLatestArticles => String::from("https://data-api.coindesk.com/news/v1/article/list"),
393            Self::NewsSources => String::from("https://data-api.coindesk.com/news/v1/source/list"),
394            Self::NewsCategories => String::from("https://data-api.coindesk.com/news/v1/category/list"),
395            // Overview
396            Self::OverviewMktCapOHLCV => String::from("https://data-api.coindesk.com/overview/v1/historical/marketcap/all/assets/days"),
397        }
398    }
399
400    fn add_unit_to_url(&self, url: &mut String, unit: &CCUnit) -> () {
401        match self {
402            Self::IndicesOHLCV | Self::SpotOHLCV | Self::FuturesOHLCV |
403            Self::OptionsOHLCV | Self::DerIndicesOHLCV | Self::OCDEXOHLCV => {
404                match unit {
405                    CCUnit::Day | CCUnit::NA => url.push_str(&"/days"),
406                    CCUnit::Hour => url.push_str(&"/hours"),
407                    CCUnit::Minute => url.push_str(&"/minutes"),
408                }
409            },
410            _ => (),
411        }
412    }
413
414    /// Produces URL for a given API endpoint.
415    ///
416    /// # Input
417    /// - `unit`: Unit of the interval between successive data points
418    pub fn url(&self, unit: &CCUnit) -> String {
419        let mut url: String = self.resolve_url();
420        self.add_unit_to_url(&mut url, unit);
421        url
422    }
423}
424
425
426#[cfg(test)]
427mod tests {
428
429    #[test]
430    fn unit_test_add_unit_to_url() -> () {
431        use crate::{CCUnit, CCAPIEndpoint};
432        let unit: CCUnit = CCUnit::Hour;
433        let api_endpoint: CCAPIEndpoint = CCAPIEndpoint::IndicesOHLCV;
434        assert_eq!(api_endpoint.url(&unit), String::from("https://data-api.coindesk.com/index/cc/v1/historical/hours"));
435    }
436}