Skip to main content

bybit/models/
auth_response.rs

1use crate::prelude::*;
2
3/// Enum representing WebSocket authentication responses.
4///
5/// Encapsulates authentication responses for different WebSocket connection types
6/// (private streams and trade streams). Bots use this to verify authentication
7/// success and handle authentication failures appropriately.
8#[derive(Debug, Serialize, Deserialize, Clone)]
9#[serde(untagged)]
10pub enum AuthResponse {
11    /// Authentication response for private WebSocket streams.
12    ///
13    /// Used for private data streams (position, execution, order, wallet updates).
14    /// Bots should check the `success` field to confirm authentication.
15    PrivateAuth(PrivateAuthData),
16
17    /// Authentication response for trade WebSocket streams.
18    ///
19    /// Used for trade/order entry streams. Has a different format than private streams.
20    /// Bots should check the `ret_code` field (0 for success).
21    TradeAuth(TradeAuthData),
22}
23
24/// Authentication data for private WebSocket streams.
25#[derive(Debug, Serialize, Deserialize, Clone)]
26pub struct PrivateAuthData {
27    /// Whether authentication was successful.
28    ///
29    /// `true` if authentication succeeded, `false` otherwise.
30    /// Bots should check this field before proceeding with private stream operations.
31    pub success: bool,
32
33    /// Return message from authentication.
34    ///
35    /// Typically empty string for success, error message for failure.
36    /// Bots should log this for debugging authentication issues.
37    #[serde(rename = "ret_msg")]
38    pub ret_msg: String,
39
40    /// Operation type, always "auth" for authentication responses.
41    ///
42    /// Bots use this to identify the message type.
43    pub op: String,
44
45    /// Connection ID for the authenticated WebSocket connection.
46    ///
47    /// A unique identifier for the WebSocket connection.
48    /// Bots can use this to track specific connections.
49    #[serde(rename = "conn_id")]
50    pub conn_id: String,
51
52    /// Request ID (optional).
53    ///
54    /// The ID of the authentication request, if provided.
55    /// Bots can use this to correlate requests and responses.
56    #[serde(rename = "req_id")]
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub req_id: Option<String>,
59}
60
61/// Authentication data for trade WebSocket streams.
62#[derive(Debug, Serialize, Deserialize, Clone)]
63pub struct TradeAuthData {
64    /// Return code from authentication.
65    ///
66    /// `0` for success, non-zero for errors.
67    /// Common error codes:
68    /// - `10004`: invalid signature
69    /// - `10001`: parameter error
70    /// - `20001`: repeat authentication
71    /// Bots should check this field before proceeding with trade operations.
72    #[serde(rename = "retCode")]
73    pub ret_code: i32,
74
75    /// Return message from authentication.
76    ///
77    /// "OK" for success, error message for failure.
78    /// Bots should log this for debugging authentication issues.
79    #[serde(rename = "retMsg")]
80    pub ret_msg: String,
81
82    /// Operation type, always "auth" for authentication responses.
83    ///
84    /// Bots use this to identify the message type.
85    pub op: String,
86
87    /// Connection ID for the authenticated WebSocket connection.
88    ///
89    /// A unique identifier for the WebSocket connection.
90    /// Bots can use this to track specific connections.
91    #[serde(rename = "connId")]
92    pub conn_id: String,
93
94    /// Request ID (optional).
95    ///
96    /// The ID of the authentication request, if provided.
97    /// Bots can use this to correlate requests and responses.
98    #[serde(rename = "reqId")]
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub req_id: Option<String>,
101}
102
103impl PrivateAuthData {
104    /// Creates a new PrivateAuthData instance.
105    pub fn new(success: bool, ret_msg: &str, conn_id: &str, req_id: Option<&str>) -> Self {
106        Self {
107            success,
108            ret_msg: ret_msg.to_string(),
109            op: "auth".to_string(),
110            conn_id: conn_id.to_string(),
111            req_id: req_id.map(|s| s.to_string()),
112        }
113    }
114
115    /// Returns true if authentication was successful.
116    pub fn is_success(&self) -> bool {
117        self.success
118    }
119
120    /// Returns true if authentication failed.
121    pub fn is_failure(&self) -> bool {
122        !self.success
123    }
124}
125
126impl TradeAuthData {
127    /// Creates a new TradeAuthData instance.
128    pub fn new(ret_code: i32, ret_msg: &str, conn_id: &str, req_id: Option<&str>) -> Self {
129        Self {
130            ret_code,
131            ret_msg: ret_msg.to_string(),
132            op: "auth".to_string(),
133            conn_id: conn_id.to_string(),
134            req_id: req_id.map(|s| s.to_string()),
135        }
136    }
137
138    /// Returns true if authentication was successful (ret_code == 0).
139    pub fn is_success(&self) -> bool {
140        self.ret_code == 0
141    }
142
143    /// Returns true if authentication failed (ret_code != 0).
144    pub fn is_failure(&self) -> bool {
145        self.ret_code != 0
146    }
147
148    /// Returns the authentication error code if authentication failed.
149    pub fn error_code(&self) -> Option<i32> {
150        if self.is_failure() {
151            Some(self.ret_code)
152        } else {
153            None
154        }
155    }
156}
157
158impl AuthResponse {
159    /// Returns true if authentication was successful.
160    pub fn is_success(&self) -> bool {
161        match self {
162            AuthResponse::PrivateAuth(data) => data.is_success(),
163            AuthResponse::TradeAuth(data) => data.is_success(),
164        }
165    }
166
167    /// Returns true if authentication failed.
168    pub fn is_failure(&self) -> bool {
169        !self.is_success()
170    }
171
172    /// Returns the connection ID from the authentication response.
173    pub fn conn_id(&self) -> &str {
174        match self {
175            AuthResponse::PrivateAuth(data) => &data.conn_id,
176            AuthResponse::TradeAuth(data) => &data.conn_id,
177        }
178    }
179
180    /// Returns the return message from the authentication response.
181    pub fn ret_msg(&self) -> &str {
182        match self {
183            AuthResponse::PrivateAuth(data) => &data.ret_msg,
184            AuthResponse::TradeAuth(data) => &data.ret_msg,
185        }
186    }
187
188    /// Returns the error code if authentication failed.
189    pub fn error_code(&self) -> Option<i32> {
190        match self {
191            AuthResponse::PrivateAuth(data) => {
192                if data.is_failure() {
193                    // For private auth, we don't have a numeric error code
194                    // Return -1 to indicate failure without specific code
195                    Some(-1)
196                } else {
197                    None
198                }
199            }
200            AuthResponse::TradeAuth(data) => data.error_code(),
201        }
202    }
203}