get_market_summary
Retrieve a comprehensive market report for Base tokens including price, volume estimates, liquidity, and volatility metrics to analyze token performance.
Instructions
Combined report: price, volume estimate, liquidity, volatility for a token
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| token_address | Yes | Token contract address on Base |
Implementation Reference
- src/index.ts:922-1034 (handler)Tool registration and handler implementation for 'get_market_summary' which retrieves market data including price, liquidity, volume estimate, and volatility for a given token address.
server.tool( "get_market_summary", "Combined report: price, volume estimate, liquidity, volatility for a token", { token_address: z.string().describe("Token contract address on Base"), }, async ({ token_address }) => { try { const quoteAddress = WETH; const [tokenDecimals, quoteDecimals, tokenSymbol, tokenName] = await Promise.all([ getTokenDecimals(token_address), getTokenDecimals(quoteAddress), getTokenSymbol(token_address), (async () => { try { const c = new ethers.Contract(token_address, ERC20_ABI, provider); return await c.name(); } catch { return "Unknown"; } })(), ]); const pools = await findAllPools(token_address, quoteAddress); if (pools.length === 0) { return { content: [{ type: "text" as const, text: `No DEX pools found for ${token_address} on Base.` }] }; } // Best price const prices = pools.map((p) => ({ dex: p.dex, price: calculatePrice(p, tokenDecimals, quoteDecimals), })); const bestPrice = prices.reduce((best, p) => (p.price > best.price ? p : best), prices[0]); // Liquidity summary let totalEthLiquidity = 0; for (const pool of pools) { if (pool.sqrtPriceX96 === undefined) { const ethRes = pool.tokenIsToken0 ? Number(ethers.formatUnits(pool.reserve1, quoteDecimals)) : Number(ethers.formatUnits(pool.reserve0, quoteDecimals)); totalEthLiquidity += ethRes * 2; } } // Recent swaps for volume + volatility (last ~6 hours = ~10800 blocks) const lookbackBlocks = 10800; const swaps = await getSwapHistory(pools[0], tokenDecimals, quoteDecimals, lookbackBlocks); const swapPrices = swaps.map((s) => s.price); const returns = calculateReturns(swapPrices); const vol = stddev(returns); // Estimate volume from swap count (rough) const volumeEstimate = swaps.length > 0 ? `~${swaps.length} swaps in last 6h` : "No recent swaps"; // Total supply let totalSupply = "Unknown"; try { const c = new ethers.Contract(token_address, ERC20_ABI, provider); const supply = await c.totalSupply(); totalSupply = Number(ethers.formatUnits(supply, tokenDecimals)).toLocaleString(); } catch { // ignore } const summary = { token: { address: token_address, name: tokenName, symbol: tokenSymbol, decimals: tokenDecimals, totalSupply, }, price: { current: formatEth(bestPrice.price), dex: bestPrice.dex, poolCount: pools.length, }, liquidity: { totalValueETH: formatEth(totalEthLiquidity), pools: pools.map((p) => p.dex).join(", "), }, volume: volumeEstimate, volatility: swapPrices.length >= 3 ? { perSwap: (vol * 100).toFixed(4) + "%", annualized: (vol * Math.sqrt(365 * 24) * 100).toFixed(2) + "%", swapCount: swaps.length, } : "Insufficient swap data", priceRange6h: swapPrices.length > 0 ? { low: formatEth(Math.min(...swapPrices)), high: formatEth(Math.max(...swapPrices)), } : "No data", }; return { content: [{ type: "text" as const, text: JSON.stringify(summary, null, 2), }], }; } catch (err: unknown) { const msg = err instanceof Error ? err.message : String(err); return { content: [{ type: "text" as const, text: `Error: ${msg}` }] }; } } );