import { c as stringEnum, i as jsonResult, o as readNumberParam, r as errorResult, s as readStringParam, u as Type } from "../../tool-helpers-CVAcqiCy.mjs";
import { getWalletState, requirePublicClient, requireWalletClient } from "../services/walletconnect-service.mjs";
import { checkBalance } from "../services/safety-service.mjs";
//#region extensions/crypto/src/tools/liquidity.ts
/**
* Liquidity Tool — Uniswap V4/V3 liquidity position management.
*
* Actions:
*   - positions: List all V3 positions for the connected wallet
*   - v4_position: Read a specific V4 position by token ID
*   - v4_pool: Read V4 pool state (price, liquidity, tick)
*   - v3_mint: Mint a new V3 liquidity position
*   - v4_mint: Mint a new V4 liquidity position
*   - v3_add: Add liquidity to an existing V3 position
*   - v3_remove: Remove liquidity from a V3 position
*   - v3_collect: Collect accumulated fees from a V3 position
*
* Uses ClawnchLiquidity from @clawnch/clawncher-sdk.
* Write operations go through ClawnchConnect for approval.
*/
/** Validate and convert a token ID string to BigInt. */
function validateTokenId(raw) {
	const trimmed = raw.trim();
	if (!/^\d+$/.test(trimmed)) throw new Error(`Invalid token_id: "${raw}". Must be a non-negative integer.`);
	return BigInt(trimmed);
}
/** Validate a numeric amount string. */
function validateAmount(raw) {
	const trimmed = raw.trim();
	if (!trimmed || !/^\d+(\.\d+)?$/.test(trimmed)) throw new Error(`Invalid amount: "${raw}". Must be a positive number (e.g. "1.5" or "100").`);
	return trimmed;
}
const LiquiditySchema = Type.Object({
	action: stringEnum([
		"positions",
		"v4_position",
		"v4_pool",
		"v3_mint",
		"v4_mint",
		"v3_add",
		"v3_remove",
		"v3_collect"
	], { description: "positions: list V3 positions. v4_position: read V4 position. v4_pool: read pool state. v3_mint/v4_mint: open new position. v3_add: add to existing. v3_remove: withdraw. v3_collect: claim fees." }),
	token_id: Type.Optional(Type.String({ description: "Position NFT token ID (for v4_position, v3_add, v3_remove, v3_collect)." })),
	token0: Type.Optional(Type.String({ description: "Token 0 address — must be the lower address (for mint and v4_pool)." })),
	token1: Type.Optional(Type.String({ description: "Token 1 address — must be the higher address (for mint and v4_pool)." })),
	fee: Type.Optional(Type.Number({ description: "Fee tier in hundredths of bps (e.g. 3000 = 0.3%). Default: 3000." })),
	tick_spacing: Type.Optional(Type.Number({ description: "Tick spacing for V4 pool. Default: 60." })),
	hook_address: Type.Optional(Type.String({ description: "V4 hook contract address. Default: zero address (no hook)." })),
	tick_lower: Type.Optional(Type.Number({ description: "Lower tick boundary for new positions." })),
	tick_upper: Type.Optional(Type.Number({ description: "Upper tick boundary for new positions." })),
	amount0: Type.Optional(Type.String({ description: "Amount of token0 in human-readable units (for mint/add)." })),
	amount1: Type.Optional(Type.String({ description: "Amount of token1 in human-readable units (for mint/add)." })),
	percentage: Type.Optional(Type.Number({ description: "Percentage of liquidity to remove (0-100). Default: 100. For v3_remove." })),
	slippage_bps: Type.Optional(Type.Number({ description: "Slippage tolerance in basis points (e.g. 50 = 0.5%). Default: 50." }))
});
function createLiquidityTool() {
	return {
		name: "liquidity",
		label: "Liquidity",
		ownerOnly: true,
		description: "Manage Uniswap V4 and V3 liquidity positions on Base. List positions, read pool state, mint/add/remove liquidity, and collect fees. Write operations go through ClawnchConnect for approval.",
		parameters: LiquiditySchema,
		execute: async (_toolCallId, args) => {
			const params = args;
			const action = readStringParam(params, "action", { required: true });
			if (!getWalletState().connected) return errorResult("No wallet connected. Use clawnchconnect tool to connect first.");
			try {
				const { ClawnchLiquidity } = await import("../../dist-CXAY4yCt.mjs");
				const liquidity = new ClawnchLiquidity({
					wallet: requireWalletClient(),
					publicClient: requirePublicClient(),
					network: "mainnet"
				});
				switch (action) {
					case "positions": return handlePositions(liquidity);
					case "v4_position": return handleV4Position(liquidity, params);
					case "v4_pool": return handleV4Pool(liquidity, params);
					case "v3_mint": return handleV3Mint(liquidity, params);
					case "v4_mint": return handleV4Mint(liquidity, params);
					case "v3_add": return handleV3Add(liquidity, params);
					case "v3_remove": return handleV3Remove(liquidity, params);
					case "v3_collect": return handleV3Collect(liquidity, params);
					default: return errorResult(`Unknown action: ${action}`);
				}
			} catch (err) {
				return errorResult(`Liquidity operation failed: ${err instanceof Error ? err.message : String(err)}`);
			}
		}
	};
}
async function handlePositions(liquidity) {
	const positions = await liquidity.v3GetPositionsForWallet();
	if (positions.length === 0) return jsonResult({
		count: 0,
		message: "No V3 liquidity positions found for this wallet."
	});
	const formatted = positions.map((p, i) => ({
		index: i + 1,
		tokenId: p.tokenId.toString(),
		version: p.version,
		token0: p.token0,
		token1: p.token1,
		feeTier: `${p.fee / 1e4}%`,
		tickRange: `${p.tickLower} → ${p.tickUpper}`,
		liquidity: p.liquidity.toString(),
		isActive: p.liquidity > 0n,
		unclaimedFees: {
			token0: p.unclaimedFees.token0.toString(),
			token1: p.unclaimedFees.token1.toString()
		}
	}));
	return jsonResult({
		count: positions.length,
		positions: formatted
	});
}
async function handleV4Position(liquidity, params) {
	const tokenId = readStringParam(params, "token_id");
	if (!tokenId) return errorResult("token_id is required for v4_position.");
	const pos = await liquidity.v4GetPosition(validateTokenId(tokenId));
	return jsonResult({
		tokenId: pos.tokenId.toString(),
		token0: pos.token0,
		token1: pos.token1,
		feeTier: `${pos.fee / 1e4}%`,
		tickRange: `${pos.tickLower} → ${pos.tickUpper}`,
		liquidity: pos.liquidity.toString(),
		unclaimedFees: {
			token0: pos.unclaimedFees.token0.toString(),
			token1: pos.unclaimedFees.token1.toString()
		}
	});
}
async function handleV4Pool(liquidity, params) {
	const poolKey = {
		currency0: readStringParam(params, "token0", { required: true }),
		currency1: readStringParam(params, "token1", { required: true }),
		fee: readNumberParam(params, "fee") ?? 3e3,
		tickSpacing: readNumberParam(params, "tick_spacing") ?? 60,
		hooks: readStringParam(params, "hook_address") ?? "0x0000000000000000000000000000000000000000"
	};
	const state = await liquidity.v4GetPoolState(poolKey);
	const sqrtPrice = Number(state.sqrtPriceX96) / Number(2n ** 96n);
	const price = sqrtPrice * sqrtPrice;
	return jsonResult({
		poolId: state.poolId,
		sqrtPriceX96: state.sqrtPriceX96.toString(),
		price_token1_per_token0: price,
		tick: state.tick,
		liquidity: state.liquidity.toString()
	});
}
/** Read on-chain decimals for a token, with well-known fallbacks. */
async function getTokenDecimals(tokenAddress) {
	const known = {
		"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": 6,
		"0xfde4c96c8593536e31f229ea8f37b2ada2699bb2": 6
	}[tokenAddress.toLowerCase()];
	if (known !== void 0) return known;
	if (tokenAddress.toLowerCase() === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") return 18;
	try {
		const publicClient = requirePublicClient();
		const { erc20Abi } = await import("../../_esm-BrzUp3yp.mjs").then((n) => n.t);
		return await publicClient.readContract({
			address: tokenAddress,
			abi: erc20Abi,
			functionName: "decimals"
		});
	} catch {
		return 18;
	}
}
/** Convert a human-readable amount string to BigInt wei using actual token decimals. */
async function toTokenWei(amount, tokenAddress) {
	const trimmed = validateAmount(amount);
	const decimals = await getTokenDecimals(tokenAddress);
	const { parseUnits } = await import("../../_esm-BrzUp3yp.mjs").then((n) => n.t);
	return parseUnits(trimmed, decimals);
}
async function handleV3Mint(liquidity, params) {
	const token0 = readStringParam(params, "token0", { required: true });
	const token1 = readStringParam(params, "token1", { required: true });
	const tickLower = readNumberParam(params, "tick_lower", { required: true });
	const tickUpper = readNumberParam(params, "tick_upper", { required: true });
	const amount0 = readStringParam(params, "amount0", { required: true });
	const amount1 = readStringParam(params, "amount1", { required: true });
	const fee = readNumberParam(params, "fee") ?? 3e3;
	const safety = await checkBalance({ requiredEth: 0 });
	if (!safety.safe) return errorResult(`Insufficient gas: ${safety.blockers.join("; ")}`);
	const amount0Wei = await toTokenWei(amount0, token0);
	const amount1Wei = await toTokenWei(amount1, token1);
	const result = await liquidity.v3MintPosition({
		token0,
		token1,
		fee,
		tickLower,
		tickUpper,
		amount0Desired: amount0Wei,
		amount1Desired: amount1Wei,
		deadline: 1200
	});
	return jsonResult({
		status: "success",
		action: "v3_mint",
		tokenId: result.tokenId.toString(),
		liquidity: result.liquidity.toString(),
		amount0: result.amount0.toString(),
		amount1: result.amount1.toString(),
		txHash: result.txHash
	});
}
async function handleV4Mint(liquidity, params) {
	const token0 = readStringParam(params, "token0", { required: true });
	const token1 = readStringParam(params, "token1", { required: true });
	const tickLower = readNumberParam(params, "tick_lower", { required: true });
	const tickUpper = readNumberParam(params, "tick_upper", { required: true });
	const amount0 = readStringParam(params, "amount0", { required: true });
	const amount1 = readStringParam(params, "amount1", { required: true });
	const fee = readNumberParam(params, "fee") ?? 3e3;
	const tickSpacing = readNumberParam(params, "tick_spacing") ?? 60;
	const hookAddress = readStringParam(params, "hook_address");
	const slippageBps = readNumberParam(params, "slippage_bps") ?? 50;
	const safety = await checkBalance({ requiredEth: 0 });
	if (!safety.safe) return errorResult(`Insufficient gas: ${safety.blockers.join("; ")}`);
	const amount0Wei = await toTokenWei(amount0, token0);
	const amount1Wei = await toTokenWei(amount1, token1);
	const result = await liquidity.v4MintPosition({
		token0,
		token1,
		fee,
		tickSpacing,
		hookAddress,
		tickLower,
		tickUpper,
		amount0Desired: amount0Wei,
		amount1Desired: amount1Wei,
		slippageBps,
		deadline: 1200
	});
	return jsonResult({
		status: "success",
		action: "v4_mint",
		tokenId: result.tokenId.toString(),
		liquidity: result.liquidity.toString(),
		amount0: result.amount0.toString(),
		amount1: result.amount1.toString(),
		txHash: result.txHash
	});
}
async function handleV3Add(liquidity, params) {
	const tokenId = readStringParam(params, "token_id", { required: true });
	const amount0 = readStringParam(params, "amount0", { required: true });
	const amount1 = readStringParam(params, "amount1", { required: true });
	const token0 = readStringParam(params, "token0");
	const token1 = readStringParam(params, "token1");
	const safety = await checkBalance({ requiredEth: 0 });
	if (!safety.safe) return errorResult(`Insufficient gas: ${safety.blockers.join("; ")}`);
	const a0 = validateAmount(amount0);
	const a1 = validateAmount(amount1);
	const amount0Wei = token0 ? await toTokenWei(a0, token0) : BigInt(Math.round(parseFloat(a0) * 0xde0b6b3a7640000));
	const amount1Wei = token1 ? await toTokenWei(a1, token1) : BigInt(Math.round(parseFloat(a1) * 0xde0b6b3a7640000));
	const result = await liquidity.v3AddLiquidity(validateTokenId(tokenId), {
		amount0Desired: amount0Wei,
		amount1Desired: amount1Wei,
		deadline: 1200
	});
	return jsonResult({
		status: "success",
		action: "v3_add",
		tokenId,
		amount0: result.amount0.toString(),
		amount1: result.amount1.toString(),
		txHash: result.txHash
	});
}
async function handleV3Remove(liquidity, params) {
	const tokenId = readStringParam(params, "token_id", { required: true });
	const percentage = readNumberParam(params, "percentage") ?? 100;
	const safety = await checkBalance({ requiredEth: 0 });
	if (!safety.safe) return errorResult(`Insufficient gas: ${safety.blockers.join("; ")}`);
	const pct = percentage / 100;
	const result = await liquidity.v3RemoveLiquidity(validateTokenId(tokenId), {
		percentageToRemove: pct,
		burnToken: pct === 1,
		deadline: 1200
	});
	return jsonResult({
		status: "success",
		action: "v3_remove",
		tokenId,
		percentage,
		amount0: result.amount0.toString(),
		amount1: result.amount1.toString(),
		txHash: result.txHash
	});
}
async function handleV3Collect(liquidity, params) {
	const tokenId = readStringParam(params, "token_id", { required: true });
	const safety = await checkBalance({ requiredEth: 0 });
	if (!safety.safe) return errorResult(`Insufficient gas: ${safety.blockers.join("; ")}`);
	const result = await liquidity.v3CollectFees(validateTokenId(tokenId));
	return jsonResult({
		status: "success",
		action: "v3_collect",
		tokenId,
		feesCollected: {
			token0: result.amount0.toString(),
			token1: result.amount1.toString()
		},
		txHash: result.txHash
	});
}
//#endregion
export { createLiquidityTool };

//# sourceMappingURL=liquidity.mjs.map