185 lines
6.3 KiB
Python
185 lines
6.3 KiB
Python
"""
|
|
MEXC Timestamp and Signature Debug
|
|
|
|
This script tests different timestamp and recvWindow combinations to fix the signature validation.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import hashlib
|
|
import hmac
|
|
from urllib.parse import urlencode
|
|
import requests
|
|
|
|
# Add paths for imports
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), 'NN'))
|
|
|
|
def test_mexc_timestamp_debug():
|
|
"""Test different timestamp strategies"""
|
|
print("="*60)
|
|
print("MEXC TIMESTAMP AND SIGNATURE DEBUG")
|
|
print("="*60)
|
|
|
|
api_key = os.getenv('MEXC_API_KEY')
|
|
api_secret = os.getenv('MEXC_SECRET_KEY')
|
|
|
|
if not api_key or not api_secret:
|
|
print("❌ Missing API credentials")
|
|
return False
|
|
|
|
base_url = "https://api.mexc.com"
|
|
api_version = "api/v3"
|
|
|
|
# Test 1: Get server time directly
|
|
print("1. Getting server time...")
|
|
|
|
try:
|
|
response = requests.get(f"{base_url}/{api_version}/time", timeout=10)
|
|
if response.status_code == 200:
|
|
server_time_data = response.json()
|
|
server_time = server_time_data['serverTime']
|
|
local_time = int(time.time() * 1000)
|
|
time_diff = server_time - local_time
|
|
|
|
print(f" Server time: {server_time}")
|
|
print(f" Local time: {local_time}")
|
|
print(f" Difference: {time_diff}ms")
|
|
|
|
else:
|
|
print(f" ❌ Failed to get server time: {response.status_code}")
|
|
return False
|
|
except Exception as e:
|
|
print(f" ❌ Error getting server time: {e}")
|
|
return False
|
|
|
|
# Test 2: Try different timestamp strategies
|
|
strategies = [
|
|
("Server time exactly", server_time),
|
|
("Server time - 500ms", server_time - 500),
|
|
("Server time - 1000ms", server_time - 1000),
|
|
("Server time - 2000ms", server_time - 2000),
|
|
("Local time", local_time),
|
|
("Local time - 1000ms", local_time - 1000),
|
|
]
|
|
|
|
# Test with different recvWindow values
|
|
recv_windows = [5000, 10000, 30000, 60000]
|
|
|
|
print(f"\n2. Testing different timestamp strategies and recvWindow values...")
|
|
|
|
for strategy_name, timestamp in strategies:
|
|
print(f"\n Strategy: {strategy_name} (timestamp: {timestamp})")
|
|
|
|
for recv_window in recv_windows:
|
|
print(f" Testing recvWindow: {recv_window}ms")
|
|
|
|
# Test account info request
|
|
params = {
|
|
'timestamp': timestamp,
|
|
'recvWindow': recv_window
|
|
}
|
|
|
|
# Generate signature
|
|
sorted_params = sorted(params.items())
|
|
query_string = urlencode(sorted_params)
|
|
signature = hmac.new(
|
|
api_secret.encode('utf-8'),
|
|
query_string.encode('utf-8'),
|
|
hashlib.sha256
|
|
).hexdigest()
|
|
|
|
params['signature'] = signature
|
|
|
|
# Make request
|
|
headers = {'X-MEXC-APIKEY': api_key}
|
|
url = f"{base_url}/{api_version}/account"
|
|
|
|
try:
|
|
response = requests.get(url, params=params, headers=headers, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
print(f" ✅ SUCCESS")
|
|
account_data = response.json()
|
|
print(f" Account type: {account_data.get('accountType', 'Unknown')}")
|
|
return True # Found working combination
|
|
else:
|
|
error_data = response.json() if 'application/json' in response.headers.get('content-type', '') else {'msg': response.text}
|
|
error_code = error_data.get('code', 'Unknown')
|
|
error_msg = error_data.get('msg', 'Unknown')
|
|
print(f" ❌ Error {error_code}: {error_msg}")
|
|
|
|
except Exception as e:
|
|
print(f" ❌ Exception: {e}")
|
|
|
|
print(f"\n❌ No working timestamp/recvWindow combination found")
|
|
return False
|
|
|
|
def test_minimal_signature():
|
|
"""Test with minimal parameters to isolate signature issues"""
|
|
print(f"\n3. Testing minimal signature generation...")
|
|
|
|
api_key = os.getenv('MEXC_API_KEY')
|
|
api_secret = os.getenv('MEXC_SECRET_KEY')
|
|
|
|
base_url = "https://api.mexc.com"
|
|
api_version = "api/v3"
|
|
|
|
# Get fresh server time
|
|
try:
|
|
response = requests.get(f"{base_url}/{api_version}/time", timeout=10)
|
|
server_time = response.json()['serverTime']
|
|
print(f" Fresh server time: {server_time}")
|
|
except Exception as e:
|
|
print(f" ❌ Failed to get server time: {e}")
|
|
return False
|
|
|
|
# Test with absolute minimal parameters
|
|
minimal_params = {
|
|
'timestamp': server_time
|
|
}
|
|
|
|
# Generate signature with minimal params
|
|
sorted_params = sorted(minimal_params.items())
|
|
query_string = urlencode(sorted_params)
|
|
signature = hmac.new(
|
|
api_secret.encode('utf-8'),
|
|
query_string.encode('utf-8'),
|
|
hashlib.sha256
|
|
).hexdigest()
|
|
|
|
minimal_params['signature'] = signature
|
|
|
|
print(f" Minimal params: {minimal_params}")
|
|
print(f" Query string: {query_string}")
|
|
print(f" Signature: {signature}")
|
|
|
|
# Test account request with minimal params
|
|
headers = {'X-MEXC-APIKEY': api_key}
|
|
url = f"{base_url}/{api_version}/account"
|
|
|
|
try:
|
|
response = requests.get(url, params=minimal_params, headers=headers, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
print(f" ✅ Minimal signature works!")
|
|
return True
|
|
else:
|
|
error_data = response.json() if 'application/json' in response.headers.get('content-type', '') else {'msg': response.text}
|
|
print(f" ❌ Minimal signature failed: {error_data.get('code', 'Unknown')} - {error_data.get('msg', 'Unknown')}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f" ❌ Exception with minimal signature: {e}")
|
|
return False
|
|
|
|
if __name__ == "__main__":
|
|
success = test_mexc_timestamp_debug()
|
|
|
|
if not success:
|
|
success = test_minimal_signature()
|
|
|
|
if success:
|
|
print(f"\n🎉 Found working MEXC configuration!")
|
|
else:
|
|
print(f"\n🚨 MEXC signature/timestamp issue persists") |