import { J as isAddress, X as getAddress } from "../../chain-dTUyiOxD.mjs";
//#region extensions/crypto/src/lib/ens-resolver.ts
/**
* ENS / On-chain Identity Resolution — shared utility for all tools.
*
* Resolves ENS names (*.eth), Basenames (*.base.eth), and plain addresses
* into normalized 0x addresses. Used by every tool that accepts an address
* parameter, so users can type "vitalik.eth" instead of the raw address.
*
* Uses viem's built-in ENS support:
* - publicClient.getEnsAddress() — name → address
* - publicClient.getEnsName() — address → name (reverse resolution)
* - publicClient.getEnsAvatar() — address → avatar URL
*
* ENS resolution requires an Ethereum mainnet client (ENS registry lives on L1).
* For Base, we also check the Base ENS resolver for *.base.eth names.
*/
/**
* Get the appropriate public client for ENS resolution.
* - *.base.eth → use the provided client (expected to be a Base client)
* - *.eth → get an Ethereum L1 client via RpcManager
* Falls back to the provided client if L1 is unavailable.
*/
async function getEnsClient(name, fallback) {
	if (name.endsWith(".base.eth")) return fallback;
	try {
		const { getRpcManager } = await import("../services/rpc-provider.mjs");
		return await getRpcManager().getClient(1);
	} catch {
		return fallback;
	}
}
const ENS_CACHE = /* @__PURE__ */ new Map();
const CACHE_TTL_MS = 300 * 1e3;
function getCached(name) {
	const entry = ENS_CACHE.get(name.toLowerCase());
	if (!entry) return null;
	if (Date.now() - entry.timestamp > CACHE_TTL_MS) {
		ENS_CACHE.delete(name.toLowerCase());
		return null;
	}
	return entry.address;
}
function setCache(name, address) {
	ENS_CACHE.set(name.toLowerCase(), {
		address,
		timestamp: Date.now()
	});
	if (ENS_CACHE.size > 500) {
		const oldest = Array.from(ENS_CACHE.entries()).sort((a, b) => a[1].timestamp - b[1].timestamp).slice(0, 100);
		for (const [key] of oldest) ENS_CACHE.delete(key);
	}
}
/** Clear the ENS cache (for testing). */
function clearEnsCache() {
	ENS_CACHE.clear();
}
/** Check if a string looks like an ENS name (*.eth, *.base.eth, etc.) */
function isEnsName(input) {
	if (!input || typeof input !== "string") return false;
	const trimmed = input.trim().toLowerCase();
	return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*\.(eth|base\.eth)$/i.test(trimmed);
}
/** Check if input is a valid hex address OR an ENS name. */
function isAddressOrEns(input) {
	if (!input || typeof input !== "string") return false;
	return isAddress(input) || isEnsName(input);
}
/**
* Resolve an address-or-ENS input to a checksummed 0x address.
*
* - If input is already a valid address, returns it checksummed.
* - If input is an ENS name, resolves via the provided publicClient.
* - Throws if resolution fails or input is invalid.
*
* @param input - Address string or ENS name (e.g., "vitalik.eth", "0x1234...")
* @param publicClient - viem PublicClient (must be connected to Ethereum mainnet for ENS)
*/
async function resolveAddressOrEns(input, publicClient) {
	const trimmed = input.trim();
	if (isAddress(trimmed)) return {
		address: getAddress(trimmed),
		input: trimmed,
		wasEnsResolution: false
	};
	if (isEnsName(trimmed)) {
		const cached = getCached(trimmed);
		if (cached) return {
			address: cached,
			input: trimmed,
			ensName: trimmed,
			wasEnsResolution: true
		};
		try {
			const address = await (await getEnsClient(trimmed, publicClient)).getEnsAddress({ name: trimmed });
			if (!address) throw new Error(`ENS name "${trimmed}" does not resolve to an address.`);
			const checksummed = getAddress(address);
			setCache(trimmed, checksummed);
			return {
				address: checksummed,
				input: trimmed,
				ensName: trimmed,
				wasEnsResolution: true
			};
		} catch (err) {
			if (err instanceof Error && err.message.includes("does not resolve")) throw err;
			throw new Error(`Failed to resolve ENS name "${trimmed}": ${err instanceof Error ? err.message : String(err)}`);
		}
	}
	throw new Error(`Invalid address or ENS name: "${trimmed}". Expected a 0x address (42 chars) or an ENS name (e.g., name.eth).`);
}
/**
* Reverse-resolve an address to an ENS name (if one exists).
* Returns null if no reverse record is set.
*/
async function reverseResolveEns(address, publicClient) {
	try {
		return await (await getEnsClient("reverse.eth", publicClient)).getEnsName({ address }) ?? null;
	} catch {
		return null;
	}
}
/**
* Get a full ENS profile for an address (name + avatar).
*/
async function getEnsProfile(address, publicClient) {
	const name = await reverseResolveEns(address, publicClient);
	let avatar = null;
	if (name) try {
		avatar = await (await getEnsClient(name, publicClient)).getEnsAvatar({ name });
	} catch {}
	return {
		address,
		name,
		avatar
	};
}
/**
* Batch-resolve multiple address-or-ENS inputs.
* Returns results in the same order as inputs.
* Individual failures are returned as errors in the result array.
*/
async function resolveMany(inputs, publicClient) {
	return Promise.all(inputs.map(async (input) => {
		try {
			return await resolveAddressOrEns(input, publicClient);
		} catch (err) {
			return err instanceof Error ? err : new Error(String(err));
		}
	}));
}
//#endregion
export { clearEnsCache, getEnsProfile, isAddressOrEns, isEnsName, resolveAddressOrEns, resolveMany, reverseResolveEns };

//# sourceMappingURL=ens-resolver.mjs.map