import { PaymentChannel , PaymentChannelJSON } from '../PaymentChannel' ; import * as BigNumber from 'bignumber.js' ; import { namespaced } from '../util/namespaced' ; import IEngine from './IEngine' ; import ChannelId from '../ChannelId' ; import IChannelsDatabase from './IChannelsDatabase' ; import Logger from '@machinomy/logger' ; import ChannelInflator from '../ChannelInflator' ; const LOG = new Logger ( 'abstract-channels-database' ) ; export default abstract class AbstractChannelsDatabase < T extends IEngine > implements IChannelsDatabase { engine : T ; kind : string ; inflator : ChannelInflator ; constructor ( engine , inflator , namespace ) { this . kind = namespaced ( namespace , 'channel' ) ; this . engine = engine ; this . inflator = inflator ; } inflatePaymentChannels ( channels ) { if ( ! channels . length ) { return Promise . resolve ( [ ] ) ; } return Promise . all ( channels . map ( ( chan ) => this . inflatePaymentChannel ( chan ) ) ) as Promise < Array < PaymentChannel > > ; } async inflatePaymentChannel ( json ) { if ( ! json ) { return null ; } else { return this . inflator . inflate ( json ) ; } } filterByState ( state , channels ) { return channels . filter ( ( chan ) => chan ? chan . state === state : false ) ; } abstract save ( paymentChannel ) ; saveOrUpdate ( paymentChannel ) { LOG . info ( `Saving or updating channel with ID ${ paymentChannel . channelId . toString ( ) }` ) ; return this . firstById ( paymentChannel . channelId ) . then ( ( found ) => { if ( found ) { LOG . info ( `Spending channel with ID ${ paymentChannel . channelId . toString ( ) }: ${ JSON . stringify ( paymentChannel ) }` ) ; return this . spend ( paymentChannel . channelId , paymentChannel . spent ) ; } else { LOG . info ( `Saving channel with ID ${ paymentChannel . channelId . toString ( ) }: ${ JSON . stringify ( paymentChannel ) }` ) ; return this . save ( paymentChannel ) ; } } ) ; } abstract deposit ( channelId , value ) ; abstract firstById ( channelId ) ; abstract spend ( channelId , spent ) ; abstract all ( ) ; abstract allOpen ( ) ; async allSettling ( ) { const all = await this . all ( ) ; return this . filterByState ( 1 , all ) ; } abstract findUsable ( sender , receiver , amount ) ; abstract findBySenderReceiver ( sender , receiver ) ; abstract findBySenderReceiverChannelId ( sender , receiver , channelId ) ; abstract updateState ( channelId , state ) ; abstract updateSettlingUntil ( channelId , settlingUntil ) ; }