import { Wallet, ethers } from 'ethers';
import { Hex } from '@layerzerolabs/lz-utilities';
import { Logger } from '@layerzerolabs/io-devtools';
import dotenv from 'dotenv';

declare function setRequestEvmContract(wallet: Wallet, isTestnet: boolean, evmSpotTokenAddress: string, evmExtraWeiDecimals: number, coreSpotTokenId: number, logLevel: string): Promise<any>;
declare function setFinalizeEvmContract(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, nonce: number, logLevel: string): Promise<any>;

declare function useBigBlock(wallet: Wallet, isTestnet: boolean, logLevel: string): Promise<any>;
declare function useSmallBlock(wallet: Wallet, isTestnet: boolean, logLevel: string): Promise<any>;

interface BaseInfoRequest {
    type: string;
    [key: string]: unknown;
}
/** Base structure for exchange requests. */
interface BaseExchangeRequest {
    /** Action to perform. */
    action: {
        /** Type of action. */
        type: string;
        /** Additional action parameters. */
        [key: string]: unknown;
    };
    /** Unique request identifier (recommended current timestamp in ms). */
    nonce: number;
    /** Cryptographic signature. */
    signature: {
        r: Hex;
        s: Hex;
        v: number;
    };
}
/** Base structure for exchange responses. */
interface BaseExchangeResponse {
    /** Response status */
    status: 'ok' | 'err';
    /** Error message or success data */
    response: string | {
        /** Type of response. */
        type: string;
        /** Specific data for the operation. */
        data?: unknown;
    };
}
interface Signature {
    r: string;
    s: string;
    v: number;
}
type ValueType = number | bigint | string | boolean | null | Uint8Array | readonly ValueType[] | ValueMap | BaseInfoRequest;
interface ValueMap {
    [key: string]: ValueType;
}

declare const HYPERLIQUID_URLS: {
    MAINNET: string;
    TESTNET: string;
};
declare const RPC_URLS: {
    MAINNET: string;
    TESTNET: string;
};
declare const CHAIN_IDS: {
    MAINNET: number;
    TESTNET: number;
};
declare const ENDPOINTS: {
    INFO: string;
    EXCHANGE: string;
};
declare const MAX_HYPERCORE_SUPPLY: number;
/**
 * These are the token ids for USDC on hypercore mainnet and testnet
 * It can be reproduced by grabbing the entire spotMeta and finding USDC because Hyperliquid does not have an API to target query an asset (April 8, 2025)
 *  -   curl -X POST "https://api.hyperliquid.xyz/info" -H "Content-Type: application/json" -d '{"type": "spotMeta"}' > spotOut.json
 *  -   Goto tokens and the first entry should be USDC with an index of 0
 */
declare const USDC_TOKEN_ID: {
    MAINNET: number;
    TESTNET: number;
};
declare function toAssetBridgeAddress(tokenIndex: number): string;

interface CoreSpotMetaData {
    name: string;
    szDecimals: number;
    weiDecimals: number;
    index: number;
    tokenId: string;
    isCanonical: boolean;
    evmContract: null | {
        address: string;
        evm_extra_wei_decimals: number;
    };
    fullName: string | null;
    deployerTradingFeeShare: string;
}
interface TxData {
    from: string;
    txHash: string;
    nonce: number;
    weiDiff: number;
    assetBridgeAddress: string;
    connected: boolean;
}
interface UserGenesis$1 {
    userAndWei: Array<{
        address: string;
        wei: string;
    }>;
    existingTokenAndWei: Array<{
        token: number;
        wei: string;
    }>;
    blacklistUsers: string[];
}
interface CoreSpotDeployment {
    coreSpot: CoreSpotMetaData;
    txData: TxData;
    userGenesis: UserGenesis$1;
}
interface SpotMeta {
    tokens: CoreSpotMetaData[];
}
type SpotInfoBalance = [address: string, balance: string];
interface SpotInfo {
    name: string;
    maxSupply: string;
    totalSupply: string;
    circulatingSupply: string;
    szDecimals: number;
    weiDecimals: number;
    midPx: string;
    markPx: string;
    prevDayPx: string;
    genesis: {
        userBalances: SpotInfoBalance[];
        existingTokenBalances: SpotInfoBalance[];
    };
    deployer: string;
    deployGas: string;
    deployTime: string;
    seededUsdc: string;
    nonCirculatingUserBalances: SpotInfoBalance[];
    futureEmissions: string;
}
interface DeployState {
    token: number;
    spec: {
        name: string;
        szDecimals: number;
        weiDecimals: number;
    };
    fullName: string | null;
    spots: number[];
    maxSupply: number;
    hyperliquidityGenesisBalance: string;
    totalGenesisBalanceWei: string;
    userGenesisBalances: [string, string][];
    existingTokenGenesisBalances: [number, string][];
}
interface GasAuction {
    startTimeSeconds: number;
    durationSeconds: number;
    startGas: string;
    currentGas: string | null;
    endGas: string;
}
interface SpotDeployStates {
    states: DeployState[];
    gasAuction: GasAuction;
}

