import { providers } from "ethers";
import { EventSearchConfig, DefaultLogLevels, MakeOptional, AnyObject } from "../utils";
import winston from "winston";
import { Contract, BigNumber, Event, EventFilter } from "ethers";
import { Deposit, DepositWithBlock, Fill, FillWithBlock, RefundRequestWithBlock, RelayerRefundExecutionWithBlock, RootBundleRelayWithBlock, SpeedUp, TokensBridged, FundsDepositedEvent, DepositWithBlockStringified, FillWithBlockStringified, SpeedUpStringified, TokensBridgedStringified, RelayerRefundExecutionWithBlockStringified, FundsDepositedEventStringified, RefundRequestWithBlockStringified } from "../interfaces";
import { HubPoolClient } from "./HubPoolClient";
import { BaseAbstractClient } from "./BaseAbstractClient";
declare type Block = providers.Block;
declare type _SpokePoolUpdate = {
    success: boolean;
    currentTime: number;
    firstDepositId: number;
    latestBlockNumber: number;
    latestDepositId: number;
    events: Event[][];
    blocks: {
        [blockNumber: number]: Block;
    };
    searchEndBlock: number;
};
export declare type SpokePoolUpdate = {
    success: false;
} | _SpokePoolUpdate;
/**
 * SpokePoolClient is a client for the SpokePool contract. It is responsible for querying the SpokePool contract
 * for events and storing them in memory. It also provides some convenience methods for querying the stored events.
 */
