import { Provider } from "ethers/providers" ; import { UNASSIGNED_SEQ_NO } from "../constants" ; import { SetStateCommitment } from "../ethereum" ; import { StateChannel , StateChannelJSON } from "../models" ; import { xkeyKthAddress } from "." ; import { Opcode , Protocol } from "./enums" ; import { Context , ProtocolExecutionFlow , ProtocolMessage , UninstallParams } from "./types" ; import { computeTokenIndexedFreeBalanceIncrements } from "./utils/get-outcome-increments" ; import { assertIsValidSignature } from "./utils/signature-validator" ; const protocol = Protocol . Uninstall ; const { OP_SIGN , IO_SEND , IO_SEND_AND_WAIT } = Opcode ; description export const UNINSTALL_PROTOCOL = { 0 : async function * ( context ) { const { message , provider , store , network } = context ; const { sharedData : { stateChannelsMap } } = store ; const { params , processID } = message ; const { responderXpub , appIdentityHash } = params as UninstallParams ; const responderAddress = xkeyKthAddress ( responderXpub , 0 ) ; const postProtocolStateChannel = await computeStateTransition ( params as UninstallParams , stateChannelsMap , provider ) ; const uninstallCommitment = new SetStateCommitment ( network , postProtocolStateChannel . freeBalance . identity , postProtocolStateChannel . freeBalance . hashOfLatestState , postProtocolStateChannel . freeBalance . versionNumber , postProtocolStateChannel . freeBalance . timeout ) ; const signature = yield [ OP_SIGN , uninstallCommitment ] ; const { customData : { signature : responderSignature } } = yield [ IO_SEND_AND_WAIT , { protocol , processID , params , toXpub : responderXpub , customData : { signature } , seq : 1 } as ProtocolMessage ] ; assertIsValidSignature ( responderAddress , uninstallCommitment , responderSignature ) ; const finalCommitment = uninstallCommitment . getSignedTransaction ( [ signature , responderSignature ] ) ; await store . setCommitment ( [ protocol , appIdentityHash ] , finalCommitment ) ; await store . saveStateChannel ( postProtocolStateChannel ) ; } , 1 : async function * ( context ) { const { message , provider , store , network } = context ; const { sharedData : { stateChannelsMap } } = store ; const { params , processID } = message ; const { initiatorXpub , appIdentityHash } = params as UninstallParams ; const initiatorAddress = xkeyKthAddress ( initiatorXpub , 0 ) ; const postProtocolStateChannel = await computeStateTransition ( params as UninstallParams , stateChannelsMap , provider ) ; const uninstallCommitment = new SetStateCommitment ( network , postProtocolStateChannel . freeBalance . identity , postProtocolStateChannel . freeBalance . hashOfLatestState , postProtocolStateChannel . freeBalance . versionNumber , postProtocolStateChannel . freeBalance . timeout ) ; const initiatorSignature = context . message . customData . signature ; assertIsValidSignature ( initiatorAddress , uninstallCommitment , initiatorSignature ) ; const responderSignature = yield [ OP_SIGN , uninstallCommitment ] ; const finalCommitment = uninstallCommitment . getSignedTransaction ( [ responderSignature , initiatorSignature ] ) ; await store . setCommitment ( [ protocol , appIdentityHash ] , finalCommitment ) ; await store . saveStateChannel ( postProtocolStateChannel ) ; yield [ IO_SEND , { protocol , processID , toXpub : initiatorXpub , seq : UNASSIGNED_SEQ_NO , customData : { signature : responderSignature } } as ProtocolMessage ] ; } } ; async function computeStateTransition ( params , stateChannelsMap , provider ) { const { appIdentityHash , multisigAddress } = params ; const stateChannel = StateChannel . fromJson ( stateChannelsMap [ multisigAddress ] ) ; return stateChannel . uninstallApp ( appIdentityHash , await computeTokenIndexedFreeBalanceIncrements ( stateChannel . getAppInstance ( appIdentityHash ) , provider ) ) ; }