import { DecodedLogEntryEvent, LogTopic } from "web3";
import { fnVoid } from "./commonTypes";
import { IEventSubscription } from "./pubSubEventService";
/**
 * Support for working with events that originate from Arc contracts
 * and are served up by Web3.
 *
 * For more information, see [Web3 Events](/Events.md#web3events).
 */
export declare class Web3EventService {
    /**
     * Returns a function that creates an EventFetcher<TEventArgs>.
     * For subclasses to use to create their event handlers.
     * This is identical to what you get with Truffle, except with enhancements.
     *
     * Note that the callback parameter of `EventFetcher.get` is optional; you
     * may alternatively obtain the promise of a `Array<TEventArgs>` from the return value
     * of `get`.
     *
     * For more information, see [Web3 Events](/Events.md#web3events).
     *
     * @param baseEvent - the event from the Truffle contract.
     * @param preProcessEvent - optionally supply this to modify the err and log arguments before they are
     * passed to the `get`/`watch` callback.
     * @param baseArgFilter arg filter to always merge into any supplied argFilter.
     * @type TEventArgs - name of the event args (EventResult) interface, like NewProposalEventResult
     */
    createEventFetcherFactory<TEventArgs>(baseEvent: any, preProcessEvent?: PreProcessEventCallback<TEventArgs>, baseArgFilter?: any): EventFetcherFactory<TEventArgs>;
    /**
     * Converts a `EventFetcherFactory<TEventArgs>` into a
     * `EntityFetcherFactory<TEntity, TEventArgs>`.  So whenever a web3 event
     * is received by the given `EventFetcherFactory`, we transform the `TEventArgs`
     * into `TEntities`.
     *
     * Note that the callback parameter of `EntityFetcher.get` is optional; you
     * may alternatively obtain the promise of a `Array<TEntity>` from the return value
     * of `get`.
     *
     * See [Arc Web3 Events in Arc.js](/Events.md#web3events).
     *
     * @param eventFetcherFactory
     * @param transformEventCallback Function to convert an instance of TEventArgs into
     * the promise of an instance of TEntity.  If it returns `undefined` then no entity
     * is returned for that event, so this is a programatic way in which events
     * can be filtered.
     * @param givenCallback Function that will be invoked upon the receipt of each event,
     * @param baseArgFilter arg filter to always merge into any supplied argFilter.
     */
    createEntityFetcherFactory<TEntity, TEventArgs>(eventFetcherFactory: EventFetcherFactory<TEventArgs>, transformEventCallback: TransformEventCallback<TEntity, TEventArgs>, baseArgFilter?: any): EntityFetcherFactory<TEntity, TEventArgs>;
    /**
     * Returns a function that we will use internally to handle each Web3 event
     * @param suppressDups
     * @param preProcessEvent
     */
    private createBaseWeb3EventHandler;
}
export interface EventPreProcessorReturn<TEventArgs> {
    error: Error;
    log: Array<DecodedLogEntryEvent<TEventArgs>>;
}
export declare type PreProcessEventCallback<TEventArgs> = (error: Error, log: Array<DecodedLogEntryEvent<TEventArgs>>) => EventPreProcessorReturn<TEventArgs>;
export declare type TransformEventCallback<TDest, TSrc> = (event: DecodedLogEntryEvent<TSrc>) => Promise<TDest | undefined>;
/**
 * Function that returns an `EntityFetcher<TEntity>`.
 *
 * @type TEntity The type returns to the callback.
 */
export declare type EntityFetcherFactory<TDest, TSrc> = (
/**
 * Arg values by which you wish to filter the web3 event logs, e.g.
 * `{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}`.
 *
 * Note this always applies to the underlying web3 event values
 * not to property values of transformed entities.
 */
argsFilter?: any, 
/**
 * Web3 event filter options.  Typically something like `{ fromBlock: 0 }`.
 * Note if you don't want Arc.js to suppress duplicate events, set `suppressDups` to false.
 */
filterObject?: EventFetcherFilterObject, 
/**
 * Optional callback to immediately start start watching.
 * Without this you will call `get` or `watch`.
 */
callback?: EntityWatchCallback<TDest>, 
/**
 * Optional and only used when callback is supplied. If set
 * then will not invoke the callback until the transaction has been mined to the requiredDepth.
 */
requiredDepth?: number) => EntityFetcher<TDest, TSrc>;
export declare type EntityWatchCallback<TEntity> = (error: Error, entity: TEntity) => void;
export declare type EntityGetCallback<TEntity> = (error: Error, entity: Promise<Array<TEntity>>) => void;
export declare type EntityWatchSubscriptionCallback<TEntity> = (eventName: string, payload: TEntity) => void;
/**
 * Returned by EntityFetcherFactory<TDest, TSrc>.
 */
export interface EntityFetcher<TDest, TSrc> {
    /**
     * Get an array of `TDest` from Web3, given the filter supplied to the EntityFetcherFactory.
     * You may supply a callback, which will be given the array, or you may
     * accept the promise of the array from the return value of `get`.
     * If `requiredDepth` is set then will not invoke the callback until the transaction has been mined to
     * the requiredDepth.
     */
    get: (callback?: EntityGetCallback<TDest>, requiredDepth?: number) => Promise<Array<TDest>>;
    /**
     * Watch for `TDest`s from Web3, given the filter supplied to the EntityFetcherFactory.
     * The callback is invoked once per event firing.
     * If `requiredDepth` is set then will not invoke the callback until the transaction has been mined to
     * the requiredDepth.
     */
    watch: (callback: EntityWatchCallback<TDest>, requiredDepth?: number) => void;
    /**
     * Watch for `TDest`s from Web3, given the filter supplied to the EntityFetcherFactory.
     * The Pub.Sub is published once per event firing.
     * `subscribe` returns the subscription on which you must remember to call `unsubscribe` when you are
     * done watching.
     * If `requiredDepth` is set then will not invoke the callback until the transaction has been mined to
     * the requiredDepth.
     *
     * Supply whatever name you want for `eventName`.  This enables you to scope
     * event handlers across event types and schemes.
     */
    subscribe: (eventName: string, callback?: EntityWatchSubscriptionCallback<TDest>, requiredDepth?: number) => IEventSubscription;
    /**
     * Stop watching the event.
     */
    stopWatching(callback?: fnVoid): void;
    /**
     * Asynchronously stop watching the event, for environments where
     * synchronous methods are not allowed.
     */
    stopWatchingAsync(): Promise<void>;
}
/**
 * Function that returns an `EventFetcher<TEventArgs>`.
 *
 * @type TEventArgs The type of the `args` object.
 */
