From 27a746261cad2ff2829ed564a11836c807245c1d Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Fri, 17 May 2019 15:54:52 +0200 Subject: [PATCH] Add JS wrapper for kredits kit This makes it easier to deploy new DAOs and the deploy script is less dependent on truffle --- lib/abis/KreditsKit.json | 1 + lib/kreditskit.js | 49 ++++++++++++++++++++++++++++++++++++++++ scripts/new-dao.js | 26 +++++++++------------ 3 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 lib/abis/KreditsKit.json create mode 100644 lib/kreditskit.js diff --git a/lib/abis/KreditsKit.json b/lib/abis/KreditsKit.json new file mode 100644 index 0000000..8202592 --- /dev/null +++ b/lib/abis/KreditsKit.json @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"ens","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fac","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"appId","type":"bytes32"}],"name":"latestVersionAppBase","outputs":[{"name":"base","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"appIds","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_fac","type":"address"},{"name":"_ens","type":"address"},{"name":"_appIds","type":"bytes32[4]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"dao","type":"address"}],"name":"DeployInstance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"dao","type":"address"},{"indexed":false,"name":"appProxy","type":"address"},{"indexed":false,"name":"appId","type":"bytes32"}],"name":"InstalledApp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"appProxy","type":"address"},{"indexed":false,"name":"appId","type":"bytes32"}],"name":"InstalledApp","type":"event"},{"constant":false,"inputs":[],"name":"newInstance","outputs":[{"name":"dao","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/kreditskit.js b/lib/kreditskit.js new file mode 100644 index 0000000..30538a1 --- /dev/null +++ b/lib/kreditskit.js @@ -0,0 +1,49 @@ +const ethers = require('ethers'); + +const ABI = require('./abis/KreditsKit.json'); +const Addresses = require('./addresses/KreditsKit.json'); + +class KreditsKit { + + constructor(provider, signer, options = {}) { + let { address, abi, ipfsConfig } = options; + + this.provider = provider; + this.signer = signer; + this.options = options; + this.address = address + this.abi = abi || ABI; + } + + init() { + return this.provider.getNetwork().then((network) => { + this.address = this.address || Addresses[network.chainId.toString()]; + this.contract = new ethers.Contract( + this.address, + this.abi, + (this.signer || this.provider) + ); + return this; + }); + } + + appIdFor(contractName) { + // see appIds in KreditsKit.sol for more details + const knownContracts = ['Contribution', 'Contributor', 'Proposal', 'Token']; + return this.contract.functions.appIds(knownContracts.indexOf(contractName)); + } + + newDAO(options = {}) { + return this.contract.functions.newInstance(options).then(transaction => { + return transaction.wait().then(result => { + const deployEvent = result.events.find(e => e.event === 'DeployInstance'); + return { + daoAddress: deployEvent.args.dao, + transactionHash: transaction.hash + } + }); + }); + } +} + +module.exports = KreditsKit; diff --git a/scripts/new-dao.js b/scripts/new-dao.js index 4694c48..8601034 100644 --- a/scripts/new-dao.js +++ b/scripts/new-dao.js @@ -1,13 +1,13 @@ const fs = require('fs'); const path = require('path'); +const ethers = require('ethers'); const fileInject = require('./helpers/file_inject.js'); const getNetworkId = require('./helpers/networkid.js'); +const KreditsKit = require('../lib/kreditskit'); const addressesPath = path.join(__dirname, '..', 'lib/addresses'); -const KreditsKit = artifacts.require('KreditsKit') - module.exports = async function(callback) { const networkId = await getNetworkId(web3) console.log(`Deploying to networkId: ${networkId}`) @@ -20,25 +20,21 @@ module.exports = async function(callback) { } console.log(`Using KreditsKit at: ${kreditsKitAddress}`); - let kreditsKit = KreditsKit.at(kreditsKitAddress) + const provider = new ethers.providers.Web3Provider(web3.currentProvider); + let signer = provider.getSigner(); - kreditsKit.newInstance().then((ret) => { - console.log(ret.logs); - const installedEvents = ret.logs.filter(log => log.event === 'InstalledApp').map(log => log.args) - const deployEvents = ret.logs.filter(log => log.event === 'DeployInstance').map(log => log.args) + let kit = await new KreditsKit(provider, signer).init() - if (deployEvents.length > 1) { - callback(new Error("More than one DAO was deployed. Something is wrong")) - } - const daoAddress = deployEvents[0].dao; + // TODO: get rid of the hard coded gas limit + kit.newDAO({ gasLimit: 10000000 }).then(result => { + console.log(result); + fileInject(path.join(addressesPath, 'dao.json'), networkId, result.daoAddress) - fileInject(path.join(addressesPath, 'dao.json'), networkId, daoAddress) - - console.log(`\n\nCreated new DAO at: ${daoAddress}`) + console.log(`\n\nCreated new DAO at: ${result.daoAddress}`) callback(); }).catch((err) => { - console.log('failed to create a new instance') + console.log('failed to create a new DAO') callback(err) }) }