import { TypeTagStruct, TypeArgument, EntryFunctionArgumentTypes, SimpleEntryFunctionArgumentTypes, InputViewFunctionData } from '@aptos-labs/ts-sdk';

declare enum ChainId {
    MOVEMENT_SUZUKA = 27,
    MOVEMENT_IMOLA = 30732,
    MOVEMENT_BAKU = 100,
    APTOS_MAINNET = 1,
    APTOS_TESTNET = 2,
    APTOS_DEVNET = 146,
    SUI_MAINNET = 1000,
    SUI_TESTNET = 1001,
    SUI_DEVNET = 1002
}
declare const SUPPORTED_CHAINS: readonly [ChainId.APTOS_DEVNET, ChainId.APTOS_TESTNET];
type SupportedChainsType = (typeof SUPPORTED_CHAINS)[number];
declare enum NativeCurrencyName {
    MOVE = "MOVE",
    APT = "APT",
    SUI = "SUI"
}

declare class Fraction {
    readonly numerator: bigint;
    readonly denominator: bigint;
    constructor(numerator: BigintIsh, denominator?: BigintIsh);
    private static tryParseFraction;
    get quotient(): bigint;
    get remainder(): Fraction;
    invert(): Fraction;
    add(other: Fraction | BigintIsh): Fraction;
    subtract(other: Fraction | BigintIsh): Fraction;
    lessThan(other: Fraction | BigintIsh): boolean;
    equalTo(other: Fraction | BigintIsh): boolean;
    greaterThan(other: Fraction | BigintIsh): boolean;
    multiply(other: Fraction | BigintIsh): Fraction;
    divide(other: Fraction | BigintIsh): Fraction;
    toSignificant(significantDigits: number, format?: object, rounding?: Rounding): string;
    toFixed(decimalPlaces: number, format?: object, rounding?: Rounding): string;
    /**
     * Helper method for converting any super class back to a fraction
     */
    get asFraction(): Fraction;
}

/**
 * Converts a fraction to a percent
 * @param fraction the fraction to convert
 */
declare function toPercent(fraction: Fraction): Percent;
declare class Percent extends Fraction {
    /**
     * This boolean prevents a fraction from being interpreted as a Percent
     */
    readonly isPercent: true;
    static toPercent: typeof toPercent;
    add(other: Fraction | BigintIsh): Percent;
    subtract(other: Fraction | BigintIsh): Percent;
    multiply(other: Fraction | BigintIsh): Percent;
    divide(other: Fraction | BigintIsh): Percent;
    toSignificant(significantDigits?: number, format?: object, rounding?: Rounding): string;
    toFixed(decimalPlaces?: number, format?: object, rounding?: Rounding): string;
}

interface SerializedToken {
    chainId: number;
    address: string;
    decimals: number;
    symbol: string;
    name?: string;
    projectLink?: string;
}
declare class Token extends BaseCurrency {
    readonly isNative: false;
    readonly isToken: true;
    readonly isFungibleAsset: boolean;
    readonly address: string;
    readonly projectLink?: string;
    constructor(chainId: number, address: string, decimals: number, symbol: string, isFungibleAsset: boolean, name?: string, projectLink?: string);
    equals(other: Currency): boolean;
    sortsBefore(other: Token): boolean;
    get wrapped(): Token;
    get serialize(): SerializedToken;
}

declare abstract class BaseCurrency {
    abstract readonly isNative: boolean;
    abstract readonly isToken: boolean;
    abstract readonly isFungibleAsset: boolean;
    readonly chainId: number;
    readonly decimals: number;
    readonly symbol: string;
    readonly name?: string;
    protected constructor(chainId: number, decimals: number, symbol: string, name?: string);
    abstract equals(other: BaseCurrency): boolean;
    abstract get wrapped(): Token;
}

declare abstract class NativeCurrency extends BaseCurrency {
    readonly isNative: true;
    readonly isToken: false;
    readonly isFungibleAsset: false;
}

type Currency = NativeCurrency | Token;

