#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OkxChannelType {
Public,
Private,
Business,
}
impl std::fmt::Display for OkxChannelType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
OkxChannelType::Public => write!(f, "public"),
OkxChannelType::Private => write!(f, "private"),
OkxChannelType::Business => write!(f, "business"),
}
}
}
pub trait OkxEndpointRouter {
fn rest_endpoint(&self) -> &'static str;
fn ws_endpoint(&self, channel_type: OkxChannelType) -> &str;
fn is_demo_trading(&self) -> bool;
}
use super::Okx;
impl OkxEndpointRouter for Okx {
fn rest_endpoint(&self) -> &'static str {
"https://www.okx.com"
}
fn ws_endpoint(&self, channel_type: OkxChannelType) -> &str {
if self.is_testnet_trading() {
match channel_type {
OkxChannelType::Public => "wss://wspap.okx.com:8443/ws/v5/public?brokerId=9999",
OkxChannelType::Private => "wss://wspap.okx.com:8443/ws/v5/private?brokerId=9999",
OkxChannelType::Business => "wss://wspap.okx.com:8443/ws/v5/business?brokerId=9999",
}
} else {
match channel_type {
OkxChannelType::Public => "wss://ws.okx.com:8443/ws/v5/public",
OkxChannelType::Private => "wss://ws.okx.com:8443/ws/v5/private",
OkxChannelType::Business => "wss://ws.okx.com:8443/ws/v5/business",
}
}
}
fn is_demo_trading(&self) -> bool {
self.is_testnet_trading()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::okx::OkxOptions;
use ccxt_core::ExchangeConfig;
fn create_test_okx() -> Okx {
Okx::new(ExchangeConfig::default()).unwrap()
}
fn create_demo_okx() -> Okx {
let config = ExchangeConfig {
sandbox: true,
..Default::default()
};
Okx::new(config).unwrap()
}
#[test]
fn test_rest_endpoint_production() {
let okx = create_test_okx();
let url = okx.rest_endpoint();
assert_eq!(url, "https://www.okx.com");
}
#[test]
fn test_rest_endpoint_demo() {
let okx = create_demo_okx();
let url = okx.rest_endpoint();
assert_eq!(url, "https://www.okx.com");
}
#[test]
fn test_ws_endpoint_public_production() {
let okx = create_test_okx();
let url = okx.ws_endpoint(OkxChannelType::Public);
assert_eq!(url, "wss://ws.okx.com:8443/ws/v5/public");
assert!(!url.contains("brokerId"));
}
#[test]
fn test_ws_endpoint_public_demo() {
let okx = create_demo_okx();
let url = okx.ws_endpoint(OkxChannelType::Public);
assert!(url.contains("wspap.okx.com"));
assert!(url.contains("/ws/v5/public"));
assert!(url.contains("brokerId=9999"));
}
#[test]
fn test_ws_endpoint_private_production() {
let okx = create_test_okx();
let url = okx.ws_endpoint(OkxChannelType::Private);
assert_eq!(url, "wss://ws.okx.com:8443/ws/v5/private");
assert!(!url.contains("brokerId"));
}
#[test]
fn test_ws_endpoint_private_demo() {
let okx = create_demo_okx();
let url = okx.ws_endpoint(OkxChannelType::Private);
assert!(url.contains("wspap.okx.com"));
assert!(url.contains("/ws/v5/private"));
assert!(url.contains("brokerId=9999"));
}
#[test]
fn test_ws_endpoint_business_production() {
let okx = create_test_okx();
let url = okx.ws_endpoint(OkxChannelType::Business);
assert_eq!(url, "wss://ws.okx.com:8443/ws/v5/business");
assert!(!url.contains("brokerId"));
}
#[test]
fn test_ws_endpoint_business_demo() {
let okx = create_demo_okx();
let url = okx.ws_endpoint(OkxChannelType::Business);
assert!(url.contains("wspap.okx.com"));
assert!(url.contains("/ws/v5/business"));
assert!(url.contains("brokerId=9999"));
}
#[test]
fn test_is_demo_trading_false_by_default() {
let okx = create_test_okx();
assert!(!okx.is_demo_trading());
}
#[test]
fn test_is_demo_trading_with_sandbox_config() {
let okx = create_demo_okx();
assert!(okx.is_demo_trading());
}
#[test]
fn test_is_demo_trading_with_testnet_option() {
let config = ExchangeConfig::default();
let options = OkxOptions {
testnet: true,
..Default::default()
};
let okx = Okx::new_with_options(config, options).unwrap();
assert!(okx.is_demo_trading());
}
#[test]
fn test_channel_type_display() {
assert_eq!(format!("{}", OkxChannelType::Public), "public");
assert_eq!(format!("{}", OkxChannelType::Private), "private");
assert_eq!(format!("{}", OkxChannelType::Business), "business");
}
#[test]
fn test_channel_type_equality() {
assert_eq!(OkxChannelType::Public, OkxChannelType::Public);
assert_eq!(OkxChannelType::Private, OkxChannelType::Private);
assert_eq!(OkxChannelType::Business, OkxChannelType::Business);
assert_ne!(OkxChannelType::Public, OkxChannelType::Private);
assert_ne!(OkxChannelType::Private, OkxChannelType::Business);
}
#[test]
fn test_all_channel_types_production() {
let okx = create_test_okx();
let channels = [
(OkxChannelType::Public, "/ws/v5/public"),
(OkxChannelType::Private, "/ws/v5/private"),
(OkxChannelType::Business, "/ws/v5/business"),
];
for (channel_type, expected_path) in channels {
let url = okx.ws_endpoint(channel_type);
assert!(
url.contains(expected_path),
"URL {} should contain {}",
url,
expected_path
);
assert!(
url.contains("ws.okx.com"),
"Production URL {} should contain ws.okx.com",
url
);
}
}
#[test]
fn test_all_channel_types_demo() {
let okx = create_demo_okx();
let channels = [
(OkxChannelType::Public, "/ws/v5/public"),
(OkxChannelType::Private, "/ws/v5/private"),
(OkxChannelType::Business, "/ws/v5/business"),
];
for (channel_type, expected_path) in channels {
let url = okx.ws_endpoint(channel_type);
assert!(
url.contains(expected_path),
"URL {} should contain {}",
url,
expected_path
);
assert!(
url.contains("wspap.okx.com"),
"Demo URL {} should contain wspap.okx.com",
url
);
assert!(
url.contains("brokerId=9999"),
"Demo URL {} should contain brokerId=9999",
url
);
}
}
#[test]
fn test_rest_endpoint_same_for_production_and_demo() {
let okx_prod = create_test_okx();
let okx_demo = create_demo_okx();
assert_eq!(okx_prod.rest_endpoint(), okx_demo.rest_endpoint());
}
#[test]
fn test_ws_endpoints_differ_for_production_and_demo() {
let okx_prod = create_test_okx();
let okx_demo = create_demo_okx();
assert_ne!(
okx_prod.ws_endpoint(OkxChannelType::Public),
okx_demo.ws_endpoint(OkxChannelType::Public)
);
assert_ne!(
okx_prod.ws_endpoint(OkxChannelType::Private),
okx_demo.ws_endpoint(OkxChannelType::Private)
);
assert_ne!(
okx_prod.ws_endpoint(OkxChannelType::Business),
okx_demo.ws_endpoint(OkxChannelType::Business)
);
}
}