import { Contract } from 'ethers'; import { ProtocolDetector } from './ProtocolDetector'; /** * Vault balance structure */ export interface VaultBalances { bal0: bigint; bal1: bigint; } /** * Vault input interface for balance queries */ export interface VaultInput { vaultAddress: string; beaconName: string; token0: string; token1: string; } /** * BalanceQuerier retrieves vault token balances * * Uses protocol-specific methods to query balances: * - PoolShark, Blackhole, Aerodrome: algebraVaultDetailsByAddress() * - Other protocols: vaultBalancesByAddressWithFees() */ export class BalanceQuerier { private protocolDetector: ProtocolDetector; private steerPeripheryContract: Contract; constructor( steerPeripheryContract: Contract, protocolDetector?: ProtocolDetector, ) { this.steerPeripheryContract = steerPeripheryContract; this.protocolDetector = protocolDetector || new ProtocolDetector(); } /** * Get vault token balances * * Uses different methods based on protocol: * - PoolShark, Blackhole, Aerodrome: algebraVaultDetailsByAddress() * - All other protocols: vaultBalancesByAddressWithFees() * * @param vault - Vault input with address and beacon name * @returns Promise - Token balances (bal0, bal1) */ async getVaultBalances(vault: VaultInput): Promise { let bal0: bigint; let bal1: bigint; // Protocol-specific balance query if ( this.protocolDetector.isPoolSharkVault(vault.beaconName) || this.protocolDetector.isBlackholeVault(vault.beaconName) || this.protocolDetector.isAerodromeVault(vault.beaconName) ) { // Use algebraVaultDetailsByAddress for these protocols const algebraDetails = await this.steerPeripheryContract.algebraVaultDetailsByAddress( vault.vaultAddress, ); bal0 = algebraDetails.token0Balance; bal1 = algebraDetails.token1Balance; } else { // Use standard vaultBalancesByAddressWithFees for other protocols const vaultBalancesFn = this.steerPeripheryContract.getFunction( 'vaultBalancesByAddressWithFees', ); [bal0, bal1] = await vaultBalancesFn.staticCall(vault.vaultAddress); } return { bal0, bal1 }; } }