// Code generated by the multiversx-sc proxy generator. DO NOT EDIT.

////////////////////////////////////////////////////
////////////////// AUTO-GENERATED //////////////////
////////////////////////////////////////////////////

#![allow(dead_code)]
#![allow(clippy::all)]

use multiversx_sc::proxy_imports::*;

pub struct MultisigProxy;

impl<Env, From, To, Gas> TxProxyTrait<Env, From, To, Gas> for MultisigProxy
where
    Env: TxEnv,
    From: TxFrom<Env>,
    To: TxTo<Env>,
    Gas: TxGas<Env>,
{
    type TxProxyMethods = MultisigProxyMethods<Env, From, To, Gas>;

    fn proxy_methods(self, tx: Tx<Env, From, To, (), Gas, (), ()>) -> Self::TxProxyMethods {
        MultisigProxyMethods { wrapped_tx: tx }
    }
}

pub struct MultisigProxyMethods<Env, From, To, Gas>
where
    Env: TxEnv,
    From: TxFrom<Env>,
    To: TxTo<Env>,
    Gas: TxGas<Env>,
{
    wrapped_tx: Tx<Env, From, To, (), Gas, (), ()>,
}

#[rustfmt::skip]
impl<Env, From, Gas> MultisigProxyMethods<Env, From, (), Gas>
where
    Env: TxEnv,
    Env::Api: VMApi,
    From: TxFrom<Env>,
    Gas: TxGas<Env>,
{
    pub fn init<
        Arg0: ProxyArg<usize>,
        Arg1: ProxyArg<MultiValueEncoded<Env::Api, ManagedAddress<Env::Api>>>,
    >(
        self,
        quorum: Arg0,
        board: Arg1,
    ) -> TxTypedDeploy<Env, From, NotPayable, Gas, ()> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_deploy()
            .argument(&quorum)
            .argument(&board)
            .original_result()
    }
}

#[rustfmt::skip]
impl<Env, From, To, Gas> MultisigProxyMethods<Env, From, To, Gas>
where
    Env: TxEnv,
    Env::Api: VMApi,
    From: TxFrom<Env>,
    To: TxTo<Env>,
    Gas: TxGas<Env>,
{
    pub fn upgrade<
        Arg0: ProxyArg<usize>,
        Arg1: ProxyArg<MultiValueEncoded<Env::Api, ManagedAddress<Env::Api>>>,
    >(
        self,
        quorum: Arg0,
        board: Arg1,
    ) -> TxTypedUpgrade<Env, From, To, NotPayable, Gas, ()> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_upgrade()
            .argument(&quorum)
            .argument(&board)
            .original_result()
    }
}

