import { Address , BN , checkThat , isSimpleAllocation , OpenChannel } from '@statechannels/wallet-core' ; import _ from 'lodash' ; import { Transaction } from 'objection' ; import { Logger } from 'pino' ; import { ChainServiceRequest } from '../models/chain-service-request' ; import { Channel } from '../models/channel' ; import { WalletObjective } from '../models/objective' ; import { Store } from '../engine/store' ; import { EngineResponse } from '../engine/engine-response' ; export class DirectFunder { constructor ( private store , private logger , private timingMetrics = false ) { } public static create ( store , logger , timingMetrics = false ) { return new DirectFunder ( store , logger , timingMetrics ) ; } /**
     * Runs the ledger funding protocol
     *
     * Returns true if the channel is funded, false otherwise
     */ public async crank ( objective , channel , response , tx ) { const asset = this . asset ( channel ) ; const { targetBefore , targetAfter , targetTotal } = channel . fundingMilestones ; const currentFunding = await this . store . getFunding ( channel . channelId , asset , tx ) ; const currentAmount = currentFunding ?. amount || 0 ; if ( BN . gte ( currentAmount , targetTotal ) ) return true ; if ( BN . lt ( currentAmount , targetBefore ) ) return false ; if ( BN . gte ( currentAmount , targetAfter ) ) return false ; if ( await this . store . fundingRequestExists ( channel . channelId , tx ) ) return false ; const amountToDeposit = BN . sub ( targetAfter , currentAmount ) ; await ChainServiceRequest . insertOrUpdate ( channel . channelId , 'fund' , tx ) ; response . queueChainRequest ( [ { type : 'FundChannel' , channelId : channel . channelId , asset , expectedHeld : BN . from ( currentAmount ) , amount : BN . from ( amountToDeposit ) , } , ] ) ; return false ; } private asset ( channel ) { const supported = channel . supported ; if ( ! supported ) { throw new Error ( `Channel passed to DirectFunder has no supported state` ) ; } const { asset } = checkThat ( supported ?. outcome , isSimpleAllocation ) ; return asset ; } }