
- Created Alembic migrations for SQLite database - Set up database initialization on app startup - Fixed linting issues with Ruff - Updated README with comprehensive documentation - Configured startup tasks and health checks
62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
import secrets
|
|
from typing import Any, List, Optional
|
|
from pathlib import Path
|
|
from pydantic import field_validator
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
# Basic application info
|
|
PROJECT_NAME: str = "Solana Arbitrage Trading System"
|
|
PROJECT_DESCRIPTION: str = "A backend system for detecting and executing arbitrage opportunities on Solana DEXes"
|
|
VERSION: str = "0.1.0"
|
|
API_V1_STR: str = "/api/v1"
|
|
|
|
# Security
|
|
SECRET_KEY: str = secrets.token_urlsafe(32)
|
|
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 8 days
|
|
|
|
# Database
|
|
DB_DIR: Path = Path("/app") / "storage" / "db"
|
|
SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite"
|
|
|
|
# Solana configuration
|
|
SOLANA_RPC_URL: str = "https://api.mainnet-beta.solana.com"
|
|
SOLANA_NETWORK: str = "mainnet-beta" # Can be mainnet-beta, testnet, or devnet
|
|
WALLET_KEYPAIR_PATH: Optional[str] = None # Path to the keypair JSON file
|
|
|
|
# Trading parameters
|
|
PROFIT_THRESHOLD_PERCENT: float = 1.0 # Minimum profit percentage to consider an opportunity
|
|
MAX_SLIPPAGE_PERCENT: float = 0.5 # Maximum allowed slippage percentage
|
|
EXECUTION_ENABLED: bool = False # Whether to actually execute trades or just monitor
|
|
SCAN_INTERVAL_SECONDS: int = 10 # How often to scan for arbitrage opportunities
|
|
|
|
# Monitored tokens - comma-separated list of token addresses to monitor
|
|
MONITORED_TOKENS: List[str] = []
|
|
|
|
@field_validator("MONITORED_TOKENS", mode="before")
|
|
def validate_monitored_tokens(cls, v: Any) -> List[str]:
|
|
if isinstance(v, str) and v:
|
|
return [token.strip() for token in v.split(",")]
|
|
return []
|
|
|
|
# DEX configuration
|
|
ENABLED_DEXES: List[str] = ["jupiter", "raydium"]
|
|
|
|
@field_validator("ENABLED_DEXES", mode="before")
|
|
def validate_enabled_dexes(cls, v: Any) -> List[str]:
|
|
if isinstance(v, str) and v:
|
|
return [dex.strip().lower() for dex in v.split(",")]
|
|
return ["jupiter", "raydium"] # Default if not specified
|
|
|
|
model_config = SettingsConfigDict(
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
case_sensitive=True,
|
|
)
|
|
|
|
|
|
settings = Settings()
|
|
|
|
# Create DB directory if it doesn't exist
|
|
settings.DB_DIR.mkdir(parents=True, exist_ok=True) |