web3-copilot / src /tools /coingecko_tool.py
Priyanshi Saxena
feat: added api tools
f104fee
raw
history blame
5.03 kB
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", [])
}