import winston from "winston";
import { SpokePoolClient } from "../SpokePoolClient";
import { HubPoolClient } from "../HubPoolClient";
import { CachedUBABundleState, ModifiedUBAFlow, SystemFeeResult, UBAClientState } from "./UBAClientTypes";
import { CachingMechanismInterface, UbaFlow, UbaInflow } from "../../interfaces";
import { BigNumber } from "ethers";
import { BaseAbstractClient } from "../BaseAbstractClient";
import UBAConfig from "../../UBAFeeCalculator/UBAFeeConfig";
import { UBAClientConfig } from "./UBAClientConfig";
/**
 * @notice This class reconstructs UBA bundle data for every bundle that has been created since the
 * UBA activation. Its performance can be signficantly sped up by integrating an external caching layer
 * like IPFS or Redis. It provides an interface that is designed to be called by actors who want to
 * to reconstruct a past bundle's state or validate a live bundle's state in order to evaluate a pending
 * root bundle, propose a new root bundle, or get the latest prices as a relayer or fee quoter.
 */
export declare class UBAClientWithRefresh extends BaseAbstractClient {
    readonly clientConfig: UBAClientConfig;
    readonly tokens: string[];
    protected readonly hubPoolClient: HubPoolClient;
    readonly spokePoolClients: {
        [chainId: number]: SpokePoolClient;
    };
    protected readonly cachingClient?: CachingMechanismInterface | undefined;
    ubaClientState: UBAClientState;
    ubaBundleStates: Record<string, CachedUBABundleState>;
    enabledChainIds: number[];
    chainIdIndices: number[];
    ubaBundleBlockRanges: number[][][];
    latestBlockTimestamps: Record<number, number>;
    logger: winston.Logger;
    /**
     * @notice Constructs a new UBAClientinstance.
     * @param clientConfig Configuration to customize the UBAClient instance.
     * @param tokens Tokens to load bundle state for.
     * @param hubPoolClient
     * @param spokePoolClients
     */
    constructor(clientConfig: UBAClientConfig, tokens: string[], hubPoolClient: HubPoolClient, spokePoolClients: {
        [chainId: number]: SpokePoolClient;
    }, cachingClient?: CachingMechanismInterface | undefined);
    /**
     * @notice Intended to be called by Relayer to set `realizedLpFeePct` for a deposit, where
     * realizedLpFeePct for this deposit should be equal to the lpFee plus the depositBalancingFee.
     * @param deposit Should be the deposit that the caller wants to compute the realizedLpFeePct for.
     */
    computeFeesForDeposit(deposit: UbaInflow): SystemFeeResult;
    /**
     * @notice Can be used by Relayer to approximate next refund balancing fees on refund chain. This is useful
     * for the relayer because they can only assume that their fill gets mined as the "next" fill on the destination
     * chain.
     * @dev Should work even if there are no validated flows or no bundle states yet.
     */
    computeBalancingFeeForNextRefund(repaymentChainId: number, refundTokenSymbol: string, amount: BigNumber): BigNumber;
    /**
     * @notice Expected to be called by dataworker to reconstruct bundle roots using validated flow information
     * in bundle.
     */
    getModifiedFlows(chainId: number, tokenSymbol: string, startBlock: number, endBlock: number): ModifiedUBAFlow[];
    getKeyForBundle: (bundleBlockRanges: number[][], tokenSymbol: string, chainId: number) => string;
    /**
     * Can be used by middleware API to refresh the latest bundle state for a given token and chain. The API
     * can serve this information and make it very fast to then compute the next deposit and refund balancing fees.
     * @param tokenSymbol
     * @param chainId
     * @returns
     */
    getLatestBundleState(tokenSymbol: string, chainId: number): {
        flows: ModifiedUBAFlow[];
        ubaConfig: UBAConfig;
    };
    /**
     * This client should only access the `ubaBundleStates` state via this function.
     */
    private getBundleState;
    /**
     * @notice Compute the LP fee for a given amount.
     */
    private computeLpFee;
    /**
     * Validate flows in bundle block ranges. Returns the flows mapped by chain ID where the flow occurred and also
     * caches the validated flows in this class instance.
     * @param blockRanges The block ranges to validate flows for. Must be a known block range in this.ubaBundleBlockRanges class variable.
     * @param tokenSymbol Flows to filter on.
     * @returns
     */
    private validateFlowsInBundle;
    /**
     * Return flow with computed fees if it is valid. Otherwise, return undefined. Inflows are always valid,
     * while outflows need to match against an inflow and have set the correct realizedLpFeePct
     * @param flow Flow to validate. It's assumed that flow is already matched with a deposit, if its an outflow.
     * @returns Validated flow or undefined if flow cannot be validated.
     */
    protected validateFlow(flow: UbaFlow): Promise<ModifiedUBAFlow | undefined>;
    /**
     * Locates the bundle range containing the flow on the specified chain and then tries to return the matching
     * validated flow if it already exists in memory.
     * @param flowBlock
     * @param flowChain
     * @param flow
     * @returns
     */
    private getMatchingValidatedFlow;
    /**
     * Returns a convenient mapping of the most recent block ranges for each chain.
     * Assumption: For each chain, there should be the same number of block ranges returned.
     * Assumption: The block ranges for each chain should cover from the activation bundle start block
     * for the UBA until the latest block searched for the chain.
     * @param bundleCount Block ranges to fetch per chain
     * @returns A dictionary mapping chainId to an array of block ranges, where the ranges are arrays of length two
     *         and the first element is the start block and the second element is the end block.
     */
    private getMostRecentBundleBlockRangesPerChain;
    /**
     * Return the block range stored in this.ubaBundleBlockRanges that contains the flow.
     * @param flowBlock
     * @param flowChain
     * @returns
     */
    private getUbaBundleBlockRangeContainingFlow;
    /**
     * This client should only update the `ubaBundleStates` state via this function.
     */
    private appendValidatedFlowsToClassState;
    /**
     * Updates the bundle state.
     */
    update(): Promise<void>;
}
