import type * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';
import type { KeetaAnchorMetadataServerConfig } from '../../lib/anchor-metadata-server.js';
import { KeetaAnchorMetadataServer } from '../../lib/anchor-metadata-server.js';
import { KeetaNet } from '../../client/index.js';
import type { ConversionInputCanonicalJSON, KeetaFXAnchorEstimate, KeetaFXAnchorQuote, KeetaFXAnchorQuoteJSON, KeetaNetAccount } from './common.ts';
import * as Signing from '../../lib/utils/signing.js';
import type { ServiceMetadata } from '../../lib/resolver.ts';
import { KeetaAnchorQueueRunner } from '../../lib/queue/index.js';
import type { KeetaAnchorQueueStorageDriver, KeetaAnchorQueueRequestID, KeetaAnchorQueueRunnerConfigurationObject } from '../../lib/queue/index.ts';
import { KeetaAnchorQueuePipelineAdvanced } from '../../lib/queue/pipeline.js';
import type { JSONSerializable } from '../../lib/utils/json.ts';
import type { DeepRequired } from '../../lib/utils/types.ts';
import type { SharedAnchorMetadataLegalExtension } from '../../lib/metadata.types.js';
export type GetConversionRateAndFeeContext = {
    /**
     * The purpose for why getConversionRateAndFee is being called
     *   estimate means it is being called to get an estimate for a swap
     *   quote means it is being called to get a firm quote for a swap that will be executed
     */
    purpose: 'quote' | 'estimate';
} | {
    /**
     * The purpose for why getConversionRateAndFee is being called
     *   exchange means it is being called right before executing a swap, when the user is requesting a floating rate swap
     */
    purpose: 'exchange';
    /**
     * The request information related to this exchange
     */
    request: KeetaFXAnchorQueueStage1Request;
};
export interface KeetaAnchorFXServerConfig extends KeetaAnchorMetadataServerConfig {
    /**
     * The data to use for the index page (optional)
     */
    homepage?: string | (() => Promise<string> | string);
    /**
     * All accounts that may be used by the server to perform swaps
     *
     * Temporary compatibility: If this is not provided, the single
     * `account` property will be used to create a set of one account.
     */
    accounts?: InstanceType<typeof KeetaNet.lib.Account.Set>;
    /**
     * Account to use to perform transactions
     *
     * @deprecated Use `signer` and `accounts` instead
     */
    account?: InstanceType<typeof KeetaNet.lib.Account> | undefined;
    /**
     * Account which can be used to sign transactions
     * for the accounts above
     *
     * This may be either a function or a KeetaNet Account instance.
     *
     * Temporary compatibility: If not provided, the `account` property
     * will be used as the signer.
     */
    signer?: InstanceType<typeof KeetaNet.lib.Account> | ((request: ConversionInputCanonicalJSON) => Promise<InstanceType<typeof KeetaNet.lib.Account>> | InstanceType<typeof KeetaNet.lib.Account>);
    /**
     * Account which performs the signing and validation of quotes,
     * This can be null but only if `quoteConfiguration.issueQuotes` is false.
     */
    quoteSigner: Signing.SignableAccount | null;
    /**
     * Indicates whether the liquidity provider requires a quote before performing an exchange
     * defaults to requiresQuote: true
     */
    quoteConfiguration?: {
        requiresQuote: true;
    } | {
        requiresQuote: false;
        /**
         * Indicates whether to call validateQuote before performing the exchange, defaults to true if validateQuote is provided
         */
        validateQuoteBeforeExchange: boolean;
        /**
         * Indicates if the server should issue quotes when requested, if not it will throw a
         */
        issueQuotes: boolean;
    };
    /**
     * Configuration for FX handling
     */
    fx: SharedAnchorMetadataLegalExtension & {
        /**
         * Supported conversions
         */
        from?: NonNullable<ServiceMetadata['services']['fx']>[string]['from'];
        /**
         * Asset identifiers in which this FX provider accepts fee
         * denomination. Advertised in service metadata so clients
         * can select a preferred cost asset.
         */
        acceptedCostAssets?: NonNullable<ServiceMetadata['services']['fx']>[string]['acceptedCostAssets'];
        /**
         * Optional callback to validate a quote before completing an exchange
         *
         * This allows the FX Server operator to reject quotes that are no longer
         * acceptable (e.g., due to price changes, expiry, or other business logic)
         *
         * @param quote The quote to validate
         * @returns true to accept the quote and proceed with the exchange, false to reject it
         */
        validateQuote?: (quote: ValidateQuoteArguments) => Promise<boolean> | boolean;
    } & ({
        performExchanges?: true;
        /**
         * Handle the conversion request of one token to another
         *
         * This is used to handle quotes and estimates
         */
        getConversionRateAndFee: (request: ConversionInputCanonicalJSON, context: GetConversionRateAndFeeContext) => Promise<KeetaFXInternalPriceQuote>;
    } | {
        performExchanges: false;
        /**
         * Get the estimate price of an exchange, this should be provided when getConversionRateAndFee is not provided
         * The server will not handle exchanges if getConversionRateAndFee is not provided, but it will still provide quotes and estimates based on this function
         */
        estimateRateAndFee: (request: ConversionInputCanonicalJSON) => Promise<KeetaFXInternalPriceEstimate>;
    });
    /**
     * Storage driver to use for stateful operation and managing queues
     *
     * You are responsible for running and maintaining the queue processor unless
     * you enable auto-run below.
     */
    storage?: {
        /**
         * The storage driver or queue runner to use to serialize
         * and batch requests
         */
        queue: KeetaAnchorQueueStorageDriver<JSONSerializable, JSONSerializable>;
        /**
         * If enabled the server will automatically run the queue processor
         */
        autoRun?: boolean;
    };
    /**
     * Methods to extend the shared queue pipeline runners used by all accounts.
     *
     * These extensions add shared success and failure handlers that receive
     * results from all account-specific runners (in the `runners` object),
     * which internally pipe into these shared handlers.
     *
     * Useful for adding jobs before or after the main FX processing.
     */
    queueRunnerExtensions?: KeetaFXAnchorQueuePipelineExtensions;
    /**
     * The network client to use for submitting blocks
     */
    client: {
        client: KeetaNet.Client;
        network: bigint;
        networkAlias: typeof KeetaNet.Client.Config.networksArray[number];
    } | KeetaNet.UserClient;
}
export type KeetaFXInternalPriceQuote = Omit<KeetaFXAnchorQuote, 'signed' | 'request'> & Pick<KeetaFXAnchorEstimate, 'convertedAmountBound'>;
export type KeetaFXInternalPriceEstimate = Omit<KeetaFXInternalPriceQuote, 'account'>;
export type ValidateQuoteArguments = KeetaFXInternalPriceQuote & Partial<Omit<KeetaFXAnchorQuote, keyof KeetaFXInternalPriceQuote>>;
export declare function toValidateQuoteInput(input: KeetaFXAnchorQuoteJSON | KeetaFXInternalPriceQuote | KeetaFXAnchorQuote): ValidateQuoteArguments;
type KeetaFXAnchorQueueStage1Request = {
    account: KeetaNetAccount;
    block: Parameters<typeof KeetaNet.UserClient['acceptSwapRequest']>[0]['block'];
    request: ConversionInputCanonicalJSON;
    expected: Extract<DeepRequired<NonNullable<Parameters<typeof KeetaNet.UserClient['acceptSwapRequest']>[0]['expected']>>, {
        receive: unknown;
    }> | null;
};
type KeetaFXAnchorQueueStage1Response = {
    /**
     * All the blocks for the given swap request
     */
    blocks: string[];
    /**
     * The hash of one of the blocks submitted
     */
    blockhash: string;
};
declare class KeetaFXAnchorQueuePipelineStage1 extends KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response> {
    protected readonly serverConfig: KeetaAnchorFXServerConfig;
    protected sequential: boolean;
    /**
     * Timeout for processing a single job -- if exceeded the job is marked as aborted
     */
    protected processTimeout: number;
    constructor(config: ConstructorParameters<typeof KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>>[0] & {
        serverConfig: KeetaAnchorFXServerConfig;
    });
    /**
     * Handles both stuck (no status update after a long period) and
     * aborted (timeout while processing an entry) states.
     *
     * We just put the job back into pending because the processor
     * will check the network state again.
     */
    protected processorStuck(entry: Parameters<NonNullable<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processorStuck']>>[0]): ReturnType<NonNullable<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processorStuck']>>;
    /**
     * Process the entry, attempting to submit the swap block(s)
     * to the network.  Verifies the block can be submitted before
     * attempting submission.  Also verifies if the block is already
     * on the network and marks the job as completed if so.
     */
    protected processor(entry: Parameters<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processor']>[0]): ReturnType<KeetaAnchorQueueRunner<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>['processor']>;
    protected encodeRequest(request: KeetaFXAnchorQueueStage1Request): JSONSerializable;
    protected encodeResponse(response: KeetaFXAnchorQueueStage1Response | null): JSONSerializable | null;
    protected decodeRequest(request: JSONSerializable): KeetaFXAnchorQueueStage1Request;
    protected decodeResponse(response: JSONSerializable | null): KeetaFXAnchorQueueStage1Response | null;
}
type RunnerOrRunnerWithOptions<Req, Res> = ({
    processor: KeetaAnchorQueueRunner<Req, Res>['processor'];
} & KeetaAnchorQueueRunnerConfigurationObject) | KeetaAnchorQueueRunner<Req, Res>['processor'];
type KeetaFXAnchorQueuePipelineExtensions = {
    success?: RunnerOrRunnerWithOptions<KeetaFXAnchorQueueStage1Response, KeetaFXAnchorQueueStage1Response>;
    failure?: RunnerOrRunnerWithOptions<KeetaFXAnchorQueueStage1Request, JSONSerializable>;
};
type KeetaFXAnchorQueuePipelineAdditionalConfig = {
    serverConfig: KeetaAnchorFXServerConfig;
    accounts: InstanceType<typeof KeetaNet.lib.Account.Set>;
    extensions?: KeetaFXAnchorQueuePipelineExtensions | undefined;
};
declare class KeetaFXAnchorQueuePipeline extends KeetaAnchorQueuePipelineAdvanced<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response> {
    #private;
    private readonly serverConfig;
    private readonly accounts;
    private runners;
    private extensions?;
    private successStageRunner;
    private failureStageRunner;
    constructor(options: ConstructorParameters<typeof KeetaAnchorQueuePipelineAdvanced<KeetaFXAnchorQueueStage1Request, KeetaFXAnchorQueueStage1Response>>[0] & KeetaFXAnchorQueuePipelineAdditionalConfig);
    protected createPipeline(): Promise<void>;
    protected getStage(stageID: typeof KeetaAnchorQueuePipelineAdvanced.StageID.first | typeof KeetaAnchorQueuePipelineAdvanced.StageID.last): KeetaFXAnchorQueuePipelineStage1;
    add(request: KeetaFXAnchorQueueStage1Request): ReturnType<KeetaFXAnchorQueuePipelineStage1['add']>;
    /**
     * Get the status of a request by ID.
     * If the request is found in any of the runners, it is returned with its current status.
     * Because typically the user will only care about the status of the first stage-
     * The request will be marked as failed or completed if it is found in the success or failure stages, instead of the status from those stages.
     * @param id The ID of the request to get the status of
     * @returns The inferred status of the request, or null if the request is not found
     */
    get(id: KeetaAnchorQueueRequestID): ReturnType<KeetaFXAnchorQueuePipelineStage1['get']>;
    run(options?: Parameters<KeetaFXAnchorQueuePipelineStage1['run']>[0]): ReturnType<KeetaFXAnchorQueuePipelineStage1['run']>;
    maintain(): Promise<void>;
    destroy(): Promise<void>;
}
type SharedHTTPServerConfigType = Pick<KeetaAnchorFXServerConfig, 'fx' | 'homepage' | keyof KeetaAnchorMetadataServerConfig>;
declare abstract class BaseKeetaNetFXAnchorHTTPServer<ConfigType extends SharedHTTPServerConfigType> extends KeetaAnchorMetadataServer<NonNullable<ServiceMetadata['services']['fx']>[string], ConfigType> implements Omit<Required<KeetaAnchorFXServerConfig>, 'storage' | 'queueRunnerExtensions' | 'accounts' | 'account' | 'signer' | 'client' | 'quoteSigner' | 'quoteConfiguration' | 'metadataSigner'> {
    readonly homepage: NonNullable<KeetaAnchorFXServerConfig['homepage']>;
    readonly fx: KeetaAnchorFXServerConfig['fx'];
    readonly canPerformExchanges: boolean;
    protected abstract quoteConfiguration: Exclude<KeetaAnchorFXServerConfig['quoteConfiguration'], undefined> | null;
    protected accounts: InstanceType<typeof KeetaNet.lib.Account.Set> | null;
    constructor(config: ConfigType);
    protected getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: 'estimate'): Promise<KeetaFXInternalPriceEstimate | KeetaFXInternalPriceQuote>;
    protected getUnsignedQuoteData(conversion: ConversionInputCanonicalJSON, purpose: 'quote'): Promise<KeetaFXInternalPriceQuote>;
    protected initRoutes(config: ConfigType): Promise<KeetaAnchorHTTPServer.Routes>;
    /**
     * Return the servers endpoints and possible currency conversions metadata
     */
    protected buildServiceMetadata(): Promise<NonNullable<ServiceMetadata['services']['fx']>[string]>;
}
export declare class KeetaNetFXAnchorEstimateHTTPServer extends BaseKeetaNetFXAnchorHTTPServer<SharedHTTPServerConfigType> {
    protected quoteConfiguration: null;
    constructor(config: SharedHTTPServerConfigType);
}
export declare class KeetaNetFXAnchorHTTPServer extends BaseKeetaNetFXAnchorHTTPServer<KeetaAnchorFXServerConfig> implements Omit<Required<KeetaAnchorFXServerConfig>, 'storage' | 'queueRunnerExtensions' | 'metadataSigner'> {
    readonly client: KeetaAnchorFXServerConfig['client'];
    readonly accounts: NonNullable<KeetaAnchorFXServerConfig['accounts']>;
    readonly account: KeetaAnchorFXServerConfig['account'];
    readonly signer: NonNullable<KeetaAnchorFXServerConfig['signer']>;
    readonly quoteSigner: KeetaAnchorFXServerConfig['quoteSigner'];
    readonly fx: KeetaAnchorFXServerConfig['fx'];
    readonly pipeline: KeetaFXAnchorQueuePipeline;
    readonly quoteConfiguration: Exclude<KeetaAnchorFXServerConfig['quoteConfiguration'], undefined>;
    protected autoRun: boolean;
    protected autoRunRunning: boolean;
    constructor(config: KeetaAnchorFXServerConfig);
    protected initRoutes(config: KeetaAnchorFXServerConfig): Promise<KeetaAnchorHTTPServer.Routes>;
    protected buildServiceMetadata(): Promise<NonNullable<ServiceMetadata['services']['fx']>[string]>;
    stop(): Promise<void>;
}
export {};
//# sourceMappingURL=server.d.ts.map