/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
/**
 * Globals
 */
/// <reference types="chai" />
/// <reference types="mocha" />

declare type EventEmitter = import("events").EventEmitter;

declare type BN = import("bn.js");
declare type Web3 = import("web3").default;
declare type AbiItem = import("web3-utils").AbiItem;
declare type TransactionConfig = import("web3-core").TransactionConfig;
declare type PromiEvent<T> = import("web3-core").PromiEvent<T>;
declare type TransactionReceipt = import("web3-core").TransactionReceipt;
declare type Web3EventOptions = import("web3-eth-contract").EventOptions;

declare const assert: Chai.AssertStatic;
declare const expect: Chai.ExpectStatic;

declare const web3: Web3;

declare const artifacts: Truffle.Artifacts;

/**
 * Global contract function
 */
interface ContractFunction extends Mocha.SuiteFunction {
  (
    title: string,
    fn: (this: Mocha.Suite, accounts: Truffle.Accounts) => void
  ): Mocha.Suite;
  only: ExclusiveContractFunction;
  skip: PendingContractFunction;
}

interface ExclusiveContractFunction extends Mocha.ExclusiveSuiteFunction {
  (
    title: string,
    fn: (this: Mocha.Suite, accounts: Truffle.Accounts) => void
  ): Mocha.Suite;
}

interface PendingContractFunction extends Mocha.PendingSuiteFunction {
  (
    title: string,
    fn: (this: Mocha.Suite, accounts: Truffle.Accounts) => void
  ): Mocha.Suite | void;
}

declare const contract: ContractFunction;

/**
 * Namespace
 */
declare namespace Truffle {
  type Accounts = string[];

  interface TransactionDetails {
    from?: string;
    gas?: BN | number | string;
    gasPrice?: BN | number | string;
    maxPriorityFeePerGas?: BN | number | string;
    maxFeePerGas?: BN | number | string;
    value?: BN | string;
  }

  export interface TransactionLog<EVENTS extends AnyEvent> {
    address: string;
    event: EVENTS["name"];
    args: EVENTS["args"];
    blockHash: string;
    blockNumber: number;
    logIndex: number;
    transactionHash: string;
    transactionIndex: number;
    type: string;
  }

  export interface TransactionResponse<EVENTS extends AnyEvent> {
    tx: string;
    receipt: any;
    logs: TransactionLog<EVENTS>[];
  }

  export interface AnyEvent {
    name: string;
    args: any;
  }

  interface Contract<T> extends ContractNew<any[]> {
    deployed(): Promise<T>;
    at(address: string): Promise<T>;
    link(name: string, address: string): void;
    link<U>(contract: Contract<U>): void;
    address: string;
    contractName: string;
  }

  interface EventOptions {
    filter?: Web3EventOptions["filter"];
    fromBlock?: Web3EventOptions["fromBlock"];
    topics?: Web3EventOptions["topics"];
  }

  interface ContractInstance {
    address: string;
    contract: any;
    transactionHash: string;
    abi: AbiItem[];
    allEvents(params?: EventOptions): EventEmitter;
    send(
      value: Required<TransactionConfig>["value"],
      txParams?: TransactionConfig
    ): PromiEvent<TransactionReceipt>;
    sendTransaction(
      transactionConfig: TransactionConfig
    ): PromiEvent<TransactionReceipt>;
  }

  interface ContractNew<ARGs extends any[]> {
    "new"(...args: ARGs): any;
  }

  interface Deployer {
    link(
      library: Truffle.Contract<any>,
      destination: Truffle.Contract<any>
    ): Deployer;
    link(
      library: Truffle.Contract<any>,
      destinations: Array<Truffle.Contract<any>>
    ): Deployer;
    deploy<T extends any[]>(c: ContractNew<T>, ...args: T): Deployer;
  }

  type Migration = (
    deploy: Deployer,
    network: string,
    accounts: Accounts
  ) => void;
}
