import BigNumber from 'bignumber.js';
import { AbiVersion, VmVersion } from '../tx/builder/constants.js';
import { SignTx, ChannelState, ChannelOptions } from './internal.js';
import { Encoded } from '../utils/encoder.js';
import { ContractCallObjectReturnType } from '../apis/node/index.js';
import { ContractCallObject } from '../contract/Contract.js';
import ChannelSpend from './Spend.js';
interface CallContractOptions {
    /**
     * Amount the caller of the contract commits to it
     */
    amount?: number | BigNumber;
    /**
     * ABI encoded compiled AEVM call data for the code
     */
    callData?: Encoded.ContractBytearray;
    /**
     * Version of the ABI
     */
    abiVersion?: AbiVersion;
    /**
     * Address of the contract to call
     */
    contract?: Encoded.ContractAddress;
}
interface CallContractResult extends CallContractOptions {
    returnValue?: any;
    gasUsed?: number | BigNumber;
    gasPrice?: number | BigNumber;
    height?: number;
    callerNonce?: number;
    log?: any;
    returnType?: ContractCallObjectReturnType;
}
interface Contract {
    abiVersion: AbiVersion;
    active: boolean;
    deposit: number | BigNumber;
    id: string;
    ownerId: string;
    referrerIds: string[];
    vmVersion: VmVersion;
}
/**
 * @category state channel
 */
