import { EthApi , requireAccount } from "@joincivil/ethapi" ; import { CivilErrors , getDefaultFromBlock , is0x0Address , pollHelpers , listingHelpers } from "@joincivil/utils" ; import { EthAddress , ListingWrapper , BigNumber , UserChallengeData , WrappedChallengeData , WrappedAppealChallengeID , WrappedChallengeID , } from "@joincivil/typescript-types" ; import * as Debug from "debug" ; import { Observable } from "rxjs/Observable" ; import { ContentProvider } from "../../content/contentprovider" ; import { TwoStepEthTransaction } from "../../types" ; import { BaseWrapper } from "../basewrapper" ; import { CivilTCRMultisigProxy } from "../generated/multisig/civil_t_c_r" ; import { CivilTCRContract } from "../generated/wrappers/civil_t_c_r" ; import { MultisigProxyTransaction } from "../multisig/basemultisigproxy" ; import { Challenge } from "./challenge" ; import { Council } from "./council" ; import { CVLToken } from "./cvltoken" ; import { Government } from "./government" ; import { Listing } from "./listing" ; import { Parameterizer } from "./parameterizer" ; import { Voting } from "./voting" ; import { TransactionConfig } from "web3-core" ; const debug = Debug ( "civil:tcr" ) ; /**
 * The CivilTCR tracks the status of addresses that have been applied and allows
 * users to make transactions that modify the state of the TCR.
 *
 * Users can get stream of currently approved addresses, as well as specific information
 * about individual listings (may or may not be approved)
 *
 * Users can also apply to the registry, challenge applications or listings, as well
 * as collect winnings related to challenges, or withdraw/deposit tokens from listings.
 *
 * NOTE: If instantiated with a multisig wallet, *all* transactions are proxied through multisig.
 */ export class CivilTCR extends BaseWrapper < CivilTCRContract > { public static async singleton ( ethApi , contentProvider ) { const instance = await CivilTCRContract . singletonTrusted ( ethApi ) ; if ( ! instance ) { debug ( "Smart-contract wrapper for TCR returned null, unsupported network" ) ; throw new Error ( CivilErrors . UnsupportedNetwork ) ; } const multisigProxyDummy = CivilTCRMultisigProxy . createNonMultisig ( ethApi , instance ) ; const network = await ethApi . network ( ) ; const defaultBlock = getDefaultFromBlock ( network ) ; return new CivilTCR ( ethApi , contentProvider , instance , multisigProxyDummy , await Voting . singleton ( ethApi ) , defaultBlock ) ; } public static async singletonMultisigProxy ( ethApi , contentProvider , multisigAddress ? ) { const instance = await CivilTCRContract . singletonTrusted ( ethApi ) ; if ( ! instance ) { debug ( "Smart-contract wrapper for TCR returned null, unsupported network" ) ; throw new Error ( CivilErrors . UnsupportedNetwork ) ; } const multisigProxy = await CivilTCRMultisigProxy . create ( ethApi , instance , multisigAddress ) ; const defaultBlock = getDefaultFromBlock ( await ethApi . network ( ) ) ; return new CivilTCR ( ethApi , contentProvider , instance , multisigProxy , await Voting . singleton ( ethApi ) , defaultBlock ) ; } private contentProvider : ContentProvider ; private voting : Voting ; /** If instantiated with `multisigAddress` undefined, proxy will send transactions directly to the contract instance. */ private multisigProxy : CivilTCRMultisigProxy ; private constructor ( ethApi , contentProvider , instance , multisigProxy , voting , defaultBlock ) { super ( ethApi , instance , defaultBlock ) ; this . contentProvider = contentProvider ; this . multisigProxy = multisigProxy ; this . voting = voting ; this . defaultBlock = defaultBlock ; } /**
     * Get address for voting contract used with this TCR
     */ public async getVotingAddress ( ) { return this . instance . voting . callAsync ( ) ; } /**
     * Get Voting instance used with this TCR
     */ public getVoting ( ) { return this . voting ; } /**
     * Returns Parameterizer instance associated with this TCR
     */ public async getParameterizer ( ) { return Parameterizer . atUntrusted ( this . ethApi , await this . getParameterizerAddress ( ) ) ; } public async getGovernment ( ) { return Government . atUntrusted ( this . ethApi , await this . getGovernmentAddress ( ) ) ; } public async getCouncil ( ) { return Council . singleton ( this . ethApi ) ; } /**
     * Get address for token used with this TCR
     */ public async getTokenAddress ( ) { return this . instance . token . callAsync ( ) ; } public async getGovernmentAddress ( ) { return this . instance . government . callAsync ( ) ; } /**
     * Get Token instance used with this TCR
     */ public async getToken ( ) { if ( this . multisigProxy . multisigEnabled ) { return CVLToken . atUntrusted ( this . ethApi , await this . getTokenAddress ( ) , await this . multisigProxy . getMultisigAddress ( ) ) ; } else { return CVLToken . atUntrusted ( this . ethApi , await this . getTokenAddress ( ) ) ; } } /**
     * Get address for parameterizer contract used with this TCR
     */ public async getParameterizerAddress ( ) { return this . instance . parameterizer . callAsync ( ) ; } param fromBlock returns public allEventsExceptWhitelistFromBlock ( fromBlock = this . defaultBlock , toBlock ? ) { return Observable . merge ( this . instance . _ApplicationStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _AppealRequestedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _AppealGrantedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _FailedChallengeOverturnedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _SuccessfulChallengeOverturnedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _GrantedAppealChallengedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _GrantedAppealOverturnedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _GrantedAppealConfirmedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _DepositStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _WithdrawalStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _ApplicationRemovedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _ListingRemovedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _ListingWithdrawnStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _TouchAndRemovedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _ChallengeFailedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) , this . instance . _ChallengeSucceededStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) ; } param fromBlock returns public allEventsFromBlock ( fromBlock = this . defaultBlock , toBlock ? ) { return Observable . merge ( this . allEventsExceptWhitelistFromBlock ( fromBlock , toBlock ) , this . instance . _ApplicationWhitelistedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) ) ; } param fromBlock returns public whitelistedListings ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ApplicationWhitelistedStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) ; } param fromBlock returns public listingsInApplicationStage ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ApplicationStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) ; } param fromBlock returns public readyToBeWhitelistedListings ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ApplicationStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . canBeWhitelisted ( l . data ) ) ; } param fromBlock returns public currentChallengedCommitVotePhaseListings ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . isInChallengedCommitVotePhase ( l . data ) ) ; } param fromBlock returns public currentChallengedRevealVotePhaseListings ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . isInChallengedRevealVotePhase ( l . data ) ) ; } param fromBlock returns public listingsAwaitingAppealRequest ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . isAwaitingAppealRequest ( l . data ) ) ; } public listingsWithChallengeToResolve ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . canChallengeBeResolved ( l . data ) ) ; } param fromBlock returns public listingsAwaitingAppealJudgment ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . isListingAwaitingAppealJudgment ( l . data ) ) ; } param fromBlock returns public listingsAwaitingAppealChallenge ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . isListingAwaitingAppealChallenge ( l . data ) ) ; } param fromBlock returns public listingsInAppealChallengeCommitPhase ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . isInAppealChallengeCommitPhase ( l . data ) ) ; } param fromBlock returns public listingsInAppealChallengeRevealPhase ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . isInAppealChallengeRevealPhase ( l . data ) ) ; } param fromBlock returns public listingsWithAppealToResolve ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ChallengeStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => listingHelpers . canListingAppealBeResolved ( l . data ) ) ; } param fromBlock returns public rejectedListings ( fromBlock = this . defaultBlock , toBlock ? ) { return this . instance . _ApplicationStream ( { } , { fromBlock , toBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) . concatFilter ( l => l . data . appExpiry . isZero ( ) ) ; } public allApplicationsEver ( ) { return this . instance . _ApplicationStream ( { } , { fromBlock : this . defaultBlock } ) . map ( e => new Listing ( this . ethApi , this . instance , e . returnValues . listingAddress , this . defaultBlock ) ) . concatMap ( async ( l ) => l . getListingWrapper ( ) ) ; } public allChallengeIDsEver ( ) { return this . instance . _ChallengeStream ( { } , { fromBlock : this . defaultBlock } ) . map ( e => { return { listingAddress : e . returnValues . listingAddress , challengeID : new BigNumber ( e . returnValues . challengeID ) , } ; } ) ; } public allAppealChallengeIDsEver ( ) { return this . instance . _GrantedAppealChallengedStream ( { } , { fromBlock : this . defaultBlock } ) . map ( e => { return { listingAddress : e . returnValues . listingAddress , appealChallengeToChallengeID : { appealChallengeID : new BigNumber ( e . returnValues . appealChallengeID ) , challengeID : new BigNumber ( e . returnValues . challengeID ) , } , } ; } ) ; } public challengesStartedByUser ( user ) { return this . instance . _ChallengeStream ( { challenger : user } , { fromBlock : this . defaultBlock } ) . map ( e => new BigNumber ( e . returnValues . challengeID ) ) ; } param fromBlock param user public rewardsCollected ( fromBlock = this . defaultBlock , user ? , toBlock ? ) { return this . instance . _RewardClaimedStream ( { voter : user } , { fromBlock , toBlock } ) . map ( e => new BigNumber ( e . returnValues . challengeID ) ) ; } public getListing ( listingAddress ) { return new Listing ( this . ethApi , this . instance , listingAddress , this . defaultBlock ) ; } public async getRawGrantAppealTxData ( listingAddress ) { return this . instance . grantAppeal . getRaw ( listingAddress , "" , { gas : 0 } ) ; } public async getChallengeIDForPollID ( pollID ) { const [ , challenger ] = await this . instance . challenges . callAsync ( pollID . toString ( ) ) ; if ( challenger && challenger !== "" && ! is0x0Address ( challenger ) ) { const challengeStream = this . instance . _ChallengeStream ( { challengeID : pollID } , { fromBlock : this . defaultBlock } ) ; const appealChallengeStream = this . instance . _GrantedAppealChallengedStream ( { appealChallengeID : pollID } , { fromBlock : this . defaultBlock } ) ; const event = await challengeStream . merge ( appealChallengeStream ) . first ( ) . toPromise ( ) ; return new BigNumber ( event . returnValues . challengeID ) ; } else { return this . ethApi . toBigNumber ( 0 ) ; } } public async getChallengeData ( challengeID , listingAddr ? ) { const challenge = new Challenge ( this . ethApi , this . instance , challengeID ) ; let listingAddress = listingAddr ; if ( ! listingAddress ) { listingAddress = await challenge . getListingIdForChallenge ( ) ; } const challengeData = await challenge . getChallengeData ( ) ; return { listingAddress , challengeID : new BigNumber ( challengeID ) , challenge : challengeData , } ; } public async getUserAppealChallengeData ( appealChallengeID , user ) { let didUserCommit ; let didUserReveal ; let didUserCollect ; let didUserRescue = false ; let didCollectAmount ; let isVoterWinner ; let salt ; let numTokens ; let choice ; let voterReward ; const [ , , resolved ] = await this . instance . challenges . callAsync ( appealChallengeID . toString ( ) ) ; const pollData = await this . voting . getPoll ( appealChallengeID ) ; let canUserReveal ; let canUserRescue ; let canUserCollect ; if ( user ) { didUserCommit = await this . voting . didCommitVote ( user , appealChallengeID ) ; if ( didUserCommit ) { didUserReveal = await this . voting . didRevealVote ( user , appealChallengeID ) ; if ( resolved ) { if ( didUserReveal ) { const reveal = await this . voting . getRevealedVoteEvent ( appealChallengeID , user ) ; salt = reveal ! . returnValues . salt ; numTokens = reveal ! . returnValues . numTokens ; choice = reveal ! . returnValues . choice ; didUserCollect = await this . instance . tokenClaims . callAsync ( appealChallengeID . toString ( ) , user ) ; isVoterWinner = await this . voting . isVoterWinner ( appealChallengeID , user ) ; canUserCollect = isVoterWinner && ! didUserCollect ; } else { didUserRescue = ! ( await this . voting . canRescueTokens ( user , appealChallengeID ) ) ; } } else { canUserReveal = ! didUserReveal && ( await pollHelpers . isInRevealStage ( pollData ) ) ; } canUserRescue = ! didUserReveal && ! didUserRescue && ! ( await pollHelpers . isInCommitStage ( pollData ) ) && ! ( await pollHelpers . isInRevealStage ( pollData ) ) ; } } if ( didUserCollect ) { didCollectAmount = await this . getRewardClaimed ( appealChallengeID , user ) ; } if ( isVoterWinner && ! didUserCollect ) { voterReward = await this . voterReward ( appealChallengeID , new BigNumber ( salt as string ) , user ) ; } return { didUserCommit , didUserReveal , canUserReveal , didUserCollect , canUserCollect , didUserRescue , canUserRescue , didCollectAmount , isVoterWinner , salt : new BigNumber ( salt as string ) , numTokens : new BigNumber ( numTokens as string ) , choice : new BigNumber ( choice as string ) , voterReward , } ; } public async getUserChallengeData ( challengeID , user ) { let didUserCommit ; let didUserReveal ; let didUserCollect ; let didUserRescue = false ; let didCollectAmount ; let isVoterWinner ; let salt ; let numTokens ; let choice ; let voterReward ; const challenge = new Challenge ( this . ethApi , this . instance , challengeID ) ; const challengeData = await challenge . getChallengeData ( ) ; const resolved = challengeData . resolved ; const pollData = await this . voting . getPoll ( challengeID ) ; let canUserReveal ; let canUserRescue ; let canUserCollect ; if ( user ) { didUserCommit = await this . voting . didCommitVote ( user , challengeID ) ; if ( didUserCommit ) { didUserReveal = await this . voting . didRevealVote ( user , challengeID ) ; if ( resolved ) { if ( didUserReveal ) { const reveal = await this . voting . getRevealedVoteEvent ( challengeID , user ) ; salt = reveal ! . returnValues . salt ; numTokens = reveal ! . returnValues . numTokens ; choice = reveal ! . returnValues . choice ; didUserCollect = await this . instance . tokenClaims . callAsync ( challengeID . toString ( ) , user ) ; if ( challengeData . appeal && challengeData . appeal . appealGranted ) { if ( challengeData . appeal . appealChallenge && challengeData . appeal . appealChallenge . resolved && ( await this . voting . isPollPassed ( new BigNumber ( challengeData . appeal . appealChallengeID ) ) ) ) { isVoterWinner = await this . voting . isVoterWinner ( challengeID , user ) ; } else { isVoterWinner = ! ( await this . voting . isVoterWinner ( challengeID , user ) ) ; } } else { isVoterWinner = await this . voting . isVoterWinner ( challengeID , user ) ; } canUserCollect = isVoterWinner && ! didUserCollect ; } else { didUserRescue = ! ( await this . voting . canRescueTokens ( user , challengeID ) ) ; } } else { canUserReveal = ! didUserReveal && ( await pollHelpers . isInRevealStage ( pollData ) ) ; } canUserRescue = ! didUserReveal && ! didUserRescue && ! ( await pollHelpers . isInCommitStage ( pollData ) ) && ! ( await pollHelpers . isInRevealStage ( pollData ) ) ; } } if ( didUserCollect ) { didCollectAmount = await this . getRewardClaimed ( challengeID , user ) ; } if ( isVoterWinner && ! didUserCollect ) { voterReward = await this . voterReward ( challengeID , new BigNumber ( salt as string ) , user ) ; } return { didUserCommit , didUserReveal , canUserReveal , didUserCollect , canUserCollect , didUserRescue , canUserRescue , didCollectAmount , isVoterWinner , salt : new BigNumber ( salt as string ) , numTokens : new BigNumber ( numTokens as string ) , choice : new BigNumber ( choice as string ) , voterReward , } ; } public async getRewardClaimed ( challengeID , user ) { const reward = await this . instance . _RewardClaimedStream ( { challengeID , voter : user } , { fromBlock : this . defaultBlock } ) . first ( ) . toPromise ( ) ; return new BigNumber ( reward . returnValues . reward ) ; } /**
     * Contract Getters
     */ param challengeID param salt param voter public async voterReward ( challengeID , salt , voter ? ) { let who = voter ; if ( ! who ) { who = await requireAccount ( this . ethApi ) . toPromise ( ) ; } return this . instance . voterReward . callAsync ( who , challengeID . toString ( ) , salt . toString ( ) ) . then ( e => new BigNumber ( e ) ) ; } param address public async determineReward ( challengeID ) { return this . instance . determineReward . callAsync ( challengeID . toString ( ) ) . then ( e => new BigNumber ( e ) ) ; } param challengeID param address public async hasClaimedTokens ( challengeID , voter ? ) { let who = voter ; if ( ! who ) { who = await requireAccount ( this . ethApi ) . toPromise ( ) ; } return this . instance . tokenClaims . callAsync ( challengeID . toString ( ) , who ) ; } /**
     * Contract Transactions
     */ param address param deposit param applicationContent public async apply ( listingAddress , deposit , applicationContent ) { return this . applyWithURI ( listingAddress , deposit , "" ) ; } param address param deposit param applicationContentURI public async applyWithURI ( listingAddress , deposit , applicationContentURI ) { return this . multisigProxy . apply . sendTransactionAsync ( listingAddress , deposit . toString ( ) , applicationContentURI ) ; } param address param depositAmount public async deposit ( listingAddress , depositAmount ) { return this . multisigProxy . deposit . sendTransactionAsync ( listingAddress , depositAmount . toString ( ) ) ; } param address param withdrawalAmount public async withdraw ( listingAddress , withdrawalAmount ) { return this . multisigProxy . withdraw . sendTransactionAsync ( listingAddress , withdrawalAmount . toString ( ) ) ; } param address public async exitListing ( listingAddress ) { return this . multisigProxy . exit . sendTransactionAsync ( listingAddress ) ; } param listingAddress param data public async challenge ( listingAddress , data = "" ) { const { uri } = await this . contentProvider . put ( data ) ; return this . challengeWithURI ( listingAddress , uri ) ; } public async requestAppeal ( listingAddress , data = "" ) { const { uri } = await this . contentProvider . put ( data ) ; return this . requestAppealWithURI ( listingAddress , uri ) ; } public async grantAppeal ( listingAddress , data = "" ) { return this . multisigProxy . grantAppeal . sendTransactionAsync ( listingAddress , data ) ; } public async challengeGrantedAppeal ( listingAddress , data = "" ) { return this . multisigProxy . challengeGrantedAppeal . sendTransactionAsync ( listingAddress , data ) ; } public async challengeGrantedAppealWithURI ( listingAddress , uri = "" ) { return this . multisigProxy . challengeGrantedAppeal . sendTransactionAsync ( listingAddress , uri ) ; } param address param data public async challengeWithURI ( listingAddress , data = "" ) { return this . multisigProxy . challenge . sendTransactionAsync ( listingAddress , data ) ; } param address param data public async requestAppealWithURI ( listingAddress , data = "" ) { return this . multisigProxy . requestAppeal . sendTransactionAsync ( listingAddress , data ) ; } param address public async updateStatus ( listingAddress ) { return this . multisigProxy . updateStatus . sendTransactionAsync ( listingAddress ) ; } param challengeID param salt public async claimReward ( challengeID , salt ) { return this . multisigProxy . claimReward . sendTransactionAsync ( challengeID . toString ( ) , salt . toString ( ) ) ; } param challengeIDs param salts public async multiClaimReward ( challengeIDs , salts ) { return this . multisigProxy . claimRewards . sendTransactionAsync ( challengeIDs . map ( e => e . toString ( ) ) , salts . map ( e => e . toString ( ) ) ) ; } }