nautilus_binance/common/
urls.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! URL resolution helpers for Binance API endpoints.
17
18use super::{
19    consts::{
20        BINANCE_FUTURES_COIN_HTTP_URL, BINANCE_FUTURES_COIN_TESTNET_HTTP_URL,
21        BINANCE_FUTURES_COIN_TESTNET_WS_URL, BINANCE_FUTURES_COIN_WS_URL,
22        BINANCE_FUTURES_USD_HTTP_URL, BINANCE_FUTURES_USD_TESTNET_HTTP_URL,
23        BINANCE_FUTURES_USD_TESTNET_WS_URL, BINANCE_FUTURES_USD_WS_URL, BINANCE_OPTIONS_HTTP_URL,
24        BINANCE_OPTIONS_WS_URL, BINANCE_SPOT_HTTP_URL, BINANCE_SPOT_TESTNET_HTTP_URL,
25        BINANCE_SPOT_TESTNET_WS_URL, BINANCE_SPOT_WS_URL,
26    },
27    enums::{BinanceEnvironment, BinanceProductType},
28};
29
30/// Returns the HTTP base URL for the given product type and environment.
31#[must_use]
32pub fn get_http_base_url(
33    product_type: BinanceProductType,
34    environment: BinanceEnvironment,
35) -> &'static str {
36    match (product_type, environment) {
37        // Mainnet
38        (BinanceProductType::Spot | BinanceProductType::Margin, BinanceEnvironment::Mainnet) => {
39            BINANCE_SPOT_HTTP_URL
40        }
41        (BinanceProductType::UsdM, BinanceEnvironment::Mainnet) => BINANCE_FUTURES_USD_HTTP_URL,
42        (BinanceProductType::CoinM, BinanceEnvironment::Mainnet) => BINANCE_FUTURES_COIN_HTTP_URL,
43        (BinanceProductType::Options, BinanceEnvironment::Mainnet) => BINANCE_OPTIONS_HTTP_URL,
44
45        // Testnet
46        (BinanceProductType::Spot | BinanceProductType::Margin, BinanceEnvironment::Testnet) => {
47            BINANCE_SPOT_TESTNET_HTTP_URL
48        }
49        (BinanceProductType::UsdM, BinanceEnvironment::Testnet) => {
50            BINANCE_FUTURES_USD_TESTNET_HTTP_URL
51        }
52        (BinanceProductType::CoinM, BinanceEnvironment::Testnet) => {
53            BINANCE_FUTURES_COIN_TESTNET_HTTP_URL
54        }
55        // Options testnet not available, fall back to mainnet
56        (BinanceProductType::Options, BinanceEnvironment::Testnet) => BINANCE_OPTIONS_HTTP_URL,
57    }
58}
59
60/// Returns the WebSocket base URL for the given product type and environment.
61#[must_use]
62pub fn get_ws_base_url(
63    product_type: BinanceProductType,
64    environment: BinanceEnvironment,
65) -> &'static str {
66    match (product_type, environment) {
67        // Mainnet
68        (BinanceProductType::Spot | BinanceProductType::Margin, BinanceEnvironment::Mainnet) => {
69            BINANCE_SPOT_WS_URL
70        }
71        (BinanceProductType::UsdM, BinanceEnvironment::Mainnet) => BINANCE_FUTURES_USD_WS_URL,
72        (BinanceProductType::CoinM, BinanceEnvironment::Mainnet) => BINANCE_FUTURES_COIN_WS_URL,
73        (BinanceProductType::Options, BinanceEnvironment::Mainnet) => BINANCE_OPTIONS_WS_URL,
74
75        // Testnet
76        (BinanceProductType::Spot | BinanceProductType::Margin, BinanceEnvironment::Testnet) => {
77            BINANCE_SPOT_TESTNET_WS_URL
78        }
79        (BinanceProductType::UsdM, BinanceEnvironment::Testnet) => {
80            BINANCE_FUTURES_USD_TESTNET_WS_URL
81        }
82        (BinanceProductType::CoinM, BinanceEnvironment::Testnet) => {
83            BINANCE_FUTURES_COIN_TESTNET_WS_URL
84        }
85        // Options testnet not available, fall back to mainnet
86        (BinanceProductType::Options, BinanceEnvironment::Testnet) => BINANCE_OPTIONS_WS_URL,
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use rstest::rstest;
93
94    use super::*;
95
96    #[rstest]
97    fn test_http_url_spot_mainnet() {
98        let url = get_http_base_url(BinanceProductType::Spot, BinanceEnvironment::Mainnet);
99        assert_eq!(url, "https://api.binance.com");
100    }
101
102    #[rstest]
103    fn test_http_url_spot_testnet() {
104        let url = get_http_base_url(BinanceProductType::Spot, BinanceEnvironment::Testnet);
105        assert_eq!(url, "https://testnet.binance.vision");
106    }
107
108    #[rstest]
109    fn test_http_url_usdm_mainnet() {
110        let url = get_http_base_url(BinanceProductType::UsdM, BinanceEnvironment::Mainnet);
111        assert_eq!(url, "https://fapi.binance.com");
112    }
113
114    #[rstest]
115    fn test_http_url_coinm_mainnet() {
116        let url = get_http_base_url(BinanceProductType::CoinM, BinanceEnvironment::Mainnet);
117        assert_eq!(url, "https://dapi.binance.com");
118    }
119
120    #[rstest]
121    fn test_ws_url_spot_mainnet() {
122        let url = get_ws_base_url(BinanceProductType::Spot, BinanceEnvironment::Mainnet);
123        assert_eq!(url, "wss://stream.binance.com:9443/ws");
124    }
125
126    #[rstest]
127    fn test_ws_url_usdm_mainnet() {
128        let url = get_ws_base_url(BinanceProductType::UsdM, BinanceEnvironment::Mainnet);
129        assert_eq!(url, "wss://fstream.binance.com/ws");
130    }
131}