From 7f300067034658898a4cadee056ebfc2543065ba Mon Sep 17 00:00:00 2001 From: bumi Date: Tue, 10 Apr 2018 16:25:17 +0200 Subject: [PATCH 01/30] More consistent contract parameter naming --- contracts/Operator.sol | 62 ++++++++++++++---------------------------- contracts/Token.sol | 9 +++--- 2 files changed, 25 insertions(+), 46 deletions(-) diff --git a/contracts/Operator.sol b/contracts/Operator.sol index 7b4fc6f..76fe3bd 100644 --- a/contracts/Operator.sol +++ b/contracts/Operator.sol @@ -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 ProposalCreated(uint256 id, address creator, uint recipientId, uint256 amount); event ProposalVoted(uint256 id, address voter, uint256 totalVotes); - event ProposalExecuted(uint256 id, uint recipient, uint256 amount); + event ProposalExecuted(uint256 id, uint recipientId, uint256 amount); modifier coreOnly() { require(contributorsContract().addressIsCore(msg.sender)); @@ -55,45 +55,29 @@ 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 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)); + function addProposal(uint recipientId, uint256 amount, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public returns { + require(contributorsContract().exists(recipientId)); proposalId = proposalsCount + 1; uint _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.recipientId = recipientId; + p.amount = amount; + p.ipfsHash = ipfsHash; + p.hashFunction = hashFunction; + p.hashSize = hashSize; p.votesCount = 0; - p.votesNeeded = _votesNeeded; + p.votesNeeded = votesNeeded; p.exists = true; proposalsCount++; ProposalCreated(proposalId, msg.sender, p.recipientId, 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 id) 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[id]; return ( p.creator, p.recipientId, @@ -109,25 +93,22 @@ 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, msg.sender, p.votesCount); } - function executeProposal(uint proposalId) private returns (bool) { + function executeProposal(uint proposalId) private { var p = proposals[proposalId]; require(!p.executed); require(p.votesCount >= p.votesNeeded); @@ -135,7 +116,6 @@ contract Operator is Upgradeable { tokenContract().mintFor(recipientAddress, p.amount, proposalId); p.executed = true; ProposalExecuted(proposalId, p.recipientId, p.amount); - return true; } } diff --git a/contracts/Token.sol b/contracts/Token.sol index d892165..3ce085b 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 recipientAddress, uint256 amount, uint proposalId) onlyRegistryContractFor('Operator') public { + totalSupply_ = totalSupply_.add(amount); + balances[recipientAddress] = balances[recipientAddress].add(amount); - LogMint(_recipient, _amount, _proposalId); - return true; + LogMint(recipientAddress, amount, proposalId); } } From 147904e2378d04a11d5790a10356df9b1986b107 Mon Sep 17 00:00:00 2001 From: bumi Date: Tue, 10 Apr 2018 16:40:11 +0200 Subject: [PATCH 02/30] maybe more consitent --- contracts/Operator.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/Operator.sol b/contracts/Operator.sol index 76fe3bd..79d070f 100644 --- a/contracts/Operator.sol +++ b/contracts/Operator.sol @@ -76,7 +76,8 @@ contract Operator is Upgradeable { ProposalCreated(proposalId, msg.sender, p.recipientId, p.amount); } - function getProposal(uint id) 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) { + function getProposal(uint proposalId) public view returns (uint256 id, address creator, uint256 recipientId, 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, From e116e7ebf3f52f78eefa416c7ab24a5d9f9cfe87 Mon Sep 17 00:00:00 2001 From: bumi Date: Tue, 10 Apr 2018 17:49:16 +0200 Subject: [PATCH 03/30] Use new naming convention to call address things accounts So here we use creatorAccount - similar to proposalId. Like this we will always have an *Account or *Id as identifier. --- contracts/Operator.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/Operator.sol b/contracts/Operator.sol index 79d070f..dc3bf46 100644 --- a/contracts/Operator.sol +++ b/contracts/Operator.sol @@ -7,7 +7,7 @@ import './Contributors.sol'; contract Operator is Upgradeable { struct Proposal { - address creator; + address creatorAccount; uint recipientId; uint votesCount; uint votesNeeded; @@ -24,9 +24,9 @@ contract Operator is Upgradeable { mapping(uint256 => Proposal) public proposals; uint256 public proposalsCount; - event ProposalCreated(uint256 id, address creator, uint recipientId, uint256 amount); - event ProposalVoted(uint256 id, address voter, uint256 totalVotes); - event ProposalExecuted(uint256 id, uint recipientId, uint256 amount); + event ProposalCreated(uint256 id, address creatorAccount, uint256 recipientId, uint256 amount); + event ProposalVoted(uint256 id, uint256 contributorId, uint256 totalVotes); + event ProposalExecuted(uint256 id, uint256 recipientId, uint256 amount); modifier coreOnly() { require(contributorsContract().addressIsCore(msg.sender)); @@ -62,7 +62,7 @@ contract Operator is Upgradeable { uint _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75; var p = proposals[proposalId]; - p.creator = msg.sender; + p.creatorAccount = msg.sender; p.recipientId = recipientId; p.amount = amount; p.ipfsHash = ipfsHash; @@ -106,7 +106,7 @@ contract Operator is Upgradeable { if (p.votesCount >= p.votesNeeded) { executeProposal(proposalId); } - ProposalVoted(proposalId, msg.sender, p.votesCount); + ProposalVoted(proposalId, voterId, p.votesCount); } function executeProposal(uint proposalId) private { From b85117835dd36c24bc20ab244afc4f8ff2033ab7 Mon Sep 17 00:00:00 2001 From: bumi Date: Tue, 10 Apr 2018 18:02:00 +0200 Subject: [PATCH 04/30] update contributor account vs. address --- contracts/Contributors.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 3a0350d581f5d0438ce023dcab0a62b2c21b3820 Mon Sep 17 00:00:00 2001 From: bumi Date: Tue, 10 Apr 2018 18:16:19 +0200 Subject: [PATCH 05/30] Fix --- contracts/Operator.sol | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/contracts/Operator.sol b/contracts/Operator.sol index dc3bf46..cff99e6 100644 --- a/contracts/Operator.sol +++ b/contracts/Operator.sol @@ -55,11 +55,11 @@ contract Operator is Upgradeable { return contributorsContract().coreContributorsCount(); } - function addProposal(uint recipientId, uint256 amount, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public returns { + function addProposal(uint recipientId, uint256 amount, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public { require(contributorsContract().exists(recipientId)); - proposalId = proposalsCount + 1; - uint _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75; + uint256 proposalId = proposalsCount + 1; + uint256 _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75; var p = proposals[proposalId]; p.creatorAccount = msg.sender; @@ -69,18 +69,19 @@ contract Operator is Upgradeable { p.hashFunction = hashFunction; p.hashSize = hashSize; p.votesCount = 0; - p.votesNeeded = votesNeeded; + p.votesNeeded = _votesNeeded; p.exists = true; proposalsCount++; ProposalCreated(proposalId, msg.sender, p.recipientId, p.amount); } - function getProposal(uint proposalId) public view returns (uint256 id, address creator, uint256 recipientId, uint256 votesCount, uint256 votesNeeded, uint256 amount, bool executed, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, uint256[] voterIds, bool exists) { + function getProposal(uint proposalId) public view returns (uint256 id, address creatorAccount, uint256 recipientId, 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, + id, + p.creatorAccount, p.recipientId, p.votesCount, p.votesNeeded, From 4fd35a86c8aac68081bacf28646a65b8388ec9be Mon Sep 17 00:00:00 2001 From: bumi Date: Sun, 15 Apr 2018 19:35:30 +0200 Subject: [PATCH 06/30] update seeds --- config/seeds.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/seeds.js b/config/seeds.js index 90badf1..ae3403a 100644 --- a/config/seeds.js +++ b/config/seeds.js @@ -8,9 +8,9 @@ let contractCalls = { }, Operator: { addProposal: [ - [1, 23, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" - [2, 42, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" - [2, 100, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32] // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" + [2, 23, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" + [3, 42, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" + [3, 100, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32] // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs" ], vote: [ [1] From d7c8ee46bdf941ea18651401d135c0c9417b6c2f Mon Sep 17 00:00:00 2001 From: bumi Date: Sun, 15 Apr 2018 19:58:28 +0200 Subject: [PATCH 07/30] Rename recipientId to contributorId in Operator --- contracts/Operator.sol | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/contracts/Operator.sol b/contracts/Operator.sol index cff99e6..45541ba 100644 --- a/contracts/Operator.sol +++ b/contracts/Operator.sol @@ -8,7 +8,7 @@ contract Operator is Upgradeable { struct Proposal { address creatorAccount; - uint recipientId; + 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 creatorAccount, uint256 recipientId, uint256 amount); - event ProposalVoted(uint256 id, uint256 contributorId, uint256 totalVotes); - event ProposalExecuted(uint256 id, uint256 recipientId, 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,15 +55,15 @@ contract Operator is Upgradeable { return contributorsContract().coreContributorsCount(); } - function addProposal(uint recipientId, uint256 amount, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public { - require(contributorsContract().exists(recipientId)); + function addProposal(uint contributorId, uint256 amount, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public { + require(contributorsContract().exists(contributorId)); uint256 proposalId = proposalsCount + 1; uint256 _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75; var p = proposals[proposalId]; p.creatorAccount = msg.sender; - p.recipientId = recipientId; + p.contributorId = contributorId; p.amount = amount; p.ipfsHash = ipfsHash; p.hashFunction = hashFunction; @@ -73,16 +73,16 @@ contract Operator is Upgradeable { 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 (uint256 id, address creatorAccount, uint256 recipientId, uint256 votesCount, uint256 votesNeeded, uint256 amount, bool executed, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, uint256[] voterIds, bool exists) { + 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 ( id, p.creatorAccount, - p.recipientId, + p.contributorId, p.votesCount, p.votesNeeded, p.amount, @@ -114,10 +114,10 @@ contract Operator is Upgradeable { 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); + ProposalExecuted(proposalId, p.contributorId, p.amount); } } From 9e57567cd3250396f1364957deb9551be3fca7b9 Mon Sep 17 00:00:00 2001 From: bumi Date: Sun, 15 Apr 2018 20:21:49 +0200 Subject: [PATCH 08/30] rename recipent to contributor in token contract --- contracts/Token.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/Token.sol b/contracts/Token.sol index 3ce085b..9d81a9f 100644 --- a/contracts/Token.sol +++ b/contracts/Token.sol @@ -17,11 +17,11 @@ contract Token is Upgradeable, BasicToken { decimals = 18; } - function mintFor(address recipientAddress, uint256 amount, uint proposalId) onlyRegistryContractFor('Operator') public { + function mintFor(address contributorAccount, uint256 amount, uint proposalId) onlyRegistryContractFor('Operator') public { totalSupply_ = totalSupply_.add(amount); - balances[recipientAddress] = balances[recipientAddress].add(amount); + balances[contributorAccount] = balances[contributorAccount].add(amount); - LogMint(recipientAddress, amount, proposalId); + LogMint(contributorAccount, amount, proposalId); } } From 4b1cbbd0f7540b11ef638c53c86a27905ff47d05 Mon Sep 17 00:00:00 2001 From: bumi Date: Sun, 15 Apr 2018 21:03:12 +0200 Subject: [PATCH 09/30] Persist ganache DB and use fixed Mnemonic This persists the state of the ganache db and uses a fixed mnemonic code to create accounts. It now acts more like a local presistent database and no need to send funds to the accounts after restart. --- .gitignore | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) 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/package.json b/package.json index b97dd9c..f5c22e7 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "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", + "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" }, From 64ce554c492c11b4ef200a7a995d63801e9d0e8b Mon Sep 17 00:00:00 2001 From: bumi Date: Mon, 16 Apr 2018 11:01:43 +0200 Subject: [PATCH 10/30] readme --- README.mdown | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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 From f2fc9fd1610b17bd8e032f9a80970fe7d524c474 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Tue, 17 Apr 2018 13:13:52 +0200 Subject: [PATCH 11/30] Add empty Ganache DB directory --- .ganache-db/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .ganache-db/.gitkeep diff --git a/.ganache-db/.gitkeep b/.ganache-db/.gitkeep new file mode 100644 index 0000000..e69de29 From d5e68e1639c6e0a497d9827540d992af53e82e87 Mon Sep 17 00:00:00 2001 From: bumi Date: Wed, 18 Apr 2018 18:51:27 +0200 Subject: [PATCH 12/30] Hello wrapper library --- lib/abis/Contributors.json | 2 +- lib/abis/Operator.json | 2 +- lib/abis/Token.json | 2 +- lib/addresses/Contributors.json | 2 +- lib/addresses/Operator.json | 2 +- lib/addresses/Registry.json | 2 +- lib/addresses/Token.json | 2 +- lib/contracts/base.js | 27 +++ lib/contracts/contributor.js | 58 +++++ lib/contracts/index.js | 5 + lib/contracts/operator.js | 58 +++++ lib/contracts/token.js | 7 + lib/index.js | 1 - lib/kredits.js | 128 ++++++++++ lib/serializers/contribution.js | 66 ++++++ lib/serializers/contributor.js | 95 ++++++++ lib/utils/ipfs.js | 59 +++++ package-lock.json | 408 ++++++++++++++------------------ package.json | 8 +- scripts/build-json.js | 4 +- 20 files changed, 694 insertions(+), 244 deletions(-) create mode 100644 lib/contracts/base.js create mode 100644 lib/contracts/contributor.js create mode 100644 lib/contracts/index.js create mode 100644 lib/contracts/operator.js create mode 100644 lib/contracts/token.js delete mode 100644 lib/index.js create mode 100644 lib/kredits.js create mode 100644 lib/serializers/contribution.js create mode 100644 lib/serializers/contributor.js create mode 100644 lib/utils/ipfs.js 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..2ccea3a 100644 --- a/lib/addresses/Contributors.json +++ b/lib/addresses/Contributors.json @@ -1 +1 @@ -{"100":"0x34262a9471ede40e94497d110652dcf0f26fa0db"} \ No newline at end of file +{"100":"0xa7fc9b1f678c41396b53904f94f50a42ff44d826"} \ No newline at end of file diff --git a/lib/addresses/Operator.json b/lib/addresses/Operator.json index 11272fd..0ef267e 100644 --- a/lib/addresses/Operator.json +++ b/lib/addresses/Operator.json @@ -1 +1 @@ -{"100":"0x901f3e99a170619857b354c101aa97244885a39e"} \ No newline at end of file +{"100":"0x95d3bd7d136bb0b7ac9988097e964236f8a9976e"} \ No newline at end of file diff --git a/lib/addresses/Registry.json b/lib/addresses/Registry.json index d7f6ba1..8a5492a 100644 --- a/lib/addresses/Registry.json +++ b/lib/addresses/Registry.json @@ -1 +1 @@ -{"100":"0x9447a29373cf3ce0edf41804820c2a9da0ef4fd9"} \ No newline at end of file +{"100":"0x513f8e80a8fbb9fa188320ecf231efcf2f6da9c5"} \ No newline at end of file diff --git a/lib/addresses/Token.json b/lib/addresses/Token.json index 763d73c..658df01 100644 --- a/lib/addresses/Token.json +++ b/lib/addresses/Token.json @@ -1 +1 @@ -{"100":"0x8ecf9fa8a1c50179cef966d53aaee3d2a382c932"} \ No newline at end of file +{"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..4249d48 --- /dev/null +++ b/lib/contracts/contributor.js @@ -0,0 +1,58 @@ +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) { + let json = ContributorSerializer.serialize(contributorAttr); + // TODO: validate against schema + + return this.ipfs + .add(json) + .then((ipfsHashAttr) => { + let contributor = [ + contributorAttr.address, + ipfsHashAttr.hashDigest, + ipfsHashAttr.hashFunction, + ipfsHashAttr.hashSize, + contributorAttr.isCore, + ]; + + console.log('[kredits] addContributor', ...contributor); + return this.functions.addContributor(...contributor); + }); + } +} + +module.exports = Contributor; diff --git a/lib/contracts/index.js b/lib/contracts/index.js new file mode 100644 index 0000000..9fd06ae --- /dev/null +++ b/lib/contracts/index.js @@ -0,0 +1,5 @@ +module.exports = { + Contributors: require('./contributor'), + Operator: require('./operator'), + Token: require('./token') +} diff --git a/lib/contracts/operator.js b/lib/contracts/operator.js new file mode 100644 index 0000000..3887f0f --- /dev/null +++ b/lib/contracts/operator.js @@ -0,0 +1,58 @@ +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) { + 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, + ]; + + console.log('[kredits] addProposal', ...proposal); + return this.functions.addProposal(...proposal); + }); + } +} + +module.exports = Operator; diff --git a/lib/contracts/token.js b/lib/contracts/token.js new file mode 100644 index 0000000..5f914ed --- /dev/null +++ b/lib/contracts/token.js @@ -0,0 +1,7 @@ +const Base = require('./base'); + +class Token extends Base { +} + +module.exports = Base; + 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..f1238fb --- /dev/null +++ b/lib/kredits.js @@ -0,0 +1,128 @@ +const ethers = require('ethers'); +const RSVP = require('rsvp'); + +const abis = { + Contributors: require('./abis/Contributors.json'), + Operator: require('./abis/Operator.json'), + Registry: require('./abis/Registry.json'), + Token: require('./abis/Token.json') +}; +const addresses = { + Registry: 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 { + static get contractNames() { + return Object.keys(abis); + } + + constructor(provider, signer, addresses) { + this.provider = provider; + this.signer = signer; + + // Initialize our registry contract + this.addresses = addresses; + this.contracts = {}; + } + + static setup(provider, signer, ipfsConfig) { + this.ipfsConfig = ipfsConfig; + let ipfsAPI = new IPFS(ipfsConfig); + this.ipfs = ipfsAPI; + + return this.ipfs._ipfsAPI.id().catch((error) => { + throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`); + }).then(() => { + + let registryContract = this.initRegistryContract(provider); + + let addresses = Kredits.contractNames.reduce((mem, name) => { + let contractName = capitalize(name); + mem[contractName] = registryContract.functions.getProxyFor(contractName).catch((error) => { + throw new Error(`Failed to get address for ${contractName} from registry at ${registryContract.address} + - correct registry? does it have version entry? - ${error.message}` + ); + }); + return mem; + }, {}); + + return RSVP.hash(addresses) + .then((addresses) => { + let kredits = new Kredits(provider, signer, addresses); + kredits.ipfs = ipfsAPI; + return kredits; + }); + }); + } + + static initRegistryContract(provider) { + let address = addresses['Registry'][provider.chainId]; + if (!address) { + throw new Error(`Registry address not found; invalid network? + requested network: ${provider.chainId} + supported networks: ${Object.keys(addresses['Registry'])} + `); + } + provider.getCode(address).then((code) => { + // not sure if we always get the same return value of the code is not available + // that's why checking if it is < 5 long + if (code === '0x00' || code.length < 5) { + throw new Error(`Registry not found at ${address} on network ${provider.chainId}`); + } + }); + let abi = abis['Registry']; + console.log('Initialize registry contract:', address, abi, provider); + return new ethers.Contract(address, abi, provider); + } + + get ipfs() { + return this._ipfsAPI; + } + set ipfs(ipfs) { + this._ipfsAPI = ipfs; + } + + get Contributor() { + // TODO: rename to contributor + return this.contractFor('contributors'); + } + + get Operator() { + return this.contractFor('operator'); + } + + get Token() { + return this.contractFor('token'); + } + + // Should be private + contractFor(name) { + if (this.contracts[name]) { + return this.contracts[name]; + } + + let contractName = capitalize(name); + console.log(contractName); + console.log(contracts); + let address = this.addresses[contractName]; + if (!address || !abis[contractName]) { + throw new Error(`Address or ABI not found for ${contractName}`); + } + let contract = new ethers.Contract(address, abis[contractName], this.signer); + this.contracts[name] = new contracts[contractName](contract); + this.contracts[name].ipfs = this.ipfs; + + return this.contracts[name]; + } +} + +module.exports = Kredits; diff --git a/lib/serializers/contribution.js b/lib/serializers/contribution.js new file mode 100644 index 0000000..e57365c --- /dev/null +++ b/lib/serializers/contribution.js @@ -0,0 +1,66 @@ +/** + * 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, + } = deserialized; + + let data = { + "@context": "https://schema.kosmos.org", + "@type": "Contribution", + "contributor": { + "ipfs": contributorIpfsHash + }, + kind, + description, + "details": {} + }; + + if (url) { + data["url"] = url; + } + + // Write it pretty to ipfs + return JSON.stringify(data, null, 2); + } +} + +module.exports = Contribution; diff --git a/lib/serializers/contributor.js b/lib/serializers/contributor.js new file mode 100644 index 0000000..985641d --- /dev/null +++ b/lib/serializers/contributor.js @@ -0,0 +1,95 @@ +/** + * 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, + 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/ipfs.js b/lib/utils/ipfs.js new file mode 100644 index 0000000..6dc1887 --- /dev/null +++ b/lib/utils/ipfs.js @@ -0,0 +1,59 @@ +const ipfsAPI = require('ipfs-api'); +const multihashes = require('multihashes'); + +class IPFS { + + constructor(config) { + this._ipfsAPI = ipfsAPI(config); + this._config = config; + } + + catAndMerge(data, deserialize) { + // if no hash details are found simply return the data; nothing to merge + if (!data.hashSize || data.hashSize === 0) { + return data; + } + // merge ipfsHash (encoded from hashDigest, hashSize, hashFunction) + data.ipfsHash = this.encodeHash(data); + + return this.cat(data) + .then(deserialize) + .then((attributes) => { + return Object.assign({}, data, attributes); + }); + } + + add(data) { + return this._ipfsAPI + .add(new this._ipfsAPI.Buffer(data)) + .then((res) => { + return this.decodeHash(res[0].hash); + }); + } + + cat(hashData) { + let ipfsHash = hashData; // default - if it is a string + if (hashData.hasOwnProperty('hashSize')) { + ipfsHash = this.encodeHash(hashData); + } + return this._ipfsAPI.cat(ipfsHash); + } + + decodeHash(ipfsHash) { + let multihash = multihashes.decode(multihashes.fromB58String(ipfsHash)); + return { + hashDigest: '0x' + multihashes.toHexString(multihash.digest), + hashSize: multihash.length, + hashFunction: multihash.code, + ipfsHash: ipfsHash + }; + } + + encodeHash(hashData) { + let digest = this._ipfsAPI.Buffer.from(hashData.hashDigest.slice(2), 'hex'); + return multihashes.encode(digest, hashData.hashFunction, hashData.hashSize); + } + +} + +module.exports = IPFS; diff --git a/package-lock.json b/package-lock.json index 9e52047..e3024a1 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": { @@ -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,24 @@ "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==" }, "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 +4255,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 +4289,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", @@ -4442,7 +4378,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 +4581,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 +4608,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 +4616,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 +4661,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 +4669,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 +4701,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 +4751,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 +5026,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 +5060,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 +5068,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 +5096,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 +5168,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 +5207,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 +5230,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 +5258,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 +5295,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 +5321,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 +5357,7 @@ } }, "webcrypto-shim": { - "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "dev": true + "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" }, "webpack-addons": { "version": "1.1.5", @@ -5532,8 +5475,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 +5527,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 +5540,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 +5559,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 f5c22e7..b2e9257 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "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" }, @@ -25,8 +25,12 @@ "homepage": "https://github.com/67P/truffle-kredits#readme", "devDependencies": { "ganache-cli": "^6.0.3", - "ipfs-api": "^19.0.0", "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/build-json.js b/scripts/build-json.js index f8bd472..2a426e5 100644 --- a/scripts/build-json.js +++ b/scripts/build-json.js @@ -26,6 +26,6 @@ files.forEach((fileName) => { }, {}); fs.writeFileSync(addresseFile, JSON.stringify(addresses)); - let indexFile = path.join(libPath, 'index.js'); - fs.writeFileSync(indexFile, `module.exports = ${JSON.stringify(files)};`); }); + +console.log("Don't forget to reaload the JSON files from your application; i.e. restart kredits-web"); From 8b0df655e80de2a8dbae9726073047a02772bd64 Mon Sep 17 00:00:00 2001 From: bumi Date: Thu, 19 Apr 2018 00:23:28 +0200 Subject: [PATCH 13/30] Remove debug logs The classes from the library should be less noisy --- lib/contracts/contributor.js | 1 - lib/contracts/operator.js | 1 - lib/kredits.js | 3 --- 3 files changed, 5 deletions(-) diff --git a/lib/contracts/contributor.js b/lib/contracts/contributor.js index 4249d48..127e2dc 100644 --- a/lib/contracts/contributor.js +++ b/lib/contracts/contributor.js @@ -49,7 +49,6 @@ class Contributor extends Base { contributorAttr.isCore, ]; - console.log('[kredits] addContributor', ...contributor); return this.functions.addContributor(...contributor); }); } diff --git a/lib/contracts/operator.js b/lib/contracts/operator.js index 3887f0f..bcb31b8 100644 --- a/lib/contracts/operator.js +++ b/lib/contracts/operator.js @@ -49,7 +49,6 @@ class Operator extends Base { ipfsHashAttr.hashSize, ]; - console.log('[kredits] addProposal', ...proposal); return this.functions.addProposal(...proposal); }); } diff --git a/lib/kredits.js b/lib/kredits.js index f1238fb..33bbe8b 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -80,7 +80,6 @@ class Kredits { } }); let abi = abis['Registry']; - console.log('Initialize registry contract:', address, abi, provider); return new ethers.Contract(address, abi, provider); } @@ -111,8 +110,6 @@ class Kredits { } let contractName = capitalize(name); - console.log(contractName); - console.log(contracts); let address = this.addresses[contractName]; if (!address || !abis[contractName]) { throw new Error(`Address or ABI not found for ${contractName}`); From 424a2c4d023586c70858522c5213322af56a38ef Mon Sep 17 00:00:00 2001 From: bumi Date: Thu, 19 Apr 2018 00:28:03 +0200 Subject: [PATCH 14/30] Fix token modle.exports --- lib/contracts/token.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/contracts/token.js b/lib/contracts/token.js index 5f914ed..effbaaa 100644 --- a/lib/contracts/token.js +++ b/lib/contracts/token.js @@ -3,5 +3,5 @@ const Base = require('./base'); class Token extends Base { } -module.exports = Base; +module.exports = Token; From a16cd862f6354fc20537921f0517f2e36ca6a94a Mon Sep 17 00:00:00 2001 From: bumi Date: Thu, 19 Apr 2018 00:40:33 +0200 Subject: [PATCH 15/30] Better ipfs handling and default configs --- lib/kredits.js | 14 +++----------- lib/utils/ipfs.js | 3 +++ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/lib/kredits.js b/lib/kredits.js index 33bbe8b..8182137 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -32,14 +32,13 @@ class Kredits { // Initialize our registry contract this.addresses = addresses; this.contracts = {}; + this.ipfs = new IPFS(); } - static setup(provider, signer, ipfsConfig) { - this.ipfsConfig = ipfsConfig; + static setup(provider, signer, ipfsConfig = null) { let ipfsAPI = new IPFS(ipfsConfig); - this.ipfs = ipfsAPI; - return this.ipfs._ipfsAPI.id().catch((error) => { + return ipfsAPI._ipfsAPI.id().catch((error) => { throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`); }).then(() => { @@ -83,13 +82,6 @@ class Kredits { return new ethers.Contract(address, abi, provider); } - get ipfs() { - return this._ipfsAPI; - } - set ipfs(ipfs) { - this._ipfsAPI = ipfs; - } - get Contributor() { // TODO: rename to contributor return this.contractFor('contributors'); diff --git a/lib/utils/ipfs.js b/lib/utils/ipfs.js index 6dc1887..e0aecb6 100644 --- a/lib/utils/ipfs.js +++ b/lib/utils/ipfs.js @@ -4,6 +4,9 @@ const multihashes = require('multihashes'); class IPFS { constructor(config) { + if (!config) { + config = {host: 'localhost', port: '5001', protocol: 'http'}; + } this._ipfsAPI = ipfsAPI(config); this._config = config; } From 42bfb3d24ef7208f23260ad0401a908da428d500 Mon Sep 17 00:00:00 2001 From: bumi Date: Thu, 19 Apr 2018 01:30:27 +0200 Subject: [PATCH 16/30] Fallback to provider if no contract signer is given No signing functions will be available then. --- lib/kredits.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/kredits.js b/lib/kredits.js index 8182137..4e37b9b 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -106,7 +106,8 @@ class Kredits { if (!address || !abis[contractName]) { throw new Error(`Address or ABI not found for ${contractName}`); } - let contract = new ethers.Contract(address, abis[contractName], this.signer); + let signerOrProvider = this.signer || this.provider; + let contract = new ethers.Contract(address, abis[contractName], signerOrProvider); this.contracts[name] = new contracts[contractName](contract); this.contracts[name].ipfs = this.ipfs; From 3ad9835f7996299e8e0e6633d8a04d43e04cb2b8 Mon Sep 17 00:00:00 2001 From: bumi Date: Thu, 19 Apr 2018 15:02:40 +0200 Subject: [PATCH 17/30] Add kovan deployment --- lib/addresses/Contributors.json | 2 +- lib/addresses/Operator.json | 2 +- lib/addresses/Registry.json | 2 +- lib/addresses/Token.json | 2 +- truffle.js | 5 +++++ 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/addresses/Contributors.json b/lib/addresses/Contributors.json index 2ccea3a..7c8cb62 100644 --- a/lib/addresses/Contributors.json +++ b/lib/addresses/Contributors.json @@ -1 +1 @@ -{"100":"0xa7fc9b1f678c41396b53904f94f50a42ff44d826"} \ 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 0ef267e..b865526 100644 --- a/lib/addresses/Operator.json +++ b/lib/addresses/Operator.json @@ -1 +1 @@ -{"100":"0x95d3bd7d136bb0b7ac9988097e964236f8a9976e"} \ 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 8a5492a..8bdcb57 100644 --- a/lib/addresses/Registry.json +++ b/lib/addresses/Registry.json @@ -1 +1 @@ -{"100":"0x513f8e80a8fbb9fa188320ecf231efcf2f6da9c5"} \ No newline at end of file +{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x513f8e80a8fbb9fa188320ecf231efcf2f6da9c5"} \ No newline at end of file diff --git a/lib/addresses/Token.json b/lib/addresses/Token.json index 658df01..9242b73 100644 --- a/lib/addresses/Token.json +++ b/lib/addresses/Token.json @@ -1 +1 @@ -{"100":"0x3fc29fbe40c2d0ca78c7e81342f00226650fe2ad"} \ No newline at end of file +{"42":"0xf71ccf7ab48044ef9ae0b5e6983dbd3266b78b36","100":"0x3fc29fbe40c2d0ca78c7e81342f00226650fe2ad"} \ No newline at end of file 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" } } }; From 7f56e1163a2f2d4718214964fbb35b059eac07f1 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Thu, 19 Apr 2018 15:23:15 +0200 Subject: [PATCH 18/30] Add accounts to contributor serialization --- lib/serializers/contributor.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/serializers/contributor.js b/lib/serializers/contributor.js index 985641d..d426370 100644 --- a/lib/serializers/contributor.js +++ b/lib/serializers/contributor.js @@ -35,6 +35,7 @@ class Contributor { name, kind, url, + accounts, github_uid, github_username, wiki_username, From b6bc5af7bf4c9b7aded6a032bd7acb0bd57e475d Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Thu, 19 Apr 2018 15:39:00 +0200 Subject: [PATCH 19/30] Serialize details in contributions --- lib/serializers/contribution.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/serializers/contribution.js b/lib/serializers/contribution.js index e57365c..149b077 100644 --- a/lib/serializers/contribution.js +++ b/lib/serializers/contribution.js @@ -41,6 +41,7 @@ class Contribution { kind, description, url, + details } = deserialized; let data = { @@ -51,7 +52,7 @@ class Contribution { }, kind, description, - "details": {} + "details": details || {} }; if (url) { From fbd15953abc095ec04a71924bc3fccb2a74b2b81 Mon Sep 17 00:00:00 2001 From: Manuel Wiedenmann Date: Fri, 20 Apr 2018 00:16:14 +0200 Subject: [PATCH 20/30] Rename contributorAttr address -> account --- lib/contracts/contributor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/contracts/contributor.js b/lib/contracts/contributor.js index 127e2dc..94d4921 100644 --- a/lib/contracts/contributor.js +++ b/lib/contracts/contributor.js @@ -42,7 +42,7 @@ class Contributor extends Base { .add(json) .then((ipfsHashAttr) => { let contributor = [ - contributorAttr.address, + contributorAttr.account, ipfsHashAttr.hashDigest, ipfsHashAttr.hashFunction, ipfsHashAttr.hashSize, From fba767cd40ce26c59034a2d7fc58e1d589a91e12 Mon Sep 17 00:00:00 2001 From: Manuel Wiedenmann Date: Fri, 20 Apr 2018 00:18:06 +0200 Subject: [PATCH 21/30] Only create only registry addresses --- scripts/build-json.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/build-json.js b/scripts/build-json.js index 2a426e5..3bc2855 100644 --- a/scripts/build-json.js +++ b/scripts/build-json.js @@ -18,14 +18,15 @@ 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)); - + if (fileName === 'Registry') { + 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)); + } }); console.log("Don't forget to reaload the JSON files from your application; i.e. restart kredits-web"); From 9669f0137ba7cc70bd3fadd47ee926c214882779 Mon Sep 17 00:00:00 2001 From: bumi Date: Thu, 19 Apr 2018 15:59:40 +0200 Subject: [PATCH 22/30] Use prompt instead of argv arguments in scripts This makes it easier to handle truffle arguments which we for example need to specify the network. So we ask the user for input instead on using the argv array which might change. --- package-lock.json | 19 +++++++++++++++++++ package.json | 1 + scripts/add-contributor.js | 12 +++++------- scripts/add-proposal.js | 12 +++++------- scripts/cli.js | 16 +++++++--------- scripts/multihash.js | 2 +- scripts/send-funds.js | 16 ++++++++-------- 7 files changed, 46 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3024a1..473e969 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4230,6 +4230,16 @@ "resolved": "https://registry.npmjs.org/promisify-es6/-/promisify-es6-1.0.3.tgz", "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", @@ -4343,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", diff --git a/package.json b/package.json index b2e9257..9cf8786 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "homepage": "https://github.com/67P/truffle-kredits#readme", "devDependencies": { "ganache-cli": "^6.0.3", + "promptly": "^3.0.3", "truffle": "^4.1.3", "zeppelin-solidity": "^1.7.0" }, diff --git a/scripts/add-contributor.js b/scripts/add-contributor.js index e003bd9..2636c2a 100644 --- a/scripts/add-contributor.js +++ b/scripts/add-contributor.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 contributorToAddAddress = process.argv[4]; - if(!contributorToAddAddress) { - console.log('please provide an address'); - proxess.exit(); - } - let ipfsHash = process.argv[5] || 'QmQyZJT9uikzDYTZLhhyVZ5ReZVCoMucYzyvDokDJsijhj'; + let contributorToAddAddress = await promptly.prompt('Contributor address: '); + let ipfsHash = await promptly.prompt('IPFS hash (blank for default): ', { default: 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs' }); + let contributorMultihash = getBytes32FromMultiash(ipfsHash); let isCore = true; let contributorResult = await contributors.addContributor(contributorToAddAddress, contributorMultihash.digest, contributorMultihash.hashFunction, contributorMultihash.size, isCore); 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/cli.js b/scripts/cli.js index 20ac150..ca0b005 100644 --- a/scripts/cli.js +++ b/scripts/cli.js @@ -1,17 +1,15 @@ const REPL = require('repl'); +const promptly = require('promptly'); 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); diff --git a/scripts/multihash.js b/scripts/multihash.js index bf59b2f..e80719c 100644 --- a/scripts/multihash.js +++ b/scripts/multihash.js @@ -1,4 +1,4 @@ -var bs58 = require('bs58'); +const bs58 = require('bs58'); function getBytes32FromMultiash(multihash) { const decoded = bs58.decode(multihash); 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(); From 6738abd0b3e0cfec231f025d2cd091bd4bfec4fa Mon Sep 17 00:00:00 2001 From: bumi Date: Fri, 20 Apr 2018 02:09:30 +0200 Subject: [PATCH 23/30] Add support for contract tx call options This allows to provide options like gas price/limit settings for the state changing contract calls. These options are simply passed to the ethers contract instance. We need to provide the gas limit when using the jsonrpc provider. (ganache failed with revert if not enought gas was provider) --- lib/contracts/contributor.js | 4 ++-- lib/contracts/operator.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/contracts/contributor.js b/lib/contracts/contributor.js index 94d4921..1845730 100644 --- a/lib/contracts/contributor.js +++ b/lib/contracts/contributor.js @@ -34,7 +34,7 @@ class Contributor extends Base { }); } - add(contributorAttr) { + add(contributorAttr, callOptions = {}) { let json = ContributorSerializer.serialize(contributorAttr); // TODO: validate against schema @@ -49,7 +49,7 @@ class Contributor extends Base { contributorAttr.isCore, ]; - return this.functions.addContributor(...contributor); + return this.functions.addContributor(...contributor, callOptions); }); } } diff --git a/lib/contracts/operator.js b/lib/contracts/operator.js index bcb31b8..83a5eae 100644 --- a/lib/contracts/operator.js +++ b/lib/contracts/operator.js @@ -34,7 +34,7 @@ class Operator extends Base { }); } - addProposal(proposalAttr) { + addProposal(proposalAttr, callOptions = {}) { let json = ContributionSerializer.serialize(proposalAttr); // TODO: validate against schema @@ -49,7 +49,7 @@ class Operator extends Base { ipfsHashAttr.hashSize, ]; - return this.functions.addProposal(...proposal); + return this.functions.addProposal(...proposal, callOptions); }); } } From 3da3e22214cd9b1ad603229281b8472fee8db17e Mon Sep 17 00:00:00 2001 From: bumi Date: Fri, 20 Apr 2018 03:08:18 +0200 Subject: [PATCH 24/30] Refactor kredits address initialization This moves the Kredits initialization to the instance which allows us to be more flexible with handling contract addresses. Example: var k = new Kredits(provider, signer, {Registry: '0xabc'}); k.init().then((kredits) { ...}); var k = new Kredits(provider, signer, {Contributors: '0xabc'}) k.Contributor.add(...); --- lib/contracts/index.js | 5 ++- lib/contracts/registry.js | 6 +++ lib/kredits.js | 89 +++++++++++++++++---------------------- 3 files changed, 47 insertions(+), 53 deletions(-) create mode 100644 lib/contracts/registry.js diff --git a/lib/contracts/index.js b/lib/contracts/index.js index 9fd06ae..a4a1792 100644 --- a/lib/contracts/index.js +++ b/lib/contracts/index.js @@ -1,5 +1,6 @@ module.exports = { Contributors: require('./contributor'), Operator: require('./operator'), - Token: require('./token') -} + Token: require('./token'), + Registry: require('./registry') +}; 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/kredits.js b/lib/kredits.js index 8182137..8cb0075 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -1,17 +1,15 @@ const ethers = require('ethers'); const RSVP = require('rsvp'); -const abis = { +const ABIS = { Contributors: require('./abis/Contributors.json'), Operator: require('./abis/Operator.json'), Registry: require('./abis/Registry.json'), Token: require('./abis/Token.json') }; -const addresses = { - Registry: require('./addresses/Registry.json') -}; +const RegistryAddress = require('./addresses/Registry.json'); -const contracts = require('./contracts'); +const Contracts = require('./contracts'); const IPFS = require('./utils/ipfs') // Helpers @@ -22,64 +20,52 @@ function capitalize(word) { class Kredits { static get contractNames() { - return Object.keys(abis); + return Object.keys(ABIS); } constructor(provider, signer, addresses) { this.provider = provider; this.signer = signer; - // Initialize our registry contract - this.addresses = addresses; + // 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(); } - static setup(provider, signer, ipfsConfig = null) { - let ipfsAPI = new IPFS(ipfsConfig); + init(names) { + let contractsToLoad = names || Kredits.contractNames; + 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 }); + } - return ipfsAPI._ipfsAPI.id().catch((error) => { + static setup(provider, signer, ipfsConfig = null) { + console.log('Kredits.setup() is deprecated use new Kredits().init() instead'); + let ipfs = new IPFS(ipfsConfig); + + return ipfs._ipfsAPI.id().catch((error) => { throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`); }).then(() => { - let registryContract = this.initRegistryContract(provider); - - let addresses = Kredits.contractNames.reduce((mem, name) => { - let contractName = capitalize(name); - mem[contractName] = registryContract.functions.getProxyFor(contractName).catch((error) => { - throw new Error(`Failed to get address for ${contractName} from registry at ${registryContract.address} - - correct registry? does it have version entry? - ${error.message}` - ); - }); - return mem; - }, {}); - - return RSVP.hash(addresses) - .then((addresses) => { - let kredits = new Kredits(provider, signer, addresses); - kredits.ipfs = ipfsAPI; - return kredits; - }); + return new Kredits(provider, signer).init().then((kredits) => { + kredits.ipfs = ipfs; + return kredits; + }); }); } - static initRegistryContract(provider) { - let address = addresses['Registry'][provider.chainId]; - if (!address) { - throw new Error(`Registry address not found; invalid network? - requested network: ${provider.chainId} - supported networks: ${Object.keys(addresses['Registry'])} - `); - } - provider.getCode(address).then((code) => { - // not sure if we always get the same return value of the code is not available - // that's why checking if it is < 5 long - if (code === '0x00' || code.length < 5) { - throw new Error(`Registry not found at ${address} on network ${provider.chainId}`); - } - }); - let abi = abis['Registry']; - return new ethers.Contract(address, abi, provider); + get Registry() { + return this.contractFor('registry'); } get Contributor() { @@ -101,13 +87,14 @@ class Kredits { return this.contracts[name]; } - let contractName = capitalize(name); - let address = this.addresses[contractName]; - if (!address || !abis[contractName]) { + 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 contract = new ethers.Contract(address, abis[contractName], this.signer); - this.contracts[name] = new contracts[contractName](contract); + let contract = new ethers.Contract(address, abi, this.signer); + this.contracts[name] = new Contracts[contractName](contract); this.contracts[name].ipfs = this.ipfs; return this.contracts[name]; From 2503ac7c73774ae97d8629294732ac7b2f4feee2 Mon Sep 17 00:00:00 2001 From: bumi Date: Fri, 20 Apr 2018 12:56:09 +0200 Subject: [PATCH 25/30] Refactor helper scripts to use kredits module This reuses the kredits library functions in the helper scripts and seeds. We no longer need to add IPFS hashes manually but simply can provider contributor/proposal data. --- config/seeds.js | 74 +++++--------------------------------- package-lock.json | 16 ++++++--- package.json | 3 +- scripts/add-contributor.js | 61 ++++++++++++++++--------------- scripts/cli.js | 20 +++++++---- scripts/multihash.js | 35 ------------------ scripts/seeds.js | 51 ++++++++++++++------------ 7 files changed, 98 insertions(+), 162 deletions(-) delete mode 100644 scripts/multihash.js 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/package-lock.json b/package-lock.json index 473e969..070e4e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -106,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": { @@ -5420,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": { diff --git a/package.json b/package.json index 9cf8786..36784fd 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "scripts": { "build-json": "truffle compile && node ./scripts/build-json.js", - "bootstrap": "truffle migrate --reset && truffle exec scripts/seeds.js && npm run build-json", + "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,6 +24,7 @@ }, "homepage": "https://github.com/67P/truffle-kredits#readme", "devDependencies": { + "async-each-series": "^1.1.0", "ganache-cli": "^6.0.3", "promptly": "^3.0.3", "truffle": "^4.1.3", diff --git a/scripts/add-contributor.js b/scripts/add-contributor.js index 2636c2a..34bb282 100644 --- a/scripts/add-contributor.js +++ b/scripts/add-contributor.js @@ -1,45 +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'); -function getBytes32FromMultiash(multihash) { - const decoded = bs58.decode(multihash); +const ethers = require('ethers'); +const Kredits = require('../lib/kredits'); - 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 = await promptly.prompt('Contributor address: '); - let ipfsHash = await promptly.prompt('IPFS hash (blank for default): ', { default: 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs' }); + console.log(`Using contributors at: ${kredits.Contributor.contract.address}`); - 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); + 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 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); + console.log("\nAdding contributor:"); + console.log(contributorAttributes); - let proposalId = await operator.proposalsCount(); - let votingResult = await operator.vote(proposalId.toNumber()-1); - console.log('Voted for proposal', proposalId.toString(), votingResult.tx); + 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/cli.js b/scripts/cli.js index ca0b005..f1c733f 100644 --- a/scripts/cli.js +++ b/scripts/cli.js @@ -1,6 +1,9 @@ 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) => { @@ -12,26 +15,31 @@ module.exports = function(callback) { 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 e80719c..0000000 --- a/scripts/multihash.js +++ /dev/null @@ -1,35 +0,0 @@ -const 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(); } From 92f3963c5aff73af70a4d14866e7b6216a8ed8ef Mon Sep 17 00:00:00 2001 From: bumi Date: Fri, 20 Apr 2018 13:01:44 +0200 Subject: [PATCH 26/30] Remove not needed static contractNames function --- lib/kredits.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/kredits.js b/lib/kredits.js index 8cb0075..f4a065d 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -19,9 +19,6 @@ function capitalize(word) { } class Kredits { - static get contractNames() { - return Object.keys(ABIS); - } constructor(provider, signer, addresses) { this.provider = provider; @@ -36,7 +33,7 @@ class Kredits { } init(names) { - let contractsToLoad = names || Kredits.contractNames; + let contractsToLoad = names || Object.keys(ABIS); let addressPromises = contractsToLoad.map((contractName) => { return this.Registry.functions.getProxyFor(contractName).then((address) => { this.addresses[contractName] = address; From 6ca23de343efbcd4fa359a16ff3401632c4e4819 Mon Sep 17 00:00:00 2001 From: Manuel Wiedenmann Date: Sat, 21 Apr 2018 10:44:09 +0200 Subject: [PATCH 27/30] Lock ethers.js at 3.0.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 36784fd..84ad412 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "zeppelin-solidity": "^1.7.0" }, "dependencies": { - "ethers": "^3.0.15", + "ethers": "3.0.15", "ipfs-api": "^19.0.0", "rsvp": "^4.8.2" } From 7ba32bb0ed95d6149ce248bdf828b306117d7f79 Mon Sep 17 00:00:00 2001 From: bumi Date: Sat, 21 Apr 2018 16:45:04 +0200 Subject: [PATCH 28/30] Extract healthcheck into its own class This moves the whole checks if everything is running into its own class and is no longer inside the different functions. Makes the functions smaller and the healthcheck can be used from the client only if wanted/needed. --- lib/kredits.js | 18 +++++++++--------- lib/utils/healthcheck.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 lib/utils/healthcheck.js diff --git a/lib/kredits.js b/lib/kredits.js index 9062d69..5ec030a 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -1,6 +1,8 @@ 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'), @@ -49,15 +51,9 @@ class Kredits { static setup(provider, signer, ipfsConfig = null) { console.log('Kredits.setup() is deprecated use new Kredits().init() instead'); let ipfs = new IPFS(ipfsConfig); - - return ipfs._ipfsAPI.id().catch((error) => { - throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`); - }).then(() => { - - return new Kredits(provider, signer).init().then((kredits) => { - kredits.ipfs = ipfs; - return kredits; - }); + return new Kredits(provider, signer).init().then((kredits) => { + kredits.ipfs = ipfs; + return kredits; }); } @@ -98,6 +94,10 @@ class Kredits { return this.contracts[name]; } + + healthcheck() { + return new Healthcheck(this).check(); + } } module.exports = Kredits; 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; From 92c566c13cd5d28aae8060677540af6330c2795a Mon Sep 17 00:00:00 2001 From: Manuel Wiedenmann Date: Sat, 21 Apr 2018 20:01:46 +0200 Subject: [PATCH 29/30] Fix build-json to merge addresses --- lib/addresses/Registry.json | 2 +- scripts/build-json.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/addresses/Registry.json b/lib/addresses/Registry.json index 8bdcb57..25faf40 100644 --- a/lib/addresses/Registry.json +++ b/lib/addresses/Registry.json @@ -1 +1 @@ -{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x513f8e80a8fbb9fa188320ecf231efcf2f6da9c5"} \ No newline at end of file +{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x7458dea485d9d8301e3ce43e8a1ec1456be5ba83"} \ No newline at end of file diff --git a/scripts/build-json.js b/scripts/build-json.js index 3bc2855..db00827 100644 --- a/scripts/build-json.js +++ b/scripts/build-json.js @@ -20,11 +20,12 @@ files.forEach((fileName) => { 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)); } }); From 471c705e6416edac56c8e0cb7754538eb2b88c8b Mon Sep 17 00:00:00 2001 From: Manuel Wiedenmann Date: Sat, 21 Apr 2018 20:59:59 +0200 Subject: [PATCH 30/30] Replaces the ipfsHash buffer with a B58 string --- lib/utils/ipfs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/utils/ipfs.js b/lib/utils/ipfs.js index e0aecb6..3c53ce0 100644 --- a/lib/utils/ipfs.js +++ b/lib/utils/ipfs.js @@ -17,9 +17,9 @@ class IPFS { return data; } // merge ipfsHash (encoded from hashDigest, hashSize, hashFunction) - data.ipfsHash = this.encodeHash(data); + data.ipfsHash = multihashes.toB58String(this.encodeHash(data)); - return this.cat(data) + return this.cat(data.ipfsHash) .then(deserialize) .then((attributes) => { return Object.assign({}, data, attributes);