import { Contract, ContractReceipt, ContractTransaction } from 'ethers';
import EventEmitter from 'eventemitter3';
import { InternalEvents, StreamrClientEventEmitter, StreamrClientEvents } from '../events';
import { LoggerFactory } from './LoggerFactory';
export interface ContractEvent {
    onMethodExecute: (methodName: string) => void;
    onTransactionSubmit: (methodName: string, tx: ContractTransaction) => void;
    onTransactionConfirm: (methodName: string, tx: ContractTransaction, receipt: ContractReceipt) => void;
}
export type ObservableContract<T extends Contract> = T & {
    eventEmitter: EventEmitter<ContractEvent>;
};
export declare function waitForTx(txToSubmit: Promise<ContractTransaction>): Promise<ContractReceipt>;
/**
 * Adds error handling, logging and limits concurrency.
 *
 * You can use the decorated contract normally, e.g.:
 *     const tx = await contract.createFoobar(123)
 *     return await tx.wait()
 * or
 *     await contract.getFoobar(456)
 */
export declare const createDecoratedContract: <T extends Contract>(contract: Contract, contractName: string, loggerFactory: LoggerFactory, maxConcurrentCalls: number) => ObservableContract<T>;
export declare const queryAllReadonlyContracts: <T, C>(call: (contract: C) => Promise<T>, contracts: C[]) => Promise<T>;
export declare const initContractEventGateway: <TSourcePayloads extends any[], TSourceName extends string, TTargetName extends keyof StreamrClientEvents | keyof InternalEvents>(opts: {
    sourceName: TSourceName;
    targetName: TTargetName;
    sourceEmitter: {
        on: (name: TSourceName, listener: (...args: TSourcePayloads) => void) => void;
        off: (name: TSourceName, listener: (...args: TSourcePayloads) => void) => void;
    };
    targetEmitter: StreamrClientEventEmitter;
    transformation: (...args: TSourcePayloads) => Parameters<(StreamrClientEvents & InternalEvents)[TTargetName]>[0];
    loggerFactory: LoggerFactory;
}) => void;
