import { Events, ObservableEventEmitter } from '@streamr/utils';
import type { TransactionResponse } from 'ethers';
import { BaseContract, Contract, ContractTransactionReceipt, ContractTransactionResponse } from 'ethers';
import EventEmitter from 'eventemitter3';
import { LoggerFactory } from '../utils/LoggerFactory';
export interface ContractEvent {
    onMethodExecute: (methodName: string) => void;
    onTransactionSubmit: (methodName: string, tx: ContractTransactionResponse) => void;
    onTransactionConfirm: (methodName: string, receipt: ContractTransactionReceipt | null) => void;
}
export type ObservableContract<T extends BaseContract> = T & {
    eventEmitter: EventEmitter<ContractEvent>;
};
export declare function waitForTx(txToSubmit: Promise<TransactionResponse>): Promise<ContractTransactionReceipt>;
/**
 * 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 BaseContract>(contract: Contract, contractName: string, loggerFactory: LoggerFactory, maxConcurrentCalls: number) => ObservableContract<T>;
export declare const initContractEventGateway: <TSourcePayloads extends any[], TSourceName extends string, TTarget extends Events<TTarget>, TTargetName extends keyof TTarget>(opts: {
    sourceName: TSourceName;
    targetName: TTargetName;
    sourceEmitter: {
        on: (name: TSourceName, listener: (...args: TSourcePayloads) => void) => void;
        off: (name: TSourceName, listener: (...args: TSourcePayloads) => void) => void;
    };
    targetEmitter: ObservableEventEmitter<TTarget>;
    transformation: (...args: TSourcePayloads) => Parameters<TTarget[TTargetName]>[0];
    loggerFactory: LoggerFactory;
}) => void;
