/// <reference types="node" />
/// <reference types="node" />
import { RemoveCertificate } from '@shardeum-foundation/lib-types/build/src/p2p/LostTypes';
import { EventEmitter } from 'events';
import { Handler } from 'express';
import Log4js from 'log4js';
import Crypto from '../crypto';
import Debug from '../debug';
import LoadDetection from '../load-detection';
import Logger, { LogFlags } from '../logger';
import * as Network from '../network';
import * as Archivers from '../p2p/Archivers';
import * as ServiceQueue from '../p2p/ServiceQueue';
import * as Wrapper from '../p2p/Wrapper';
import RateLimiting from '../rate-limiting';
import Reporter from '../reporter';
import * as ShardusTypes from '../shardus/shardus-types';
import { DevSecurityLevel } from '../shardus/shardus-types';
import StateManager from '../state-manager';
import { CachedAppData, QueueCountsResult } from '../state-manager/state-manager-types';
import { DebugComplete } from '../state-manager/TransactionQueue';
import Statistics from '../statistics';
import Storage from '../storage';
import MemoryReporting from '../utils/memoryReporting';
import NestedCounters from '../utils/nestedCounters';
import Profiler from '../utils/profiler';
import SocketIO from 'socket.io';
import { P2P } from '@shardeum-foundation/lib-types';
export declare let logDir_global: any;
type RouteHandlerRegister = (route: string, authHandler: Handler, responseHandler?: Handler) => void;
interface Shardus {
    io: SocketIO.Server;
    profiler: Profiler;
    nestedCounters: NestedCounters;
    memoryReporting: MemoryReporting;
    config: ShardusTypes.StrictServerConfiguration;
    logger: Logger;
    mainLogger: Log4js.Logger;
    seqLogger: Log4js.Logger;
    fatalLogger: Log4js.Logger;
    appLogger: Log4js.Logger;
    exitHandler: any;
    storage: Storage;
    crypto: Crypto;
    network: Network.NetworkClass;
    p2p: Wrapper.P2P;
    debug: Debug;
    appProvided: boolean;
    app: ShardusTypes.App;
    reporter: Reporter;
    stateManager: StateManager;
    statistics: Statistics;
    loadDetection: LoadDetection;
    rateLimiting: RateLimiting;
    heartbeatInterval: number;
    heartbeatTimer: NodeJS.Timeout;
    registerExternalGet: RouteHandlerRegister;
    registerExternalPost: RouteHandlerRegister;
    registerExternalPut: RouteHandlerRegister;
    registerExternalDelete: RouteHandlerRegister;
    registerExternalPatch: RouteHandlerRegister;
    serviceQueue: {
        registerBeforeAddVerifier: typeof ServiceQueue.registerBeforeAddVerifier;
        registerApplyVerifier: typeof ServiceQueue.registerApplyVerifier;
        registerShutdownHandler: typeof ServiceQueue.registerShutdownHandler;
        containsTxData: typeof ServiceQueue.containsTxData;
        containsTx: typeof ServiceQueue.containsTx;
        addNetworkTx: typeof ServiceQueue.addNetworkTx;
        getLatestNetworkTxEntryForSubqueueKey: typeof ServiceQueue.getLatestNetworkTxEntryForSubqueueKey;
    };
    _listeners: any;
    appliedConfigChanges: Set<string>;
    debugForeverLoopCounter: number;
    debugForeverLoopsEnabled: boolean;
}
/**
 * The main module that is used by the app developer to interact with the shardus api
 */
