1use crate::common::enums::{OKXEnvironment, OKXRegion};
19
20const OKX_HTTP_URL: &str = "https://www.okx.com";
22const OKX_WS_PUBLIC_URL: &str = "wss://ws.okx.com:8443/ws/v5/public";
23const OKX_WS_PRIVATE_URL: &str = "wss://ws.okx.com:8443/ws/v5/private";
24const OKX_WS_BUSINESS_URL: &str = "wss://ws.okx.com:8443/ws/v5/business";
25const OKX_DEMO_WS_PUBLIC_URL: &str = "wss://wspap.okx.com:8443/ws/v5/public";
26const OKX_DEMO_WS_PRIVATE_URL: &str = "wss://wspap.okx.com:8443/ws/v5/private";
27const OKX_DEMO_WS_BUSINESS_URL: &str = "wss://wspap.okx.com:8443/ws/v5/business";
28
29const OKX_EEA_HTTP_URL: &str = "https://eea.okx.com";
31const OKX_EEA_WS_PUBLIC_URL: &str = "wss://wseea.okx.com:8443/ws/v5/public";
32const OKX_EEA_WS_PRIVATE_URL: &str = "wss://wseea.okx.com:8443/ws/v5/private";
33const OKX_EEA_WS_BUSINESS_URL: &str = "wss://wseea.okx.com:8443/ws/v5/business";
34const OKX_EEA_DEMO_WS_PUBLIC_URL: &str = "wss://wseeapap.okx.com:8443/ws/v5/public";
35const OKX_EEA_DEMO_WS_PRIVATE_URL: &str = "wss://wseeapap.okx.com:8443/ws/v5/private";
36const OKX_EEA_DEMO_WS_BUSINESS_URL: &str = "wss://wseeapap.okx.com:8443/ws/v5/business";
37
38const OKX_US_HTTP_URL: &str = "https://us.okx.com";
40const OKX_US_WS_PUBLIC_URL: &str = "wss://wsus.okx.com:8443/ws/v5/public";
41const OKX_US_WS_PRIVATE_URL: &str = "wss://wsus.okx.com:8443/ws/v5/private";
42const OKX_US_WS_BUSINESS_URL: &str = "wss://wsus.okx.com:8443/ws/v5/business";
43const OKX_US_DEMO_WS_PUBLIC_URL: &str = "wss://wsuspap.okx.com:8443/ws/v5/public";
44const OKX_US_DEMO_WS_PRIVATE_URL: &str = "wss://wsuspap.okx.com:8443/ws/v5/private";
45const OKX_US_DEMO_WS_BUSINESS_URL: &str = "wss://wsuspap.okx.com:8443/ws/v5/business";
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum OKXEndpointType {
50 Public,
51 Private,
52 Business,
53}
54
55pub fn requires_authentication(endpoint_type: OKXEndpointType) -> bool {
57 matches!(
58 endpoint_type,
59 OKXEndpointType::Private | OKXEndpointType::Business
60 )
61}
62
63#[must_use]
68pub const fn get_http_base_url(region: OKXRegion) -> &'static str {
69 match region {
70 OKXRegion::Global => OKX_HTTP_URL,
71 OKXRegion::Eea => OKX_EEA_HTTP_URL,
72 OKXRegion::Us => OKX_US_HTTP_URL,
73 }
74}
75
76#[must_use]
78pub fn get_ws_base_url_public(region: OKXRegion, environment: OKXEnvironment) -> &'static str {
79 match (region, environment) {
80 (OKXRegion::Global, OKXEnvironment::Live) => OKX_WS_PUBLIC_URL,
81 (OKXRegion::Global, OKXEnvironment::Demo) => OKX_DEMO_WS_PUBLIC_URL,
82 (OKXRegion::Eea, OKXEnvironment::Live) => OKX_EEA_WS_PUBLIC_URL,
83 (OKXRegion::Eea, OKXEnvironment::Demo) => OKX_EEA_DEMO_WS_PUBLIC_URL,
84 (OKXRegion::Us, OKXEnvironment::Live) => OKX_US_WS_PUBLIC_URL,
85 (OKXRegion::Us, OKXEnvironment::Demo) => OKX_US_DEMO_WS_PUBLIC_URL,
86 }
87}
88
89#[must_use]
91pub fn get_ws_base_url_private(region: OKXRegion, environment: OKXEnvironment) -> &'static str {
92 match (region, environment) {
93 (OKXRegion::Global, OKXEnvironment::Live) => OKX_WS_PRIVATE_URL,
94 (OKXRegion::Global, OKXEnvironment::Demo) => OKX_DEMO_WS_PRIVATE_URL,
95 (OKXRegion::Eea, OKXEnvironment::Live) => OKX_EEA_WS_PRIVATE_URL,
96 (OKXRegion::Eea, OKXEnvironment::Demo) => OKX_EEA_DEMO_WS_PRIVATE_URL,
97 (OKXRegion::Us, OKXEnvironment::Live) => OKX_US_WS_PRIVATE_URL,
98 (OKXRegion::Us, OKXEnvironment::Demo) => OKX_US_DEMO_WS_PRIVATE_URL,
99 }
100}
101
102#[must_use]
104pub fn get_ws_base_url_business(region: OKXRegion, environment: OKXEnvironment) -> &'static str {
105 match (region, environment) {
106 (OKXRegion::Global, OKXEnvironment::Live) => OKX_WS_BUSINESS_URL,
107 (OKXRegion::Global, OKXEnvironment::Demo) => OKX_DEMO_WS_BUSINESS_URL,
108 (OKXRegion::Eea, OKXEnvironment::Live) => OKX_EEA_WS_BUSINESS_URL,
109 (OKXRegion::Eea, OKXEnvironment::Demo) => OKX_EEA_DEMO_WS_BUSINESS_URL,
110 (OKXRegion::Us, OKXEnvironment::Live) => OKX_US_WS_BUSINESS_URL,
111 (OKXRegion::Us, OKXEnvironment::Demo) => OKX_US_DEMO_WS_BUSINESS_URL,
112 }
113}
114
115#[must_use]
121pub fn derive_ws_url(base_url: &str, channel: &str) -> String {
122 let url = base_url.trim_end_matches('/');
123 for suffix in ["/public", "/private", "/business"] {
124 if let Some(base) = url.strip_suffix(suffix) {
125 return format!("{base}/{channel}");
126 }
127 }
128 format!("{url}/{channel}")
129}
130
131#[must_use]
133pub fn get_ws_url(
134 endpoint_type: OKXEndpointType,
135 region: OKXRegion,
136 environment: OKXEnvironment,
137) -> &'static str {
138 match endpoint_type {
139 OKXEndpointType::Public => get_ws_base_url_public(region, environment),
140 OKXEndpointType::Private => get_ws_base_url_private(region, environment),
141 OKXEndpointType::Business => get_ws_base_url_business(region, environment),
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use rstest::rstest;
148
149 use super::*;
150
151 #[rstest]
152 fn test_endpoint_authentication() {
153 assert!(!requires_authentication(OKXEndpointType::Public));
154 assert!(requires_authentication(OKXEndpointType::Private));
155 assert!(requires_authentication(OKXEndpointType::Business));
156 }
157
158 #[rstest]
159 #[case(OKXRegion::Global, "https://www.okx.com")]
160 #[case(OKXRegion::Eea, "https://eea.okx.com")]
161 #[case(OKXRegion::Us, "https://us.okx.com")]
162 fn test_http_base_url(#[case] region: OKXRegion, #[case] expected: &str) {
163 assert_eq!(get_http_base_url(region), expected);
164 }
165
166 #[rstest]
167 #[case(
168 OKXRegion::Global,
169 "wss://ws.okx.com:8443/ws/v5/public",
170 "wss://ws.okx.com:8443/ws/v5/private",
171 "wss://ws.okx.com:8443/ws/v5/business"
172 )]
173 #[case(
174 OKXRegion::Eea,
175 "wss://wseea.okx.com:8443/ws/v5/public",
176 "wss://wseea.okx.com:8443/ws/v5/private",
177 "wss://wseea.okx.com:8443/ws/v5/business"
178 )]
179 #[case(
180 OKXRegion::Us,
181 "wss://wsus.okx.com:8443/ws/v5/public",
182 "wss://wsus.okx.com:8443/ws/v5/private",
183 "wss://wsus.okx.com:8443/ws/v5/business"
184 )]
185 fn test_ws_urls_live(
186 #[case] region: OKXRegion,
187 #[case] public: &str,
188 #[case] private: &str,
189 #[case] business: &str,
190 ) {
191 assert_eq!(get_ws_base_url_public(region, OKXEnvironment::Live), public);
192 assert_eq!(
193 get_ws_base_url_private(region, OKXEnvironment::Live),
194 private
195 );
196 assert_eq!(
197 get_ws_base_url_business(region, OKXEnvironment::Live),
198 business
199 );
200 }
201
202 #[rstest]
203 #[case(
204 OKXRegion::Global,
205 "wss://wspap.okx.com:8443/ws/v5/public",
206 "wss://wspap.okx.com:8443/ws/v5/private",
207 "wss://wspap.okx.com:8443/ws/v5/business"
208 )]
209 #[case(
210 OKXRegion::Eea,
211 "wss://wseeapap.okx.com:8443/ws/v5/public",
212 "wss://wseeapap.okx.com:8443/ws/v5/private",
213 "wss://wseeapap.okx.com:8443/ws/v5/business"
214 )]
215 #[case(
216 OKXRegion::Us,
217 "wss://wsuspap.okx.com:8443/ws/v5/public",
218 "wss://wsuspap.okx.com:8443/ws/v5/private",
219 "wss://wsuspap.okx.com:8443/ws/v5/business"
220 )]
221 fn test_ws_urls_demo(
222 #[case] region: OKXRegion,
223 #[case] public: &str,
224 #[case] private: &str,
225 #[case] business: &str,
226 ) {
227 assert_eq!(get_ws_base_url_public(region, OKXEnvironment::Demo), public);
228 assert_eq!(
229 get_ws_base_url_private(region, OKXEnvironment::Demo),
230 private
231 );
232 assert_eq!(
233 get_ws_base_url_business(region, OKXEnvironment::Demo),
234 business
235 );
236 }
237
238 #[rstest]
239 #[case(
240 "wss://ws.okx.com:8443/ws/v5/public",
241 "business",
242 "wss://ws.okx.com:8443/ws/v5/business"
243 )]
244 #[case(
245 "wss://wseea.okx.com:8443/ws/v5/public",
246 "private",
247 "wss://wseea.okx.com:8443/ws/v5/private"
248 )]
249 #[case(
250 "wss://wseea.okx.com:8443/ws/v5/private",
251 "business",
252 "wss://wseea.okx.com:8443/ws/v5/business"
253 )]
254 #[case(
255 "wss://wseea.okx.com:8443/ws/v5/private/",
256 "business",
257 "wss://wseea.okx.com:8443/ws/v5/business"
258 )]
259 #[case(
260 "wss://custom.proxy:8443/ws/v5",
261 "business",
262 "wss://custom.proxy:8443/ws/v5/business"
263 )]
264 fn test_derive_ws_url(#[case] base_url: &str, #[case] channel: &str, #[case] expected: &str) {
265 assert_eq!(derive_ws_url(base_url, channel), expected);
266 }
267
268 #[rstest]
269 #[case(OKXRegion::Global)]
270 #[case(OKXRegion::Eea)]
271 #[case(OKXRegion::Us)]
272 fn test_get_ws_url_by_type(#[case] region: OKXRegion) {
273 assert_eq!(
274 get_ws_url(OKXEndpointType::Public, region, OKXEnvironment::Live),
275 get_ws_base_url_public(region, OKXEnvironment::Live)
276 );
277 assert_eq!(
278 get_ws_url(OKXEndpointType::Private, region, OKXEnvironment::Live),
279 get_ws_base_url_private(region, OKXEnvironment::Live)
280 );
281 assert_eq!(
282 get_ws_url(OKXEndpointType::Business, region, OKXEnvironment::Live),
283 get_ws_base_url_business(region, OKXEnvironment::Live)
284 );
285 }
286}