diff --git a/.ganache-db/.gitkeep b/.ganache-db/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore index 48912d2..697f31a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build -node_modules \ No newline at end of file +node_modules +.ganache-db \ No newline at end of file diff --git a/README.mdown b/README.mdown index 48517ef..95143bc 100644 --- a/README.mdown +++ b/README.mdown @@ -22,11 +22,18 @@ We use following solidity contract libraries: For local development it is recommended to use [ganache-cli](https://github.com/trufflesuite/ganache-cli) (or the [ganache GUI](http://truffleframework.com/ganache/) to run a local development chain. Using the ganache simulator no full Ethereum node is required. -We default to the port 7545 for development to not get in conflict with the default Ethereum RPC port. Have a look at `ganache-cli` for more configuration options. +We default to: + +* port 7545 for development to not get in conflict with the default Ethereum RPC port. +* network ID 100 to stay on the same network id +* store ganache data in .ganache-db to presist the chain data across restarts +* use a fixed Mnemonic code to get the same accounts across restarts + +Have a look at `ganache-cli` for more configuration options. Run your ganache simulator before using Kredits locally: - $ ganache-cli -p 7545 + $ npm run ganache (which is: ganache-cli -p 7545 -i 100 --db=./.ganache-db -m kredits) ### Truffle console diff --git a/config/seeds.js b/config/seeds.js index ae3403a..d8b84e5 100644 --- a/config/seeds.js +++ b/config/seeds.js @@ -1,65 +1,9 @@ -let contractCalls = { - Contributors: { - addContributor: [ - // make sure to use an IPFS hash of one of the objects in ipfsContent - ['0x24dd2aedd8a9fe52ac071b3a23b2fc8f225c185e', '0x272bbfc66166f26cae9c9b96b7f9590e095f02edf342ac2dd71e1667a12116ca', 18, 32, true], // QmQyZJT9uikzDYTZLhhyVZ5ReZVCoMucYzyvDokDJsijhj - ['0xa502eb4021f3b9ab62f75b57a94e1cfbf81fd827', '0x9569ed44826286597982e40bbdff919c6b7752e29d13250efca452644e6b4b25', 18, 32, true] // QmYPu8zvtfDy18ZqHCviVxnKtxycw5UTJLJyk9oAEjWfnL - ] - }, - Operator: { - addProposal: [ - [2, 23, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" - [3, 42, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" - [3, 100, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32] // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" - ], - vote: [ - [1] - ] - } -}; -let ipfsContent = [ - { - "@context": "https://schema.kosmos.org", - "@type": "Contributor", - "kind": "person", - "name": "Râu Cao", - "url": "https://sebastian.kip.pe", - "accounts": [ - { - "site": "github.com", - "username": "skddc", - "uid": 842, - "url": "https://github.com/skddc/" - }, - ] - }, - { - "@context": "https://schema.kosmos.org", - "@type": "Contributor", - "kind": "person", - "name": "Bumi", - "url": "https://michaelbumann.com", - "accounts": [ - { - "site": "github.com", - "username": "bumi", - "uid": 318, - "url": "https://github.com/bumi/" - }, - ] - }, - { - "@context": "https://schema.kosmos.org", - "@type": "Contribution", - "contributor": { - "ipfs": "QmQ2ZZS2bXgneQfKtVTVxe6dV7pcJuXnTeZJQtoVUFsAtJ" - }, - "kind": "dev", - "description": "hacking hacking on kredits", - "url": "https://github.com/67P/kredits-web/pull/11", - "details": {} - } - -] - -module.exports = { contractCalls, ipfsContent }; +let contractCalls = [ + ['Contributor', 'add', [{ account: '0x7e8f313c56f809188313aa274fa67ee58c31515d', name: 'bumi', isCore: true, kind: 'preson', url: '', github_username: 'bumi', github_uid: 318, wiki_username: 'bumi' }, {gasLimit: 200000}]], + ['Contributor', 'add', [{ account: '0xa502eb4021f3b9ab62f75b57a94e1cfbf81fd827', name: 'raucau', isCore: true, kind: 'person', url: '', github_username: 'skddc', github_uid: 842, wiki_username: 'raucau' }, {gasLimit: 200000}]], + ['Operator', 'addProposal', [{ contributorId: 2, amount: 42, kind: 'code', description: 'runs the seeds', url: '' }, {gasLimit: 350000}]], + ['Operator', 'addProposal', [{ contributorId: 3, amount: 23, kind: 'code', description: 'runs the seeds', url: '' }, {gasLimit: 350000}]], + ['Operator', 'addProposal', [{contributorId: 3, amount: 100, kind: 'code', description: 'hacks on kredits', url: '' }, {gasLimit: 350000}]], + ['Operator', 'vote', ['1', {gasLimit: 250000}]] +]; +module.exports = { contractCalls }; diff --git a/contracts/Contributors.sol b/contracts/Contributors.sol index d876979..939d02b 100644 --- a/contracts/Contributors.sol +++ b/contracts/Contributors.sol @@ -49,7 +49,7 @@ contract Contributors is Upgradeable { return count; } - function updateContributorAddress(uint id, address oldAccount, address newAccount) public onlyCoreOrOperator { + function updateContributorAccount(uint id, address oldAccount, address newAccount) public onlyCoreOrOperator { contributorIds[oldAccount] = 0; contributorIds[newAccount] = id; contributors[id].account = newAccount; diff --git a/contracts/Operator.sol b/contracts/Operator.sol index b950a70..390f7af 100644 --- a/contracts/Operator.sol +++ b/contracts/Operator.sol @@ -7,8 +7,8 @@ import './Contributors.sol'; contract Operator is Upgradeable { struct Proposal { - address creator; - uint recipientId; + address creatorAccount; + uint contributorId; uint votesCount; uint votesNeeded; uint256 amount; @@ -24,9 +24,9 @@ contract Operator is Upgradeable { mapping(uint256 => Proposal) public proposals; uint256 public proposalsCount; - event ProposalCreated(uint256 id, address creator, uint recipient, uint256 amount); - event ProposalVoted(uint256 id, address voter, uint256 totalVotes); - event ProposalExecuted(uint256 id, uint recipient, uint256 amount); + event ProposalCreated(uint256 id, address creatorAccount, uint256 contributorId, uint256 amount); + event ProposalVoted(uint256 id, uint256 voterId, uint256 totalVotes); + event ProposalExecuted(uint256 id, uint256 contributorId, uint256 amount); modifier coreOnly() { require(contributorsContract().addressIsCore(msg.sender)); @@ -55,48 +55,34 @@ contract Operator is Upgradeable { return contributorsContract().coreContributorsCount(); } - function addContributor(address _address, bytes32 _ipfsHash, uint8 _hashFunction, uint8 _hashSize, bool _isCore) public coreOnly { - contributorsContract().addContributor(_address, _ipfsHash, _hashFunction, _hashSize, _isCore); - } + function addProposal(uint contributorId, uint256 amount, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public { + require(contributorsContract().exists(contributorId)); - function updateContributorIpfsHash(uint _id, bytes32 _ipfsHash, uint8 _hashFunction, uint8 _hashSize) public coreOnly { - contributorsContract().updateContributorIpfsHash(_id, _ipfsHash, _hashFunction, _hashSize); - } - - function getContributor(uint _id) view public returns (address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore) { - bool exists; - - (account, ipfsHash, hashFunction, hashSize, isCore, exists) = contributorsContract().contributors(_id); - - require(exists); - } - - function addProposal(uint _recipient, uint256 _amount, bytes32 _ipfsHash, uint8 _hashFunction, uint8 _hashSize) public returns (uint256 proposalId) { - require(contributorsContract().exists(_recipient)); - - proposalId = proposalsCount + 1; - uint _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75; + uint256 proposalId = proposalsCount + 1; + uint256 _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75; var p = proposals[proposalId]; - p.creator = msg.sender; - p.recipientId = _recipient; - p.amount = _amount; - p.ipfsHash = _ipfsHash; - p.hashFunction = _hashFunction; - p.hashSize = _hashSize; + p.creatorAccount = msg.sender; + p.contributorId = contributorId; + p.amount = amount; + p.ipfsHash = ipfsHash; + p.hashFunction = hashFunction; + p.hashSize = hashSize; p.votesCount = 0; p.votesNeeded = _votesNeeded; p.exists = true; proposalsCount++; - ProposalCreated(proposalId, msg.sender, p.recipientId, p.amount); + ProposalCreated(proposalId, msg.sender, p.contributorId, p.amount); } - function getProposal(uint _proposalId) public view returns (address creator, uint256 recipientId, uint256 votesCount, uint256 votesNeeded, uint256 amount, bool executed, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, uint256[] voterIds, bool exists) { - Proposal storage p = proposals[_proposalId]; + function getProposal(uint proposalId) public view returns (uint256 id, address creatorAccount, uint256 contributorId, uint256 votesCount, uint256 votesNeeded, uint256 amount, bool executed, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, uint256[] voterIds, bool exists) { + id = proposalId; + Proposal storage p = proposals[id]; return ( - p.creator, - p.recipientId, + id, + p.creatorAccount, + p.contributorId, p.votesCount, p.votesNeeded, p.amount, @@ -109,22 +95,19 @@ contract Operator is Upgradeable { ); } - function vote(uint256 _proposalId) public coreOnly returns (uint _pId, bool _executed) { - var p = proposals[_proposalId]; + function vote(uint256 proposalId) public coreOnly { + var p = proposals[proposalId]; require(!p.executed); - uint256 contributorId = contributorsContract().getContributorIdByAddress(msg.sender); - require(p.votes[contributorId] != true); - p.voterIds.push(contributorId); - p.votes[contributorId] = true; + uint256 voterId = contributorsContract().getContributorIdByAddress(msg.sender); + require(p.votes[voterId] != true); + p.voterIds.push(voterId); + p.votes[voterId] = true; p.votesCount++; - _executed = false; - _pId = _proposalId; if (p.votesCount >= p.votesNeeded) { - executeProposal(_proposalId); - _executed = true; + executeProposal(proposalId); } - ProposalVoted(_pId, msg.sender, p.votesCount); + ProposalVoted(proposalId, voterId, p.votesCount); } function batchVote(uint256[] _proposalIds) public coreOnly { @@ -133,15 +116,15 @@ contract Operator is Upgradeable { } } - function executeProposal(uint proposalId) private returns (bool) { + function executeProposal(uint proposalId) private { + var p = proposals[proposalId]; require(!p.executed); require(p.votesCount >= p.votesNeeded); - address recipientAddress = contributorsContract().getContributorAddressById(p.recipientId); + address recipientAddress = contributorsContract().getContributorAddressById(p.contributorId); tokenContract().mintFor(recipientAddress, p.amount, proposalId); p.executed = true; - ProposalExecuted(proposalId, p.recipientId, p.amount); - return true; + ProposalExecuted(proposalId, p.contributorId, p.amount); } } diff --git a/contracts/Token.sol b/contracts/Token.sol index d892165..9d81a9f 100644 --- a/contracts/Token.sol +++ b/contracts/Token.sol @@ -17,12 +17,11 @@ contract Token is Upgradeable, BasicToken { decimals = 18; } - function mintFor(address _recipient, uint256 _amount, uint _proposalId) onlyRegistryContractFor('Operator') public returns (bool success) { - totalSupply_ = totalSupply_.add(_amount); - balances[_recipient] = balances[_recipient].add(_amount); + function mintFor(address contributorAccount, uint256 amount, uint proposalId) onlyRegistryContractFor('Operator') public { + totalSupply_ = totalSupply_.add(amount); + balances[contributorAccount] = balances[contributorAccount].add(amount); - LogMint(_recipient, _amount, _proposalId); - return true; + LogMint(contributorAccount, amount, proposalId); } } diff --git a/lib/abis/Contributors.json b/lib/abis/Contributors.json index 5fcc4a0..702a28a 100644 --- a/lib/abis/Contributors.json +++ b/lib/abis/Contributors.json @@ -1 +1 @@ -[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"contributors","outputs":[{"name":"account","type":"address"},{"name":"profileHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"contributorIds","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"oldProfileHash","type":"bytes32"},{"indexed":false,"name":"newProfileHash","type":"bytes32"}],"name":"ContributorProfileUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"oldAddress","type":"address"},{"indexed":false,"name":"newAddress","type":"address"}],"name":"ContributorAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"_address","type":"address"}],"name":"ContributorAdded","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_oldAddress","type":"address"},{"name":"_newAddress","type":"address"}],"name":"updateContributorAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"},{"name":"_profileHash","type":"bytes32"}],"name":"updateContributorProfileHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"},{"name":"_profileHash","type":"bytes32"},{"name":"isCore","type":"bool"}],"name":"addContributor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"isCore","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"addressIsCore","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"addressExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getContributorAddressById","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getContributorById","outputs":[{"name":"account","type":"address"},{"name":"profileHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"},{"name":"exists","type":"bool"},{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file +[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"contributors","outputs":[{"name":"account","type":"address"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"contributorIds","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"oldIpfsHash","type":"bytes32"},{"indexed":false,"name":"newIpfsHash","type":"bytes32"}],"name":"ContributorProfileUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"oldAccount","type":"address"},{"indexed":false,"name":"newAccount","type":"address"}],"name":"ContributorAccountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"account","type":"address"}],"name":"ContributorAdded","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"oldAccount","type":"address"},{"name":"newAccount","type":"address"}],"name":"updateContributorAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"}],"name":"updateContributorIpfsHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"}],"name":"addContributor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"isCore","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"addressIsCore","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"addressExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"getContributorAddressById","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getContributorById","outputs":[{"name":"id","type":"uint256"},{"name":"account","type":"address"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"},{"name":"balance","type":"uint256"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abis/Operator.json b/lib/abis/Operator.json index fe3549c..5975fea 100644 --- a/lib/abis/Operator.json +++ b/lib/abis/Operator.json @@ -1 +1 @@ -[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"creator","type":"address"},{"name":"recipientId","type":"uint256"},{"name":"votesCount","type":"uint256"},{"name":"votesNeeded","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"executed","type":"bool"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"creator","type":"address"},{"indexed":false,"name":"recipient","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"totalVotes","type":"uint256"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"recipient","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"constant":true,"inputs":[],"name":"contributorsContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"},{"name":"_profileHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"},{"name":"_isCore","type":"bool"}],"name":"addContributor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_profileHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"}],"name":"updateContributorProfileHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getContributor","outputs":[{"name":"account","type":"address"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"profileHash","type":"bytes32"},{"name":"isCore","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proposalsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"uint256"},{"name":"_amount","type":"uint256"},{"name":"_ipfsHash","type":"bytes32"},{"name":"_hashFunction","type":"uint8"},{"name":"_hashSize","type":"uint8"}],"name":"addProposal","outputs":[{"name":"proposalId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposalId","type":"uint256"}],"name":"vote","outputs":[{"name":"_pId","type":"uint256"},{"name":"_executed","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_proposalId","type":"uint256"}],"name":"hasVotedFor","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file +[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"creatorAccount","type":"address"},{"name":"contributorId","type":"uint256"},{"name":"votesCount","type":"uint256"},{"name":"votesNeeded","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"executed","type":"bool"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proposalsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"creatorAccount","type":"address"},{"indexed":false,"name":"contributorId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"voterId","type":"uint256"},{"indexed":false,"name":"totalVotes","type":"uint256"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"contributorId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"constant":true,"inputs":[],"name":"contributorsContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"contributorId","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"}],"name":"addProposal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"proposalId","type":"uint256"}],"name":"getProposal","outputs":[{"name":"id","type":"uint256"},{"name":"creatorAccount","type":"address"},{"name":"contributorId","type":"uint256"},{"name":"votesCount","type":"uint256"},{"name":"votesNeeded","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"executed","type":"bool"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"voterIds","type":"uint256[]"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"proposalId","type":"uint256"}],"name":"vote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abis/Token.json b/lib/abis/Token.json index 53158c7..2b02b6b 100644 --- a/lib/abis/Token.json +++ b/lib/abis/Token.json @@ -1 +1 @@ -[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"proposalId","type":"uint256"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_proposalId","type":"uint256"}],"name":"mintFor","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"proposalId","type":"uint256"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"contributorAccount","type":"address"},{"name":"amount","type":"uint256"},{"name":"proposalId","type":"uint256"}],"name":"mintFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/addresses/Contributors.json b/lib/addresses/Contributors.json index 49c655e..7c8cb62 100644 --- a/lib/addresses/Contributors.json +++ b/lib/addresses/Contributors.json @@ -1 +1 @@ -{"100":"0x34262a9471ede40e94497d110652dcf0f26fa0db"} \ No newline at end of file +{"42":"0x205fe1b3dac678b594c5f0535e7d158e38591f93","100":"0xa7fc9b1f678c41396b53904f94f50a42ff44d826"} \ No newline at end of file diff --git a/lib/addresses/Operator.json b/lib/addresses/Operator.json index 11272fd..b865526 100644 --- a/lib/addresses/Operator.json +++ b/lib/addresses/Operator.json @@ -1 +1 @@ -{"100":"0x901f3e99a170619857b354c101aa97244885a39e"} \ No newline at end of file +{"42":"0x9fd66ee78a5ebe86006f12b37ff59c63f9caa15b","100":"0x95d3bd7d136bb0b7ac9988097e964236f8a9976e"} \ No newline at end of file diff --git a/lib/addresses/Registry.json b/lib/addresses/Registry.json index d7f6ba1..25faf40 100644 --- a/lib/addresses/Registry.json +++ b/lib/addresses/Registry.json @@ -1 +1 @@ -{"100":"0x9447a29373cf3ce0edf41804820c2a9da0ef4fd9"} \ No newline at end of file +{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x7458dea485d9d8301e3ce43e8a1ec1456be5ba83"} \ No newline at end of file diff --git a/lib/addresses/Token.json b/lib/addresses/Token.json index 763d73c..9242b73 100644 --- a/lib/addresses/Token.json +++ b/lib/addresses/Token.json @@ -1 +1 @@ -{"100":"0x8ecf9fa8a1c50179cef966d53aaee3d2a382c932"} \ No newline at end of file +{"42":"0xf71ccf7ab48044ef9ae0b5e6983dbd3266b78b36","100":"0x3fc29fbe40c2d0ca78c7e81342f00226650fe2ad"} \ No newline at end of file diff --git a/lib/contracts/base.js b/lib/contracts/base.js new file mode 100644 index 0000000..de43c19 --- /dev/null +++ b/lib/contracts/base.js @@ -0,0 +1,27 @@ +class Base { + constructor(contract) { + this.contract = contract; + } + + get functions() { + return this.contract.functions; + } + + get ipfs() { + if (!this._ipfsAPI) { throw new Error('IPFS API not configured; please set an ipfs instance'); } + return this._ipfsAPI; + } + + set ipfs(ipfsAPI) { + this._ipfsAPI = ipfsAPI; + } + + 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; + } +} +module.exports = Base; diff --git a/lib/contracts/contributor.js b/lib/contracts/contributor.js new file mode 100644 index 0000000..1845730 --- /dev/null +++ b/lib/contracts/contributor.js @@ -0,0 +1,57 @@ +const ethers = require('ethers'); +const RSVP = require('rsvp'); + +const ContributorSerializer = require('../serializers/contributor'); +const Base = require('./base'); + +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 this.ipfs.catAndMerge(data, ContributorSerializer.deserialize); + }); + } + + add(contributorAttr, callOptions = {}) { + let json = ContributorSerializer.serialize(contributorAttr); + // TODO: validate against schema + + return this.ipfs + .add(json) + .then((ipfsHashAttr) => { + let contributor = [ + contributorAttr.account, + ipfsHashAttr.hashDigest, + ipfsHashAttr.hashFunction, + ipfsHashAttr.hashSize, + contributorAttr.isCore, + ]; + + return this.functions.addContributor(...contributor, callOptions); + }); + } +} + +module.exports = Contributor; diff --git a/lib/contracts/index.js b/lib/contracts/index.js new file mode 100644 index 0000000..a4a1792 --- /dev/null +++ b/lib/contracts/index.js @@ -0,0 +1,6 @@ +module.exports = { + Contributors: require('./contributor'), + Operator: require('./operator'), + Token: require('./token'), + Registry: require('./registry') +}; diff --git a/lib/contracts/operator.js b/lib/contracts/operator.js new file mode 100644 index 0000000..83a5eae --- /dev/null +++ b/lib/contracts/operator.js @@ -0,0 +1,57 @@ +const ethers = require('ethers'); +const RSVP = require('rsvp'); + +const ContributionSerializer = require('../serializers/contribution'); +const Base = require('./base'); + +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 this.ipfs.catAndMerge(data, ContributionSerializer.deserialize); + }); + } + + addProposal(proposalAttr, callOptions = {}) { + let json = ContributionSerializer.serialize(proposalAttr); + // TODO: validate against schema + + return this.ipfs + .add(json) + .then((ipfsHashAttr) => { + let proposal = [ + proposalAttr.contributorId, + proposalAttr.amount, + ipfsHashAttr.hashDigest, + ipfsHashAttr.hashFunction, + ipfsHashAttr.hashSize, + ]; + + return this.functions.addProposal(...proposal, callOptions); + }); + } +} + +module.exports = Operator; diff --git a/lib/contracts/registry.js b/lib/contracts/registry.js new file mode 100644 index 0000000..a3af768 --- /dev/null +++ b/lib/contracts/registry.js @@ -0,0 +1,6 @@ +const Base = require('./base'); + +class Registry extends Base { +} + +module.exports = Registry; diff --git a/lib/contracts/token.js b/lib/contracts/token.js new file mode 100644 index 0000000..effbaaa --- /dev/null +++ b/lib/contracts/token.js @@ -0,0 +1,7 @@ +const Base = require('./base'); + +class Token extends Base { +} + +module.exports = Token; + diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index d01d9de..0000000 --- a/lib/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = ["Contributors","Operator","Registry","Token"]; \ No newline at end of file diff --git a/lib/kredits.js b/lib/kredits.js new file mode 100644 index 0000000..5ec030a --- /dev/null +++ b/lib/kredits.js @@ -0,0 +1,103 @@ +const ethers = require('ethers'); +const RSVP = require('rsvp'); + +const Healthcheck = require('./utils/healthcheck'); + +const ABIS = { + Contributors: require('./abis/Contributors.json'), + Operator: require('./abis/Operator.json'), + Registry: require('./abis/Registry.json'), + Token: require('./abis/Token.json') +}; +const RegistryAddress = require('./addresses/Registry.json'); + +const Contracts = require('./contracts'); +const IPFS = require('./utils/ipfs') + +// Helpers +function capitalize(word) { + let [first, ...rest] = word; + return `${first.toUpperCase()}${rest.join('')}`; +} + +class Kredits { + + constructor(provider, signer, addresses) { + this.provider = provider; + this.signer = signer; + + // by default we only need the registry address. + // the rest is loaded from there in the init() function + this.addresses = addresses || {Registry: RegistryAddress[this.provider.chainId.toString()]}; // chaiID must be a string + this.abis = ABIS; + this.contracts = {}; + this.ipfs = new IPFS(); + } + + init(names) { + let contractsToLoad = names || Object.keys(ABIS); + let addressPromises = contractsToLoad.map((contractName) => { + return this.Registry.functions.getProxyFor(contractName).then((address) => { + this.addresses[contractName] = address; + }).catch((error) => { + throw new Error(`Failed to get address for ${contractName} from registry at ${this.Registry.contract.address} + - correct registry? does it have version entry? - ${error.message}` + ); + }); + }); + return RSVP.all(addressPromises).then(() => { return this }); + } + + static setup(provider, signer, ipfsConfig = null) { + console.log('Kredits.setup() is deprecated use new Kredits().init() instead'); + let ipfs = new IPFS(ipfsConfig); + return new Kredits(provider, signer).init().then((kredits) => { + kredits.ipfs = ipfs; + return kredits; + }); + } + + get Registry() { + return this.contractFor('registry'); + } + + 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]; + } + + const contractName = capitalize(name); + const address = this.addresses[contractName]; + const abi = this.abis[contractName]; + if (!address || !abi) { + throw new Error(`Address or ABI not found for ${contractName}`); + } + + let signerOrProvider = this.signer || this.provider; + let contract = new ethers.Contract(address, abi, signerOrProvider); + this.contracts[name] = new Contracts[contractName](contract); + this.contracts[name].ipfs = this.ipfs; + + return this.contracts[name]; + } + + healthcheck() { + return new Healthcheck(this).check(); + } +} + +module.exports = Kredits; diff --git a/lib/serializers/contribution.js b/lib/serializers/contribution.js new file mode 100644 index 0000000..149b077 --- /dev/null +++ b/lib/serializers/contribution.js @@ -0,0 +1,67 @@ +/** + * Handle serialization for JSON-LD object of the contribution, according to + * https://github.com/67P/kosmos-schemas/blob/master/schemas/contribution.json + * + * @class + * @public + */ +class Contribution { + /** + * 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, + details + } = deserialized; + + let data = { + "@context": "https://schema.kosmos.org", + "@type": "Contribution", + "contributor": { + "ipfs": contributorIpfsHash + }, + kind, + description, + "details": details || {} + }; + + if (url) { + data["url"] = url; + } + + // Write it pretty to ipfs + return JSON.stringify(data, null, 2); + } +} + +module.exports = Contribution; diff --git a/lib/serializers/contributor.js b/lib/serializers/contributor.js new file mode 100644 index 0000000..d426370 --- /dev/null +++ b/lib/serializers/contributor.js @@ -0,0 +1,96 @@ +/** + * Handle serialization for JSON-LD object of the contributor, according to + * https://github.com/67P/kosmos-schemas/blob/master/schemas/contributor.json + * + * @class + * @public + */ +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, + accounts, + 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); + } +} + +module.exports = Contributor; diff --git a/lib/utils/healthcheck.js b/lib/utils/healthcheck.js new file mode 100644 index 0000000..8a76c58 --- /dev/null +++ b/lib/utils/healthcheck.js @@ -0,0 +1,28 @@ +class Healthcheck { + constructor(kredits) { + this.kredits = kredits; + } + + check() { + return this.kredits.ipfs._ipfsAPI.id() + .catch((error) => { + throw new Error(`IPFS node not available; config: ${JSON.stringify(this.kredits.ipfs.config)} - ${error.message}`); + }) + .then(() => { + let promises = Object.keys(this.kredits.contracts).map((name) => { + let contractWrapper = this.kredits.contracts[name]; + return this.kredits.provider.getCode(contractWrapper.contract.address).then((code) => { + // not sure if we always get the same return value if the code is not available + // so checking if it is < 5 long + if (code === '0x00' || code.length < 5) { + throw new Error(`Contract for: ${name} not found at ${contractWrapper.contract.address} on network ${this.kredits.provider.chainId}`); + } + return true; + }); + }); + return Promise.all(promises); + }); + } +} + +module.exports = Healthcheck; diff --git a/lib/utils/ipfs.js b/lib/utils/ipfs.js new file mode 100644 index 0000000..3c53ce0 --- /dev/null +++ b/lib/utils/ipfs.js @@ -0,0 +1,62 @@ +const ipfsAPI = require('ipfs-api'); +const multihashes = require('multihashes'); + +class IPFS { + + constructor(config) { + if (!config) { + config = {host: 'localhost', port: '5001', protocol: 'http'}; + } + 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 = multihashes.toB58String(this.encodeHash(data)); + + return this.cat(data.ipfsHash) + .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); + } + +} + +module.exports = IPFS; diff --git a/package-lock.json b/package-lock.json index 9e52047..070e4e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,11 @@ "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", "dev": true }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" + }, "ansi-escapes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", @@ -89,11 +94,10 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.0.0.tgz", "integrity": "sha512-Y+FKviD0uyIWWo/xE0XkUl0x1allKFhzEVJ+//2Dgqpy+n+B77MlPNqvyk7Vx50M9XyVzjnRhDqJAEAsyivlbA==", - "dev": true, "requires": { "bn.js": "4.11.6", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "ast-types": { @@ -102,10 +106,10 @@ "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", "dev": true }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "async-each-series": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz", + "integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=", "dev": true }, "babel-code-frame": { @@ -1005,14 +1009,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base-x": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz", "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", - "dev": true, "requires": { "safe-buffer": "5.1.1" } @@ -1032,14 +1034,12 @@ "bindings": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", - "dev": true + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" }, "bip66": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, "requires": { "safe-buffer": "5.1.1" } @@ -1048,7 +1048,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, "requires": { "readable-stream": "2.3.5", "safe-buffer": "5.1.1" @@ -1057,20 +1056,17 @@ "blakejs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=", - "dev": true + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" }, "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" @@ -1090,8 +1086,7 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browser-stdout": { "version": "1.3.0", @@ -1100,14 +1095,13 @@ "dev": true }, "browserify-aes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", - "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "requires": { "buffer-xor": "1.0.3", "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", "inherits": "2.0.3", "safe-buffer": "5.1.1" @@ -1117,7 +1111,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dev": true, "requires": { "base-x": "3.0.4" } @@ -1125,20 +1118,17 @@ "buffer-from": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", - "dev": true + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==" }, "buffer-loader": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/buffer-loader/-/buffer-loader-0.0.1.tgz", - "integrity": "sha1-TWd8qS3YiTEIeLAqL7z6txICTPI=", - "dev": true + "integrity": "sha1-TWd8qS3YiTEIeLAqL7z6txICTPI=" }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, "builtin-modules": { "version": "1.1.1", @@ -1149,8 +1139,7 @@ "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, "cacheable-request": { "version": "2.1.4", @@ -1194,7 +1183,6 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/cids/-/cids-0.5.3.tgz", "integrity": "sha512-ujWbNP8SeLKg5KmGrxYZM4c+ttd+wwvegrdtgmbi2KNFUbQN4pqsGZaGQE3rhjayXTbKFq36bYDbKhsnD0eMsg==", - "dev": true, "requires": { "multibase": "0.4.0", "multicodec": "0.2.6", @@ -1205,7 +1193,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, "requires": { "inherits": "2.0.3", "safe-buffer": "5.1.1" @@ -1390,14 +1377,12 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, "requires": { "buffer-from": "1.0.0", "inherits": "2.0.3", @@ -1420,29 +1405,27 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "1.0.4", "inherits": "2.0.3", + "md5.js": "1.3.4", "ripemd160": "2.0.1", "sha.js": "2.4.11" } }, "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", - "dev": true, + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "inherits": "2.0.3", "ripemd160": "2.0.1", "safe-buffer": "5.1.1", @@ -1534,8 +1517,7 @@ "detect-node": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", - "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", - "dev": true + "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=" }, "diff": { "version": "3.5.0", @@ -1553,11 +1535,10 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, "requires": { - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6" + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", + "create-hmac": "1.1.7" } }, "duplexer3": { @@ -1588,14 +1569,13 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "dev": true, "requires": { "bn.js": "4.11.6", "brorand": "1.1.0", "hash.js": "1.1.3", "hmac-drbg": "1.0.1", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, @@ -1609,7 +1589,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, "requires": { "once": "1.4.0" } @@ -1671,6 +1650,46 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "ethers": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-3.0.15.tgz", + "integrity": "sha512-d/tiMUavaeaY2GFqjpgfPzT46cEc0cilP3hnlTXR3LR/HR5Qrhv4PfdgW3gxBlR5aBTtUeM/lo8z8ph3JdtFhQ==", + "requires": { + "aes-js": "3.0.0", + "bn.js": "4.11.6", + "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" + }, + "dependencies": { + "elliptic": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", + "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", + "requires": { + "bn.js": "4.11.6", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "inherits": "2.0.1" + } + }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + } + } + }, "ethjs-abi": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", @@ -1686,7 +1705,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, "requires": { "md5.js": "1.3.4", "safe-buffer": "5.1.1" @@ -1822,8 +1840,7 @@ "flatmap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/flatmap/-/flatmap-0.0.3.tgz", - "integrity": "sha1-Hxik2TgVLUlZZfnJWNkjqy3WabQ=", - "dev": true + "integrity": "sha1-Hxik2TgVLUlZZfnJWNkjqy3WabQ=" }, "flow-parser": { "version": "0.67.1", @@ -1872,8 +1889,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "ganache-cli": { "version": "6.1.0", @@ -1974,7 +1990,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -2172,22 +2187,21 @@ } }, "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", - "dev": true, + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "hash.js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, "requires": { "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "he": { @@ -2200,10 +2214,9 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, "requires": { "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, @@ -2263,7 +2276,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -2272,8 +2284,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -2336,14 +2347,12 @@ "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "ipfs-api": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/ipfs-api/-/ipfs-api-19.0.0.tgz", "integrity": "sha512-eDWW66KccHbK/yHlrKdmzw7Tm15tocIgr8Hrwx9xiZinxqtXbsM1AorKTaJ7ZJLls97KiclPRMRIDTIL54q++g==", - "dev": true, "requires": { "async": "2.6.0", "big.js": "5.0.3", @@ -2363,7 +2372,7 @@ "multihashes": "0.4.13", "ndjson": "1.5.0", "once": "1.4.0", - "peer-id": "0.10.6", + "peer-id": "0.10.7", "peer-info": "0.11.6", "promisify-es6": "1.0.3", "pull-defer": "0.2.2", @@ -2381,7 +2390,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, "requires": { "lodash": "4.17.5" } @@ -2389,8 +2397,7 @@ "big.js": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.0.3.tgz", - "integrity": "sha512-av8LNZGBl4cg2r4ZhWqghJOxi2P8UCcWhdmrFgcHPMmUJ6jx1FbnyxjwL4URYzMK3QJg60qeMefQhv9G14oYKA==", - "dev": true + "integrity": "sha512-av8LNZGBl4cg2r4ZhWqghJOxi2P8UCcWhdmrFgcHPMmUJ6jx1FbnyxjwL4URYzMK3QJg60qeMefQhv9G14oYKA==" } } }, @@ -2398,7 +2405,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/ipfs-block/-/ipfs-block-0.6.1.tgz", "integrity": "sha512-28dgGsb2YsYnFs+To4cVBX8e/lTCb8eWDzGhN5csj3a/sHMOYrHeK8+Ez0IV67CI3lqKGuG/ZD01Cmd6JUvKrQ==", - "dev": true, "requires": { "cids": "0.5.3" } @@ -2407,7 +2413,6 @@ "version": "0.1.14", "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-0.1.14.tgz", "integrity": "sha512-s1tEnwKhdd17MmyC/EUMNVMDYzKhCiHDI11TF8tSBeWkEQp+0WUxkYuqvz0R5TSi2lNDJ/oVnEmwWhki2spUiQ==", - "dev": true, "requires": { "protons": "1.0.1" } @@ -2416,7 +2421,6 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/ipld-dag-pb/-/ipld-dag-pb-0.13.1.tgz", "integrity": "sha512-HxybRQvpY8IQ9T0bImlT5v4LBR3jJAgEnFRA/ZU2UNIiBuRkbirI9+VSX03+WkiYooiFMoZz6Qp/xYMdoogNWg==", - "dev": true, "requires": { "async": "2.6.0", "bs58": "4.0.1", @@ -2429,14 +2433,13 @@ "protons": "1.0.1", "pull-stream": "3.6.7", "pull-traverse": "1.0.3", - "stable": "0.1.6" + "stable": "0.1.7" }, "dependencies": { "async": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, "requires": { "lodash": "4.17.5" } @@ -2525,7 +2528,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-ipfs/-/is-ipfs-0.3.2.tgz", "integrity": "sha512-82V1j4LMkYy7H4seQQzOWqo7FiW3I64/1/ryo3dhtWKfOvm7ZolLMRQQfGKs4OXWauh5rAkPnamVcRISHwhmpQ==", - "dev": true, "requires": { "bs58": "4.0.1", "cids": "0.5.3", @@ -2606,8 +2608,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-utf8": { "version": "0.2.1", @@ -2624,8 +2625,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", @@ -2719,8 +2719,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json3": { "version": "3.3.2", @@ -2746,8 +2745,7 @@ "keypair": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/keypair/-/keypair-1.0.1.tgz", - "integrity": "sha1-dgNxknCvtlZO04oiCHoG/Jqk6hs=", - "dev": true + "integrity": "sha1-dgNxknCvtlZO04oiCHoG/Jqk6hs=" }, "keyv": { "version": "3.0.0", @@ -2789,11 +2787,10 @@ "version": "0.12.1", "resolved": "https://registry.npmjs.org/libp2p-crypto/-/libp2p-crypto-0.12.1.tgz", "integrity": "sha512-1/z8rxZ0DcQNreZhEsl7PnLr7DWOioSvYbKBLGkRwNRiNh1JJLgh0PdTySBb44wkrOGT+TxcGRd7iq3/X6Wxwg==", - "dev": true, "requires": { "asn1.js": "5.0.0", "async": "2.6.0", - "browserify-aes": "1.1.1", + "browserify-aes": "1.2.0", "bs58": "4.0.1", "keypair": "1.0.1", "libp2p-crypto-secp256k1": "0.2.2", @@ -2810,7 +2807,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, "requires": { "lodash": "4.17.5" } @@ -2821,7 +2817,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/libp2p-crypto-secp256k1/-/libp2p-crypto-secp256k1-0.2.2.tgz", "integrity": "sha1-DdUh8Yq8TjahUuJOmzYwewrpzwU=", - "dev": true, "requires": { "async": "2.6.0", "multihashing-async": "0.4.8", @@ -2834,7 +2829,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, "requires": { "lodash": "4.17.5" } @@ -3149,8 +3143,7 @@ "lodash": { "version": "4.17.5", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", - "dev": true + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" }, "lodash._baseassign": { "version": "3.2.0", @@ -3206,8 +3199,7 @@ "lodash.filter": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", - "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", - "dev": true + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" }, "lodash.isarguments": { "version": "3.1.0", @@ -3235,14 +3227,12 @@ "lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", - "dev": true + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" }, "lodash.uniqby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=", - "dev": true + "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=" }, "log-symbols": { "version": "2.2.0", @@ -3299,8 +3289,7 @@ "looper": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", - "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=", - "dev": true + "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=" }, "loose-envify": { "version": "1.3.1", @@ -3321,7 +3310,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", - "dev": true, "requires": { "pseudomap": "1.0.2", "yallist": "2.1.2" @@ -3340,22 +3328,9 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", - "dev": true, "requires": { "hash-base": "3.0.4", "inherits": "2.0.3" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" - } - } } }, "mem": { @@ -3480,22 +3455,19 @@ "dev": true }, "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "1.1.11" } @@ -3599,7 +3571,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-3.1.0.tgz", "integrity": "sha512-QhmsD/TufS5KB7brd1rkzLz2sJqybQlDT9prroiWacaw61DtHoe2X/vcAnOu8mZc7s7ZzevFPvY5tzv3yjBXlQ==", - "dev": true, "requires": { "bs58": "4.0.1", "ip": "1.1.5", @@ -3613,7 +3584,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.4.0.tgz", "integrity": "sha512-fnYvZJWDn3eSJ7EeWvS8zbOpRwuyPHpDggSnqGXkQMvYED5NdO9nyqnZboGvAT+r/60J8KZ09tW8YJHkS22sFw==", - "dev": true, "requires": { "base-x": "3.0.4" } @@ -3622,7 +3592,6 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.2.6.tgz", "integrity": "sha512-VGyRUDkxdJzWnj9x3C49MzI3+TtKKDYNfIBOaWBCNuPk6CE5CwwkL15gJtsLDfLay0fL4xTh4Af3kBbJSxSppw==", - "dev": true, "requires": { "varint": "5.0.0" } @@ -3631,7 +3600,6 @@ "version": "0.4.13", "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.13.tgz", "integrity": "sha512-HwJGEKPCpLlNlgGQA56CYh/Wsqa+c4JAq8+mheIgw7OK5T4QvNJqgp6TH8gZ4q4l1aiWeNat/H/MrFXmTuoFfQ==", - "dev": true, "requires": { "bs58": "4.0.1", "varint": "5.0.0" @@ -3641,7 +3609,6 @@ "version": "0.4.8", "resolved": "https://registry.npmjs.org/multihashing-async/-/multihashing-async-0.4.8.tgz", "integrity": "sha512-LCc4lfxmTJOHKIjZjFNgvmfB6nXS/ErLInT9uwU8udFrRm2PH+aTPk3mfCREKmCiSHOlCWiv2O8rlnBx+OjlMw==", - "dev": true, "requires": { "async": "2.6.0", "blakejs": "1.1.0", @@ -3655,7 +3622,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, "requires": { "lodash": "4.17.5" } @@ -3663,8 +3629,7 @@ "js-sha3": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz", - "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==", - "dev": true + "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==" } } }, @@ -3683,8 +3648,7 @@ "murmurhash3js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/murmurhash3js/-/murmurhash3js-3.0.1.tgz", - "integrity": "sha1-Ppg+W0fCoG9DpxMXTn5DXKBEuZg=", - "dev": true + "integrity": "sha1-Ppg+W0fCoG9DpxMXTn5DXKBEuZg=" }, "mute-stream": { "version": "0.0.7", @@ -3695,14 +3659,12 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "ndjson": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-1.5.0.tgz", "integrity": "sha1-rmA7NrE0vOw0e0UkIrC/mNWDLsg=", - "dev": true, "requires": { "json-stringify-safe": "5.0.1", "minimist": "1.2.0", @@ -3713,8 +3675,7 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" } } }, @@ -3739,14 +3700,12 @@ "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", - "dev": true + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" }, "nodeify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nodeify/-/nodeify-1.0.1.tgz", "integrity": "sha1-ZKtpp7268DzhB7TwM1yHwLnpGx0=", - "dev": true, "requires": { "is-promise": "1.0.1", "promise": "1.3.0" @@ -3755,8 +3714,7 @@ "is-promise": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", - "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=", - "dev": true + "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=" } } }, @@ -3872,7 +3830,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1.0.2" } @@ -3890,7 +3847,6 @@ "version": "0.3.7", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", - "dev": true, "requires": { "wordwrap": "0.0.3" } @@ -4118,8 +4074,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "2.0.1", @@ -4143,10 +4098,9 @@ } }, "peer-id": { - "version": "0.10.6", - "resolved": "https://registry.npmjs.org/peer-id/-/peer-id-0.10.6.tgz", - "integrity": "sha512-NyJgPRy108amQClcuBI/VZtyFJLDaTsPC3nVhZ87mpY5JVFmI2Er4atMap6/ToRJxm/RBX1Nh8CMxzlXCpfKKw==", - "dev": true, + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/peer-id/-/peer-id-0.10.7.tgz", + "integrity": "sha512-VEpMFcL9q0NQijmR0jsj38OGbY4yzaWMEareVkDahopmlNT+Cpsot8btPgsgBBApP9NiZj2Enwvh8rZN30ocQw==", "requires": { "async": "2.6.0", "libp2p-crypto": "0.12.1", @@ -4158,7 +4112,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, "requires": { "lodash": "4.17.5" } @@ -4169,18 +4122,16 @@ "version": "0.11.6", "resolved": "https://registry.npmjs.org/peer-info/-/peer-info-0.11.6.tgz", "integrity": "sha512-xrVNiAF1IhVJNGEg5P2UQN+subaEkszT8YkC3zdy06MK0vTH3cMHB+HH+ZURkoSLssc3HbK58ecXeKpQ/4zq5w==", - "dev": true, "requires": { "lodash.uniqby": "4.7.0", "multiaddr": "3.1.0", - "peer-id": "0.10.6" + "peer-id": "0.10.7" } }, "pem-jwk": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/pem-jwk/-/pem-jwk-1.5.1.tgz", "integrity": "sha1-eoY3/S9nqCflfAxC4cI8P9Us+wE=", - "dev": true, "requires": { "asn1.js": "1.0.3" }, @@ -4189,18 +4140,16 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-1.0.3.tgz", "integrity": "sha1-KBuj7B8kSP52X5Kk7s+IP+E2S1Q=", - "dev": true, "requires": { "bn.js": "1.3.0", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "bn.js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-1.3.0.tgz", "integrity": "sha1-DbTL+W+PI7dC9by50ap6mZSgXoM=", - "dev": true, "optional": true } } @@ -4259,14 +4208,12 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-1.3.0.tgz", "integrity": "sha1-5cyaTIJ45GZP/twBx9qEhCsEAXU=", - "dev": true, "requires": { "is-promise": "1.0.1" }, @@ -4274,28 +4221,34 @@ "is-promise": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", - "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=", - "dev": true + "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=" } } }, "promisify-es6": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/promisify-es6/-/promisify-es6-1.0.3.tgz", - "integrity": "sha512-N9iVG+CGJsI4b4ZGazjwLnxErD2d9Pe4DPvvXSxYA9tFNu8ymXME4Qs5HIQ0LMJpNM7zj+m0NlNnNeqFpKzqnA==", - "dev": true + "integrity": "sha512-N9iVG+CGJsI4b4ZGazjwLnxErD2d9Pe4DPvvXSxYA9tFNu8ymXME4Qs5HIQ0LMJpNM7zj+m0NlNnNeqFpKzqnA==" + }, + "promptly": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-3.0.3.tgz", + "integrity": "sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g==", + "dev": true, + "requires": { + "pify": "3.0.0", + "read": "1.0.7" + } }, "protocol-buffers-schema": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz", - "integrity": "sha512-Xdayp8sB/mU+sUV4G7ws8xtYMGdQnxbeIfLjyO9TZZRJdztBGhlmbI5x1qcY4TG5hBkIKGnc28i7nXxaugu88w==", - "dev": true + "integrity": "sha512-Xdayp8sB/mU+sUV4G7ws8xtYMGdQnxbeIfLjyO9TZZRJdztBGhlmbI5x1qcY4TG5hBkIKGnc28i7nXxaugu88w==" }, "protons": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/protons/-/protons-1.0.1.tgz", "integrity": "sha512-+0ZKnfVs+4c43tbAQ5j0Mck8wPcLnlxUYzKQoB4iDW4ocdXGnN4P+0dDbgX1FTpoY9+7P2Tn2scJyHHqj+S/lQ==", - "dev": true, "requires": { "protocol-buffers-schema": "3.3.2", "safe-buffer": "5.1.1", @@ -4312,38 +4265,32 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "pull-defer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.2.tgz", - "integrity": "sha1-CIew/7MK8ypW2+z6csFnInHwexM=", - "dev": true + "integrity": "sha1-CIew/7MK8ypW2+z6csFnInHwexM=" }, "pull-pushable": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", - "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=", - "dev": true + "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=" }, "pull-stream": { "version": "3.6.7", "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.7.tgz", - "integrity": "sha512-XdE2/o1I2lK7A+sbbA/HjYnd5Xk7wL5CwAKzqHIgcBsluDb0LiKHNTl1K0it3/RKPshQljLf4kl1aJ12YsCCGQ==", - "dev": true + "integrity": "sha512-XdE2/o1I2lK7A+sbbA/HjYnd5Xk7wL5CwAKzqHIgcBsluDb0LiKHNTl1K0it3/RKPshQljLf4kl1aJ12YsCCGQ==" }, "pull-traverse": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pull-traverse/-/pull-traverse-1.0.3.tgz", - "integrity": "sha1-dPtde+f6a9enjpeTPhmbeUWGaTg=", - "dev": true + "integrity": "sha1-dPtde+f6a9enjpeTPhmbeUWGaTg=" }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "1.4.1", "once": "1.4.0" @@ -4352,8 +4299,7 @@ "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, "query-string": { "version": "5.1.1", @@ -4407,6 +4353,15 @@ } } }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "0.0.7" + } + }, "read-chunk": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", @@ -4442,7 +4397,6 @@ "version": "2.3.5", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", - "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", @@ -4646,17 +4600,25 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", - "dev": true, "requires": { "hash-base": "2.0.2", "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "requires": { + "inherits": "2.0.3" + } + } } }, "rsa-pem-to-jwk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/rsa-pem-to-jwk/-/rsa-pem-to-jwk-1.1.3.tgz", "integrity": "sha1-JF52vbfnI0z+58oDLTG1TDj6uY4=", - "dev": true, "requires": { "object-assign": "2.1.1", "rsa-unpack": "0.0.6" @@ -4665,8 +4627,7 @@ "object-assign": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" } } }, @@ -4674,11 +4635,15 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/rsa-unpack/-/rsa-unpack-0.0.6.tgz", "integrity": "sha1-9Q69VqYoN45jHylxYQJs6atO3bo=", - "dev": true, "requires": { "optimist": "0.3.7" } }, + "rsvp": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.2.tgz", + "integrity": "sha512-8CU1Wjxvzt6bt8zln+hCjyieneU9s0LRW+lPRsjyVCY8Vm1kTbK7btBIrCGg6yY9U4undLDm/b1hKEEi1tLypg==" + }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", @@ -4715,8 +4680,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "scoped-regex": { "version": "1.0.0", @@ -4724,16 +4688,20 @@ "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=", "dev": true }, + "scrypt-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz", + "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=" + }, "secp256k1": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", - "dev": true, "requires": { "bindings": "1.3.0", "bip66": "1.1.5", "bn.js": "4.11.6", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "drbg.js": "1.0.1", "elliptic": "6.4.0", "nan": "2.10.0", @@ -4752,11 +4720,15 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=" + }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, "requires": { "inherits": "2.0.3", "safe-buffer": "5.1.1" @@ -4798,7 +4770,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/signed-varint/-/signed-varint-2.0.1.tgz", "integrity": "sha1-UKmYnafJjCxh2tEZvJdHDvhSgSk=", - "dev": true, "requires": { "varint": "5.0.0" } @@ -5074,22 +5045,19 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", - "dev": true, "requires": { "through2": "2.0.3" } }, "stable": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz", - "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA=", - "dev": true + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.7.tgz", + "integrity": "sha512-LmxBix+nUtyihSBpxXAhRakYEy49fan2suysdS1fUZcKjI+krXmH8DCZJ3yfngfrOnIFNU8O73EgNTzO2jI53w==" }, "stream-http": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz", "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==", - "dev": true, "requires": { "builtin-status-codes": "3.0.0", "inherits": "2.0.3", @@ -5111,7 +5079,6 @@ "version": "1.7.2", "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz", "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=", - "dev": true, "requires": { "looper": "3.0.0", "pull-stream": "3.6.7" @@ -5120,8 +5087,7 @@ "streamifier": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz", - "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=", - "dev": true + "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=" }, "strict-uri-encode": { "version": "1.1.0", @@ -5149,7 +5115,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, "requires": { "safe-buffer": "5.1.1" } @@ -5222,7 +5187,6 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", - "dev": true, "requires": { "bl": "1.2.2", "end-of-stream": "1.4.1", @@ -5262,7 +5226,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, "requires": { "readable-stream": "2.3.5", "xtend": "4.0.1" @@ -5286,8 +5249,7 @@ "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" }, "to-fast-properties": { "version": "1.0.3", @@ -5315,14 +5277,12 @@ "tweetnacl": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz", - "integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins=", - "dev": true + "integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins=" }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "underscore": { "version": "1.6.0", @@ -5354,8 +5314,12 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" }, "v8-compile-cache": { "version": "1.1.2", @@ -5376,8 +5340,7 @@ "varint": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", - "integrity": "sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8=", - "dev": true + "integrity": "sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8=" }, "vinyl": { "version": "1.2.0", @@ -5413,8 +5376,7 @@ } }, "webcrypto-shim": { - "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "dev": true + "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" }, "webpack-addons": { "version": "1.1.5", @@ -5458,6 +5420,14 @@ "recast": "0.12.9", "temp": "0.8.3", "write-file-atomic": "1.3.4" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } } }, "recast": { @@ -5532,8 +5502,7 @@ "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" }, "wrap-ansi": { "version": "2.1.0", @@ -5585,8 +5554,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { "version": "1.3.4", @@ -5599,11 +5567,15 @@ "slide": "1.1.6" } }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "3.2.1", @@ -5614,8 +5586,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { "version": "11.0.0", diff --git a/package.json b/package.json index b97dd9c..84ad412 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,14 @@ "name": "kredits-contracts", "version": "1.0.0", "description": "Ethereum contracts and npm wrapper for Kredits", - "main": "index.js", + "main": "./lib/kredits.js", "directories": { "test": "test" }, "scripts": { "build-json": "truffle compile && node ./scripts/build-json.js", - "bootstrap": "truffle migrate --reset && truffle exec scripts/seeds.js && npm run build-json", - "ganache": "ganache-cli -p 7545 -i 100", + "bootstrap": "truffle migrate --reset && npm run build-json && truffle exec scripts/seeds.js", + "ganache": "ganache-cli -p 7545 -i 100 --db=./.ganache-db -m kredits", "dev": "truffle migrate && npm run build-json", "test": "echo \"Error: no test specified\" && exit 1" }, @@ -24,9 +24,15 @@ }, "homepage": "https://github.com/67P/truffle-kredits#readme", "devDependencies": { + "async-each-series": "^1.1.0", "ganache-cli": "^6.0.3", - "ipfs-api": "^19.0.0", + "promptly": "^3.0.3", "truffle": "^4.1.3", "zeppelin-solidity": "^1.7.0" + }, + "dependencies": { + "ethers": "3.0.15", + "ipfs-api": "^19.0.0", + "rsvp": "^4.8.2" } } diff --git a/scripts/add-contributor.js b/scripts/add-contributor.js index e003bd9..34bb282 100644 --- a/scripts/add-contributor.js +++ b/scripts/add-contributor.js @@ -1,47 +1,50 @@ const Registry = artifacts.require('./Registry.sol'); -const Operator = artifacts.require('./Operator.sol'); -const Contributors = artifacts.require('./Contributors.sol'); +const promptly = require('promptly'); +const bs58 = require('bs58'); -var bs58 = require('bs58'); +const ethers = require('ethers'); +const Kredits = require('../lib/kredits'); -function getBytes32FromMultiash(multihash) { - const decoded = bs58.decode(multihash); - - return { - digest: `0x${decoded.slice(2).toString('hex')}`, - hashFunction: decoded[0], - size: decoded[1], - }; +async function prompt(message, options) { + if (!options) { + options = {default: ''} + } + return await promptly.prompt(message, options); } module.exports = function(callback) { Registry.deployed().then(async (registry) => { - var operatorAddress = await registry.getProxyFor('Operator'); - var contributorsAddress = await registry.getProxyFor('Contributors'); - var operator = await Operator.at(operatorAddress); - var contributors = await Contributors.at(contributorsAddress); + const networkId = parseInt(web3.version.network); + const provider = new ethers.providers.Web3Provider( + web3.currentProvider, { chainId: networkId } + ); + const kredits = await Kredits.setup(provider, provider.getSigner()); - let contributorToAddAddress = process.argv[4]; - if(!contributorToAddAddress) { - console.log('please provide an address'); - proxess.exit(); - } - let ipfsHash = process.argv[5] || 'QmQyZJT9uikzDYTZLhhyVZ5ReZVCoMucYzyvDokDJsijhj'; - let contributorMultihash = getBytes32FromMultiash(ipfsHash); - let isCore = true; - let contributorResult = await contributors.addContributor(contributorToAddAddress, contributorMultihash.digest, contributorMultihash.hashFunction, contributorMultihash.size, isCore); - console.log('Contributor added, tx: ', contributorResult.tx); + console.log(`Using contributors at: ${kredits.Contributor.contract.address}`); - let contributorId = await contributors.getContributorIdByAddress(contributorToAddAddress); - let proposalMultihash = getBytes32FromMultiash('QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'); - let proposalResult = await operator.addProposal(contributorId, 23, proposalMultihash.digest, proposalMultihash.hashFunction, proposalMultihash.size); - console.log('Proposal added, tx: ', proposalResult.tx); + let contributorAttributes = { + account: await prompt('Contributor address: ', {}), + name: await prompt('Name: '), + isCore: await prompt('core? y/n') === 'y', + kind: await prompt('Kind (default person): ', {default: 'person'}), + url: await prompt('URL: '), + github_username: await prompt('GitHub username: '), + github_uid: await prompt('GitHub UID: '), + wiki_username: await prompt('Wiki username: '), + }; - let proposalId = await operator.proposalsCount(); - let votingResult = await operator.vote(proposalId.toNumber()-1); - console.log('Voted for proposal', proposalId.toString(), votingResult.tx); + console.log("\nAdding contributor:"); + console.log(contributorAttributes); + + kredits.Contributor.add(contributorAttributes, {gasLimit: 250000}).then((result) => { + console.log("\n\nResult:"); + console.log(result); + callback(); + }).catch((error) => { + console.log('Failed to create contributor'); + callback(error); + }); - callback(); }); } diff --git a/scripts/add-proposal.js b/scripts/add-proposal.js index 35a8c55..6dbe117 100644 --- a/scripts/add-proposal.js +++ b/scripts/add-proposal.js @@ -1,8 +1,9 @@ const Registry = artifacts.require('./Registry.sol'); const Operator = artifacts.require('./Operator.sol'); const Contributors = artifacts.require('./Contributors.sol'); +const promptly = require('promptly'); -var bs58 = require('bs58'); +const bs58 = require('bs58'); function getBytes32FromMultiash(multihash) { const decoded = bs58.decode(multihash); @@ -22,12 +23,9 @@ module.exports = function(callback) { var operator = await Operator.at(operatorAddress); var contributors = await Contributors.at(contributorsAddress); - let recipientAddress = process.argv[4]; - if(!recipientAddress) { - console.log('please provide an address'); - process.exit(); - } - let ipfsHash = process.argv[5] || 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'; + let recipientAddress = await promptly.prompt('Contributor address: '); + let ipfsHash = await promptly.prompt('IPFS hash (blank for default): ', { default: 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs' }); + let multihash = getBytes32FromMultiash(ipfsHash); let contributorId = await contributors.getContributorIdByAddress(recipientAddress); diff --git a/scripts/build-json.js b/scripts/build-json.js index f8bd472..db00827 100644 --- a/scripts/build-json.js +++ b/scripts/build-json.js @@ -18,14 +18,16 @@ files.forEach((fileName) => { let abiFile = path.join(abisPath, `${fileName}.json`); fs.writeFileSync(abiFile, JSON.stringify(file.abi)); - let addresseFile = path.join(addressesPath, `${fileName}.json`); - let addresses = Object.keys(file.networks) - .reduce((addresses, key) => { - addresses[key] = file.networks[key].address; - return addresses; - }, {}); - fs.writeFileSync(addresseFile, JSON.stringify(addresses)); - - let indexFile = path.join(libPath, 'index.js'); - fs.writeFileSync(indexFile, `module.exports = ${JSON.stringify(files)};`); + if (fileName === 'Registry') { + let addresseFile = path.join(addressesPath, `${fileName}.json`); + let content = fs.readFileSync(addresseFile); + let addresses = Object.keys(file.networks) + .reduce((addresses, key) => { + addresses[key] = file.networks[key].address; + return addresses; + }, JSON.parse(content)); + fs.writeFileSync(addresseFile, JSON.stringify(addresses)); + } }); + +console.log("Don't forget to reaload the JSON files from your application; i.e. restart kredits-web"); diff --git a/scripts/cli.js b/scripts/cli.js index 20ac150..f1c733f 100644 --- a/scripts/cli.js +++ b/scripts/cli.js @@ -1,39 +1,45 @@ const REPL = require('repl'); +const promptly = require('promptly'); + +const ethers = require('ethers'); +const Kredits = require('../lib/kredits'); module.exports = function(callback) { const Registry = artifacts.require('./Registry.sol'); Registry.deployed().then(async (registry) => { - let contractName = process.argv[4]; - let method = process.argv[5]; - let args = process.argv.slice(6); - - if (!contractName) { - console.log("Usage:"); - console.log(" truffle exec scripts/cli.js [ ]"); - callback(); - return; + let contractName = await promptly.prompt('Contract Name: '); + let method = await promptly.prompt('Function: '); + let argumentInput = await promptly.prompt('Arguments (comma separated): ', { default: '' }); + let args = []; + if (argumentInput !== '') { + args = argumentInput.split(',').map(a => a.trim()); } - let contractAddress = await registry.getProxyFor(contractName); - console.log(`Using ${contractName} at ${contractAddress}`); - let contract = await artifacts.require(`./${contractName}`).at(contractAddress); + const networkId = parseInt(web3.version.network); + const provider = new ethers.providers.Web3Provider( + web3.currentProvider, { chainId: networkId } + ); + const kredits = await Kredits.setup(provider, provider.getSigner()); + + const contract = kredits[contractName].contract; + console.log(`Using ${contractName} at ${contract.address}`); + console.log(`Calling ${method} with ${JSON.stringify(args)}`); if (!contract[method]) { callback(new Error(`Method ${method} is not defined on ${contractName}`)); return; } - console.log(`Calling ${method} with ${JSON.stringify(args)}`); contract[method](...args).then((result) => { console.log("\nResult:"); console.log(result); console.log("\nStartig a REPL. (type .exit to exit)"); - console.log(`defined variables: result, ${contractName}, web3`); + console.log(`defined variables: result, ${contractName}, kredis`); let r = REPL.start(); r.context.result = result; r.context[contractName] = contract; - r.context.web3 = web3; + r.context.kredits = kredits; r.on('exit', () => { console.log('Bye'); diff --git a/scripts/multihash.js b/scripts/multihash.js deleted file mode 100644 index bf59b2f..0000000 --- a/scripts/multihash.js +++ /dev/null @@ -1,35 +0,0 @@ -var bs58 = require('bs58'); - -function getBytes32FromMultiash(multihash) { - const decoded = bs58.decode(multihash); - - return { - digest: `0x${decoded.slice(2).toString('hex')}`, - hashFunction: decoded[0], - size: decoded[1], - }; -} - - -function getMultihashFromBytes32(multihash) { - const { digest, hashFunction, size } = multihash; - if (size === 0) return null; - - // cut off leading "0x" - const hashBytes = Buffer.from(digest.slice(2), 'hex'); - - // prepend hashFunction and digest size - //const multihashBytes = new (hashBytes.constructor)(2 + hashBytes.length); - const multihashBytes = new Buffer(2 + hashBytes.length); - - console.log(hashBytes.constructor); - - multihashBytes[0] = hashFunction; - multihashBytes[1] = size; - multihashBytes.set(hashBytes, 2); - - return bs58.encode(multihashBytes); -} - -var m = getBytes32FromMultiash(process.argv[2]); -console.log(m) diff --git a/scripts/seeds.js b/scripts/seeds.js index 69d79fa..7e9fd9a 100644 --- a/scripts/seeds.js +++ b/scripts/seeds.js @@ -1,34 +1,39 @@ const path = require('path'); const seeds = require(path.join(__dirname, '..', '/config/seeds.js')); -const IPFS = require('ipfs-api'); -var ipfs = IPFS({host: 'localhost', port: '5001', protocol: 'http'}) +const ethers = require('ethers'); +const Kredits = require('../lib/kredits'); + +const each = require('async-each-series'); module.exports = function(callback) { const Registry = artifacts.require('./Registry.sol'); - const contracts = {}; - Registry.deployed().then((registry) => { - Object.keys(seeds.contractCalls).forEach(async (contract) => { - var address = await registry.getProxyFor(contract); - console.log(`Using ${contract} at ${address}`); - contracts[contract] = await artifacts.require(contract).at(address); + Registry.deployed().then(async (registry) => { - Object.keys(seeds.contractCalls[contract]).forEach((method) => { - seeds.contractCalls[contract][method].forEach((args) => { - console.log(`[Sending] ${contract}.#${method}(${JSON.stringify(args)})`); - contracts[contract][method](...args).then((result) => { - console.log(`[Result] ${contract}.${method}(${JSON.stringify(args)}) => ${result.tx}`); - }); - }); + const networkId = parseInt(web3.version.network); + const provider = new ethers.providers.Web3Provider( + web3.currentProvider, { chainId: networkId } + ); + const kredits = await Kredits.setup(provider, provider.getSigner()); + + each(seeds.contractCalls, (call, next) => { + let [contractName, method, args] = call; + let contractWrapper = kredits[contractName]; + let func; + if (contractWrapper[method]) { + func = contractWrapper[method]; + } else { + func = contractWrapper.functions[method]; + } + func.apply(contractWrapper, args).then((result) => { + console.log(`[OK] kredits.${contractName}.${method}(${JSON.stringify(args)}) => ${result.hash}`); + next(); + }).catch((error) => { + console.log(`[FAILD] kredits.${contractName}.${method}(${JSON.stringify(args)})`); + callback(error) }); - }); + }, () => { console.log("\nDone!") }); + }); - - - seeds.ipfsContent.forEach((content) => { - ipfs.add(new ipfs.Buffer(JSON.stringify(content))).then((result) => { console.log(`[IPFS] added ${result[0].hash}`) }); - }); - - callback(); } diff --git a/scripts/send-funds.js b/scripts/send-funds.js index 262e286..eff869a 100644 --- a/scripts/send-funds.js +++ b/scripts/send-funds.js @@ -1,12 +1,12 @@ +const promptly = require('promptly'); + +module.exports = async function(callback) { + let recipient = await promptly.prompt('Recipient address: '); + let amount = await promptly.prompt('Amount: ', {default: '1'}); + amount = parseInt(amount); + + console.log(`sending ${amount} ETH from ${web3.eth.accounts[0]} to ${recipient}`); -module.exports = function(callback) { - let recipient = process.argv[4]; - if (!recipient) { - console.log('Please provide a recipient address'); - process.exit(); - } - let amount = parseInt(process.argv[5]) || 1; - console.log(recipient); web3.eth.sendTransaction({to: recipient, value: web3.toWei(amount), from: web3.eth.accounts[0]}, console.log); callback(); diff --git a/truffle.js b/truffle.js index f591088..77e88c5 100644 --- a/truffle.js +++ b/truffle.js @@ -5,6 +5,11 @@ module.exports = { host: "127.0.0.1", port: 7545, network_id: "*" // Match any network id + }, + kovan: { + host: "127.0.0.1", + port: 8545, + network_id: "42" } } };