Update and adapt for new kredits contracts release #68

Merged
raucao merged 6 commits from chore/kredits_upgrade into master 2022-11-02 18:09:09 +00:00
4 changed files with 4960 additions and 1896 deletions

View File

@ -10,15 +10,20 @@ contributions.
## Setup
### Ethereum wallet
### Wallet
You will need an Ethereum wallet for your bot, so it can interact with the
Ethereum smart contracts. `npm run create-wallet` will do the job for you.
You will need a keypair/wallet for your bot, so it can interact with the smart
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
**Warning: outdated instructions!**
*TODO adapt instructions for new permission model*
The bot wallet needs the following Aragon contract permissions to interact
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_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_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_DAO_ADDRESS` | DAO Kernel address |
| `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_PROTOCOL` | Protocol (http or https) used by [grant](https://www.npmjs.com/package/grant") to generate the OAuth redirect URLs (default: "http") |

View File

@ -1,14 +1,11 @@
const fs = require('fs');
const util = require('util');
const fetch = require('node-fetch');
const ethers = require('ethers');
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 walletJson = fs.readFileSync(walletPath);
const providerUrl = process.env.KREDITS_PROVIDER_URL;
const daoAddress = process.env.KREDITS_DAO_ADDRESS;
const providerUrl = process.env.KREDITS_PROVIDER_URL || 'http://localhost:7545';
const ipfsConfig = {
host: process.env.IPFS_API_HOST || 'localhost',
@ -38,12 +35,9 @@ module.exports = async function(robot) {
// Ethereum provider/node setup
//
let ethProvider;
if (providerUrl) {
ethProvider = new ethers.providers.JsonRpcProvider(providerUrl);
} else {
ethProvider = new ethers.getDefaultProvider('rinkeby');
}
robot.logger.info('[hubot-kredits] Using blockchain node/API at', providerUrl);
const ethProvider = new ethers.providers.JsonRpcProvider(providerUrl);
const signer = new NonceManager(wallet.connect(ethProvider));
//
@ -51,9 +45,6 @@ module.exports = async function(robot) {
//
const opts = { ipfsConfig };
if (daoAddress) {
opts.addresses = { Kernel: daoAddress };
}
let kredits;
try {
@ -63,8 +54,8 @@ module.exports = async function(robot) {
process.exit(1);
}
const Contributor = kredits.Contributor;
const Proposal = kredits.Proposal;
const Contribution = kredits.Contribution;
// TODO const Reimbursement = kredits.Reimbursement;
robot.logger.info('[hubot-kredits] Wallet address: ' + wallet.address);
@ -73,9 +64,9 @@ module.exports = async function(robot) {
//
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'))) {
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.respond(/got ETH\??/i, res => {
robot.respond(/got RBTC\??/i, res => {
ethProvider.getBalance(wallet.address).then((balance) => {
res.send(`My wallet contains ${ethers.utils.formatEther(balance)} ETH`);
});
});
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');
res.send(`My wallet contains ${ethers.utils.formatEther(balance)} RBTC`);
});
});
@ -115,31 +85,23 @@ module.exports = async function(robot) {
//
function watchContractEvents() {
ethProvider.getBlockNumber().then((blockNumber) => {
ethProvider.getBlockNumber().then(blockNumber => {
// 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(`[hubot-kredits] Watching events from block ${nextBlock} onward`);
ethProvider.resetEventsBlock(nextBlock);
Proposal.on('ProposalCreated', handleProposalCreated);
// TODO handle all known events (that make sense here)
// Contribution.on('ContributorAdded', handleContributorAdded);
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) {
Contributor.getById(contributorId).then((contributor) => {
Contribution.getById(contributionId).then((contribution) => {
robot.logger.debug(`[hubot-kredits] Contribution #${contribution.id} added (${contribution.description})`);
Contributor.getById(contributorId).then(_ => {
Contribution.getById(contributionId).then(contribution => {
robot.logger.debug(`[hubot-kredits] Contribution #${contribution.id} added (${amount} kredits for "${contribution.description}")`);
});
});
}

6762
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "hubot-kredits",
"version": "3.8.0",
"name": "@kredits/hubot-kredits",
"version": "4.0.1",
"description": "Kosmos Kredits functionality for chat bots",
"main": "index.js",
"scripts": {
@ -12,6 +12,7 @@
},
"dependencies": {
"@ethersproject/experimental": "5.0.0",
"@kredits/contracts": "^7.0.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"eth-provider": "^0.2.2",
@ -21,7 +22,6 @@
"grant-express": "^4.6.1",
"group-array": "^1.0.0",
"kosmos-schemas": "^1.1.2",
"kredits-contracts": "^6.0.0",
"node-cron": "^2.0.3",
"node-fetch": "^2.3.0",
"prompt": "^1.0.0",