import LazyLevel from "@dao-xyz/lazy-level";
import { Multiaddr } from "@multiformats/multiaddr";
import { MinReplicas } from "./exchange-heads.js";
import { Entry, Log } from "@dao-xyz/peerbit-log";
import { X25519PublicKey, Ed25519Keypair, PublicKeyEncryptionResolver, Ed25519PublicKey } from "@dao-xyz/peerbit-crypto";
import { FastKeychain } from "./encryption.js";
import { Program, Address, LogCallbackOptions } from "@dao-xyz/peerbit-program";
import { PubSubData, Subscription, SubscriptionEvent, UnsubcriptionEvent } from "@dao-xyz/libp2p-direct-sub";
import "@libp2p/peer-id";
import { Libp2pExtended } from "@dao-xyz/peerbit-libp2p";
import { SubscriptionType } from "@dao-xyz/peerbit-program";
import { TrimToByteLengthOption } from "@dao-xyz/peerbit-log";
import { TrimToLengthOption } from "@dao-xyz/peerbit-log";
import { CreateOptions as ClientCreateOptions } from "@dao-xyz/peerbit-libp2p";
export declare const logger: import("pino").Logger<import("pino").LoggerOptions | import("pino").DestinationStream>;
interface ProgramWithMetadata {
    program: Program;
    openCounter: number;
}
interface LogWithMetaata {
    open: number;
    log: Log<any>;
    sync?: SyncFilter;
    minReplicas: MinReplicas;
}
export type OptionalCreateOptions = {
    limitSigning?: boolean;
    minReplicas?: number;
    refreshIntreval?: number;
    libp2pExternal?: boolean;
};
export type CreateOptions = {
    directory?: string;
    cache: LazyLevel;
    identity: Ed25519Keypair;
    keychain: FastKeychain;
} & OptionalCreateOptions;
export type SyncFilter = (entries: Entry<any>) => Promise<boolean> | boolean;
export type CreateInstanceOptions = {
    libp2p?: Libp2pExtended | ClientCreateOptions;
    directory?: string;
    cache?: LazyLevel;
} & OptionalCreateOptions;
export type OpenOptions = {
    entryToReplicate?: Entry<any>;
    role?: SubscriptionType;
    sync?: SyncFilter;
    timeout?: number;
    minReplicas?: MinReplicas | number;
    trim?: TrimToByteLengthOption | TrimToLengthOption;
    reset?: boolean;
} & {
    log?: LogCallbackOptions;
};
export declare class Peerbit {
    _libp2p: Libp2pExtended;
    directory?: string;
    _minReplicas: number;
    programs: Map<string, ProgramWithMetadata>;
    limitSigning: boolean;
    logs: Map<string, LogWithMetaata>;
    private _sortedPeersCache;
    private _gidPeersHistory;
    private _openProgramQueue;
    private _disconnected;
    private _disconnecting;
    private _refreshInterval;
    private _lastSubscriptionMessageId;
    private _cache;
    private _libp2pExternal?;
    private _identityHash;
    private _identity;
    private _keychain;
    constructor(libp2p: Libp2pExtended, options: CreateOptions);
    static create(options?: CreateInstanceOptions): Promise<Peerbit>;
    get libp2p(): Libp2pExtended;
    get cache(): LazyLevel;
    get encryption(): PublicKeyEncryptionResolver;
    get disconnected(): boolean;
    get disconnecting(): boolean;
    get identityHash(): string;
    get identity(): Ed25519Keypair;
    importKeypair(keypair: Ed25519Keypair): Promise<void>;
    exportKeypair<T extends Ed25519PublicKey | X25519PublicKey>(publicKey: T): Promise<T extends X25519PublicKey ? X25519PublicKey extends T ? import("@dao-xyz/peerbit-crypto").X25519Keypair : Ed25519Keypair : Ed25519Keypair>;
    /**
     * Dial a peer with an Ed25519 peerId
     */
    dial(address: string | Multiaddr | Multiaddr[] | Peerbit): Promise<boolean | undefined>;
    stop(): Promise<void>;
    onWrite<T>(_program: Program, log: Log<any>, entry: Entry<T>): void;
    _maybeOpenStorePromise: Promise<boolean>;
    _onMessage(evt: CustomEvent<PubSubData>): Promise<void>;
    _onUnsubscription(evt: CustomEvent<UnsubcriptionEvent>): Promise<void>;
    _onSubscription(evt: CustomEvent<SubscriptionEvent>): Promise<void>;
    private modifySortedSubscriptionCache;
    handleSubscriptionChange(fromHash: string, changes: Subscription[], subscribed: boolean): Promise<void>;
    /**
     * When a peers join the networkk and want to participate the leaders for particular log subgraphs might change, hence some might start replicating, might some stop
     * This method will go through my owned entries, and see whether I should share them with a new leader, and/or I should stop care about specific entries
     * @param channel
     */
    replicationReorganization(changedLogs: Set<string> | string[]): Promise<boolean>;
    _onClose(program: Program, log: Log<any>): Promise<void>;
    _onProgamClose(program: Program, programCache: LazyLevel): Promise<void>;
    addProgram(program: Program): ProgramWithMetadata;
    getReplicatorsSorted(log: Log<any>): string[] | undefined;
    getObservers(address: Address): string[] | undefined;
    isLeader(log: Log<any>, slot: {
        toString(): string;
    }, numberOfLeaders: number): Promise<boolean>;
    findLeaders(log: Log<any>, subject: {
        toString(): string;
    }, numberOfLeaders: number): Promise<string[]>;
    private subscribeToProgram;
    private unsubscribeToProgram;
    hasSubscribedToTopic(topic: string): boolean;
    /**
     * Default behaviour of a store is only to accept heads that are forks (new roots) with some probability
     * and to replicate heads (and updates) which is requested by another peer
     * @param store
     * @param options
     * @returns
     */
    open<S extends Program>(storeOrAddress: /* string | Address |  */ S | Address | string, options?: OpenOptions): Promise<S>;
}
export {};
