Spaces:
Running
Running
Update whale_news_data.py
Browse files- whale_news_data.py +93 -26
whale_news_data.py
CHANGED
|
@@ -32,15 +32,17 @@ class EnhancedWhaleMonitor:
|
|
| 32 |
self._validate_api_keys()
|
| 33 |
|
| 34 |
self.whale_threshold_usd = 50000
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
self.data_manager = None
|
| 37 |
self.r2_service = r2_service
|
| 38 |
|
| 39 |
self.address_labels = {}
|
| 40 |
self._initialize_comprehensive_exchange_addresses()
|
| 41 |
|
| 42 |
-
self.contract_cache = {}
|
| 43 |
-
self.symbol_networks = {}
|
| 44 |
self.token_price_cache = {}
|
| 45 |
self.token_decimals_cache = {}
|
| 46 |
|
|
@@ -115,6 +117,38 @@ class EnhancedWhaleMonitor:
|
|
| 115 |
if self.r2_service:
|
| 116 |
asyncio.create_task(self._load_contracts_from_r2())
|
| 117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
def _validate_api_keys(self):
|
| 119 |
"""التحقق من صحة مفاتيح API المطلوبة فقط"""
|
| 120 |
print("🔍 التحقق من صحة مفاتيح API...")
|
|
@@ -313,8 +347,22 @@ class EnhancedWhaleMonitor:
|
|
| 313 |
response = self.r2_service.s3_client.get_object(Bucket="trading", Key=key)
|
| 314 |
contracts_data = json.loads(response['Body'].read())
|
| 315 |
|
| 316 |
-
|
| 317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
|
| 319 |
except Exception as e:
|
| 320 |
print(f"⚠️ لم يتم العثور على قاعدة بيانات العقود في R2: {e}")
|
|
@@ -336,13 +384,23 @@ class EnhancedWhaleMonitor:
|
|
| 336 |
|
| 337 |
# 1. البحث عن عقد العملة إذا لم يتم توفيره
|
| 338 |
if not contract_address:
|
| 339 |
-
|
| 340 |
-
if not
|
| 341 |
print(f"❌ لم يتم العثور على عقد للعملة {symbol}")
|
| 342 |
return self._create_no_contract_response(symbol)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 343 |
|
| 344 |
-
# 2. تحديد الشبكة المناسبة فقط
|
| 345 |
-
network = self.symbol_networks.get(symbol.lower())
|
| 346 |
if not network:
|
| 347 |
print(f"❌ لم يتم تحديد شبكة للعملة {symbol}")
|
| 348 |
return self._create_no_contract_response(symbol)
|
|
@@ -944,7 +1002,9 @@ class EnhancedWhaleMonitor:
|
|
| 944 |
'ATOM': 'cosmos',
|
| 945 |
'UNI': 'uniswap',
|
| 946 |
'AAVE': 'aave',
|
| 947 |
-
'KCS': 'kucoin-shares'
|
|
|
|
|
|
|
| 948 |
}
|
| 949 |
|
| 950 |
coingecko_id = symbol_mapping.get(base_symbol, base_symbol.lower())
|
|
@@ -1078,34 +1138,41 @@ class EnhancedWhaleMonitor:
|
|
| 1078 |
|
| 1079 |
print(f"🔍 البحث عن عقد للعملة: {symbol} (الرمز الأساسي: {base_symbol})")
|
| 1080 |
|
| 1081 |
-
# 1. البحث في
|
| 1082 |
-
if symbol_lower in self.
|
| 1083 |
-
|
| 1084 |
-
|
| 1085 |
-
|
| 1086 |
-
|
| 1087 |
-
|
| 1088 |
-
|
| 1089 |
-
|
| 1090 |
-
|
| 1091 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1092 |
|
| 1093 |
-
#
|
| 1094 |
print(f" 🔍 البحث في CoinGecko عن {base_symbol}...")
|
| 1095 |
coingecko_result = await self._find_contract_via_coingecko(base_symbol)
|
| 1096 |
|
| 1097 |
if coingecko_result:
|
| 1098 |
address, network = coingecko_result
|
| 1099 |
-
|
| 1100 |
-
|
| 1101 |
-
|
|
|
|
|
|
|
| 1102 |
|
| 1103 |
# حفظ في R2 إذا كان متوفراً
|
| 1104 |
if self.r2_service:
|
| 1105 |
await self._save_contracts_to_r2()
|
| 1106 |
|
| 1107 |
print(f" ✅ تم العثور على عقد {symbol} عبر CoinGecko على شبكة {network}: {address}")
|
| 1108 |
-
return
|
| 1109 |
else:
|
| 1110 |
print(f" ❌ فشل العثور على عقد لـ {symbol} في CoinGecko")
|
| 1111 |
|
|
|
|
| 32 |
self._validate_api_keys()
|
| 33 |
|
| 34 |
self.whale_threshold_usd = 50000
|
| 35 |
+
|
| 36 |
+
# تحسين تخزين العقود والشبكات
|
| 37 |
+
self.contracts_db = {}
|
| 38 |
+
self._initialize_contracts_db(contracts_db or {})
|
| 39 |
+
|
| 40 |
self.data_manager = None
|
| 41 |
self.r2_service = r2_service
|
| 42 |
|
| 43 |
self.address_labels = {}
|
| 44 |
self._initialize_comprehensive_exchange_addresses()
|
| 45 |
|
|
|
|
|
|
|
| 46 |
self.token_price_cache = {}
|
| 47 |
self.token_decimals_cache = {}
|
| 48 |
|
|
|
|
| 117 |
if self.r2_service:
|
| 118 |
asyncio.create_task(self._load_contracts_from_r2())
|
| 119 |
|
| 120 |
+
def _initialize_contracts_db(self, initial_contracts):
|
| 121 |
+
"""تهيئة قاعدة بيانات العقود مع تحسين تخزين الشبكات"""
|
| 122 |
+
print("🔄 تهيئة قاعدة بيانات العقود...")
|
| 123 |
+
|
| 124 |
+
for symbol, contract_data in initial_contracts.items():
|
| 125 |
+
if isinstance(contract_data, dict):
|
| 126 |
+
# إذا كانت البيانات بالفعل في الصيغة الجديدة
|
| 127 |
+
self.contracts_db[symbol] = contract_data
|
| 128 |
+
else:
|
| 129 |
+
# إذا كانت البيانات في الصيغة القديمة، نحولها للصيغة الجديدة
|
| 130 |
+
self.contracts_db[symbol] = {
|
| 131 |
+
'address': contract_data,
|
| 132 |
+
'network': self._detect_network_from_address(contract_data)
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
print(f"✅ تم تحميل {len(self.contracts_db)} عقد في قاعدة البيانات")
|
| 136 |
+
|
| 137 |
+
def _detect_network_from_address(self, address):
|
| 138 |
+
"""اكتشاف الشبكة من عنوان العقد"""
|
| 139 |
+
if not isinstance(address, str):
|
| 140 |
+
return 'ethereum' # قيمة افتراضية
|
| 141 |
+
|
| 142 |
+
address_lower = address.lower()
|
| 143 |
+
|
| 144 |
+
# اكتشاف الشبكة بناءً على تنسيق العنوان
|
| 145 |
+
if address_lower.startswith('0x') and len(address_lower) == 42:
|
| 146 |
+
return 'ethereum' # معظم عناوين EVM تبدأ بـ 0x
|
| 147 |
+
elif len(address_lower) == 44 and not address_lower.startswith('0x'):
|
| 148 |
+
return 'solana' # عناوين Solana عادة 44 حرف
|
| 149 |
+
else:
|
| 150 |
+
return 'ethereum' # افتراضي
|
| 151 |
+
|
| 152 |
def _validate_api_keys(self):
|
| 153 |
"""التحقق من صحة مفاتيح API المطلوبة فقط"""
|
| 154 |
print("🔍 التحقق من صحة مفاتيح API...")
|
|
|
|
| 347 |
response = self.r2_service.s3_client.get_object(Bucket="trading", Key=key)
|
| 348 |
contracts_data = json.loads(response['Body'].read())
|
| 349 |
|
| 350 |
+
# تحسين تحميل البيانات مع اكتشاف الشبكات
|
| 351 |
+
loaded_count = 0
|
| 352 |
+
for symbol, contract_data in contracts_data.items():
|
| 353 |
+
if isinstance(contract_data, dict):
|
| 354 |
+
# البيانات بالفعل في الصيغة الجديدة
|
| 355 |
+
self.contracts_db[symbol] = contract_data
|
| 356 |
+
loaded_count += 1
|
| 357 |
+
else:
|
| 358 |
+
# تحويل البيانات القديمة للصيغة الجديدة
|
| 359 |
+
self.contracts_db[symbol] = {
|
| 360 |
+
'address': contract_data,
|
| 361 |
+
'network': self._detect_network_from_address(contract_data)
|
| 362 |
+
}
|
| 363 |
+
loaded_count += 1
|
| 364 |
+
|
| 365 |
+
print(f"✅ تم تحميل {loaded_count} عقد من R2")
|
| 366 |
|
| 367 |
except Exception as e:
|
| 368 |
print(f"⚠️ لم يتم العثور على قاعدة بيانات العقود في R2: {e}")
|
|
|
|
| 384 |
|
| 385 |
# 1. البحث عن عقد العملة إذا لم يتم توفيره
|
| 386 |
if not contract_address:
|
| 387 |
+
contract_info = await self._find_contract_address_enhanced(symbol)
|
| 388 |
+
if not contract_info:
|
| 389 |
print(f"❌ لم يتم العثور على عقد للعملة {symbol}")
|
| 390 |
return self._create_no_contract_response(symbol)
|
| 391 |
+
|
| 392 |
+
contract_address = contract_info['address']
|
| 393 |
+
network = contract_info['network']
|
| 394 |
+
else:
|
| 395 |
+
# إذا تم توفير العنوان، نحتاج لاكتشاف الشبكة
|
| 396 |
+
contract_info = await self._find_contract_address_enhanced(symbol)
|
| 397 |
+
if contract_info and 'network' in contract_info:
|
| 398 |
+
network = contract_info['network']
|
| 399 |
+
else:
|
| 400 |
+
# اكتشاف الشبكة من العنوان إذا لم نجد معلومات
|
| 401 |
+
network = self._detect_network_from_address(contract_address)
|
| 402 |
+
print(f"🌐 تم اكتشاف الشبكة تلقائياً: {network}")
|
| 403 |
|
|
|
|
|
|
|
| 404 |
if not network:
|
| 405 |
print(f"❌ لم يتم تحديد شبكة للعملة {symbol}")
|
| 406 |
return self._create_no_contract_response(symbol)
|
|
|
|
| 1002 |
'ATOM': 'cosmos',
|
| 1003 |
'UNI': 'uniswap',
|
| 1004 |
'AAVE': 'aave',
|
| 1005 |
+
'KCS': 'kucoin-shares',
|
| 1006 |
+
'MIRA': 'mirai-2',
|
| 1007 |
+
'XL1': 'xl1'
|
| 1008 |
}
|
| 1009 |
|
| 1010 |
coingecko_id = symbol_mapping.get(base_symbol, base_symbol.lower())
|
|
|
|
| 1138 |
|
| 1139 |
print(f"🔍 البحث عن عقد للعملة: {symbol} (الرمز الأساسي: {base_symbol})")
|
| 1140 |
|
| 1141 |
+
# 1. البحث في قاعدة البيانات المحلية
|
| 1142 |
+
if symbol_lower in self.contracts_db:
|
| 1143 |
+
contract_info = self.contracts_db[symbol_lower]
|
| 1144 |
+
print(f" ✅ وجد في قاعدة البيانات المحلية: {contract_info}")
|
| 1145 |
+
|
| 1146 |
+
# إذا كانت البيانات في الصيغة القديمة، نحولها للصيغة الجديدة
|
| 1147 |
+
if isinstance(contract_info, str):
|
| 1148 |
+
network = self._detect_network_from_address(contract_info)
|
| 1149 |
+
contract_info = {
|
| 1150 |
+
'address': contract_info,
|
| 1151 |
+
'network': network
|
| 1152 |
+
}
|
| 1153 |
+
self.contracts_db[symbol_lower] = contract_info
|
| 1154 |
+
print(f" 🔄 تم تحويل البيانات للصيغة الجديدة: {contract_info}")
|
| 1155 |
+
|
| 1156 |
+
return contract_info
|
| 1157 |
|
| 1158 |
+
# 2. البحث في CoinGecko مع تحديد الشبكة
|
| 1159 |
print(f" 🔍 البحث في CoinGecko عن {base_symbol}...")
|
| 1160 |
coingecko_result = await self._find_contract_via_coingecko(base_symbol)
|
| 1161 |
|
| 1162 |
if coingecko_result:
|
| 1163 |
address, network = coingecko_result
|
| 1164 |
+
contract_info = {
|
| 1165 |
+
'address': address,
|
| 1166 |
+
'network': network
|
| 1167 |
+
}
|
| 1168 |
+
self.contracts_db[symbol_lower] = contract_info
|
| 1169 |
|
| 1170 |
# حفظ في R2 إذا كان متوفراً
|
| 1171 |
if self.r2_service:
|
| 1172 |
await self._save_contracts_to_r2()
|
| 1173 |
|
| 1174 |
print(f" ✅ تم العثور على عقد {symbol} عبر CoinGecko على شبكة {network}: {address}")
|
| 1175 |
+
return contract_info
|
| 1176 |
else:
|
| 1177 |
print(f" ❌ فشل العثور على عقد لـ {symbol} في CoinGecko")
|
| 1178 |
|