2020-10-19 06:57:02 +02:00
import config from '../../config' ;
2020-09-10 09:46:23 +02:00
import * as fs from 'fs' ;
2020-09-18 18:43:45 +02:00
import { OffersData as OffersData , TradesData , Currency } from './interfaces' ;
2020-09-10 09:46:23 +02:00
import bisqMarket from './markets-api' ;
2020-10-13 10:27:52 +02:00
import logger from '../../logger' ;
2020-09-10 09:46:23 +02:00
class Bisq {
2020-09-18 18:43:45 +02:00
private static FOLDER_WATCH_CHANGE_DETECTION_DEBOUNCE = 4000 ;
2020-10-19 13:58:25 +02:00
private static MARKET_JSON_PATH = config . BISQ_MARKETS . DATA_PATH ;
2020-09-10 09:46:23 +02:00
private static MARKET_JSON_FILE_PATHS = {
2020-11-23 14:46:14 +01:00
activeCryptoCurrency : '/active_crypto_currency_list.json' ,
activeFiatCurrency : '/active_fiat_currency_list.json' ,
2020-09-10 09:46:23 +02:00
cryptoCurrency : '/crypto_currency_list.json' ,
fiatCurrency : '/fiat_currency_list.json' ,
offers : '/offers_statistics.json' ,
trades : '/trade_statistics.json' ,
} ;
2020-09-18 18:43:45 +02:00
private cryptoCurrencyLastMtime = new Date ( '2016-01-01' ) ;
private fiatCurrencyLastMtime = new Date ( '2016-01-01' ) ;
private offersLastMtime = new Date ( '2016-01-01' ) ;
private tradesLastMtime = new Date ( '2016-01-01' ) ;
2020-09-10 09:46:23 +02:00
private subdirectoryWatcher : fs.FSWatcher | undefined ;
constructor ( ) { }
startBisqService ( ) : void {
this . checkForBisqDataFolder ( ) ;
this . loadBisqDumpFile ( ) ;
2020-09-13 12:51:53 +02:00
this . startBisqDirectoryWatcher ( ) ;
2020-09-10 09:46:23 +02:00
}
private checkForBisqDataFolder() {
if ( ! fs . existsSync ( Bisq . MARKET_JSON_PATH + Bisq . MARKET_JSON_FILE_PATHS . cryptoCurrency ) ) {
2020-10-13 10:27:52 +02:00
logger . err ( Bisq . MARKET_JSON_PATH + Bisq . MARKET_JSON_FILE_PATHS . cryptoCurrency + ` doesn't exist. Make sure Bisq is running and the config is correct before starting the server. ` ) ;
2020-09-10 09:46:23 +02:00
return process . exit ( 1 ) ;
}
}
2020-09-13 12:51:53 +02:00
private startBisqDirectoryWatcher() {
2020-09-10 09:46:23 +02:00
if ( this . subdirectoryWatcher ) {
this . subdirectoryWatcher . close ( ) ;
}
if ( ! fs . existsSync ( Bisq . MARKET_JSON_PATH + Bisq . MARKET_JSON_FILE_PATHS . cryptoCurrency ) ) {
2020-10-13 10:27:52 +02:00
logger . warn ( Bisq . MARKET_JSON_PATH + Bisq . MARKET_JSON_FILE_PATHS . cryptoCurrency + ` doesn't exist. Trying to restart sub directory watcher again in 3 minutes. ` ) ;
2020-09-13 12:51:53 +02:00
setTimeout ( ( ) = > this . startBisqDirectoryWatcher ( ) , 180000 ) ;
2020-09-10 09:46:23 +02:00
return ;
}
let fsWait : NodeJS.Timeout | null = null ;
this . subdirectoryWatcher = fs . watch ( Bisq . MARKET_JSON_PATH , ( ) = > {
if ( fsWait ) {
clearTimeout ( fsWait ) ;
}
fsWait = setTimeout ( ( ) = > {
2020-10-13 11:43:09 +02:00
logger . debug ( ` Change detected in the Bisq market data folder. ` ) ;
2020-09-10 09:46:23 +02:00
this . loadBisqDumpFile ( ) ;
2020-09-18 18:43:45 +02:00
} , Bisq . FOLDER_WATCH_CHANGE_DETECTION_DEBOUNCE ) ;
2020-09-10 09:46:23 +02:00
} ) ;
}
private async loadBisqDumpFile ( ) : Promise < void > {
const start = new Date ( ) . getTime ( ) ;
try {
2020-09-18 18:43:45 +02:00
let marketsDataUpdated = false ;
const cryptoMtime = this . getFileMtime ( Bisq . MARKET_JSON_FILE_PATHS . cryptoCurrency ) ;
const fiatMtime = this . getFileMtime ( Bisq . MARKET_JSON_FILE_PATHS . fiatCurrency ) ;
if ( cryptoMtime > this . cryptoCurrencyLastMtime || fiatMtime > this . fiatCurrencyLastMtime ) {
const cryptoCurrencyData = await this . loadData < Currency [ ] > ( Bisq . MARKET_JSON_FILE_PATHS . cryptoCurrency ) ;
const fiatCurrencyData = await this . loadData < Currency [ ] > ( Bisq . MARKET_JSON_FILE_PATHS . fiatCurrency ) ;
2020-11-23 14:46:14 +01:00
const activeCryptoCurrencyData = await this . loadData < Currency [ ] > ( Bisq . MARKET_JSON_FILE_PATHS . activeCryptoCurrency ) ;
const activeFiatCurrencyData = await this . loadData < Currency [ ] > ( Bisq . MARKET_JSON_FILE_PATHS . activeFiatCurrency ) ;
2020-10-13 11:43:09 +02:00
logger . debug ( 'Updating Bisq Market Currency Data' ) ;
2020-11-23 14:46:14 +01:00
bisqMarket . setCurrencyData ( cryptoCurrencyData , fiatCurrencyData , activeCryptoCurrencyData , activeFiatCurrencyData ) ;
2020-09-18 18:43:45 +02:00
if ( cryptoMtime > this . cryptoCurrencyLastMtime ) {
this . cryptoCurrencyLastMtime = cryptoMtime ;
}
if ( fiatMtime > this . fiatCurrencyLastMtime ) {
this . fiatCurrencyLastMtime = fiatMtime ;
}
marketsDataUpdated = true ;
}
const offersMtime = this . getFileMtime ( Bisq . MARKET_JSON_FILE_PATHS . offers ) ;
if ( offersMtime > this . offersLastMtime ) {
const offersData = await this . loadData < OffersData [ ] > ( Bisq . MARKET_JSON_FILE_PATHS . offers ) ;
2020-10-13 11:43:09 +02:00
logger . debug ( 'Updating Bisq Market Offers Data' ) ;
2020-09-18 18:43:45 +02:00
bisqMarket . setOffersData ( offersData ) ;
this . offersLastMtime = offersMtime ;
marketsDataUpdated = true ;
}
const tradesMtime = this . getFileMtime ( Bisq . MARKET_JSON_FILE_PATHS . trades ) ;
if ( tradesMtime > this . tradesLastMtime ) {
const tradesData = await this . loadData < TradesData [ ] > ( Bisq . MARKET_JSON_FILE_PATHS . trades ) ;
2020-10-13 11:43:09 +02:00
logger . debug ( 'Updating Bisq Market Trades Data' ) ;
2020-09-18 18:43:45 +02:00
bisqMarket . setTradesData ( tradesData ) ;
this . tradesLastMtime = tradesMtime ;
marketsDataUpdated = true ;
}
if ( marketsDataUpdated ) {
2020-09-19 18:02:02 +02:00
bisqMarket . updateCache ( ) ;
2020-09-29 14:38:01 +02:00
const time = new Date ( ) . getTime ( ) - start ;
2020-10-13 11:43:09 +02:00
logger . debug ( 'Bisq market data updated in ' + time + ' ms' ) ;
2020-09-18 18:43:45 +02:00
}
2020-09-10 09:46:23 +02:00
} catch ( e ) {
2020-10-28 05:00:48 +01:00
logger . err ( 'loadBisqMarketDataDumpFile() error.' + e . message || e ) ;
2020-09-10 09:46:23 +02:00
}
}
2020-09-18 18:43:45 +02:00
private getFileMtime ( path : string ) : Date {
const stats = fs . statSync ( Bisq . MARKET_JSON_PATH + path ) ;
return stats . mtime ;
}
2020-09-10 09:46:23 +02:00
private loadData < T > ( path : string ) : Promise < T > {
return new Promise ( ( resolve , reject ) = > {
fs . readFile ( Bisq . MARKET_JSON_PATH + path , 'utf8' , ( err , data ) = > {
if ( err ) {
reject ( err ) ;
}
try {
const parsedData = JSON . parse ( data ) ;
resolve ( parsedData ) ;
} catch ( e ) {
reject ( 'JSON parse error (' + path + ')' ) ;
}
} ) ;
} ) ;
}
}
export default new Bisq ( ) ;