declare class CurrencyAmount<T extends Currency> extends Fraction {
    readonly currency: T;
    readonly decimalScale: bigint;
    static fromRawAmount<T extends Currency>(currency: T, rawAmount: BigintIsh): CurrencyAmount<T>;
    static fromFractionalAmount<T extends Currency>(currency: T, numerator: BigintIsh, denominator: BigintIsh): CurrencyAmount<T>;
    protected constructor(currency: T, numerator: BigintIsh, denominator?: BigintIsh);
    add(other: CurrencyAmount<T>): CurrencyAmount<T>;
    subtract(other: CurrencyAmount<T>): CurrencyAmount<T>;
    multiply(other: Fraction | BigintIsh): CurrencyAmount<T>;
    divide(other: Fraction | BigintIsh): CurrencyAmount<T>;
    toSignificant(significantDigits?: number, format?: object, rounding?: Rounding): string;
    toFixed(decimalPlaces?: number, format?: object, rounding?: Rounding): string;
    toExact(format?: object): string;
    get wrapped(): CurrencyAmount<Token>;
}

declare class Price<TBase extends Currency, TQuote extends Currency> extends Fraction {
    readonly baseCurrency: TBase;
    readonly quoteCurrency: TQuote;
    readonly scalar: Fraction;
    /**
     * Construct a price, either with the base and quote currency amount, or the
     * @param args
     */
    constructor(...args: [TBase, TQuote, BigintIsh, BigintIsh] | [
        {
            baseAmount: CurrencyAmount<TBase>;
            quoteAmount: CurrencyAmount<TQuote>;
        }
    ]);
    /**
     * Flip the price, switching the base and quote currency
     */
    invert(): Price<TQuote, TBase>;
    /**
     * Multiply the price by another price, returning a new price. The other price must have the same base currency as this price's quote currency
     * @param other the other price
     */
    multiply<TOtherQuote extends Currency>(other: Price<TQuote, TOtherQuote>): Price<TBase, TOtherQuote>;
    /**
     * Return the amount of quote currency corresponding to a given amount of the base currency
     * @param currencyAmount the amount of base currency to quote against the price
     */
    quote(currencyAmount: CurrencyAmount<TBase>): CurrencyAmount<TQuote>;
    /**
     * Get the value scaled by decimals for formatting
     * @private
     */
    private get adjustedForDecimals();
    toSignificant(significantDigits?: number, format?: object, rounding?: Rounding): string;
    toFixed(decimalPlaces?: number, format?: object, rounding?: Rounding): string;
}

type BigintIsh = bigint | string | number;
declare enum TradeType {
    EXACT_INPUT = 0,
    EXACT_OUTPUT = 1
}
declare enum Rounding {
    ROUND_DOWN = 0,
    ROUND_HALF_UP = 1,
    ROUND_UP = 2
}
declare const MINIMUM_LIQUIDITY = 1000n;
declare const ZERO = 0n;
declare const ONE = 1n;
declare const TWO = 2n;
declare const THREE = 3n;
declare const FIVE = 5n;
declare const TEN = 10n;
declare const _100 = 100n;
declare const _997 = 997n;
declare const _1000 = 1000n;
declare const BASIS_POINTS = 10000n;
declare const MaxUint256: bigint;
declare const ZERO_PERCENT: Percent;
declare const ONE_HUNDRED_PERCENT: Percent;

declare const V2_FACTORY_ADDRESS = "0xbe9c218a7a8fa9a176f55362111b1a41863acfc6d740d19441d2216c06bafd9d::factory";
declare const V2_ROUTER_ADDRESS = "0xbe9c218a7a8fa9a176f55362111b1a41863acfc6d740d19441d2216c06bafd9d::router";
declare const V2_PAIR_ADDRESS = "0xbe9c218a7a8fa9a176f55362111b1a41863acfc6d740d19441d2216c06bafd9d::pair";
declare const V2_LIBRARY_ADDRESS = "0xbe9c218a7a8fa9a176f55362111b1a41863acfc6d740d19441d2216c06bafd9d::library";

declare class FungibleAsset extends Token {
    constructor(chainId: number, address: string, decimals: number, symbol: string, name?: string, projectLink?: string);
    sortsBefore(other: Asset): boolean;
    equals(other: Asset): boolean;
}

declare const MOVE_COIN: "0x1::aptos_coin::AptosCoin";
declare class MoveCoin extends NativeCurrency {
    address: typeof MOVE_COIN;
    structTag: TypeTagStruct;
    projectLink: string;
    protected constructor(chainId: number);
    static _moveCache: {
        [chainId: number]: MoveCoin;
    };
    static onChain(chainId: number): MoveCoin;
    equals(other: Asset): boolean;
    get wrapped(): Coin;
    sortsBefore(other: Asset): boolean;
    get serialize(): SerializedToken;
}

