import { c as stringEnum, i as jsonResult, r as errorResult, s as readStringParam, u as Type } from "../../tool-helpers-CVAcqiCy.mjs";
import { getPublicClient, getWalletState, isBankrMode } from "../services/walletconnect-service.mjs";
import { getPriceOracle } from "../services/price-oracle.mjs";
import { getRpcManager } from "../services/rpc-provider.mjs";
import { isEnsName, resolveAddressOrEns } from "../lib/ens-resolver.mjs";
//#region extensions/crypto/src/tools/defi-balance.ts
/**
* DeFi Balance Tool — wallet balance and token holdings
*
* Uses RpcManager for fault-tolerant multi-chain RPC access and
* PriceOracle for cross-validated ETH price.
*/
const DefiBalanceSchema = Type.Object({
	action: stringEnum([
		"overview",
		"tokens",
		"eth"
	], { description: "overview: full portfolio summary. tokens: ERC-20 token list. eth: just ETH balance." }),
	address: Type.Optional(Type.String({ description: "Wallet address (0x...) or ENS name (e.g. vitalik.eth). Defaults to connected wallet." })),
	chain: Type.Optional(Type.String({ description: "Chain to check (default: \"base\"). Options: base, ethereum, arbitrum, optimism, polygon. Bankr mode adds: solana, unichain" }))
});
function createDefiBalanceTool() {
	return {
		name: "defi_balance",
		label: "DeFi Balance",
		ownerOnly: false,
		description: "Check wallet balances — ETH, ERC-20 tokens, and total portfolio value. Defaults to the connected wallet on Base. Supports Base, Ethereum, Arbitrum, Optimism, Polygon via multi-RPC failover. In Bankr mode, also supports Solana and Unichain with full token breakdowns.",
		parameters: DefiBalanceSchema,
		execute: async (_toolCallId, args) => {
			const params = args;
			const action = readStringParam(params, "action", { required: true });
			const chain = readStringParam(params, "chain") || "base";
			let address;
			const addressInput = readStringParam(params, "address");
			if (!addressInput) {
				const state = getWalletState();
				if (!state.connected || !state.address) return errorResult("No wallet connected and no address provided. Connect a wallet first or pass an address parameter.");
				address = state.address;
			} else if (isEnsName(addressInput)) try {
				const publicClient = getPublicClient();
				if (!publicClient) return errorResult("Public client not available for ENS resolution.");
				address = (await resolveAddressOrEns(addressInput, publicClient)).address;
			} catch (err) {
				return errorResult(err instanceof Error ? err.message : String(err));
			}
			else address = addressInput;
			if (isBankrMode() && !readStringParam(params, "address")) return handleBankrBalance(action, chain);
			switch (action) {
				case "overview": return handleOverview(address, chain);
				case "tokens": return handleTokens(address, chain);
				case "eth": return handleEthBalance(address, chain);
				default: return errorResult(`Unknown action: ${action}`);
			}
		}
	};
}
/**
* Get a public client for the requested chain.
* Tries RpcManager first (multi-provider failover), falls back to
* the WalletConnect service's single client for backward compatibility.
*/
async function getClientForChain(chain) {
	try {
		return await getRpcManager().getClient(chain);
	} catch {
		const wc = getPublicClient();
		if (wc) return wc;
		throw new Error("No RPC available. Set ALCHEMY_API_KEY or configure RPC providers.");
	}
}
async function handleEthBalance(address, chain) {
	try {
		const publicClient = await getClientForChain(chain);
		const { formatEther } = await import("../../_esm-BrzUp3yp.mjs").then((n) => n.t);
		const balance = await publicClient.getBalance({ address });
		const ethBalance = formatEther(balance);
		let ethPriceUsd = 0;
		let priceConfidence;
		try {
			const ethPrice = await getPriceOracle().getEthPrice();
			ethPriceUsd = ethPrice.priceUsd;
			priceConfidence = ethPrice.confidence;
		} catch {}
		return jsonResult({
			address,
			chain,
			ethBalance,
			ethBalanceWei: balance.toString(),
			ethPriceUsd: ethPriceUsd || void 0,
			ethValueUsd: ethPriceUsd ? parseFloat(ethBalance) * ethPriceUsd : void 0,
			priceConfidence
		});
	} catch (err) {
		return errorResult(`Balance check failed: ${err instanceof Error ? err.message : String(err)}`);
	}
}
async function handleTokens(address, chain) {
	try {
		await getClientForChain(chain);
		const chainId = getRpcManager().resolveChainId(chain);
		try {
			const { ClawnchClient } = await import("../../dist-CXAY4yCt.mjs");
			const fees = await new ClawnchClient({ baseUrl: process.env.CLAWNCHER_API_URL || "https://clawn.ch" }).getAvailableFees(address);
			if (fees) return jsonResult({
				address,
				chain,
				source: "clawnch-api",
				...fees
			});
		} catch {}
		return jsonResult({
			address,
			chain,
			chainId,
			note: "For detailed ERC-20 balances, set up an Alchemy/Infura RPC or use Clawnch API. ETH balance is available via action \"eth\". Use defi_price tool to check individual token prices."
		});
	} catch (err) {
		return errorResult(`Token balance check failed: ${err instanceof Error ? err.message : String(err)}`);
	}
}
async function handleBankrBalance(action, chain) {
	try {
		const { getBankrBalances } = await import("../services/bankr-api.mjs");
		const { CHAIN_MAP } = await import("../services/bankr-types.mjs");
		const bankrChain = CHAIN_MAP[chain.toLowerCase()];
		const data = await getBankrBalances(bankrChain ? [bankrChain] : [
			"base",
			"mainnet",
			"polygon",
			"unichain",
			"solana"
		]);
		if (action === "eth") {
			const nativeBalances = data.chains.map((c) => ({
				chain: c.chain,
				balance: c.nativeBalance,
				balanceUsd: c.nativeBalanceUsd
			}));
			return jsonResult({
				source: "bankr",
				nativeBalances,
				totalNativeUsd: nativeBalances.reduce((sum, b) => sum + b.balanceUsd, 0)
			});
		}
		if (action === "tokens") return jsonResult({
			source: "bankr",
			tokensByChain: data.chains.filter((c) => c.tokens.length > 0).map((c) => ({
				chain: c.chain,
				tokens: c.tokens.map((t) => ({
					symbol: t.symbol,
					name: t.name,
					balance: t.balance,
					balanceUsd: t.balanceUsd,
					price: t.price
				}))
			})),
			totalTokensUsd: data.chains.reduce((sum, c) => sum + c.tokens.reduce((s, t) => s + t.balanceUsd, 0), 0)
		});
		return jsonResult({
			source: "bankr",
			portfolio: data.chains.map((c) => ({
				chain: c.chain,
				native: {
					balance: c.nativeBalance,
					balanceUsd: c.nativeBalanceUsd
				},
				tokens: c.tokens.map((t) => ({
					symbol: t.symbol,
					name: t.name,
					balance: t.balance,
					balanceUsd: t.balanceUsd,
					price: t.price
				})),
				totalUsd: c.totalUsd
			})),
			totalUsd: data.totalUsd
		});
	} catch (err) {
		return errorResult(`Bankr balance check failed: ${err instanceof Error ? err.message : String(err)}`);
	}
}
async function handleOverview(address, chain) {
	try {
		const ethResult = await handleEthBalance(address, chain);
		const ethData = JSON.parse(ethResult.content[0].text);
		const tokenResult = await handleTokens(address, chain);
		const tokenData = JSON.parse(tokenResult.content[0].text);
		return jsonResult({
			address,
			chain,
			eth: {
				balance: ethData.ethBalance,
				priceUsd: ethData.ethPriceUsd,
				valueUsd: ethData.ethValueUsd,
				priceConfidence: ethData.priceConfidence
			},
			tokens: tokenData,
			totalValueUsd: ethData.ethValueUsd ?? "ETH price unavailable"
		});
	} catch (err) {
		return errorResult(`Portfolio overview failed: ${err instanceof Error ? err.message : String(err)}`);
	}
}
//#endregion
export { createDefiBalanceTool };

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