#[rustfmt::skip]
impl<Env, From, To, Gas> MultisigProxyMethods<Env, From, To, Gas>
where
    Env: TxEnv,
    Env::Api: VMApi,
    From: TxFrom<Env>,
    To: TxTo<Env>,
    Gas: TxGas<Env>,
{
    /// Allows the contract to receive funds even if it is marked as unpayable in the protocol. 
    pub fn deposit(
        self,
    ) -> TxTypedCall<Env, From, To, (), Gas, ()> {
        self.wrapped_tx
            .raw_call("deposit")
            .original_result()
    }

    /// Returns `true` (`1`) if the user has signed the action. 
    /// Does not check whether or not the user is still a board member and the signature valid. 
    pub fn signed<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
        Arg1: ProxyArg<usize>,
    >(
        self,
        user: Arg0,
        action_id: Arg1,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, bool> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("signed")
            .argument(&user)
            .argument(&action_id)
            .original_result()
    }

    /// Used by board members to sign actions. 
    pub fn sign<
        Arg0: ProxyArg<usize>,
    >(
        self,
        action_id: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, ()> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("sign")
            .argument(&action_id)
            .original_result()
    }

    /// Board members can withdraw their signatures if they no longer desire for the action to be executed. 
    /// Actions that are left with no valid signatures can be then deleted to free up storage. 
    pub fn unsign<
        Arg0: ProxyArg<usize>,
    >(
        self,
        action_id: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, ()> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("unsign")
            .argument(&action_id)
            .original_result()
    }

    /// Clears storage pertaining to an action that is no longer supposed to be executed. 
    /// Any signatures that the action received must first be removed, via `unsign`. 
    /// Otherwise this endpoint would be prone to abuse. 
    pub fn discard_action<
        Arg0: ProxyArg<usize>,
    >(
        self,
        action_id: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, ()> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("discardAction")
            .argument(&action_id)
            .original_result()
    }

    /// Minimum number of signatures needed to perform any action. 
    pub fn quorum(
        self,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("getQuorum")
            .original_result()
    }

    /// Denormalized board member count. 
    /// It is kept in sync with the user list by the contract. 
    pub fn num_board_members(
        self,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("getNumBoardMembers")
            .original_result()
    }

    /// Denormalized proposer count. 
    /// It is kept in sync with the user list by the contract. 
    pub fn num_proposers(
        self,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("getNumProposers")
            .original_result()
    }

    /// The index of the last proposed action. 
    /// 0 means that no action was ever proposed yet. 
    pub fn get_action_last_index(
        self,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("getActionLastIndex")
            .original_result()
    }

    /// Initiates board member addition process. 
    /// Can also be used to promote a proposer to board member. 
    pub fn propose_add_board_member<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
    >(
        self,
        board_member_address: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeAddBoardMember")
            .argument(&board_member_address)
            .original_result()
    }

    /// Initiates proposer addition process.. 
    /// Can also be used to demote a board member to proposer. 
    pub fn propose_add_proposer<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
    >(
        self,
        proposer_address: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeAddProposer")
            .argument(&proposer_address)
            .original_result()
    }

    /// Removes user regardless of whether it is a board member or proposer. 
    pub fn propose_remove_user<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
    >(
        self,
        user_address: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeRemoveUser")
            .argument(&user_address)
            .original_result()
    }

    pub fn propose_change_quorum<
        Arg0: ProxyArg<usize>,
    >(
        self,
        new_quorum: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeChangeQuorum")
            .argument(&new_quorum)
            .original_result()
    }

    /// Propose a transaction in which the contract will perform a transfer-execute call. 
    /// Can send EGLD without calling anything. 
    /// Can call smart contract endpoints directly. 
    /// Doesn't really work with builtin functions. 
    pub fn propose_transfer_execute<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
        Arg1: ProxyArg<BigUint<Env::Api>>,
        Arg2: ProxyArg<FunctionCall<Env::Api>>,
    >(
        self,
        to: Arg0,
        egld_amount: Arg1,
        function_call: Arg2,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeTransferExecute")
            .argument(&to)
            .argument(&egld_amount)
            .argument(&function_call)
            .original_result()
    }

    /// Propose a transaction in which the contract will perform a transfer-execute call. 
    /// Can call smart contract endpoints directly. 
    /// Can use ESDTTransfer/ESDTNFTTransfer/MultiESDTTransfer to send tokens, while also optionally calling endpoints. 
    /// Works well with builtin functions. 
    /// Cannot simply send EGLD directly without calling anything. 
    pub fn propose_async_call<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
        Arg1: ProxyArg<BigUint<Env::Api>>,
        Arg2: ProxyArg<FunctionCall<Env::Api>>,
    >(
        self,
        to: Arg0,
        egld_amount: Arg1,
        function_call: Arg2,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeAsyncCall")
            .argument(&to)
            .argument(&egld_amount)
            .argument(&function_call)
            .original_result()
    }

    pub fn propose_sc_deploy_from_source<
        Arg0: ProxyArg<BigUint<Env::Api>>,
        Arg1: ProxyArg<ManagedAddress<Env::Api>>,
        Arg2: ProxyArg<CodeMetadata>,
        Arg3: ProxyArg<MultiValueEncoded<Env::Api, ManagedBuffer<Env::Api>>>,
    >(
        self,
        amount: Arg0,
        source: Arg1,
        code_metadata: Arg2,
        arguments: Arg3,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeSCDeployFromSource")
            .argument(&amount)
            .argument(&source)
            .argument(&code_metadata)
            .argument(&arguments)
            .original_result()
    }

    pub fn propose_sc_upgrade_from_source<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
        Arg1: ProxyArg<BigUint<Env::Api>>,
        Arg2: ProxyArg<ManagedAddress<Env::Api>>,
        Arg3: ProxyArg<CodeMetadata>,
        Arg4: ProxyArg<MultiValueEncoded<Env::Api, ManagedBuffer<Env::Api>>>,
    >(
        self,
        sc_address: Arg0,
        amount: Arg1,
        source: Arg2,
        code_metadata: Arg3,
        arguments: Arg4,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("proposeSCUpgradeFromSource")
            .argument(&sc_address)
            .argument(&amount)
            .argument(&source)
            .argument(&code_metadata)
            .argument(&arguments)
            .original_result()
    }

    /// Returns `true` (`1`) if `getActionValidSignerCount >= getQuorum`. 
    pub fn quorum_reached<
        Arg0: ProxyArg<usize>,
    >(
        self,
        action_id: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, bool> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("quorumReached")
            .argument(&action_id)
            .original_result()
    }

    /// Proposers and board members use this to launch signed actions. 
    pub fn perform_action_endpoint<
        Arg0: ProxyArg<usize>,
    >(
        self,
        action_id: Arg0,
    ) -> TxTypedCall<Env, From, To, NotPayable, Gas, OptionalValue<ManagedAddress<Env::Api>>> {
        self.wrapped_tx
            .payment(NotPayable)
            .raw_call("performAction")
            .argument(&action_id)
            .original_result()
    }

    pub fn dns_register<
        Arg0: ProxyArg<ManagedAddress<Env::Api>>,
        Arg1: ProxyArg<ManagedBuffer<Env::Api>>,
    >(
        self,
        dns_address: Arg0,
        name: Arg1,
    ) -> TxTypedCall<Env, From, To, (), Gas, ()> {
        self.wrapped_tx
            .raw_call("dnsRegister")
            .argument(&dns_address)
            .argument(&name)
            .original_result()
    }
}

