/**
 * Wrap a network node.
 */
import { IMessageType } from '@protobuf-ts/runtime';
import { ServerCallContext } from '@protobuf-ts/runtime-rpc';
import { DhtAddress, PeerDescriptor } from '@streamr/dht';
import { ProtoRpcClient } from '@streamr/proto-rpc';
import { ExternalRpcClient, ExternalRpcClientClass, NetworkOptions, StreamMessage as NewStreamMessage, ProxyDirection } from '@streamr/trackerless-network';
import { MetricsContext, StreamPartID, UserID } from '@streamr/utils';
import { Authentication } from './Authentication';
import { NetworkPeerDescriptor, StrictStreamrClientConfig } from './Config';
import { DestroySignal } from './DestroySignal';
import { OperatorRegistry } from './contracts/OperatorRegistry';
import { StreamMessage as OldStreamMessage } from './protocol/StreamMessage';
export interface NetworkNodeStub {
    getNodeId: () => DhtAddress;
    addMessageListener: (listener: (msg: NewStreamMessage) => void) => void;
    removeMessageListener: (listener: (msg: NewStreamMessage) => void) => void;
    join: (streamPartId: StreamPartID, neighborRequirement?: {
        minCount: number;
        timeout: number;
    }) => Promise<void>;
    leave: (streamPartId: StreamPartID) => Promise<void>;
    broadcast: (streamMessage: NewStreamMessage) => Promise<void>;
    getStreamParts: () => StreamPartID[];
    getNeighbors: (streamPartId: StreamPartID) => readonly DhtAddress[];
    getPeerDescriptor: () => PeerDescriptor;
    getOptions: () => NetworkOptions;
    getMetricsContext: () => MetricsContext;
    getDiagnosticInfo: () => Record<string, unknown>;
    hasStreamPart: (streamPartId: StreamPartID) => boolean;
    inspect(node: PeerDescriptor, streamPartId: StreamPartID): Promise<boolean>;
    start: (doJoin?: boolean) => Promise<void>;
    stop: () => Promise<void>;
    setProxies: (streamPartId: StreamPartID, nodes: PeerDescriptor[], direction: ProxyDirection, userId: UserID, connectionCount?: number) => Promise<void>;
    isProxiedStreamPart(streamPartId: StreamPartID): boolean;
    setStreamPartEntryPoints: (streamPartId: StreamPartID, peerDescriptors: PeerDescriptor[]) => void;
    createExternalRpcClient<T extends ExternalRpcClient>(clientClass: ExternalRpcClientClass<T>): ProtoRpcClient<T>;
    registerExternalNetworkRpcMethod<RequestClass extends IMessageType<RequestType>, ResponseClass extends IMessageType<ResponseType>, RequestType extends object, ResponseType extends object>(request: RequestClass, response: ResponseClass, name: string, fn: (req: RequestType, context: ServerCallContext) => Promise<ResponseType>): void;
}
export interface Events {
    start: () => void;
}
/**
 * The factory is used so that integration tests can replace the real network node with a fake instance
 */
export declare class NetworkNodeFactory {
    createNetworkNode(opts: NetworkOptions): NetworkNodeStub;
}
/**
 * Wrap a network node.
 * Lazily creates & starts node on first call to getNode().
 */
export declare class NetworkNodeFacade {
    private cachedNode?;
    private startNodeCalled;
    private startNodeComplete;
    private readonly messageListeners;
    private readonly networkNodeFactory;
    private readonly operatorRegistry;
    private readonly config;
    private readonly authentication;
    private readonly eventEmitter;
    private readonly destroySignal;
    constructor(networkNodeFactory: NetworkNodeFactory, operatorRegistry: OperatorRegistry, config: Pick<StrictStreamrClientConfig, 'network' | 'contracts'>, authentication: Authentication, destroySignal: DestroySignal);
    private getNetworkOptions;
    /**
     * Stop network node, or wait for it to stop if already stopping.
     * Subsequent calls to getNode/start will fail.
     */
    private destroy;
    /**
     * Start network node, or wait for it to start if already started.
     */
    private startNodeTask;
    private initNode;
    startNode: () => Promise<unknown>;
    getNode(): Promise<Omit<NetworkNodeStub, 'start' | 'stop'>>;
    getNodeId(): Promise<DhtAddress>;
    join(streamPartId: StreamPartID, neighborRequirement?: {
        minCount: number;
        timeout: number;
    }): Promise<void>;
    leave(streamPartId: StreamPartID): Promise<void>;
    broadcast(msg: OldStreamMessage): Promise<void>;
    addMessageListener(listener: (msg: OldStreamMessage) => void): void;
    removeMessageListener(listener: (msg: OldStreamMessage) => void): void;
    isProxiedStreamPart(streamPartId: StreamPartID): Promise<boolean>;
    getMetricsContext(): Promise<MetricsContext>;
    getPeerDescriptor(): Promise<PeerDescriptor>;
    getDiagnosticInfo(): Promise<Record<string, unknown>>;
    getStreamParts(): Promise<readonly StreamPartID[]>;
    getNeighbors(streamPartId: StreamPartID): Promise<readonly DhtAddress[]>;
    getOptions(): Promise<NetworkOptions>;
    inspect(node: NetworkPeerDescriptor, streamPartId: StreamPartID): Promise<boolean>;
    setProxies(streamPartId: StreamPartID, nodes: NetworkPeerDescriptor[], direction: ProxyDirection, connectionCount?: number): Promise<void>;
    setStreamPartEntryPoints(streamPartId: StreamPartID, nodeDescriptors: NetworkPeerDescriptor[]): Promise<void>;
    discoverOperators(leader: NetworkPeerDescriptor, streamPartId: StreamPartID): Promise<NetworkPeerDescriptor[]>;
    private createExternalRpcClient;
    registerOperator(opts: {
        getAssignedNodesForStreamPart: (streamPartId: StreamPartID) => NetworkPeerDescriptor[];
    }): Promise<void>;
    private isStarting;
    once<E extends keyof Events>(eventName: E, listener: Events[E]): void;
    private getEntryPoints;
}
