Merge pull request #5 from PombeirP/feature/token-funding

Add funding using tokens and local debugging with VS code
This commit is contained in:
Andy Tudhope 2018-03-20 09:02:40 +02:00 committed by GitHub
commit 9597cde0a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 50 deletions

28
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug via NPM",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run-script",
"debug"
],
"env": {
"WEBHOOK_SECRET": ""
},
"port": 9229
},
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/index.js"
}
]
}

View File

@ -2,6 +2,7 @@ const winston = require('winston');
const ethers = require('ethers'); const ethers = require('ethers');
const Wallet = ethers.Wallet; const Wallet = ethers.Wallet;
const Contract = ethers.Contract;
const providers = ethers.providers; const providers = ethers.providers;
const utils = ethers.utils; const utils = ethers.utils;
@ -9,6 +10,8 @@ const prices = require('./prices');
const config = require('../config'); const config = require('../config');
const github = require('./github'); const github = require('./github');
const contractAddressString = 'Contract address:';
const logger = winston.createLogger({ const logger = winston.createLogger({
level: 'info', level: 'info',
@ -34,7 +37,7 @@ const needsFunding = function (req) {
const hasAddress = function (req) { const hasAddress = function (req) {
const commentBody = req.body.comment.body; const commentBody = req.body.comment.body;
if (commentBody.search('Contract address:') === -1) { if (commentBody.search(contractAddressString) === -1) {
return false; return false;
} else { } else {
return true; return true;
@ -43,34 +46,15 @@ const hasAddress = function (req) {
const getAddress = function (req) { const getAddress = function (req) {
const commentBody = req.body.comment.body; const commentBody = req.body.comment.body;
return commentBody.substring(commentBody.search("Contract address:") + 19, commentBody.search("Contract address:") + 61) const index = commentBody.search(contractAddressString) + 19
} return commentBody.substring(index, index + 42)
const getLabelMock = function (req) {
return new Promise((resolve, reject) => {
github.getLabels(req)
.then(labels => {
const bountyLabels = labels.filter(name => config.bountyLabels.hasOwnProperty(name));
if (bountyLabels.length === 1) {
resolve(bountyLabels[0]);
} else {
reject('Error getting bounty labels: ' + bountyLabels);
}
})
.catch((err) => {
reject(err)
});
});
} }
const getLabel = function (req) { const getLabel = function (req) {
if (config.debug) {
return getLabelMock(req);
}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
github.getLabels(req) github.getLabels(req)
.then(labels => { .then(labels => {
const bountyLabels = labels.filter(name => config.bountyLabels.hasOwnProperty(name)); const bountyLabels = labels.filter(label => config.bountyLabels.hasOwnProperty(label.name));
if (bountyLabels.length === 1) { if (bountyLabels.length === 1) {
resolve(bountyLabels[0]); resolve(bountyLabels[0]);
} else { } else {
@ -86,7 +70,6 @@ const getAmountMock = function (req) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
resolve(10); resolve(10);
}); });
} }
const getAmount = function (req) { const getAmount = function (req) {
@ -98,7 +81,7 @@ const getAmount = function (req) {
.then(function (values) { .then(function (values) {
let label = values[0]; let label = values[0];
let tokenPrice = values[1]; let tokenPrice = values[1];
let amountToPayDollar = config.priceHour * config.bountyLabels[label]; let amountToPayDollar = config.priceHour * config.bountyLabels[label.name];
resolve(amountToPayDollar / tokenPrice); resolve(amountToPayDollar / tokenPrice);
}) })
.catch((err) => { .catch((err) => {
@ -128,10 +111,7 @@ const error = function (errorMessage) {
} }
const sendTransaction = async function (to, amount, gasPrice) {
const sendTransaction = function (to, amount, gasPrice) {
var chainId = providers.Provider.chainId.ropsten; var chainId = providers.Provider.chainId.ropsten;
var chainName = providers.networks.ropsten; var chainName = providers.networks.ropsten;
@ -144,9 +124,8 @@ const sendTransaction = function (to, amount, gasPrice) {
const provider = ethers.providers.getDefaultProvider(chainName); const provider = ethers.providers.getDefaultProvider(chainName);
wallet.provider = provider; wallet.provider = provider;
if (config.token === 'ETH') {
const transaction = {
var transaction = {
gasLimit: config.gasLimit, gasLimit: config.gasLimit,
gasPrice: gasPrice, gasPrice: gasPrice,
to: to, to: to,
@ -154,17 +133,43 @@ const sendTransaction = function (to, amount, gasPrice) {
chainId: chainId chainId: chainId
}; };
return new Promise((resolve, reject) => { return await wallet.sendTransaction(transaction);
wallet.sendTransaction(transaction) } else {
.then(function(hash) { let hash = null;
logTransaction(hash);
resolve(hash); async function getAddress() { return wallet.address; }
}).catch(function(err) { async function sign(transaction) { return wallet.sign(transaction); }
reject(err);
}); async function resolveName(addressOrName) { return await provider.resolveName(addressOrName); }
}); async function estimateGas(transaction) { return await provider.estimateGas(transaction); }
async function getGasPrice() { return await provider.getGasPrice(); }
async function getTransactionCount(blockTag) { return await provider.getTransactionCount(blockTag); }
async function sendTransaction(transaction) {
hash = await provider.sendTransaction(transaction);
return hash;
} }
const customSigner = {
getAddress: getAddress,
provider: {
resolveName: resolveName,
estimateGas: estimateGas,
getGasPrice: getGasPrice,
getTransactionCount: getTransactionCount,
sendTransaction: sendTransaction
},
sign: sign
}
const tokenContract = config.tokenContracts[config.token];
const contractAddress = tokenContract.address;
const contract = new Contract(contractAddress, tokenContract.abi, customSigner);
const bigNumberAmount = ethers.utils.bigNumberify(amount);
await contract.transfer(to, bigNumberAmount);
return hash;
}
}
module.exports = { module.exports = {
needsFunding: needsFunding, needsFunding: needsFunding,

View File

@ -7,6 +7,42 @@ const BOUNTY_LABELS = {
'bounty-xl': 10000 'bounty-xl': 10000
} }
const ERC20_ABI = [
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
}
];
const TOKEN_CONTRACTS = {
'STT': {
address: '0xc55cF4B03948D7EBc8b9E8BAD92643703811d162',
abi: ERC20_ABI
},
'SNT': {
address: '0x744d70fdbe2ba4cf95131626614a1763df805b9e',
abi: ERC20_ABI
}
}
module.exports = { module.exports = {
// Debug mode for testing the bot // Debug mode for testing the bot
debug: true, debug: true,
@ -38,6 +74,9 @@ module.exports = {
// Bounty Labels for the issues and the correspondent hours (e.g. {'bounty-xs': 3}) // Bounty Labels for the issues and the correspondent hours (e.g. {'bounty-xs': 3})
bountyLabels: BOUNTY_LABELS, bountyLabels: BOUNTY_LABELS,
// Contract info for the different supported tokens
tokenContracts: TOKEN_CONTRACTS,
// username for the bot which has to comment for starting the process (e.g. status-bounty-) // username for the bot which has to comment for starting the process (e.g. status-bounty-)
githubUsername: 'status-open-bounty', githubUsername: 'status-open-bounty',

View File

@ -96,17 +96,17 @@ const processRequest = function (req) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Promise.all([amountPromise, gasPricePromise]) Promise.all([amountPromise, gasPricePromise])
.then(function (results) { .then(function (results) {
let amount = results[0]; const amount = results[0];
let gasPrice = results[1]; const gasPrice = results[1];
bot.sendTransaction(to, amount, gasPrice) bot.sendTransaction(to, amount, gasPrice)
.then(function () { .then(function (hash) {
bot.logTransaction(hash);
resolve(); resolve();
}) })
.catch(function (err) { .catch(function (err) {
reject(err); reject(err);
}); });
}) })
.catch(function (err) { .catch(function (err) {
reject(err); reject(err);

View File

@ -5,6 +5,7 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "node index.js", "start": "node index.js",
"debug": "node --inspect-brk index.js",
"test": "./node_modules/mocha/bin/mocha" "test": "./node_modules/mocha/bin/mocha"
}, },
"author": "", "author": "",