import { BeaconEvent, BeaconEventHandlerFunction, BeaconEventType } from '../events';
import { AccountInfo, TransportType, BeaconMessageType, RequestPermissionInput, RequestSignPayloadInput, RequestOperationInput, RequestBroadcastInput, PermissionResponseOutput, SignPayloadResponseOutput, OperationResponseOutput, BroadcastResponseOutput, Network, AppMetadata, ExtendedPeerInfo, ColorMode, Blockchain, BlockchainRequestV3, BlockchainResponseV3, PermissionRequestV3, PermissionResponseV3, ProofOfEventChallengeResponse, RequestProofOfEventChallengeInput, PeerInfoType, SimulatedProofOfEventChallengeResponse, RequestSimulatedProofOfEventChallengeInput } from '@airgap/beacon-types';
import { Client, Transport } from '@airgap/beacon-core';
import { BlockExplorer } from '../utils/block-explorer';
import { DAppClientOptions } from './DAppClientOptions';
import { BeaconEventHandler } from '@airgap/beacon-dapp';
import { DappPostMessageTransport } from '../transports/DappPostMessageTransport';
import { DappP2PTransport } from '../transports/DappP2PTransport';
import { DappWalletConnectTransport } from '../transports/DappWalletConnectTransport';
/**
 * @publicapi
 *
 * The DAppClient has to be used in decentralized applications. It handles all the logic related to connecting to beacon-compatible
 * wallets and sending requests.
 *
 * @category DApp
 */
