import { AppABIEncodings , AppInstanceInfo , AppInstanceJson , MultiAssetMultiPartyCoinTransferInterpreterParams , Node , SolidityValueType , TwoPartyFixedOutcomeInterpreterParams } from "@counterfactual/types" ; import { BigNumber } from "ethers/utils" ; import EventEmitter from "eventemitter3" ; import { Provider } from "./provider" ; import { CounterfactualEvent } from "./types" ; export enum AppInstanceEventType { UPDATE_STATE = "updateState" , UNINSTALL = "uninstall" , ERROR = "error" } /**
 * Represents an installed app instance
 */ export class AppInstance { /**
     * Unique ID of this app instance.
     */ readonly identityHash : string ; readonly appDefinition : string ; readonly abiEncodings : AppABIEncodings ; readonly timeout : BigNumber ; readonly initiatorDeposit : BigNumber ; readonly responderDeposit : BigNumber ; readonly intermediaryIdentifier ? : string ; /**
     * Interpreter-related Fields
     */ readonly twoPartyOutcomeInterpreterParams ? : TwoPartyFixedOutcomeInterpreterParams ; readonly multiAssetMultiPartyCoinTransferInterpreterParams ? : MultiAssetMultiPartyCoinTransferInterpreterParams ; private readonly eventEmitter : EventEmitter = new EventEmitter ( ) ; private readonly validEventTypes = Object . keys ( AppInstanceEventType ) . map ( key => AppInstanceEventType [ key ] ) ; constructor ( info , readonly provider ) { this . identityHash = info . identityHash ; if ( info [ "appInterface" ] !== undefined ) { this . appDefinition = info [ "appInterface" ] . addr ; this . abiEncodings = { stateEncoding : info [ "appInterface" ] . stateEncoding , actionEncoding : info [ "appInterface" ] . actionEncoding } ; this . timeout = info [ "defaultTimeout" ] ; } else { this . appDefinition = info [ "appDefinition" ] ; this . abiEncodings = info [ "abiEncodings" ] ; this . timeout = info [ "timeout" ] ; } this . initiatorDeposit = info [ "initiatorDeposit" ] ; this . responderDeposit = info [ "responderDeposit" ] ; this . intermediaryIdentifier = info [ "intermediaryIdentifier" ] ; } /**
     * Whether this app is virtual i.e. installation was routed through intermediaryIdentifier
     */ get isVirtual ( ) : boolean { return ! ! this . intermediaryIdentifier ; } async return async getState ( ) { const response = await this . provider . callRawNodeMethod ( Node . RpcMethodName . GET_STATE , { appInstanceId : this . identityHash } ) ; const result = response . result as Node . GetStateResult ; return result . state ; } note async param action return async takeAction ( action ) { const response = await this . provider . callRawNodeMethod ( Node . RpcMethodName . TAKE_ACTION , { action , appInstanceId : this . identityHash } ) ; const result = response . result as Node . TakeActionResult ; return result . newState ; } async async uninstall ( ) { await this . provider . callRawNodeMethod ( this . intermediaryIdentifier ? Node . RpcMethodName . UNINSTALL_VIRTUAL : Node . RpcMethodName . UNINSTALL , { intermediaryIdentifier : this . intermediaryIdentifier , appInstanceId : this . identityHash } ) ; } param eventType param callback on ( eventType , callback ) { this . validateEventType ( eventType ) ; this . eventEmitter . on ( eventType , callback ) ; } param eventType param callback once ( eventType , callback ) { this . validateEventType ( eventType ) ; this . eventEmitter . once ( eventType , callback ) ; } param eventType param callback off ( eventType , callback ) { this . validateEventType ( eventType ) ; this . eventEmitter . off ( eventType , callback ) ; } ignore private validateEventType ( eventType ) { if ( ! this . validEventTypes . includes ( eventType ) ) { throw new Error ( `"${ eventType }" is not a valid event` ) ; } } ignore emit ( eventType , event ) { this . eventEmitter . emit ( eventType , event ) ; } }