import { AAVE, CBETH, MORPHO, TOKENS } from "../lib/contract-registry.mjs";
//#region extensions/crypto/src/services/lending-service.ts
const LENDING_CONTRACTS = {
	aave: {
		pool: AAVE.pool,
		poolDataProvider: AAVE.poolDataProvider,
		oracle: AAVE.oracle,
		chain: 8453,
		name: "Aave V3 Base"
	},
	morpho: {
		core: MORPHO.core,
		chain: 8453,
		name: "Morpho Base"
	}
};
const LENDING_ASSETS = {
	ETH: {
		symbol: "ETH",
		address: TOKENS.base.WETH,
		decimals: 18,
		aToken: AAVE.aTokens.WETH.aToken,
		variableDebtToken: AAVE.aTokens.WETH.debtToken
	},
	USDC: {
		symbol: "USDC",
		address: TOKENS.base.USDC,
		decimals: 6,
		aToken: AAVE.aTokens.USDC.aToken,
		variableDebtToken: AAVE.aTokens.USDC.debtToken
	},
	cbETH: {
		symbol: "cbETH",
		address: CBETH.base,
		decimals: 18,
		aToken: AAVE.aTokens.cbETH.aToken,
		variableDebtToken: AAVE.aTokens.cbETH.debtToken
	},
	USDbC: {
		symbol: "USDbC",
		address: TOKENS.base.USDbC,
		decimals: 6,
		aToken: AAVE.aTokens.USDbC.aToken,
		variableDebtToken: AAVE.aTokens.USDbC.debtToken
	}
};
const AAVE_POOL_ABI = [
	{
		name: "supply",
		type: "function",
		stateMutability: "nonpayable",
		inputs: [
			{
				name: "asset",
				type: "address"
			},
			{
				name: "amount",
				type: "uint256"
			},
			{
				name: "onBehalfOf",
				type: "address"
			},
			{
				name: "referralCode",
				type: "uint16"
			}
		],
		outputs: []
	},
	{
		name: "borrow",
		type: "function",
		stateMutability: "nonpayable",
		inputs: [
			{
				name: "asset",
				type: "address"
			},
			{
				name: "amount",
				type: "uint256"
			},
			{
				name: "interestRateMode",
				type: "uint256"
			},
			{
				name: "referralCode",
				type: "uint16"
			},
			{
				name: "onBehalfOf",
				type: "address"
			}
		],
		outputs: []
	},
	{
		name: "repay",
		type: "function",
		stateMutability: "nonpayable",
		inputs: [
			{
				name: "asset",
				type: "address"
			},
			{
				name: "amount",
				type: "uint256"
			},
			{
				name: "interestRateMode",
				type: "uint256"
			},
			{
				name: "onBehalfOf",
				type: "address"
			}
		],
		outputs: [{
			name: "",
			type: "uint256"
		}]
	},
	{
		name: "withdraw",
		type: "function",
		stateMutability: "nonpayable",
		inputs: [
			{
				name: "asset",
				type: "address"
			},
			{
				name: "amount",
				type: "uint256"
			},
			{
				name: "to",
				type: "address"
			}
		],
		outputs: [{
			name: "",
			type: "uint256"
		}]
	},
	{
		name: "getUserAccountData",
		type: "function",
		stateMutability: "view",
		inputs: [{
			name: "user",
			type: "address"
		}],
		outputs: [
			{
				name: "totalCollateralBase",
				type: "uint256"
			},
			{
				name: "totalDebtBase",
				type: "uint256"
			},
			{
				name: "availableBorrowsBase",
				type: "uint256"
			},
			{
				name: "currentLiquidationThreshold",
				type: "uint256"
			},
			{
				name: "ltv",
				type: "uint256"
			},
			{
				name: "healthFactor",
				type: "uint256"
			}
		]
	}
];
const ERC20_APPROVE_ABI = [{
	name: "approve",
	type: "function",
	stateMutability: "nonpayable",
	inputs: [{
		name: "spender",
		type: "address"
	}, {
		name: "amount",
		type: "uint256"
	}],
	outputs: [{
		name: "",
		type: "bool"
	}]
}, {
	name: "allowance",
	type: "function",
	stateMutability: "view",
	inputs: [{
		name: "owner",
		type: "address"
	}, {
		name: "spender",
		type: "address"
	}],
	outputs: [{
		name: "",
		type: "uint256"
	}]
}];
var LendingService = class {
	/**
	* Resolve asset symbol to lending asset info.
	*/
	resolveAsset(symbolOrAddress) {
		const upper = symbolOrAddress.toUpperCase();
		if (LENDING_ASSETS[upper]) return LENDING_ASSETS[upper];
		const lower = symbolOrAddress.toLowerCase();
		for (const asset of Object.values(LENDING_ASSETS)) if (asset.address.toLowerCase() === lower) return asset;
		return null;
	}
	/**
	* Get user account data from Aave V3 (health factor, collateral, debt).
	*/
	async getUserAccountData(userAddress, publicClient) {
		const [totalCollateral, totalDebt, availableBorrows, liqThreshold, ltv, healthFactor] = await publicClient.readContract({
			address: LENDING_CONTRACTS.aave.pool,
			abi: AAVE_POOL_ABI,
			functionName: "getUserAccountData",
			args: [userAddress]
		});
		return {
			totalCollateralUsd: Number(totalCollateral) / 1e8,
			totalDebtUsd: Number(totalDebt) / 1e8,
			availableBorrowsUsd: Number(availableBorrows) / 1e8,
			liquidationThreshold: Number(liqThreshold) / 100,
			ltv: Number(ltv) / 100,
			healthFactor: healthFactor >= BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") ? Infinity : Number(healthFactor) / 0xde0b6b3a7640000
		};
	}
	/**
	* Supply an asset to Aave V3.
	* Returns the confirmed transaction hash.
	*/
	async supply(asset, amount, userAddress, walletClient, publicClient) {
		await this.ensureApproval(asset.address, LENDING_CONTRACTS.aave.pool, amount, userAddress, walletClient, publicClient);
		const hash = await walletClient.writeContract({
			address: LENDING_CONTRACTS.aave.pool,
			abi: AAVE_POOL_ABI,
			functionName: "supply",
			args: [
				asset.address,
				amount,
				userAddress,
				0
			]
		});
		await publicClient.waitForTransactionReceipt({ hash });
		return {
			hash,
			action: "supply",
			asset: asset.symbol,
			amount: amount.toString()
		};
	}
	/**
	* Borrow an asset from Aave V3 (variable rate).
	*/
	async borrow(asset, amount, userAddress, walletClient, publicClient) {
		const hash = await walletClient.writeContract({
			address: LENDING_CONTRACTS.aave.pool,
			abi: AAVE_POOL_ABI,
			functionName: "borrow",
			args: [
				asset.address,
				amount,
				BigInt(2),
				0,
				userAddress
			]
		});
		if (publicClient) await publicClient.waitForTransactionReceipt({ hash });
		return {
			hash,
			action: "borrow",
			asset: asset.symbol,
			amount: amount.toString()
		};
	}
	/**
	* Repay a borrowed asset on Aave V3.
	* Use amount = MaxUint256 to repay entire debt.
	*
	* When skipApproval is true, the caller has already handled approval
	* (e.g. for max repay with bounded approval instead of MaxUint256).
	*/
	async repay(asset, amount, userAddress, walletClient, publicClient, skipApproval = false) {
		if (!skipApproval) await this.ensureApproval(asset.address, LENDING_CONTRACTS.aave.pool, amount, userAddress, walletClient, publicClient);
		const hash = await walletClient.writeContract({
			address: LENDING_CONTRACTS.aave.pool,
			abi: AAVE_POOL_ABI,
			functionName: "repay",
			args: [
				asset.address,
				amount,
				BigInt(2),
				userAddress
			]
		});
		await publicClient.waitForTransactionReceipt({ hash });
		return {
			hash,
			action: "repay",
			asset: asset.symbol,
			amount: amount.toString()
		};
	}
	/**
	* Withdraw a supplied asset from Aave V3.
	* Use amount = MaxUint256 to withdraw entire balance.
	*/
	async withdraw(asset, amount, userAddress, walletClient, publicClient) {
		const hash = await walletClient.writeContract({
			address: LENDING_CONTRACTS.aave.pool,
			abi: AAVE_POOL_ABI,
			functionName: "withdraw",
			args: [
				asset.address,
				amount,
				userAddress
			]
		});
		if (publicClient) await publicClient.waitForTransactionReceipt({ hash });
		return {
			hash,
			action: "withdraw",
			asset: asset.symbol,
			amount: amount.toString()
		};
	}
	/**
	* Get list of supported lending assets.
	*/
	getSupportedAssets() {
		return Object.values(LENDING_ASSETS);
	}
	/**
	* Get supported protocols.
	* Note: Morpho contract address is defined in LENDING_CONTRACTS for future use,
	* but is not yet implemented. Only Aave V3 is currently supported.
	*/
	getSupportedProtocols() {
		return [{
			id: "aave",
			name: LENDING_CONTRACTS.aave.name,
			chain: LENDING_CONTRACTS.aave.chain
		}];
	}
	/**
	* Get the current variable debt balance for an asset.
	* Useful for calculating exact repay amounts instead of MaxUint256 approvals.
	*/
	async getDebtBalance(asset, userAddress, publicClient) {
		if (!asset.variableDebtToken) return 0n;
		const { erc20Abi } = await import("../../_esm-BrzUp3yp.mjs").then((n) => n.t);
		return await publicClient.readContract({
			address: asset.variableDebtToken,
			abi: erc20Abi,
			functionName: "balanceOf",
			args: [userAddress]
		});
	}
	/**
	* Public wrapper for ensureApproval — used when the caller needs to
	* control the approval amount separately (e.g. max repay with bounded approval).
	*/
	async ensureApprovalPublic(tokenAddress, amount, owner, walletClient, publicClient) {
		await this.ensureApproval(tokenAddress, LENDING_CONTRACTS.aave.pool, amount, owner, walletClient, publicClient);
	}
	async ensureApproval(tokenAddress, spender, amount, owner, walletClient, publicClient) {
		if (await publicClient.readContract({
			address: tokenAddress,
			abi: ERC20_APPROVE_ABI,
			functionName: "allowance",
			args: [owner, spender]
		}) < amount) {
			const approveHash = await walletClient.writeContract({
				address: tokenAddress,
				abi: ERC20_APPROVE_ABI,
				functionName: "approve",
				args: [spender, amount]
			});
			await publicClient.waitForTransactionReceipt({ hash: approveHash });
		}
	}
};
let _instance = null;
function getLendingService() {
	if (!_instance) _instance = new LendingService();
	return _instance;
}
function resetLendingService() {
	_instance = null;
}
//#endregion
export { AAVE_POOL_ABI, ERC20_APPROVE_ABI, LENDING_ASSETS, LENDING_CONTRACTS, LendingService, getLendingService, resetLendingService };

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