type Asset = MoveCoin | Coin | FungibleAsset;

declare class Coin extends Token {
    constructor(chainId: number, address: string, decimals: number, symbol: string, name?: string, projectLink?: string);
    sortsBefore(other: Asset): boolean;
    equals(other: Asset): boolean;
}

declare const computePairAddress: ({ tokenA, tokenB, }: {
    tokenA: Asset;
    tokenB: Asset;
}) => Promise<string>;
declare class Pair {
    readonly liquidityToken: Asset;
    private readonly tokenAmounts;
    private static addressCache;
    private static addressComputationPromises;
    private static getCacheKey;
    static getAddress(tokenA: Asset, tokenB: Asset): string;
    private static precomputeAddress;
    private constructor();
    static create(currencyAmountA: CurrencyAmount<Asset>, tokenAmountB: CurrencyAmount<Asset>): Promise<Pair>;
    /**
     * Returns true if the token is either token0 or token1
     * @param token to check
     */
    involvesToken(token: Asset): boolean;
    /**
     * Returns the current mid price of the pair in terms of token0, i.e. the ratio of reserve1 to reserve0
     */
    get token0Price(): Price<Asset, Asset>;
    /**
     * Returns the current mid price of the pair in terms of token1, i.e. the ratio of reserve0 to reserve1
     */
    get token1Price(): Price<Asset, Asset>;
    /**
     * Return the price of the given token in terms of the other token in the pair.
     * @param token token to return price of
     */
    priceOf(token: Asset): Price<Asset, Asset>;
    /**
     * Returns the chain ID of the tokens in the pair.
     */
    get chainId(): number;
    get token0(): Asset;
    get token1(): Asset;
    get reserve0(): CurrencyAmount<Asset>;
    get reserve1(): CurrencyAmount<Asset>;
    reserveOf(token: Asset): CurrencyAmount<Asset>;
    getOutputAmount(inputAmount: CurrencyAmount<Asset>): [CurrencyAmount<Asset>, Pair];
    getInputAmount(outputAmount: CurrencyAmount<Asset>): [CurrencyAmount<Asset>, Pair];
    getLiquidityMinted(totalSupply: CurrencyAmount<Asset>, tokenAmountA: CurrencyAmount<Asset>, tokenAmountB: CurrencyAmount<Asset>): CurrencyAmount<Asset>;
    getLiquidityValue(token: Asset, totalSupply: CurrencyAmount<Asset>, liquidity: CurrencyAmount<Asset>, feeOn?: boolean, kLast?: BigintIsh): CurrencyAmount<Asset>;
}

declare class Route<TInput extends Asset, TOutput extends Asset> {
    readonly pairs: Pair[];
    readonly path: Asset[];
    readonly input: TInput;
    readonly output: TOutput;
    constructor(pairs: Pair[], input: TInput, output: TOutput);
    private _midPrice;
    get midPrice(): Price<TInput, TOutput>;
    get chainId(): number;
}

interface InputOutput<TInput extends Asset, TOutput extends Asset> {
    readonly inputAmount: CurrencyAmount<TInput>;
    readonly outputAmount: CurrencyAmount<TOutput>;
}
declare function inputOutputComparator<TInput extends Asset, TOutput extends Asset>(a: InputOutput<TInput, TOutput>, b: InputOutput<TInput, TOutput>): number;
declare function tradeComparator<TInput extends Asset, TOutput extends Asset, TTradeType extends TradeType>(a: Trade<TInput, TOutput, TTradeType>, b: Trade<TInput, TOutput, TTradeType>): number;
interface BestTradeOptions {
    maxNumResults?: number;
    maxHops?: number;
}
/**
 * Represents a trade executed against a list of pairs.
 * Does not account for slippage, i.e. trades that front run this trade and move the price.
 */