export declare class SpokePoolClient extends BaseAbstractClient {
    readonly logger: winston.Logger;
    readonly spokePool: Contract;
    readonly hubPoolClient: HubPoolClient | null;
    readonly chainId: number;
    deploymentBlock: number;
    readonly eventSearchConfig: MakeOptional<EventSearchConfig, "toBlock">;
    protected currentTime: number;
    protected depositHashes: {
        [depositHash: string]: DepositWithBlock;
    };
    protected depositHashesToFills: {
        [depositHash: string]: FillWithBlock[];
    };
    protected speedUps: {
        [depositorAddress: string]: {
            [depositId: number]: SpeedUp[];
        };
    };
    protected depositRoutes: {
        [originToken: string]: {
            [DestinationChainId: number]: boolean;
        };
    };
    protected tokensBridged: TokensBridged[];
    protected rootBundleRelays: RootBundleRelayWithBlock[];
    protected relayerRefundExecutions: RelayerRefundExecutionWithBlock[];
    protected earlyDeposits: FundsDepositedEvent[];
    protected queryableEventNames: string[];
    earliestDepositIdQueried: number;
    latestDepositIdQueried: number;
    firstDepositIdForSpokePool: number;
    lastDepositIdForSpokePool: number;
    firstBlockToSearch: number;
    latestBlockSearched: number;
    latestBlockNumber: number;
    fills: {
        [OriginChainId: number]: FillWithBlock[];
    };
    refundRequests: RefundRequestWithBlock[];
    /**
     * Creates a new SpokePoolClient.
     * @param logger A logger instance.
     * @param spokePool The SpokePool contract instance that this client will query.
     * @param hubPoolClient An optional HubPoolClient instance. This is used to fetch spoke data that is not stored on the SpokePool contract but is stored on the HubPool contract.
     * @param chainId The chain ID of the chain that this client is querying.
     * @param deploymentBlock The block number that the SpokePool contract was deployed at.
     * @param eventSearchConfig An optional EventSearchConfig object that controls how far back in history the client will search for events. If not provided, the client will only search for events from the deployment block.
     */
    constructor(logger: winston.Logger, spokePool: Contract, hubPoolClient: HubPoolClient | null, chainId: number, deploymentBlock: number, eventSearchConfig?: MakeOptional<EventSearchConfig, "toBlock">);
    _queryableEventNames(): {
        [eventName: string]: EventFilter;
    };
    /**
     * Retrieves a list of deposits from the SpokePool contract destined for the given destination chain ID.
     * @param destinationChainId The destination chain ID.
     * @returns A list of deposits.
     */
    getDepositsForDestinationChain(destinationChainId: number): DepositWithBlock[];
    /**
     * Retrieves a list of deposits from the SpokePool contract that are associated with this spoke pool.
     * @returns A list of deposits.
     * @note This method returns all deposits, regardless of destination chain ID in sorted order.
     */
    getDeposits(): DepositWithBlock[];
    /**
     * Retrieves a list of the tokens that have been bridged.
     * @returns A list of tokens.
     */
    getTokensBridged(): TokensBridged[];
    /**
     * Retrieves a mapping of tokens and their associated destination chain IDs that can be bridged.
     * @returns A mapping of tokens and their associated destination chain IDs in a nested mapping.
     */
    getDepositRoutes(): {
        [originToken: string]: {
            [DestinationChainId: number]: boolean;
        };
    };
    /**
     * Determines whether a deposit route is enabled for the given origin token and destination chain ID.
     * @param originToken The origin token address.
     * @param destinationChainId The destination chain ID.
     * @returns True if the deposit route is enabled, false otherwise.
     */
    isDepositRouteEnabled(originToken: string, destinationChainId: number): boolean;
    /**
     * Retrieves a list of all the available origin tokens that can be bridged.
     * @returns A list of origin tokens.
     */
    getAllOriginTokens(): string[];
    /**
     * Retrieves a list of fills from the SpokePool contract.
     * @returns A list of fills.
     */
    getFills(): FillWithBlock[];
    /**
     * Retrieves a list of fills from a specific origin chain ID.
     * @param originChainId The origin chain ID.
     * @returns A list of fills.
     */
    getFillsForOriginChain(originChainId: number): FillWithBlock[];
    /**
     * Retrieves a list of fills from a specific relayer address.
     * @param relayer The relayer address.
     * @returns A list of fills.
     */
    getFillsForRelayer(relayer: string): FillWithBlock[];
    /**
     * Retrieves a list of fills from a given block range.
     * @param startingBlock The starting block number.
     * @param endingBlock The ending block number.
     * @returns A list of fills.
     */
    getFillsWithBlockInRange(startingBlock: number, endingBlock: number): FillWithBlock[];
    /**
     * Retrieves a list of refund requests from the SpokePool contract that are within an optional block range.
     * @param fromBlock The starting block number. If not provided, requests will not be filtered by any bounds.
     * @param toBlock The ending block number. If not provided, requests will not be filtered by any bounds.
     * @returns A list of refund requests.
     */
    getRefundRequests(fromBlock?: number, toBlock?: number): RefundRequestWithBlock[];
    /**
     * Retrieves a list of root bundle relays from the SpokePool contract.
     * @returns A list of root bundle relays.
     */
    getRootBundleRelays(): RootBundleRelayWithBlock[];
    /**
     * Retrieves the ID of the latest root bundle.
     * @returns The ID of the latest root bundle. This will be 0 if no root bundles have been relayed.
     */
    getLatestRootBundleId(): number;
    /**
     * Retrieves a list of relayer refund executions from the SpokePool contract.
     * @returns A list of relayer refund executions.
     */
    getRelayerRefundExecutions(): RelayerRefundExecutionWithBlock[];
    /**
     * Retrieves a mapping of token addresses to relayer addresses to the amount of refunds that have been executed.
     * @returns A mapping of token addresses to relayer addresses to the amount of refunds that have been executed.
     */
    getExecutedRefunds(relayerRefundRoot: string): {
        [tokenAddress: string]: {
            [relayer: string]: BigNumber;
        };
    };
    /**
     * Appends a speed up signature to a specific deposit.
     * @param deposit The deposit to append the speed up signature to.
     * @returns A new deposit instance with the speed up signature appended to the deposit.
     */
    appendMaxSpeedUpSignatureToDeposit(deposit: DepositWithBlock): DepositWithBlock;
    /**
     * Find a corresponding deposit for a given fill.
     * @param fill The fill to find a corresponding deposit for.
     * @returns The corresponding deposit if found, undefined otherwise.
     */
    getDepositForFill(fill: Fill, fillFieldsToIgnore?: string[]): DepositWithBlock | undefined;
    /**
     * @dev TODO This function is a bit of a hack for now and its dangerous to leave public because it allows the caller to
     * manipulate internal data that was set at update() time. This is a workaround the current structure where UBAClient
     * is dependent on SpokePoolClient, but one of the SpokePoolClient's internal data structures, `deposits` is dependent
     * on the UBA client state being updated in order to have set correct realizedLpFeePcts. This function is currently
     * designed to be called by the UBA client for each deposit that is loaded and have it reset the realizedLpFeePct
     * equal to the depositBalancingFee plus the LP fee.
     */
    updateDepositRealizedLpFeePct(event: Deposit, realizedLpFeePct: BigNumber): void;
    /**
     * Find the unfilled amount for a given deposit. This is the full deposit amount minus the total filled amount.
     * @param deposit The deposit to find the unfilled amount for.
     * @param fillCount The number of fills that have been applied to this deposit.
     * @param invalidFills The invalid fills that have been applied to this deposit.
     * @returns The unfilled amount.
     */
    getValidUnfilledAmountForDeposit(deposit: Deposit): {
        unfilledAmount: BigNumber;
        fillCount: number;
        invalidFills: Fill[];
    };
    /**
     * Formulate a hash for a given deposit or fill
     * @param event The deposit or fill to formulate a hash for.
     * @returns The hash.
     * @note This hash is used to match deposits and fills together.
     * @note This hash takes the form of: `${depositId}-${originChainId}`.
     */
    getDepositHash(event: Deposit | Fill | DepositWithBlock | FillWithBlock): string;
    /**
     * Find the block range that contains the deposit ID. This is a binary search that searches for the block range
     * that contains the deposit ID.
     * @param targetDepositId The target deposit ID to search for.
     * @param initLow The initial lower bound of the block range to search.
     * @param initHigh The initial upper bound of the block range to search.
     * @param maxSearches The maximum number of searches to perform. This is used to prevent infinite loops.
     * @returns The block range that contains the deposit ID.
     * @note  // We want to find the block range that satisfies these conditions:
     *        // - the low block has deposit count <= targetDepositId
     *        // - the high block has a deposit count > targetDepositId.
     *        // This way the caller can search for a FundsDeposited event between [low, high] that will always
     *        // contain the event emitted when deposit ID was incremented to targetDepositId + 1. This is the same transaction
     *        // where the deposit with deposit ID = targetDepositId was created.
     */
    _getBlockRangeForDepositId(targetDepositId: number, initLow: number, initHigh: number, maxSearches: number): Promise<{
        low: number;
        high: number;
    }>;
    /**
     * Finds the deposit id at a specific block number.
     * @param blockTag The block number to search for the deposit ID at.
     * @returns The deposit ID.
     */
    _getDepositIdAtBlock(blockTag: number): Promise<number>;
    /**
     * Queries the SpokePool contract for a list of historical fills that match the given fill and deposit.
     * @param fill The fill to match.
     * @param deposit The deposit to match.
     * @param toBlock The block number to search up to.
     * @returns A list of fills that match the given fill and deposit.
     */
    queryHistoricalMatchingFills(fill: Fill, deposit: Deposit, toBlock: number): Promise<FillWithBlock[]>;
    /**
     * Queries the SpokePool contract for a list of fills that match the given fill.
     * @param fill The fill to match.
     * @param searchConfig The search configuration.
     * @returns A Promise that resolves to a list of fills that match the given fill.
     */
    queryFillsInBlockRange(matchingFill: Fill, searchConfig: EventSearchConfig): Promise<FillWithBlock[]>;
    /**
     * Performs an update to refresh the state of this client. This will query the SpokePool contract for new events
     * and store them in memory. This method is the primary method for updating the state of this client.
     * @param eventsToQuery An optional list of events to query. If not provided, all events will be queried.
     * @returns A Promise that resolves to a SpokePoolUpdate object.
     */
    protected _update(eventsToQuery: string[]): Promise<SpokePoolUpdate>;
    /**
     * A wrapper over the `_update` method that handles errors and logs. This method additionally calls into the
     * HubPoolClient to update the state of this client with data from the HubPool contract.
     * @param eventsToQuery An optional list of events to query. If not provided, all events will be queried.
     * @returns A Promise that resolves to a SpokePoolUpdate object.
     * @note This method is the primary method for updating the state of this client externally.
     * @see _update
     */
    update(eventsToQuery?: string[]): Promise<void>;
    /**
     * Retrieves the l2TokenAddress for a given executed refund leaf.
     * @param chainId The chain ID of the executed refund leaf.
     * @param eventL2Token The l2TokenAddress of the executed refund leaf.
     * @returns The l2TokenAddress of the executed refund leaf.
     */
    static getExecutedRefundLeafL2Token(chainId: number, eventL2Token: string): string;
    /**
     * Computes the realized LP fee percentage for a given deposit.
     * @param depositEvent The deposit event to compute the realized LP fee percentage for.
     * @returns The realized LP fee percentage.
     */
    protected computeRealizedLpFeePct(depositEvent: FundsDepositedEvent): Promise<{
        realizedLpFeePct: BigNumber | undefined;
        quoteBlock: number;
    }>;
    /**
     * Retrieves the destination token for a given deposit.
     * @param deposit The deposit to retrieve the destination token for.
     * @returns The destination token.
     */
    protected getDestinationTokenForDeposit(deposit: DepositWithBlock): string;
    /**
     * Performs a log for a specific level, message and data.
     * @param level The log level.
     * @param message The log message.
     * @param data Optional data to log.
     */
    protected log(level: DefaultLogLevels, message: string, data?: AnyObject): void;
    /**
     * Retrieves the current time from the SpokePool contract.
     * @returns The current time.
     */
    getCurrentTime(): number;
    /**
     * Finds a deposit for a given deposit ID, destination chain ID and depositor address. This method will search for
     * the deposit in the SpokePool contract and return it if found. If the deposit is not found, this method will
     * perform a binary search to find the block range that contains the deposit ID and then perform an eth_getLogs
     * call to find the deposit.
     * @param depositId The deposit ID to find.
     * @param destinationChainId The destination chain ID to find.
     * @param depositor The depositor address to find.
     * @returns The deposit if found.
     * @note This method is used to find deposits that are outside of the search range of this client.
     */
    findDeposit(depositId: number, destinationChainId: number, depositor: string): Promise<DepositWithBlock>;
    updateFromJSON(spokePoolClientState: Partial<ReturnType<SpokePoolClient["toJSON"]>>): void;
    toJSON(): {
        chainId: number;
        deploymentBlock: number;
        eventSearchConfig: MakeOptional<EventSearchConfig, "toBlock">;
        currentTime: number;
        depositHashes: Record<string, DepositWithBlockStringified>;
        depositHashesToFills: Record<string, FillWithBlockStringified[]>;
        speedUps: {
            [depositorAddress: string]: {
                [depositId: number]: SpeedUpStringified[];
            };
        };
        depositRoutes: {
            [originToken: string]: {
                [DestinationChainId: number]: boolean;
            };
        };
        tokensBridged: TokensBridgedStringified[];
        rootBundleRelays: RootBundleRelayWithBlock[];
        relayerRefundExecutions: RelayerRefundExecutionWithBlockStringified[];
        earlyDeposits: FundsDepositedEventStringified[];
        queryableEventNames: string[];
        earliestDepositIdQueried: number;
        earliestDepositIdForSpokePool: number;
        latestDepositIdQueried: number;
        latestDepositIdForSpokePool: number;
        firstBlockToSearch: number;
        latestBlockSearched: number;
        isUpdated: boolean;
        fills: Record<string, FillWithBlockStringified[]>;
        refundRequests: RefundRequestWithBlockStringified[];
    };
}
export {};
