import libraries.balance_accounts as balance_accounts from libraries.wrappers import earn_binance from libraries.wrappers import earn_kucoin from libraries.wrappers import earn_okx from libraries.wrappers import earn_gateio from libraries.earner import earner from threading import Thread from flask import Flask, jsonify, request import time import datetime import json import sqlite3 def load_keys_from_db(file_name: str) -> list: ''' Load valid API keys Parameters ---------- file_name : str Name of the database file Returns ------- valid_keys : list List of valid API keys ''' database_connection = sqlite3.connect(file_name) database_cursor = database_connection.cursor() database_cursor.execute("SELECT * FROM credentials_table") data = database_cursor.fetchall() database_connection.close() valid_keys = [line[1] for line in data] return valid_keys def seconds_to_time(total_seconds: float) -> str: ''' Takes an int or float as an input and it returns a D:HH:MM:SS formatted string. Parameters: total_seconds (float): The number of seconds to convert Returns: str: The formatted string ''' time_delta = datetime.timedelta(seconds=total_seconds) hours = time_delta.seconds//3600 remainder = time_delta.seconds%3600 minutes = remainder//60 seconds = remainder%60 return f"{time_delta.days}:{hours:02d}:{minutes:02d}:{seconds:02d}" def main(): while True: threads = [] #Run earners for item in earners: threads.append(Thread(target=item.run)) for item in threads: item.start() for item in threads: item.join() #Print status print("="*80) subscriptions = [] redemptions = [] for item in earners: print(item.get_status_string()) subscriptions.append(item.get_last_subscription()) redemptions.append(item.get_last_redemption()) last_subscription = max(subscriptions, key=lambda d: next(iter(d.values()))) last_subscription_key = next(iter(last_subscription.keys())) last_subscription_value = next(iter(last_subscription.values())) if last_subscription_value == 0: last_subscription_key = "Never" last_subscription_value = "" else: last_subscription_value = datetime.datetime.fromtimestamp(last_subscription_value).strftime('%Y-%m-%d %H:%M:%S') last_redemption = max(redemptions, key=lambda d: next(iter(d.values()))) last_redemption_key = next(iter(last_redemption.keys())) last_redemption_value = next(iter(last_redemption.values())) if last_redemption_value == 0: last_redemption_key = "Never" last_redemption_value = "" else: last_redemption_value = datetime.datetime.fromtimestamp(last_redemption_value).strftime('%Y-%m-%d %H:%M:%S') print("-"*80) total_on_trading = sum([item.get_trading_balance() for item in earners]) total_on_earning = sum([item.get_earning_balance() for item in earners]) print(f"Version {version} | Total funds: {total_on_trading+total_on_earning:.2f} | Total on earn: {total_on_earning:.2f} ({total_on_earning/total_on_trading*100:.2f}%)") print(f"Uptime: {seconds_to_time(time.time()-start_time)} | Last subscription: {last_subscription_key} - {last_subscription_value} | Last redemption: {last_redemption_key} - {last_redemption_value}") #Wait for next lap time.sleep(config["lap_time"]) ######################### ######### API ########### ######################### earn_api = Flask(__name__) @earn_api.route("/toggle_pause", methods=['POST']) def return_global_status(): ''' GET request Parameters: broker: str ''' if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys: if request.json is None: return jsonify({'Error': 'request.json is None'}) broker = request.json["broker"] for item in earners: if str(item.connector)==broker: item.toggle_pause() return jsonify({'Status': item.is_paused}) return jsonify({'Error': 'broker not found'}) return jsonify({'Error': 'API key invalid'}), 401 if __name__=="__main__": version = "2025.01.07" start_time = time.time() with open("config.json") as f: config = json.load(f) connectors = {"binance": earn_binance.binance_earn(), "gateio": earn_gateio.gateio_earn(), "kucoin": earn_kucoin.kucoin_earn(), "okx": earn_okx.okx_earn()} earners = [] for item in config["exchanges"]: earners.append(earner(connectors[item], config["exchanges"][item])) #Load valid API keys valid_keys = load_keys_from_db("keys/api_credentials.db") main()