import { LabelHash, EncodedLabelHash, Label } from 'enssdk';
import { EnsRainbowClientLabelSet, EnsRainbowPublicConfig } from '@ensnode/ensnode-sdk';

/**
 * Error thrown by {@link EnsRainbowApiClient} methods when the ENSRainbow service responds
 * with a non-2xx HTTP status code.
 *
 * Carries the HTTP status code as a structured property (rather than only embedding it in the
 * error message) so callers can branch their retry/abort logic on the status — e.g. retry on
 * `503 Service Unavailable` while ENSRainbow bootstraps, but abort immediately on `404`/`500`,
 * which usually indicate a misconfigured base URL or a hard server failure.
 *
 * Network-level failures (DNS, ECONNREFUSED, fetch parse errors) are *not* wrapped in this
 * class — they propagate as their original `Error` (typically a `TypeError` from `fetch`),
 * because such failures are commonly transient during cold start and should remain retryable
 * by callers.
 */
declare class EnsRainbowHttpError extends Error {
    readonly name = "EnsRainbowHttpError";
    /**
     * The HTTP status code returned by the ENSRainbow service.
     */
    readonly status: number;
    /**
     * The HTTP status text returned by the ENSRainbow service, if any.
     */
    readonly statusText: string;
    constructor(message: string, status: number, statusText?: string);
}
declare namespace EnsRainbow {
    export type ApiClientOptions = EnsRainbowApiClientOptions;
    export interface ApiClient {
        count(): Promise<CountResponse>;
        /**
         * Get the public configuration of the ENSRainbow service
         */
        config(): Promise<ENSRainbowPublicConfig>;
        /**
         * Heal a labelHash to its original label.
         * Accepts a strict `LabelHash`, an `EncodedLabelHash` (bracket-enclosed), or any string
         * that can be normalized (missing `0x` prefix, uppercase hex chars, or 63-char hex).
         * Returns a `HealBadRequestError` if the input cannot be normalized to a valid labelHash.
         */
        heal(labelHash: LabelHash | EncodedLabelHash | string): Promise<HealResponse>;
        health(): Promise<HealthResponse>;
        /**
         * Check whether the ENSRainbow service has finished bootstrapping and is ready to serve requests.
         *
         * Throws when the service is not ready (e.g. 503 while the database is still being downloaded
         * or validated) so callers can retry.
         */
        ready(): Promise<ReadyResponse>;
        getOptions(): Readonly<EnsRainbowApiClientOptions>;
    }
    type StatusCode = (typeof StatusCode)[keyof typeof StatusCode];
    type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
    export interface HealthResponse {
        status: "ok";
    }
    /**
     * Response returned by `GET /ready` when the ENSRainbow service is ready to serve requests.
     */
    export interface ReadyResponse {
        status: "ok";
    }
    /**
     * Generic error shape used by endpoints that return 503 Service Unavailable while the
     * database is still bootstrapping (downloading, extracting, or validating).
     */
    export interface ServiceUnavailableError {
        status: typeof StatusCode.Error;
        error: string;
        errorCode: typeof ErrorCode.ServiceUnavailable;
    }
    export interface BaseHealResponse<Status extends StatusCode, Error extends ErrorCode> {
        status: Status;
        label?: Label | never;
        error?: string | never;
        errorCode?: Error | never;
    }
    export interface HealSuccess extends BaseHealResponse<typeof StatusCode.Success, never> {
        status: typeof StatusCode.Success;
        label: Label;
        error?: never;
        errorCode?: never;
    }
    export interface HealNotFoundError extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.NotFound> {
        status: typeof StatusCode.Error;
        label?: never;
        error: string;
        errorCode: typeof ErrorCode.NotFound;
    }
    export interface HealServerError extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {
        status: typeof StatusCode.Error;
        label?: never;
        error: string;
        errorCode: typeof ErrorCode.ServerError;
    }
    export interface HealBadRequestError extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.BadRequest> {
        status: typeof StatusCode.Error;
        label?: never;
        error: string;
        errorCode: typeof ErrorCode.BadRequest;
    }
    export interface HealServiceUnavailableError extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.ServiceUnavailable> {
        status: typeof StatusCode.Error;
        label?: never;
        error: string;
        errorCode: typeof ErrorCode.ServiceUnavailable;
    }
    export type HealResponse = HealSuccess | HealNotFoundError | HealServerError | HealBadRequestError | HealServiceUnavailableError;
    export type HealError = Exclude<HealResponse, HealSuccess>;
    /**
     * Server errors and transient bootstrap errors should not be cached.
     */
    export type CacheableHealResponse = Exclude<HealResponse, HealServerError | HealServiceUnavailableError>;
    export interface BaseCountResponse<Status extends StatusCode, Error extends ErrorCode> {
        status: Status;
        count?: number | never;
        timestamp?: string | never;
        error?: string | never;
        errorCode?: Error | never;
    }
    export interface CountSuccess extends BaseCountResponse<typeof StatusCode.Success, never> {
        status: typeof StatusCode.Success;
        /** The total count of labels that can be healed by the ENSRainbow instance. Always a
         * non-negative integer. */
        count: number;
        timestamp: string;
        error?: never;
        errorCode?: never;
    }
    export interface CountServerError extends BaseCountResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {
        status: typeof StatusCode.Error;
        count?: never;
        timestamp?: never;
        error: string;
        errorCode: typeof ErrorCode.ServerError;
    }
    export interface CountServiceUnavailableError extends BaseCountResponse<typeof StatusCode.Error, typeof ErrorCode.ServiceUnavailable> {
        status: typeof StatusCode.Error;
        count?: never;
        timestamp?: never;
        error: string;
        errorCode: typeof ErrorCode.ServiceUnavailable;
    }
    export type CountResponse = CountSuccess | CountServerError | CountServiceUnavailableError;
    /**
     * Complete public configuration object for ENSRainbow.
     *
     * Contains all public configuration information about the ENSRainbow service instance,
     * including version, label set information, and record counts.
     */
    export type ENSRainbowPublicConfig = EnsRainbowPublicConfig;
    export {  };
}
interface EnsRainbowApiClientOptions {
    /**
     * The maximum number of `HealResponse` values to cache.
     * Must be a non-negative integer.
     * Setting to 0 will disable caching.
     */
    cacheCapacity: number;
    /**
     * The URL of an ENSRainbow API endpoint.
     */
    endpointUrl: URL;
    /**
     * Optional client label set preferences that the ENSRainbow server at endpointUrl is expected to
     * support. If provided, enables deterministic heal results across time, such that only
     * labels from label sets with versions less than or equal to this value will be returned.
     * Therefore, even if the ENSRainbow server later ingests label sets with greater versions
     * than this value, the results returned across time can be deterministic. If
     * provided, heal operations with this EnsRainbowApiClient will validate the ENSRainbow
     * server manages a compatible label set. If not provided no specific labelSetId validation
     * will be performed during heal operations.
     * If `labelSetId` is provided without `labelSetVersion`, the server will use the latest
     * available version.
     * If `labelSetVersion` is defined, only labels from sets less than or equal to this value
     * will be returned.
     * When `labelSetVersion` is defined, `labelSetId` must also be defined.
     */
    clientLabelSet?: EnsRainbowClientLabelSet;
}
/**
 * ENSRainbow API client
 *
 * @example
 * ```typescript
 * // default options
 * const client = new EnsRainbowApiClient();
 * // custom options
 * const client = new EnsRainbowApiClient({
 *  endpointUrl: new URL("https://api.ensrainbow.io"),
 * });
 * ```
 */
