diff --git a/crypto/sol/app.py b/crypto/sol/app.py index 51d82e0..2ecccf8 100644 --- a/crypto/sol/app.py +++ b/crypto/sol/app.py @@ -41,6 +41,8 @@ from typing import List, Dict, Any, Tuple import random +app = Flask(__name__) + load_dotenv() load_dotenv('.env.secret') # ToDo - make it work @@ -60,11 +62,6 @@ error_logger.setLevel(logging.ERROR) error_logger.addHandler(error_file_handler) -app = Flask(__name__) - -ENV_FILE = '.env' - - # Function to find the latest log file def get_latest_log_file(): log_dir = './logs' @@ -73,7 +70,7 @@ def get_latest_log_file(): # filter files mask log_20241005_004103_143116.json files = [f for f in os.listdir(log_dir) if os.path.isfile(os.path.join(log_dir, f)) and f.startswith('log_')] - latest_file = max(files, key=lambda x: os.path.getctime(os.path.join(log_dir, x))) + latest_file = max(files, key=lambda x: os.path.getmtime(os.path.join(log_dir, x))) return os.path.join(log_dir, latest_file) except Exception as e: logging.error(f"Error fetching latest log file: {e}") @@ -81,7 +78,7 @@ def get_latest_log_file(): # Flask route to retry processing the last log @app.route('/retry-last-log', methods=['GET']) -def retry_last_log(): +async def retry_last_log(): latest_log_file = get_latest_log_file() if not latest_log_file: return jsonify({"error": "No log files found"}), 404 @@ -91,10 +88,13 @@ def retry_last_log(): with open(latest_log_file, 'r') as f: log = json.load(f) - # await process_log(log) - # Run the asynchronous process_log function - asyncio.run(process_log(log)) - return jsonify({"status": "Log dump processed successfully"}), 200 + result = await process_log(log) + + return jsonify({ + "file": latest_log_file, + "status": "Log dump processed successfully", + "result": result + }), 200 except Exception as e: logging.error(f"Error processing log dump: {e}") @@ -469,7 +469,7 @@ async def get_wallet_balances(wallet_address, doGetTokenName=True): # sleep for 1 second to avoid rate limiting await asyncio.sleep(2) - TOKENS_INFO[mint]['holdedAmount'] = amount + TOKENS_INFO[mint]['holdedAmount'] = round(amount,decimals) TOKENS_INFO[mint]['decimals'] = decimals balances[mint] = { 'name': token_name or 'N/A', @@ -477,8 +477,8 @@ async def get_wallet_balances(wallet_address, doGetTokenName=True): 'amount': amount, 'decimals': decimals } - # sleep for 1 second to avoid rate limiting - logging.debug(f"Balance for {token_name} ({mint}): {amount}") + # sleep for 1 second to avoid rate limiting + logging.debug(f"Account balance for {token_name} ({mint}): {amount}") else: logging.warning(f"Unexpected data format for account: {account}") except Exception as e: @@ -943,13 +943,13 @@ async def process_log(log_result): except Exception as e: logging.error(f"Error aquiring log details and following: {e}") await send_telegram_message(f"Not followed! Error following move.") - return + except Exception as e: logging.error(f"Error processing log: {e}") - + return tr_details # "Program log: Instruction: Swap2", # "Program log: order_id: 13985890735038016", # "Program log: AbrMJWfDVRZ2EWCQ1xSCpoVeVgZNpq1U2AoYG98oRXfn", source @@ -995,7 +995,7 @@ async def follow_move(move): your_balance_info = next((balance for balance in your_balances.values() if balance['address'] == move['token_in']), None) if your_balance_info is not None: # Use the balance - print(f"Your balance: {your_balance_info['amount']}") + print(f"Your balance: {your_balance_info['amount']} {move['symbol_in']}") else: print("No ballance found for {move['symbol_in']}. Skipping move.") await send_telegram_message(f"No ballance found for {move['symbol_in']}. Skipping move.") @@ -1009,7 +1009,7 @@ async def follow_move(move): token_name_out = TOKENS_INFO[move['token_out']].get('symbol') or await get_token_metadata_symbol(move['token_out']) if not your_balance: - msg = f"Move Failed:\nNo balance found for token {move['token_in']}. Cannot follow move." + msg = f"Move not followed:\nNo balance found for token {move['symbol_in']}. Cannot follow move." logging.warning(msg) await send_telegram_message(msg) return @@ -1021,9 +1021,11 @@ async def follow_move(move): # # always get 99% of the amount to swap # amount_to_swap = amount_to_swap * 0.95 + decimals = token_info.get('decimals') # Convert to lamports # if decimals is 6, then amount = amount * 1e6; if 9, then amount = amount * 1e9 - amount = int(amount_to_swap * 10**token_info.get('decimals') ) + amount = int(amount_to_swap * 10**decimals) + if your_balance < amount_to_swap: msg = ( @@ -1190,6 +1192,7 @@ async def subscribe_to_wallet(): logger.error(f"WebSocket error: {e}") except Exception as e: logger.error(f"An unexpected error occurred: {e}") + await unsubscribe(websocket, subscription_id) await send_telegram_message("reconnecting...") logger.info(f"Attempting to reconnect in {reconnect_delay} seconds...") await asyncio.sleep(reconnect_delay) @@ -1248,6 +1251,7 @@ async def process_messages(websocket, subscription_id): except websockets.exceptions.ConnectionClosedError as e: logger.error(f"Connection closed unexpectedly: {e}") await send_telegram_message("Connection to Solana network was closed. Not listening for transactions right now. Attempting to reconnect...") + pass except json.JSONDecodeError as e: logger.error(f"Failed to decode JSON: {e}") except Exception as e: @@ -1274,6 +1278,8 @@ async def check_PK(): logging.error("Private key not found in environment variables. Will not be able to sign transactions.") # send TG warning message await send_telegram_message("Warning: Private key not found in environment variables. Will not be able to sign transactions.") + + async def main(): @@ -1281,19 +1287,15 @@ async def main(): await check_PK() await subscribe_to_wallet() -def run_flask(): - # Run Flask app without the reloader, so we can run the async main function - app.run(debug=False, port=3001, use_reloader=False) +async def run_flask(): + loop = asyncio.get_running_loop() + await loop.run_in_executor(None, lambda: app.run(debug=False, port=3001, use_reloader=False)) + +async def run_all(): + await asyncio.gather( + main(), + run_flask() + ) if __name__ == '__main__': - - # Create an event loop for the async tasks - loop = asyncio.get_event_loop() - loop.run_until_complete(main()) - # Start Flask in a separate thread - # flask_thread = threading.Thread(target=run_flask) - # flask_thread.start() - - # Run the async main function - asyncio.run(main()) - run_flask() + asyncio.run(run_all()) \ No newline at end of file