import { DefundChannel } from '@statechannels/wallet-core' ; import { Transaction } from 'objection' ; import { Logger } from 'pino' ; import { WalletObjective } from '../models/objective' ; import { Cranker , Nothing } from '../objectives/objective-manager' ; import { Store } from '../engine/store' ; import { EngineResponse } from '../engine/engine-response' ; import { Defunder } from './defunder' ; export const enum WaitingFor { transactionSubmission = 'ChannelDefunder.transactionSubmission' } export class ChannelDefunder implements Cranker < WalletObjective < DefundChannel > > { constructor ( private store , private logger , private timingMetrics = false ) { } public static create ( store , logger , timingMetrics = false ) { return new ChannelDefunder ( store , logger , timingMetrics ) ; } public async crank ( objective , response , tx ) { const { targetChannelId : channelId } = objective . data ; const channel = await this . store . getAndLockChannel ( channelId , tx ) ; await channel . $fetchGraph ( 'funding' , { transaction : tx } ) ; await channel . $fetchGraph ( 'chainServiceRequests' , { transaction : tx } ) ; if ( channel . fundingStrategy !== 'Direct' ) { this . logger . error ( `Only direct funding is currently supported, but channel ${ channel . channelId } has the ${ channel . fundingStrategy } strategy` ) ; await this . store . markObjectiveStatus ( objective , 'failed' , tx ) ; return Nothing . ToWaitFor ; } const { didSubmitTransaction } = await Defunder . create ( this . store , this . logger , this . timingMetrics ) . crank ( channel , objective , response , tx ) ; if ( didSubmitTransaction ) { await this . store . markObjectiveStatus ( objective , 'succeeded' , tx ) ; response . queueSucceededObjective ( objective ) ; return Nothing . ToWaitFor ; } else return WaitingFor . transactionSubmission ; } }