import { RpcInterface } from '@polkadot/rpc-core/jsonrpc.types';
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { AnyFunction, ModulesWithCalls } from '@polkadot/types/types';
import { ApiInterfaceRx, ApiOptions, ApiTypes, DecorateMethod, DecoratedRpc, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics } from '../types';
import BN from 'bn.js';
import { BehaviorSubject } from 'rxjs';
import { ExactDerive } from '@polkadot/api-derive';
import { Constants } from '@polkadot/api-metadata/consts/types';
import { Storage } from '@polkadot/api-metadata/storage/types';
import RpcCore from '@polkadot/rpc-core';
import { Metadata } from '@polkadot/types';
import { DeriveAllSections } from '../util/decorate';
import Events from './Events';
export default abstract class Decorate<ApiType> extends Events {
    protected __phantom: BN;
    protected _consts?: Constants;
    protected _derive?: ReturnType<Decorate<ApiType>['decorateDerive']>;
    protected _extrinsics?: SubmittableExtrinsics<ApiType>;
    protected _extrinsicType: number;
    protected _genesisHash?: Hash;
    protected _isConnected: BehaviorSubject<boolean>;
    protected _isReady: boolean;
    protected readonly _options: ApiOptions;
    protected _query?: QueryableStorage<ApiType>;
    protected _queryMulti?: QueryableStorageMulti<ApiType>;
    protected _rpc?: DecoratedRpc<ApiType, RpcInterface>;
    protected _rpcCore: RpcCore;
    protected _runtimeMetadata?: Metadata;
    protected _runtimeVersion?: RuntimeVersion;
    protected _rx: Partial<ApiInterfaceRx>;
    protected _type: ApiTypes;
    /**
     * This is the one and only method concrete children classes need to implement.
     * It's a higher-order function, which takes one argument
     * `method: Method extends (...args: any[]) => Observable<any>`
     * (and one optional `options`), and should return the user facing method.
     * For example:
     * - For ApiRx, `decorateMethod` should just be identity, because the input
     * function is already an Observable
     * - For ApiPromise, `decorateMethod` should return a function that takes all
     * the parameters from `method`, adds an optional `callback` argument, and
     * returns a Promise.
     *
     * We could easily imagine other user-facing interfaces, which are simply
     * implemented by transforming the Observable to Stream/Iterator/Kefir/Bacon
     * via `deocrateMethod`.
     */
    protected decorateMethod: DecorateMethod<ApiType>;
    /**
     * @description Create an instance of the class
     *
     * @param options Options object to create API instance or a Provider instance
     *
     * @example
     * <BR>
     *
     * ```javascript
     * import Api from '@polkadot/api/promise';
     *
     * const api = new Api().isReady();
     *
     * api.rpc.subscribeNewHeads((header) => {
     *   console.log(`new block #${header.number.toNumber()}`);
     * });
     * ```
     */
    constructor(options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>);
    /**
     * @returns `true` if the API operates with subscriptions
     */
    readonly hasSubscriptions: boolean;
    private decorateFunctionMeta;
    protected filterRpc(): Promise<void>;
    protected filterRpcMethods(methods: string[]): void;
    protected decorateRpc<ApiType>(rpc: RpcCore, decorateMethod: DecorateMethod<ApiType>): DecoratedRpc<ApiType, RpcInterface>;
    protected decorateMulti<ApiType>(decorateMethod: DecorateMethod<ApiType>): QueryableStorageMulti<ApiType>;
    protected decorateExtrinsics<ApiType>(extrinsics: ModulesWithCalls, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType>;
    private decorateExtrinsicEntry;
    protected decorateStorage<ApiType>(storage: Storage, decorateMethod: DecorateMethod<ApiType>): QueryableStorage<ApiType>;
    private decorateStorageEntry;
    private decorateStorageEntryLinked;
    protected decorateDerive(apiRx: ApiInterfaceRx, decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<ApiType, ExactDerive>;
    /**
     * Put the `this.onCall` function of ApiRx here, because it is needed by
     * `api._rx`.
     */
    protected rxDecorateMethod: <Method extends AnyFunction>(method: Method) => Method;
}
