You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

253 lines
7.5 KiB

const os = require('os');
const fs = require('fs-extra');
const portscanner = require('portscanner');
const exec = require('child_process').exec;
const execFile = require('child_process').execFile;
const path = require('path');
const request = require('request');
const Promise = require('bluebird');
const RATES_UPDATE_INTERVAL = 60000;
module.exports = (shepherd) => {
shepherd.get('/mm/start', (req, res, next) => {
shepherd.log('mm start is called');
shepherd.startMarketMaker({ passphrase: req.query.passphrase });
shepherd.mmupass = null;
shepherd.mmupass = setInterval(() => {
const options = {
url: `http://localhost:7783`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ method: 'balance' }),
};
// send back body on both success and error
// this bit replicates iguana core's behaviour
request(options, (error, response, body) => {
if (response &&
response.statusCode &&
response.statusCode === 200) {
const _parsedBody = JSON.parse(body);
if (_parsedBody.userpass) {
res.end(body);
clearInterval(shepherd.mmupass);
shepherd.mmupass = _parsedBody.userpass;
shepherd.mmPublic.mmupass = shepherd.mmupass;
shepherd.mmPublic.isAuth = true;
shepherd.mmPublic.coins = _parsedBody.coins;
shepherd.log(`mm start success`);
shepherd.log(`mm userpass ${_parsedBody.userpass}`);
shepherd.getCoinsHelper();
shepherd.getRates();
}
} else {
shepherd.log(`mm start responded with error ${error}`);
/*res.end(body ? body : JSON.stringify({
result: 'error',
error: {
code: -777,
message: `unable to call method balance at port 7783`,
},
}));*/
}
});
}, 500);
});
shepherd.getCoinsHelper = () => {
const defaultCoinsListFile = path.join(__dirname, '../dex/coins.json');
const _coins = fs.readJsonSync(defaultCoinsListFile, { throws: false });
let coins = {};
for (let i = 0; i < _coins.length; i++) {
coins[_coins[i].coin] = _coins[i];
}
coins.MNZ.name = 'Monaize';
coins.KMD = { coin: 'KMD', name: 'Komodo' };
coins.BTC = { coin: 'BTC', name: 'Bitcoin' };
coins.IOP.name = 'Internet of People';
shepherd.mmPublic.coinsHelper = coins;
}
shepherd.getRates = () => {
function _getRates() {
const options = {
url: `https://min-api.cryptocompare.com/data/price?fsym=KMD&tsyms=BTC,USD`,
method: 'GET',
};
// send back body on both success and error
// this bit replicates iguana core's behaviour
request(options, (error, response, body) => {
if (response &&
response.statusCode &&
response.statusCode === 200) {
const _parsedBody = JSON.parse(body);
shepherd.log(`rates ${body}`);
shepherd.mmPublic.rates = _parsedBody;
} else {
shepherd.log(`mm unable to retrieve KMD/BTC,USD rate`);
}
});
}
_getRates();
shepherd.mmRatesInterval = setInterval(() => {
_getRates();
}, RATES_UPDATE_INTERVAL);
}
shepherd.getMMCacheData = () => {
return new Promise((resolve, reject) => {
resolve(shepherd.mmPublic);
});
}
shepherd.get('/mm/stop', (req, res, next) => {
shepherd.log('mm stop is called');
clearInterval(shepherd.mmRatesInterval);
shepherd.killRogueProcess('marketmaker');
shepherd.mmPublic = {
coins: [],
mmupass: null,
swaps: [],
bids: [],
asks: [],
isAuth: false,
rates: {},
};
const successObj = {
msg: 'success',
result: 'executed',
};
res.end(JSON.stringify(successObj));
});
shepherd.get('/mm/restart', (req, res, next) => {
shepherd.log('mm restart is called');
shepherd.killRogueProcess('marketmaker');
shepherd.mmPublic = {
coins: {},
mmupass: null,
swaps: [],
bids: [],
asks: [],
isAuth: false,
};
setTimeout(() => {
shepherd.startMarketMaker({ passphrase: req.query.passphrase });
const successObj = {
msg: 'success',
result: 'restarting',
};
res.end(JSON.stringify(successObj));
}, 1000);
});
shepherd.startMarketMaker = (data) => {
const defaultCoinsListFile = path.join(__dirname, '../dex/coins.json');
try {
// check if marketmaker instance is already running
portscanner.checkPortStatus(7783, '127.0.0.1', (error, status) => {
// Status is 'open' if currently in use or 'closed' if available
if (status === 'closed') {
// add BarterDEX check
const _coinsListFile = shepherd.agamaDir + '/coins.json';
fs.pathExists(_coinsListFile, (err, exists) => {
if (exists) {
shepherd.log('dex coins file exist');
data.coinslist = fs.readJsonSync(_coinsListFile, { throws: false });
shepherd.execMarketMaker(data);
} else if (!exists) {
shepherd.log(`dex coins file doesnt exist`);
fs.copy(defaultCoinsListFile, _coinsListFile)
.then(() => {
shepherd.log(`dex coins file copied to ${shepherd.agamaDir}`);
data.coinslist = fs.readJsonSync(_coinsListFile, { throws: false });
shepherd.execMarketMaker(data);
})
.catch(err => {
shepherd.log(`unable to copy dex coins file, ${err}`);
});
} else if (err) {
shepherd.log(`dex coins file doesnt exist, ${err}`);
}
});
} else {
shepherd.log(`port 7783 marketmaker is already in use`);
}
});
} catch(e) {
shepherd.log(`failed to start marketmaker err: ${e}`);
}
}
shepherd.execMarketMaker = (data) => {
const _customParam = {
gui: 'agama-buildog',
client: 1,
profitmargin: 0.01, // (?)
userhome: `${process.env.HOME}`,
passphrase: data.passphrase,
coins: data.coinslist,
};
//console.log(JSON.stringify(_customParam))
//console.log(`exec ${BarterDEXBin} ${JSON.stringify(_customParam)}`);
let params = _customParam;
if (os.platform() !== 'win32') {
params = `'${JSON.stringify(_customParam)}'`;
} else {
shepherd.mmBin = `"${shepherd.mmBin}"`;
params.userhome = process.env.APPDATA;
if (!!params.coins) { // if not undefined and true
delete params.coins; // for Windows we should use coins.json file, and don't pass coins in command line
}
params = JSON.stringify(_customParam);
params = params.replace(/"/g, '\\"');
params = `"${params}"`;
}
const logStream = fs.createWriteStream(`${shepherd.agamaDir}/logFile.log`, { flags: 'a' });
shepherd.log('starting mm');
const mmid = exec(`${shepherd.mmBin} ${params}`, {
cwd: shepherd.agamaDir,
maxBuffer: 1024 * 50000 // 50 mb
}, function(error, stdout, stderr) {
// console.log(`stdout: ${stdout}`);
// console.log(`stderr: ${stderr}`);
if (error !== null) {
shepherd.log(`mm exec error: ${error}`);
}
});
mmid.stdout.on('data', (data) => {
// console.log(`child stdout:\n${data}`);
}).pipe(logStream);
mmid.stderr.on('data', (data) => {
// console.error(`child stderr:\n${data}`);
}).pipe(logStream);
}
return shepherd;
};