#!/usr/bin/env python3 """ Debug MEXC Order Signature Tests order signature generation against MEXC API """ import os import sys import time import hmac import hashlib import logging import requests from pathlib import Path # Add project root to path project_root = Path(__file__).parent sys.path.insert(0, str(project_root)) # Enable debug logging logging.basicConfig(level=logging.DEBUG) def test_order_signature(): """Test order signature generation""" print("MEXC Order Signature Debug") print("=" * 50) # Get API credentials api_key = os.getenv('MEXC_API_KEY', '') api_secret = os.getenv('MEXC_SECRET_KEY', '') if not api_key or not api_secret: print("❌ No MEXC API credentials found") return False # Test order parameters timestamp = str(int(time.time() * 1000)) params = { 'symbol': 'ETHUSDC', 'side': 'BUY', 'type': 'LIMIT', 'quantity': '0.003', 'price': '2900', 'timeInForce': 'GTC', 'timestamp': timestamp, 'recvWindow': '5000' } print(f"Order parameters: {params}") # Test 1: Manual signature generation (timestamp first) print("\n1. Manual signature generation (timestamp first):") # Create parameter string with timestamp first, then alphabetical param_list = [f"timestamp={params['timestamp']}"] for key in sorted(params.keys()): if key != 'timestamp': param_list.append(f"{key}={params[key]}") params_string = '&'.join(param_list) print(f"Params string: {params_string}") signature_manual = hmac.new( api_secret.encode('utf-8'), params_string.encode('utf-8'), hashlib.sha256 ).hexdigest() print(f"Manual signature: {signature_manual}") # Test 2: Interface signature generation print("\n2. Interface signature generation:") from NN.exchanges.mexc_interface import MEXCInterface mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=False) signature_interface = mexc._generate_signature(params) print(f"Interface signature: {signature_interface}") # Compare if signature_manual == signature_interface: print("✅ Signatures match!") else: print("❌ Signatures don't match") print("This indicates a problem with the signature generation method") return False # Test 3: Try order with manual signature print("\n3. Testing order with manual method:") url = "https://api.mexc.com/api/v3/order" headers = { 'X-MEXC-APIKEY': api_key } order_params = params.copy() order_params['signature'] = signature_manual print(f"Making POST request to: {url}") print(f"Headers: {headers}") print(f"Params: {order_params}") try: response = requests.post(url, headers=headers, params=order_params, timeout=10) print(f"Response status: {response.status_code}") print(f"Response: {response.text}") if response.status_code == 200: print("✅ Manual order method works!") return True else: print("❌ Manual order method failed") # Test 4: Try test order endpoint print("\n4. Testing with test order endpoint:") test_url = "https://api.mexc.com/api/v3/order/test" response2 = requests.post(test_url, headers=headers, params=order_params, timeout=10) print(f"Test order response: {response2.status_code} - {response2.text}") if response2.status_code == 200: print("✅ Test order works - real order parameters might have issues") # Test 5: Try different parameter variations print("\n5. Testing different parameter sets:") # Minimal parameters minimal_params = { 'symbol': 'ETHUSDC', 'side': 'BUY', 'type': 'LIMIT', 'quantity': '0.003', 'price': '2900', 'timestamp': str(int(time.time() * 1000)), 'recvWindow': '5000' } # Generate signature for minimal params minimal_param_list = [f"timestamp={minimal_params['timestamp']}"] for key in sorted(minimal_params.keys()): if key != 'timestamp': minimal_param_list.append(f"{key}={minimal_params[key]}") minimal_params_string = '&'.join(minimal_param_list) minimal_signature = hmac.new( api_secret.encode('utf-8'), minimal_params_string.encode('utf-8'), hashlib.sha256 ).hexdigest() minimal_params['signature'] = minimal_signature print(f"Minimal params: {minimal_params_string}") print(f"Minimal signature: {minimal_signature}") response3 = requests.post(test_url, headers=headers, params=minimal_params, timeout=10) print(f"Minimal params response: {response3.status_code} - {response3.text}") except Exception as e: print(f"Request failed: {e}") return False return False if __name__ == "__main__": test_order_signature()