Notify channel from ProposalCreated event

This handles incoming events (for now only ProposalCreated, but easy to
extend), and moves the channel message for new proposals to the event
handler, so that they're being announced for all proposals, including
those created manually from kredits-web for example.
This commit is contained in:
Basti 2017-06-20 18:59:58 -07:00
parent 0e6898d93b
commit 94baf62c51

View File

@ -136,9 +136,9 @@ const tv4 = require('tv4');
function getContributorData(i) {
let promise = new Promise((resolve, reject) => {
getValueFromContract('contributorAddresses', i).then(address => {
robot.logger.debug('address', address);
// robot.logger.debug('address', address);
getValueFromContract('contributors', address).then(person => {
robot.logger.debug('person', person);
// robot.logger.debug('person', person);
let c = {
address: address,
name: person[1],
@ -146,8 +146,9 @@ const tv4 = require('tv4');
ipfsHash: person[2]
};
if (c.ipfsHash) {
// robot.logger.debug('[kredits] loading contributor profile loaded for', c.name, c.ipfsHash, '...');
loadProfileFromIPFS(c).then(contributor => {
robot.logger.debug('[kredits] contributor', contributor);
// robot.logger.debug('[kredits] contributor profile loaded for', c.name);
resolve(contributor);
}).catch(() => console.log('[kredits] error fetching contributor info from IPFS for '+c.name));
} else {
@ -187,6 +188,22 @@ const tv4 = require('tv4');
return promise;
}
function getContributorByAddress(address) {
let promise = new Promise((resolve, reject) => {
getContributors().then(contributors => {
let contrib = contributors.find(c => {
return c.address === address;
});
if (contrib) {
resolve(contrib);
} else {
reject();
}
});
});
return promise;
}
function messageRoom(message) {
robot.messageRoom(process.env.KREDITS_ROOM, message);
}
@ -228,17 +245,21 @@ const tv4 = require('tv4');
};
if (! tv4.validate(contribution, schemas["contribution"])) {
console.log('[kredits] invalid contribution data: ', util.inspect(contribution));
robot.logger.error('[kredits] invalid contribution data: ', util.inspect(contribution));
return Promise.reject('invalid contribution data');
}
// robot.logger.debug('[kredits] creating IPFS document for contribution:', contribution.description);
return ipfs.add(new ipfs.Buffer(JSON.stringify(contribution)))
.then(res => { return res[0].hash; })
.catch(err => console.log(err));
.then(res => {
// robot.logger.debug('[kredits] created IPFS document', res[0].hash);
return res[0].hash;
}).catch(err => robot.logger.error('[kredits] couldn\'t create IPFS document', err));
}
function createProposal(recipient, amount, url, description, details) {
robot.logger.debug(`Creating proposal to issue ${amount}₭S to ${recipient} for ${url}...`);
robot.logger.debug(`[kredits] Creating proposal to issue ${amount}₭S to ${recipient} for ${url}...`);
return new Promise((resolve, reject) => {
// Get contributor details for GitHub user
@ -246,16 +267,16 @@ const tv4 = require('tv4');
// Create document containing contribution data on IPFS
createContributionDocument(c, url, description, details).then(ipfsHash => {
// Create proposal on ethereum blockchain
kredits.addProposal(c.address, amount, url, ipfsHash, (e/* , d */) => {
kredits.addProposal(c.address, amount, url, ipfsHash, (e, d) => {
if (e) { reject(e); return; }
messageRoom(`Let's give ${recipient} some kredits for ${url}: https://kredits.kosmos.org`);
robot.logger.debug('[kredits] proposal created:', util.inspect(d));
resolve();
});
});
}, () => {
messageRoom(`I wanted to propose giving kredits to ${recipient} for ${url}, but I can't find their contact data. Please add them as a contributor: https://kredits.kosmos.org`);
resolve();
});
resolve();
});
}
@ -280,7 +301,8 @@ const tv4 = require('tv4');
let description = `${repoName}: ${issue.title}`;
recipients.forEach(recipient => {
createProposal(recipient, amount, web_url, description, issue);
createProposal(recipient, amount, web_url, description, issue)
.catch(err => robot.logger.error(err));
});
resolve();
@ -318,7 +340,8 @@ const tv4 = require('tv4');
let description = `${repoName}: ${pull_request.title}`;
recipients.forEach(recipient => {
createProposal(recipient, amount, web_url, description, pull_request);
createProposal(recipient, amount, web_url, description, pull_request)
.catch(err => robot.logger.error(err));
});
resolve();
@ -359,5 +382,50 @@ const tv4 = require('tv4');
}
});
function watchContractEvents() {
web3.eth.getBlockNumber((err, blockNumber) => {
if (err) {
robot.logger.error('[kredits] couldn\t get current block number');
return false;
}
// current block is the last mined one, thus we check from the next
// mined one onwards to prevent getting previous events
let nextBlock = blockNumber + 1;
robot.logger.debug(`[kredits] watching events from block ${nextBlock} onward`);
kredits.allEvents({fromBlock: nextBlock, toBlock: 'latest'}, (error, data) => {
robot.logger.debug('[kredits] received contract event', data.event);
if (data.blockNumber < nextBlock) {
// I don't know why, but the filter doesn't work as intended
robot.logger.debug('[kredits] dismissing old event from block', data.blockNumber);
return false;
}
switch (data.event) {
case 'ProposalCreated':
handleProposalCreated(data);
break;
// case 'ProposalExecuted':
// handleProposalExecuted(data);
// break;
// case 'ProposalVoted':
// handleProposalVoted(data);
// break;
// case 'Transfer':
// handleTransfer(data);
// break;
}
});
});
}
function handleProposalCreated(data) {
getContributorByAddress(data.args.recipient).then((contributor) => {
messageRoom(`Let's give ${contributor.name} some kredits for ${data.args.url}: https://kredits.kosmos.org`);
});
}
watchContractEvents();
};
}());