declare class Trade<TInput extends Asset, TOutput extends Asset, TTradeType extends TradeType> {
    /**
     * The route of the trade, i.e. which pairs the trade goes through and the input/output currencies.
     */
    readonly route: Route<TInput, TOutput>;
    /**
     * The type of the trade, either exact in or exact out.
     */
    readonly tradeType: TTradeType;
    /**
     * The input amount for the trade assuming no slippage.
     */
    readonly inputAmount: CurrencyAmount<TInput>;
    /**
     * The output amount for the trade assuming no slippage.
     */
    readonly outputAmount: CurrencyAmount<TOutput>;
    /**
     * The price expressed in terms of output amount/input amount.
     */
    readonly executionPrice: Price<TInput, TOutput>;
    /**
     * The percent difference between the mid price before the trade and the trade execution price.
     */
    readonly priceImpact: Percent;
    /**
     * Constructs an exact in trade with the given amount in and route
     * @param route route of the exact in trade
     * @param amountIn the amount being passed in
     */
    static exactIn<TInput extends Asset, TOutput extends Asset>(route: Route<TInput, TOutput>, amountIn: CurrencyAmount<TInput>): Trade<TInput, TOutput, TradeType.EXACT_INPUT>;
    /**
     * Constructs an exact out trade with the given amount out and route
     * @param route route of the exact out trade
     * @param amountOut the amount returned by the trade
     */
    static exactOut<TInput extends Asset, TOutput extends Asset>(route: Route<TInput, TOutput>, amountOut: CurrencyAmount<TOutput>): Trade<TInput, TOutput, TradeType.EXACT_OUTPUT>;
    constructor(route: Route<TInput, TOutput>, amount: TTradeType extends TradeType.EXACT_INPUT ? CurrencyAmount<TInput> : CurrencyAmount<TOutput>, tradeType: TTradeType);
    /**
     * Get the minimum amount that must be received from this trade for the given slippage tolerance
     * @param slippageTolerance tolerance of unfavorable slippage from the execution price of this trade
     */
    minimumAmountOut(slippageTolerance: Percent): CurrencyAmount<TOutput>;
    /**
     * Get the maximum amount in that can be spent via this trade for the given slippage tolerance
     * @param slippageTolerance tolerance of unfavorable slippage from the execution price of this trade
     */
    maximumAmountIn(slippageTolerance: Percent): CurrencyAmount<TInput>;
    /**
     * Given a list of pairs, and a fixed amount in, returns the top `maxNumResults` trades that go from an input token
     * amount to an output token, making at most `maxHops` hops.
     * Note this does not consider aggregation, as routes are linear. It's possible a better route exists by splitting
     * the amount in among multiple routes.
     * @param pairs the pairs to consider in finding the best trade
     * @param nextAmountIn exact amount of input currency to spend
     * @param currencyOut the desired currency out
     * @param maxNumResults maximum number of results to return
     * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pair
     * @param currentPairs used in recursion; the current list of pairs
     * @param currencyAmountIn used in recursion; the original value of the currencyAmountIn parameter
     * @param bestTrades used in recursion; the current list of best trades
     */
    static bestTradeExactIn<TInput extends Asset, TOutput extends Asset>(pairs: Pair[], currencyAmountIn: CurrencyAmount<TInput>, currencyOut: TOutput, { maxNumResults, maxHops }?: BestTradeOptions, currentPairs?: Pair[], nextAmountIn?: CurrencyAmount<Asset>, bestTrades?: Trade<TInput, TOutput, TradeType.EXACT_INPUT>[]): Trade<TInput, TOutput, TradeType.EXACT_INPUT>[];
    /**
     * Return the execution price after accounting for slippage tolerance
     * @param slippageTolerance the allowed tolerated slippage
     */
    worstExecutionPrice(slippageTolerance: Percent): Price<TInput, TOutput>;
    /**
     * similar to the above method but instead targets a fixed output amount
     * given a list of pairs, and a fixed amount out, returns the top `maxNumResults` trades that go from an input token
     * to an output token amount, making at most `maxHops` hops
     * note this does not consider aggregation, as routes are linear. it's possible a better route exists by splitting
     * the amount in among multiple routes.
     * @param pairs the pairs to consider in finding the best trade
     * @param currencyIn the currency to spend
     * @param nextAmountOut the exact amount of currency out
     * @param maxNumResults maximum number of results to return
     * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pair
     * @param currentPairs used in recursion; the current list of pairs
     * @param currencyAmountOut used in recursion; the original value of the currencyAmountOut parameter
     * @param bestTrades used in recursion; the current list of best trades
     */
    static bestTradeExactOut<TInput extends Asset, TOutput extends Asset>(pairs: Pair[], currencyIn: TInput, currencyAmountOut: CurrencyAmount<TOutput>, { maxNumResults, maxHops }?: BestTradeOptions, currentPairs?: Pair[], nextAmountOut?: CurrencyAmount<Asset>, bestTrades?: Trade<TInput, TOutput, TradeType.EXACT_OUTPUT>[]): Trade<TInput, TOutput, TradeType.EXACT_OUTPUT>[];
}

