Update and adapt for new kredits contracts release
This commit is contained in:
parent
c27fefcfdc
commit
710bd90172
18
README.md
18
README.md
@ -10,15 +10,20 @@ contributions.
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
### Ethereum wallet
|
### Wallet
|
||||||
|
|
||||||
You will need an Ethereum wallet for your bot, so it can interact with the
|
You will need a keypair/wallet for your bot, so it can interact with the smart
|
||||||
Ethereum smart contracts. `npm run create-wallet` will do the job for you.
|
contracts. `npm run create-wallet` will do the job for you.
|
||||||
|
|
||||||
The wallet must be funded with enough ETH to interact with the contracts.
|
The wallet must be funded with enough native chain tokens to interact with the
|
||||||
|
contracts (i.e. it must be able to pay gas/tx fees)
|
||||||
|
|
||||||
### Contract permissions
|
### Contract permissions
|
||||||
|
|
||||||
|
**Warning: outdated instructions!**
|
||||||
|
|
||||||
|
*TODO adapt instructions for new permission model*
|
||||||
|
|
||||||
The bot wallet needs the following Aragon contract permissions to interact
|
The bot wallet needs the following Aragon contract permissions to interact
|
||||||
with [kredits-contracts]:
|
with [kredits-contracts]:
|
||||||
|
|
||||||
@ -41,11 +46,10 @@ As usual in Hubot, you can add all config as environment variables.
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `KREDITS_WEBHOOK_TOKEN` | A string for building your secret webhook URLs |
|
| `KREDITS_WEBHOOK_TOKEN` | A string for building your secret webhook URLs |
|
||||||
| `KREDITS_ROOM` | The bot will talk to you in this room |
|
| `KREDITS_ROOM` | The bot will talk to you in this room |
|
||||||
| `KREDITS_WALLET_PATH` | Path to an Etherum wallet JSON file (default: `./wallet.json`) |
|
| `KREDITS_WALLET_PATH` | Path to an wallet JSON file (default: `./wallet.json`) |
|
||||||
| `KREDITS_WALLET_PASSWORD` | Wallet password |
|
| `KREDITS_WALLET_PASSWORD` | Wallet password |
|
||||||
| `KREDITS_PROVIDER_URL` | Ethereum JSON-RPC URL (default: `http://localhost:7545`) |
|
| `KREDITS_PROVIDER_URL` | JSON-RPC URL of a blockchain node (default: `http://localhost:7545`) |
|
||||||
| `KREDITS_WEB_URL` | URL of the Kredits Web app (default: `https://kredits.kosmos.org`) |
|
| `KREDITS_WEB_URL` | URL of the Kredits Web app (default: `https://kredits.kosmos.org`) |
|
||||||
| `KREDITS_DAO_ADDRESS` | DAO Kernel address |
|
|
||||||
| `KREDITS_SESSION_SECRET` | Secret used by [grant](https://www.npmjs.com/package/grant) to sign the session ID |
|
| `KREDITS_SESSION_SECRET` | Secret used by [grant](https://www.npmjs.com/package/grant) to sign the session ID |
|
||||||
| `KREDITS_GRANT_HOST` | Host used by [grant](https://www.npmjs.com/package/grant) to generate OAuth redirect URLs (default: `localhost:8888`) |
|
| `KREDITS_GRANT_HOST` | Host used by [grant](https://www.npmjs.com/package/grant) to generate OAuth redirect URLs (default: `localhost:8888`) |
|
||||||
| `KREDITS_GRANT_PROTOCOL` | Protocol (http or https) used by [grant](https://www.npmjs.com/package/grant") to generate the OAuth redirect URLs (default: "http") |
|
| `KREDITS_GRANT_PROTOCOL` | Protocol (http or https) used by [grant](https://www.npmjs.com/package/grant") to generate the OAuth redirect URLs (default: "http") |
|
||||||
|
70
index.js
70
index.js
@ -1,14 +1,11 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const util = require('util');
|
|
||||||
const fetch = require('node-fetch');
|
|
||||||
const ethers = require('ethers');
|
const ethers = require('ethers');
|
||||||
const NonceManager = require('@ethersproject/experimental').NonceManager;
|
const NonceManager = require('@ethersproject/experimental').NonceManager;
|
||||||
const Kredits = require('kredits-contracts');
|
const Kredits = require('@kredits/contracts');
|
||||||
|
|
||||||
const walletPath = process.env.KREDITS_WALLET_PATH || './wallet.json';
|
const walletPath = process.env.KREDITS_WALLET_PATH || './wallet.json';
|
||||||
const walletJson = fs.readFileSync(walletPath);
|
const walletJson = fs.readFileSync(walletPath);
|
||||||
const providerUrl = process.env.KREDITS_PROVIDER_URL;
|
const providerUrl = process.env.KREDITS_PROVIDER_URL || 'http://localhost:7545';
|
||||||
const daoAddress = process.env.KREDITS_DAO_ADDRESS;
|
|
||||||
|
|
||||||
const ipfsConfig = {
|
const ipfsConfig = {
|
||||||
host: process.env.IPFS_API_HOST || 'localhost',
|
host: process.env.IPFS_API_HOST || 'localhost',
|
||||||
@ -38,12 +35,9 @@ module.exports = async function(robot) {
|
|||||||
// Ethereum provider/node setup
|
// Ethereum provider/node setup
|
||||||
//
|
//
|
||||||
|
|
||||||
let ethProvider;
|
robot.logger.info('[hubot-kredits] Using blockchain node/API at', providerUrl);
|
||||||
if (providerUrl) {
|
|
||||||
ethProvider = new ethers.providers.JsonRpcProvider(providerUrl);
|
const ethProvider = new ethers.providers.JsonRpcProvider(providerUrl);
|
||||||
} else {
|
|
||||||
ethProvider = new ethers.getDefaultProvider('rinkeby');
|
|
||||||
}
|
|
||||||
const signer = new NonceManager(wallet.connect(ethProvider));
|
const signer = new NonceManager(wallet.connect(ethProvider));
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -51,9 +45,6 @@ module.exports = async function(robot) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
const opts = { ipfsConfig };
|
const opts = { ipfsConfig };
|
||||||
if (daoAddress) {
|
|
||||||
opts.addresses = { Kernel: daoAddress };
|
|
||||||
}
|
|
||||||
let kredits;
|
let kredits;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -63,8 +54,8 @@ module.exports = async function(robot) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
const Contributor = kredits.Contributor;
|
const Contributor = kredits.Contributor;
|
||||||
const Proposal = kredits.Proposal;
|
|
||||||
const Contribution = kredits.Contribution;
|
const Contribution = kredits.Contribution;
|
||||||
|
// TODO const Reimbursement = kredits.Reimbursement;
|
||||||
|
|
||||||
robot.logger.info('[hubot-kredits] Wallet address: ' + wallet.address);
|
robot.logger.info('[hubot-kredits] Wallet address: ' + wallet.address);
|
||||||
|
|
||||||
@ -73,9 +64,9 @@ module.exports = async function(robot) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
ethProvider.getBalance(wallet.address).then(balance => {
|
ethProvider.getBalance(wallet.address).then(balance => {
|
||||||
robot.logger.info('[hubot-kredits] Wallet balance: ' + ethers.utils.formatEther(balance) + 'ETH');
|
robot.logger.info('[hubot-kredits] Wallet balance: ' + ethers.utils.formatEther(balance) + ' RBTC');
|
||||||
if (balance.lt(ethers.utils.parseEther('0.0001'))) {
|
if (balance.lt(ethers.utils.parseEther('0.0001'))) {
|
||||||
messageRoom(`Yo gang, I\'m broke! Please drop me some ETH to ${wallet.address}. kthxbai.`);
|
messageRoom(`Yo gang, I\'m broke! Please send some RBTC to ${wallet.address}. kthxbai.`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -83,30 +74,9 @@ module.exports = async function(robot) {
|
|||||||
// Robot chat commands/interaction
|
// Robot chat commands/interaction
|
||||||
//
|
//
|
||||||
|
|
||||||
robot.respond(/got ETH\??/i, res => {
|
robot.respond(/got RBTC\??/i, res => {
|
||||||
ethProvider.getBalance(wallet.address).then((balance) => {
|
ethProvider.getBalance(wallet.address).then((balance) => {
|
||||||
res.send(`My wallet contains ${ethers.utils.formatEther(balance)} ETH`);
|
res.send(`My wallet contains ${ethers.utils.formatEther(balance)} RBTC`);
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
robot.respond(/propose (\d*)\s?\S*\s?to (\S+)(?:\sfor (.*))?$/i, res => {
|
|
||||||
let [_, amount, githubUser, description] = res.match;
|
|
||||||
let url = null;
|
|
||||||
createProposal(githubUser, amount, description, url).then((result) => {
|
|
||||||
messageRoom('Sounds good! Will be listed on https://kredits.kosmos.org in a bit...');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
robot.respond(/list open proposals/i, res => {
|
|
||||||
Proposal.all().then((proposals) => {
|
|
||||||
proposals.forEach((proposal) => {
|
|
||||||
if (!proposal.executed) {
|
|
||||||
Contributor.getById(proposal.contributorId).then((contributor) => {
|
|
||||||
messageRoom(`* ${proposal.amount} kredits to ${contributor.name} for ${proposal.description}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
messageRoom('https://kredits.kosmos.org');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -115,31 +85,23 @@ module.exports = async function(robot) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
function watchContractEvents() {
|
function watchContractEvents() {
|
||||||
ethProvider.getBlockNumber().then((blockNumber) => {
|
ethProvider.getBlockNumber().then(blockNumber => {
|
||||||
// current block is the last mined one, thus we check from the next
|
// current block is the last mined one, thus we check from the next
|
||||||
// mined one onwards to prevent getting previous events
|
// mined one onwards to prevent getting previous events
|
||||||
let nextBlock = blockNumber + 1;
|
let nextBlock = blockNumber + 1;
|
||||||
robot.logger.debug(`[hubot-kredits] Watching events from block ${nextBlock} onward`);
|
robot.logger.debug(`[hubot-kredits] Watching events from block ${nextBlock} onward`);
|
||||||
ethProvider.resetEventsBlock(nextBlock);
|
ethProvider.resetEventsBlock(nextBlock);
|
||||||
|
|
||||||
Proposal.on('ProposalCreated', handleProposalCreated);
|
// TODO handle all known events (that make sense here)
|
||||||
|
// Contribution.on('ContributorAdded', handleContributorAdded);
|
||||||
Contribution.on('ContributionAdded', handleContributionAdded);
|
Contribution.on('ContributionAdded', handleContributionAdded);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleProposalCreated(proposalId, creatorAccount, contributorId, amount) {
|
|
||||||
Contributor.getById(contributorId).then((contributor) => {
|
|
||||||
Proposal.getById(proposalId).then((proposal) => {
|
|
||||||
robot.logger.debug(`[hubot-kredits] Proposal created (${proposal.description})`);
|
|
||||||
// messageRoom(`Let's give ${contributor.name} some kredits for ${proposal.url} (${proposal.description}): https://kredits.kosmos.org`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleContributionAdded(contributionId, contributorId, amount) {
|
function handleContributionAdded(contributionId, contributorId, amount) {
|
||||||
Contributor.getById(contributorId).then((contributor) => {
|
Contributor.getById(contributorId).then(_ => {
|
||||||
Contribution.getById(contributionId).then((contribution) => {
|
Contribution.getById(contributionId).then(contribution => {
|
||||||
robot.logger.debug(`[hubot-kredits] Contribution #${contribution.id} added (${contribution.description})`);
|
robot.logger.debug(`[hubot-kredits] Contribution #${contribution.id} added (${amount} kredits for "${contribution.description}")`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
6759
package-lock.json
generated
6759
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@
|
|||||||
"grant-express": "^4.6.1",
|
"grant-express": "^4.6.1",
|
||||||
"group-array": "^1.0.0",
|
"group-array": "^1.0.0",
|
||||||
"kosmos-schemas": "^1.1.2",
|
"kosmos-schemas": "^1.1.2",
|
||||||
"kredits-contracts": "^6.0.0",
|
"@kredits/contracts": "git+https://gitea.kosmos.org/kredits/contracts#deploy-rsk",
|
||||||
"node-cron": "^2.0.3",
|
"node-cron": "^2.0.3",
|
||||||
"node-fetch": "^2.3.0",
|
"node-fetch": "^2.3.0",
|
||||||
"prompt": "^1.0.0",
|
"prompt": "^1.0.0",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user