import { Address, QuantityInterface } from '@melonproject/token-math';
import { Contracts } from '../../Contracts';
import { Environment } from '../environment/Environment';
import { OptionsOrCallback, Options } from './prepareTransaction';
export declare type TransactionArg = number | number[] | string | string[];
export declare type TransactionArgs = TransactionArg[] | any;
export interface UnsignedRawTransaction {
    from: string;
    to?: string;
    value?: string;
    gas?: string;
    gasPrice?: string;
    data?: string;
    nonce?: string;
}
export interface MelonTransaction<Args> {
    amguInEth: QuantityInterface;
    params: Args;
    rawTransaction: UnsignedRawTransaction;
    signedTransaction?: string;
    transactionArgs: TransactionArgs;
}
export declare type GuardFunction<Args> = (environment: Environment, params?: Args, contractAddress?: Address, options?: Options) => Promise<void>;
export declare type PrepareArgsFunction<Args> = (environment: Environment, params: Args, contractAddress?: Address) => Promise<TransactionArgs>;
export declare type PostProcessFunction<Args, Result> = (environment: Environment, receipt: any, params?: Args, contractAddress?: Address) => Promise<Result>;
export declare type TransactionFactory = <Args, Result>(name: string, contract: Contracts, guard?: GuardFunction<Args>, prepareArgs?: PrepareArgsFunction<Args>, postProcess?: PostProcessFunction<Args, Result>, defaultOptions?: OptionsOrCallback) => EnhancedExecute<Args, Result>;
declare type SendFunction<Args> = (environment: Environment, contractAddress: Address, signedTransactionData: string, params?: Args, options?: OptionsOrCallback) => Promise<any>;
declare type PrepareFunction<Args> = (environment: Environment, contractAddress: Address, params?: Args, options?: OptionsOrCallback) => Promise<MelonTransaction<Args>>;
declare type ExecuteFunction<Args, Result> = (environment: Environment, contractAddress: Address, params?: Args, options?: OptionsOrCallback) => Promise<Result>;
export interface ExecuteMixin<Args> {
    send: SendFunction<Args>;
    prepare: PrepareFunction<Args>;
}
export declare type EnhancedExecute<Args, Result> = ExecuteFunction<Args, Result> & ExecuteMixin<Args>;
export interface WithTransactionDecoratorOptions<Args, Result> {
    guard?: GuardFunction<Args>;
    prepareArgs?: PrepareArgsFunction<Args>;
    postProcess?: PostProcessFunction<Args, Result>;
    options?: OptionsOrCallback;
}
export declare type WithTransactionDecorator = <Args, Result>(transaction: EnhancedExecute<Args, Result>, decorator: WithTransactionDecoratorOptions<Args, Result>) => EnhancedExecute<Args, Result>;
export declare const defaultGuard: GuardFunction<any>;
export declare const defaultPrepareArgs: PrepareArgsFunction<any>;
export declare const defaultPostProcess: PostProcessFunction<any, any>;
/**
 * The transaction factory returns a function "execute" (You have to rename it
 * to the actual name of the transaction, for example: "transfer"). As a
 * minimum, one needs to provide the transaction name and the contract path:
 *
 * ```typescript
 * const transfer = transactionFactory('transfer', Contract.Token);
 * ```
 *
 * This transfer function can then be executed directly:
 *
 * ```typescript
 * await transfer(new Address('0xdeadbeef'));
 * ```
 *
 * Or sliced into a prepare and a send part:
 * ```typescript
 * const preparedTransaction: PreparedTransaction =
 *    await transfer.prepare(new Address('0xdeadbeef'));
 *
 * // pass that prepared transaction to the signer
 * const result = await transfer.send(new Address('0xdeadbeef'),
 *    preparedTransaction);
 * ```
 */
declare const transactionFactory: TransactionFactory;
export { transactionFactory };
