/// <reference types="node" />
import { EventEmitter } from 'events';
import { Logger } from 'ilp-logger';
import { DataAndMoneyStream } from './stream';
import * as IlpPacket from 'ilp-packet';
import { Packet, Frame, StreamCloseFrame, ErrorCode } from './packet';
import { CongestionController } from './util/congestion';
import { Plugin } from './util/plugin-interface';
import Long from 'long';
import Rational from './util/rational';
import { StoppableTimeout } from './util/stoppable-timeout';
export interface ConnectionOpts {
    connectionId?: string;
    plugin: Plugin;
    destinationAccount?: string;
    sourceAccount?: string;
    slippage?: number;
    enablePadding?: boolean;
    connectionTag?: string;
    receiptNonce?: Buffer;
    receiptSecret?: Buffer;
    maxRemoteStreams?: number;
    connectionBufferSize?: number;
    minExchangeRatePrecision?: number;
    idleTimeout?: number;
    maximumPacketAmount?: string;
    exchangeRate?: number;
    getExpiry?: (destination: string) => Date;
    shouldFulfill?: (packetAmount: Long, packetId: Buffer, connectionTag?: string) => Promise<void>;
}
export interface BuildConnectionOpts extends ConnectionOpts {
    sourceAccount: string;
    assetCode: string;
    assetScale: number;
    isServer: boolean;
    sharedSecret: Buffer;
}
interface NewConnectionOpts extends BuildConnectionOpts {
    pskKey: Buffer;
    fulfillmentKey: Buffer;
}
export declare class ConnectionError extends Error {
    streamErrorCode: ErrorCode;
    constructor(message: string, streamErrorCode?: ErrorCode);
}
export declare class IlpRejectionError extends Error {
    ilpReject: IlpPacket.IlpReject;
    constructor(message: string, ilpReject: IlpPacket.IlpReject);
}
declare enum RemoteState {
    Init = 0,
    Connected = 1,
    Closed = 2
}
export interface PacketError {
    sourceAmount: Long;
    code: string;
}
export interface TestVolleyResult {
    maxDigits: number;
    exchangeRate: Rational;
    maxPacketAmounts: Long[];
    packetErrors: PacketError[];
}
export declare class Connection extends EventEmitter {
    readonly connectionTag?: string;
    protected readonly _receiptNonce?: Buffer;
    protected readonly _receiptSecret?: Buffer;
    protected connectionId: string;
    protected plugin: Plugin;
    protected _sourceAccount: string;
    protected _sourceAssetCode: string;
    protected _sourceAssetScale: number;
    protected _destinationAccount?: string;
    protected _destinationAssetCode?: string;
    protected _destinationAssetScale?: number;
    protected sharedSecret: Buffer;
    protected _pskKey: Buffer;
    protected _fulfillmentKey: Buffer;
    protected isServer: boolean;
    protected slippage: Rational;
    protected allowableReceiveExtra: Rational;
    protected enablePadding: boolean;
    protected maxBufferedData: number;
    protected idleTimeout: number;
    protected lastActive: Date;
    protected idleTimer?: NodeJS.Timer;
    protected rateRetryTimer: StoppableTimeout;
    protected nextPacketSequence: number;
    protected streams: Map<number, DataAndMoneyStream>;
    protected closedStreams: Set<number>;
    protected nextStreamId: number;
    protected maxStreamId: number;
    protected log: Logger;
    protected sending: boolean;
    protected looping: boolean;
    protected congestion: CongestionController;
    protected minExchangeRatePrecision: number;
    protected connected: boolean;
    protected closed: boolean;
    protected done: boolean;
    protected exchangeRate?: Rational;
    protected retryDelay: number;
    protected queuedFrames: Frame[];
    protected remoteState: RemoteState;
    protected remoteMaxStreamId: number;
    protected remoteKnowsOurAccount: boolean;
    protected remoteMaxOffset: number;
    protected _incomingHold: Long;
    protected _totalReceived: Long;
    protected _totalSent: Long;
    protected _totalDelivered: Long;
    protected _lastPacketExchangeRate: Rational;
    protected getExpiry: (destination: string) => Date;
    protected shouldFulfill?: (packetAmount: Long, packetId: Buffer, connectionTag?: string) => Promise<void>;
    constructor(opts: NewConnectionOpts);
    static build(opts: BuildConnectionOpts): Promise<Connection>;
    connect(): Promise<void>;
    end(): Promise<void>;
    destroy(err?: Error): Promise<void>;
    createStream(): DataAndMoneyStream;
    get destinationAccount(): string | undefined;
    get destinationAssetScale(): number | undefined;
    get destinationAssetCode(): string | undefined;
    get sourceAccount(): string;
    get sourceAssetScale(): number;
    get sourceAssetCode(): string;
    get minimumAcceptableExchangeRate(): string;
    get lastPacketExchangeRate(): string;
    get totalDelivered(): string;
    get totalSent(): string;
    get totalReceived(): string;
    handlePrepare(prepare: IlpPacket.IlpPrepare): Promise<IlpPacket.IlpFulfill>;
    protected handleControlFrames(frames: Frame[]): void;
    protected handleNewStream(streamId: number): void;
    protected handleStreamClose(frame: StreamCloseFrame): void;
    protected startSendLoop(): Promise<void>;
    protected loadAndSendPacket(): Promise<void>;
    protected sendTestPacketVolley(testPacketAmounts: Long[]): Promise<TestVolleyResult>;
    protected setupExchangeRate(): Promise<void>;
    protected determineExchangeRate(): Promise<void>;
    private stopTimers;
    protected sendTestPacket(amount: Long, timeout?: number): Promise<Packet | IlpPacket.IlpReject | null>;
    protected sendConnectionClose(err?: ConnectionError | Error): Promise<void>;
    protected sendPacket(packet: Packet, sourceAmount: Long, unfulfillable?: boolean): Promise<Packet | void>;
    protected undoRejectedPacket(requestPacket: Packet): void;
    protected handleConnectorError(reject: IlpPacket.IlpReject, amountSent: Long): Promise<void>;
    protected safeEmit(...args: Parameters<typeof EventEmitter.prototype.emit>): void;
    protected getOutgoingOffsets(): {
        currentOffset: number;
        maxOffset: number;
    };
    protected getIncomingOffsets(): {
        current: number;
        max: number;
        maxAcceptable: number;
    };
    protected removeStreamRecord(stream: DataAndMoneyStream): void;
    private startIdleTimer;
    private testIdle;
    private bumpIdle;
    private addIncomingHold;
    private removeIncomingHold;
    private addTotalReceived;
    private addTotalSent;
    private addTotalDelivered;
    private getNextPacketSequence;
    private maybePushAccountFrames;
}
export {};