/**
 * This is an optional action that can be performed at any time after
 * RegisterToken2. While the fee share defaults to 100%, this action
 * can be resent multiple times as long as the fee share is not increasing.
 * @param token - The token
 * @param share - The deployer trading fee share. Range: ["0%", "100%"]. Examples: "0.012%", "99.4%"
 */
interface SetDeployerTradingFeeShare {
    token: number;
    share: string;
}
/**
 * UserGenesis can be called multiple times
 * @param token - The token involved in the genesis.
 * @param userAndWei - A list of tuples of user address and genesis amount (wei).
 * @param existingTokenAndWei - A list of tuples of existing token and total genesis amount for holders of that token (wei).
 * @param blacklistUsers - A list of tuples of users and blacklist status (True if blacklist, False to remove existing blacklisted user).
 */
interface UserGenesis {
    token: number;
    userAndWei: Array<[string, string]>;
    existingTokenAndWei: Array<[number, string]>;
    blacklistUsers?: Array<[string, boolean]>;
}
/**
 * Genesis denotes the initial creation of a token with a maximum supply.
 * @param maxSupply - Checksum ensureing all calls to UserGenesis succeeded
 * @param noHyperliquidity - Set hyperliquidity balance to 0.
 */
interface Genesis {
    token: number;
    maxSupply: string;
    noHyperliquidity: boolean;
}
/**
 * @param tokens - [base token index,  quote token index]
 * @dev The base token index is the token index of the token that will be used as the base for the spot.
 * @dev The quote token index is the token index of the token that will be used as the quote for the spot - this is the token that will be used to pay the trading fee like USDC.
 */
interface RegisterSpot {
    tokens: [number, number];
}
/**
 * @param spot - The spot index (different from base token index)
 * @param startPx - The starting price.
 * @param orderSz - The size of each order (float, not wei)
 * @param nOrders - The number of orders. If "noHyperliquidity" was set to True, then this must be 0.
 * @param nSeededLevels - The number of levels the deployer wishes to seed with usdc instead of tokens.
 */
interface RegisterHyperliquidity {
    spot: number;
    startPx: string;
    orderSz: string;
    nOrders: number;
    nSeededLevels?: number;
}

interface EvmUserModifyRequest extends BaseExchangeRequest {
    action: {
        type: 'evmUserModify';
        usingBigBlocks: boolean;
    };
}
interface EvmSpotDeploy extends BaseExchangeRequest {
    action: {
        type: 'spotDeploy';
        requestEvmContract: {
            token: number;
            address: string;
            evmExtraWeiDecimals: number;
        };
    };
}
interface FinalizeEvmContract extends BaseExchangeRequest {
    action: {
        type: 'finalizeEvmContract';
        token: number;
        input: {
            create: {
                nonce: number;
            };
        };
    };
}
interface SpotDeployAction extends BaseExchangeRequest {
    action: {
        type: 'spotDeploy';
        setDeployerTradingFeeShare: SetDeployerTradingFeeShare;
    } | {
        type: 'spotDeploy';
        userGenesis: UserGenesis;
    } | {
        type: 'spotDeploy';
        genesis: Genesis;
    } | {
        type: 'spotDeploy';
        registerSpot: RegisterSpot;
    } | {
        type: 'spotDeploy';
        registerHyperliquidity: RegisterHyperliquidity;
    };
}

declare function getSpotMeta(wallet: Wallet | null, isTestnet: boolean, logLevel: string, tokenIndex: string): Promise<CoreSpotMetaData>;
declare function getHipTokenInfo(wallet: Wallet | null, isTestnet: boolean, logLevel: string, tokenAddress: string): Promise<SpotInfo>;
declare function getSpotDeployState(deployerAddres: string, isTestnet: boolean, logLevel: string): Promise<SpotDeployStates>;

