Spaces:
Sleeping
Sleeping
| from typing import Dict, Any, Optional | |
| from pydantic import BaseModel, PrivateAttr | |
| from src.tools.base_tool import BaseWeb3Tool, Web3ToolInput | |
| from src.utils.config import config | |
| class CoinGeckoTool(BaseWeb3Tool): | |
| name: str = "coingecko_data" | |
| description: str = """Get cryptocurrency price, volume, market cap and trend data from CoinGecko. | |
| Useful for: price analysis, market rankings, volume trends, price changes. | |
| Input: cryptocurrency name/symbol (bitcoin, ethereum, BTC, ETH) or market query.""" | |
| args_schema: type[BaseModel] = Web3ToolInput | |
| _base_url: str = PrivateAttr(default="https://api.coingecko.com/api/v3") | |
| _symbol_map: Dict[str, str] = PrivateAttr(default_factory=lambda: { | |
| "btc": "bitcoin", "eth": "ethereum", "sol": "solana", "ada": "cardano", | |
| "dot": "polkadot", "bnb": "binancecoin", "usdc": "usd-coin", | |
| "usdt": "tether", "xrp": "ripple", "avax": "avalanche-2", | |
| "link": "chainlink", "matic": "matic-network", "uni": "uniswap" | |
| }) | |
| def __init__(self): | |
| super().__init__() | |
| async def _arun(self, query: str, filters: Optional[Dict[str, Any]] = None) -> str: | |
| try: | |
| filters = filters or {} | |
| if filters.get("type") == "trending": | |
| return await self._get_trending() | |
| elif filters.get("type") == "market_overview": | |
| return await self._get_market_overview() | |
| elif filters.get("type") == "price_history": | |
| return await self._get_price_history(query, filters.get("days", 30)) | |
| else: | |
| return await self._get_coin_data(query) | |
| except Exception as e: | |
| return f"CoinGecko error: {str(e)}" | |
| async def _get_trending(self) -> str: | |
| data = await self.make_request(f"{self._base_url}/search/trending") | |
| data = await self.make_request(f"{self.base_url}/search/trending") | |
| trending = data.get("coins", [])[:5] | |
| result = "π₯ **Trending Cryptocurrencies:**\n\n" | |
| for i, coin in enumerate(trending, 1): | |
| item = coin.get("item", {}) | |
| name = item.get("name", "Unknown") | |
| symbol = item.get("symbol", "").upper() | |
| rank = item.get("market_cap_rank", "N/A") | |
| result += f"{i}. **{name} ({symbol})** - Rank #{rank}\n" | |
| return result | |
| async def _get_market_overview(self) -> str: | |
| data = await self.make_request(f"{self._base_url}/coins/markets", params)10, "page": 1} | |
| data = await self.make_request(f"{self.base_url}/coins/markets", params) | |
| result = "π **Top Cryptocurrencies by Market Cap:**\n\n" | |
| for coin in data[:10]: | |
| name = coin.get("name", "Unknown") | |
| symbol = coin.get("symbol", "").upper() | |
| price = coin.get("current_price", 0) | |
| change = coin.get("price_change_percentage_24h", 0) | |
| mcap = coin.get("market_cap", 0) | |
| emoji = "π" if change >= 0 else "π" | |
| result += f"{emoji} **{name} ({symbol})**: ${price:,.4f} ({change:+.2f}%) | MCap: ${mcap/1e9:.2f}B\n" | |
| return result | |
| coin_id = self._symbol_map.get(query.lower(), query.lower()) | |
| coin_id = self.symbol_map.get(query.lower(), query.lower()) | |
| params = { | |
| "ids": coin_id, | |
| "vs_currencies": "usd", | |
| "include_24hr_change": "true", | |
| "include_24hr_vol": "true", | |
| "include_market_cap": "true" | |
| } | |
| data = await self.make_request(f"{self._base_url}/simple/price", params) | |
| data = await self.make_request(f"{self.base_url}/simple/price", params) | |
| if coin_id not in data: | |
| return f"No data found for {query}" | |
| coin_data = data[coin_id] | |
| price = coin_data.get("usd", 0) | |
| change = coin_data.get("usd_24h_change", 0) | |
| volume = coin_data.get("usd_24h_vol", 0) | |
| mcap = coin_data.get("usd_market_cap", 0) | |
| emoji = "π" if change >= 0 else "π" | |
| result = f"π° **{query.upper()} Market Data:**\n\n" | |
| result += f"{emoji} **Price**: ${price:,.4f}\n" | |
| result += f"π **24h Change**: {change:+.2f}%\n" | |
| result += f"π **24h Volume**: ${volume:,.0f}\n" | |
| result += f"π¦ **Market Cap**: ${mcap:,.0f}\n" | |
| return result | |
| coin_id = self._symbol_map.get(symbol.lower(), symbol.lower()) | |
| params = {"vs_currency": "usd", "days": days} | |
| data = await self.make_request(f"{self._base_url}/coins/{coin_id}/market_chart", params) | |
| data = await self.make_request(f"{self.base_url}/coins/{coin_id}/market_chart", params) | |
| return { | |
| "symbol": symbol.upper(), | |
| "prices": data.get("prices", []), | |
| "volumes": data.get("total_volumes", []), | |
| "market_caps": data.get("market_caps", []) | |
| } | |