#[type_abi]
#[derive(TopEncode)]
pub struct ActionFullInfo<Api>
where
    Api: ManagedTypeApi,
{
    pub action_id: usize,
    pub action_data: Action<Api>,
    pub signers: ManagedVec<Api, ManagedAddress<Api>>,
}

#[rustfmt::skip]
#[type_abi]
#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone)]
pub enum Action<Api>
where
    Api: ManagedTypeApi,
{
    Nothing,
    AddBoardMember(ManagedAddress<Api>),
    AddProposer(ManagedAddress<Api>),
    RemoveUser(ManagedAddress<Api>),
    ChangeQuorum(usize),
    SendTransferExecute(CallActionData<Api>),
    SendAsyncCall(CallActionData<Api>),
    SCDeployFromSource {
        amount: BigUint<Api>,
        source: ManagedAddress<Api>,
        code_metadata: CodeMetadata,
        arguments: ManagedVec<Api, ManagedBuffer<Api>>,
    },
    SCUpgradeFromSource {
        sc_address: ManagedAddress<Api>,
        amount: BigUint<Api>,
        source: ManagedAddress<Api>,
        code_metadata: CodeMetadata,
        arguments: ManagedVec<Api, ManagedBuffer<Api>>,
    },
}

#[type_abi]
#[derive(NestedEncode, NestedDecode, Clone)]
pub struct CallActionData<Api>
where
    Api: ManagedTypeApi,
{
    pub to: ManagedAddress<Api>,
    pub egld_amount: BigUint<Api>,
    pub endpoint_name: ManagedBuffer<Api>,
    pub arguments: ManagedVec<Api, ManagedBuffer<Api>>,
}

#[type_abi]
#[derive(TopEncode, TopDecode)]
pub enum UserRole {
    None,
    Proposer,
    BoardMember,
}