declare function setTradingFeeShare(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, share: string, logLevel: string): Promise<any>;
declare function setUserGenesis(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, action: string, logLevel: string): Promise<{
    responseForUserGenesis: {};
    responseForBlacklistUsers: {};
}>;
declare function setGenesis(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, logLevel: string): Promise<any>;
declare function setNoHyperliquidity(wallet: Wallet, isTestnet: boolean, tokenIndex: number, logLevel: string): Promise<any>;
declare function registerSpot(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, logLevel: string): Promise<any>;

/**
 * @dev Creates a keccak hash based on the packed action, nonce, and vault address.
 * @dev I just ripped off - https://github.com/hyperliquid-dex/hyperliquid-python-sdk/blob/master/hyperliquid/utils/signing.py#L137-L145
 *
 * @param action - The action data to be packed with MessagePack.
 * @param vaultAddress - The vault address as a hex string or null.
 * @param nonce - A numeric nonce.
 *
 * @returns The keccak hash as a hex string.
 */
declare function computeL1ActionHash(action: ValueType, nonce: number, vaultAddress: string | null): string;
/**
 * Sign an L1 action.
 *
 * @dev Signature generation depends on the order of the action keys.
 * @dev I just ripped off - https://github.com/hyperliquid-dex/hyperliquid-python-sdk/blob/master/hyperliquid/utils/signing.py#L152-L177
 *
 * @param args.wallet - Wallet to sign the action.
 * @param args.action - The action to be signed.
 * @param args.nonce - Unique request identifier (recommended current timestamp in ms).
 * @param args.isTestnet - Indicates if the action is for the testnet. Default is `false`.
 * @param args.vaultAddress - Optional vault address used in the action.
 *
 * @returns The signature components r, s, and v.
 */
declare function signL1Action(args: {
    wallet: Wallet;
    action: ValueType;
    nonce: number;
    isTestnet?: boolean;
    vaultAddress: Hex | null;
}): Promise<{
    r: Hex;
    s: Hex;
    v: number;
}>;
declare function getTimestampMs(): number;
declare function getHyperliquidWallet(privateKey?: string): Promise<ethers.Wallet>;

declare class HyperliquidClient {
    private readonly client;
    private readonly baseUrl;
    private readonly isTestnet;
    private readonly logger;
    constructor(isTestnet: boolean, logLevel: string);
    submitHyperliquidAction(endpoint: string, wallet: Wallet | null, action: ValueType): Promise<any>;
}

declare function getCoreSpotDeployment(index: string | number, isTestnet: boolean, logger?: Logger): CoreSpotDeployment;
declare function writeCoreSpotDeployment(index: string | number, isTestnet: boolean, coreSpotDeployment: CoreSpotDeployment, logger?: Logger): void;
declare function writeUpdatedCoreSpotDeployment(index: string | number, isTestnet: boolean, tokenFullName: string, tokenAddress: string, txData: TxData, logger?: Logger): void;
declare function writeNativeSpotConnected(index: string | number, isTestnet: boolean, connected: boolean, weiDiff: number, logger?: Logger): void;
declare function getHyperEVMOAppDeployment(oapp_config: string, network: string, logger?: Logger): Promise<{
    contractName: string;
    deployment: string;
}>;
declare function getERC20abi(): Promise<any>;

declare function loadEnv(): dotenv.DotenvParseOutput;

export { type BaseExchangeRequest, type BaseExchangeResponse, type BaseInfoRequest, CHAIN_IDS, type CoreSpotDeployment, type CoreSpotMetaData, type DeployState, ENDPOINTS, type EvmSpotDeploy, type EvmUserModifyRequest, type FinalizeEvmContract, type GasAuction, HYPERLIQUID_URLS, HyperliquidClient, MAX_HYPERCORE_SUPPLY, RPC_URLS, type Signature, type SpotDeployAction, type SpotDeployStates, type SpotInfo, type SpotInfoBalance, type SpotMeta, type TxData, USDC_TOKEN_ID, type UserGenesis$1 as UserGenesis, type ValueMap, type ValueType, computeL1ActionHash, getCoreSpotDeployment, getERC20abi, getHipTokenInfo, getHyperEVMOAppDeployment, getHyperliquidWallet, getSpotDeployState, getSpotMeta, getTimestampMs, loadEnv, registerSpot, setFinalizeEvmContract, setGenesis, setNoHyperliquidity, setRequestEvmContract, setTradingFeeShare, setUserGenesis, signL1Action, toAssetBridgeAddress, useBigBlock, useSmallBlock, writeCoreSpotDeployment, writeNativeSpotConnected, writeUpdatedCoreSpotDeployment };
