import { BigNumber, BigNumberish } from '@ethersproject/bignumber';
import { BytesLike } from '@ethersproject/bytes';
import { BaseProvider } from '@ethersproject/providers';
import { Protocol } from '@uniswap/router-sdk';
import { ChainId } from '@uniswap/sdk-core';
import { Options as RetryOptions } from 'async-retry';
import { SupportedRoutes, V3Route, V4Route } from '../routers/router';
import { CurrencyAmount } from '../util/amounts';
import { Result } from './multicall-provider';
import { UniswapMulticallProvider } from './multicall-uniswap-provider';
import { ProviderConfig } from './provider';
/**
 * Emulate on-chain [PathKey](https://github.com/Uniswap/v4-periphery/blob/main/src/libraries/PathKey.sol#L8) struct
 */
export declare type PathKey = {
    intermediateCurrency: string;
    fee: BigNumberish;
    tickSpacing: BigNumberish;
    hooks: string;
    hookData: BytesLike;
};
export declare type SupportedPath = string | PathKey[];
/**
 * Emulate on-chain [QuoteExactParams](https://github.com/Uniswap/v4-periphery/blob/main/src/interfaces/IQuoter.sol#L34) struct
 */
export declare type QuoteExactParams = {
    exactCurrency: string;
    path: PathKey[];
    exactAmount: BigNumberish;
};
/**
 * Emulate on-chain [ExtraQuoteExactInputParams](https://github.com/Uniswap/mixed-quoter/blob/main/src/interfaces/IMixedRouteQuoterV2.sol#L44C12-L44C38) struct
 */
declare type NonEncodableData = {
    hookData: BytesLike;
};
export declare type ExtraQuoteExactInputParams = {
    nonEncodableData: NonEncodableData[];
};
export declare type QuoteInputType = QuoteExactParams[] | [string, string] | [string, ExtraQuoteExactInputParams, string];
/**
 * An on chain quote for a swap.
 */
export declare type AmountQuote = {
    amount: CurrencyAmount;
    /**
     * Quotes can be null (e.g. pool did not have enough liquidity).
     */
    quote: BigNumber | null;
    /**
     * For each pool in the route, the sqrtPriceX96 after the swap.
     */
    sqrtPriceX96AfterList: BigNumber[] | null;
    /**
     * For each pool in the route, the number of ticks crossed.
     */
    initializedTicksCrossedList: number[] | null;
    /**
     * An estimate of the gas used by the swap. This is returned by the multicall
     * and is not necessarily accurate due to EIP-2929 causing gas costs to vary
     * depending on if the slot has already been loaded in the call.
     */
    gasEstimate: BigNumber | null;
    /**
     * Final attempted gas limit set by the on-chain quote provider
     */
    gasLimit: BigNumber | null;
};
export declare class BlockConflictError extends Error {
    name: string;
}
export declare class SuccessRateError extends Error {
    name: string;
}
export declare class ProviderBlockHeaderError extends Error {
    name: string;
}
export declare class ProviderTimeoutError extends Error {
    name: string;
}
/**
 * This error typically means that the gas used by the multicall has
 * exceeded the total call gas limit set by the node provider.
 *
 * This can be resolved by modifying BatchParams to request fewer
 * quotes per call, or to set a lower gas limit per quote.
 *
 * @export
 * @class ProviderGasError
 */
export declare class ProviderGasError extends Error {
    name: string;
}
export declare type QuoteRetryOptions = RetryOptions;
/**
 * The V3 route and a list of quotes for that route.
 */
export declare type RouteWithQuotes<TRoute extends SupportedRoutes> = [
    TRoute,
    AmountQuote[]
];
/**
 * Final consolidated return type of all on-chain quotes.
 */
export declare type OnChainQuotes<TRoute extends SupportedRoutes> = {
    routesWithQuotes: RouteWithQuotes<TRoute>[];
    blockNumber: BigNumber;
};
export declare type SupportedExactOutRoutes = V4Route | V3Route;
/**
 * Provider for getting on chain quotes using routes containing V3 pools or V2 pools.
 *
 * @export
 * @interface IOnChainQuoteProvider
 */
