import { getWalletState, isBankrMode, requirePublicClient } from "./walletconnect-service.mjs";
import { getCredentialVault } from "./credential-vault.mjs";
import { getPrice } from "./price-service.mjs";
//#region extensions/crypto/src/services/safety-service.ts
/**
* Safety Service — pre-flight checks before any on-chain write operation.
*
* Wired into defi-swap, clawnch-launch, and clawnch-fees before execution.
* Uses herd-intelligence for token audits and swap validation.
* Uses defi-balance logic for balance sufficiency checks.
*/
/**
* Check if the connected wallet has enough ETH for a given amount + gas.
*/
async function checkBalance(opts) {
	const warnings = [];
	const blockers = [];
	const details = {};
	const state = getWalletState();
	if (!state.connected || !state.address) return {
		safe: false,
		warnings,
		blockers: ["No wallet connected"],
		details
	};
	try {
		const publicClient = requirePublicClient();
		const { formatEther } = await import("../../_esm-BrzUp3yp.mjs").then((n) => n.t);
		const balance = await publicClient.getBalance({ address: state.address });
		const ethBalance = parseFloat(formatEther(balance));
		details.ethBalance = ethBalance;
		const gasBuffer = .005;
		const requiredEth = (opts.requiredEth ?? 0) + gasBuffer;
		if (ethBalance < requiredEth) blockers.push(`Insufficient ETH. Have ${ethBalance.toFixed(4)} ETH, need ~${requiredEth.toFixed(4)} ETH (${opts.requiredEth?.toFixed(4) ?? "0"} + ${gasBuffer} gas buffer).`);
		else if (ethBalance < requiredEth * 1.2) warnings.push(`Low ETH balance (${ethBalance.toFixed(4)}). Transaction may succeed but leaves little for future gas.`);
		if (opts.requiredTokenAddress && opts.requiredTokenAmount) try {
			const tokenAddr = opts.requiredTokenAddress;
			const erc20Abi = [
				{
					name: "balanceOf",
					type: "function",
					stateMutability: "view",
					inputs: [{
						name: "account",
						type: "address"
					}],
					outputs: [{
						name: "",
						type: "uint256"
					}]
				},
				{
					name: "decimals",
					type: "function",
					stateMutability: "view",
					inputs: [],
					outputs: [{
						name: "",
						type: "uint8"
					}]
				},
				{
					name: "symbol",
					type: "function",
					stateMutability: "view",
					inputs: [],
					outputs: [{
						name: "",
						type: "string"
					}]
				}
			];
			const [rawBalance, decimals, symbol] = await Promise.all([
				publicClient.readContract({
					address: tokenAddr,
					abi: erc20Abi,
					functionName: "balanceOf",
					args: [state.address]
				}),
				publicClient.readContract({
					address: tokenAddr,
					abi: erc20Abi,
					functionName: "decimals"
				}).catch(() => 18),
				publicClient.readContract({
					address: tokenAddr,
					abi: erc20Abi,
					functionName: "symbol"
				}).catch(() => "TOKEN")
			]);
			const { formatUnits } = await import("../../_esm-BrzUp3yp.mjs").then((n) => n.t);
			const tokenBalance = parseFloat(formatUnits(rawBalance, Number(decimals)));
			const requiredAmount = parseFloat(opts.requiredTokenAmount);
			details.tokenBalance = tokenBalance;
			details.tokenSymbol = symbol;
			if (tokenBalance < requiredAmount) blockers.push(`Insufficient ${symbol}. Have ${tokenBalance.toFixed(4)}, need ${requiredAmount.toFixed(4)}.`);
		} catch (tokenErr) {
			warnings.push(`Token balance check failed: ${tokenErr instanceof Error ? tokenErr.message : String(tokenErr)}`);
		}
	} catch (err) {
		warnings.push(`Balance check failed: ${err instanceof Error ? err.message : String(err)}`);
	}
	return {
		safe: blockers.length === 0,
		warnings,
		blockers,
		details
	};
}
/**
* Audit a token for safety using herd-intelligence (if available).
* Non-blocking — returns warnings but doesn't block if the service is unavailable.
*/
async function auditToken(tokenAddress) {
	const warnings = [];
	const blockers = [];
	const details = {};
	const accessToken = getCredentialVault().getSecret("intel.herd.accessToken", "safety-service");
	if (!accessToken) {
		warnings.push("Herd Intelligence not configured (no HERD_ACCESS_TOKEN). Token audit skipped.");
		return {
			safe: true,
			warnings,
			blockers,
			details
		};
	}
	try {
		const { HerdIntelligence } = await import("../../dist-CXAY4yCt.mjs");
		const audit = await new HerdIntelligence({ accessToken }).auditTokenSafety(tokenAddress, { blockchain: "base" });
		details.audit = audit;
		const riskLevel = audit?.riskLevel ?? audit?.risk_level;
		const reason = audit?.reason ?? audit?.summary ?? "";
		const isHoneypot = audit?.isHoneypot ?? audit?.honeypot ?? false;
		if (riskLevel === "critical") blockers.push(`CRITICAL RISK: Token ${tokenAddress} — ${reason || "Do not interact."}`);
		else if (riskLevel === "high") warnings.push(`HIGH RISK: Token ${tokenAddress} — ${reason || "Exercise extreme caution."}`);
		else if (riskLevel === "medium") warnings.push(`MEDIUM RISK: Token ${tokenAddress} — ${reason || "Proceed with caution."}`);
		if (isHoneypot) blockers.push(`HONEYPOT DETECTED: Token ${tokenAddress} cannot be sold after purchase.`);
	} catch (err) {
		warnings.push(`Token audit unavailable: ${err instanceof Error ? err.message : String(err)}`);
	}
	return {
		safe: blockers.length === 0,
		warnings,
		blockers,
		details
	};
}
/**
* Validate a swap before execution: balance + token audit + route check.
* When routing through Bankr, skip local checks — Bankr's Sentinel handles security.
*/
async function validateSwap(opts) {
	if (isBankrMode()) return {
		safe: true,
		warnings: ["Bankr Sentinel active — security screening handled server-side"],
		blockers: [],
		details: { bankrMode: true }
	};
	const allWarnings = [];
	const allBlockers = [];
	const allDetails = {};
	const AUTOSIGN_DANGER_CAP_ETH = .1;
	try {
		if (getWalletState().mode === "private_key") {
			if (opts.amountEth > AUTOSIGN_DANGER_CAP_ETH) allWarnings.push(`Transaction value (${opts.amountEth} ETH) exceeds auto-sign safety cap of ${AUTOSIGN_DANGER_CAP_ETH} ETH. In private key mode, consider using WalletConnect (/walletsign) for transactions above this threshold.`);
		}
	} catch {}
	const isEthIn = opts.tokenIn.toLowerCase() === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" || opts.tokenIn.toLowerCase() === "0x4200000000000000000000000000000000000006";
	const balanceCheck = await checkBalance({
		requiredEth: isEthIn ? opts.amountEth : void 0,
		requiredTokenAddress: isEthIn ? void 0 : opts.tokenIn,
		requiredTokenAmount: isEthIn ? void 0 : String(opts.amountEth)
	});
	allWarnings.push(...balanceCheck.warnings);
	allBlockers.push(...balanceCheck.blockers);
	allDetails.balance = balanceCheck.details;
	if (!new Set([
		"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
		"0x4200000000000000000000000000000000000006",
		"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
		"0xfde4c96c8593536e31f229ea8f37b2ada2699bb2",
		"0x50c5725949a6f0c72e6c4a641f24049a917db0cb"
	]).has(opts.tokenOut.toLowerCase())) {
		const tokenAudit = await auditToken(opts.tokenOut);
		allWarnings.push(...tokenAudit.warnings);
		allBlockers.push(...tokenAudit.blockers);
		allDetails.tokenAudit = tokenAudit.details;
	}
	try {
		const [priceIn, priceOut] = await Promise.all([getPrice(opts.tokenIn).catch(() => null), getPrice(opts.tokenOut).catch(() => null)]);
		allDetails.prices = {
			tokenIn: priceIn ? {
				symbol: priceIn.symbol,
				priceUsd: priceIn.priceUsd
			} : null,
			tokenOut: priceOut ? {
				symbol: priceOut.symbol,
				priceUsd: priceOut.priceUsd
			} : null
		};
	} catch {}
	return {
		safe: allBlockers.length === 0,
		warnings: allWarnings,
		blockers: allBlockers,
		details: allDetails
	};
}
/**
* Pre-flight check for token launch: balance for gas + dev buy.
*/
async function validateLaunch(opts) {
	return checkBalance({ requiredEth: (opts.devBuyEth ?? 0) + .01 });
}
/**
* Pre-flight check for fee claims: just gas check.
*/
async function validateClaim() {
	return checkBalance({ requiredEth: 0 });
}
//#endregion
export { auditToken, checkBalance, validateClaim, validateLaunch, validateSwap };

//# sourceMappingURL=safety-service.mjs.map