import { c as stringEnum, i as jsonResult, r as errorResult, s as readStringParam, u as Type } from "../../tool-helpers-CVAcqiCy.mjs";
import { fetchDexScreener, resolveChain } from "../services/dexscreener-service.mjs";
import { getPriceOracle } from "../services/price-oracle.mjs";
//#region extensions/crypto/src/tools/defi-price.ts
/**
* DeFi Price Tool — token price lookup via multi-source PriceOracle.
*
* For well-known tokens: uses PriceOracle (DexScreener + CoinGecko +
* DeFiLlama + CoinMarketCap) with cross-validation and confidence scoring.
* For contract addresses / unknown tokens: falls back to DexScreener only.
*/
const DefiPriceSchema = Type.Object({
	action: stringEnum([
		"lookup",
		"search",
		"trending"
	], { description: "lookup: get price for a specific token. search: find tokens by name/symbol. trending: top trending tokens." }),
	token: Type.Optional(Type.String({ description: "Token symbol (e.g. \"ETH\", \"USDC\"), name, or contract address (0x...)" })),
	chain: Type.Optional(Type.String({ description: "Chain to query (default: \"base\"). Options: base, ethereum, arbitrum, optimism, polygon" }))
});
function createDefiPriceTool() {
	return {
		name: "defi_price",
		label: "DeFi Price",
		ownerOnly: false,
		description: "Look up token prices, search for tokens, and see trending tokens. Uses cross-validated multi-source oracle (DexScreener, CoinGecko, DeFiLlama, CoinMarketCap) with confidence scoring and divergence detection. Supports any ERC-20 token on Base, Ethereum, Arbitrum, Optimism, Polygon.",
		parameters: DefiPriceSchema,
		execute: async (_toolCallId, args) => {
			const params = args;
			const action = readStringParam(params, "action", { required: true });
			switch (action) {
				case "lookup": return handleLookup(params);
				case "search": return handleSearch(params);
				case "trending": return handleTrending(params);
				default: return errorResult(`Unknown action: ${action}`);
			}
		}
	};
}
async function handleLookup(params) {
	const token = readStringParam(params, "token", { required: true });
	const chain = resolveChain(readStringParam(params, "chain") || "base");
	const isAddress = token.startsWith("0x") && token.length === 42;
	if (!isAddress) try {
		const result = await getPriceOracle().getPrice(token, chain);
		if (result.priceUsd > 0) {
			let dexData = null;
			try {
				dexData = ((await fetchDexScreener(`/latest/dex/search?q=${encodeURIComponent(token)}`))?.pairs ?? []).filter((p) => !chain || p.chainId === chain).sort((a, b) => (b.liquidity?.usd ?? 0) - (a.liquidity?.usd ?? 0))[0];
			} catch {}
			return jsonResult({
				found: true,
				symbol: token.toUpperCase(),
				name: dexData?.baseToken?.name ?? token,
				address: dexData?.baseToken?.address,
				priceUsd: result.priceUsd,
				confidence: result.confidence,
				sources: result.sources.filter((s) => !s.error).map((s) => ({
					name: s.name,
					price: s.priceUsd
				})),
				divergencePercent: result.divergencePercent,
				warning: result.warning,
				change24h: dexData?.priceChange?.h24 ?? void 0,
				volume24h: dexData?.volume?.h24 ?? void 0,
				liquidity: dexData?.liquidity?.usd ?? void 0,
				marketCap: dexData?.marketCap ?? dexData?.fdv ?? void 0,
				pairAddress: dexData?.pairAddress,
				dexId: dexData?.dexId,
				url: dexData?.url
			});
		}
	} catch {}
	try {
		let data;
		if (isAddress) data = await fetchDexScreener(`/tokens/v1/${chain}/${token}`);
		else data = await fetchDexScreener(`/latest/dex/search?q=${encodeURIComponent(token)}`);
		const pairs = data?.pairs || data || [];
		if (!pairs.length) return jsonResult({
			found: false,
			query: token,
			chain,
			message: `No results found for "${token}" on ${chain}. Try a contract address or different chain.`
		});
		const top = (Array.isArray(pairs) ? pairs : [pairs]).filter((p) => !chain || p.chainId === chain).sort((a, b) => (b.liquidity?.usd ?? 0) - (a.liquidity?.usd ?? 0))[0];
		if (!top) return jsonResult({
			found: false,
			query: token,
			chain,
			message: `Found matches but none on ${chain}.`
		});
		return jsonResult({
			found: true,
			address: top.baseToken?.address ?? token,
			symbol: top.baseToken?.symbol ?? token,
			name: top.baseToken?.name ?? "",
			priceUsd: parseFloat(top.priceUsd ?? "0"),
			change24h: top.priceChange?.h24 ?? 0,
			volume24h: top.volume?.h24 ?? 0,
			liquidity: top.liquidity?.usd ?? 0,
			marketCap: top.marketCap ?? top.fdv,
			source: "dexscreener",
			confidence: "single-source",
			pairAddress: top.pairAddress,
			dexId: top.dexId,
			url: top.url
		});
	} catch (err) {
		return errorResult(`Price lookup failed: ${err instanceof Error ? err.message : String(err)}`);
	}
}
async function handleSearch(params) {
	const token = readStringParam(params, "token", { required: true });
	try {
		const pairs = (await fetchDexScreener(`/latest/dex/search?q=${encodeURIComponent(token)}`))?.pairs ?? [];
		const seen = /* @__PURE__ */ new Map();
		for (const pair of pairs) {
			const addr = pair.baseToken?.address;
			if (!addr) continue;
			const existing = seen.get(addr);
			if (!existing || (pair.liquidity?.usd ?? 0) > (existing.liquidity?.usd ?? 0)) seen.set(addr, pair);
		}
		const results = Array.from(seen.values()).sort((a, b) => (b.liquidity?.usd ?? 0) - (a.liquidity?.usd ?? 0)).slice(0, 10).map((p) => ({
			symbol: p.baseToken?.symbol,
			name: p.baseToken?.name,
			address: p.baseToken?.address,
			chain: p.chainId,
			priceUsd: parseFloat(p.priceUsd ?? "0"),
			liquidity: p.liquidity?.usd ?? 0,
			volume24h: p.volume?.h24 ?? 0,
			url: p.url
		}));
		return jsonResult({
			query: token,
			results,
			count: results.length
		});
	} catch (err) {
		return errorResult(`Search failed: ${err instanceof Error ? err.message : String(err)}`);
	}
}
async function handleTrending(params) {
	const chain = resolveChain(readStringParam(params, "chain") || "base");
	try {
		const results = (await fetchDexScreener(`/token-boosts/top/v1`) ?? []).filter((t) => !chain || t.chainId === chain).slice(0, 20).map((t) => ({
			symbol: t.tokenAddress ? void 0 : t.description,
			address: t.tokenAddress,
			chain: t.chainId,
			url: t.url,
			boostAmount: t.totalAmount
		}));
		return jsonResult({
			chain,
			trending: results,
			count: results.length,
			note: "Trending tokens by DexScreener boost amount"
		});
	} catch (err) {
		return errorResult(`Trending lookup failed: ${err instanceof Error ? err.message : String(err)}`);
	}
}
//#endregion
export { createDefiPriceTool };

//# sourceMappingURL=defi-price.mjs.map