Skip to main content

coinbase_advanced/rest/
public.rs

1//! Public (unauthenticated) API endpoints.
2
3use serde::Deserialize;
4
5use crate::client::RestClient;
6use crate::error::Result;
7use crate::models::{
8    Candle, GetCandlesParams, GetCandlesResponse, GetMarketTradesParams, GetMarketTradesResponse,
9    GetProductBookParams, GetProductBookResponse, ListProductsParams, ListProductsResponse,
10    Product, ProductBook,
11};
12
13/// Server time response.
14#[derive(Debug, Clone, Deserialize)]
15pub struct ServerTime {
16    /// ISO 8601 formatted time.
17    pub iso: String,
18    /// Unix epoch seconds.
19    #[serde(rename = "epochSeconds")]
20    pub epoch_seconds: String,
21    /// Unix epoch milliseconds.
22    #[serde(rename = "epochMillis")]
23    pub epoch_millis: String,
24}
25
26/// API for accessing public (unauthenticated) endpoints.
27///
28/// These endpoints do not require API credentials and can be used
29/// to access market data without authentication.
30pub struct PublicApi<'a> {
31    client: &'a RestClient,
32}
33
34impl<'a> PublicApi<'a> {
35    /// Create a new Public API instance.
36    pub(crate) fn new(client: &'a RestClient) -> Self {
37        Self { client }
38    }
39
40    /// Get the current server time.
41    ///
42    /// This is useful for synchronizing your local clock with
43    /// the Coinbase server.
44    ///
45    /// # Example
46    ///
47    /// ```no_run
48    /// # use coinbase_advanced::RestClient;
49    /// # async fn example() -> coinbase_advanced::Result<()> {
50    /// let client = RestClient::builder().build()?;
51    ///
52    /// let time = client.public().get_time().await?;
53    /// println!("Server time: {}", time.iso);
54    /// # Ok(())
55    /// # }
56    /// ```
57    pub async fn get_time(&self) -> Result<ServerTime> {
58        self.client.public_get("/time").await
59    }
60
61    /// List all public products.
62    ///
63    /// Similar to the authenticated products endpoint but does not
64    /// require credentials.
65    pub async fn list_products(&self, params: ListProductsParams) -> Result<ListProductsResponse> {
66        self.client
67            .public_get_with_query("/market/products", &params)
68            .await
69    }
70
71    /// List all products with default parameters.
72    pub async fn list_products_all(&self) -> Result<ListProductsResponse> {
73        self.list_products(ListProductsParams::default()).await
74    }
75
76    /// Get a single product by ID.
77    pub async fn get_product(&self, product_id: &str) -> Result<Product> {
78        let endpoint = format!("/market/products/{}", product_id);
79        self.client.public_get(&endpoint).await
80    }
81
82    /// Get the order book for a product.
83    pub async fn get_product_book(&self, params: GetProductBookParams) -> Result<ProductBook> {
84        let response: GetProductBookResponse = self
85            .client
86            .public_get_with_query("/market/product_book", &params)
87            .await?;
88        Ok(response.pricebook)
89    }
90
91    /// Get candlestick (OHLCV) data for a product.
92    pub async fn get_candles(&self, params: GetCandlesParams) -> Result<Vec<Candle>> {
93        let endpoint = format!("/market/products/{}/candles", params.product_id);
94        let response: GetCandlesResponse = self
95            .client
96            .public_get_with_query(&endpoint, &params)
97            .await?;
98        Ok(response.candles)
99    }
100
101    /// Get recent trades for a product.
102    pub async fn get_market_trades(
103        &self,
104        params: GetMarketTradesParams,
105    ) -> Result<GetMarketTradesResponse> {
106        let endpoint = format!("/market/products/{}/ticker", params.product_id);
107        self.client.public_get_with_query(&endpoint, &params).await
108    }
109}