Script now prompts user to download and install needed xmrig for mining Monero if it is not already installed.
This commit is contained in:
1 parent
682bd157fd
commit
ddb655071b
1 file changed
+250
-56
+250
-56
@@ -11,22 +11,236 @@ import os
|
|||||||
import time
|
import time
|
||||||
import signal
|
import signal
|
||||||
import platform
|
import platform
|
||||||
|
import urllib.request
|
||||||
|
import tarfile
|
||||||
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional, Tuple
|
||||||
|
|
||||||
class MoneroMiner:
|
class MoneroMiner:
|
||||||
def __init__(self, config_file: str = "miner-monero.json"):
|
def __init__(self, config_file: str = "miner-monero.json"):
|
||||||
self.config_file = config_file
|
self.config_file = config_file
|
||||||
self.config = self.load_config()
|
self.script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
self.config = None
|
||||||
self.process: Optional[subprocess.Popen] = None
|
self.process: Optional[subprocess.Popen] = None
|
||||||
|
|
||||||
|
def detect_os(self) -> str:
|
||||||
|
"""Detect the operating system"""
|
||||||
|
system = platform.system()
|
||||||
|
if system == 'Darwin':
|
||||||
|
return 'macos'
|
||||||
|
elif system == 'Linux':
|
||||||
|
return 'linux'
|
||||||
|
elif system == 'Windows':
|
||||||
|
return 'windows'
|
||||||
|
else:
|
||||||
|
return 'unknown'
|
||||||
|
|
||||||
|
def detect_cpu_arch(self) -> str:
|
||||||
|
"""Detect CPU architecture"""
|
||||||
|
machine = platform.machine().lower()
|
||||||
|
if machine in ['arm64', 'aarch64']:
|
||||||
|
return 'arm64'
|
||||||
|
elif machine in ['x86_64', 'amd64', 'x64']:
|
||||||
|
return 'x64'
|
||||||
|
else:
|
||||||
|
return machine
|
||||||
|
|
||||||
|
def get_latest_xmrig_version(self) -> Optional[str]:
|
||||||
|
"""Fetch the latest XMRig version from GitHub"""
|
||||||
|
try:
|
||||||
|
url = "https://api.github.com/repos/xmrig/xmrig/releases/latest"
|
||||||
|
req = urllib.request.Request(url)
|
||||||
|
req.add_header('User-Agent', 'Mozilla/5.0')
|
||||||
|
|
||||||
|
with urllib.request.urlopen(req, timeout=10) as response:
|
||||||
|
data = json.loads(response.read().decode())
|
||||||
|
return data['tag_name'].lstrip('v')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error fetching latest version: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def check_xmrig_installed(self) -> bool:
|
||||||
|
"""Check if xmrig is installed"""
|
||||||
|
# Check in script directory first
|
||||||
|
local_paths = [
|
||||||
|
os.path.join(self.script_dir, 'xmrig'),
|
||||||
|
os.path.join(self.script_dir, 'xmrig.exe'),
|
||||||
|
]
|
||||||
|
|
||||||
|
for path in local_paths:
|
||||||
|
if os.path.exists(path) and os.access(path, os.X_OK):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Check in system PATH
|
||||||
|
try:
|
||||||
|
result = subprocess.run(['which', 'xmrig'],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=5)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def download_and_install_xmrig(self) -> bool:
|
||||||
|
"""Download and install XMRig based on OS and architecture"""
|
||||||
|
os_type = self.detect_os()
|
||||||
|
arch = self.detect_cpu_arch()
|
||||||
|
|
||||||
|
print(f"\nDetected OS: {os_type}")
|
||||||
|
print(f"Detected Architecture: {arch}")
|
||||||
|
|
||||||
|
if os_type != 'macos':
|
||||||
|
print(f"\nAutomatic installation is currently only supported for macOS.")
|
||||||
|
print(f"Please install XMRig manually from: https://github.com/xmrig/xmrig/releases")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Get latest version
|
||||||
|
print("\nFetching latest XMRig version from GitHub...")
|
||||||
|
version = self.get_latest_xmrig_version()
|
||||||
|
|
||||||
|
if not version:
|
||||||
|
print("Could not determine latest version. Using default version 6.24.0")
|
||||||
|
version = "6.24.0"
|
||||||
|
|
||||||
|
print(f"Latest version: {version}")
|
||||||
|
|
||||||
|
# Determine filename based on architecture
|
||||||
|
if arch == 'arm64':
|
||||||
|
filename = f"xmrig-{version}-macos-arm64.tar.gz"
|
||||||
|
elif arch == 'x64':
|
||||||
|
filename = f"xmrig-{version}-macos-x64.tar.gz"
|
||||||
|
else:
|
||||||
|
print(f"Unsupported architecture: {arch}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
download_url = f"https://github.com/xmrig/xmrig/releases/download/v{version}/{filename}"
|
||||||
|
|
||||||
|
print(f"\nReady to download: {filename}")
|
||||||
|
print(f"URL: {download_url}")
|
||||||
|
|
||||||
|
# Prompt user
|
||||||
|
while True:
|
||||||
|
response = input("\nDownload and install XMRig? (Y/N): ").strip().upper()
|
||||||
|
if response in ['Y', 'N']:
|
||||||
|
break
|
||||||
|
print("Please enter Y or N")
|
||||||
|
|
||||||
|
if response == 'N':
|
||||||
|
print("Installation cancelled.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Download
|
||||||
|
print(f"\nDownloading {filename}...")
|
||||||
|
local_filename = os.path.join(self.script_dir, filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
urllib.request.urlretrieve(download_url, local_filename)
|
||||||
|
print("Download complete!")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error downloading file: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Extract
|
||||||
|
print("Extracting archive...")
|
||||||
|
try:
|
||||||
|
with tarfile.open(local_filename, 'r:gz') as tar:
|
||||||
|
# Find the xmrig binary in the archive
|
||||||
|
for member in tar.getmembers():
|
||||||
|
if member.name.endswith('/xmrig') or member.name == 'xmrig':
|
||||||
|
member.name = 'xmrig'
|
||||||
|
tar.extract(member, self.script_dir)
|
||||||
|
break
|
||||||
|
|
||||||
|
xmrig_path = os.path.join(self.script_dir, 'xmrig')
|
||||||
|
|
||||||
|
# Make executable
|
||||||
|
os.chmod(xmrig_path, 0o755)
|
||||||
|
print(f"XMRig installed successfully at: {xmrig_path}")
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
os.remove(local_filename)
|
||||||
|
print("Cleaned up temporary files.")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error extracting archive: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def prompt_wallet_address(self) -> str:
|
||||||
|
"""Prompt user for wallet address"""
|
||||||
|
default_wallet = "85NGrygcwq36kjLaNKZevT53H4EeHRQYeje5Y3gq3GYkKsEpwKpGjqd1tGxAVEjDfxEha6SYtyNYPbmPXduYqy47Q6JwbuW"
|
||||||
|
|
||||||
|
print("\n" + "="*60)
|
||||||
|
print("Monero Wallet Configuration")
|
||||||
|
print("="*60)
|
||||||
|
print(f"\nDefault wallet address:")
|
||||||
|
print(f"{default_wallet}")
|
||||||
|
print("\nPress ENTER to use the default wallet, or paste your own:")
|
||||||
|
|
||||||
|
wallet = input("Wallet Address: ").strip()
|
||||||
|
|
||||||
|
if not wallet:
|
||||||
|
wallet = default_wallet
|
||||||
|
print("Using default wallet address.")
|
||||||
|
else:
|
||||||
|
print("Using your wallet address.")
|
||||||
|
|
||||||
|
return wallet
|
||||||
|
|
||||||
|
def setup_initial_config(self):
|
||||||
|
"""Setup initial configuration with user input"""
|
||||||
|
os_type = self.detect_os()
|
||||||
|
arch = self.detect_cpu_arch()
|
||||||
|
is_mac = os_type == 'macos'
|
||||||
|
is_arm = arch == 'arm64'
|
||||||
|
|
||||||
|
# Get wallet address from user
|
||||||
|
wallet_address = self.prompt_wallet_address()
|
||||||
|
|
||||||
|
# Determine xmrig path
|
||||||
|
xmrig_path = os.path.join(self.script_dir, 'xmrig')
|
||||||
|
if is_mac:
|
||||||
|
miner_executable = "./xmrig"
|
||||||
|
else:
|
||||||
|
miner_executable = "xmrig"
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"wallet_address": wallet_address,
|
||||||
|
"mining_mode": "pool",
|
||||||
|
"miner_executable": miner_executable,
|
||||||
|
"pool_address": "pool.supportxmr.com:443",
|
||||||
|
"pool_password": "x",
|
||||||
|
"worker_name": f"m2-miner" if is_arm else "worker1",
|
||||||
|
"node_address": "127.0.0.1:18081",
|
||||||
|
"threads": 0,
|
||||||
|
"cpu_max_usage": 75,
|
||||||
|
"huge_pages": True if not is_mac else False,
|
||||||
|
"randomx_mode": "auto",
|
||||||
|
"tls_enabled": True,
|
||||||
|
"nicehash": False,
|
||||||
|
"extra_args": [],
|
||||||
|
"log_file": "monero-miner.log",
|
||||||
|
"api_port": 0,
|
||||||
|
"donate_level": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(self.config_file, 'w') as f:
|
||||||
|
json.dump(config, f, indent=4)
|
||||||
|
|
||||||
|
print(f"\nConfiguration saved to: {self.config_file}")
|
||||||
|
return config
|
||||||
|
|
||||||
def load_config(self) -> Dict:
|
def load_config(self) -> Dict:
|
||||||
"""Load configuration from JSON file"""
|
"""Load configuration from JSON file"""
|
||||||
if not os.path.exists(self.config_file):
|
if not os.path.exists(self.config_file):
|
||||||
print(f"Configuration file '{self.config_file}' not found.")
|
print(f"Configuration file '{self.config_file}' not found.")
|
||||||
print("Creating example configuration file...")
|
print("Setting up initial configuration...")
|
||||||
self.create_example_config()
|
return None
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.config_file, 'r') as f:
|
with open(self.config_file, 'r') as f:
|
||||||
@@ -54,48 +268,32 @@ class MoneroMiner:
|
|||||||
if config['mining_mode'] == 'pool' and 'pool_address' not in config:
|
if config['mining_mode'] == 'pool' and 'pool_address' not in config:
|
||||||
raise ValueError("pool_address is required for pool mining")
|
raise ValueError("pool_address is required for pool mining")
|
||||||
|
|
||||||
def create_example_config(self):
|
def initialize(self):
|
||||||
"""Create an example configuration file with platform-specific defaults"""
|
"""Initialize the miner - check for xmrig and setup config"""
|
||||||
is_mac = platform.system() == 'Darwin'
|
# Check if xmrig is installed
|
||||||
is_arm = platform.machine().lower() in ['arm64', 'aarch64']
|
xmrig_was_just_installed = False
|
||||||
|
|
||||||
example_config = {
|
if not self.check_xmrig_installed():
|
||||||
"wallet_address": "YOUR_MONERO_WALLET_ADDRESS_HERE",
|
print("\n" + "="*60)
|
||||||
"mining_mode": "pool",
|
print("XMRig Not Detected")
|
||||||
"miner_executable": "xmrig" if not is_mac else "./xmrig",
|
print("="*60)
|
||||||
"pool_address": "pool.supportxmr.com:443",
|
print("\nXMRig mining software is not installed.")
|
||||||
"pool_password": "x",
|
|
||||||
"worker_name": f"m2-miner" if is_arm else "worker1",
|
# Try to install
|
||||||
"node_address": "127.0.0.1:18081",
|
if not self.download_and_install_xmrig():
|
||||||
"threads": 0,
|
print("\nPlease install XMRig manually and try again.")
|
||||||
"cpu_max_usage": 75,
|
sys.exit(1)
|
||||||
"huge_pages": True if not is_mac else False,
|
|
||||||
"randomx_mode": "auto",
|
xmrig_was_just_installed = True
|
||||||
"tls_enabled": True,
|
else:
|
||||||
"nicehash": False,
|
print("\nXMRig detected ✓")
|
||||||
"extra_args": [],
|
|
||||||
"log_file": "monero-miner.log",
|
|
||||||
"api_port": 0,
|
|
||||||
"donate_level": 1
|
|
||||||
}
|
|
||||||
|
|
||||||
with open(self.config_file, 'w') as f:
|
# Load or create config
|
||||||
json.dump(example_config, f, indent=4)
|
self.config = self.load_config()
|
||||||
|
|
||||||
print(f"Created example configuration file: {self.config_file}")
|
# If config doesn't exist OR xmrig was just installed, setup new config with wallet prompt
|
||||||
print("\n" + "="*60)
|
if self.config is None or xmrig_was_just_installed:
|
||||||
print("IMPORTANT: Edit the configuration file and set your wallet!")
|
self.config = self.setup_initial_config()
|
||||||
print("="*60)
|
|
||||||
if is_mac:
|
|
||||||
print("\nFor Mac users:")
|
|
||||||
print("1. Download XMRig from: https://github.com/xmrig/xmrig/releases")
|
|
||||||
print("2. Extract and place 'xmrig' binary in the same folder as this script")
|
|
||||||
print("3. Run: chmod +x xmrig")
|
|
||||||
print("\nPopular Monero pools:")
|
|
||||||
print(" - SupportXMR: pool.supportxmr.com:443")
|
|
||||||
print(" - MoneroOcean: gulf.moneroocean.stream:10128")
|
|
||||||
print(" - Nanopool: xmr-us-east1.nanopool.org:14433")
|
|
||||||
print(" - MineXMR: pool.minexmr.com:443")
|
|
||||||
|
|
||||||
def build_command(self) -> list:
|
def build_command(self) -> list:
|
||||||
"""Build the XMRig mining command based on configuration"""
|
"""Build the XMRig mining command based on configuration"""
|
||||||
@@ -103,9 +301,6 @@ class MoneroMiner:
|
|||||||
|
|
||||||
# Add wallet address
|
# Add wallet address
|
||||||
wallet = self.config['wallet_address']
|
wallet = self.config['wallet_address']
|
||||||
if wallet == "YOUR_MONERO_WALLET_ADDRESS_HERE":
|
|
||||||
print("Error: Please set your Monero wallet address in the config file!")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Configure based on mining mode
|
# Configure based on mining mode
|
||||||
if self.config['mining_mode'] == 'solo':
|
if self.config['mining_mode'] == 'solo':
|
||||||
@@ -227,13 +422,7 @@ class MoneroMiner:
|
|||||||
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f"\nError: Miner executable '{cmd[0]}' not found.")
|
print(f"\nError: Miner executable '{cmd[0]}' not found.")
|
||||||
print("\nFor macOS/Apple Silicon:")
|
print("\nPlease ensure XMRig is properly installed.")
|
||||||
print("1. Download XMRig from: https://github.com/xmrig/xmrig/releases")
|
|
||||||
print("2. Look for 'xmrig-X.X.X-macos-arm64.tar.gz' for M2 Mac")
|
|
||||||
print("3. Extract and place 'xmrig' in the same folder as this script")
|
|
||||||
print("4. Run: chmod +x xmrig")
|
|
||||||
print("\nFor Linux:")
|
|
||||||
print(" sudo apt install xmrig # or download from GitHub")
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error starting miner: {e}")
|
print(f"Error starting miner: {e}")
|
||||||
@@ -276,10 +465,14 @@ def main():
|
|||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
config_file = sys.argv[1]
|
config_file = sys.argv[1]
|
||||||
|
|
||||||
# Create and start miner
|
# Create miner instance
|
||||||
miner = MoneroMiner(config_file)
|
miner = MoneroMiner(config_file)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Initialize (check xmrig, setup config)
|
||||||
|
miner.initialize()
|
||||||
|
|
||||||
|
# Show stats info and start mining
|
||||||
miner.show_stats()
|
miner.show_stats()
|
||||||
miner.start_mining()
|
miner.start_mining()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
@@ -287,7 +480,8 @@ def main():
|
|||||||
miner.stop_mining()
|
miner.stop_mining()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"\nError: {e}")
|
print(f"\nError: {e}")
|
||||||
miner.stop_mining()
|
if miner.process:
|
||||||
|
miner.stop_mining()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in new issue
Block a user