export declare class DAppClient extends Client {
    /**
     * The description of the app
     */
    readonly description?: string;
    /**
     * The block explorer used by the SDK
     */
    readonly blockExplorer: BlockExplorer;
    /**
     * Automatically switch between apps on Mobile Devices (Enabled by Default)
     */
    private enableAppSwitching;
    /**
     * Enable metrics tracking (Disabled by Default)
     */
    private enableMetrics?;
    private userId?;
    network: Network;
    protected readonly events: BeaconEventHandler;
    protected postMessageTransport: DappPostMessageTransport | undefined;
    protected p2pTransport: DappP2PTransport | undefined;
    protected walletConnectTransport: DappWalletConnectTransport | undefined;
    protected wcProjectId?: string;
    protected wcRelayUrl?: string;
    private isGetActiveAccountHandled;
    private readonly openRequestsOtherTabs;
    /**
     * A map of requests that are currently "open", meaning we have sent them to a wallet and are still awaiting a response.
     */
    private readonly openRequests;
    /**
     * The currently active account. For all requests that are associated to a specific request (operation request, signing request),
     * the active account is used to determine the network and destination wallet
     */
    private _activeAccount;
    /**
     * The currently active peer. This is used to address a peer in case the active account is not set. (Eg. for permission requests)
     */
    private _activePeer;
    private _initPromise;
    private isInitPending;
    private readonly activeAccountLoaded;
    private readonly appMetadataManager;
    private readonly disclaimerText?;
    private readonly errorMessages;
    private readonly featuredWallets;
    private readonly storageValidator;
    private readonly beaconIDB;
    private debounceSetActiveAccount;
    private multiTabChannel;
    constructor(config: DAppClientOptions);
    private checkIfBCLeaderExists;
    private onElectedLeaderhandler;
    private onBCMessageHandler;
    private prepareRequest;
    private createStateSnapshot;
    private initUserID;
    initInternalTransports(): Promise<void>;
    private initEvents;
    private onRelayerError;
    private wcToastHandler;
    private channelClosedHandler;
    /**
     * Destroy the instance.
     *
     * WARNING: Call `destroy` whenever you no longer need dAppClient
     * as it frees internal subscriptions to the transport and therefore the instance may no longer work properly.
     * If you wish to disconnect your dApp, use `disconnect` instead.
     */
    destroy(): Promise<void>;
    init(transport?: Transport<any>, substratePairing?: boolean): Promise<TransportType>;
    /**
     * Returns the active account
     */
    getActiveAccount(): Promise<AccountInfo | undefined>;
    private isInvalidState;
    private resetInvalidState;
    /**
     * Sets the active account
     *
     * @param account The account that will be set as the active account
     */
    setActiveAccount(account?: AccountInfo): Promise<void>;
    /**
     * Clear the active account
     */
    clearActiveAccount(): Promise<void>;
    setColorMode(colorMode: ColorMode): Promise<void>;
    getColorMode(): Promise<ColorMode>;
    /**
     * @deprecated
     *
     * Use getOwnAppMetadata instead
     */
    getAppMetadata(): Promise<AppMetadata>;
    showPrepare(): Promise<void>;
    hideUI(elements: ('alert' | 'toast')[]): Promise<void>;
    private tryToAppSwitch;
    private addQueryParam;
    private buildPayload;
    private updateMetricsStorage;
    private sendMetrics;
    private checkMakeRequest;
    /**
     * Will remove the account from the local storage and set a new active account if necessary.
     *
     * @param accountIdentifier ID of the account
     */
    removeAccount(accountIdentifier: string): Promise<void>;
    /**
     * Remove all accounts and set active account to undefined
     */
    removeAllAccounts(): Promise<void>;
    /**
     * Removes a peer and all the accounts that have been connected through that peer
     *
     * @param peer Peer to be removed
     */
    removePeer(peer: ExtendedPeerInfo, sendDisconnectToPeer?: boolean): Promise<void>;
    /**
     * Remove all peers and all accounts that have been connected through those peers
     */
    removeAllPeers(sendDisconnectToPeers?: boolean): Promise<void>;
    /**
     * Allows the user to subscribe to specific events that are fired in the SDK
     *
     * @param internalEvent The event to subscribe to
     * @param eventCallback The callback that will be called when the event occurs
     */
    subscribeToEvent<K extends BeaconEvent>(internalEvent: K, eventCallback: BeaconEventHandlerFunction<BeaconEventType[K]>): Promise<void>;
    /**
     * Check if we have permissions to send the specific message type to the active account.
     * If no active account is set, only permission requests are allowed.
     *
     * @param type The type of the message
     */
    checkPermissions(type: BeaconMessageType): Promise<boolean>;
    sendNotification(title: string, message: string, payload: string, protocolIdentifier: string): Promise<string>;
    private blockchains;
    addBlockchain(chain: Blockchain): void;
    removeBlockchain(chainIdentifier: string): void;
    permissionRequest(input: PermissionRequestV3<string>): Promise<PermissionResponseV3<string>>;
    request(input: BlockchainRequestV3<string>): Promise<BlockchainResponseV3<string>>;
    /**
     * Send a permission request to the DApp. This should be done as the first step. The wallet will respond
     * with an publicKey and permissions that were given. The account returned will be set as the "activeAccount"
     * and will be used for the following requests.
     *
     * @param input The message details we need to prepare the PermissionRequest message.
     */
    requestPermissions(input?: RequestPermissionInput): Promise<PermissionResponseOutput>;
    /**
     * Send a proof of event request to the wallet. The wallet will either accept or decline the challenge.
     * If it is accepted, the challenge will be stored, meaning that even if the user refresh the page, the DAppClient will keep checking if the challenge has been fulfilled.
     * Once the challenge is stored, a challenge stored message will be sent to the wallet.
     * It's **highly recommended** to run a proof of event challenge to check the identity of an abstracted account
     *
     * @param input The message details we need to prepare the ProofOfEventChallenge message.
     */
    requestProofOfEventChallenge(input: RequestProofOfEventChallengeInput): Promise<ProofOfEventChallengeResponse>;
    /**
     * Send a simulated proof of event request to the wallet. The wallet will either accept or decline the challenge.
     * It's the same than `requestProofOfEventChallenge` but rather than executing operations on the blockchain to prove the identity,
     * The wallet will return a list of operations that you'll be able to run on your side to verify the identity of the abstracted account
     * It's **highly recommended** to run a proof of event challenge to check the identity of an abstracted account
     *
     * @param input The message details we need to prepare the SimulatedProofOfEventChallenge message.
     */
    requestSimulatedProofOfEventChallenge(input: RequestSimulatedProofOfEventChallengeInput): Promise<SimulatedProofOfEventChallengeResponse>;
    /**
     * This method will send a "SignPayloadRequest" to the wallet. This method is meant to be used to sign
     * arbitrary data (eg. a string). It will return the signature in the format of "edsig..."
     *
     * @param input The message details we need to prepare the SignPayloadRequest message.
     */
    requestSignPayload(input: RequestSignPayloadInput): Promise<SignPayloadResponseOutput>;
    /**
     * This method will send an "EncryptPayloadRequest" to the wallet. This method is meant to be used to encrypt or decrypt
     * arbitrary data (eg. a string). It will return the encrypted or decrypted payload
     *
     * @param input The message details we need to prepare the EncryptPayloadRequest message.
     */
    /**
     * This method sends an OperationRequest to the wallet. This method should be used for all kinds of operations,
     * eg. transaction or delegation. Not all properties have to be provided. Data like "counter" and fees will be
     * fetched and calculated by the wallet (but they can still be provided if required).
     *
     * @param input The message details we need to prepare the OperationRequest message.
     */
    requestOperation(input: RequestOperationInput): Promise<OperationResponseOutput>;
    /**
     * Sends a "BroadcastRequest" to the wallet. This method can be used to inject an already signed transaction
     * to the network.
     *
     * @param input The message details we need to prepare the BroadcastRequest message.
     */
    requestBroadcast(input: RequestBroadcastInput): Promise<BroadcastResponseOutput>;
    protected setActivePeer(peer?: PeerInfoType): Promise<void>;
    /**
     * A "setter" for when the transport needs to be changed.
     */
    protected setTransport(transport?: Transport<any>): Promise<void>;
    /**
     * This method will emit an internal error message.
     *
     * @param errorMessage The error message to send.
     */
    private sendInternalError;
    /**
     * This method will remove all accounts associated with a specific peer.
     *
     * @param peersToRemove An array of peers for which accounts should be removed
     */
    private removeAccountsForPeers;
    private removeAccountsForPeerIds;
    /**
     * This message handles errors that we receive from the wallet.
     *
     * @param request The request we sent
     * @param beaconError The error we received
     */
    private handleRequestError;
    /**
     * This message will send an event when we receive a successful response to one of the requests we sent.
     *
     * @param request The request we sent
     * @param response The response we received
     */
    private notifySuccess;
    private getWalletInfoFromStorage;
    private updateStorageWallet;
    private getWalletInfo;
    private getPeer;
    /**
     * This method handles sending of requests to the DApp. It makes sure that the DAppClient is initialized and connected
     * to the transport. After that rate limits and permissions will be checked, an ID is attached and the request is sent
     * to the DApp over the transport.
     *
     * @param requestInput The BeaconMessage to be sent to the wallet
     * @param account The account that the message will be sent to
     * @param skipResponse If true, the function return as soon as the message is sent
     */
    private makeRequest;
    /**
     * This method handles sending of requests to the DApp. It makes sure that the DAppClient is initialized and connected
     * to the transport. After that rate limits and permissions will be checked, an ID is attached and the request is sent
     * to the DApp over the transport.
     *
     * @param requestInput The BeaconMessage to be sent to the wallet
     * @param account The account that the message will be sent to
     */
    private makeRequestV3;
    private makeRequestBC;
    disconnect(): Promise<void>;
    /**
     * Adds a requests to the "openRequests" set so we know what messages have already been answered/handled.
     *
     * @param id The ID of the message
     * @param promise A promise that resolves once the response for that specific message is received
     */
    private addOpenRequest;
    private sendNotificationWithAccessToken;
    private onNewAccount;
}