/**
 * Options for producing the arguments to send call to the router.
 */
interface TradeOptions {
    /**
     * How much the execution price is allowed to move unfavorably from the trade execution price.
     */
    allowedSlippage: Percent;
    /**
     * How long the swap is valid until it expires, in seconds.
     * This will be used to produce a `deadline` parameter which is computed from when the swap call parameters
     * are generated.
     */
    ttl: number;
    /**
     * The account that should receive the output of the swap.
     */
    recipient: string;
    /**
     * Whether any of the tokens in the path are fee on transfer tokens, which should be handled with special methods
     */
    feeOnTransfer?: boolean;
}
interface TradeOptionsDeadline extends Omit<TradeOptions, 'ttl'> {
    /**
     * When the transaction expires.
     * This is an alternate to specifying the ttl, for when you do not want to use local time.
     */
    deadline: number;
}
/**
 * The parameters to use in the call to the Router module to execute a trade.
 */
interface SwapParameters {
    methodName: string;
    typeArgs?: Array<TypeArgument>;
    args?: Array<EntryFunctionArgumentTypes | SimpleEntryFunctionArgumentTypes>;
}
/**
 * Represents the Razor DEX Router module, and has static methods for helping execute trades.
 */
declare abstract class Router {
    /**
     * Cannot be constructed.
     */
    private constructor();
    /**
     * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
     * @param trade to produce call parameters for
     * @param options options for the call parameters
     */
    static swapCallParameters(trade: Trade<Asset, Asset, TradeType>, options: TradeOptions | TradeOptionsDeadline): SwapParameters;
}

declare const get_pair: (tokenA: string, tokenB: string) => InputViewFunctionData;

/**
 * Returns the percent difference between the mid price and the execution price, i.e. price impact.
 * @param midPrice mid price before the trade
 * @param inputAmount the input amount of the trade
 * @param outputAmount the output amount of the trade
 */
declare function computePriceImpact<TBase extends Currency, TQuote extends Currency>(midPrice: Price<TBase, TQuote>, inputAmount: CurrencyAmount<TBase>, outputAmount: CurrencyAmount<TQuote>): Percent;

declare function sortedInsert<T>(items: T[], add: T, maxSize: number, comparator: (a: T, b: T) => number): T | null;

/**
 * Computes floor(sqrt(value))
 * @param value the value for which to compute the square root, rounded down
 */
declare function sqrt(y: bigint): bigint;

declare function getTokenComparator(balances: {
    [tokenAddress: string]: CurrencyAmount<Token> | undefined;
}): (tokenA: Token, tokenB: Token) => number;
declare function sortCurrencies<T extends Currency>(currencies: T[]): T[];

export { type Asset, BASIS_POINTS, BaseCurrency, type BestTradeOptions, type BigintIsh, ChainId, Coin, type Currency, CurrencyAmount, FIVE, Fraction, FungibleAsset, MINIMUM_LIQUIDITY, MaxUint256, MoveCoin, NativeCurrency, NativeCurrencyName, ONE, ONE_HUNDRED_PERCENT, Pair, Percent, Price, Rounding, Route, Router, SUPPORTED_CHAINS, type SerializedToken, type SupportedChainsType, type SwapParameters, TEN, THREE, TWO, Token, Trade, type TradeOptions, type TradeOptionsDeadline, TradeType, V2_FACTORY_ADDRESS, V2_LIBRARY_ADDRESS, V2_PAIR_ADDRESS, V2_ROUTER_ADDRESS, ZERO, ZERO_PERCENT, _100, _1000, _997, computePairAddress, computePriceImpact, getTokenComparator, get_pair, inputOutputComparator, sortCurrencies, sortedInsert, sqrt, tradeComparator };
