Merge branch 'master' into feature/store-models-in-service

# Conflicts:
#	app/controllers/index.js
#	tests/unit/controllers/index-test.js
This commit is contained in:
2018-04-15 20:23:39 +02:00
11 changed files with 53 additions and 34 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ export default Component.extend({
// Default attributes used by reset
attributes: {
recipientId: null,
contributorId: null,
kind: 'community',
amount: null,
description: null,
@@ -22,7 +22,7 @@ export default Component.extend({
contributors: [],
isValidRecipient: isPresent('recipientId'),
isValidRecipient: isPresent('contributorId'),
isValidAmount: computed('amount', function() {
return parseInt(this.get('amount'), 10) > 0;
}),
+2 -2
View File
@@ -1,9 +1,9 @@
<form {{action "submit" on="submit"}}>
<p>
<select required onchange={{action (mut recipientId) value="target.value"}}>
<select required onchange={{action (mut contributorId) value="target.value"}}>
<option value="" selected disabled hidden>Contributor</option>
{{#each contributors as |contributor|}}
<option value={{contributor.id}} selected={{eq recipientId contributor.id}}>{{contributor.github_username}}</option>
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.github_username}}</option>
{{/each}}
</select>
</p>
+4 -5
View File
@@ -42,10 +42,9 @@ export default Controller.extend({
this.get('proposals').pushObject(proposal);
},
_handleProposalExecuted(proposalId, recipientId, amount) {
// TODO: check if proposalId is already a string
_handleProposalExecuted(proposalId, contributorId, amount) {
let proposal = this.get('proposals')
.findBy('id', proposalId.toString());
.findBy('id', proposalId);
if (proposal.get('isExecuted')) {
Ember.Logger.debug('[index] proposal already executed, not adding from event');
@@ -57,13 +56,13 @@ export default Controller.extend({
});
this.get('contributors')
.findBy('id', recipientId.toString())
.findBy('id', contributorId)
.incrementProperty('balance', amount);
},
_handleProposalVoted(proposalId, voter, totalVotes) {
this.get('proposals')
.findBy('id', proposalId.toString())
.findBy('id', proposalId)
.setProperties({ 'votesCount': totalVotes });
},
+1 -1
View File
@@ -11,7 +11,7 @@ export default Controller.extend({
actions: {
save(proposal) {
// contributorIpfsHash is needed for the proposal ipfs data. I'm not happy to do this here but I think to load all the contributors in addProposal again is a bit too much. I hope we can refactor it later.
let contributor = this.get('contributors').findBy('id', proposal.recipientId);
let contributor = this.get('contributors').findBy('id', proposal.contributorId);
proposal.contributorIpfsHash = contributor.get('ipfsHash');
return this.get('kredits').addProposal(proposal)
+1 -1
View File
@@ -47,7 +47,7 @@ export default class Operator extends Base {
.add(json)
.then((ipfsHashAttr) => {
let proposal = [
proposalAttr.recipientId,
proposalAttr.contributorId,
proposalAttr.amount,
ipfsHashAttr.ipfsHash,
ipfsHashAttr.hashFunction,
+35 -10
View File
@@ -27,22 +27,44 @@ export default class Kredits {
this.ipfsConfig = ipfsConfig;
this.ipfs = new IPFS(ipfsConfig);
let registryContract = this.initRegistryContract(provider);
return this.ipfs._ipfsAPI.id().catch((error) => {
throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`);
}).then(() => {
let addresses = Object.keys(contracts).reduce((mem, name) => {
let contractName = capitalize(name);
mem[contractName] = registryContract.functions.getProxyFor(contractName);
return mem;
}, {});
let registryContract = this.initRegistryContract(provider);
return RSVP.hash(addresses)
.then((addresses) => {
return new Kredits(provider, signer, addresses);
});
let addresses = Object.keys(contracts).reduce((mem, name) => {
let contractName = capitalize(name);
mem[contractName] = registryContract.functions.getProxyFor(contractName).catch((error) => {
throw new Error(`Failed to get address for ${contractName} from registry at ${registryContract.address}
- correct registry? does it have version entry? - ${error.message}`
);
});
return mem;
}, {});
return RSVP.hash(addresses)
.then((addresses) => {
return new Kredits(provider, signer, addresses);
});
});
}
static initRegistryContract(provider) {
let address = addresses['Registry'][provider.chainId];
if (!address) {
throw new Error(`Registry address not found; invalid network?
requested network: ${provider.chainId}
supported networks: ${Object.keys(addresses['Registry'])}
`);
}
provider.getCode(address).then((code) => {
// not sure if we always get the same return value of the code is not available
// that's why checking if it is < 5 long
if (code === '0x00' || code.length < 5) {
throw new Error(`Registry not found at ${address} on network ${provider.chainId}`);
}
});
let abi = abis['Registry'];
console.log('Initialize registry contract:', address, abi, provider);
return new ethers.Contract(address, abi, provider);
@@ -69,6 +91,9 @@ export default class Kredits {
let contractName = capitalize(name);
let address = this.addresses[contractName];
if (!address || !abis[contractName]) {
throw new Error(`Address or ABI not found for ${contractName}`);
}
let contract = new ethers.Contract(address, abis[contractName], this.signer);
this.contracts[name] = new contracts[contractName](contract);
-1
View File
@@ -51,5 +51,4 @@ export default class IPFS {
return multihashes.encode(digest, hashData.hashFunction, hashData.hashSize);
}
}
+4 -4
View File
@@ -8,8 +8,8 @@ export default EmberObject.extend({
// Contract
id: bignumber('idRaw', 'toString'),
creatorAddress: null,
recipientId: bignumber('recipientIdRaw', 'toString'),
creatorAccount: null,
contributorId: bignumber('contributorIdRaw', 'toString'),
amount: bignumber('amountRaw', 'toNumber'),
votesCount: bignumber('votesCountRaw', 'toNumber'),
votesNeeded: bignumber('votesNeededRaw', 'toNumber'),
@@ -28,7 +28,7 @@ export default EmberObject.extend({
// Relationships
// TODO: Optimize it. We don't need to find the contributor every time we add a new one
contributor: computed('recipientId', 'kredits.contributors.[]', function() {
return this.get('kredits.contributors').findBy('id', this.get('recipientId'));
contributor: computed('contributorId', 'kredits.contributors.[]', function() {
return this.get('kredits.contributors').findBy('id', this.get('contributorId'));
})
});
+2
View File
@@ -13,6 +13,8 @@ export default Route.extend({
transition.retry();
}
}
}).catch((error) => {
console.log('Error initializing Kredits', error);
});
},
+2
View File
@@ -1,4 +1,5 @@
import computed from 'ember-computed';
import ethers from 'npm:ethers';
export default function(dependentKey, converterMethod) {
return computed(dependentKey, {
@@ -6,6 +7,7 @@ export default function(dependentKey, converterMethod) {
return this.get(dependentKey)[converterMethod]();
},
set (key, value) {
value = ethers.utils.bigNumberify(value);
this.set(dependentKey, value);
return value[converterMethod]();
}
-8
View File
@@ -12,20 +12,12 @@ moduleFor('controller:index', 'Unit | Controller | index', {
});
let addFixtures = function(controller) {
controller.set('model', {
contributors: [],
proposals: []
});
[
{ github_username: "neo", github_uid: "318", balance: 10000 },
{ github_username: "morpheus", github_uid: "843", balance: 15000 },
{ github_username: "trinity", github_uid: "123", balance: 5000 },
{ github_username: "mouse", github_uid: "696", balance: 0 }
].forEach(fixture => {
// we expect a bignumer but I don't want to add the bignumber dependency here... so this is some hack to return an object that looks good enough for the test
let fakeBignumber = function(balance) { return { toNumber: function() { return balance; } }; };
fixture.balance = fakeBignumber(fixture.balance);
controller.get('kredits.contributors').push(Contributor.create(fixture));
});
};