diff --git a/CHANGELOG.md b/CHANGELOG.md index c9fc86c..942cf3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,25 +3,21 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -## [0.0.70](https://github.com/kleros/kleros-api/compare/v0.0.69...v0.0.70) (2018-03-16) +## [0.0.70](https://github.com/kleros/kleros-api/compare/v0.0.69...v0.0.70) (2018-03-16) ### Bug Fixes * **notifications:** error in stateful notifications ([2155f60](https://github.com/kleros/kleros-api/commit/2155f60)) - - -## [0.0.69](https://github.com/kleros/kleros-api/compare/v0.0.68...v0.0.69) (2018-03-15) +## [0.0.69](https://github.com/kleros/kleros-api/compare/v0.0.68...v0.0.69) (2018-03-15) ### Bug Fixes * untranspiled files outside src directory ([83f1d59](https://github.com/kleros/kleros-api/commit/83f1d59)) - - ## [0.0.68](https://github.com/kleros/kleros-api/compare/v0.0.65...v0.0.68) (2018-03-15) diff --git a/package.json b/package.json index a596e60..95faace 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,12 @@ { "name": "kleros-api", "version": "0.0.70", - "description": "A Javascript library that makes it easy to build relayers and other DApps that use the Kleros protocol.", - "keywords": [ - "Blockchain", - "Ethereum", - "Kleros" - ], + "description": + "A Javascript library that makes it easy to build relayers and other DApps that use the Kleros protocol.", + "keywords": ["Blockchain", "Ethereum", "Kleros"], "main": "lib/index.js", "module": "es/index.js", - "files": [ - "es", - "lib", - "umd" - ], + "files": ["es", "lib", "umd"], "homepage": "https://kleros.io", "repository": "github:kleros/kleros-api", "bugs": "https://github.com/kleros/kleros-api/issues", @@ -35,12 +28,11 @@ "commitmsg": "kleros-scripts commitmsg", "cz": "kleros-scripts cz", "start": "babel src --out-dir ./es --watch --source-maps", - "build": "rimraf ./umd ./es ./lib && webpack --env.NODE_ENV=production -p && babel src --out-dir ./es --source-maps && cross-env BABEL_ENV=commonjs babel src --out-dir ./lib --source-maps" + "build": + "rimraf ./umd ./es ./lib && webpack --env.NODE_ENV=production -p && babel src --out-dir ./es --source-maps && cross-env BABEL_ENV=commonjs babel src --out-dir ./lib --source-maps" }, "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] + "extends": ["@commitlint/config-conventional"] }, "devDependencies": { "babel-cli": "^6.26.0", diff --git a/src/abstractWrappers/AbstractWrapper.js b/src/abstractWrappers/AbstractWrapper.js index 0ded7f5..b13ead4 100644 --- a/src/abstractWrappers/AbstractWrapper.js +++ b/src/abstractWrappers/AbstractWrapper.js @@ -1,3 +1,5 @@ +import * as errorConstants from '../constants/error' + class AbstractWrapper { /** * AbstractWrapper is the parent class for abstract classes that interact with the @@ -58,9 +60,7 @@ class AbstractWrapper { */ _checkArbitratorWrappersSet = () => { if (!this._Arbitrator) - throw new Error( - 'No Arbitrator Contract Wrapper specified. Please call setArbitrator' - ) + throw new Error(errorConstants.NO_ARBITRATOR_WRAPPER_SPECIFIED) } /** @@ -69,9 +69,7 @@ class AbstractWrapper { */ _checkArbitrableWrappersSet = () => { if (!this._ArbitrableContract) - throw new Error( - 'No Arbitrable Contract Wrapper specified. Please call setArbitrable' - ) + throw new Error(errorConstants.NO_ARBITRABLE_WRAPPER_SPECIFIED) } /** diff --git a/src/abstractWrappers/Arbitrator.js b/src/abstractWrappers/Arbitrator.js index 6a0e234..657a9a4 100644 --- a/src/abstractWrappers/Arbitrator.js +++ b/src/abstractWrappers/Arbitrator.js @@ -34,16 +34,8 @@ class Arbitrator extends AbstractWrapper { arbitratorAddress, // address of KlerosPOC account ) => { - const txHash = await this._Arbitrator.buyPNK( - amount, - arbitratorAddress, - account - ) - if (txHash) { - return this.getPNKBalance(arbitratorAddress, account) - } else { - throw new Error('unable to buy PNK') - } + await this._Arbitrator.buyPNK(amount, arbitratorAddress, account) + return this.getPNKBalance(arbitratorAddress, account) } /** diff --git a/src/abstractWrappers/Disputes.js b/src/abstractWrappers/Disputes.js index 377a86c..687bd9f 100644 --- a/src/abstractWrappers/Disputes.js +++ b/src/abstractWrappers/Disputes.js @@ -256,26 +256,19 @@ class Disputes extends AbstractWrapper { * @param {string} account - Ethereum account. * @param {string} arbitrableContractAddress - Address address of arbitrable contract. * @param {number} [arbitrationCost=DEFAULT_ARBITRATION_FEE] - Amount to pay the arbitrator. - * @returns {string} - txHash hash transaction | Error. + * @returns {object} - The result transaction object. */ - raiseDisputePartyA = async ( + raiseDisputePartyA = ( account, arbitrableContractAddress, arbitrationCost = arbitratorConstants.DEFAULT_ARBITRATION_FEE ) => { this._checkArbitrableWrappersSet() - try { - const txHash = await this._ArbitrableContract.payArbitrationFeeByPartyA( - account, - arbitrableContractAddress, - arbitrationCost - ) - - if (!txHash) throw new Error('unable to pay arbitration fee for party A') - return txHash - } catch (err) { - throw new Error(err) - } + return this._ArbitrableContract.payArbitrationFeeByPartyA( + account, + arbitrableContractAddress, + arbitrationCost + ) } /** @@ -283,23 +276,19 @@ class Disputes extends AbstractWrapper { * @param {string} account - Ethereum account. * @param {string} arbitrableContractAddress - Address address of arbitrable contract. * @param {number} [arbitrationCost=DEFAULT_ARBITRATION_FEE] - Amount to pay the arbitrator. - * @returns {string} - txHash hash of the transaction | Error. + * @returns {object} - The result transaction object. */ - raiseDisputePartyB = async ( + raiseDisputePartyB = ( account, arbitrableContractAddress, arbitrationCost = arbitratorConstants.DEFAULT_ARBITRATION_FEE ) => { this._checkArbitrableWrappersSet() - - const txHash = await this._ArbitrableContract.payArbitrationFeeByPartyB( + return this._ArbitrableContract.payArbitrationFeeByPartyB( account, arbitrableContractAddress, arbitrationCost ) - - if (!txHash) throw new Error('unable to pay arbitration fee for party B') - return txHash } /** @@ -435,16 +424,16 @@ class Disputes extends AbstractWrapper { * @param {number} ruling - Int representing the jurors decision. * @param {number[]} draws - Int[] of drawn votes for dispute. * @param {string} account - Address of user. - * @returns {string} - Transaction hash | Error. + * @returns {object} - The result transaction object. */ - submitVotesForDispute = async ( + submitVotesForDispute = ( arbitratorAddress, disputeId, ruling, draws, account - ) => { - const txHash = await this._Arbitrator.submitVotes( + ) => + this._Arbitrator.submitVotes( arbitratorAddress, disputeId, ruling, @@ -452,13 +441,6 @@ class Disputes extends AbstractWrapper { account ) - if (txHash) { - return txHash - } else { - throw new Error('unable to submit votes') - } - } - /** * Gets the deadline for an arbitrator's period, which is also the deadline for all its disputes. * @param {string} arbitratorAddress - The address of the arbitrator contract. @@ -580,7 +562,7 @@ class Disputes extends AbstractWrapper { ) if (_.isEmpty(disputeArray)) - throw new Error(`User ${account} does not have store data for dispute`) + throw new Error(errorConstants.NO_STORE_DATA_FOR_DISPUTE(account)) return disputeArray[0] } @@ -630,17 +612,10 @@ class Disputes extends AbstractWrapper { * @returns {object[]} - Array of ruling objects. */ getRulingOptions = async (arbitratorAddress, disputeId) => { - const dispute = await this._Arbitrator.getDispute( + const arbitrableContractAddress = (await this._Arbitrator.getDispute( arbitratorAddress, disputeId - ) - if (!dispute) { - throw new Error( - `Cannot fetch ruling options: Dispute from arbitrator ${arbitratorAddress} with disputeId: ${disputeId} does not exist` - ) - } - const arbitrableContractAddress = dispute.arbitratedContract - + )).arbitratedContract return this._ArbitrableContract.getRulingOptions( arbitrableContractAddress, arbitratorAddress, @@ -660,16 +635,11 @@ class Disputes extends AbstractWrapper { this._checkArbitratorWrappersSet() this._checkArbitrableWrappersSet() - // Get dispute data from contract, and throw if not found. Also get current session and period + // Get dispute data from contract. Also get the current session and period. const [dispute, arbitratorData] = await Promise.all([ this._Arbitrator.getDispute(arbitratorAddress, disputeId), this._Arbitrator.getData(arbitratorAddress, account) ]) - if (!dispute) { - throw new Error( - `Dispute with arbitrator: ${arbitratorAddress} and disputeId: ${disputeId} does not exist` - ) - } // Get arbitrable contract data and evidence const arbitrableContractAddress = dispute.arbitratedContract @@ -802,43 +772,36 @@ class Disputes extends AbstractWrapper { * @returns {int[]} - array of active disputeId */ _getOpenDisputesForSession = async arbitratorAddress => { + const currentSession = (await this._Arbitrator.getData(arbitratorAddress)) + .session const openDisputes = [] - // contract data - const arbitratorData = await this._Arbitrator.getData(arbitratorAddress) - let disputeId = 0 - const currentSession = arbitratorData.session + let disputeId = 0 let dispute while (1) { - // iterate over all disputes (FIXME inefficient) + // Iterate over all the disputes + // TODO: Implement a more performant solution try { - try { - dispute = await this._Arbitrator.getDispute( - arbitratorAddress, - disputeId - ) - // eslint-disable-next-line no-unused-vars - } catch (err) { - // FIXME standardize - throw new Error(errorConstants.TYPE.DISPUTE_OUT_OF_RANGE) - } - - if (dispute.arbitratedContract === ethConstants.NULL_ADDRESS) break - // session + number of appeals - const disputeSession = dispute.firstSession + dispute.numberOfAppeals - // if dispute not in current session skip - if (disputeSession !== currentSession) { - disputeId++ - continue - } - - openDisputes.push(disputeId) - // check next dispute - disputeId += 1 + dispute = await this._Arbitrator.getDispute( + arbitratorAddress, + disputeId + ) } catch (err) { - if (err.message === errorConstants.TYPE.DISPUTE_OUT_OF_RANGE) break + // Dispute out of range, break + if (err.message === errorConstants.UNABLE_TO_FETCH_DISPUTE) break + console.error(err) throw err } + + // Dispute has no arbitrable contract, break + if (dispute.arbitratedContract === ethConstants.NULL_ADDRESS) break + + // If dispute is in the current session, add it to the result array + if (dispute.firstSession + dispute.numberOfAppeals === currentSession) + openDisputes.push(disputeId) + + // Advance to the next dispute + disputeId++ } return openDisputes diff --git a/src/abstractWrappers/Notifications.js b/src/abstractWrappers/Notifications.js index 2ac78e3..62e6167 100644 --- a/src/abstractWrappers/Notifications.js +++ b/src/abstractWrappers/Notifications.js @@ -4,6 +4,7 @@ import * as ethConstants from '../constants/eth' import * as arbitratorConstants from '../constants/arbitrator' import * as notificationConstants from '../constants/notification' import * as disputeConstants from '../constants/dispute' +import * as errorConstants from '../constants/error' import AbstractWrapper from './AbstractWrapper' @@ -310,12 +311,14 @@ class Notifications extends AbstractWrapper { await this._sendPushNotification(callback, notification) } - // check next dispute - disputeId += 1 - // eslint-disable-next-line no-unused-vars + + // Check the next dispute + disputeId++ } catch (err) { - // getDispute(n) throws an error if index out of range - break + // Dispute out of range, break + if (err.message === errorConstants.UNABLE_TO_FETCH_DISPUTE) break + console.error(err) + throw err } } } diff --git a/src/constants/error.js b/src/constants/error.js index ec14891..3a8e704 100644 --- a/src/constants/error.js +++ b/src/constants/error.js @@ -1,3 +1,60 @@ -export const TYPE = { - DISPUTE_OUT_OF_RANGE: 'Dispute out of range' -} +// StoreProviderWrapper +export const PROFILE_NOT_FOUND = user => `No profile found for user: ${user}.` +export const NOTIFICATION_NOT_FOUND = txHash => + `No notification with txHash ${txHash} exists.` + +// ContractWrapper +export const UNABLE_TO_DEPLOY_CONTRACT = + 'Unable to deploy contract, are you sure the contract artifact is correct?' +export const CONTRACT_NOT_DEPLOYED = + 'Unable to load contract. Are you sure the contract is deployed and you are on the right network?' +export const UNABLE_TO_LOAD_CONTRACT = + 'Unable to load contract. Are you sure the contract artifact is correct?' + +// PinakionWrapper +export const UNABLE_TO_SET_KLEROS = 'Unable to set Kleros.' +export const UNABLE_TO_TRANSFER_OWNERSHIP = 'Unable to transfer ownership.' + +// KlerosWrapper +export const UNABLE_TO_BUY_PNK = + 'Unable to buy PNK, are you sure you have enough ETH?' +export const UNABLE_TO_ACTIVATE_PNK = + 'Unable to activate PNK, are you sure you have enough?' +export const UNABLE_TO_FETCH_ARBITRATION_COST = + 'Unable to fetch arbitration cost.' +export const UNABLE_TO_FETCH_TIME_PER_PERIOD = 'Unable to fetch time per period' +export const UNABLE_TO_PASS_PERIOD = 'Unable to pass period.' +export const UNABLE_TO_FETCH_DISPUTE = 'Unable to fetch dispute.' +export const UNABLE_TO_FETCH_AMOUNT_OF_JURORS = + 'Unable to fetch amount of jurors' +export const UNABLE_TO_SUBMIT_VOTES = 'Unable to submit votes.' +export const UNABLE_TO_APPEAL = 'Unable to appeal.' +export const UNABLE_TO_REPARTITION_TOKENS = 'Unable to repartition tokens.' +export const UNABLE_TO_EXECUTE_RULING = 'Unable to execute ruling.' +export const ACCOUNT_NOT_A_JUROR_FOR_CONTRACT = (account, contractAddress) => + `${account} is not a juror for contract ${contractAddress}` +export const PERIOD_OUT_OF_RANGE = periodNumber => + `Period ${periodNumber} does not have a time associated with it.` +export const DISPUTE_DOES_NOT_EXIST = disputeId => + `Dispute ${disputeId} does not exist` + +// ArbitrableTransactionWrapper +export const UNABLE_TO_PAY_ARBITRATION_FEE = + 'Unable to pay fee, are you sure you have enough PNK?' +export const UNABLE_TO_PAY_SELLER = + 'Unable to pay the seller, are you sure you have enough ETH?' +export const UNABLE_TO_CALL_TIMEOUT = 'Unable to call timeout.' +export const CONTRACT_IS_NOT_WAITING_ON_OTHER_PARTY = + 'Unable to call timeout, because the contract is not waiting on the other party.' +export const TIMEOUT_NOT_REACHED = + 'Unable to call timeout, because it has not been reached yet.' + +// AbstractWrapper +export const NO_ARBITRATOR_WRAPPER_SPECIFIED = + 'No Arbitrator Contract Wrapper specified. Please call setArbitrator.' +export const NO_ARBITRABLE_WRAPPER_SPECIFIED = + 'No Arbitrable Contract Wrapper specified. Please call setArbitrable.' + +// Disputes +export const NO_STORE_DATA_FOR_DISPUTE = account => + `Account ${account} does not have store data for dispute` diff --git a/src/contractWrappers/ArbitrableTransactionWrapper.js b/src/contractWrappers/ArbitrableTransactionWrapper.js index ac467fd..c74d7f6 100644 --- a/src/contractWrappers/ArbitrableTransactionWrapper.js +++ b/src/contractWrappers/ArbitrableTransactionWrapper.js @@ -3,6 +3,7 @@ import _ from 'lodash' import * as ethConstants from '../constants/eth' import * as contractConstants from '../constants/contract' +import * as errorConstants from '../constants/error' import ContractWrapper from './ContractWrapper' @@ -61,51 +62,45 @@ class ArbitrableTransactionWrapper extends ContractWrapper { } /** - * Load an existing arbitrableTransaction contract + * Load an existing ArbitrableTransaction contract * @param {string} address Contract address - * @returns {object} contractInstance | Error + * @returns {object} - The contract instance. */ load = async address => { - // return contract instance if already loaded + // Return contract instance if already loaded if (this.contractInstance && this.contractInstance.address === address) return this.contractInstance - try { - const contractInstance = await this._instantiateContractIfExistsAsync( - arbitrableTransaction, - address - ) - - this.contractInstance = contractInstance - this.address = address + this.contractInstance = await this._instantiateContractIfExistsAsync( + arbitrableTransaction, + address + ) + this.address = address - return contractInstance - } catch (err) { - throw new Error(err) - } + return this.contractInstance } /** * Pay the party B. To be called when the good is delivered or the service rendered. * @param {string} account - Ethereum account (default account[0]). * @param {string} contractAddress - The address of the arbitrator contract. - * @returns {string} - txHash hash transaction | Error + * @returns {object} - The result transaction object. */ pay = async ( account = this._Web3Wrapper.getAccount(0), contractAddress // ethereum address of the contract ) => { + await this.load(contractAddress) + try { - this.contractInstance = await this.load(contractAddress) - const txHashObj = await this.contractInstance.pay({ + return this.contractInstance.pay({ from: account, gas: ethConstants.TRANSACTION.GAS, value: 0 }) - - return txHashObj.tx } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_PAY_SELLER) } } @@ -114,23 +109,24 @@ class ArbitrableTransactionWrapper extends ContractWrapper { * @param {string} account - Ethereum account (default account[0]). * @param {string} contractAddress - The address of the arbitrator contract. * @param {number} arbitrationCost - Amount to pay the arbitrator. (default 10000 wei). - * @returns {string} - txHash hash transaction | Error. + * @returns {object} - The result transaction object. */ payArbitrationFeeByPartyA = async ( account = this._Web3Wrapper.getAccount(0), contractAddress, // ethereum address of the contract arbitrationCost = 0.15 ) => { + await this.load(contractAddress) + try { - this.contractInstance = await this.load(contractAddress) - const txHashObj = await this.contractInstance.payArbitrationFeeByPartyA({ + return this.contractInstance.payArbitrationFeeByPartyA({ from: account, gas: ethConstants.TRANSACTION.GAS, value: this._Web3Wrapper.toWei(arbitrationCost, 'ether') }) - return txHashObj.tx } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_PAY_ARBITRATION_FEE) } } @@ -139,24 +135,24 @@ class ArbitrableTransactionWrapper extends ContractWrapper { * @param {string} account Ethereum account (default account[1]). * @param {string} contractAddress - The address of the arbitrator contract. * @param {number} arbitrationCost Amount to pay the arbitrator. (default 10000 wei). - * @returns {string} txHash hash transaction | Error. + * @returns {object} - The result transaction object. */ payArbitrationFeeByPartyB = async ( account = this._Web3Wrapper.getAccount(1), contractAddress, // ethereum address of the contract arbitrationCost = 0.15 ) => { + await this.load(contractAddress) + try { - this.contractInstance = await this.load(contractAddress) - const txHashObj = await this.contractInstance.payArbitrationFeeByPartyB({ + return this.contractInstance.payArbitrationFeeByPartyB({ from: account, gas: ethConstants.TRANSACTION.GAS, value: this._Web3Wrapper.toWei(arbitrationCost, 'ether') }) - - return txHashObj.tx } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_PAY_ARBITRATION_FEE) } } @@ -176,7 +172,8 @@ class ArbitrableTransactionWrapper extends ContractWrapper { description = '', url ) => { - this.contractInstance = await this.load(contractAddress) + await this.load(contractAddress) + const txHashObj = await this.contractInstance.submitEvidence( JSON.stringify(name, description, url), { @@ -193,35 +190,33 @@ class ArbitrableTransactionWrapper extends ContractWrapper { * Call by partyA if partyB is timeout * @param {string} account ETH address of user * @param {string} contractAddress ETH address of contract - * @returns {string} txHash Hash transaction + * @returns {object} The result transaction object. */ callTimeOutPartyA = async ( account = this._Web3Wrapper.getAccount(0), contractAddress ) => { - try { - this.contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const status = (await this.contractInstance.status()).toNumber() - const timeout = (await this.contractInstance.timeout()).toNumber() - const lastInteraction = (await this.contractInstance.lastInteraction()).toNumber() - if (status !== contractConstants.STATUS.WAITING_PARTY_B) { - throw new Error('Status contract is not WAITING_PARTY_B') - } + const status = (await this.contractInstance.status()).toNumber() + const timeout = (await this.contractInstance.timeout()).toNumber() + const lastInteraction = (await this.contractInstance.lastInteraction()).toNumber() - if (Date.now() >= lastInteraction + timeout) { - throw new Error('The timeout is not reached') - } + if (status !== contractConstants.STATUS.WAITING_PARTY_B) { + throw new Error(errorConstants.CONTRACT_IS_NOT_WAITING_ON_OTHER_PARTY) + } else if (Date.now() >= lastInteraction + timeout) { + throw new Error(errorConstants.TIMEOUT_NOT_REACHED) + } - const txHashObj = await this.contractInstance.timeOutByPartyA({ + try { + return this.contractInstance.timeOutByPartyA({ from: account, gas: ethConstants.TRANSACTION.GAS, value: 0 }) - - return txHashObj.tx } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_CALL_TIMEOUT) } } @@ -229,36 +224,33 @@ class ArbitrableTransactionWrapper extends ContractWrapper { * Call by partyB if partyA is timeout. * @param {string} account - ETH address of user. * @param {string} contractAddress - ETH address of contract. - * @returns {string} - txHash Hash transaction. + * @returns {object} The result transaction object. */ callTimeOutPartyB = async ( account = this._Web3Wrapper.getAccount(1), contractAddress ) => { - try { - this.contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const status = await this.contractInstance.status() - const timeout = await this.contractInstance.timeout() - const lastInteraction = await this.contractInstance.lastInteraction() + const status = await this.contractInstance.status() + const timeout = await this.contractInstance.timeout() + const lastInteraction = await this.contractInstance.lastInteraction() - if (status !== contractConstants.STATUS.WAITING_PARTY_A) { - throw new Error('Status contract is not WAITING_PARTY_A') - } - - if (Date.now() >= lastInteraction + timeout) { - throw new Error('The timeout is not reached') - } + if (status !== contractConstants.STATUS.WAITING_PARTY_A) { + throw new Error(errorConstants.CONTRACT_IS_NOT_WAITING_ON_OTHER_PARTY) + } else if (Date.now() >= lastInteraction + timeout) { + throw new Error(errorConstants.TIMEOUT_NOT_REACHED) + } - const txHashObj = await this.contractInstance.timeOutByPartyB({ + try { + return this.contractInstance.timeOutByPartyB({ from: account, gas: ethConstants.TRANSACTION.GAS, value: 0 }) - - return txHashObj.tx } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_CALL_TIMEOUT) } } @@ -275,17 +267,17 @@ class ArbitrableTransactionWrapper extends ContractWrapper { arbitratorAddress, disputeId ) => { - const contractInstance = await this.load(arbitrableContractAddress) + await this.load(arbitrableContractAddress) // fetch dispute resolution options - const statusNumber = (await contractInstance.status()).toNumber() + const statusNumber = (await this.contractInstance.status()).toNumber() // should this just be !== ? if (statusNumber < contractConstants.STATUS.DISPUTE_CREATED) return [] // FIXME we should have a block number to start from so we don't have to rip through the entire chain const disputeEvents = await new Promise((resolve, reject) => { - contractInstance + this.contractInstance .Dispute({}, { fromBlock: 0, toBlock: 'latest' }) .get((error, eventResult) => { if (error) reject(error) @@ -324,7 +316,7 @@ class ArbitrableTransactionWrapper extends ContractWrapper { * @returns {object} Object Data of the contract. */ getData = async address => { - const contractInstance = await this.load(address) + await this.load(address) const [ arbitrator, @@ -340,22 +332,20 @@ class ArbitrableTransactionWrapper extends ContractWrapper { lastInteraction, amount ] = await Promise.all([ - contractInstance.arbitrator(), - contractInstance.arbitratorExtraData(), - // contractInstance.hashContract(), - contractInstance.timeout(), - contractInstance.partyA(), - contractInstance.partyB(), - contractInstance.status(), - contractInstance.arbitratorExtraData(), - contractInstance.disputeID(), - contractInstance.partyAFee(), - contractInstance.partyBFee(), - contractInstance.lastInteraction(), - contractInstance.amount() - ]).catch(err => { - throw new Error(err) - }) + this.contractInstance.arbitrator(), + this.contractInstance.arbitratorExtraData(), + // this.contractInstance.hashContract(), + this.contractInstance.timeout(), + this.contractInstance.partyA(), + this.contractInstance.partyB(), + this.contractInstance.status(), + this.contractInstance.arbitratorExtraData(), + this.contractInstance.disputeID(), + this.contractInstance.partyAFee(), + this.contractInstance.partyBFee(), + this.contractInstance.lastInteraction(), + this.contractInstance.amount() + ]) return { address, diff --git a/src/contractWrappers/BlockHashRNGWrapper.js b/src/contractWrappers/BlockHashRNGWrapper.js index 1b52cbe..8df88fe 100644 --- a/src/contractWrappers/BlockHashRNGWrapper.js +++ b/src/contractWrappers/BlockHashRNGWrapper.js @@ -43,20 +43,15 @@ class BlockHashRNGWrapper extends ContractWrapper { /** * Load an existing contract * @param {string} address - contract address - * @returns {object} - Conract Instance | Error + * @returns {object} - The contract instance. */ load = async address => { - try { - const contractInstance = await this._instantiateContractIfExistsAsync( - RNG, - address - ) - this.contractInstance = contractInstance - this.address = address - return contractInstance - } catch (err) { - throw new Error(err) - } + this.contractInstance = await this._instantiateContractIfExistsAsync( + RNG, + address + ) + this.address = address + return this.contractInstance } } diff --git a/src/contractWrappers/CentralizedArbitratorWrapper.js b/src/contractWrappers/CentralizedArbitratorWrapper.js index 0be2071..791e1a9 100644 --- a/src/contractWrappers/CentralizedArbitratorWrapper.js +++ b/src/contractWrappers/CentralizedArbitratorWrapper.js @@ -50,20 +50,15 @@ class CentralizedArbitratorWrapper extends ContractWrapper { /** * Load an existing contract * @param {string} address - contract address - * @returns {object} - Conract Instance | Error + * @returns {object} - The contract instance. */ load = async address => { - try { - const contractInstance = await this._instantiateContractIfExistsAsync( - centralizedArbitrator, - address - ) - this.contractInstance = contractInstance - this.address = address - return contractInstance - } catch (err) { - throw new Error(err) - } + this.contractInstance = await this._instantiateContractIfExistsAsync( + centralizedArbitrator, + address + ) + this.address = address + return this.contractInstance } } diff --git a/src/contractWrappers/ContractWrapper.js b/src/contractWrappers/ContractWrapper.js index c3a267b..395c8ba 100644 --- a/src/contractWrappers/ContractWrapper.js +++ b/src/contractWrappers/ContractWrapper.js @@ -2,6 +2,7 @@ import contract from 'truffle-contract' import _ from 'lodash' import * as ethConstants from '../constants/eth' +import * as errorConstants from '../constants/error' /** * Contract wrapper @@ -20,16 +21,12 @@ class ContractWrapper { * @private * @param {object} artifact - The contract artifact. * @param {string} address - The hex encoded contract Ethereum address - * @returns {object} - truffle-contract object | Error + * @returns {object} - The contract instance. */ _instantiateContractIfExistsAsync = async (artifact, address) => { - const c = await contract(artifact) - - const providerObj = await this._Web3Wrapper.getProvider() - - await c.setProvider(providerObj) - try { + const c = await contract(artifact) + await c.setProvider(await this._Web3Wrapper.getProvider()) const contractInstance = _.isUndefined(address) ? await c.deployed() : await c.at(address) @@ -42,12 +39,8 @@ class ContractWrapper { // eslint-disable-next-line no-loop-func contractInstance[funcABI.name] = async (...args) => { - try { - await func.estimateGas(...args) // Estimate gas (also checks for possible failures) - return func(...args) // Call original function - } catch (err) { - throw err // TODO: Custom errors - } + await func.estimateGas(...args) // Estimate gas (also checks for possible failures) + return func(...args) // Call original function } // Keep reference to the original function for special cases @@ -60,13 +53,12 @@ class ContractWrapper { return contractInstance } catch (err) { - const errMsg = `${err}` + console.error(err) - if (_.includes(errMsg, 'not been deployed to detected network')) { - throw new Error('ContractDoesNotExist') - } else { - throw new Error('UnhandledError') - } + if (_.includes(err.message, 'not been deployed to detected network')) + throw new Error(errorConstants.CONTRACT_NOT_DEPLOYED) + + throw new Error(errorConstants.UNABLE_TO_LOAD_CONTRACT) } } @@ -79,28 +71,25 @@ class ContractWrapper { * @returns {object} - truffle-contract Object | err The contract object or an error */ _deployAsync = async (account, value, artifact, ...args) => { - if (_.isEmpty(account)) { - account = this._Web3Wrapper.getAccount(0) - } - - const MyContract = contract({ - abi: artifact.abi, - unlinked_binary: artifact.bytecode - ? artifact.bytecode - : artifact.unlinked_binary - }) + if (_.isEmpty(account)) account = this._Web3Wrapper.getAccount(0) - const provider = await this._Web3Wrapper.getProvider() - MyContract.setProvider(provider) try { - let contractDeployed = await MyContract.new(...args, { + const MyContract = contract({ + abi: artifact.abi, + unlinked_binary: artifact.bytecode + ? artifact.bytecode + : artifact.unlinked_binary + }) + MyContract.setProvider(await this._Web3Wrapper.getProvider()) + + return MyContract.new(...args, { from: account, value: value, gas: ethConstants.TRANSACTION.GAS }) - return contractDeployed } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_DEPLOY_CONTRACT) } } diff --git a/src/contractWrappers/KlerosWrapper.js b/src/contractWrappers/KlerosWrapper.js index cf2cf21..4433736 100644 --- a/src/contractWrappers/KlerosWrapper.js +++ b/src/contractWrappers/KlerosWrapper.js @@ -2,6 +2,7 @@ import kleros from 'kleros/build/contracts/KlerosPOC' import _ from 'lodash' import * as ethConstants from '../constants/eth' +import * as errorConstants from '../constants/error' import ContractWrapper from './ContractWrapper' @@ -55,89 +56,87 @@ class KlerosWrapper extends ContractWrapper { /** * Load an existing contract * @param {string} address - contract address - * @returns {object} - Conract Instance | Error + * @returns {object} - The contract instance. */ load = async address => { - // return contract instance if already loaded + // Return contract instance if already loaded if (this.contractInstance && this.contractInstance.address === address) return this.contractInstance - try { - // instantiate new contract instance from address - const contractInstance = await this._instantiateContractIfExistsAsync( - kleros, - address - ) - this.contractInstance = contractInstance - this.address = address - - return contractInstance - } catch (err) { - throw new Error(err) - } + this.contractInstance = await this._instantiateContractIfExistsAsync( + kleros, + address + ) + this.address = address + return this.contractInstance } /** * Use Arbitrator.buyPNK - * @param {string} amount - number of pinakion to buy - * @param {string} contractAddress - address of klerosPOC contract - * @param {string} account - address of user - * @returns {object} - txHash + * @param {string} amount - The number of pinakion to buy. + * @param {string} contractAddress - The address of the KlerosPOC contract. + * @param {string} account - The address of the user. + * @returns {object} - The result transaction object. */ buyPNK = async ( amount, contractAddress, // address of KlerosPOC account = this._Web3Wrapper.getAccount(0) ) => { - this.contractInstance = await this.load(contractAddress) + await this.load(contractAddress) + try { - const txHashObj = await this.contractInstance.buyPinakion({ + return this.contractInstance.buyPinakion({ from: account, gas: ethConstants.TRANSACTION.GAS, value: this._Web3Wrapper.toWei(amount, 'ether') }) - return txHashObj.tx } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_BUY_PNK) } } /** * Get PNK Balances. - * @param {string} contractAddress - address of KlerosPOC contract - * @param {string} account - address of user - * @returns {object} - balance information including total PNK balance and activated tokens + * @param {string} contractAddress - The address of the KlerosPOC contract. + * @param {string} account - The address of the user. + * @returns {object} - Balance information including total PNK balance and activated tokens. */ getPNKBalance = async ( contractAddress, account = this._Web3Wrapper.getAccount(0) ) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const juror = await contractInstance.jurors(account) + const juror = await this.contractInstance.jurors(account) if (!juror) throw new Error( - `${account} is not a juror for contract ${contractAddress}` + errorConstants.ACCOUNT_NOT_A_JUROR_FOR_CONTRACT( + account, + contractAddress + ) ) - // total tokens stored in contract - const contractBalance = this._Web3Wrapper.fromWei(juror[0], 'ether') - // tokens activated in court session - const currentSession = await contractInstance.session() + // Total tokens + const totalTokens = this._Web3Wrapper.fromWei(juror[0], 'ether') + + // Activated Tokens + const currentSession = await this.contractInstance.session() let activatedTokens = 0 - if (juror[2].toNumber() === currentSession.toNumber()) { + if (juror[2].toNumber() === currentSession.toNumber()) activatedTokens = this._Web3Wrapper.fromWei( juror[4].toNumber() - juror[3].toNumber(), 'ether' ) - } - // tokens locked into disputes + + // Locked Tokens const lockedTokens = this._Web3Wrapper.fromWei(juror[1], 'ether') return { + tokenBalance: totalTokens, activatedTokens, - lockedTokens, - tokenBalance: contractBalance + lockedTokens } } @@ -154,7 +153,8 @@ class KlerosWrapper extends ContractWrapper { contractAddress, // klerosPOC contract address account = this._Web3Wrapper.getAccount(0) ) => { - this.contractInstance = await this.load(contractAddress) + await this.load(contractAddress) + try { await this.contractInstance.activateTokens( this._Web3Wrapper.toWei(amount, 'ether'), @@ -164,7 +164,8 @@ class KlerosWrapper extends ContractWrapper { } ) } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_ACTIVATE_PNK) } return this.getPNKBalance(contractAddress, account) @@ -174,19 +175,20 @@ class KlerosWrapper extends ContractWrapper { * Fetch the cost of arbitration * @param {string} contractAddress - address of kleros POC contract. * @param {bytes} contractExtraData - extra data from arbitrable contract. - * @returns {number} - cost of arbitration. + * @returns {number} - The cost of arbitration. */ getArbitrationCost = async (contractAddress, contractExtraData) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) try { - const arbitrationCost = await contractInstance.arbitrationCost( + const arbitrationCost = await this.contractInstance.arbitrationCost( contractExtraData ) return this._Web3Wrapper.fromWei(arbitrationCost, 'ether') } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_FETCH_ARBITRATION_COST) } } @@ -200,14 +202,16 @@ class KlerosWrapper extends ContractWrapper { contractAddress, account = this._Web3Wrapper.getAccount(0) ) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) + try { - await contractInstance.passPeriod.original({ + await this.contractInstance.passPeriod.original({ from: account, gas: ethConstants.TRANSACTION.GAS }) } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_PASS_PERIOD) } return this.getData(contractAddress) @@ -220,7 +224,7 @@ class KlerosWrapper extends ContractWrapper { * @param {number} ruling - int representing the jurors decision. * @param {number[]} votes - int[] of drawn votes for dispute. * @param {string} account - address of user. - * @returns {string} - tx hash. + * @returns {object} - The result transaction object. */ submitVotes = async ( contractAddress, @@ -229,22 +233,16 @@ class KlerosWrapper extends ContractWrapper { votes, account = this._Web3Wrapper.getAccount(0) ) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) try { - const txHashObj = await contractInstance.voteRuling( - disputeId, - ruling, - votes, - { - from: account, - gas: ethConstants.TRANSACTION.GAS - } - ) - - return txHashObj.tx + return this.contractInstance.voteRuling(disputeId, ruling, votes, { + from: account, + gas: ethConstants.TRANSACTION.GAS + }) } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_SUBMIT_VOTES) } } @@ -254,7 +252,7 @@ class KlerosWrapper extends ContractWrapper { * @param {number} disputeId - Index of the dispute. * @param {string} extraData - Extra data. * @param {string} account - Address of user. - * @returns {string} - Tx hash. + * @returns {object} - The result transaction object. */ appealRuling = async ( contractAddress, @@ -262,22 +260,17 @@ class KlerosWrapper extends ContractWrapper { extraData, account = this._Web3Wrapper.getAccount(0) ) => { - const contractInstance = await this.load(contractAddress) - const appealFee = await contractInstance.appealCost(disputeId, extraData) - try { - const appealTxHash = await this.contractInstance.appeal( - disputeId, - extraData, - { - from: account, - value: appealFee, - gas: ethConstants.TRANSACTION.GAS - } - ) + await this.load(contractAddress) - return appealTxHash.tx + try { + return this.contractInstance.appeal(disputeId, extraData, { + from: account, + value: await this.contractInstance.appealCost(disputeId, extraData), + gas: ethConstants.TRANSACTION.GAS + }) } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_APPEAL) } } @@ -286,27 +279,23 @@ class KlerosWrapper extends ContractWrapper { * @param {string} contractAddress - address of KlerosPOC contract. * @param {number} disputeId - index of the dispute. * @param {string} account - address of user. - * @returns {string} - tx hash. + * @returns {object} - The result transaction object. */ repartitionJurorTokens = async ( contractAddress, disputeId, account = this._Web3Wrapper.getAccount(0) ) => { - const contractInstance = await this.load(contractAddress) - try { - // partition tokens - const repartitionTxHash = await contractInstance.oneShotTokenRepartition( - disputeId, - { - from: account, - gas: ethConstants.TRANSACTION.GAS - } - ) + await this.load(contractAddress) - return repartitionTxHash.tx + try { + return this.contractInstance.oneShotTokenRepartition(disputeId, { + from: account, + gas: ethConstants.TRANSACTION.GAS + }) } catch (err) { - throw err + console.error(err) + throw new Error(errorConstants.UNABLE_TO_REPARTITION_TOKENS) } } @@ -315,27 +304,23 @@ class KlerosWrapper extends ContractWrapper { * @param {string} contractAddress - address of KlerosPOC contract. * @param {number} disputeId - index of the dispute. * @param {string} account - address of user. - * @returns {string} - tx hash. + * @returns {object} - The result transaction object. */ executeRuling = async ( contractAddress, disputeId, account = this._Web3Wrapper.getAccount(0) ) => { - this.contractInstance = await this.load(contractAddress) - try { - // execute ruling - const executeTxHash = await this.contractInstance.executeRuling( - disputeId, - { - from: account, - gas: ethConstants.TRANSACTION.GAS - } - ) + await this.load(contractAddress) - return executeTxHash.tx + try { + return this.contractInstance.executeRuling(disputeId, { + from: account, + gas: ethConstants.TRANSACTION.GAS + }) } catch (err) { - throw err + console.error(err) + throw new Error(errorConstants.UNABLE_TO_EXECUTE_RULING) } } @@ -343,32 +328,35 @@ class KlerosWrapper extends ContractWrapper { * Get time for a period. * @param {string} contractAddress - address of KlerosPOC contract. * @param {number} periodNumber - int representing period. - * @returns {number} - seconds in the period. + * @returns {number} - The seconds in the period. */ getTimeForPeriod = async (contractAddress, periodNumber) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const timePerPeriod = await contractInstance.timePerPeriod(periodNumber) - - if (timePerPeriod) { - return timePerPeriod.toNumber() - } else { - throw new Error( - `Period ${periodNumber} does not have a time associated with it. periodNumber out of range` - ) + let timePerPeriod + try { + timePerPeriod = await this.contractInstance.timePerPeriod(periodNumber) + } catch (err) { + console.error(err) + throw new Error(errorConstants.UNABLE_TO_FETCH_TIME_PER_PERIOD) } + + if (timePerPeriod) return timePerPeriod.toNumber() + + throw new Error(errorConstants.PERIOD_OUT_OF_RANGE(periodNumber)) } /** * Get dispute. - * @param {string} contractAddress - Address of KlerosPOC contract. - * @param {number} disputeId - Index of dispute. - * @returns {object} - dispute data from contract. + * @param {string} contractAddress - The address of the KlerosPOC contract. + * @param {number} disputeId - The index of the dispute. + * @returns {object} - The dispute data from the contract. */ getDispute = async (contractAddress, disputeId) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) + try { - const dispute = await contractInstance.disputes(disputeId) + const dispute = await this.contractInstance.disputes(disputeId) const numberOfAppeals = dispute[2].toNumber() const rulingChoices = dispute[3].toNumber() @@ -378,7 +366,7 @@ class KlerosWrapper extends ContractWrapper { const voteCounts = [] for (let choice = 0; choice <= rulingChoices; choice++) voteCounts.push( - contractInstance + this.contractInstance .getVoteCount(disputeId, appeal, choice) .then(v => v.toNumber()) ) @@ -387,7 +375,7 @@ class KlerosWrapper extends ContractWrapper { ;[voteCounters, status] = await Promise.all([ Promise.all(voteCounters.map(voteCounts => Promise.all(voteCounts))), - contractInstance.disputeStatus(disputeId) + this.contractInstance.disputeStatus(disputeId) ]) return { @@ -402,7 +390,8 @@ class KlerosWrapper extends ContractWrapper { status: status.toNumber() } } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_FETCH_DISPUTE) } } @@ -413,15 +402,19 @@ class KlerosWrapper extends ContractWrapper { * @returns {number} - Number of jurors for a dispute. */ getAmountOfJurorsForDispute = async (contractAddress, disputeId) => { - const contractInstance = await this.load(contractAddress) - - const amountOfJurors = await contractInstance.amountJurors(disputeId) + await this.load(contractAddress) - if (amountOfJurors) { - return amountOfJurors.toNumber() - } else { - throw new Error(`Dispute ${disputeId} does not exist`) + let amountOfJurors + try { + amountOfJurors = await this.contractInstance.amountJurors(disputeId) + } catch (err) { + console.error(err) + throw new Error(errorConstants.UNABLE_TO_FETCH_AMOUNT_OF_JURORS) } + + if (amountOfJurors) return amountOfJurors.toNumber() + + throw new Error(errorConstants.DISPUTE_DOES_NOT_EXIST) } /** @@ -438,9 +431,9 @@ class KlerosWrapper extends ContractWrapper { contractAddress, jurorAddress = this._Web3Wrapper.getAccount(0) ) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const isDrawn = await contractInstance.isDrawn( + const isDrawn = await this.contractInstance.isDrawn( disputeId, jurorAddress, draw @@ -458,14 +451,14 @@ class KlerosWrapper extends ContractWrapper { * @returns {bool} - Boolean indicating if juror can rule or not. */ canRuleDispute = async (arbitratorAddress, disputeId, draws, account) => { - const contractInstance = await this.load(arbitratorAddress) + await this.load(arbitratorAddress) - const validDraws = await contractInstance.validDraws( + const validDraws = await this.contractInstance.validDraws( account, disputeId, draws ) - const lastRuling = (await contractInstance.getLastSessionVote( + const lastRuling = (await this.contractInstance.getLastSessionVote( disputeId, account )).toNumber() @@ -482,9 +475,12 @@ class KlerosWrapper extends ContractWrapper { * @returns {number} - Int indicating the ruling of the dispute. */ currentRulingForDispute = async (contractAddress, disputeId, appeal) => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const ruling = await contractInstance.getWinningChoice(disputeId, appeal) + const ruling = await this.contractInstance.getWinningChoice( + disputeId, + appeal + ) return ruling.toNumber() } @@ -495,9 +491,9 @@ class KlerosWrapper extends ContractWrapper { * @returns {number} - Int indicating the period. */ getPeriod = async contractAddress => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const currentPeriod = await contractInstance.period() + const currentPeriod = await this.contractInstance.period() return currentPeriod.toNumber() } @@ -508,9 +504,9 @@ class KlerosWrapper extends ContractWrapper { * @returns {number} - Int indicating the session. */ getSession = async contractAddress => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) - const currentSession = await contractInstance.session() + const currentSession = await this.contractInstance.session() return currentSession.toNumber() } @@ -523,7 +519,7 @@ class KlerosWrapper extends ContractWrapper { * @returns {object} - Data for kleros POC from contract. */ getData = async contractAddress => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) const [ pinakionContractAddress, @@ -532,14 +528,12 @@ class KlerosWrapper extends ContractWrapper { session, lastPeriodChange ] = await Promise.all([ - contractInstance.pinakion(), - contractInstance.rng(), - contractInstance.period(), - contractInstance.session(), - contractInstance.lastPeriodChange() - ]).catch(err => { - throw new Error(err) - }) + this.contractInstance.pinakion(), + this.contractInstance.rng(), + this.contractInstance.period(), + this.contractInstance.session(), + this.contractInstance.lastPeriodChange() + ]) return { pinakionContractAddress, diff --git a/src/contractWrappers/PinakionWrapper.js b/src/contractWrappers/PinakionWrapper.js index 6651bfe..c7b2b5d 100644 --- a/src/contractWrappers/PinakionWrapper.js +++ b/src/contractWrappers/PinakionWrapper.js @@ -2,6 +2,7 @@ import PinakionPOC from 'kleros/build/contracts/PinakionPOC' // FIXME: mock import _ from 'lodash' import * as ethConstants from '../constants/eth' +import * as errorConstants from '../constants/error' import ContractWrapper from './ContractWrapper' @@ -45,18 +46,12 @@ class PinakionWrapper extends ContractWrapper { * @returns {object} - Contract Instance | Error. */ load = async address => { - try { - const contractInstance = await this._instantiateContractIfExistsAsync( - PinakionPOC, - address - ) - this.contractInstance = contractInstance - this.address = address - - return contractInstance - } catch (err) { - throw new Error(err) - } + this.contractInstance = await this._instantiateContractIfExistsAsync( + PinakionPOC, + address + ) + this.address = address + return this.contractInstance } /** @@ -64,23 +59,23 @@ class PinakionWrapper extends ContractWrapper { * @param {string} contractAddress - Address of PNK contract. * @param {string} klerosAddress - Address of Kleros POC contract. * @param {string} account - Address of user. - * @returns {string} - Tx hash. + * @returns {object} - The result transaction object. */ setKleros = async ( contractAddress, klerosAddress, account = this._Web3Wrapper.getAccount(0) ) => { + await this.load(contractAddress) + try { - let contractInstance = await this.load(contractAddress) - const txHashObj = await contractInstance.setKleros(klerosAddress, { + return this.contractInstance.setKleros(klerosAddress, { from: account, gas: ethConstants.TRANSACTION.GAS }) - - return txHashObj.tx } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_SET_KLEROS) } } @@ -89,26 +84,23 @@ class PinakionWrapper extends ContractWrapper { * @param {string} contractAddress - Address of PNK contract. * @param {string} klerosAddress - Address of Kleros POC contract. * @param {string} account - Address of user. - * @returns {string} - Tx hash. + * @returns {object} - The result transaction object. */ transferOwnership = async ( contractAddress, klerosAddress, account = this._Web3Wrapper.getAccount(0) ) => { - try { - const contractInstance = await this.load(contractAddress) - const txHashObj = await contractInstance.transferOwnership( - klerosAddress, - { - from: account, - gas: ethConstants.TRANSACTION.GAS - } - ) + await this.load(contractAddress) - return txHashObj.tx + try { + return this.contractInstance.transferOwnership(klerosAddress, { + from: account, + gas: ethConstants.TRANSACTION.GAS + }) } catch (err) { - throw new Error(err) + console.error(err) + throw new Error(errorConstants.UNABLE_TO_TRANSFER_OWNERSHIP) } } @@ -119,14 +111,12 @@ class PinakionWrapper extends ContractWrapper { * @returns {object} - Data from PNK contract. */ getData = async contractAddress => { - const contractInstance = await this.load(contractAddress) + await this.load(contractAddress) const [owner, kleros] = await Promise.all([ - contractInstance.owner(), - contractInstance.kleros() - ]).catch(err => { - throw new Error(err) - }) + this.contractInstance.owner(), + this.contractInstance.kleros() + ]) return { owner, diff --git a/src/utils/StoreProviderWrapper.js b/src/utils/StoreProviderWrapper.js index 5e30d83..0bbf65e 100644 --- a/src/utils/StoreProviderWrapper.js +++ b/src/utils/StoreProviderWrapper.js @@ -1,5 +1,7 @@ import _ from 'lodash' +import * as errorConstants from '../constants/error' + import PromiseQueue from './PromiseQueue' class StoreProviderWrapper { @@ -75,7 +77,7 @@ class StoreProviderWrapper { getDisputeData = async (arbitratorAddress, disputeId, userAddress) => { const userProfile = await this.getUserProfile(userAddress) if (!userProfile) - throw new Error(`No profile found for address: ${userAddress}`) + throw new Error(errorConstants.PROFILE_NOT_FOUND(userAddress)) let disputeData = _.filter( userProfile.disputes, @@ -93,7 +95,7 @@ class StoreProviderWrapper { getContractByHash = async (userAddress, hash) => { const userProfile = await this.getUserProfile(userAddress) if (!userProfile) - throw new Error(`No profile found for address: ${userAddress}`) + throw new Error(errorConstants.PROFILE_NOT_FOUND(userAddress)) let contractData = _.filter(userProfile.contracts, o => o.hash === hash) @@ -104,7 +106,7 @@ class StoreProviderWrapper { getContractByAddress = async (userAddress, addressContract) => { const userProfile = await this.getUserProfile(userAddress) if (!userProfile) - throw new Error(`No profile found for this address: ${userAddress}`) + throw new Error(errorConstants.PROFILE_NOT_FOUND(userAddress)) let contract = _.filter( userProfile.contracts, @@ -344,9 +346,8 @@ class StoreProviderWrapper { notification.txHash === txHash && notification.logIndex === logIndex ) - if (_.isNull(notificationIndex)) { - throw new TypeError(`No notification with txHash ${txHash} exists`) - } + if (_.isNull(notificationIndex)) + throw new Error(errorConstants.NOTIFICATION_NOT_FOUND(txHash)) userProfile.notifications[notificationIndex].read = isRead delete userProfile._id diff --git a/tests/integration/contracts.test.js b/tests/integration/contracts.test.js index 72b985d..50c8aae 100644 --- a/tests/integration/contracts.test.js +++ b/tests/integration/contracts.test.js @@ -204,7 +204,7 @@ describe('Contracts', () => { ) // raise dispute party A - const txHashRaiseDisputeByPartyA = await KlerosInstance.disputes.raiseDisputePartyA( + const raiseDisputeByPartyATxObj = await KlerosInstance.disputes.raiseDisputePartyA( partyA, arbitrableContractAddress, arbitrationCost - @@ -213,7 +213,7 @@ describe('Contracts', () => { 'ether' ) ) - expect(txHashRaiseDisputeByPartyA).toEqual( + expect(raiseDisputeByPartyATxObj.tx).toEqual( expect.stringMatching(/^0x[a-f0-9]{64}$/) ) // tx hash diff --git a/tests/integration/disputeResolution.test.js b/tests/integration/disputeResolution.test.js index 295041c..0d0e5f1 100644 --- a/tests/integration/disputeResolution.test.js +++ b/tests/integration/disputeResolution.test.js @@ -153,7 +153,7 @@ describe('Dispute Resolution', () => { ) // raise dispute party A - const txHashRaiseDisputeByPartyA = await KlerosInstance.disputes.raiseDisputePartyA( + const raiseDisputeByPartyATxObj = await KlerosInstance.disputes.raiseDisputePartyA( partyA, arbitrableContractAddress, arbitrationCost - @@ -162,7 +162,7 @@ describe('Dispute Resolution', () => { 'ether' ) ) - expect(txHashRaiseDisputeByPartyA).toEqual( + expect(raiseDisputeByPartyATxObj.tx).toEqual( expect.stringMatching(/^0x[a-f0-9]{64}$/) ) // tx hash @@ -170,7 +170,7 @@ describe('Dispute Resolution', () => { // FIXME use arbitrableTransaction const partyBFeeContractInstance = await arbitrableContractInstance.partyBFee() - const txHashRaiseDisputeByPartyB = await KlerosInstance.disputes.raiseDisputePartyB( + const raiseDisputeByPartyBTxObj = await KlerosInstance.disputes.raiseDisputePartyB( partyB, arbitrableContractAddress, arbitrationCost - @@ -179,7 +179,7 @@ describe('Dispute Resolution', () => { 'ether' ) ) - expect(txHashRaiseDisputeByPartyB).toEqual( + expect(raiseDisputeByPartyBTxObj.tx).toEqual( expect.stringMatching(/^0x[a-f0-9]{64}$/) ) // tx hash const dispute = await KlerosInstance.klerosPOC.getDispute( @@ -261,6 +261,7 @@ describe('Dispute Resolution', () => { klerosPOCAddress, other ) + console.info(newState) expect(newState.period).toEqual(i) } let drawA = [] diff --git a/tests/unit/abstractWrappers/Disputes.test.js b/tests/unit/abstractWrappers/Disputes.test.js index 79328d4..611d469 100644 --- a/tests/unit/abstractWrappers/Disputes.test.js +++ b/tests/unit/abstractWrappers/Disputes.test.js @@ -1,5 +1,6 @@ import DisputesApi from '../../../src/abstractWrappers/Disputes' import * as arbitratorConstants from '../../../src/constants/arbitrator' +import * as errorConstants from '../../../src/constants/error' describe('Disputes', () => { let mockArbitratorWrapper = {} @@ -59,7 +60,7 @@ describe('Disputes', () => { if (fakeDisputes[disputeID]) { return fakeDisputes[disputeID] } else { - throw new Error('no dispute') + throw new Error(errorConstants.UNABLE_TO_FETCH_DISPUTE) } } @@ -107,7 +108,7 @@ describe('Disputes', () => { if (fakeDisputes[disputeID]) { return fakeDisputes[disputeID] } else { - throw new Error('no dispute') + throw new Error(errorConstants.UNABLE_TO_FETCH_DISPUTE) } } @@ -155,7 +156,7 @@ describe('Disputes', () => { if (fakeDisputes[disputeID]) { return fakeDisputes[disputeID] } else { - throw new Error('no dispute') + throw new Error(errorConstants.UNABLE_TO_FETCH_DISPUTE) } } @@ -203,7 +204,7 @@ describe('Disputes', () => { if (fakeDisputes[disputeID]) { return fakeDisputes[disputeID] } else { - throw new Error('no dispute') + throw new Error(errorConstants.UNABLE_TO_FETCH_DISPUTE) } }