deribit_http/config/
credentials.rs

1use crate::HttpError;
2use pretty_simple_display::{DebugPretty, DisplaySimple};
3use serde::{Deserialize, Serialize};
4use std::env;
5use tracing::warn;
6
7/// API credentials for authentication
8#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
9pub struct ApiCredentials {
10    /// Client ID for OAuth2
11    pub client_id: Option<String>,
12    /// Client secret for OAuth2
13    pub client_secret: Option<String>,
14}
15
16impl ApiCredentials {
17    /// Validates whether the required fields `client_id` and `client_secret` are present.
18    ///
19    /// # Returns
20    ///
21    /// * `true` - If both `client_id` and `client_secret` are `Some` (i.e., not `None`).
22    /// * `false` - If either `client_id` or `client_secret` is `None`.
23    ///
24    pub fn is_valid(&self) -> bool {
25        self.client_id.is_some() && self.client_secret.is_some()
26    }
27
28    /// Creates a new instance of the struct with credentials initialized from environment variables.
29    ///
30    /// # Returns
31    /// - `Ok(Self)`: If the credentials are properly configured and valid.
32    /// - `Err(HttpError::ConfigError)`: If the credentials are not properly set or invalid, with an appropriate
33    ///   error message indicating the configuration issue.
34    ///
35    /// # Note
36    /// - If the credentials are invalid or not set, a warning will be logged, and only public API endpoints
37    ///   will be accessible.
38    ///
39    pub fn new() -> Result<Self, HttpError> {
40        let creds = Self::default();
41        if creds.is_valid() {
42            Ok(creds)
43        } else {
44            warn!(
45                "API credentials are provided in environment variables, only public endpoints will be available."
46            );
47            Err(HttpError::ConfigError(
48                "API credentials are not properly set in environment variables".into(),
49            ))
50        }
51    }
52
53    /// Retrieves the client credentials (Client ID and Client Secret) required for OAuth2 authentication.
54    ///
55    /// # Returns
56    /// - `Ok((String, String))`: A tuple containing the `client_id` and `client_secret` if they are both set.
57    /// - `Err(HttpError)`: An error of type `HttpError::ConfigError` if either `client_id` or `client_secret` is not set.
58    ///
59    /// # Errors
60    /// Returns an `HttpError::ConfigError` with a message indicating that both `Client ID`
61    /// and `Client Secret` must be set for OAuth2 authentication when either or both are absent.
62    ///
63    /// # Note
64    /// This function assumes that `client_id` and `client_secret` are optional fields.
65    /// Ensure they are properly configured before invoking this function.
66    pub fn get_client_credentials(&self) -> Result<(String, String), HttpError> {
67        if self.client_id.is_some() && self.client_secret.is_some() {
68            Ok((
69                self.client_id.clone().unwrap(),
70                self.client_secret.clone().unwrap(),
71            ))
72        } else {
73            Err(HttpError::ConfigError(
74                "Client ID and Client Secret must be set for OAuth2 authentication".into(),
75            ))
76        }
77    }
78}
79
80impl Default for ApiCredentials {
81    fn default() -> Self {
82        dotenv::dotenv().ok();
83        let client_id = env::var("DERIBIT_CLIENT_ID").ok();
84        let client_secret = env::var("DERIBIT_CLIENT_SECRET").ok();
85        Self {
86            client_id,
87            client_secret,
88        }
89    }
90}