import { EventEmitter } from 'events' ; import * as IlpPacket from 'ilp-packet' ; import * as Long from 'long' ; import * as ILDCP from 'ilp-protocol-ildcp' ; import { Writer } from 'oer-utils' ; import Rational from '../../src/util/rational' ; export interface DataHandler { ( data ) : Promise < Buffer > ; } export interface MoneyHandler { ( amount ) : Promise < void > ; } export default class MockPlugin extends EventEmitter { static readonly version = 2 ; public dataHandler : DataHandler ; public moneyHandler : MoneyHandler ; public exchangeRate : number ; public connected : boolean ; public mirror : MockPlugin ; protected identity : string ; protected assetCode : string ; public maxAmount ? : number | Long ; constructor ( exchangeRate , mirror ? ) { super ( ) ; this . dataHandler = this . defaultDataHandler ; this . moneyHandler = this . defaultMoneyHandler ; this . exchangeRate = exchangeRate ; this . mirror = mirror || new MockPlugin ( 1 / exchangeRate , this ) ; this . identity = ( mirror ? 'peerB' : 'peerA' ) ; this . assetCode = ( mirror ? 'XYZ' : 'ABC' ) ; this . maxAmount = 1000 ; } async connect ( ) { this . connected = true ; return Promise . resolve ( ) ; } async disconnect ( ) { this . emit ( 'disconnect' ) ; this . connected = false ; return Promise . resolve ( ) ; } isConnected ( ) { return this . connected ; } async sendData ( data ) { if ( data [ 0 ] === IlpPacket . Type . TYPE_ILP_PREPARE ) { const exchangeRate = Rational . fromNumber ( this . exchangeRate , true ) ; const parsed = IlpPacket . deserializeIlpPrepare ( data ) ; if ( parsed . destination === 'peer.config' ) { return ILDCP . serializeIldcpResponse ( { clientAddress : 'test.' + this . identity , assetScale : 9 , assetCode : this . assetCode } ) ; } const amount = Long . fromString ( parsed . amount , true ) ; if ( this . maxAmount !== undefined && amount . greaterThan ( this . maxAmount ) ) { const writer = new Writer ( ) ; writer . writeUInt64 ( amount ) ; writer . writeUInt64 ( this . maxAmount ) ; return IlpPacket . serializeIlpReject ( { code : 'F08' , message : 'Packet amount too large' , triggeredBy : 'test.connector' , data : writer . getBuffer ( ) } ) ; } const newPacket = IlpPacket . serializeIlpPrepare ( { ... parsed , amount : exchangeRate . multiplyByLong ( amount ) . toString ( 10 ) } ) ; return this . mirror . dataHandler ( newPacket ) ; } else { return this . mirror . dataHandler ( data ) ; } } async sendMoney ( amount ) { return this . mirror . moneyHandler ( amount ) ; } registerDataHandler ( handler ) { this . dataHandler = async ( data ) => { const reply = await handler ( data ) ; if ( this . connected ) { return reply ; } else { throw new Error ( 'Not connected' ) ; } } ; } deregisterDataHandler ( ) { this . dataHandler = this . defaultDataHandler ; } registerMoneyHandler ( handler ) { this . moneyHandler = handler ; } deregisterMoneyHandler ( ) { this . moneyHandler = this . defaultMoneyHandler ; } async defaultDataHandler ( data ) { return IlpPacket . serializeIlpReject ( { code : 'F02' , triggeredBy : 'example.mock-plugin' , message : 'No data handler registered' , data : Buffer . alloc ( 0 ) } ) ; } async defaultMoneyHandler ( amount ) { return ; } }