diff --git a/bot/index.js b/bot/index.js index 203c0f1..cfe2c2d 100644 --- a/bot/index.js +++ b/bot/index.js @@ -1,30 +1,30 @@ const winston = require('winston'); -const SignerProvider = require('ethjs-provider-signer'); +const signerProvider = require('ethjs-provider-signer'); const sign = require('ethjs-signer').sign; -const Eth = require('ethjs-query'); +const eth = require('ethjs-query'); const prices = require('./prices'); const config = require('../config'); -const provider = new SignerProvider(config.signerPath, { +const provider = new signerProvider(config.signerPath, { signTransaction: (rawTx, cb) => cb(null, sign(rawTx, process.env.KEY)), accounts: (cb) => cb(null, [address]), }); -const eth = new Eth(provider); +const eth = new eth(provider); const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ - new winston.transports.File({ filename: 'error.log', level: 'error' }), - new winston.transports.File({ filename: 'info.log', level: 'info'}), - new winston.transports.File({ filename: 'combined.log' }) + new winston.transports.File({ filename: config.logPath + 'error.log', level: 'error' }), + new winston.transports.File({ filename: config.logPath + 'info.log', level: 'info'}), + new winston.transports.File({ filename: config.logPath + 'combined.log' }) ] }); const bountyLabels = { - 'bounty-xs': 1, + 'bounty-xs': 1, 'bounty-s': 10, - 'bounty-m': 100, + 'bounty-m': 100, 'bounty-l': 1000, 'bounty-xl': 10000, 'bounty-xx': 100000 @@ -45,13 +45,13 @@ const getAddress = function(req) { } const getLabel = function(req) { - let labelNames = req.body.issue.labels.map(lableObj => lableObj.name); + let labelNames = req.body.issue.labels.map(labelObj => labelObj.name); labels = labelNames.filter(name => bountyLabels.hasOwnProperty(name)); if (labels.length == 1) return labels[0]; - + //log error return 0; } @@ -71,19 +71,32 @@ const getAmount = function(req) { const getGasPrice = function(req) { let gasPricePromise = prices.getGasPrice(); + return gasPricePromise; +} - gasPricePromise - .then((gasPrice) => {return gasPrice}) - .catch((err) => {console.log("TODO-ERROR: Failed gas price request throw log error")}); - // Check how to handle errors when promises does not arrive +// Logging functions + +const logFunding = function(txId, from, to, amount, gasPrice){ + logger.info("\nSuccesfully funded bounty with transaction ", txId); + logger.info(" * From: ", from); + logger.info(" * To: ", to); + logger.info(" * Amount: ", amount); + logger.info(" * Gas Price: ", gasPrice); + logger.info("===================================================="); } const log = function(msg) { logger.info(msg); } +const error = function(requestBody, errorMessage) { + logger.error("[ERROR] Request processing failed: ", errorMessage); + logger.error("[ERROR] Request body: ", requestBody); +} + + module.exports = { - eth: new Eth(provider), + eth: new eth(provider), needsFunding: needsFunding, getAddress: getAddress, getAmount: getAmount, diff --git a/config/default.js b/config/default.js index b34d64e..8620482 100644 --- a/config/default.js +++ b/config/default.js @@ -1,9 +1,18 @@ module.exports = { - urlEndpoint: "/autobounty/fund", - signerPath: "https://ropsten.infura.io", - sourceAddress: "XXXXX", - token: "SNT", + debug: true, + urlEndpoint: '/autobounty/fund', + logPath: '../log/', + signerPath: 'https://ropsten.infura.io', + sourceAddress: 'XXXXX', + token: 'SNT', gasLimit: 92000, priceHour: 35, - workHours: {xs: 2000, s: 2500} + bountyLabelsHours: { + 'bounty-xs': 1, + 'bounty-s': 10, + 'bounty-m': 100, + 'bounty-l': 1000, + 'bounty-xl': 10000, + 'bounty-xx': 100000 + }; } diff --git a/index.js b/index.js index 01a3916..55ce007 100644 --- a/index.js +++ b/index.js @@ -12,56 +12,76 @@ const config = require('./config'); const bot = require('./bot'); var express = require('express'), - cors = require('cors'), - helmet = require('helmet'), - app = express(), - bodyParser = require('body-parser'), - jsonParser = bodyParser.json(); +cors = require('cors'), +helmet = require('helmet'), +app = express(), +bodyParser = require('body-parser'), +jsonParser = bodyParser.json(); app.use(cors()); app.use(helmet()); // Receive a POST request at the address specified by an env. var. app.post(`${config.urlEndpoint}`, jsonParser, function(req, res, next) { - // TODO decide how long the delay to start everything should be - if (!req.body || !req.body.action) - return res.sendStatus(400); + // TODO decide how long the delay to start everything should be + if (!req.body || !req.body.action) { + return res.sendStatus(400); + } - if (!bot.needsFunding(req)) - return res.sendStatus(204); + if (!bot.needsFunding(req)) { + return res.sendStatus(204); + } - //const eth = bot.eth; - //const from = config.sourceAddress; - //const to = bot.getAddress(req); - const amount = bot.getAmount(req); - const gasPrice = bot.getGasPrice(); - bot.log('amount: ' + amount); - bot.log('gasPrice: ' + gasPrice); - /* - eth.getTransactionCount(address, (err, nonce) => { - eth.sendTransaction({ - from: from, - to: to, - gas: gas, - gasPrice: gasPrice, - value: amount, - nonce, - }, (err, txID) => { - if (err) { - config.log('Request failed', err) - return res.status(500).json(err) - } - else { - config.log('Successful request:', txID) - res.json({ txID }) - } - }); - }); - */ - return res.sendStatus(200); -}); + const eth = bot.eth; + const from = config.sourceAddress; + const to = bot.getAddress(req); + + // Asynchronous requests for Gas Price and Amount + const amountPromise = bot.getAmount(req); + const gasPricePromise = bot.getGasPrice(); + + Promise.all([amountPromise, gasPricePromise]) + .then(function(amount, gasPrice){ + sendTransaction(eth, from, to, amount, gasPrice) + }) + .catch(function(error){ + bot.error(req.body, error); + }); + +} + + +const sendTransaction = function(eth, from, to, amount, gasPrice){ + if (!config.debug){ + + eth.getTransactionCount(from, (err, nonce) => { + eth.sendTransaction({ + from: from, + to: to, + gas: gas, + gasPrice: gasPrice, + value: amount, + nonce, + }, (err, txID) => { + if (err) { + bot.error(req.body, err) + return res.status(500).json(err) + } + else { + bot.logFunding(txID, from, to, amount, gasPrice); + res.json({ txID }) + } + }); + }); + + return res.sendStatus(200); + } else { + let txId = -1; + bot.logFunding(txID, from, to, amount, gasPrice); + } +} const port = process.env.PORT || 8181 app.listen(port, function(){ - console.log('Autobounty listening on port', port); + bot.log('Autobounty listening on port', port); });