#![allow(dead_code)]
use std::env;
use std::sync::Once;
use rust_okx::{Credentials, Error, OkxClient, RestError};
fn load_dotenv() {
static INIT: Once = Once::new();
INIT.call_once(|| {
let _ = dotenvy::dotenv();
});
}
pub fn public_client() -> OkxClient {
OkxClient::builder().build()
}
pub fn live_client() -> Option<OkxClient> {
let creds = credentials("OKX_API_KEY", "OKX_API_SECRET", "OKX_PASSPHRASE")?;
Some(OkxClient::builder().credentials(creds).build())
}
pub fn demo_client() -> Option<OkxClient> {
let creds = credentials(
"OKX_DEMO_API_KEY",
"OKX_DEMO_API_SECRET",
"OKX_DEMO_PASSPHRASE",
)?;
Some(
OkxClient::builder()
.credentials(creds)
.demo_trading(true)
.build(),
)
}
fn credentials(key: &str, secret: &str, passphrase: &str) -> Option<Credentials> {
load_dotenv();
let key = non_empty(key)?;
let secret = non_empty(secret)?;
let passphrase = non_empty(passphrase)?;
Some(Credentials::new(key, secret, passphrase))
}
fn non_empty(var: &str) -> Option<String> {
env::var(var).ok().filter(|v| !v.is_empty())
}
pub fn live_client_or_skip(test: &str) -> Option<OkxClient> {
let client = live_client();
if client.is_none() {
eprintln!("skipping {test}: OKX_API_* env vars not set");
}
client
}
pub fn env_non_empty(var: &str) -> Option<String> {
load_dotenv();
non_empty(var)
}
pub fn expect_ok_or_api_unavailable<T>(result: Result<T, Error>, endpoint: &str) {
match result {
Ok(_) => {}
Err(Error::Rest(RestError::Okx { code, message, .. })) => {
eprintln!("skipping {endpoint}: OKX returned {code} {message}");
}
Err(error) => panic!("{endpoint} failed: {error}"),
}
}
pub fn ok_or_skip<T>(result: Result<T, Error>, label: &str) -> Option<T> {
match result {
Ok(v) => Some(v),
Err(Error::Rest(RestError::HttpStatus { status, .. })) if status.is_server_error() => {
eprintln!("skipping {label}: OKX returned HTTP {status}");
None
}
Err(e) => panic!("{label}: {e}"),
}
}