declare class EnsRainbowApiClient implements EnsRainbow.ApiClient {
    private readonly options;
    private readonly cache;
    private readonly clientLabelSetSearchParams;
    static readonly DEFAULT_CACHE_CAPACITY = 1000;
    /**
     * Create default client options.
     *
     * @returns default options
     */
    static defaultOptions(): EnsRainbow.ApiClientOptions;
    constructor(options?: Partial<EnsRainbow.ApiClientOptions>);
    /**
     * Attempt to [heal](https://ensnode.io/ensrainbow/concepts/glossary#heal) a labelHash to its original label.
     *
     * Note on returned labels: ENSRainbow returns labels exactly as they are
     * represented in source rainbow table data. This means:
     *
     * - Labels may or may not be ENS-normalized
     * - Labels can contain any valid string, including dots, null bytes, or be empty
     * - Clients should handle all possible string values appropriately
     *
     * @param labelHash - A labelHash to heal, either as a strict `LabelHash`, an `EncodedLabelHash`
     * (bracket-enclosed), or any string that can be normalized (missing `0x` prefix, uppercase hex
     * chars, or 63-char hex are all accepted and normalized automatically).
     * @returns a `HealResponse` indicating the result of the request and the healed label if successful.
     * Returns a `HealBadRequestError` if the input cannot be normalized to a valid labelHash.
     * @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
     * CORS violations, or Invalid URLs
     * @example
     * ```typescript
     * const response = await client.heal(
     *   "0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc"
     * );
     *
     * console.log(response);
     *
     * // Output:
     * // {
     * //   status: "success",
     * //   label: "vitalik"
     * // }
     *
     * const notFoundResponse = await client.heal(
     *   "0xf64dc17ae2e2b9b16dbcb8cb05f35a2e6080a5ff1dc53ac0bc48f0e79111f264"
     * );
     *
     * console.log(notFoundResponse);
     *
     * // Output:
     * // {
     * //   status: "error",
     * //   error: "Label not found",
     * //   errorCode: 404
     * // }
     * ```
     */
    heal(labelHash: LabelHash | EncodedLabelHash | string): Promise<EnsRainbow.HealResponse>;
    /**
     * Get Count of Healable Labels
     *
     * @returns a `CountResponse` indicating the result and the timestamp of the request and the
     * number of healable labels if successful
     * @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
     * CORS violations, or Invalid URLs
     * @example
     *
     * const response = await client.count();
     *
     * console.log(response);
     *
     * // {
     * //   "status": "success",
     * //   "count": 133856894,
     * //   "timestamp": "2024-01-30T11:18:56Z"
     * // }
     *
     */
    count(): Promise<EnsRainbow.CountResponse>;
    /**
     *
     * Simple verification that the service is running, either in your local setup or for the
     * provided hosted instance.
     * @returns a status of ENS Rainbow service
     * @example
     *
     * const response = await client.health();
     *
     * console.log(response);
     *
     * // {
     * //   "status": "ok",
     * // }
     */
    health(): Promise<EnsRainbow.HealthResponse>;
    /**
     * Check whether the ENSRainbow service is ready (database is downloaded, validated, and open).
     *
     * Unlike {@link EnsRainbowApiClient.health}, which is a pure liveness probe that succeeds as soon
     * as the HTTP server is accepting requests, `ready()` only resolves once the service has finished
     * bootstrapping its database. Clients that require a usable database (e.g. ENSIndexer) should
     * poll this method instead of `health()` during startup.
     *
     * @throws {EnsRainbowHttpError} if the service responds with a non-2xx status. The thrown
     * error carries the HTTP `status` so callers can distinguish the retryable bootstrap case
     * (`503 Service Unavailable`) from likely-non-retryable misconfiguration / server failures
     * (e.g. `404`, `500`) and abort retries early in the latter cases.
     * @throws Network/fetch errors (DNS, ECONNREFUSED, etc.) propagate as their original error
     * type and should generally remain retryable, since they are common during cold start before
     * the ENSRainbow HTTP server has bound its port.
     */
    ready(): Promise<EnsRainbow.ReadyResponse>;
    /**
     * Get the public configuration of the ENSRainbow service.
     *
     * @throws {EnsRainbowHttpError} if the service responds with a non-2xx status.
     */
    config(): Promise<EnsRainbow.ENSRainbowPublicConfig>;
    /**
     * Get a copy of the current client options.
     *
     * @returns a copy of the current client options.
     */
    getOptions(): Readonly<EnsRainbowApiClientOptions>;
}
/**
 * Determine if a heal response is an error.
 *
 * @param response the heal response to check
 * @returns true if the response is an error, false otherwise
 */
declare const isHealError: (response: EnsRainbow.HealResponse) => response is EnsRainbow.HealError;
/**
 * Determine if a heal response is cacheable.
 *
 * Server errors at not cachable and should be retried.
 *
 * @param response the heal response to check
 * @returns true if the response is cacheable, false otherwise
 */
declare const isCacheableHealResponse: (response: EnsRainbow.HealResponse) => response is EnsRainbow.CacheableHealResponse;

export { EnsRainbow, EnsRainbowApiClient, type EnsRainbowApiClientOptions, EnsRainbowHttpError, isCacheableHealResponse, isHealError };
