import { HardhatUserConfig } from 'hardhat/config';
import * as hardhat_types from 'hardhat/types';
import { HardhatNetworkUserConfig } from 'hardhat/types';
import * as hardhat_internal_core_runtime_environment from 'hardhat/internal/core/runtime-environment';
import { Environment } from 'hardhat/internal/core/runtime-environment';
import * as hardhat_deploy_dist_src_DeploymentsManager from 'hardhat-deploy/dist/src/DeploymentsManager';
import { DeploymentsManager } from 'hardhat-deploy/dist/src/DeploymentsManager';
import * as ethers from 'ethers';
import { Signer } from 'ethers';
import * as hardhat_deploy_dist_types from 'hardhat-deploy/dist/types';

interface NetworkUserConfig {
    rpc: string;
    id: number;
    name: string;
    testnet?: boolean;
    icon?: string;
    currency?: Currency;
    verify?: Verify;
    deploy?: Deploy;
    explorer?: Explorer;
}
interface Deploy extends Omit<HardhatNetworkUserConfig, 'chainId' | 'chains' | 'url' | 'verify' | 'accounts'> {
    accounts?: any[];
    [key: string]: any;
}
interface Currency {
    name: string;
    /** 2-6 characters long */
    symbol: string;
    decimals: number;
}
interface Verify {
    uri?: string;
    api?: string;
    key?: string;
}
interface Metadata {
    name: string;
    icon?: string;
}
interface Explorer {
    name: string;
    url: string;
}

interface ProviderForkingConfig {
    forkBlockNumber?: number;
    fork?: string;
}

declare const ethereumProvider: hardhat_types.EthereumProvider;
declare const updateEthereumProvider: (object: hardhat_types.EthereumProvider) => void;
declare const provider: ethers.Provider;
declare const updateProvider: (object: ethers.Provider) => void;
declare const runner: ethers.ContractRunner;
declare const updateRunner: (object: ethers.ContractRunner) => void;
declare const signer: ethers.Signer;
declare const updateSigner: (object: ethers.Signer) => void;
declare const network: NetworkUserConfig & {
    alias: string;
};
declare const updateNetwork: (object: NetworkUserConfig & {
    alias: string;
}) => void;
declare const manager: hardhat_deploy_dist_src_DeploymentsManager.DeploymentsManager;
declare const updateManager: (object: hardhat_deploy_dist_src_DeploymentsManager.DeploymentsManager) => void;
declare const env: hardhat_internal_core_runtime_environment.Environment;
declare const updateEnv: (object: hardhat_internal_core_runtime_environment.Environment) => void;

declare function initial(network: string, forking?: ProviderForkingConfig): Promise<void>;

declare function createManager(env: Environment): DeploymentsManager;

declare function createEnvironment(network?: string, forking?: ProviderForkingConfig): Environment;

declare function getSigners(): Promise<Signer[]>;
declare function getSigner(address: string): Promise<Signer>;
declare function getNamedAccounts(): Promise<{
    [name: string]: string;
}>;
declare function getUnnamedAccounts(): Promise<string[]>;
declare function getNamedAccount(name: string): Promise<string>;
declare function getUnnamedAccount(): Promise<string>;
declare function getNamedSigner(name: string): Promise<Signer>;
declare function getChainId(): Promise<string>;
declare function getArtifact(name: string): Promise<hardhat_types.Artifact>;
declare function getExtendedArtifact(name: string): Promise<hardhat_deploy_dist_types.ExtendedArtifact>;