declare class Shardus extends EventEmitter {
    constructor({ server: config, logs: logsConfig, storage: storageConfig }: ShardusTypes.StrictShardusConfiguration);
    /**
     * This function is what the app developer uses to setup all the SDK functions used by shardus
     * @typedef {import('./index').App} App
     */
    setup(app: ShardusTypes.App): this;
    /**
     * Calling this function will start the network
     * @param {*} exitProcOnFail Exit the process if an error occurs
     */
    start(): Promise<void>;
    /**
     * This function designed to help fetch the network account and
     * call updateConfigChangeQueue before our node has finished syncing
     * This is needed as a node will be sensitive to config changes
     * happening around the time it is syncing
     * @param {*} account
     * @param {*} lastCycle
     */
    earlyConfigFetchAndPatch(lastCycle_counter: number): Promise<void>;
    /**
     * Function used to register event listeners
     * @param {*} emitter Socket emitter to be called
     * @param {*} event Event name to be registered
     * @param {*} callback Callback function to be executed on event
     */
    _registerListener(emitter: any, event: any, callback: any): void;
    /**
     * Function used to register event listeners
     * @param {*} event Name of the event to be unregistered
     */
    _unregisterListener(event: any): void;
    /**
     * Function to unregister all event listeners
     */
    _cleanupListeners(): void;
    _timestampAndQueueTransaction(tx: ShardusTypes.OpaqueTransaction, appData: any, global?: boolean, noConsensus?: boolean, loggingContext?: string): Promise<{
        success: boolean;
        reason: string;
        status: number;
    } | {
        success: boolean;
        reason: string;
        status: number;
        txId: string;
    }>;
    /**
     * Function used to register listeners for transaction related events
     */
    _attemptCreateAppliedListener(): void;
    /**
     * Function to unregister all transaction related events
     */
    _attemptRemoveAppliedListener(): void;
    /**
     * function to unregister listener for the "accepted" event
     */
    _unlinkStateManager(): void;
    /**
     * Creates an instance of the StateManager module and registers the "accepted" event listener for queueing transactions
     */
    _createAndLinkStateManager(): void;
    /**
     * Function used to allow shardus to sync data specific to an app if it should be required
     */
    syncAppData(): Promise<void>;
    /**
     * Calls the "put" function with the "set" boolean parameter set to true
     * @param {*} tx The transaction data
     */
    set(tx: any): Promise<{
        success: boolean;
        reason: string;
        status: number;
        txId?: string;
    }>;
    /**
     * Allows the application to log specific data to an app.log file
     * @param  {...any} data The data to be logged in app.log file
     */
    log(...data: any[]): void;
    /**
     * Gets log flags.
     * use these for to cull out slow log lines with stringify
     * if you pass comma separated objects to dapp.log you do not need this.
     * Also good for controlling console logging
     */
    getLogFlags(): LogFlags;
    /**
     * Submits a transaction to the network
     * Returns an object that tells whether a tx was successful or not and the reason why via the
     * validateTxnFields application SDK function.
     * Throws an error if an application was not provided to shardus.
     *
     * @param tx the TX format is not known to shardus core and can be any object
     * @param set this is an old feaure that can be used by the first node in the network to inject TXs early. candidate for deprecation
     * @param global this is used for injecting a tx that changes a global account completely different consensus is used for these.  see src/p2p/GlobalAccounts.ts
     * @param inputAppData optional opaque app data that can be passed in.  this is forwared to the dapp when precrack is called.
     * @returns
     * {
     *   success: boolean,
     *   reason: string,
     *   staus: number
     * }
     */
    put(tx: ShardusTypes.OpaqueTransaction | ShardusTypes.ReinjectedOpaqueTransaction, set?: boolean, global?: boolean, inputAppData?: any): Promise<{
        success: boolean;
        reason: string;
        status: number;
        txId?: string;
    }>;
    forwardTransactionToLuckyNodes(senderAddress: string, tx: ShardusTypes.OpaqueTransaction, txId: string, message?: string, context?: string): Promise<unknown>;
    /**
     * Returns the nodeId for this node
     */
    getNodeId(): string;
    /**
     * Returns node info given a node id
     * @param {*} id The nodeId of this node
     */
    getNode(id: string): ShardusTypes.Node | undefined;
    getRemovedNodePubKeyFromCache(id: string): ShardusTypes.Node['publicKey'] | undefined;
    getNodeByPubKey(id: string): ShardusTypes.Node;
    getNodeRotationIndex(id: string): {
        idx: number;
        total: number;
    };
    isNodeInRotationBounds(nodeId: string): boolean;
    isNodeActiveByPubKey(pubKey: string): boolean;
    isNodeReadyByPubKey(pubKey: string): boolean;
    isNodeSyncingByPubKey(pubKey: string): boolean;
    isNodeSelectedByPubKey(pubKey: string): boolean;
    isNodeActive(id: string): boolean;
    /**
     * Returns an array of cycles in the cycleChain history starting from the current cycle
     * @param {*} amount The number cycles to fetch from the recent cycle history
     */
    getLatestCycles(amount?: number): P2P.CycleCreatorTypes.CycleRecord[];
    /**
     * This function return number of active in the latest cycle.
     */
    getNumActiveNodes(): number;
    fastIsPicked(numberToPick: number): boolean;
    /**
     *
     * @returns {ShardusTypes.Cycle['mode']} returns the current network mode
     */
    getNetworkMode(): ShardusTypes.Cycle['mode'];
    /**
     * @typedef {import('../shardus/index.js').Node} Node
     */
    /**
     * getClosestNodes finds the closes nodes to a certain hash value
     * @param {string} hash any hash address (256bit 64 characters)
     * @param {number} count how many nodes to return
     * @param {boolean} selfExclude
     * @returns {string[]} returns a list of nodes ids that are closest. roughly in order of closeness
     */
    getClosestNodes(hash: string, count?: number, selfExclude?: boolean): string[];
    checkCycleShardData(tag: string): boolean;
    getClosestNodesGlobal(hash: any, count: any): string[];
    removeNodeWithCertificiate(cert: RemoveCertificate): void;
    computeNodeRank(nodeId: string, txId: string, timestamp: number): bigint;
    getShardusProfiler(): Profiler;
    /** Get the time in MS a replacement for Date.Now().  If p2p.useNTPOffsets===true then adds the NPT offset  */
    shardusGetTime(): number;
    setDebugSetLastAppAwait(label: string, complete?: DebugComplete): void;
    addNetworkTx: typeof ServiceQueue.addNetworkTx;
    getLatestNetworkTxEntryForSubqueueKey: typeof ServiceQueue.getLatestNetworkTxEntryForSubqueueKey;
    validateClosestActiveNodeSignatures(signedAppData: any, signs: ShardusTypes.Sign[], minRequired: number, nodesToSign: number, allowedBackupNodes: number): {
        success: boolean;
        reason: string;
    };
    /**
     * isNodeInDistance
     * @param {string} hash any hash address (256bit 64 characters)
     * @param {string} nodeId id of a node
     * @param {number} distance how far away can this node be to the home node of the hash
     * @returns {boolean} is the node in the distance to the target
     */
    isNodeInDistance(hash: string, nodeId: string, distance: number): boolean;
    createApplyResponse(txId: any, txTimestamp: any): {
        stateTableResults: any[];
        txId: any;
        txTimestamp: any;
        accountData: any[];
        accountWrites: any[];
        appDefinedData: {};
        failed: boolean;
        failMessage: any;
        appReceiptData: any;
        appReceiptDataHash: any;
    };
    shutdownFromDapp(tag: string, message: string, restart: boolean): Promise<void>;
    applyResponseAddReceiptData(resultObject: ShardusTypes.ApplyResponse, appReceiptData: any, appReceiptDataHash: string): void;
    applyResponseSetFailed(resultObject: ShardusTypes.ApplyResponse, failMessage: string): void;
    applyResponseAddState(resultObject: ShardusTypes.ApplyResponse, //TODO define type! :{stateTableResults: ShardusTypes.StateTableObject[], accountData:ShardusTypes.WrappedResponse[] },
    accountData: any, localCache: any, accountId: string, txId: string, txTimestamp: number, stateBefore: string, stateAfter: string, accountCreated: boolean): void;
    applyResponseAddChangedAccount(resultObject: ShardusTypes.ApplyResponse, //TODO define this type!
    accountId: string, account: ShardusTypes.WrappedResponse, txId: string, txTimestamp: number): void;
    useAccountWrites(): void;
    tryInvolveAccount(txId: string, address: string, isRead: boolean): boolean;
    signAsNode(obj: any): any;
    resetAppRelatedState(): Promise<void>;
    getLocalOrRemoteAccount(address: any, opts?: {
        useRICache: boolean;
        canThrowException?: boolean;
    }): Promise<ShardusTypes.WrappedDataFromQueue>;
    getLocalOrRemoteCachedAppData(topic: any, dataId: any): Promise<CachedAppData | null>;
    getLocalOrRemoteAccountQueueCount(address: any): Promise<QueueCountsResult>;
    registerCacheTopic(topic: string, maxCycleAge: number, maxCacheElements: number): Promise<boolean>;
    sendCorrespondingCachedAppData(topic: string, dataID: string, appData: any, cycle: number, fromId: string, txId: string): Promise<void>;
    /**
     * This function is used to query data from an account that is guaranteed to be in a remote shard
     * @param {*} address The address / publicKey of the account in which to query
     */
    getRemoteAccount(address: any): Promise<unknown>;
    getConsenusGroupForAccount(address: string): ShardusTypes.Node[];
    getRandomConsensusNodeForAccount(address: string): ShardusTypes.Node;
    isAccountRemote(address: string): boolean;
    /**
     * test once at the given probability to fail.  If it fails, log the message and return true.  If it doesnt fail, return false.
     * @param failChance 0-1
     * @param debugName
     * @param key
     * @param message
     * @param verboseRequired
     * @returns
     */
    testFailChance(failChance: number, debugName: string, key: string, message: string, verboseRequired: boolean): boolean;
    debugForeverLoop(tag: string): Promise<void>;
    setupDebugEndpoints(): void;
    /**
     * Creates a wrapped response for formatting required by shardus
     * @param {*} accountId
     * @param {*} accountCreated
     * @param {*} hash
     * @param {*} timestamp
     * @param {*} fullData
     */
    createWrappedResponse(accountId: any, accountCreated: any, hash: any, timestamp: any, fullData: any): {
        accountId: any;
        accountCreated: any;
        isPartial: boolean;
        stateId: any;
        timestamp: any;
        data: any;
    };
    /**
     * setPartialData
     * @param {Shardus.WrappedResponse} response
     * @param {any} partialData
     * @param {any} userTag
     */
    setPartialData(response: any, partialData: any, userTag: any): void;
    genericApplyPartialUpate(fullObject: any, updatedPartialObject: any): void;
    /**
     * This is for a dapp to restore a bunch of account data in a debug situation.
     * This will call back into the dapp and instruct it to commit each account
     * This will also update shardus values.
     * There is a bug with re-updating the accounts copy db though.
     * @param accountCopies
     */
    debugCommitAccountCopies(accountCopies: ShardusTypes.AccountsCopy[]): Promise<void>;
    forwardAccounts(data: Archivers.InitialAccountsData): Promise<void>;
    getDevPublicKeys(): Required<{
        [x: string]: ShardusTypes.DevSecurityLevel;
    }>;
    getDevPublicKey(keyName?: string): string;
    getDevPublicKeyMaxLevel(clearance?: DevSecurityLevel): string;
    ensureKeySecurity(keyName: string, clearance: DevSecurityLevel): boolean;
    getMultisigPublicKeys(): Required<{
        [x: string]: ShardusTypes.DevSecurityLevel;
    }>;
    getMultisigPublicKey(key: string): string;
    ensureMultisigKeySecurity(pubKey: string, level: DevSecurityLevel): boolean;
    /**
     * Shutdown this node in the network
     * @param {boolean} exitProcess Exit the process when shutting down
     */
    shutdown(exitProcess?: boolean): Promise<void>;
    /**
     * Grab the SDK interface provided by the application for shardus
     * @param {App} application
     * @returns {App}
     */
    _getApplicationInterface(application: ShardusTypes.App): ShardusTypes.App;
    /**
     * Register the exit and config routes
     */
    _registerRoutes(): void;
    /**
     * Registers exception handlers for "uncaughtException" and "unhandledRejection"
     */
    registerExceptionHandler(): void;
    /**
     * Checks a transaction timestamp for expiration
     * deprecated
     * @param {number} timestamp
     */
    updateConfigChangeQueue(account: ShardusTypes.WrappedData, lastCycle_counter: number, updateNetworkAccount: boolean): Promise<void>;
    patchObject(existingObject: any, changeObj: any, appData: any): void;
    /**
     * Do some periodic debug logic work
     * @param lastCycle
     */
    updateDebug(lastCycle: ShardusTypes.Cycle): void;
    /**
     * Sets a global account value using the GlobalAccont Class' setGlobal function.
     *
     * @param address - The address of the account.
     * @param addressHash - The hash of the address.
     * @param value - The value to set for the account.
     * @param when - The timestamp or condition when the value should be set.
     * @param source - The source of the value.
     * @param afterStateHash - The state hash after setting the value.
     */
    setGlobal(address: any, addressHash: any, value: any, when: any, source: any, afterStateHash: any): void;
    getDebugModeMiddleware(): (_req: any, res: any, next: any) => void;
    getDebugModeMiddlewareLow(): (_req: any, res: any, next: any) => void;
    getDebugModeMiddlewareMedium(): (_req: any, res: any, next: any) => void;
    getDebugModeMiddlewareHigh(): (_req: any, res: any, next: any) => void;
    getDebugModeMiddlewareMultiSig(): (_req: any, res: any, next: any) => void;
    shardus_fatal(key: any, log: any, log2?: any): void;
    monitorEvent(category: string, name: string, count: number, message: string): void;
    setMemoryLimit(topic: string, cacheCountLimit: number): void;
    getAppDataSignatures(type: string, hash: string, nodesToSign: number, appData: any, allowedBackupNodes?: number): Promise<ShardusTypes.GetAppDataSignaturesResult>;
    isOnStandbyList(publicKey: string): boolean;
    isTxInQueue(txId: string): boolean;
}
export default Shardus;
export * as ShardusTypes from '../shardus/shardus-types';
