From eac25be5b2c4ced70f55b0b3a05dadeb335b05a4 Mon Sep 17 00:00:00 2001 From: floor-licker Date: Tue, 28 Apr 2026 10:05:22 -0300 Subject: [PATCH] test: support live DNS override and credential aliases --- docs/TESTING.md | 13 +++++++++++++ src/client.rs | 29 ++++++++++++++++++++++++++--- tests/common/mod.rs | 8 ++++++-- tests/integration_tests.rs | 8 ++++++-- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/docs/TESTING.md b/docs/TESTING.md index 73102df..9edbee5 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -45,9 +45,17 @@ export POLYMARKET_API_KEY="your_api_key" export POLYMARKET_API_SECRET="your_api_secret" export POLYMARKET_API_PASSPHRASE="your_passphrase" +# Backward-compatible aliases also accepted by test helpers +export POLYMARKET_SECRET="your_api_secret" +export POLYMARKET_PASSPHRASE="your_passphrase" + # Optional (defaults provided in test helpers) export POLYMARKET_HOST="https://clob.polymarket.com" export POLYMARKET_CHAIN_ID="137" + +# Optional: pin clob.polymarket.com to a known A record if local DNS is blocked. +# Keep the hostname in POLYMARKET_HOST so HTTPS/SNI still validates. +export POLYMARKET_RESOLVE_IP="104.18.34.205" ``` #### 2. Run Integration Tests @@ -126,6 +134,11 @@ curl -I https://clob.polymarket.com/ # Check DNS resolution nslookup clob.polymarket.com + +# If local DNS fails but outbound HTTPS works, get a current A record and pin it: +curl -sS -H 'accept:application/dns-json' \ + 'https://cloudflare-dns.com/dns-query?name=clob.polymarket.com&type=A' +export POLYMARKET_RESOLVE_IP="104.18.34.205" ``` #### Authentication Issues diff --git a/src/client.rs b/src/client.rs index 4524c95..75b2360 100644 --- a/src/client.rs +++ b/src/client.rs @@ -19,6 +19,7 @@ use reqwest::{Method, RequestBuilder}; use rust_decimal::prelude::FromPrimitive; use rust_decimal::Decimal; use serde_json::Value; +use std::net::{IpAddr, SocketAddr}; use std::str::FromStr; use std::time::Duration; @@ -30,7 +31,11 @@ struct MarketByTokenResponse { condition_id: String, } -fn build_http_client(timeout: Option, max_connections: Option) -> Client { +fn build_http_client( + host: &str, + timeout: Option, + max_connections: Option, +) -> Client { let max_connections = max_connections.unwrap_or(10); let mut builder = reqwest::ClientBuilder::new() .no_proxy() @@ -44,6 +49,14 @@ fn build_http_client(timeout: Option, max_connections: Option) builder = builder.timeout(timeout); } + if let Ok(resolve_ip) = std::env::var("POLYMARKET_RESOLVE_IP") { + if let Ok(ip) = resolve_ip.parse::() { + if let Some(hostname) = extract_hostname(host) { + builder = builder.resolve(hostname, SocketAddr::new(ip, 443)); + } + } + } + builder.build().unwrap_or_else(|_| { reqwest::ClientBuilder::new() .no_proxy() @@ -52,6 +65,15 @@ fn build_http_client(timeout: Option, max_connections: Option) }) } +fn extract_hostname(host: &str) -> Option<&str> { + host.trim_start_matches("https://") + .trim_start_matches("http://") + .split('/') + .next() + .and_then(|authority| authority.split(':').next()) + .filter(|hostname| !hostname.is_empty()) +} + /// Main client for interacting with Polymarket API pub struct ClobClient { pub http_client: Client, @@ -129,7 +151,7 @@ impl ClobClient { /// Create a new client with optimized HTTP/2 settings (benchmarked 11.4% faster) /// Now includes DNS caching, connection management, and buffer pooling pub fn new(host: &str) -> Self { - let http_client = build_http_client(None, None); + let http_client = build_http_client(host, None, None); Self::build_client(host, 137, http_client, None, None, None) } @@ -144,7 +166,8 @@ impl ClobClient { None => None, }; - let http_client = build_http_client(config.timeout, config.max_connections); + let http_client = + build_http_client(&config.base_url, config.timeout, config.max_connections); Ok(Self::build_client( &config.base_url, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index a6729c4..cc1a483 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -27,8 +27,12 @@ impl Default for TestConfig { .unwrap_or(137), private_key: env::var("POLYMARKET_PRIVATE_KEY").ok(), api_key: env::var("POLYMARKET_API_KEY").ok(), - api_secret: env::var("POLYMARKET_API_SECRET").ok(), - api_passphrase: env::var("POLYMARKET_API_PASSPHRASE").ok(), + api_secret: env::var("POLYMARKET_API_SECRET") + .or_else(|_| env::var("POLYMARKET_SECRET")) + .ok(), + api_passphrase: env::var("POLYMARKET_API_PASSPHRASE") + .or_else(|_| env::var("POLYMARKET_PASSPHRASE")) + .ok(), test_timeout: Duration::from_secs(30), } } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 3a4dd27..c98df2b 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -15,8 +15,12 @@ fn load_env_vars() -> (String, Option, Option, Option) { let private_key = env::var("POLYMARKET_PRIVATE_KEY").expect("POLYMARKET_PRIVATE_KEY must be set in .env"); let api_key = env::var("POLYMARKET_API_KEY").ok(); - let api_secret = env::var("POLYMARKET_API_SECRET").ok(); - let api_passphrase = env::var("POLYMARKET_API_PASSPHRASE").ok(); + let api_secret = env::var("POLYMARKET_API_SECRET") + .or_else(|_| env::var("POLYMARKET_SECRET")) + .ok(); + let api_passphrase = env::var("POLYMARKET_API_PASSPHRASE") + .or_else(|_| env::var("POLYMARKET_PASSPHRASE")) + .ok(); (private_key, api_key, api_secret, api_passphrase) }