declare const environment_createEnvironment: typeof createEnvironment;
declare const environment_createManager: typeof createManager;
declare const environment_env: typeof env;
declare const environment_ethereumProvider: typeof ethereumProvider;
declare const environment_getArtifact: typeof getArtifact;
declare const environment_getChainId: typeof getChainId;
declare const environment_getExtendedArtifact: typeof getExtendedArtifact;
declare const environment_getNamedAccount: typeof getNamedAccount;
declare const environment_getNamedAccounts: typeof getNamedAccounts;
declare const environment_getNamedSigner: typeof getNamedSigner;
declare const environment_getSigner: typeof getSigner;
declare const environment_getSigners: typeof getSigners;
declare const environment_getUnnamedAccount: typeof getUnnamedAccount;
declare const environment_getUnnamedAccounts: typeof getUnnamedAccounts;
declare const environment_initial: typeof initial;
declare const environment_manager: typeof manager;
declare const environment_network: typeof network;
declare const environment_provider: typeof provider;
declare const environment_runner: typeof runner;
declare const environment_signer: typeof signer;
declare const environment_updateEnv: typeof updateEnv;
declare const environment_updateEthereumProvider: typeof updateEthereumProvider;
declare const environment_updateManager: typeof updateManager;
declare const environment_updateNetwork: typeof updateNetwork;
declare const environment_updateProvider: typeof updateProvider;
declare const environment_updateRunner: typeof updateRunner;
declare const environment_updateSigner: typeof updateSigner;
declare namespace environment {
  export { environment_createEnvironment as createEnvironment, environment_createManager as createManager, environment_env as env, environment_ethereumProvider as ethereumProvider, environment_getArtifact as getArtifact, environment_getChainId as getChainId, environment_getExtendedArtifact as getExtendedArtifact, environment_getNamedAccount as getNamedAccount, environment_getNamedAccounts as getNamedAccounts, environment_getNamedSigner as getNamedSigner, environment_getSigner as getSigner, environment_getSigners as getSigners, environment_getUnnamedAccount as getUnnamedAccount, environment_getUnnamedAccounts as getUnnamedAccounts, environment_initial as initial, environment_manager as manager, environment_network as network, environment_provider as provider, environment_runner as runner, environment_signer as signer, environment_updateEnv as updateEnv, environment_updateEthereumProvider as updateEthereumProvider, environment_updateManager as updateManager, environment_updateNetwork as updateNetwork, environment_updateProvider as updateProvider, environment_updateRunner as updateRunner, environment_updateSigner as updateSigner };
}

type HarstaRuntimeEnvironment = {
    addresses: Record<string, Record<string, string>>;
} & typeof environment;
type DeploymentArgs = any[] | ((env: HarstaRuntimeEnvironment) => Promise<any[]> | any[]);
interface UserDeploymentConfig {
    /**
     * Specify the chain scope for contract deployment
     */
    chains?: number[];
    /**
     * The deployed target contract name defaults to object key
     */
    target?: string;
    /**
     * Contract upgradable mode
     *
     * @default false
     */
    kind?: 'beacon' | 'uups' | 'transparent' | false;
    /**
     * Constructor for upgradable contracts
     *
     * @default 'initialize'
     */
    initializer?: false | string;
    /**
     * Contract upgradable owner
     *
     * @default signer
     */
    owner?: string;
    /**
     * Initialization parameters for deploying contracts
     *
     */
    args?: DeploymentArgs;
    /**
     * The dependent pre contract, once set, will delay deployment
     *
     */
    dependencies?: string[];
}

interface HarstaPathsConfig {
    /**
     * contracts directory
     *
     * @default 'contracts'
     */
    sources?: string;
    /**
     * addresses and external fragments directory
     *
     * @default 'config'
     */
    config?: string;
    /**
     * contracts exports abi files path
     *
     * @default '.harsta/exports'
     */
    exports?: string;
}
interface HarstaProxyConfig {
    https?: boolean;
    host: string;
    port: number;
}
interface HarstaUserConfig extends Omit<HardhatUserConfig, 'namedAccounts' | 'networks' | 'etherscan' | 'verify' | 'paths'> {
    deployments?: Record<string, UserDeploymentConfig>;
    networks?: Record<string, NetworkUserConfig>;
    paths?: HarstaPathsConfig;
    proxy?: HarstaProxyConfig;
    namedAccounts?: {
        [name: string]: string | number | {
            [network: string]: null | number | string;
        };
    };
}

export type { Currency as C, Deploy as D, Explorer as E, HarstaUserConfig as H, Metadata as M, NetworkUserConfig as N, UserDeploymentConfig as U, Verify as V, HarstaPathsConfig as a, HarstaProxyConfig as b, HarstaRuntimeEnvironment as c, DeploymentArgs as d };