export default class ChannelContract extends ChannelSpend {
    static initialize(options: ChannelOptions): Promise<ChannelContract>;
    /**
     * Trigger create contract update
     *
     * The create contract update is creating a contract inside the channel's internal state tree.
     * The update is a change to be applied on top of the latest state.
     *
     * That would create a contract with the poster being the owner of it. Poster commits initially
     * a deposit amount of coins to the new contract.
     *
     * @param options - Options
     * @param options.code - Api encoded compiled AEVM byte code
     * @param options.callData - Api encoded compiled AEVM call data for the code
     * @param options.deposit - Initial amount the owner of the contract commits to it
     * @param options.vmVersion - Version of the Virtual Machine
     * @param options.abiVersion - Version of the Application Binary Interface
     * @param sign - Function which verifies and signs create contract transaction
     * @example
     * ```js
     * channel.createContract({
     *   code: 'cb_HKtpipK4aCgYb17wZ...',
     *   callData: 'cb_1111111111111111...',
     *   deposit: 10,
     *   vmVersion: 3,
     *   abiVersion: 1
     * }).then(({ accepted, signedTx, address }) => {
     *   if (accepted) {
     *     console.log('New contract has been created')
     *     console.log('Contract address:', address)
     *   } else {
     *     console.log('New contract has been rejected')
     *   }
     * })
     * ```
     */
    createContract({ code, callData, deposit, vmVersion, abiVersion, }: {
        code: Encoded.ContractBytearray;
        callData: Encoded.ContractBytearray;
        deposit: number | BigNumber;
        vmVersion: VmVersion;
        abiVersion: AbiVersion;
    }, sign: SignTx): Promise<{
        accepted: boolean;
        signedTx: Encoded.Transaction;
        address: Encoded.ContractAddress;
    }>;
    /**
     * Trigger call a contract update
     *
     * The call contract update is calling a preexisting contract inside the channel's
     * internal state tree. The update is a change to be applied on top of the latest state.
     *
     * That would call a contract with the poster being the caller of it. Poster commits
     * an amount of coins to the contract.
     *
     * The call would also create a call object inside the channel state tree. It contains
     * the result of the contract call.
     *
     * It is worth mentioning that the gas is not consumed, because this is an off-chain
     * contract call. It would be consumed if it were an on-chain one. This could happen
     * if a call with a similar computation amount is to be forced on-chain.
     *
     * @param options - Options
     * @param sign - Function which verifies and signs contract call transaction
     * @example
     * ```js
     * channel.callContract({
     *   contract: 'ct_9sRA9AVE4BYTAkh5RNfJYmwQe1NZ4MErasQLXZkFWG43TPBqa',
     *   callData: 'cb_1111111111111111...',
     *   amount: 0,
     *   abiVersion: 1
     * }).then(({ accepted, signedTx }) => {
     *   if (accepted) {
     *     console.log('Contract called succesfully')
     *   } else {
     *     console.log('Contract call has been rejected')
     *   }
     * })
     * ```
     */
    callContract({ amount, callData, contract, abiVersion }: CallContractOptions, sign: SignTx): Promise<{
        accepted: boolean;
        signedTx: Encoded.Transaction;
    }>;
    /**
     * Trigger a force progress contract call
     * This call is going on-chain
     * @param options - Options
     * @param sign - Function which verifies and signs contract force progress transaction
     * @param callbacks - Callbacks
     * @example
     * ```js
     * channel.forceProgress({
     *   contract: 'ct_9sRA9AVE4BYTAkh5RNfJYmwQe1NZ4MErasQLXZkFWG43TPBqa',
     *   callData: 'cb_1111111111111111...',
     *   amount: 0,
     *   abiVersion: 1,
     *   gasPrice: 1000005554
     * }).then(({ accepted, signedTx }) => {
     *   if (accepted) {
     *     console.log('Contract force progress call successful')
     *   } else {
     *     console.log('Contract force progress call has been rejected')
     *   }
     * })
     * ```
     */
    forceProgress({ amount, callData, contract, abiVersion, gasLimit, gasPrice, }: CallContractOptions & {
        gasLimit?: number;
        gasPrice?: number;
    }, sign: SignTx, { onOnChainTx }?: Pick<ChannelState, 'onOnChainTx'>): Promise<{
        accepted: boolean;
        signedTx: Encoded.Transaction;
        tx: Encoded.Transaction | Uint8Array;
    }>;
    /**
     * Call contract using dry-run
     *
     * In order to get the result of a potential contract call, one might need to
     * dry-run a contract call. It takes the exact same arguments as a call would
     * and returns the call object.
     *
     * The call is executed in the channel's state, but it does not impact the state
     * whatsoever. It uses as an environment the latest channel's state and the current
     * top of the blockchain as seen by the node.
     *
     * @param options - Options
     * @example
     * ```js
     * channel.callContractStatic({
     *   contract: 'ct_9sRA9AVE4BYTAkh5RNfJYmwQe1NZ4MErasQLXZkFWG43TPBqa',
     *   callData: 'cb_1111111111111111...',
     *   amount: 0,
     *   abiVersion: 1
     * }).then(({ returnValue, gasUsed }) => {
     *   console.log('Returned value:', returnValue)
     *   console.log('Gas used:', gasUsed)
     * })
     * ```
     */
    callContractStatic({ amount, callData, contract, abiVersion, }: CallContractOptions): Promise<CallContractResult>;
    /**
     * Get contract call result
     *
     * The combination of a caller, contract and a round of execution determines the
     * contract call. Providing an incorrect set of those results in an error response.
     *
     * @param options - Options
     * @param options.caller - Address of contract caller
     * @param options.contract - Address of the contract
     * @param options.round - Round when contract was called
     * @example
     * ```js
     * channel.getContractCall({
     *   caller: 'ak_Y1NRjHuoc3CGMYMvCmdHSBpJsMDR6Ra2t5zjhRcbtMeXXLpLH',
     *   contract: 'ct_9sRA9AVE4BYTAkh5RNfJYmwQe1NZ4MErasQLXZkFWG43TPBqa',
     *   round: 3
     * }).then(({ returnType, returnValue }) => {
     *   if (returnType === 'ok') console.log(returnValue)
     * })
     * ```
     */
    getContractCall({ caller, contract, round, }: {
        caller: Encoded.AccountAddress;
        contract: Encoded.ContractAddress;
        round: number;
    }): Promise<ContractCallObject>;
    /**
     * Get the latest contract state
     *
     * @param contract - Address of the contract
     * @example
     * ```js
     * channel.getContractState(
     *   'ct_9sRA9AVE4BYTAkh5RNfJYmwQe1NZ4MErasQLXZkFWG43TPBqa'
     * ).then(({ contract }) => {
     *   console.log('deposit:', contract.deposit)
     * })
     * ```
     */
    getContractState(contract: Encoded.ContractAddress): Promise<{
        contract: Contract;
        contractState: object;
    }>;
    /**
     * Clean up all locally stored contract calls
     *
     * Contract calls are kept locally in order for the participant to be able to look them up.
     * They consume memory and in order for the participant to free it - one can prune all messages.
     * This cleans up all locally stored contract calls and those will no longer be available for
     * fetching and inspection.
     */
    cleanContractCalls(): Promise<void>;
}
export {};
