deribit_http/model/api_key.rs
1//! API key management models and types
2
3use serde::{Deserialize, Serialize};
4use serde_with::skip_serializing_none;
5
6/// API key information returned by API key management endpoints.
7///
8/// Contains all details about an API key including credentials,
9/// permissions, and configuration.
10#[skip_serializing_none]
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct ApiKeyInfo {
13 /// Unique identifier for the API key
14 pub id: u64,
15 /// Client identifier used for authentication
16 pub client_id: String,
17 /// Client secret or MD5 fingerprint of public key used for authentication
18 pub client_secret: String,
19 /// API key name that can be displayed in transaction log
20 pub name: String,
21 /// Describes maximal access for tokens generated with this key.
22 ///
23 /// Possible values include combinations of:
24 /// - `trade:[read, read_write, none]`
25 /// - `wallet:[read, read_write, none]`
26 /// - `account:[read, read_write, none]`
27 /// - `block_trade:[read, read_write, none]`
28 /// - `block_rfq:[read, read_write, none]`
29 pub max_scope: String,
30 /// Whether the API key is enabled and can be used for authentication
31 pub enabled: bool,
32 /// Whether this API key is the default (deprecated, will be removed)
33 pub default: bool,
34 /// Timestamp when the key was created or last modified, in milliseconds since Unix epoch
35 pub timestamp: u64,
36 /// List of enabled advanced on-key features.
37 ///
38 /// Available options:
39 /// - `restricted_block_trades`: Limit block_trade read scope to trades made with this key
40 /// - `block_trade_approval`: Block trades require additional user approval
41 #[serde(default)]
42 pub enabled_features: Vec<String>,
43 /// List of IP addresses whitelisted for this key
44 #[serde(default)]
45 pub ip_whitelist: Option<Vec<String>>,
46 /// PEM encoded public key (Ed25519/RSA) used for asymmetric signatures
47 pub public_key: Option<String>,
48}
49
50/// Request parameters for creating a new API key.
51///
52/// # Example
53///
54/// ```rust
55/// use deribit_http::model::CreateApiKeyRequest;
56///
57/// let request = CreateApiKeyRequest {
58/// max_scope: "account:read trade:read_write".to_string(),
59/// name: Some("my_trading_key".to_string()),
60/// ..Default::default()
61/// };
62/// ```
63#[derive(Debug, Clone, Default)]
64pub struct CreateApiKeyRequest {
65 /// Describes maximal access for tokens generated with this key.
66 ///
67 /// Required. Possible values include combinations of:
68 /// - `trade:[read, read_write, none]`
69 /// - `wallet:[read, read_write, none]`
70 /// - `account:[read, read_write, none]`
71 /// - `block_trade:[read, read_write, none]`
72 pub max_scope: String,
73 /// Name of key (only letters, numbers and underscores; max 16 characters)
74 pub name: Option<String>,
75 /// ED25519 or RSA PEM encoded public key for asymmetric API key authentication
76 pub public_key: Option<String>,
77 /// List of enabled advanced on-key features.
78 ///
79 /// Available options:
80 /// - `restricted_block_trades`
81 /// - `block_trade_approval`
82 pub enabled_features: Option<Vec<String>>,
83}
84
85/// Request parameters for editing an existing API key.
86///
87/// At least one optional parameter must be provided along with the required fields.
88///
89/// # Example
90///
91/// ```rust
92/// use deribit_http::model::EditApiKeyRequest;
93///
94/// let request = EditApiKeyRequest {
95/// id: 123,
96/// max_scope: "account:read_write trade:read_write".to_string(),
97/// name: Some("updated_key_name".to_string()),
98/// ..Default::default()
99/// };
100/// ```
101#[derive(Debug, Clone, Default)]
102pub struct EditApiKeyRequest {
103 /// ID of the API key to edit
104 pub id: u64,
105 /// Describes maximal access for tokens generated with this key.
106 ///
107 /// Required. Possible values include combinations of:
108 /// - `trade:[read, read_write, none]`
109 /// - `wallet:[read, read_write, none]`
110 /// - `account:[read, read_write, none]`
111 /// - `block_trade:[read, read_write, none]`
112 pub max_scope: String,
113 /// Name of key (only letters, numbers and underscores; max 16 characters)
114 pub name: Option<String>,
115 /// Enable or disable the API key
116 pub enabled: Option<bool>,
117 /// List of enabled advanced on-key features
118 pub enabled_features: Option<Vec<String>>,
119 /// List of IP addresses to whitelist for this key
120 pub ip_whitelist: Option<Vec<String>>,
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_api_key_info_deserialization() {
129 let json = r#"{
130 "timestamp": 1560238048714,
131 "max_scope": "account:read block_trade:read_write trade:read wallet:none",
132 "id": 5,
133 "enabled": true,
134 "enabled_features": [],
135 "default": false,
136 "public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAM7FWhKquNqLmTOV4hfYT5r3AjrYiORTT6Tn5HIfFNV8=\n-----END PUBLIC KEY-----",
137 "client_secret": "9c:6d:c9:02:fd:9f:75:6e:14:bb:71:c5:74:95:86:c8",
138 "client_id": "wcVoQGam",
139 "name": ""
140 }"#;
141
142 let info: ApiKeyInfo = serde_json::from_str(json).expect("Failed to deserialize");
143 assert_eq!(info.id, 5);
144 assert_eq!(info.client_id, "wcVoQGam");
145 assert!(info.enabled);
146 assert!(!info.default);
147 assert!(info.public_key.is_some());
148 }
149
150 #[test]
151 fn test_api_key_info_list_deserialization() {
152 let json = r#"[
153 {
154 "timestamp": 1560236001108,
155 "max_scope": "account:read block_trade:read trade:read_write wallet:read",
156 "id": 1,
157 "enabled": false,
158 "default": false,
159 "client_secret": "SjM57m1T2CfXZ4vZ76X1APjqRlJdtzHI8IwVXoQnfoM",
160 "client_id": "TiA4AyLPq3",
161 "name": "",
162 "enabled_features": []
163 },
164 {
165 "timestamp": 1560236287708,
166 "max_scope": "account:read_write block_trade:read_write trade:read_write wallet:read_write",
167 "id": 2,
168 "enabled": true,
169 "default": true,
170 "client_secret": "mwNOvbUVyQczytQ5IVM8CbzmgqNJ81WvLKfu6MXcJPs",
171 "client_id": "aD-KFx-H",
172 "name": "",
173 "enabled_features": []
174 }
175 ]"#;
176
177 let keys: Vec<ApiKeyInfo> = serde_json::from_str(json).expect("Failed to deserialize");
178 assert_eq!(keys.len(), 2);
179 assert_eq!(keys[0].id, 1);
180 assert!(!keys[0].enabled);
181 assert_eq!(keys[1].id, 2);
182 assert!(keys[1].enabled);
183 }
184
185 #[test]
186 fn test_create_api_key_request_default() {
187 let request = CreateApiKeyRequest::default();
188 assert!(request.max_scope.is_empty());
189 assert!(request.name.is_none());
190 assert!(request.public_key.is_none());
191 assert!(request.enabled_features.is_none());
192 }
193
194 #[test]
195 fn test_edit_api_key_request_default() {
196 let request = EditApiKeyRequest::default();
197 assert_eq!(request.id, 0);
198 assert!(request.max_scope.is_empty());
199 assert!(request.name.is_none());
200 assert!(request.enabled.is_none());
201 }
202}