-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
143 lines (117 loc) · 5.92 KB
/
config.py
File metadata and controls
143 lines (117 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import os
import sys
from dotenv import load_dotenv
from typing import List
# Load environment variables from .env file
load_dotenv()
def get_base_dir():
"""Get the base directory for the application (handles both development and executable)"""
if getattr(sys, 'frozen', False):
# Running as executable
return os.path.dirname(sys.executable)
else:
# Running as script
return os.path.dirname(os.path.abspath(__file__))
class Config:
"""Configuration class to manage all application settings"""
# Get base directory
BASE_DIR = get_base_dir()
# Telegram Bot Configuration
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
TELEGRAM_BOT_USERNAME = os.getenv('TELEGRAM_BOT_USERNAME', '@liquidity_rebalance_bot')
# MetaMask Configuration (will be set dynamically via /connect command)
METAMASK_PHRASE = os.getenv('METAMASK_PHRASE', '')
METAMASK_PASSWORD = os.getenv('METAMASK_PASSWORD', '')
# Browser Configuration with fallbacks
EXTENSION_PATH = os.getenv('EXTENSION_PATH') or os.path.join(BASE_DIR, 'metamask_extension')
USER_DATA_DIR = os.getenv('USER_DATA_DIR') or os.path.join(BASE_DIR, 'user_profile')
# Browser Settings
HEADLESS = os.getenv('HEADLESS', 'false').lower() == 'true'
START_MAXIMIZED = os.getenv('START_MAXIMIZED', 'true').lower() == 'true'
COLOR_SCHEME = os.getenv('COLOR_SCHEME', 'dark')
# Pool Configuration
DEFAULT_RANGE_TYPES = os.getenv('DEFAULT_RANGE_TYPES', 'passive,wide,narrow,aggressive,insane').split(',')
SHADOW_BASE_URL = os.getenv('SHADOW_BASE_URL', 'https://www.shadow.so/liquidity/')
# Monitoring Settings
POLL_INTERVAL = int(os.getenv('POLL_INTERVAL', '1'))
REBALANCE_THRESHOLD = float(os.getenv('REBALANCE_THRESHOLD', '90'))
BALANCE_TOLERANCE = float(os.getenv('BALANCE_TOLERANCE', '2'))
MONITOR_INTERVAL = int(os.getenv('MONITOR_INTERVAL', '60')) # Reduced from 30 to 60 seconds for better responsiveness
# Error Recovery Settings
MAX_BROWSER_RETRIES = int(os.getenv('MAX_BROWSER_RETRIES', '3'))
BROWSER_RESTART_DELAY = int(os.getenv('BROWSER_RESTART_DELAY', '30')) # seconds
TRANSACTION_TIMEOUT = int(os.getenv('TRANSACTION_TIMEOUT', '120')) # seconds
MAX_REBALANCE_RETRIES = int(os.getenv('MAX_REBALANCE_RETRIES', '2'))
# Security & Notifications
# Comma-separated list of Telegram user IDs allowed to use the bot. If empty, allow all.
ALLOWED_USER_IDS = [
int(x) for x in os.getenv('ALLOWED_USER_IDS', '').split(',') if x.strip().isdigit()
]
# Admin chat IDs to receive alerts/notifications
ADMIN_CHAT_IDS = [
int(x) for x in os.getenv('ADMIN_CHAT_IDS', '').split(',') if x.strip().isdigit()
]
ENABLE_NOTIFICATIONS = os.getenv('ENABLE_NOTIFICATIONS', 'true').lower() == 'true'
# Logging
LOG_DIR = os.getenv('LOG_DIR', 'logs')
@classmethod
def ensure_directories(cls):
"""Ensure all required directories exist"""
directories_to_create = [
cls.USER_DATA_DIR,
os.path.join(cls.BASE_DIR, 'data'),
cls.LOG_DIR if os.path.isabs(cls.LOG_DIR) else os.path.join(cls.BASE_DIR, cls.LOG_DIR)
]
for directory in directories_to_create:
if directory:
try:
os.makedirs(directory, exist_ok=True)
print(f"✅ Directory ensured: {directory}")
except Exception as e:
print(f"❌ Failed to create directory {directory}: {e}")
@classmethod
def validate_config(cls) -> List[str]:
"""Validate that all required configuration values are set"""
# First ensure directories exist
cls.ensure_directories()
errors = []
if not cls.TELEGRAM_BOT_TOKEN:
errors.append("TELEGRAM_BOT_TOKEN is required")
# MetaMask credentials are optional - provided via /connect command
# if not cls.METAMASK_PHRASE:
# errors.append("METAMASK_PHRASE is required")
# if not cls.METAMASK_PASSWORD:
# errors.append("METAMASK_PASSWORD is required")
# Extension path is now optional with fallback
# if not cls.EXTENSION_PATH:
# errors.append("EXTENSION_PATH is required")
# User data dir is now optional with fallback
# if not cls.USER_DATA_DIR:
# errors.append("USER_DATA_DIR is required")
# Check if extension path exists (create if doesn't exist)
if cls.EXTENSION_PATH and not os.path.exists(cls.EXTENSION_PATH):
errors.append(f"EXTENSION_PATH does not exist: {cls.EXTENSION_PATH}")
return errors
@classmethod
def print_config(cls):
"""Print current configuration (hiding sensitive data)"""
print("=== Configuration ===")
print(f"Bot Username: {cls.TELEGRAM_BOT_USERNAME}")
print(f"Extension Path: {cls.EXTENSION_PATH}")
print(f"User Data Dir: {cls.USER_DATA_DIR}")
print(f"Headless: {cls.HEADLESS}")
print(f"Range Types: {cls.DEFAULT_RANGE_TYPES}")
print(f"Poll Interval: {cls.POLL_INTERVAL}")
print(f"Monitor Interval: {cls.MONITOR_INTERVAL}s")
print(f"Rebalance Threshold: {cls.REBALANCE_THRESHOLD}%")
print(f"Balance Tolerance: {cls.BALANCE_TOLERANCE}%")
print(f"Transaction Timeout: {cls.TRANSACTION_TIMEOUT}s")
print(f"Max Browser Retries: {cls.MAX_BROWSER_RETRIES}")
print(f"Max Rebalance Retries: {cls.MAX_REBALANCE_RETRIES}")
print(f"Allowed Users: {cls.ALLOWED_USER_IDS if cls.ALLOWED_USER_IDS else 'ALL'}")
print(f"Admin Chat IDs: {cls.ADMIN_CHAT_IDS}")
print(f"Notifications: {'Enabled' if cls.ENABLE_NOTIFICATIONS else 'Disabled'}")
print(f"Log Dir: {cls.LOG_DIR}")
print("====================")
# Create a global config instance
config = Config()