export declare type EventFetcherFactory<TEventArgs> = (
/**
 * Values by which you wish to filter the logs, e.g.
 * `{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}`.
 */
argsFilter?: any, 
/**
 * Additional filter options.  Typically something like `{ fromBlock: 0 }`.
 * Note if you don't want Arc.js to suppress duplicate events, set `suppressDups` to false.
 */
filterObject?: EventFetcherFilterObject, 
/**
 * Optional callback to immediately start start watching.
 * Without this you will call `get` or `watch`.
 */
callback?: EventWatchCallback<TEventArgs>, 
/**
 * Optional and only used when callback is supplied. If set
 * then will not invoke the callback until the transaction has been mined to the requiredDepth.
 */
requiredDepth?: number) => EventFetcher<TEventArgs>;
export declare type EventWatchCallback<TEventArgs> = (error: Error, args: DecodedLogEntryEvent<TEventArgs>) => void;
export declare type EventGetCallback<TEventArgs> = (error: Error, args: Array<DecodedLogEntryEvent<TEventArgs>>) => void;
export declare type EventWatchSubscriptionCallback<TEventArgs> = (eventName: string, payload: DecodedLogEntryEvent<TEventArgs>) => void;
/**
 * Returned by EventFetcherFactory<TEventArgs>.
 * See web3 documentation article for more information about events:
 * https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-events
 *
 * @type TEventArgs The type of the `args` object.
 */
export interface EventFetcher<TEventArgs> {
    /**
     * Get an array of `DecodedLogEntryEvent` from Web3, given the filter supplied to the EventFetcherFactory.
     * You may supply a callback, which will be given the array, or you may
     * accept the promise of the array from the return value of `get`.
     * If `requiredDepth` is set then will not invoke the callback until the transaction has been mined to
     * the requiredDepth.
     */
    get: (callback?: EventGetCallback<TEventArgs>, requiredDepth?: number) => Promise<Array<DecodedLogEntryEvent<TEventArgs>>>;
    /**
     * Watch for `DecodedLogEntryEvent`s from Web3, given the filter supplied to the EventFetcherFactory.
     * The callback is invoked once per event firing.
     * If `requiredDepth` is set then will not invoke the callback until the transaction has been mined to
     * the requiredDepth.
     */
    watch: (callback: EventWatchCallback<TEventArgs>, requiredDepth?: number) => void;
    /**
     * Watch for `DecodedLogEntryEvent`s from Web3, given the filter supplied to the EventFetcherFactory.
     * The Pub.Sub is published once per event firing.
     * `subscribe` returns the subscription on which you must remember to call `unsubscribe` when you are
     * done watching.
     * If `requiredDepth` is set then will not invoke the callback until the transaction has been mined to
     * the requiredDepth.
     *
     * Supply whatever name you want for `eventName`.  This enables you to scope
     * event handlers across event types and schemes.
     */
    subscribe: (eventName: string, callback?: EventWatchSubscriptionCallback<TEventArgs>, requiredDepth?: number) => IEventSubscription;
    /**
     * Stop watching the event.
     */
    stopWatching(callback?: fnVoid): void;
    /**
     * Asynchronously stop watching the event, for environments where
     * synchronous methods are not allowed.
     */
    stopWatchingAsync(): Promise<void>;
}
/**
 * As implemented by Web3
 */
export interface Web3EventFetcher {
    get: (callback: (error: Error, args: DecodedLogEntryEvent<any> | Array<DecodedLogEntryEvent<any>>) => void) => void;
    watch: (callback: (error: Error, args: DecodedLogEntryEvent<any> | Array<DecodedLogEntryEvent<any>>) => void) => void;
    stopWatching(callback?: fnVoid): void;
    stopWatchingAsync(): Promise<void>;
}
/**
 * Haven't figured out how to export EventFetcherFilterObject that extends FilterObject from web3.
 * Maybe will be easier with web3 v1.0, or perhaps using typescript's module augmentation feature.
 */
/**
 * Options supplied to `EventFetcherFactory` and thence to `get` and `watch`.
 */
export interface EventFetcherFilterObject {
    fromBlock?: number | string;
    toBlock?: number | string;
    address?: string;
    topics?: Array<LogTopic>;
    /**
     * true to suppress duplicate events (see https://github.com/ethereum/web3.js/issues/398).
     * The default is true.
     */
    suppressDups?: boolean;
}
export declare class Web3EventSubscription<TEventArgs> implements IEventSubscription {
    private subscription;
    private fetcher;
    constructor(subscription: IEventSubscription, fetcher: EventFetcher<TEventArgs>);
    /**
     * Unsubscribe from all of the events
     * @param milliseconds number of milliseconds to timeout.
     * Default is -1 which means not to timeout at all.
     */
    unsubscribe(milliseconds?: number): Promise<void>;
}
