Extract kredits module
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import Contributor from './contributor';
|
||||
import Operator from './operator';
|
||||
import Token from './token';
|
||||
|
||||
export default {
|
||||
Contributors: Contributor,
|
||||
Operator,
|
||||
Token
|
||||
};
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import Base from './base';
|
||||
|
||||
export default class Token extends Base {
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export default class Contributor {
|
||||
description,
|
||||
details,
|
||||
url,
|
||||
} = JSON.parse(serialized);
|
||||
} = JSON.parse(serialized.toString('utf8'));
|
||||
|
||||
return {
|
||||
kind,
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user