Extract kredits module

This commit is contained in:
2018-04-09 02:09:07 +02:00
parent cb1208acaa
commit 7e04cef964
15 changed files with 343 additions and 320 deletions
+37
View File
@@ -0,0 +1,37 @@
import Kredits from '../kredits';
import { fromBytes32 } from '../utils/multihash';
export default class Base {
constructor(contract) {
this.contract = contract;
}
get functions() {
return this.contract.functions;
}
// TODO: move into utils
fetchAndMergeIpfsData(data, Serializer) {
let ipfsHash = data.ipfsHash;
if (!ipfsHash) {
return data;
}
return Kredits.ipfs
.cat(ipfsHash)
.then(Serializer.deserialize)
.then((attributes) => {
return Object.assign({}, data, attributes);
});
}
reassembleIpfsHash(data) {
let { ipfsHash: digest, hashFunction, hashSize } = data;
data.ipfsHash = fromBytes32({ digest, hashFunction, hashSize });
delete data.hashFunction;
delete data.hashSize;
return data;
}
}
+72
View File
@@ -0,0 +1,72 @@
import ethers from 'npm:ethers';
import RSVP from 'rsvp';
import Kredits from '../kredits';
import ContributorSerializer from '../serializers/contributor';
import { toBytes32 } from '../utils/multihash';
import Base from './base';
export default class Contributor extends Base {
all() {
return this.contract.functions.contributorsCount()
.then((count) => {
count = count.toNumber();
let contributors = [];
for (let id = 1; id <= count; id++) {
contributors.push(this.getById(id));
}
return RSVP.all(contributors);
});
}
getById(id) {
id = ethers.utils.bigNumberify(id);
return this.contract.functions.getContributorById(id)
.then(this.reassembleIpfsHash)
.then((data) => {
// TODO: remove as soon as the contract provides the id
data.id = id;
// TODO: rename address to account
data.address = data.account;
return data;
})
// Fetch IPFS data if available
.then((data) => {
return this.fetchAndMergeIpfsData(data, ContributorSerializer);
});
}
add(attributes) {
console.log(attributes);
let json = ContributorSerializer.serialize(attributes);
// TODO: validate against schema
return Kredits.ipfs
.add(new Kredits.ipfs.Buffer(json))
.then((res) => res[0].hash)
.then((ipfsHash) => {
Object.assign(attributes, toBytes32(ipfsHash));
return attributes;
})
.then((attributes) => {
let { address, digest, hashFunction, hashSize, isCore } = attributes;
let contributor = [
address,
digest,
hashFunction,
hashSize,
isCore,
];
console.log('[kredits] addContributor', ...contributor);
return this.contract.functions.addContributor(...contributor);
});
}
}
+9
View File
@@ -0,0 +1,9 @@
import Contributor from './contributor';
import Operator from './operator';
import Token from './token';
export default {
Contributors: Contributor,
Operator,
Token
};
+72
View File
@@ -0,0 +1,72 @@
import ethers from 'npm:ethers';
import RSVP from 'rsvp';
import Kredits from '../kredits';
import ContributionSerializer from '../serializers/contribution';
import { toBytes32 } from '../utils/multihash';
import Base from './base';
export default class Operator extends Base {
all() {
return this.contract.functions.proposalsCount()
.then((count) => {
count = count.toNumber();
let proposals = [];
for (let id = 0; id < count; id++) {
proposals.push(this.getById(id));
}
return RSVP.all(proposals);
});
}
getById(id) {
id = ethers.utils.bigNumberify(id);
return this.contract.functions.proposals(id)
.then(this.reassembleIpfsHash)
.then((data) => {
// TODO: remove as soon as the contract provides the id
data.id = id;
// TODO: rename creatorAddress to creator
data.creatorAddress = data.creator;
return data;
})
// Fetch IPFS data if available
.then((data) => {
return this.fetchAndMergeIpfsData(data, ContributionSerializer);
});
}
addProposal(attributes) {
console.log(attributes);
let json = ContributionSerializer.serialize(attributes);
// TODO: validate against schema
return Kredits.ipfs
.add(new Kredits.ipfs.Buffer(json))
.then((res) => res[0].hash)
.then((ipfsHash) => {
Object.assign(attributes, toBytes32(ipfsHash));
return attributes;
})
.then((attributes) => {
let { recipientId, amount, digest, hashFunction, hashSize } = attributes;
let proposal = [
recipientId,
amount,
digest,
hashFunction,
hashSize,
];
console.log('[kredits] addProposal', ...proposal);
return this.contract.functions.addProposal(...proposal);
});
}
}
+4
View File
@@ -0,0 +1,4 @@
import Base from './base';
export default class Token extends Base {
}
+1 -10
View File
@@ -1,10 +1 @@
import ContributionSerializer from './serializers/contribution';
import ContributorSerializer from './serializers/contributor';
import { fromBytes32, toBytes32 } from './utils/multihash';
export {
ContributionSerializer,
ContributorSerializer,
fromBytes32,
toBytes32
};
export { default } from './kredits';
+77
View File
@@ -0,0 +1,77 @@
import ethers from 'npm:ethers';
import ipfsAPI from 'npm:ipfs-api';
import RSVP from 'rsvp';
import abis from 'contracts/abis';
import addresses from 'contracts/addresses';
import contracts from './contracts';
// Helpers
function capitalize(word) {
let [first, ...rest] = word;
return `${first.toUpperCase()}${rest.join('')}`;
}
export default class Kredits {
constructor(provider, signer, addresses) {
this.provider = provider;
this.signer = signer;
// Initialize our registry contract
this.addresses = addresses;
this.contracts = {};
}
static setup(provider, signer, ipfsConfig) {
this.ipfsConfig = ipfsConfig;
this.ipfs = ipfsAPI(ipfsConfig);
let registryContract = this.initRegistryContract(provider);
let addresses = Object.keys(contracts).reduce((mem, name) => {
let contractName = capitalize(name);
mem[contractName] = registryContract.functions.getProxyFor(contractName);
return mem;
}, {});
return RSVP.hash(addresses)
.then((addresses) => {
return new Kredits(provider, signer, addresses);
});
}
static initRegistryContract(provider) {
let address = addresses['Registry'][provider.chainId];
let abi = abis['Registry'];
console.log('Initialize registry contract:', address, abi, provider);
return new ethers.Contract(address, abi, provider);
}
get Contributor() {
// TODO: rename to contributor
return this.contractFor('contributors');
}
get Operator() {
return this.contractFor('operator');
}
get Token() {
return this.contractFor('token');
}
// Should be private
contractFor(name) {
if (this.contracts[name]) {
return this.contracts[name];
}
let contractName = capitalize(name);
let address = this.addresses[contractName];
let contract = new ethers.Contract(address, abis[contractName], this.signer);
this.contracts[name] = new contracts[contractName](contract);
return this.contracts[name];
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ export default class Contributor {
description,
details,
url,
} = JSON.parse(serialized);
} = JSON.parse(serialized.toString('utf8'));
return {
kind,
+1 -1
View File
@@ -18,7 +18,7 @@ export default class Contributor {
kind,
url,
accounts,
} = JSON.parse(serialized);
} = JSON.parse(serialized.toString('utf8'));
let github_username, github_uid, wiki_username;
let github = accounts.find((a) => a.site === 'github.com');