export interface IOnChainQuoteProvider {
    /**
     * For every route, gets an exactIn quotes for every amount provided.
     * @notice While passing in exactIn V2Routes is supported, we recommend using the V2QuoteProvider to compute off chain quotes for V2 whenever possible
     *
     * @param amountIns The amounts to get quotes for.
     * @param routes The routes to get quotes for.
     * @param [providerConfig] The provider config.
     * @returns For each route returns a RouteWithQuotes object that contains all the quotes.
     * @returns The blockNumber used when generating the quotes.
     */
    getQuotesManyExactIn<TRoute extends SupportedRoutes>(amountIns: CurrencyAmount[], routes: TRoute[], providerConfig?: ProviderConfig): Promise<OnChainQuotes<TRoute>>;
    /**
     * For every route, gets ane exactOut quote for every amount provided.
     * @notice This does not support quotes for MixedRoutes (routes with both V3 and V2 pools/pairs) or pure V2 routes
     *
     * @param amountOuts The amounts to get quotes for.
     * @param routes The routes to get quotes for.
     * @param [providerConfig] The provider config.
     * @returns For each route returns a RouteWithQuotes object that contains all the quotes.
     * @returns The blockNumber used when generating the quotes.
     */
    getQuotesManyExactOut<TRoute extends SupportedExactOutRoutes>(amountOuts: CurrencyAmount[], routes: TRoute[], providerConfig?: ProviderConfig): Promise<OnChainQuotes<TRoute>>;
}
/**
 * The parameters for the multicalls we make.
 *
 * It is important to ensure that (gasLimitPerCall * multicallChunk) < providers gas limit per call.
 *
 * On chain quotes can consume a lot of gas (if the swap is so large that it swaps through a large
 * number of ticks), so there is a risk of exceeded gas limits in these multicalls.
 */
export declare type BatchParams = {
    /**
     * The number of quotes to fetch in each multicall.
     */
    multicallChunk: number;
    /**
     * The maximum call to consume for each quote in the multicall.
     */
    gasLimitPerCall: number;
    /**
     * The minimum success rate for all quotes across all multicalls.
     * If we set our gasLimitPerCall too low it could result in a large number of
     * quotes failing due to out of gas. This parameters will fail the overall request
     * in this case.
     */
    quoteMinSuccessRate: number;
};
/**
 * The fallback values for gasLimit and multicallChunk if any failures occur.
 *
 */
export declare type FailureOverrides = {
    multicallChunk: number;
    gasLimitOverride: number;
};
export declare type BlockHeaderFailureOverridesDisabled = {
    enabled: false;
};
export declare type BlockHeaderFailureOverridesEnabled = {
    enabled: true;
    rollbackBlockOffset: number;
    attemptsBeforeRollback: number;
};
export declare type BlockHeaderFailureOverrides = BlockHeaderFailureOverridesDisabled | BlockHeaderFailureOverridesEnabled;
/**
 * Config around what block number to query and how to handle failures due to block header errors.
 */
export declare type BlockNumberConfig = {
    baseBlockOffset: number;
    rollback: BlockHeaderFailureOverrides;
};
/**
 * Computes on chain quotes for swaps. For pure V3 routes, quotes are computed on-chain using
 * the 'QuoterV2' smart contract. For exactIn mixed and V2 routes, quotes are computed using the 'MixedRouteQuoterV1' contract
 * This is because computing quotes off-chain would require fetching all the tick data for each pool, which is a lot of data.
 *
 * To minimize the number of requests for quotes we use a Multicall contract. Generally
 * the number of quotes to fetch exceeds the maximum we can fit in a single multicall
 * while staying under gas limits, so we also batch these quotes across multiple multicalls.
 *
 * The biggest challenge with the quote provider is dealing with various gas limits.
 * Each provider sets a limit on the amount of gas a call can consume (on Infura this
 * is approximately 10x the block max size), so we must ensure each multicall does not
 * exceed this limit. Additionally, each quote on V3 can consume a large number of gas if
 * the pool lacks liquidity and the swap would cause all the ticks to be traversed.
 *
 * To ensure we don't exceed the node's call limit, we limit the gas used by each quote to
 * a specific value, and we limit the number of quotes in each multicall request. Users of this
 * class should set BatchParams such that multicallChunk * gasLimitPerCall is less than their node
 * providers total gas limit per call.
 *
 * @export
 * @class OnChainQuoteProvider
 */
