import { config, BIN_STEP } from '../config' import { getPublicClient, getAccount } from './client' import { LB_PAIR_ABI } from './abi' const pair = () => ({ address: config.contracts.lbPair, abi: LB_PAIR_ABI, }) export async function getActiveId(): Promise { const client = getPublicClient() const result = await client.readContract({ ...pair(), functionName: 'getActiveId', }) return Number(result) } export async function getBinStep(): Promise { const client = getPublicClient() const result = await client.readContract({ ...pair(), functionName: 'getBinStep', }) return Number(result) } export async function getBinReserves( binId: number, ): Promise<{ reserveX: bigint; reserveY: bigint }> { const client = getPublicClient() const [reserveX, reserveY] = await client.readContract({ ...pair(), functionName: 'getBin', args: [binId], }) return { reserveX, reserveY } } export async function getPoolReserves(): Promise<{ reserveX: bigint; reserveY: bigint }> { const client = getPublicClient() const [reserveX, reserveY] = await client.readContract({ ...pair(), functionName: 'getReserves', }) return { reserveX, reserveY } } export async function getUserBinBalance(binId: number): Promise { const client = getPublicClient() const account = getAccount() return await client.readContract({ ...pair(), functionName: 'balanceOf', args: [account.address, BigInt(binId)], }) } export async function getUserBinBalancesBatch( binIds: number[], ): Promise> { const client = getPublicClient() const account = getAccount() const accounts = binIds.map(() => account.address) const ids = binIds.map((id) => BigInt(id)) const balances = await client.readContract({ ...pair(), functionName: 'balanceOfBatch', args: [accounts, ids], }) const result = new Map() binIds.forEach((id, i) => { if (balances[i] > 0n) result.set(id, balances[i]) }) return result } export async function getBinTotalSupply(binId: number): Promise { const client = getPublicClient() return await client.readContract({ ...pair(), functionName: 'totalSupply', args: [BigInt(binId)], }) } export async function isApprovedForAll(spender: `0x${string}`): Promise { const client = getPublicClient() const account = getAccount() return await client.readContract({ ...pair(), functionName: 'isApprovedForAll', args: [account.address, spender], }) } export function getPriceFromBinId(binId: number, binStep = BIN_STEP): number { return (1 + binStep / 10_000) ** (binId - 8388608) } export function getBinIdFromPrice(price: number, binStep = BIN_STEP): number { return Math.round(Math.log(price) / Math.log(1 + binStep / 10_000) + 8388608) } export async function getActivePrice(): Promise<{ activeId: number; price: number }> { const activeId = await getActiveId() const price = getPriceFromBinId(activeId) return { activeId, price } } export async function findUserBinIds(searchRange = 50): Promise { const activeId = await getActiveId() const account = getAccount() const client = getPublicClient() const allBinIds: number[] = [] for (let offset = -searchRange; offset <= searchRange; offset++) { allBinIds.push(activeId + offset) } const accounts = allBinIds.map(() => account.address) const ids = allBinIds.map((id) => BigInt(id)) const balances = await client.readContract({ ...pair(), functionName: 'balanceOfBatch', args: [accounts, ids], }) return allBinIds.filter((_, i) => balances[i] > 0n) }