contracts/lib/kredits.js
Michael Bumann 94832d4d07 Add ACL contract wrapper
this mainly allows us to check if an account has a certain role and thus
if the account can call specific contract functions.

At some point we might want to extend that to support the check if an
account can call the function. For that we would need to have a mapping
between function names and roles, which we have not right now.
2019-03-28 12:39:04 +01:00

122 lines
3.2 KiB
JavaScript

const ethers = require('ethers');
const RSVP = require('rsvp');
const Preflight = require('./utils/preflight');
const ABIS = {
Contributor: require('./abis/Contributor.json'),
Contribution: require('./abis/Contribution.json'),
Token: require('./abis/Token.json'),
Proposal: require('./abis/Proposal.json'),
Kernel: require('./abis/Kernel.json'),
Acl: require('./abis/ACL.json')
};
const APP_CONTRACTS = [
'Contributor',
'Contribution',
'Token',
'Proposal',
'Acl'
];
const DaoAddresses = require('./addresses/dao.json');
const Contracts = require('./contracts');
const IPFS = require('./utils/ipfs')
// Helpers
function capitalize(word) {
let [first, ...rest] = word;
return `${first.toUpperCase()}${rest.join('')}`;
}
class Kredits {
constructor(provider, signer, options = {}) {
let { addresses, abis, ipfsConfig } = options;
this.provider = provider;
this.signer = signer;
// by default we only need the DAO/Kernel address.
// the rest is loaded from there in the init() function
this.addresses = addresses || { Kernel: DaoAddresses[this.provider.chainId.toString()] }; // chainID must be a string
this.abis = abis || ABIS;
this.ipfs = new IPFS(ipfsConfig);
this.contracts = {};
}
init(names) {
let contractsToLoad = names || APP_CONTRACTS;
let addressPromises = contractsToLoad.map((contractName) => {
return this.Kernel.getApp(contractName).then((address) => {
this.addresses[contractName] = address;
}).catch((error) => {
throw new Error(`Failed to get address for ${contractName} from registry at ${this.Registry.contract.address}
- correct registry? does it have version entry? - ${error.message}`
);
});
});
return RSVP.all(addressPromises).then(() => { return this });
}
static setup(provider, signer, ipfsConfig = null) {
console.log('Kredits.setup() is deprecated use new Kredits().init() instead');
return new Kredits(provider, signer, { ipfsConfig: ipfsConfig }).init();
}
get Kernel() {
return this.contractFor('Kernel');
}
get Contributor() {
return this.contractFor('Contributor');
}
get Contributors() {
console.log('Contributors is deprecated use Contributor instead');
return this.Contributor;
}
get Proposal() {
return this.contractFor('Proposal');
}
get Token() {
return this.contractFor('Token');
}
get Contribution() {
return this.contractFor('Contribution');
}
get Acl() {
return this.contractFor('Acl');
}
// Should be private
contractFor(name) {
if (this.contracts[name]) {
return this.contracts[name];
}
const contractName = capitalize(name);
const address = this.addresses[contractName];
const abi = this.abis[contractName];
if (!address || !abi) {
throw new Error(`Address or ABI not found for ${contractName}`);
}
let signerOrProvider = this.signer || this.provider;
let contract = new ethers.Contract(address, abi, signerOrProvider);
this.contracts[name] = new Contracts[contractName](contract);
this.contracts[name].ipfs = this.ipfs;
return this.contracts[name];
}
preflightChecks() {
return new Preflight(this).check();
}
}
module.exports = Kredits;