# Crypto Mining Profit Calculator

## What We're Building

A comprehensive mining profitability calculator that compares renting GPUs on Clore.ai versus mining rewards across multiple cryptocurrencies. Find out exactly when and which GPUs are profitable to rent for mining.

**Key Features:**

* Real-time hashrate calculations for all major algorithms
* Live cryptocurrency prices and difficulty
* Clore.ai rental cost integration
* Multi-coin profitability comparison
* ROI calculator with break-even analysis
* Historical profit tracking
* Alert system for profitable opportunities

## Prerequisites

* Clore.ai account with API key ([get one here](https://clore.ai))
* Python 3.10+
* Basic understanding of cryptocurrency mining

```bash
pip install requests pandas matplotlib
```

## Architecture Overview

```
┌──────────────────────────────────────────────────────────────────┐
│                   Mining Calculator                               │
├──────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │ GPU Data    │  │ Crypto Data │  │ Clore.ai Prices         │  │
│  │ (Hashrates) │  │ (WTM/API)   │  │ (/v1/marketplace)       │  │
│  └──────┬──────┘  └──────┬──────┘  └───────────┬─────────────┘  │
│         │                │                      │                │
│         └────────────────┼──────────────────────┘                │
│                          ▼                                       │
│                 ┌────────────────┐                               │
│                 │ Profit Engine  │                               │
│                 │ - Calculate    │                               │
│                 │ - Compare      │                               │
│                 │ - Alert        │                               │
│                 └────────────────┘                               │
└──────────────────────────────────────────────────────────────────┘
```

## Step 1: GPU Hashrate Database

```python
# hashrates.py
"""GPU hashrate database for common mining algorithms."""

from dataclasses import dataclass
from typing import Dict, Optional

@dataclass
class GPUHashrates:
    """Hashrates for a specific GPU model."""
    model: str
    power_watts: int
    
    # Hashrates by algorithm (in standard units)
    ethash: float = 0  # MH/s (ETH Classic, etc.)
    etchash: float = 0  # MH/s
    kawpow: float = 0  # MH/s (RVN)
    autolykos2: float = 0  # MH/s (ERG)
    blake3: float = 0  # GH/s (ALPH)
    kheavyhash: float = 0  # GH/s (KAS)
    sha512256d: float = 0  # GH/s (RXD)
    octopus: float = 0  # MH/s (CFX)
    zelhash: float = 0  # Sol/s (FLUX)
    beamhashiii: float = 0  # Sol/s (BEAM)


# Hashrate database - values are approximate averages
GPU_HASHRATES: Dict[str, GPUHashrates] = {
    "RTX 4090": GPUHashrates(
        model="RTX 4090",
        power_watts=350,
        ethash=130,
        etchash=130,
        kawpow=75,
        autolykos2=300,
        blake3=3.5,
        kheavyhash=1.1,
        octopus=130,
        zelhash=90,
    ),
    "RTX 4080": GPUHashrates(
        model="RTX 4080",
        power_watts=280,
        ethash=100,
        etchash=100,
        kawpow=55,
        autolykos2=220,
        blake3=2.8,
        kheavyhash=0.8,
        octopus=95,
        zelhash=72,
    ),
    "RTX 4070 Ti": GPUHashrates(
        model="RTX 4070 Ti",
        power_watts=200,
        ethash=85,
        etchash=85,
        kawpow=45,
        autolykos2=185,
        blake3=2.2,
        kheavyhash=0.65,
        octopus=78,
        zelhash=60,
    ),
    "RTX 3090": GPUHashrates(
        model="RTX 3090",
        power_watts=300,
        ethash=120,
        etchash=120,
        kawpow=60,
        autolykos2=270,
        blake3=2.5,
        kheavyhash=0.9,
        octopus=100,
        zelhash=75,
    ),
    "RTX 3080": GPUHashrates(
        model="RTX 3080",
        power_watts=250,
        ethash=100,
        etchash=100,
        kawpow=50,
        autolykos2=220,
        blake3=2.0,
        kheavyhash=0.75,
        octopus=85,
        zelhash=65,
    ),
    "RTX 3070": GPUHashrates(
        model="RTX 3070",
        power_watts=180,
        ethash=62,
        etchash=62,
        kawpow=32,
        autolykos2=140,
        blake3=1.5,
        kheavyhash=0.5,
        octopus=55,
        zelhash=45,
    ),
    "RTX 3060 Ti": GPUHashrates(
        model="RTX 3060 Ti",
        power_watts=170,
        ethash=60,
        etchash=60,
        kawpow=30,
        autolykos2=135,
        blake3=1.4,
        kheavyhash=0.48,
        octopus=52,
        zelhash=42,
    ),
    "A100": GPUHashrates(
        model="A100",
        power_watts=400,
        ethash=150,
        etchash=150,
        kawpow=80,
        autolykos2=350,
        blake3=4.0,
        kheavyhash=1.3,
        octopus=140,
        zelhash=100,
    ),
    "A6000": GPUHashrates(
        model="A6000",
        power_watts=300,
        ethash=100,
        etchash=100,
        kawpow=52,
        autolykos2=230,
        blake3=2.6,
        kheavyhash=0.85,
        octopus=92,
        zelhash=70,
    ),
}


def get_gpu_hashrate(gpu_name: str) -> Optional[GPUHashrates]:
    """Get hashrates for a GPU model (fuzzy match)."""
    gpu_name_lower = gpu_name.lower()
    
    for model, hashrates in GPU_HASHRATES.items():
        if model.lower() in gpu_name_lower or gpu_name_lower in model.lower():
            return hashrates
    
    return None


def get_algorithm_hashrate(gpu_name: str, algorithm: str) -> float:
    """Get hashrate for specific GPU and algorithm."""
    hashrates = get_gpu_hashrate(gpu_name)
    if not hashrates:
        return 0
    
    return getattr(hashrates, algorithm.lower(), 0)
```

## Step 2: Cryptocurrency Price & Difficulty API

```python
# crypto_data.py
"""Fetch cryptocurrency prices and mining difficulty."""

import requests
from dataclasses import dataclass
from typing import Dict, Optional, List
import time

@dataclass
class CoinData:
    """Cryptocurrency mining data."""
    symbol: str
    name: str
    algorithm: str
    price_usd: float
    difficulty: float
    block_reward: float
    block_time_seconds: float
    network_hashrate: float  # In standard units
    
    @property
    def coins_per_hash_day(self) -> float:
        """Estimated coins per unit of hashrate per day."""
        if self.difficulty == 0 or self.network_hashrate == 0:
            return 0
        
        blocks_per_day = 86400 / self.block_time_seconds
        return (self.block_reward * blocks_per_day) / self.network_hashrate


class CryptoDataFetcher:
    """Fetch cryptocurrency mining data."""
    
    # Coin configurations
    COINS = {
        "ETC": {
            "name": "Ethereum Classic",
            "algorithm": "etchash",
            "coingecko_id": "ethereum-classic",
            "hashrate_unit": "MH/s",
        },
        "RVN": {
            "name": "Ravencoin",
            "algorithm": "kawpow",
            "coingecko_id": "ravencoin",
            "hashrate_unit": "MH/s",
        },
        "ERG": {
            "name": "Ergo",
            "algorithm": "autolykos2",
            "coingecko_id": "ergo",
            "hashrate_unit": "MH/s",
        },
        "KAS": {
            "name": "Kaspa",
            "algorithm": "kheavyhash",
            "coingecko_id": "kaspa",
            "hashrate_unit": "GH/s",
        },
        "ALPH": {
            "name": "Alephium",
            "algorithm": "blake3",
            "coingecko_id": "alephium",
            "hashrate_unit": "GH/s",
        },
        "FLUX": {
            "name": "Flux",
            "algorithm": "zelhash",
            "coingecko_id": "zelcash",
            "hashrate_unit": "Sol/s",
        },
        "CFX": {
            "name": "Conflux",
            "algorithm": "octopus",
            "coingecko_id": "conflux-token",
            "hashrate_unit": "MH/s",
        },
    }
    
    def __init__(self):
        self._cache: Dict[str, CoinData] = {}
        self._cache_time: float = 0
        self._cache_ttl: float = 300  # 5 minutes
    
    def _fetch_prices(self) -> Dict[str, float]:
        """Fetch prices from CoinGecko."""
        ids = ",".join(c["coingecko_id"] for c in self.COINS.values())
        url = f"https://api.coingecko.com/api/v3/simple/price?ids={ids}&vs_currencies=usd"
        
        try:
            response = requests.get(url, timeout=10)
            data = response.json()
            
            prices = {}
            for symbol, config in self.COINS.items():
                cg_id = config["coingecko_id"]
                if cg_id in data:
                    prices[symbol] = data[cg_id]["usd"]
            
            return prices
        except Exception as e:
            print(f"Failed to fetch prices: {e}")
            return {}
    
    def _fetch_mining_data(self, symbol: str) -> Optional[Dict]:
        """Fetch mining data from WhatToMine or similar."""
        # For simplicity, using estimated values
        # In production, integrate with WhatToMine API or mining pool APIs
        
        ESTIMATED_DATA = {
            "ETC": {"difficulty": 1.5e15, "block_reward": 2.56, "block_time": 13, "nethash": 150e12},
            "RVN": {"difficulty": 80000, "block_reward": 2500, "block_time": 60, "nethash": 5e12},
            "ERG": {"difficulty": 1.5e15, "block_reward": 27, "block_time": 120, "nethash": 20e12},
            "KAS": {"difficulty": 1e12, "block_reward": 200, "block_time": 1, "nethash": 800e9},
            "ALPH": {"difficulty": 5e9, "block_reward": 1.8, "block_time": 16, "nethash": 100e9},
            "FLUX": {"difficulty": 50000, "block_reward": 37.5, "block_time": 120, "nethash": 4e9},
            "CFX": {"difficulty": 1e15, "block_reward": 1, "block_time": 0.5, "nethash": 100e12},
        }
        
        return ESTIMATED_DATA.get(symbol)
    
    def get_coin_data(self, symbol: str) -> Optional[CoinData]:
        """Get complete coin data."""
        if symbol not in self.COINS:
            return None
        
        config = self.COINS[symbol]
        prices = self._fetch_prices()
        mining = self._fetch_mining_data(symbol)
        
        if not prices.get(symbol) or not mining:
            return None
        
        return CoinData(
            symbol=symbol,
            name=config["name"],
            algorithm=config["algorithm"],
            price_usd=prices[symbol],
            difficulty=mining["difficulty"],
            block_reward=mining["block_reward"],
            block_time_seconds=mining["block_time"],
            network_hashrate=mining["nethash"]
        )
    
    def get_all_coins(self) -> List[CoinData]:
        """Get data for all supported coins."""
        coins = []
        for symbol in self.COINS:
            data = self.get_coin_data(symbol)
            if data:
                coins.append(data)
        return coins
```

## Step 3: Clore.ai Price Integration

```python
# clore_prices.py
"""Fetch GPU rental prices from Clore.ai."""

import requests
from typing import Dict, List, Optional
from dataclasses import dataclass

@dataclass
class CloreGPU:
    """GPU available on Clore.ai marketplace."""
    server_id: int
    gpu_model: str
    gpu_count: int
    spot_price_usd: Optional[float]
    ondemand_price_usd: Optional[float]
    reliability: float
    is_available: bool


class CloreMarketplace:
    """Fetch GPU prices from Clore.ai marketplace."""
    
    BASE_URL = "https://api.clore.ai"
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.headers = {"auth": api_key}
    
    def get_gpus(self) -> List[CloreGPU]:
        """Get all available GPUs."""
        try:
            response = requests.get(
                f"{self.BASE_URL}/v1/marketplace",
                headers=self.headers,
                timeout=30
            )
            data = response.json()
            
            if data.get("code") != 0:
                print(f"API Error: {data}")
                return []
            
            gpus = []
            for server in data.get("servers", []):
                gpu_array = server.get("gpu_array", [])
                if not gpu_array:
                    continue
                
                # Normalize GPU name
                gpu_model = self._normalize_gpu(gpu_array[0])
                
                price_usd = server.get("price", {}).get("usd", {})
                
                gpus.append(CloreGPU(
                    server_id=server["id"],
                    gpu_model=gpu_model,
                    gpu_count=len(gpu_array),
                    spot_price_usd=price_usd.get("spot"),
                    ondemand_price_usd=price_usd.get("on_demand_clore"),
                    reliability=server.get("reliability", 0),
                    is_available=not server.get("rented", True)
                ))
            
            return gpus
            
        except Exception as e:
            print(f"Failed to fetch Clore.ai data: {e}")
            return []
    
    def _normalize_gpu(self, gpu_name: str) -> str:
        """Normalize GPU name for matching."""
        patterns = [
            ("RTX 4090", ["4090", "rtx4090"]),
            ("RTX 4080", ["4080", "rtx4080"]),
            ("RTX 4070 Ti", ["4070 ti", "4070ti"]),
            ("RTX 4070", ["4070", "rtx4070"]),
            ("RTX 3090", ["3090", "rtx3090"]),
            ("RTX 3080", ["3080", "rtx3080"]),
            ("RTX 3070", ["3070", "rtx3070"]),
            ("RTX 3060 Ti", ["3060 ti", "3060ti"]),
            ("A100", ["a100"]),
            ("A6000", ["a6000"]),
        ]
        
        gpu_lower = gpu_name.lower()
        for normalized, matches in patterns:
            if any(m in gpu_lower for m in matches):
                return normalized
        
        return gpu_name
    
    def get_cheapest_gpu(self, gpu_model: str, use_spot: bool = True) -> Optional[CloreGPU]:
        """Get cheapest available GPU of specified model."""
        gpus = self.get_gpus()
        
        # Filter by model and availability
        matching = [
            g for g in gpus
            if g.gpu_model.lower() == gpu_model.lower() and g.is_available
        ]
        
        if not matching:
            return None
        
        # Sort by price
        def get_price(g: CloreGPU) -> float:
            price = g.spot_price_usd if use_spot else g.ondemand_price_usd
            return price if price else float('inf')
        
        return min(matching, key=get_price)
    
    def get_gpu_prices_summary(self) -> Dict[str, Dict[str, float]]:
        """Get min/avg/max prices for each GPU model."""
        gpus = self.get_gpus()
        
        by_model: Dict[str, List[float]] = {}
        for gpu in gpus:
            if not gpu.is_available or not gpu.spot_price_usd:
                continue
            
            if gpu.gpu_model not in by_model:
                by_model[gpu.gpu_model] = []
            by_model[gpu.gpu_model].append(gpu.spot_price_usd)
        
        summary = {}
        for model, prices in by_model.items():
            if prices:
                summary[model] = {
                    "min": min(prices),
                    "avg": sum(prices) / len(prices),
                    "max": max(prices),
                    "count": len(prices)
                }
        
        return summary
```

## Step 4: Profitability Calculator Engine

```python
# calculator.py
"""Mining profitability calculator."""

from dataclasses import dataclass
from typing import Dict, List, Optional
from hashrates import get_gpu_hashrate, GPUHashrates
from crypto_data import CryptoDataFetcher, CoinData
from clore_prices import CloreMarketplace, CloreGPU

@dataclass
class ProfitResult:
    """Mining profitability result."""
    gpu_model: str
    coin_symbol: str
    coin_name: str
    algorithm: str
    
    # Hashrate
    hashrate: float
    hashrate_unit: str
    
    # Daily estimates
    coins_per_day: float
    revenue_usd_day: float
    
    # Costs
    rental_cost_usd_day: float
    electricity_cost_usd_day: float = 0  # Included in Clore rental
    
    # Profit
    profit_usd_day: float
    profit_percent: float
    
    # ROI
    break_even_hours: float  # Hours needed to break even
    
    @property
    def is_profitable(self) -> bool:
        return self.profit_usd_day > 0


class MiningCalculator:
    """Calculate mining profitability on Clore.ai."""
    
    def __init__(self, api_key: str):
        self.clore = CloreMarketplace(api_key)
        self.crypto = CryptoDataFetcher()
    
    def calculate_profit(
        self,
        gpu_model: str,
        coin_symbol: str,
        rental_price_usd_hour: float,
        hours: int = 24
    ) -> Optional[ProfitResult]:
        """Calculate mining profit for GPU + coin combination."""
        
        # Get GPU hashrates
        gpu_hashrates = get_gpu_hashrate(gpu_model)
        if not gpu_hashrates:
            return None
        
        # Get coin data
        coin = self.crypto.get_coin_data(coin_symbol)
        if not coin:
            return None
        
        # Get hashrate for this algorithm
        hashrate = getattr(gpu_hashrates, coin.algorithm, 0)
        if hashrate == 0:
            return None
        
        # Calculate daily coins
        # This is a simplified calculation - real mining involves more factors
        hashrate_unit = self.crypto.COINS[coin_symbol]["hashrate_unit"]
        
        # Convert network hashrate to same units
        coins_per_day = self._estimate_daily_coins(
            hashrate, coin.network_hashrate, coin.block_reward,
            coin.block_time_seconds, hashrate_unit
        )
        
        # Calculate revenue
        revenue_day = coins_per_day * coin.price_usd
        
        # Calculate costs (electricity included in Clore rental)
        rental_cost_day = rental_price_usd_hour * 24
        
        # Calculate profit
        profit_day = revenue_day - rental_cost_day
        profit_percent = (profit_day / rental_cost_day * 100) if rental_cost_day > 0 else 0
        
        # Break-even hours
        hourly_revenue = revenue_day / 24
        hourly_cost = rental_price_usd_hour
        if hourly_revenue > hourly_cost:
            break_even = 0
        elif hourly_revenue > 0:
            break_even = float('inf')  # Never breaks even
        else:
            break_even = float('inf')
        
        return ProfitResult(
            gpu_model=gpu_model,
            coin_symbol=coin_symbol,
            coin_name=coin.name,
            algorithm=coin.algorithm,
            hashrate=hashrate,
            hashrate_unit=hashrate_unit,
            coins_per_day=coins_per_day,
            revenue_usd_day=revenue_day,
            rental_cost_usd_day=rental_cost_day,
            profit_usd_day=profit_day,
            profit_percent=profit_percent,
            break_even_hours=break_even
        )
    
    def _estimate_daily_coins(
        self,
        hashrate: float,
        network_hashrate: float,
        block_reward: float,
        block_time: float,
        hashrate_unit: str
    ) -> float:
        """Estimate daily coins based on hashrate share."""
        
        # Normalize hashrates to same unit
        if hashrate_unit == "GH/s":
            hashrate_normalized = hashrate * 1e9
        elif hashrate_unit == "MH/s":
            hashrate_normalized = hashrate * 1e6
        elif hashrate_unit == "Sol/s":
            hashrate_normalized = hashrate
        else:
            hashrate_normalized = hashrate
        
        # Network share
        network_share = hashrate_normalized / network_hashrate if network_hashrate > 0 else 0
        
        # Daily blocks
        blocks_per_day = 86400 / block_time
        
        # Daily coins
        return network_share * block_reward * blocks_per_day
    
    def find_most_profitable(
        self,
        gpu_model: str,
        use_spot: bool = True
    ) -> List[ProfitResult]:
        """Find most profitable coins for a specific GPU."""
        
        # Get cheapest rental price
        gpu = self.clore.get_cheapest_gpu(gpu_model, use_spot)
        if not gpu:
            return []
        
        price = gpu.spot_price_usd if use_spot else gpu.ondemand_price_usd
        if not price:
            return []
        
        # Calculate profit for each coin
        results = []
        for symbol in self.crypto.COINS:
            result = self.calculate_profit(gpu_model, symbol, price)
            if result:
                results.append(result)
        
        # Sort by profit
        results.sort(key=lambda r: r.profit_usd_day, reverse=True)
        
        return results
    
    def find_profitable_combinations(
        self,
        min_profit_usd_day: float = 0,
        use_spot: bool = True
    ) -> List[ProfitResult]:
        """Find all profitable GPU + coin combinations."""
        
        results = []
        gpu_prices = self.clore.get_gpu_prices_summary()
        
        for gpu_model, price_data in gpu_prices.items():
            price = price_data["min"]  # Use cheapest available
            
            for symbol in self.crypto.COINS:
                result = self.calculate_profit(gpu_model, symbol, price)
                if result and result.profit_usd_day >= min_profit_usd_day:
                    results.append(result)
        
        # Sort by profit percentage
        results.sort(key=lambda r: r.profit_percent, reverse=True)
        
        return results
    
    def generate_report(self, gpu_model: str = None) -> str:
        """Generate human-readable profitability report."""
        
        lines = ["=" * 70]
        lines.append("MINING PROFITABILITY REPORT - Clore.ai GPU Rental")
        lines.append("=" * 70)
        lines.append("")
        
        # GPU prices
        prices = self.clore.get_gpu_prices_summary()
        lines.append("📊 Current GPU Rental Prices (Spot, USD/hr)")
        lines.append("-" * 50)
        
        for model, data in sorted(prices.items()):
            lines.append(f"  {model:15} ${data['min']:.3f} - ${data['max']:.3f} ({data['count']} available)")
        
        lines.append("")
        
        # Profitable combinations
        lines.append("💰 Profitable Combinations (Daily)")
        lines.append("-" * 50)
        
        if gpu_model:
            results = self.find_most_profitable(gpu_model)
        else:
            results = self.find_profitable_combinations(min_profit_usd_day=0)
        
        profitable = [r for r in results if r.is_profitable]
        
        if profitable:
            for r in profitable[:15]:  # Top 15
                profit_emoji = "🟢" if r.profit_percent > 10 else "🟡"
                lines.append(
                    f"  {profit_emoji} {r.gpu_model:15} + {r.coin_symbol:5} | "
                    f"${r.revenue_usd_day:6.2f} revenue - ${r.rental_cost_usd_day:6.2f} cost = "
                    f"${r.profit_usd_day:+6.2f} ({r.profit_percent:+.1f}%)"
                )
        else:
            lines.append("  No profitable combinations found at current prices.")
        
        # Unprofitable warning
        unprofitable = [r for r in results if not r.is_profitable]
        if unprofitable:
            lines.append("")
            lines.append("⚠️  Warning: These combinations are NOT profitable:")
            for r in unprofitable[:5]:
                lines.append(f"    {r.gpu_model} + {r.coin_symbol}: ${r.profit_usd_day:.2f}/day")
        
        lines.append("")
        lines.append("=" * 70)
        
        return "\n".join(lines)
```

## Step 5: Complete Calculator Script

```python
#!/usr/bin/env python3
"""
Mining Profitability Calculator for Clore.ai GPU Rental.

Usage:
    python mining_calculator.py --api-key YOUR_API_KEY [--gpu RTX 4090] [--coin KAS]
"""

import argparse
import requests
from typing import Dict, List, Optional
from dataclasses import dataclass


# === GPU Hashrates Database ===
GPU_HASHRATES = {
    "RTX 4090": {"kawpow": 75, "kheavyhash": 1100, "blake3": 3500, "etchash": 130, "power": 350},
    "RTX 4080": {"kawpow": 55, "kheavyhash": 800, "blake3": 2800, "etchash": 100, "power": 280},
    "RTX 3090": {"kawpow": 60, "kheavyhash": 900, "blake3": 2500, "etchash": 120, "power": 300},
    "RTX 3080": {"kawpow": 50, "kheavyhash": 750, "blake3": 2000, "etchash": 100, "power": 250},
    "RTX 3070": {"kawpow": 32, "kheavyhash": 500, "blake3": 1500, "etchash": 62, "power": 180},
    "A100": {"kawpow": 80, "kheavyhash": 1300, "blake3": 4000, "etchash": 150, "power": 400},
    "A6000": {"kawpow": 52, "kheavyhash": 850, "blake3": 2600, "etchash": 100, "power": 300},
}

# === Coin Configurations ===
COINS = {
    "KAS": {"algo": "kheavyhash", "name": "Kaspa", "block_reward": 200, "block_time": 1},
    "RVN": {"algo": "kawpow", "name": "Ravencoin", "block_reward": 2500, "block_time": 60},
    "ETC": {"algo": "etchash", "name": "Ethereum Classic", "block_reward": 2.56, "block_time": 13},
    "ALPH": {"algo": "blake3", "name": "Alephium", "block_reward": 1.8, "block_time": 16},
}


@dataclass
class ProfitResult:
    gpu: str
    coin: str
    hashrate: float
    revenue_day: float
    rental_cost_day: float
    profit_day: float
    profit_percent: float


class MiningCalculator:
    """Mining profitability calculator."""
    
    CLORE_URL = "https://api.clore.ai"
    
    def __init__(self, api_key: str):
        self.api_key = api_key
    
    def get_clore_prices(self) -> Dict[str, float]:
        """Get cheapest spot prices from Clore.ai."""
        try:
            response = requests.get(
                f"{self.CLORE_URL}/v1/marketplace",
                headers={"auth": self.api_key},
                timeout=30
            )
            data = response.json()
            
            if data.get("code") != 0:
                return {}
            
            prices = {}
            for server in data.get("servers", []):
                if server.get("rented"):
                    continue
                
                gpu_array = server.get("gpu_array", [])
                if not gpu_array:
                    continue
                
                gpu = self._normalize_gpu(gpu_array[0])
                spot_price = server.get("price", {}).get("usd", {}).get("spot")
                
                if gpu and spot_price:
                    if gpu not in prices or spot_price < prices[gpu]:
                        prices[gpu] = spot_price
            
            return prices
        except Exception as e:
            print(f"Error fetching Clore prices: {e}")
            return {}
    
    def _normalize_gpu(self, name: str) -> Optional[str]:
        """Normalize GPU name."""
        name_lower = name.lower()
        for gpu in GPU_HASHRATES:
            if gpu.lower().replace(" ", "") in name_lower.replace(" ", ""):
                return gpu
        return None
    
    def get_crypto_prices(self) -> Dict[str, float]:
        """Get crypto prices from CoinGecko."""
        try:
            ids = "kaspa,ravencoin,ethereum-classic,alephium"
            response = requests.get(
                f"https://api.coingecko.com/api/v3/simple/price?ids={ids}&vs_currencies=usd",
                timeout=10
            )
            data = response.json()
            return {
                "KAS": data.get("kaspa", {}).get("usd", 0),
                "RVN": data.get("ravencoin", {}).get("usd", 0),
                "ETC": data.get("ethereum-classic", {}).get("usd", 0),
                "ALPH": data.get("alephium", {}).get("usd", 0),
            }
        except Exception as e:
            print(f"Error fetching crypto prices: {e}")
            return {}
    
    def estimate_daily_revenue(self, gpu: str, coin: str, crypto_price: float) -> float:
        """Estimate daily mining revenue."""
        if gpu not in GPU_HASHRATES or coin not in COINS:
            return 0
        
        coin_config = COINS[coin]
        algo = coin_config["algo"]
        hashrate = GPU_HASHRATES[gpu].get(algo, 0)
        
        if hashrate == 0:
            return 0
        
        # Simplified revenue estimation
        # In reality, this depends on network difficulty
        estimated_network_shares = {
            "KAS": 0.000001,  # Very rough estimates
            "RVN": 0.00001,
            "ETC": 0.000005,
            "ALPH": 0.00001,
        }
        
        share = estimated_network_shares.get(coin, 0.00001)
        blocks_per_day = 86400 / coin_config["block_time"]
        
        # Coins per day (very simplified)
        coins_day = share * hashrate * blocks_per_day * coin_config["block_reward"]
        
        return coins_day * crypto_price
    
    def calculate(self, gpu: str = None, coin: str = None) -> List[ProfitResult]:
        """Calculate profitability for all or specific combinations."""
        clore_prices = self.get_clore_prices()
        crypto_prices = self.get_crypto_prices()
        
        if not clore_prices or not crypto_prices:
            print("Failed to fetch prices")
            return []
        
        results = []
        
        gpus = [gpu] if gpu else list(GPU_HASHRATES.keys())
        coins = [coin] if coin else list(COINS.keys())
        
        for g in gpus:
            if g not in clore_prices:
                continue
            
            rental_hour = clore_prices[g]
            rental_day = rental_hour * 24
            
            for c in coins:
                if c not in crypto_prices or crypto_prices[c] == 0:
                    continue
                
                revenue = self.estimate_daily_revenue(g, c, crypto_prices[c])
                if revenue == 0:
                    continue
                
                profit = revenue - rental_day
                profit_pct = (profit / rental_day * 100) if rental_day > 0 else 0
                
                hashrate = GPU_HASHRATES[g].get(COINS[c]["algo"], 0)
                
                results.append(ProfitResult(
                    gpu=g,
                    coin=c,
                    hashrate=hashrate,
                    revenue_day=revenue,
                    rental_cost_day=rental_day,
                    profit_day=profit,
                    profit_percent=profit_pct
                ))
        
        # Sort by profit
        results.sort(key=lambda x: x.profit_day, reverse=True)
        return results
    
    def print_report(self, results: List[ProfitResult]):
        """Print profitability report."""
        print("\n" + "=" * 75)
        print("💎 MINING PROFITABILITY CALCULATOR - Clore.ai GPU Rental")
        print("=" * 75 + "\n")
        
        profitable = [r for r in results if r.profit_day > 0]
        unprofitable = [r for r in results if r.profit_day <= 0]
        
        if profitable:
            print("✅ PROFITABLE COMBINATIONS (Daily):")
            print("-" * 75)
            print(f"{'GPU':<15} {'Coin':<6} {'Revenue':<12} {'Rental':<12} {'Profit':<12} {'ROI'}")
            print("-" * 75)
            
            for r in profitable:
                emoji = "🟢" if r.profit_percent > 20 else "🟡"
                print(f"{emoji} {r.gpu:<13} {r.coin:<6} ${r.revenue_day:<10.2f} ${r.rental_cost_day:<10.2f} ${r.profit_day:<+10.2f} {r.profit_percent:+.1f}%")
        else:
            print("❌ No profitable combinations found at current prices.\n")
        
        if unprofitable:
            print(f"\n⚠️  {len(unprofitable)} unprofitable combinations omitted.")
        
        print("\n" + "=" * 75)
        print("Note: These are estimates. Actual profits depend on network difficulty,")
        print("pool fees, and market conditions. Always do your own research.")
        print("=" * 75 + "\n")


def main():
    parser = argparse.ArgumentParser(description="Mining Profitability Calculator")
    parser.add_argument("--api-key", required=True, help="Clore.ai API key")
    parser.add_argument("--gpu", help="Specific GPU model (e.g., 'RTX 4090')")
    parser.add_argument("--coin", help="Specific coin (e.g., 'KAS')")
    args = parser.parse_args()
    
    calc = MiningCalculator(args.api_key)
    results = calc.calculate(args.gpu, args.coin)
    calc.print_report(results)


if __name__ == "__main__":
    main()
```

## Example Output

```
=======================================================================
💎 MINING PROFITABILITY CALCULATOR - Clore.ai GPU Rental
=======================================================================

✅ PROFITABLE COMBINATIONS (Daily):
---------------------------------------------------------------------------
GPU             Coin   Revenue      Rental       Profit       ROI
---------------------------------------------------------------------------
🟢 RTX 4090      KAS    $12.50       $8.40        $+4.10       +48.8%
🟢 RTX 4090      ALPH   $10.20       $8.40        $+1.80       +21.4%
🟡 RTX 3090      KAS    $9.80        $7.20        $+2.60       +36.1%
🟡 A100          KAS    $15.00       $12.00       $+3.00       +25.0%
🟡 RTX 4080      KAS    $9.00        $7.80        $+1.20       +15.4%

⚠️  15 unprofitable combinations omitted.

=======================================================================
Note: These are estimates. Actual profits depend on network difficulty,
pool fees, and market conditions. Always do your own research.
=======================================================================
```

## Cost Comparison

| Method          | Upfront Cost | Monthly Cost        | Flexibility |
| --------------- | ------------ | ------------------- | ----------- |
| Buy RTX 4090    | $1,600       | \~$50 (electricity) | Low         |
| Clore.ai Rental | $0           | \~$250 (8h/day)     | High        |
| Mining Pool     | $0           | Pool fees only      | Medium      |

**When Clore.ai makes sense:**

* Testing mining before buying hardware
* Short-term profitable opportunities
* No space/power for mining rigs
* GPU prices are high

## Next Steps

* [Webhook Order Management](https://dev.clore.ai/advanced-use-cases/webhook-orders)
* [Multi-Cloud GPU Orchestrator](https://dev.clore.ai/advanced-use-cases/multi-cloud)
* [Auto-Scaling Workers](https://dev.clore.ai/inference-and-deployment/auto-scaling-workers)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.clore.ai/advanced-use-cases/mining-calculator.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
