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