/// <reference types="node" />
import { BitField } from "@node-lightning/core";
import { ILogger } from "@node-lightning/logger";
import { NoiseSocket } from "@node-lightning/noise";
import { Readable } from "stream";
import { InitFeatureFlags } from "./flags/InitFeatureFlags";
import { IWireMessage } from "./messages/IWireMessage";
import { PeerState } from "./PeerState";
import { PingPongState } from "./PingPongState";
export interface IMessageSender {
    send(buf: Buffer): void;
    sendMessage(msg: IWireMessage): void;
}
export interface IMessageReceiver {
    read(): IWireMessage;
    on(event: "readable", listener: () => void): this;
    off(event: "readable", listener: () => void): this;
}
export declare type IMessageSenderReceiver = IMessageSender & IMessageReceiver;
export interface IPeer extends IMessageSenderReceiver {
    send(buf: Buffer): void;
    sendMessage(msg: IWireMessage): void;
    disconnect(): void;
    read(): IWireMessage;
    on(event: "readable", listener: () => void): this;
    on(event: "error", listener: (err: Error) => void): this;
    off(event: "readable", listener: () => void): this;
    off(event: "error", listener: (err: Error) => void): this;
}
/**
 * Peer is an EventEmitter that layers the Lightning Network wire
 * protocol ontop of an @node-lightning/noise NoiseSocket.
 *
 * Peer itself is a state-machine with three states:
 * 1. pending
 * 2. awaiting_peer_init
 * 3. ready
 *
 * The Peer instance starts in `pending` until the underlying NoiseSocket
 * has connected.
 *
 * It then immediately sends the InitMessage as specified in the Peer
 * constructor.
 *
 * At this point, the Peer transitions to `awaiting_peer_init`.
 *
 * Once the remote peer has sent its InitMessage, the state is
 * transitioned to `ready` and the Peer can be begin sending and
 * receiving messages.
 *
 * Once the peer is in the `ready` state it will begin emitting `message`
 * events when it receives new messages from the peer.
 *
 * The Peer will also start a PingPong state machine to manage sending
 * and receiving Pings and Pongs as defined in BOLT01
 *
 * A choice (probably wrongly) was made to make Peer an EventEmitter
 * instead of a DuplexStream operating in object mode. We need to keep
 * the noise socket in flowing mode (instead of paused) because we will
 * not know the length of messages until after we have deserialized the
 * message. This makes it a challenge to implement a DuplexStream that
 * emits objects (such as messages).
 *
 * @emits ready the underlying socket has performed its handshake and
 * initialization message swap has occurred.
 *
 * @emits message a new message has been received. Only sent after the
 * `ready` event has fired.
 *
 * @emits rawmessage outputs the message as a raw buffer instead of
 * a deserialized message.
 *
 * @emits error emitted when there is an error processing a message.
 * The underlying socket will be closed after this event is emitted.
 *
 * @emits close emitted when the connection to the peer has completedly
 * closed.
 *
 * @emits open emmited when the connection to the peer has been established
 * after the handshake has been performed
 *
 * @emits end emitted when the connection to the peer is ending.
 */
export declare class Peer extends Readable implements IPeer {
    readonly ls: Buffer;
    readonly localFeatures: BitField<InitFeatureFlags>;
    readonly localChains: Buffer[];
    readonly highWaterMark: number;
    static states: typeof PeerState;
    state: PeerState;
    socket: NoiseSocket;
    messageCounter: number;
    pingPongState: PingPongState;
    logger: ILogger;
    remoteFeatures: BitField<InitFeatureFlags>;
    remoteChains: Buffer[];
    isInitiator: boolean;
    reconnectTimeoutMs: number;
    private _id;
    private _rpk;
    private _host;
    private _port;
    private _reconnectHandle;
    constructor(ls: Buffer, localFeatures: BitField<InitFeatureFlags>, localChains: Buffer[], logger: ILogger, highWaterMark?: number);
    get id(): string;
    get pubkey(): Buffer;
    get pubkeyHex(): string;
    /**
     * Connect to the remote peer and binds socket events into the Peer.
     */
    connect(rpk: Buffer, host: string, port: number): void;
    /**
     *
     * @param socket
     */
    attach(socket: NoiseSocket): void;
    /**
     * Writes data on the NoiseSocket. This method allows custom
     * serialization of methods. Use `sendMessage` to send a message
     * using the default message serialization.
     * @param buf
     */
    send(buf: Buffer): boolean;
    /**
     * Writes the message on the NoiseSocket using the default
     * serialization properties
     */
    sendMessage(m: IWireMessage): boolean;
    /**
     * Closes the socket
     */
    disconnect(): void;
    /**
     * Reconnects the socket
     */
    reconnect(): void;
    private _onSocketReady;
    private _onSocketClose;
    private _onSocketError;
    _onSocketReadable(): void;
    _read(): void;
    /**
     * Sends the initialization message to the peer. This message
     * does not matter if it is sent before or after the peer sends
     * there message.
     */
    private _sendInitMessage;
    /**
     * Processes the initialization message sent by the remote peer.
     * Once this is successfully completed, the state is transitioned
     * to `active`
     */
    private _processPeerInitMessage;
    /**
     * Process the raw message sent by the peer. These messages are
     * processed after the initialization message has been received.
     */
    private _processMessage;
}
