Remove kredits library files and use npm package #57
@@ -1,17 +0,0 @@
|
||||
export default class Base {
|
||||
constructor(contract) {
|
||||
this.contract = contract;
|
||||
}
|
||||
|
||||
get functions() {
|
||||
return this.contract.functions;
|
||||
}
|
||||
|
||||
on(type, callback) {
|
||||
let eventMethod = `on${type.toLowerCase()}`;
|
||||
// Don't use this.contract.events here. Seems to be a bug in ethers.js
|
||||
this.contract[eventMethod] = callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import ethers from 'npm:ethers';
|
||||
import RSVP from 'rsvp';
|
||||
|
||||
import Kredits from '../kredits';
|
||||
import ContributorSerializer from '../serializers/contributor';
|
||||
|
||||
import Base from './base';
|
||||
|
||||
export default class Contributor extends Base {
|
||||
all() {
|
||||
return this.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.functions.getContributorById(id)
|
||||
.then((data) => {
|
||||
// TODO: remove when naming updated on the contract
|
||||
data.hashDigest = data.ipfsHash;
|
||||
return data;
|
||||
})
|
||||
// Fetch IPFS data if available
|
||||
.then((data) => {
|
||||
return Kredits.ipfs.catAndMerge(data, ContributorSerializer.deserialize);
|
||||
});
|
||||
}
|
||||
|
||||
add(contributorAttr) {
|
||||
let json = ContributorSerializer.serialize(contributorAttr);
|
||||
// TODO: validate against schema
|
||||
|
||||
return Kredits.ipfs
|
||||
.add(json)
|
||||
.then((ipfsHashAttr) => {
|
||||
let contributor = [
|
||||
contributorAttr.address,
|
||||
ipfsHashAttr.hashDigest,
|
||||
ipfsHashAttr.hashFunction,
|
||||
ipfsHashAttr.hashSize,
|
||||
contributorAttr.isCore,
|
||||
];
|
||||
|
||||
console.log('[kredits] addContributor', ...contributor);
|
||||
return this.functions.addContributor(...contributor);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import Contributor from './contributor';
|
||||
import Operator from './operator';
|
||||
import Token from './token';
|
||||
|
||||
export default {
|
||||
Contributors: Contributor,
|
||||
Operator,
|
||||
Token
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
import ethers from 'npm:ethers';
|
||||
import RSVP from 'rsvp';
|
||||
|
||||
import Kredits from '../kredits';
|
||||
import ContributionSerializer from '../serializers/contribution';
|
||||
|
||||
import Base from './base';
|
||||
|
||||
export default class Operator extends Base {
|
||||
all() {
|
||||
return this.functions.proposalsCount()
|
||||
.then((count) => {
|
||||
count = count.toNumber();
|
||||
let proposals = [];
|
||||
|
||||
for (let id = 1; id <= count; id++) {
|
||||
proposals.push(this.getById(id));
|
||||
}
|
||||
|
||||
return RSVP.all(proposals);
|
||||
});
|
||||
}
|
||||
|
||||
getById(id) {
|
||||
id = ethers.utils.bigNumberify(id);
|
||||
|
||||
return this.functions.getProposal(id)
|
||||
.then((data) => {
|
||||
// TODO: remove when naming updated on the contract
|
||||
data.hashDigest = data.ipfsHash;
|
||||
return data;
|
||||
})
|
||||
// Fetch IPFS data if available
|
||||
.then((data) => {
|
||||
return Kredits.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
|
||||
});
|
||||
}
|
||||
|
||||
addProposal(proposalAttr) {
|
||||
let json = ContributionSerializer.serialize(proposalAttr);
|
||||
// TODO: validate against schema
|
||||
|
||||
return Kredits.ipfs
|
||||
.add(json)
|
||||
.then((ipfsHashAttr) => {
|
||||
let proposal = [
|
||||
proposalAttr.contributorId,
|
||||
proposalAttr.amount,
|
||||
ipfsHashAttr.hashDigest,
|
||||
ipfsHashAttr.hashFunction,
|
||||
ipfsHashAttr.hashSize,
|
||||
];
|
||||
|
||||
console.log('[kredits] addProposal', ...proposal);
|
||||
return this.functions.addProposal(...proposal);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import Base from './base';
|
||||
|
||||
export default class Token extends Base {
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './kredits';
|
||||
@@ -1,102 +0,0 @@
|
||||
import ethers from 'npm:ethers';
|
||||
import RSVP from 'rsvp';
|
||||
|
||||
import abis from 'contracts/abis';
|
||||
import addresses from 'contracts/addresses';
|
||||
|
||||
import contracts from './contracts';
|
||||
import IPFS from './utils/ipfs';
|
||||
|
||||
// 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 = new IPFS(ipfsConfig);
|
||||
|
||||
return this.ipfs._ipfsAPI.id().catch((error) => {
|
||||
throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`);
|
||||
}).then(() => {
|
||||
|
||||
let registryContract = this.initRegistryContract(provider);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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];
|
||||
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);
|
||||
|
||||
return this.contracts[name];
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
* Handle serialization for JSON-LD object of the contribution, according to
|
||||
* https://github.com/67P/kosmos-schemas/blob/master/schemas/contribution.json
|
||||
*
|
||||
* @class
|
||||
* @public
|
||||
*/
|
||||
export default class Contributor {
|
||||
/**
|
||||
* Deserialize JSON to object
|
||||
*
|
||||
* @method
|
||||
* @public
|
||||
*/
|
||||
static deserialize(serialized) {
|
||||
let {
|
||||
kind,
|
||||
description,
|
||||
details,
|
||||
url,
|
||||
} = JSON.parse(serialized.toString('utf8'));
|
||||
|
||||
return {
|
||||
kind,
|
||||
description,
|
||||
details,
|
||||
url,
|
||||
ipfsData: serialized,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize object to JSON
|
||||
*
|
||||
* @method
|
||||
* @public
|
||||
*/
|
||||
static serialize(deserialized) {
|
||||
let {
|
||||
contributorIpfsHash,
|
||||
kind,
|
||||
description,
|
||||
url,
|
||||
} = deserialized;
|
||||
|
||||
let data = {
|
||||
"@context": "https://schema.kosmos.org",
|
||||
"@type": "Contribution",
|
||||
"contributor": {
|
||||
"ipfs": contributorIpfsHash
|
||||
},
|
||||
kind,
|
||||
description,
|
||||
"details": {}
|
||||
};
|
||||
|
||||
if (url) {
|
||||
data["url"] = url;
|
||||
}
|
||||
|
||||
// Write it pretty to ipfs
|
||||
return JSON.stringify(data, null, 2);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Handle serialization for JSON-LD object of the contributor, according to
|
||||
* https://github.com/67P/kosmos-schemas/blob/master/schemas/contributor.json
|
||||
*
|
||||
* @class
|
||||
* @public
|
||||
*/
|
||||
export default class Contributor {
|
||||
/**
|
||||
* Deserialize JSON to object
|
||||
*
|
||||
* @method
|
||||
* @public
|
||||
*/
|
||||
static deserialize(serialized) {
|
||||
let {
|
||||
name,
|
||||
kind,
|
||||
url,
|
||||
accounts,
|
||||
} = JSON.parse(serialized.toString('utf8'));
|
||||
|
||||
let github_username, github_uid, wiki_username;
|
||||
let github = accounts.find((a) => a.site === 'github.com');
|
||||
let wiki = accounts.find((a) => a.site === 'wiki.kosmos.org');
|
||||
|
||||
if (github) {
|
||||
(({ username: github_username, uid: github_uid} = github));
|
||||
}
|
||||
if (wiki) {
|
||||
(({ username: wiki_username } = wiki));
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
kind,
|
||||
url,
|
||||
github_uid,
|
||||
github_username,
|
||||
wiki_username,
|
||||
ipfsData: serialized,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize object to JSON
|
||||
*
|
||||
* @method
|
||||
* @public
|
||||
*/
|
||||
static serialize(deserialized) {
|
||||
let {
|
||||
name,
|
||||
kind,
|
||||
url,
|
||||
github_uid,
|
||||
github_username,
|
||||
wiki_username,
|
||||
} = deserialized;
|
||||
|
||||
let data = {
|
||||
"@context": "https://schema.kosmos.org",
|
||||
"@type": "Contributor",
|
||||
kind,
|
||||
name,
|
||||
"accounts": []
|
||||
};
|
||||
|
||||
if (url) {
|
||||
data["url"] = url;
|
||||
}
|
||||
|
||||
if (github_uid) {
|
||||
data.accounts.push({
|
||||
"site": "github.com",
|
||||
"uid": github_uid,
|
||||
"username": github_username,
|
||||
"url": `https://github.com/${github_username}`
|
||||
});
|
||||
}
|
||||
|
||||
if (wiki_username) {
|
||||
data.accounts.push({
|
||||
"site": "wiki.kosmos.org",
|
||||
"username": wiki_username,
|
||||
"url": `https://wiki.kosmos.org/User:${wiki_username}`
|
||||
});
|
||||
}
|
||||
|
||||
// Write it pretty to ipfs
|
||||
return JSON.stringify(data, null, 2);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import ipfsAPI from 'npm:ipfs-api';
|
||||
import multihashes from 'npm:multihashes';
|
||||
|
||||
export default class IPFS {
|
||||
|
||||
constructor(config) {
|
||||
this._ipfsAPI = ipfsAPI(config);
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
catAndMerge(data, deserialize) {
|
||||
// if no hash details are found simply return the data; nothing to merge
|
||||
if (!data.hashSize || data.hashSize === 0) {
|
||||
return data;
|
||||
}
|
||||
// merge ipfsHash (encoded from hashDigest, hashSize, hashFunction)
|
||||
data.ipfsHash = this.encodeHash(data);
|
||||
|
||||
return this.cat(data)
|
||||
.then(deserialize)
|
||||
.then((attributes) => {
|
||||
return Object.assign({}, data, attributes);
|
||||
});
|
||||
}
|
||||
|
||||
add(data) {
|
||||
return this._ipfsAPI
|
||||
.add(new this._ipfsAPI.Buffer(data))
|
||||
.then((res) => {
|
||||
return this.decodeHash(res[0].hash);
|
||||
});
|
||||
}
|
||||
|
||||
cat(hashData) {
|
||||
let ipfsHash = hashData; // default - if it is a string
|
||||
if (hashData.hasOwnProperty('hashSize')) {
|
||||
ipfsHash = this.encodeHash(hashData);
|
||||
}
|
||||
return this._ipfsAPI.cat(ipfsHash);
|
||||
}
|
||||
|
||||
decodeHash(ipfsHash) {
|
||||
let multihash = multihashes.decode(multihashes.fromB58String(ipfsHash));
|
||||
return {
|
||||
hashDigest: '0x' + multihashes.toHexString(multihash.digest),
|
||||
hashSize: multihash.length,
|
||||
hashFunction: multihash.code,
|
||||
ipfsHash: ipfsHash
|
||||
};
|
||||
}
|
||||
|
||||
encodeHash(hashData) {
|
||||
let digest = this._ipfsAPI.Buffer.from(hashData.hashDigest.slice(2), 'hex');
|
||||
return multihashes.encode(digest, hashData.hashFunction, hashData.hashSize);
|
||||
}
|
||||
|
||||
}
|
||||
Generated
+73
-6
@@ -9754,7 +9754,7 @@
|
||||
"ember-cli-babel": {
|
||||
"version": "6.12.0",
|
||||
"resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.12.0.tgz",
|
||||
"integrity": "sha1-Otzb4SeNofzQuQOPE2DLSsXUQUw=",
|
||||
"integrity": "sha512-LMwZ3Xf3Q3jQUXaJtLLJsbbhRZRNv/iea64lZ8OgqZp1fh66CSXfmqV3L9QSuYQKPDNqFiu2v6IpOT08C6GU6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"amd-name-resolver": "0.0.7",
|
||||
@@ -10055,7 +10055,7 @@
|
||||
"ember-weakmap": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ember-weakmap/-/ember-weakmap-3.1.1.tgz",
|
||||
"integrity": "sha1-KubgCAtbgM8NEI93Utxp6pYD29c=",
|
||||
"integrity": "sha512-rfW3A1m3NFsHd/NuHyBkssU0Qf0zGcJmASGfhjZc7fIQeBZvSLIFYZTej+W+YBLPtED9h/SVW63DHTRY5PUR4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "2.11.3",
|
||||
@@ -10066,7 +10066,7 @@
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
@@ -10075,7 +10075,7 @@
|
||||
"ember-cli-babel": {
|
||||
"version": "6.12.0",
|
||||
"resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.12.0.tgz",
|
||||
"integrity": "sha1-Otzb4SeNofzQuQOPE2DLSsXUQUw=",
|
||||
"integrity": "sha512-LMwZ3Xf3Q3jQUXaJtLLJsbbhRZRNv/iea64lZ8OgqZp1fh66CSXfmqV3L9QSuYQKPDNqFiu2v6IpOT08C6GU6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"amd-name-resolver": "0.0.7",
|
||||
@@ -14007,8 +14007,69 @@
|
||||
}
|
||||
},
|
||||
"kredits-contracts": {
|
||||
"version": "github:67P/truffle-kredits#e0407cb31a5b1254630613c68654a3283ac6abe0",
|
||||
"dev": true
|
||||
"version": "github:67P/truffle-kredits#d5e68e1639c6e0a497d9827540d992af53e82e87",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ethers": "3.0.15",
|
||||
"ipfs-api": "19.0.0",
|
||||
"rsvp": "4.8.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"elliptic": {
|
||||
"version": "6.3.3",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
|
||||
"integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bn.js": "4.11.8",
|
||||
"brorand": "1.1.0",
|
||||
"hash.js": "1.1.3",
|
||||
"inherits": "2.0.1"
|
||||
}
|
||||
},
|
||||
"ethers": {
|
||||
"version": "3.0.15",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-3.0.15.tgz",
|
||||
"integrity": "sha512-d/tiMUavaeaY2GFqjpgfPzT46cEc0cilP3hnlTXR3LR/HR5Qrhv4PfdgW3gxBlR5aBTtUeM/lo8z8ph3JdtFhQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aes-js": "3.0.0",
|
||||
"bn.js": "4.11.8",
|
||||
"elliptic": "6.3.3",
|
||||
"hash.js": "1.1.3",
|
||||
"inherits": "2.0.1",
|
||||
"js-sha3": "0.5.7",
|
||||
"scrypt-js": "2.0.3",
|
||||
"setimmediate": "1.0.4",
|
||||
"uuid": "2.0.1",
|
||||
"xmlhttprequest": "1.8.0"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
|
||||
"dev": true
|
||||
},
|
||||
"js-sha3": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
|
||||
"integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=",
|
||||
"dev": true
|
||||
},
|
||||
"rsvp": {
|
||||
"version": "4.8.2",
|
||||
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.2.tgz",
|
||||
"integrity": "sha512-8CU1Wjxvzt6bt8zln+hCjyieneU9s0LRW+lPRsjyVCY8Vm1kTbK7btBIrCGg6yY9U4undLDm/b1hKEEi1tLypg==",
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
|
||||
"integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"lazy-cache": {
|
||||
"version": "1.0.4",
|
||||
@@ -20978,6 +21039,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"setimmediate": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
|
||||
"integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
|
||||
"dev": true
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@
|
||||
"ethers": "^3.0.8",
|
||||
"ipfs-api": "^19.0.0",
|
||||
"kosmos-schemas": "^1.1.2",
|
||||
"kredits-contracts": "github:67P/truffle-kredits#master",
|
||||
"kredits-contracts": "github:67P/truffle-kredits#library",
|
||||
"loader.js": "^4.2.3",
|
||||
"tv4": "^1.3.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user