Compare commits
34 Commits
v5.2.0
...
fix/ipfs-c
| Author | SHA1 | Date | |
|---|---|---|---|
| 2af9476a3f | |||
| d643e5842c | |||
| a87d5326bf | |||
| c9fed46054 | |||
| 6f2097ed46 | |||
| 94d342ce63 | |||
| f984dec95a | |||
| 145b3ea766 | |||
| a80dfee5c5 | |||
| 4649de24c8 | |||
| 8539b56a48 | |||
| f59c37827a | |||
| 58db57ee45 | |||
| b64a7ca299 | |||
| 6f09ca8d13 | |||
| 6f53c8097e | |||
| 6b2ac15f56 | |||
| 359989f235 | |||
| 5894f6323b | |||
| 09b78e1e8f | |||
| 48c8f6b9b3 | |||
| 791190f5e7 | |||
| 375d8f3275 | |||
| 3cb94fb660 | |||
| 7a6b117876 | |||
| f945b378e2 | |||
| b5b12e22ce | |||
| fe811cdb12 | |||
| 42df6fe310 | |||
| c8805be054 | |||
| 764f63fc8c | |||
| f73ccedf42 | |||
| a9093c1c40 | |||
| e405644b1d |
32
.eslintrc.js
Normal file
32
.eslintrc.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
module.exports = {
|
||||||
|
'env': {
|
||||||
|
'browser': true,
|
||||||
|
'es6': true,
|
||||||
|
'node': true
|
||||||
|
},
|
||||||
|
'extends': 'eslint:recommended',
|
||||||
|
'globals': {
|
||||||
|
'Atomics': 'readonly',
|
||||||
|
'SharedArrayBuffer': 'readonly'
|
||||||
|
},
|
||||||
|
'parserOptions': {
|
||||||
|
'ecmaVersion': 2018,
|
||||||
|
'sourceType': 'module'
|
||||||
|
},
|
||||||
|
'rules': {
|
||||||
|
'comma-dangle': ['error', {
|
||||||
|
arrays: 'always-multiline',
|
||||||
|
objects: 'always-multiline',
|
||||||
|
imports: 'never',
|
||||||
|
exports: 'never',
|
||||||
|
functions: 'ignore',
|
||||||
|
}],
|
||||||
|
'eol-last': ['error', 'always'],
|
||||||
|
semi: ['error', 'always'],
|
||||||
|
'space-before-function-paren': ['error', {
|
||||||
|
anonymous: 'never',
|
||||||
|
named: 'always',
|
||||||
|
asyncArrow: 'always',
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
9
.solhint.json
Normal file
9
.solhint.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"solhint:default",
|
||||||
|
"solhint:recommended"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"indent": "2"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
.travis.yml
Normal file
26
.travis.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "11"
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
dist: xenial
|
||||||
|
|
||||||
|
cache:
|
||||||
|
yarn: true
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||||
|
- export PATH=$HOME/.yarn/bin:$PATH
|
||||||
|
|
||||||
|
install:
|
||||||
|
- yarn install --no-lockfile --non-interactive
|
||||||
|
|
||||||
|
script:
|
||||||
|
- yarn lint:wrapper
|
||||||
|
- yarn lint:contract-tests
|
||||||
|
# - yarn lint:contracts
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
12
apps/.eslintrc.js
Normal file
12
apps/.eslintrc.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module.exports = {
|
||||||
|
'globals': {
|
||||||
|
contract: true,
|
||||||
|
describe: true,
|
||||||
|
it: true,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-unused-vars': ['error', {
|
||||||
|
'argsIgnorePattern': '^_',
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
const Contribution = artifacts.require('Contribution.sol')
|
// const Contribution = artifacts.require('Contribution.sol');
|
||||||
|
|
||||||
contract('Contribution', (accounts) => {
|
contract('Contribution', (_accounts) => {
|
||||||
it('should be tested')
|
it('should be tested');
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const Contributor = artifacts.require('Contributor.sol')
|
// const Contributor = artifacts.require('Contributor.sol');
|
||||||
|
|
||||||
contract('Contributor', (accounts) => {
|
contract('Contributor', (_accounts) => {
|
||||||
it('should be tested')
|
it('should be tested');
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const Proposal = artifacts.require('Proposal.sol')
|
// const Proposal = artifacts.require('Proposal.sol');
|
||||||
|
|
||||||
contract('Proposal', (accounts) => {
|
contract('Proposal', (_accounts) => {
|
||||||
it('should be tested')
|
it('should be tested');
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const Token = artifacts.require('Token.sol')
|
// const Token = artifacts.require('Token.sol');
|
||||||
|
|
||||||
contract('Token', (accounts) => {
|
contract('Token', (_accounts) => {
|
||||||
it('should be tested')
|
it('should be tested');
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -1,7 +1,36 @@
|
|||||||
const contractCalls = [
|
const contractCalls = [
|
||||||
['Contributor', 'add', [{ account: '0x7e8f313c56f809188313aa274fa67ee58c31515d', name: 'bumi', kind: 'person', url: '', github_username: 'bumi', github_uid: 318, wiki_username: 'Bumi' }, { gasLimit: 200000 }]],
|
['Contributor', 'add', [{
|
||||||
['Contributor', 'add', [{ account: '0x49575f3DD9a0d60aE661BC992f72D837A77f05Bc', name: 'raucao', kind: 'person', url: '', github_username: 'skddc', github_uid: 842, wiki_username: 'Basti' }, { gasLimit: 200000 }]],
|
account: '0x7e8f313c56f809188313aa274fa67ee58c31515d',
|
||||||
['Contributor', 'add', [{ account: '0xF722709ECC3B05c19d02E82a2a4A4021B8F48C62', name: 'Manuel', kind: 'person', url: '', github_username: 'fsmanuel', github_uid: 54812, wiki_username: 'Manuel' }, { gasLimit: 200000 }]],
|
name: 'bumi',
|
||||||
|
kind: 'person',
|
||||||
|
url: '',
|
||||||
|
github_username: 'bumi',
|
||||||
|
github_uid: 318,
|
||||||
|
gitea_username: 'bumi',
|
||||||
|
wiki_username: 'Bumi'
|
||||||
|
}, { gasLimit: 200000 }]],
|
||||||
|
|
||||||
|
['Contributor', 'add', [{
|
||||||
|
account: '0x49575f3DD9a0d60aE661BC992f72D837A77f05Bc',
|
||||||
|
name: 'raucao',
|
||||||
|
kind: 'person',
|
||||||
|
url: '',
|
||||||
|
github_username: 'skddc',
|
||||||
|
github_uid: 842,
|
||||||
|
gitea_username: 'raucao',
|
||||||
|
wiki_username: 'Basti'
|
||||||
|
}, { gasLimit: 200000 }]],
|
||||||
|
|
||||||
|
['Contributor', 'add', [{
|
||||||
|
account: '0xF722709ECC3B05c19d02E82a2a4A4021B8F48C62',
|
||||||
|
name: 'Manuel',
|
||||||
|
kind: 'person',
|
||||||
|
url: '',
|
||||||
|
github_username: 'fsmanuel',
|
||||||
|
github_uid: 54812,
|
||||||
|
wiki_username: 'Manuel'
|
||||||
|
}, { gasLimit: 200000 }]],
|
||||||
|
|
||||||
['Proposal', 'addProposal', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-09', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Ran the seeds', url: '' }, { gasLimit: 350000 }]],
|
['Proposal', 'addProposal', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-09', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Ran the seeds', url: '' }, { gasLimit: 350000 }]],
|
||||||
['Proposal', 'addProposal', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-10', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Ran the seeds', url: '' }, { gasLimit: 350000 }]],
|
['Proposal', 'addProposal', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-10', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Ran the seeds', url: '' }, { gasLimit: 350000 }]],
|
||||||
['Proposal', 'addProposal', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Hacked on kredits', url: '' }, { gasLimit: 350000 }]],
|
['Proposal', 'addProposal', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Hacked on kredits', url: '' }, { gasLimit: 350000 }]],
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
# Contribution deployments
|
# Contribution deployments
|
||||||
|
|
||||||
|
aragon apm publish major --environment=rinkeby"
|
||||||
|
|
||||||
|
## 2019-04-24 update balances
|
||||||
|
|
||||||
|
✔ Successfully published kredits-contribution.open.aragonpm.eth v6.0.0:
|
||||||
|
ℹ Contract address: 0x2c083EEA83fd3a99C93759D97D0317A43261c758
|
||||||
|
ℹ Content (ipfs): QmULpSqz7BgTFmDu8AL7YZZEz525xkcEzf3dPKtbRdUtFs
|
||||||
|
ℹ Transaction hash: 0x8b01c4c00162e918659d267a2beaf33b578e2aaf9f427f1aa9a43029333c5cd7
|
||||||
|
|
||||||
## 2019-04-10 - Weltempfänger release
|
## 2019-04-10 - Weltempfänger release
|
||||||
|
|
||||||
✔ Successfully published kredits-contribution.open.aragonpm.eth v5.0.0:
|
✔ Successfully published kredits-contribution.open.aragonpm.eth v5.0.0:
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
# Contributor deployments
|
# Contributor deployments
|
||||||
|
|
||||||
|
aragon apm publish major --environment=rinkeby
|
||||||
|
|
||||||
|
## 2019-04-29 update balances
|
||||||
|
|
||||||
|
✔ Successfully published kredits-contributor.open.aragonpm.eth v5.0.0:
|
||||||
|
ℹ Contract address: 0xadefa3b66b68a127Fe38bEa1813b844EE69CFD86
|
||||||
|
ℹ Content (ipfs): QmeygbQgoj2McLWzo9hJayLWuBZqFaK4HTpa5qLeQdkn5K
|
||||||
|
ℹ Transaction hash: 0x4237a9636f6e4a8190e0d5bcfa85a452da097bf654a173a88e0e1de3d078f08d
|
||||||
|
|
||||||
|
|
||||||
## 2019-04-10 - Weltempfänger release
|
## 2019-04-10 - Weltempfänger release
|
||||||
|
|
||||||
✔ Successfully published kredits-contributor.open.aragonpm.eth v4.0.0:
|
✔ Successfully published kredits-contributor.open.aragonpm.eth v4.0.0:
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
# Kredits deployment
|
# Kredits deployment
|
||||||
|
|
||||||
|
## 2019-04-24 upgrade contributor and contribution
|
||||||
|
|
||||||
|
aragon dao upgrade 0xc34edf7d11b7f8433d597f0bb0697acdff55ef14 kredits-contributor.open.aragonpm.eth --environment=rinkeby
|
||||||
|
eth-provider | Invalid provider preset/location: "local"
|
||||||
|
✔ Fetching kredits-contributor.open.aragonpm.eth@latest
|
||||||
|
✔ Upgrading app
|
||||||
|
✔ Successfully executed: "Set the resolving address of 'kredits-contributor.open.aragonpm.eth' in namespace 'App code' to 0xadefa3b66b68a127Fe38bEa1813b844EE69CFD86"
|
||||||
|
|
||||||
|
|
||||||
|
aragon dao upgrade 0xc34edf7d11b7f8433d597f0bb0697acdff55ef14 kredits-contribution.open.aragonpm.eth --environment=rinkeby
|
||||||
|
✔ Fetching kredits-contribution.open.aragonpm.eth@latest
|
||||||
|
✔ Upgrading app
|
||||||
|
✔ Successfully executed: "Set the resolving address of 'kredits-contribution.open.aragonpm.eth' in namespace 'App code' to 0x2c083EEA83fd3a99C93759D97D0317A43261c758"
|
||||||
|
|
||||||
## 2019-04-10 - Weltempfänger release
|
## 2019-04-10 - Weltempfänger release
|
||||||
|
|
||||||
Using KreditsKit at: 0x76e069b47b79442657eaf0555a32c6b16fa1b8b4
|
Using KreditsKit at: 0x76e069b47b79442657eaf0555a32c6b16fa1b8b4
|
||||||
|
|||||||
@@ -2,11 +2,15 @@ const Base = require('./base');
|
|||||||
const EthersUtils = require('ethers').utils;
|
const EthersUtils = require('ethers').utils;
|
||||||
|
|
||||||
class Acl extends Base {
|
class Acl extends Base {
|
||||||
|
hasPermission (fromAddress, contractAddress, roleID, params = null) {
|
||||||
hasPermission(fromAddress, contractAddress, roleID, params = null) {
|
|
||||||
let roleHash = EthersUtils.keccak256(EthersUtils.toUtf8Bytes(roleID));
|
let roleHash = EthersUtils.keccak256(EthersUtils.toUtf8Bytes(roleID));
|
||||||
console.log(roleHash)
|
|
||||||
return this.functions.hasPermission(fromAddress, contractAddress, roleHash, params);
|
return this.functions.hasPermission(
|
||||||
|
fromAddress,
|
||||||
|
contractAddress,
|
||||||
|
roleHash,
|
||||||
|
params
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
class Base {
|
class Base {
|
||||||
constructor(contract) {
|
constructor (contract) {
|
||||||
this.contract = contract;
|
this.contract = contract;
|
||||||
}
|
}
|
||||||
|
|
||||||
get functions() {
|
get functions () {
|
||||||
return this.contract.functions;
|
return this.contract.functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
get ipfs() {
|
get ipfs () {
|
||||||
if (!this._ipfsAPI) { throw new Error('IPFS API not configured; please set an ipfs instance'); }
|
if (!this._ipfsAPI) { throw new Error('IPFS API not configured; please set an ipfs instance'); }
|
||||||
return this._ipfsAPI;
|
return this._ipfsAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
set ipfs(ipfsAPI) {
|
set ipfs (ipfsAPI) {
|
||||||
this._ipfsAPI = ipfsAPI;
|
this._ipfsAPI = ipfsAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
on(type, callback) {
|
on (type, callback) {
|
||||||
return this.contract.on(type, callback);
|
return this.contract.on(type, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,20 +6,19 @@ class Contribution extends Record {
|
|||||||
return this.functions.contributionsCount();
|
return this.functions.contributionsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
getById(id) {
|
getById (id) {
|
||||||
return this.functions.getContribution(id)
|
return this.functions.getContribution(id)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
|
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getByContributorId(contributorId) {
|
getByContributorId (contributorId) {
|
||||||
return this.functions.getContributorAddressById(contributorId)
|
return this.functions.getContributorAddressById(contributorId)
|
||||||
.then(address => this.getByContributorAddress(address));
|
.then(address => this.getByContributorAddress(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
getByContributorAddress(address) {
|
getByContributorAddress (address) {
|
||||||
return this.functions.balanceOf(address)
|
return this.functions.balanceOf(address)
|
||||||
.then(async (balance) => {
|
.then(async (balance) => {
|
||||||
const count = balance.toNumber();
|
const count = balance.toNumber();
|
||||||
@@ -35,7 +34,7 @@ class Contribution extends Record {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async addContribution(contributionAttr, callOptions = {}) {
|
async addContribution (contributionAttr, callOptions = {}) {
|
||||||
const contribution = new ContributionSerializer(contributionAttr);
|
const contribution = new ContributionSerializer(contributionAttr);
|
||||||
|
|
||||||
try { await contribution.validate(); }
|
try { await contribution.validate(); }
|
||||||
|
|||||||
@@ -1,27 +1,29 @@
|
|||||||
const Record = require('./record');
|
const Record = require('./record');
|
||||||
const ContributorSerializer = require('../serializers/contributor');
|
const ContributorSerializer = require('../serializers/contributor');
|
||||||
|
const formatKredits = require('../utils/format-kredits');
|
||||||
|
|
||||||
class Contributor extends Record {
|
class Contributor extends Record {
|
||||||
get count () {
|
get count () {
|
||||||
return this.functions.contributorsCount();
|
return this.functions.contributorsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
getById(id) {
|
getById (id) {
|
||||||
return this.functions.getContributorById(id)
|
return this.functions.getContributorById(id)
|
||||||
.then((data) => {
|
.then(data => {
|
||||||
|
data.balanceInt = formatKredits(data.balance);
|
||||||
return this.ipfs.catAndMerge(data, ContributorSerializer.deserialize);
|
return this.ipfs.catAndMerge(data, ContributorSerializer.deserialize);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
filterByAccount(search) {
|
filterByAccount (search) {
|
||||||
return this._byAccount(search, 'filter');
|
return this._byAccount(search, 'filter');
|
||||||
}
|
}
|
||||||
|
|
||||||
findByAccount(search) {
|
findByAccount (search) {
|
||||||
return this._byAccount(search, 'find');
|
return this._byAccount(search, 'find');
|
||||||
}
|
}
|
||||||
|
|
||||||
_byAccount(search, method = 'filter') {
|
_byAccount (search, method = 'filter') {
|
||||||
return this.all().then((contributors) => {
|
return this.all().then((contributors) => {
|
||||||
const searchEntries = Object.entries(search);
|
const searchEntries = Object.entries(search);
|
||||||
|
|
||||||
@@ -37,7 +39,7 @@ class Contributor extends Record {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async add(contributorAttr, callOptions = {}) {
|
async add (contributorAttr, callOptions = {}) {
|
||||||
let contributor = new ContributorSerializer(contributorAttr);
|
let contributor = new ContributorSerializer(contributorAttr);
|
||||||
|
|
||||||
try { await contributor.validate(); }
|
try { await contributor.validate(); }
|
||||||
@@ -59,9 +61,9 @@ class Contributor extends Record {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProfile(contributorId, updateAttr, callOptions = {}) {
|
updateProfile (contributorId, updateAttr, callOptions = {}) {
|
||||||
return this.getById(contributorId).then(async (contributor) => {
|
return this.getById(contributorId).then(async (contributor) => {
|
||||||
let updatedContributorAttr = Object.assign(contributor, updateAttr)
|
let updatedContributorAttr = Object.assign(contributor, updateAttr);
|
||||||
let updatedContributor = new ContributorSerializer(updatedContributorAttr);
|
let updatedContributor = new ContributorSerializer(updatedContributorAttr);
|
||||||
|
|
||||||
try { await updatedContributor.validate(); }
|
try { await updatedContributor.validate(); }
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ module.exports = {
|
|||||||
Proposal: require('./proposal'),
|
Proposal: require('./proposal'),
|
||||||
Token: require('./token'),
|
Token: require('./token'),
|
||||||
Kernel: require('./kernel'),
|
Kernel: require('./kernel'),
|
||||||
Acl: require('./acl')
|
Acl: require('./acl'),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,19 +4,19 @@ const Base = require('./base');
|
|||||||
const KERNEL_APP_ADDR_NAMESPACE = '0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb';
|
const KERNEL_APP_ADDR_NAMESPACE = '0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb';
|
||||||
|
|
||||||
class Kernel extends Base {
|
class Kernel extends Base {
|
||||||
constructor(contract) {
|
constructor (contract) {
|
||||||
super(contract);
|
super(contract);
|
||||||
this.apm = 'aragonpm.eth'; // can be overwritten if needed
|
this.apm = 'aragonpm.eth'; // can be overwritten if needed
|
||||||
}
|
}
|
||||||
|
|
||||||
getApp(appName) {
|
getApp (appName) {
|
||||||
if (appName === 'Acl') {
|
if (appName === 'Acl') {
|
||||||
return this.functions.acl();
|
return this.functions.acl();
|
||||||
}
|
}
|
||||||
return this.functions.getApp(KERNEL_APP_ADDR_NAMESPACE, this.appNamehash(appName));
|
return this.functions.getApp(KERNEL_APP_ADDR_NAMESPACE, this.appNamehash(appName));
|
||||||
}
|
}
|
||||||
|
|
||||||
appNamehash(appName) {
|
appNamehash (appName) {
|
||||||
return namehash(`kredits-${appName.toLowerCase()}.${this.apm}`);
|
return namehash(`kredits-${appName.toLowerCase()}.${this.apm}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ class Proposal extends Record {
|
|||||||
return this.functions.proposalsCount();
|
return this.functions.proposalsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
getById(id) {
|
getById (id) {
|
||||||
return this.functions.getProposal(id)
|
return this.functions.getProposal(id)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
|
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async addProposal(proposalAttr, callOptions = {}) {
|
async addProposal (proposalAttr, callOptions = {}) {
|
||||||
const contribution = new ContributionSerializer(proposalAttr);
|
const contribution = new ContributionSerializer(proposalAttr);
|
||||||
|
|
||||||
try { await contribution.validate(); }
|
try { await contribution.validate(); }
|
||||||
@@ -37,4 +37,4 @@ class Proposal extends Record {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Proposal
|
module.exports = Proposal;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const Base = require('./base');
|
|||||||
const paged = require('../utils/pagination');
|
const paged = require('../utils/pagination');
|
||||||
|
|
||||||
class Record extends Base {
|
class Record extends Base {
|
||||||
all(options = {}) {
|
all (options = {}) {
|
||||||
return this.count
|
return this.count
|
||||||
.then((count) => {
|
.then((count) => {
|
||||||
let records = paged(count, options).map((id) => this.getById(id));
|
let records = paged(count, options).map((id) => this.getById(id));
|
||||||
@@ -11,4 +11,4 @@ class Record extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Record
|
module.exports = Record;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const ethers = require('ethers');
|
const ethers = require('ethers');
|
||||||
|
|
||||||
const Preflight = require('./utils/preflight');
|
const Preflight = require('./utils/preflight');
|
||||||
|
const deprecate = require('./utils/deprecate');
|
||||||
|
|
||||||
const ABIS = {
|
const ABIS = {
|
||||||
Contributor: require('./abis/Contributor.json'),
|
Contributor: require('./abis/Contributor.json'),
|
||||||
@@ -8,29 +9,29 @@ const ABIS = {
|
|||||||
Token: require('./abis/Token.json'),
|
Token: require('./abis/Token.json'),
|
||||||
Proposal: require('./abis/Proposal.json'),
|
Proposal: require('./abis/Proposal.json'),
|
||||||
Kernel: require('./abis/Kernel.json'),
|
Kernel: require('./abis/Kernel.json'),
|
||||||
Acl: require('./abis/ACL.json')
|
Acl: require('./abis/ACL.json'),
|
||||||
};
|
};
|
||||||
const APP_CONTRACTS = [
|
const APP_CONTRACTS = [
|
||||||
'Contributor',
|
'Contributor',
|
||||||
'Contribution',
|
'Contribution',
|
||||||
'Token',
|
'Token',
|
||||||
'Proposal',
|
'Proposal',
|
||||||
'Acl'
|
'Acl',
|
||||||
];
|
];
|
||||||
const DaoAddresses = require('./addresses/dao.json');
|
const DaoAddresses = require('./addresses/dao.json');
|
||||||
|
|
||||||
const Contracts = require('./contracts');
|
const Contracts = require('./contracts');
|
||||||
const IPFS = require('./utils/ipfs')
|
const IPFS = require('./utils/ipfs');
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
function capitalize(word) {
|
function capitalize (word) {
|
||||||
let [first, ...rest] = word;
|
let [first, ...rest] = word;
|
||||||
return `${first.toUpperCase()}${rest.join('')}`;
|
return `${first.toUpperCase()}${rest.join('')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Kredits {
|
class Kredits {
|
||||||
|
|
||||||
constructor(provider, signer, options = {}) {
|
constructor (provider, signer, options = {}) {
|
||||||
let { addresses, abis, ipfsConfig } = options;
|
let { addresses, abis, ipfsConfig } = options;
|
||||||
|
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
@@ -40,33 +41,35 @@ class Kredits {
|
|||||||
this.abis = abis || ABIS;
|
this.abis = abis || ABIS;
|
||||||
this.ipfs = new IPFS(ipfsConfig);
|
this.ipfs = new IPFS(ipfsConfig);
|
||||||
this.contracts = {};
|
this.contracts = {};
|
||||||
|
this.networkId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
init(names) {
|
init (names) {
|
||||||
let contractsToLoad = names || APP_CONTRACTS;
|
let contractsToLoad = names || APP_CONTRACTS;
|
||||||
return this.provider.getNetwork().then(network => {
|
return this.provider.getNetwork().then(network => {
|
||||||
this.addresses['Kernel'] = this.addresses['Kernel'] || DaoAddresses[network.chainId.toString()];
|
this.networkId = network.chainId.toString();
|
||||||
|
this.addresses['Kernel'] = this.addresses['Kernel'] || DaoAddresses[this.networkId];
|
||||||
|
|
||||||
let addressPromises = contractsToLoad.map((contractName) => {
|
let addressPromises = contractsToLoad.map((contractName) => {
|
||||||
return this.Kernel.getApp(contractName).then((address) => {
|
return this.Kernel.getApp(contractName).then((address) => {
|
||||||
this.addresses[contractName] = address;
|
this.addresses[contractName] = address;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.log(error);
|
|
||||||
throw new Error(`Failed to get address for ${contractName} from DAO at ${this.Kernel.contract.address}
|
throw new Error(`Failed to get address for ${contractName} from DAO at ${this.Kernel.contract.address}
|
||||||
- ${error.message}`
|
- ${error.message}`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(addressPromises).then(() => { return this });
|
return Promise.all(addressPromises).then(() => { return this; });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static setup(provider, signer, ipfsConfig = null) {
|
static setup (provider, signer, ipfsConfig = null) {
|
||||||
console.log('Kredits.setup() is deprecated use new Kredits().init() instead');
|
deprecate('Kredits.setup() is deprecated use new Kredits().init() instead');
|
||||||
return new Kredits(provider, signer, { ipfsConfig: ipfsConfig }).init();
|
return new Kredits(provider, signer, { ipfsConfig: ipfsConfig }).init();
|
||||||
}
|
}
|
||||||
|
|
||||||
get Kernel() {
|
get Kernel () {
|
||||||
let k = this.contractFor('Kernel');
|
let k = this.contractFor('Kernel');
|
||||||
// in case we want to use a special apm (e.g. development vs. production)
|
// in case we want to use a special apm (e.g. development vs. production)
|
||||||
if (this.options.apm) {
|
if (this.options.apm) {
|
||||||
@@ -75,37 +78,37 @@ class Kredits {
|
|||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
get Contributor() {
|
get Contributor () {
|
||||||
return this.contractFor('Contributor');
|
return this.contractFor('Contributor');
|
||||||
}
|
}
|
||||||
|
|
||||||
get Contributors() {
|
get Contributors () {
|
||||||
console.log('Contributors is deprecated use Contributor instead');
|
deprecate('Contributors is deprecated use Contributor instead');
|
||||||
return this.Contributor;
|
return this.Contributor;
|
||||||
}
|
}
|
||||||
|
|
||||||
get Proposal() {
|
get Proposal () {
|
||||||
return this.contractFor('Proposal');
|
return this.contractFor('Proposal');
|
||||||
}
|
}
|
||||||
|
|
||||||
get Operator() {
|
get Operator () {
|
||||||
return this.Proposal;
|
return this.Proposal;
|
||||||
}
|
}
|
||||||
|
|
||||||
get Token() {
|
get Token () {
|
||||||
return this.contractFor('Token');
|
return this.contractFor('Token');
|
||||||
}
|
}
|
||||||
|
|
||||||
get Contribution() {
|
get Contribution () {
|
||||||
return this.contractFor('Contribution');
|
return this.contractFor('Contribution');
|
||||||
}
|
}
|
||||||
|
|
||||||
get Acl() {
|
get Acl () {
|
||||||
return this.contractFor('Acl');
|
return this.contractFor('Acl');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be private
|
// Should be private
|
||||||
contractFor(name) {
|
contractFor (name) {
|
||||||
if (this.contracts[name]) {
|
if (this.contracts[name]) {
|
||||||
return this.contracts[name];
|
return this.contracts[name];
|
||||||
}
|
}
|
||||||
@@ -125,7 +128,7 @@ class Kredits {
|
|||||||
return this.contracts[name];
|
return this.contracts[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
preflightChecks() {
|
preflightChecks () {
|
||||||
return new Preflight(this).check();
|
return new Preflight(this).check();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const validator = require('../utils/validator');
|
|||||||
*/
|
*/
|
||||||
class Contribution {
|
class Contribution {
|
||||||
|
|
||||||
constructor(attrs) {
|
constructor (attrs) {
|
||||||
Object.keys(attrs).forEach(a => this[a] = attrs[a]);
|
Object.keys(attrs).forEach(a => this[a] = attrs[a]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,24 +26,24 @@ class Contribution {
|
|||||||
kind,
|
kind,
|
||||||
description,
|
description,
|
||||||
url,
|
url,
|
||||||
details
|
details,
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
"@context": "https://schema.kosmos.org",
|
'@context': 'https://schema.kosmos.org',
|
||||||
"@type": "Contribution",
|
'@type': 'Contribution',
|
||||||
"contributor": {
|
'contributor': {
|
||||||
"ipfs": contributorIpfsHash
|
'ipfs': contributorIpfsHash,
|
||||||
},
|
},
|
||||||
date,
|
date,
|
||||||
time,
|
time,
|
||||||
kind,
|
kind,
|
||||||
description,
|
description,
|
||||||
"details": details || {}
|
'details': details || {},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
data["url"] = url;
|
data['url'] = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write it pretty to ipfs
|
// Write it pretty to ipfs
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const validator = require('../utils/validator');
|
|||||||
*/
|
*/
|
||||||
class Contributor {
|
class Contributor {
|
||||||
|
|
||||||
constructor(attrs) {
|
constructor (attrs) {
|
||||||
Object.keys(attrs).forEach(a => this[a] = attrs[a]);
|
Object.keys(attrs).forEach(a => this[a] = attrs[a]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,35 +26,44 @@ class Contributor {
|
|||||||
url,
|
url,
|
||||||
github_uid,
|
github_uid,
|
||||||
github_username,
|
github_username,
|
||||||
|
gitea_username,
|
||||||
wiki_username,
|
wiki_username,
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
"@context": "https://schema.kosmos.org",
|
'@context': 'https://schema.kosmos.org',
|
||||||
"@type": "Contributor",
|
'@type': 'Contributor',
|
||||||
kind,
|
kind,
|
||||||
name,
|
name,
|
||||||
"accounts": []
|
'accounts': [],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
data["url"] = url;
|
data['url'] = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (github_uid) {
|
if (github_uid) {
|
||||||
data.accounts.push({
|
data.accounts.push({
|
||||||
"site": "github.com",
|
'site': 'github.com',
|
||||||
"uid": github_uid,
|
'uid': github_uid,
|
||||||
"username": github_username,
|
'username': github_username,
|
||||||
"url": `https://github.com/${github_username}`
|
'url': `https://github.com/${github_username}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gitea_username) {
|
||||||
|
data.accounts.push({
|
||||||
|
'site': 'gitea.kosmos.org',
|
||||||
|
'username': gitea_username,
|
||||||
|
'url': `https://gitea.kosmos.org/${gitea_username}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wiki_username) {
|
if (wiki_username) {
|
||||||
data.accounts.push({
|
data.accounts.push({
|
||||||
"site": "wiki.kosmos.org",
|
'site': 'wiki.kosmos.org',
|
||||||
"username": wiki_username,
|
'username': wiki_username,
|
||||||
"url": `https://wiki.kosmos.org/User:${wiki_username}`
|
'url': `https://wiki.kosmos.org/User:${wiki_username}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,13 +96,17 @@ class Contributor {
|
|||||||
accounts,
|
accounts,
|
||||||
} = JSON.parse(serialized.toString('utf8'));
|
} = JSON.parse(serialized.toString('utf8'));
|
||||||
|
|
||||||
let github_username, github_uid, wiki_username;
|
let github_username, github_uid, gitea_username, wiki_username;
|
||||||
let github = accounts.find((a) => a.site === 'github.com');
|
let github = accounts.find(a => a.site === 'github.com');
|
||||||
let wiki = accounts.find((a) => a.site === 'wiki.kosmos.org');
|
let gitea = accounts.find(a => a.site === 'gitea.kosmos.org');
|
||||||
|
let wiki = accounts.find(a => a.site === 'wiki.kosmos.org');
|
||||||
|
|
||||||
if (github) {
|
if (github) {
|
||||||
(({ username: github_username, uid: github_uid} = github));
|
(({ username: github_username, uid: github_uid} = github));
|
||||||
}
|
}
|
||||||
|
if (gitea) {
|
||||||
|
(({ username: gitea_username } = gitea));
|
||||||
|
}
|
||||||
if (wiki) {
|
if (wiki) {
|
||||||
(({ username: wiki_username } = wiki));
|
(({ username: wiki_username } = wiki));
|
||||||
}
|
}
|
||||||
@@ -105,6 +118,7 @@ class Contributor {
|
|||||||
accounts,
|
accounts,
|
||||||
github_uid,
|
github_uid,
|
||||||
github_username,
|
github_username,
|
||||||
|
gitea_username,
|
||||||
wiki_username,
|
wiki_username,
|
||||||
ipfsData: serialized,
|
ipfsData: serialized,
|
||||||
};
|
};
|
||||||
|
|||||||
5
lib/utils/deprecate.js
Normal file
5
lib/utils/deprecate.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/*eslint no-console: ["error", { allow: ["warn"] }] */
|
||||||
|
|
||||||
|
module.exports = function deprecate (msg) {
|
||||||
|
console.warn(msg);
|
||||||
|
};
|
||||||
10
lib/utils/format-kredits.js
Normal file
10
lib/utils/format-kredits.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
const ethersUtils = require('ethers').utils;
|
||||||
|
|
||||||
|
module.exports = function(value, options = {}) {
|
||||||
|
let etherValue = ethersUtils.formatEther(value);
|
||||||
|
if (options.asFloat) {
|
||||||
|
return parseFloat(etherValue);
|
||||||
|
} else {
|
||||||
|
return parseInt(etherValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -2,8 +2,7 @@ const ipfsClient = require('ipfs-http-client');
|
|||||||
const multihashes = require('multihashes');
|
const multihashes = require('multihashes');
|
||||||
|
|
||||||
class IPFS {
|
class IPFS {
|
||||||
|
constructor (config) {
|
||||||
constructor(config) {
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
config = { host: 'localhost', port: '5001', protocol: 'http' };
|
config = { host: 'localhost', port: '5001', protocol: 'http' };
|
||||||
}
|
}
|
||||||
@@ -11,7 +10,15 @@ class IPFS {
|
|||||||
this._config = config;
|
this._config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
catAndMerge(data, deserialize) {
|
get config () {
|
||||||
|
return this._config;
|
||||||
|
}
|
||||||
|
|
||||||
|
get peerId () {
|
||||||
|
return this._ipfsAPI.id();
|
||||||
|
}
|
||||||
|
|
||||||
|
catAndMerge (data, deserialize) {
|
||||||
// if no hash details are found simply return the data; nothing to merge
|
// if no hash details are found simply return the data; nothing to merge
|
||||||
if (!data.hashSize || data.hashSize === 0) {
|
if (!data.hashSize || data.hashSize === 0) {
|
||||||
return data;
|
return data;
|
||||||
@@ -26,7 +33,7 @@ class IPFS {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add(data) {
|
add (data) {
|
||||||
return this._ipfsAPI
|
return this._ipfsAPI
|
||||||
.add(ipfsClient.Buffer.from(data))
|
.add(ipfsClient.Buffer.from(data))
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -34,7 +41,7 @@ class IPFS {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cat(hashData) {
|
cat (hashData) {
|
||||||
let ipfsHash = hashData; // default - if it is a string
|
let ipfsHash = hashData; // default - if it is a string
|
||||||
if (hashData.hasOwnProperty('hashSize')) {
|
if (hashData.hasOwnProperty('hashSize')) {
|
||||||
ipfsHash = this.encodeHash(hashData);
|
ipfsHash = this.encodeHash(hashData);
|
||||||
@@ -42,21 +49,20 @@ class IPFS {
|
|||||||
return this._ipfsAPI.cat(ipfsHash);
|
return this._ipfsAPI.cat(ipfsHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeHash(ipfsHash) {
|
decodeHash (ipfsHash) {
|
||||||
let multihash = multihashes.decode(multihashes.fromB58String(ipfsHash));
|
let multihash = multihashes.decode(multihashes.fromB58String(ipfsHash));
|
||||||
return {
|
return {
|
||||||
hashDigest: '0x' + multihashes.toHexString(multihash.digest),
|
hashDigest: '0x' + multihashes.toHexString(multihash.digest),
|
||||||
hashSize: multihash.length,
|
hashSize: multihash.length,
|
||||||
hashFunction: multihash.code,
|
hashFunction: multihash.code,
|
||||||
ipfsHash: ipfsHash
|
ipfsHash: ipfsHash,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeHash(hashData) {
|
encodeHash (hashData) {
|
||||||
let digest = ipfsClient.Buffer.from(hashData.hashDigest.slice(2), 'hex');
|
let digest = ipfsClient.Buffer.from(hashData.hashDigest.slice(2), 'hex');
|
||||||
return multihashes.encode(digest, hashData.hashFunction, hashData.hashSize);
|
return multihashes.encode(digest, hashData.hashFunction, hashData.hashSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = IPFS;
|
module.exports = IPFS;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
function pageNumber(number, size, recordCount) {
|
function pageNumber (number, size, recordCount) {
|
||||||
let numberOfPages = Math.ceil(recordCount / size);
|
let numberOfPages = Math.ceil(recordCount / size);
|
||||||
|
|
||||||
number = parseInt(number) || 1;
|
number = parseInt(number) || 1;
|
||||||
@@ -10,7 +10,7 @@ function pageNumber(number, size, recordCount) {
|
|||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildIds(order, number, size, recordCount) {
|
function buildIds (order, number, size, recordCount) {
|
||||||
let offset = size * (number - 1);
|
let offset = size * (number - 1);
|
||||||
|
|
||||||
let start;
|
let start;
|
||||||
@@ -34,7 +34,7 @@ function buildIds(order, number, size, recordCount) {
|
|||||||
return Array.from({ length: size }, mapFunction);
|
return Array.from({ length: size }, mapFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function paged(recordCount, options = {}) {
|
module.exports = function paged (recordCount, options = {}) {
|
||||||
let { order, page } = options;
|
let { order, page } = options;
|
||||||
order = order || 'desc';
|
order = order || 'desc';
|
||||||
page = page || {};
|
page = page || {};
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
class Preflight {
|
class Preflight {
|
||||||
constructor(kredits) {
|
constructor (kredits) {
|
||||||
this.kredits = kredits;
|
this.kredits = kredits;
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check () {
|
||||||
return this.kredits.ipfs._ipfsAPI.id()
|
return this.kredits.ipfs.peerId()
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
throw new Error(`IPFS node not available; config: ${JSON.stringify(this.kredits.ipfs.config)} - ${error.message}`);
|
const ipfsConfig = JSON.stringify(this.kredits.ipfs.config);
|
||||||
|
throw new Error(`IPFS node not available; config: ${ipfsConfig} - ${error.message}`);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
let promises = Object.keys(this.kredits.contracts).map((name) => {
|
let promises = Object.keys(this.kredits.contracts).map((name) => {
|
||||||
let contractWrapper = this.kredits.contracts[name];
|
let address = this.kredits.contracts[name].contract.address;
|
||||||
return this.kredits.provider.getCode(contractWrapper.contract.address).then((code) => {
|
|
||||||
|
// TODO: I think this throws the error: Error: contract not deployed
|
||||||
|
// I guess we don't need that if check anymore...
|
||||||
|
return this.kredits.provider.getCode(address).then((code) => {
|
||||||
// not sure if we always get the same return value if the code is not available
|
// not sure if we always get the same return value if the code is not available
|
||||||
// so checking if it is < 5 long
|
// so checking if it is < 5 long
|
||||||
if (code === '0x00' || code.length < 5) {
|
if (code === '0x00' || code.length < 5) {
|
||||||
throw new Error(`Contract for: ${name} not found at ${contractWrapper.contract.address} on network ${this.kredits.provider.chainId}`);
|
throw new Error(`Contract for: ${name} not found at ${address} on network ${this.kredits.networkId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ const validator = tv4.freshApi();
|
|||||||
validator.addFormat({
|
validator.addFormat({
|
||||||
'date': function(value) {
|
'date': function(value) {
|
||||||
const dateRegexp = /^[0-9]{4,}-[0-9]{2}-[0-9]{2}$/;
|
const dateRegexp = /^[0-9]{4,}-[0-9]{2}-[0-9]{2}$/;
|
||||||
return dateRegexp.test(value) ? null : "A valid ISO 8601 full-date string is expected";
|
return dateRegexp.test(value) ? null : 'A valid ISO 8601 full-date string is expected';
|
||||||
},
|
},
|
||||||
'time': function(value) {
|
'time': function(value) {
|
||||||
const timeRegexp = /^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))$/;
|
const timeRegexp = /^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([+|-]([01][0-9]|2[0-3]):[0-5][0-9]))$/;
|
||||||
return timeRegexp.test(value) ? null : "A valid ISO 8601 full-time string is expected";
|
return timeRegexp.test(value) ? null : 'A valid ISO 8601 full-time string is expected';
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
module.exports = validator;
|
module.exports = validator;
|
||||||
|
|||||||
886
package-lock.json
generated
886
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "kredits-contracts",
|
"name": "kredits-contracts",
|
||||||
"version": "5.2.0",
|
"version": "5.3.0",
|
||||||
"description": "Ethereum contracts and npm wrapper for Kredits",
|
"description": "Ethereum contracts and npm wrapper for Kredits",
|
||||||
"main": "./lib/kredits.js",
|
"main": "./lib/kredits.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -20,6 +20,9 @@
|
|||||||
"deploy:apps": "./scripts/every-app.sh \"aragon apm publish major\"",
|
"deploy:apps": "./scripts/every-app.sh \"aragon apm publish major\"",
|
||||||
"devchain": "aragon devchain --port 7545",
|
"devchain": "aragon devchain --port 7545",
|
||||||
"dao:address": "truffle exec scripts/current-address.js",
|
"dao:address": "truffle exec scripts/current-address.js",
|
||||||
|
"lint:contracts": "solhint \"contracts/**/*.sol\" \"apps/*/contracts/**/*.sol\"",
|
||||||
|
"lint:contract-tests": "eslint apps/*/test",
|
||||||
|
"lint:wrapper": "eslint lib/",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -37,10 +40,15 @@
|
|||||||
"@aragon/kits-base": "^1.0.0",
|
"@aragon/kits-base": "^1.0.0",
|
||||||
"@aragon/os": "^4.1.0",
|
"@aragon/os": "^4.1.0",
|
||||||
"async-each-series": "^1.1.0",
|
"async-each-series": "^1.1.0",
|
||||||
|
"eslint": "^5.16.0",
|
||||||
|
"eslint-plugin-import": "^2.16.0",
|
||||||
|
"eslint-plugin-node": "^8.0.1",
|
||||||
|
"eslint-plugin-promise": "^4.1.1",
|
||||||
"eth-provider": "^0.2.2",
|
"eth-provider": "^0.2.2",
|
||||||
"openzeppelin-solidity": "^2.2.0",
|
"openzeppelin-solidity": "^2.2.0",
|
||||||
"promptly": "^3.0.3",
|
"promptly": "^3.0.3",
|
||||||
"solc": "^0.4.25"
|
"solc": "^0.4.25",
|
||||||
|
"solhint": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ethers": "^4.0.27",
|
"ethers": "^4.0.27",
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ module.exports = async function(callback) {
|
|||||||
|
|
||||||
console.log(table.toString());
|
console.log(table.toString());
|
||||||
|
|
||||||
let totalContributionBalances = await kredits.Contribution.functions.totalCount(true);
|
let totalKreditsEarned = await kredits.Contribution.functions.totalKreditsEarned(true);
|
||||||
console.log(`Total confirmed balance: ${totalContributionBalances}`);
|
console.log(`Total confirmed kredits: ${totalKreditsEarned}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,26 +21,25 @@ module.exports = async function(callback) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const contributors = await kredits.Contributor.all()
|
const contributors = await kredits.Contributor.all()
|
||||||
|
|
||||||
|
contributors.forEach((c) => {
|
||||||
|
table.push([
|
||||||
|
c.id.toString(),
|
||||||
|
c.account,
|
||||||
|
`${c.name}`,
|
||||||
|
c.isCore,
|
||||||
|
c.balanceInt.toString(),
|
||||||
|
c.totalKreditsEarned.toString(),
|
||||||
|
c.contributionsCount.toString(),
|
||||||
|
c.ipfsHash
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(table.toString())
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
callback(e);
|
callback(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
contributors.forEach((c) => {
|
|
||||||
table.push([
|
|
||||||
c.id.toString(),
|
|
||||||
c.account,
|
|
||||||
`${c.name}`,
|
|
||||||
c.isCore,
|
|
||||||
ethers.utils.formatEther(c.balance),
|
|
||||||
c.totalKreditsEarned.toString(),
|
|
||||||
c.contributionsCount.toString(),
|
|
||||||
c.ipfsHash
|
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log(table.toString())
|
|
||||||
|
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user