export declare class OnChainQuoteProvider implements IOnChainQuoteProvider {
    protected chainId: ChainId;
    protected provider: BaseProvider;
    protected multicall2Provider: UniswapMulticallProvider;
    protected retryOptions: QuoteRetryOptions;
    protected batchParams: (optimisticCachedRoutes: boolean, protocol: Protocol) => BatchParams;
    protected gasErrorFailureOverride: (protocol: Protocol) => FailureOverrides;
    protected successRateFailureOverrides: (protocol: Protocol) => FailureOverrides;
    protected blockNumberConfig: (protocol: Protocol) => BlockNumberConfig;
    protected quoterAddressOverride?: ((useMixedRouteQuoter: boolean, mixedRouteContainsV4Pool: boolean, protocol: Protocol) => string | undefined) | undefined;
    protected metricsPrefix: (chainId: ChainId, useMixedRouteQuoter: boolean, mixedRouteContainsV4Pool: boolean, protocol: Protocol, optimisticCachedRoutes: boolean) => string;
    /**
     * Creates an instance of OnChainQuoteProvider.
     *
     * @param chainId The chain to get quotes for.
     * @param provider The web 3 provider.
     * @param multicall2Provider The multicall provider to use to get the quotes on-chain.
     * Only supports the Uniswap Multicall contract as it needs the gas limitting functionality.
     * @param retryOptions The retry options for each call to the multicall.
     * @param batchParams The parameters for each batched call to the multicall.
     * @param gasErrorFailureOverride The gas and chunk parameters to use when retrying a batch that failed due to out of gas.
     * @param successRateFailureOverrides The parameters for retries when we fail to get quotes.
     * @param blockNumberConfig Parameters for adjusting which block we get quotes from, and how to handle block header not found errors.
     * @param [quoterAddressOverride] Overrides the address of the quoter contract to use.
     * @param metricsPrefix metrics prefix to differentiate between different instances of the quote provider.
     */
    constructor(chainId: ChainId, provider: BaseProvider, multicall2Provider: UniswapMulticallProvider, retryOptions?: QuoteRetryOptions, batchParams?: (optimisticCachedRoutes: boolean, protocol: Protocol) => BatchParams, gasErrorFailureOverride?: (protocol: Protocol) => FailureOverrides, successRateFailureOverrides?: (protocol: Protocol) => FailureOverrides, blockNumberConfig?: (protocol: Protocol) => BlockNumberConfig, quoterAddressOverride?: ((useMixedRouteQuoter: boolean, mixedRouteContainsV4Pool: boolean, protocol: Protocol) => string | undefined) | undefined, metricsPrefix?: (chainId: ChainId, useMixedRouteQuoter: boolean, mixedRouteContainsV4Pool: boolean, protocol: Protocol, optimisticCachedRoutes: boolean) => string);
    private getQuoterAddress;
    getQuotesManyExactIn<TRoute extends SupportedRoutes>(amountIns: CurrencyAmount[], routes: TRoute[], providerConfig?: ProviderConfig): Promise<OnChainQuotes<TRoute>>;
    getQuotesManyExactOut<TRoute extends SupportedExactOutRoutes>(amountOuts: CurrencyAmount[], routes: TRoute[], providerConfig?: ProviderConfig): Promise<OnChainQuotes<TRoute>>;
    private encodeRouteToPath;
    private getContractInterface;
    private consolidateResults;
    private getQuotesManyData;
    private partitionQuotes;
    private processQuoteResults;
    private validateBlockNumbers;
    protected validateSuccessRate(allResults: Result<[BigNumber, BigNumber[], number[], BigNumber]>[], haveRetriedForSuccessRate: boolean, useMixedRouteQuoter: boolean, mixedRouteContainsV4Pool: boolean, protocol: Protocol, optimisticCachedRoutes: boolean): void | SuccessRateError;
    /**
     * Throw an error for incorrect routes / function combinations
     * @param routes Any combination of V3, V2, and Mixed routes.
     * @param functionName
     * @param useMixedRouteQuoter true if there are ANY V2Routes or MixedRoutes in the routes parameter
     */
    protected validateRoutes(routes: SupportedRoutes[], functionName: string, useMixedRouteQuoter: boolean): void;
}
export {};
