rust-okx 0.3.0

Async Rust client for the OKX v5 REST API
Documentation
//! Integration tests for Convert endpoints.

mod common;

use std::env;

use common::live_client;
use rust_okx::OkxClient;
use rust_okx::api::convert::{ConvertHistoryRequest, ConvertQuoteRequest, ConvertTradeRequest};

fn 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
}

fn env_non_empty(var: &str) -> Option<String> {
    let _ = dotenvy::dotenv();
    env::var(var).ok().filter(|value| !value.is_empty())
}

fn mutation_enabled(test: &str) -> bool {
    let _ = dotenvy::dotenv();
    let enabled = env::var("OKX_ENABLE_CONVERT_MUTATION").as_deref() == Ok("1");
    if !enabled {
        eprintln!("skipping {test}: set OKX_ENABLE_CONVERT_MUTATION=1");
    }
    enabled
}

#[tokio::test]
async fn convert_read_only_live() {
    let Some(client) = client_or_skip("convert_read_only_live") else {
        return;
    };

    let _ = client
        .convert()
        .get_currencies()
        .await
        .expect("convert/currencies");
    let _ = client
        .convert()
        .get_currency_pair(Some("BTC"), Some("USDT"))
        .await
        .expect("convert/currency-pair");
    let _ = client
        .convert()
        .get_convert_history(&ConvertHistoryRequest::new().param("limit", "10"))
        .await
        .expect("convert/history");
}

#[tokio::test]
async fn convert_quote_and_trade_live_when_enabled() {
    let Some(client) = client_or_skip("convert_quote_and_trade_live_when_enabled") else {
        return;
    };
    if !mutation_enabled("convert_quote_and_trade_live_when_enabled") {
        return;
    }

    let from_ccy = env_non_empty("OKX_TEST_CONVERT_FROM_CCY").expect("from ccy");
    let to_ccy = env_non_empty("OKX_TEST_CONVERT_TO_CCY").expect("to ccy");
    let side = env_non_empty("OKX_TEST_CONVERT_SIDE").expect("side");
    let amount = env_non_empty("OKX_TEST_CONVERT_AMOUNT").expect("amount");
    let quote = ConvertQuoteRequest::new()
        .param("baseCcy", from_ccy)
        .param("quoteCcy", to_ccy)
        .param("side", side)
        .param("rfqSz", amount);

    let quotes = client
        .convert()
        .estimate_quote(&quote)
        .await
        .expect("convert/estimate-quote");

    let quote_id = env_non_empty("OKX_TEST_CONVERT_QUOTE_ID")
        .or_else(|| quotes.first().map(|row| row.quote_id.clone()))
        .expect("quote id");
    let trade = ConvertTradeRequest::new().param("quoteId", quote_id);
    let _ = client
        .convert()
        .convert_trade(&trade)
        .await
        .expect("convert/trade");
}