import { BigNumber } from "bignumber.js" ; import { Address , Hash } from "../commonTypes" ; import { ContractWrapperBase } from "../contractWrapperBase" ; import { ContractWrapperFactory } from "../contractWrapperFactory" ; import { ArcTransactionProposalResult , ArcTransactionResult , DecodedLogEntryEvent , IContractWrapperFactory } from "../iContractWrapperBase" ; import { LoggingService } from "../loggingService" ; import { TxGeneratingFunctionOptions } from "../transactionService" ; import { Utils } from "../utils" ; import { EventFetcherFactory , Web3EventService } from "../web3EventService" ; import { CancelProposalEventResult , CancelVotingEventResult , ExecuteProposalEventResult , GetAllowedRangeOfChoicesResult , IIntVoteInterface , NewProposalEventResult , OwnerVoteOptions , ProposalIdOption , ProposeOptions , VoteOptions , VoteProposalEventResult , VoteStatusOptions , VoteWithSpecifiedAmountsOptions } from "./iIntVoteInterface" ; /**
 * Provides the services of any voting machine that implements the `IntVoteInterface`
 * Arc contract interface.  Also serves as the base class for all the specific
 * voting machine contract wrapper classes.
 */ export class IntVoteInterfaceWrapper extends ContractWrapperBase implements IIntVoteInterface { public factory : IContractWrapperFactory < any > = IntVoteInterfaceFactory ; public name : string = "IntVoteInterface" ; public friendlyName : string = "IntVoteInterface" ; /**
     * Get or watch events fired on the creation of a new proposal.
     */ public NewProposal : EventFetcherFactory < NewProposalEventResult > ; /**
     * Get or watch events fired when a vote is cancelled.
     * Note you won't get this from GenesisProtocol whose proposals and votes are not cancellable
     */ public CancelProposal : EventFetcherFactory < CancelProposalEventResult > ; /**
     * Get or watch events fired when proposals have been executed
     */ public ExecuteProposal : EventFetcherFactory < ExecuteProposalEventResult > ; /**
     * Get or watch events fired whenever votes are cast on a proposal
     */ public VoteProposal : EventFetcherFactory < VoteProposalEventResult > ; /**
     * Get or watch events fired when a voter's vote is cancelled.
     * Note you won't get this from GenesisProtocol whose proposals and votes are not cancellable
     */ public CancelVoting : EventFetcherFactory < CancelVotingEventResult > ; /**
     * Get or watch NewProposal events, filtering out proposals that are no longer votable.
     */ public get VotableProposals ( ) : EventFetcherFactory < NewProposalEventResult > { return this . web3EventService . createEventFetcherFactory < NewProposalEventResult > ( this . contract . NewProposal , ( error , log ) => { if ( ! error ) { log = log . filter ( async ( event ) => { const proposalId = event . args . _proposalId ; return await this . isVotable ( { proposalId } ) ; } ) ; } return { error , log } ; } ) ; } param options public async propose ( options ) { if ( ! options . organizationAddress ) { LoggingService . warn ( `IntVoteInterface.propose: organizationAddress is not set, will be set to msg.sender` ) ; } const numChoiceBounds = await this . getAllowedRangeOfChoices ( ) ; if ( ! Number . isInteger ( options . numOfChoices ) ) { throw new Error ( `numOfChoices must be a number` ) ; } if ( options . numOfChoices < numChoiceBounds . minVote ) { throw new Error ( `numOfChoices cannot be less than ${ numChoiceBounds . minVote }` ) ; } if ( options . numOfChoices > numChoiceBounds . maxVote ) { throw new Error ( `numOfChoices cannot be greater than ${ numChoiceBounds . maxVote }` ) ; } if ( ! options . proposalParameters ) { throw new Error ( `proposalParameters is not set` ) ; } if ( ! options . proposerAddress ) { options . proposerAddress = Utils . NULL_ADDRESS ; } this . logContractFunctionCall ( "IntVoteInterface.propose" , options ) ; const txResult = await this . wrapTransactionInvocation ( "IntVoteInterface.propose" , options , this . contract . propose , [ options . numOfChoices , options . proposalParameters , options . proposerAddress ] ) ; return new ArcTransactionProposalResult ( txResult . tx , this . contract , this ) ; } param options public async cancelProposal ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } this . logContractFunctionCall ( "IntVoteInterface.cancelProposal" , options ) ; return this . wrapTransactionInvocation ( "IntVoteInterface.cancelProposal" , options , this . contract . cancelProposal , [ options . proposalId ] ) ; } param options public async ownerVote ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } await this . _validateVote ( options . vote , options . proposalId ) ; if ( ! options . voterAddress ) { throw new Error ( `voterAddress is not defined` ) ; } this . logContractFunctionCall ( "IntVoteInterface.ownerVote" , options ) ; return this . wrapTransactionInvocation ( "IntVoteInterface.ownerVote" , options , this . contract . ownerVote , [ options . proposalId , options . vote , options . voterAddress ] ) ; } param options public async vote ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } await this . _validateVote ( options . vote , options . proposalId ) ; this . logContractFunctionCall ( "IntVoteInterface.vote" , options ) ; return this . wrapTransactionInvocation ( "IntVoteInterface.vote" , options , this . contract . vote , [ options . proposalId , options . vote , options . voterAddress || 0 ] ) ; } param options public async voteWithSpecifiedAmounts ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } await this . _validateVote ( options . vote , options . proposalId ) ; this . logContractFunctionCall ( "IntVoteInterface.voteWithSpecifiedAmounts" , options ) ; return this . wrapTransactionInvocation ( "IntVoteInterface.voteWithSpecifiedAmounts" , options , this . contract . voteWithSpecifiedAmounts , [ options . proposalId , options . vote , options . reputation , new BigNumber ( 0 ) , options . voterAddress || 0 ] ) ; } param options public async cancelVote ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } this . logContractFunctionCall ( "IntVoteInterface.cancelVote" , options ) ; return this . wrapTransactionInvocation ( "IntVoteInterface.cancelVote" , options , this . contract . cancelVote , [ options . proposalId ] ) ; } param options public async getNumberOfChoices ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } this . logContractFunctionCall ( "IntVoteInterface.getNumberOfChoices" , options ) ; return ( await this . contract . getNumberOfChoices ( options . proposalId ) ) . toNumber ( ) ; } param proposalId public async isVotable ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } this . logContractFunctionCall ( "IntVoteInterface.isVotable" , options ) ; return await this . contract . isVotable ( options . proposalId ) ; } param options public async voteStatus ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } await this . _validateVote ( options . vote , options . proposalId ) ; this . logContractFunctionCall ( "IntVoteInterface.voteStatus" , options ) ; return await this . contract . voteStatus ( options . proposalId , options . vote ) ; } /**
     * get whether voters are allowed to cast an abstaining vote on these proposals.
     */ public async isAbstainAllow ( ) { this . logContractFunctionCall ( "IntVoteInterface.isAbstainAllow" ) ; return await this . contract . isAbstainAllow ( ) ; } param proposalId public async execute ( options ) { if ( ! options . proposalId ) { throw new Error ( `proposalId is not defined` ) ; } this . logContractFunctionCall ( "IntVoteInterface.execute" , options ) ; return this . wrapTransactionInvocation ( "IntVoteInterface.execute" , options , this . contract . execute , [ options . proposalId ] ) ; } param proposalId public async getCurrentVoteStatus ( proposalId ) { let numChoices = await this . getNumberOfChoices ( { proposalId } ) ; const abstainAllowed = await this . isAbstainAllow ( ) ; if ( ! abstainAllowed ) { ++ numChoices ; } const voteTotals = new Array < BigNumber > ( numChoices ) ; for ( let choice = 0 ; choice < numChoices ; ++ choice ) { const voteTotal = await this . voteStatus ( { vote : choice , proposalId } ) ; voteTotals [ choice ] = voteTotal ; } return voteTotals ; } /**
     * Returns promise of the allowed range of choices for a voting machine.
     */ public async getAllowedRangeOfChoices ( ) { const result = await this . contract . getAllowedRangeOfChoices ( ) ; return { maxVote : result [ 1 ] . toNumber ( ) , minVote : result [ 0 ] . toNumber ( ) , } ; } protected hydrated ( ) { this . NewProposal = this . web3EventService . createEventFetcherFactory < NewProposalEventResult > ( this . contract . NewProposal ) ; this . CancelProposal = this . web3EventService . createEventFetcherFactory < CancelProposalEventResult > ( this . contract . CancelProposal ) ; this . ExecuteProposal = this . web3EventService . createEventFetcherFactory < ExecuteProposalEventResult > ( this . contract . ExecuteProposal ) ; this . VoteProposal = this . web3EventService . createEventFetcherFactory < VoteProposalEventResult > ( this . contract . VoteProposal ) ; this . CancelVoting = this . web3EventService . createEventFetcherFactory < CancelVotingEventResult > ( this . contract . CancelVoting ) ; } protected async _validateVote ( vote , proposalId ) { const numChoices = await this . getNumberOfChoices ( { proposalId } ) ; if ( ! Number . isInteger ( vote ) || ( vote < 0 ) || ( vote > numChoices ) ) { throw new Error ( "vote choice is not valid" ) ; } if ( ( typeof vote !== "number" ) || ( vote < 0 ) ) { throw new Error ( `vote must be a number greater than or equal to zero and less than or equal to ${ numChoices }` ) ; } } protected organizationIdFromProposalCreator ( schemeAddress , creator ) { return Utils . keccak256 ( [ "address" , "address" ] , [ schemeAddress , creator ] ) ; } } export class IntVoteInterfaceFactoryType extends ContractWrapperFactory < IntVoteInterfaceWrapper > { public async new ( ) { throw new Error ( "`new` is not supported on IntVoteInterface. Only `at` is supported." ) ; } public async deployed ( ) { throw new Error ( "`deployed` is not supported on IntVoteInterface. Only `at` is supported." ) ; } } export const IntVoteInterfaceFactory = new IntVoteInterfaceFactoryType ( "IntVoteInterface" , IntVoteInterfaceWrapper , new Web3EventService ( ) ) as IntVoteInterfaceFactoryType ;