From 2f2c0e408e5ba5c30f05557861642f3e8abc9384 Mon Sep 17 00:00:00 2001 From: Sam Vitello Date: Thu, 6 Sep 2018 12:04:49 -0600 Subject: [PATCH] feat: convert balance units --- package.json | 2 +- src/actions/arbitrator.js | 23 ++++---- .../dispute/components/details/index.js | 3 +- .../dispute/components/ruling/index.js | 7 ++- src/containers/dispute/index.js | 14 ++--- .../components/case-name-cell/index.js | 10 ++-- .../components/disputes-table/index.js | 6 +- src/containers/disputes/index.js | 4 +- src/containers/home/index.js | 50 ++++++++++------ src/containers/tokens/index.js | 58 ++++++++++++++----- src/reducers/arbitrator.js | 8 +-- src/reducers/dispute.js | 4 +- src/reducers/notification.js | 2 +- src/sagas/arbitrator.js | 1 - src/sagas/dispute.js | 15 ++--- src/utils/number.js | 24 ++++++++ 16 files changed, 146 insertions(+), 85 deletions(-) diff --git a/package.json b/package.json index 6204e5c..30a2b4a 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "create-redux-form": "^0.1.2", "ethjs": "^0.3.3", "history": "^4.7.2", - "kleros-api": "^0.16.0", + "kleros-api": "^0.17.0", "lessdux": "^0.7.3", "normalize.css": "^7.0.0", "react": "^16.2.0", diff --git a/src/actions/arbitrator.js b/src/actions/arbitrator.js index 9ad1aa5..8090d10 100644 --- a/src/actions/arbitrator.js +++ b/src/actions/arbitrator.js @@ -21,25 +21,22 @@ export const arbitratorData = { // PNK Balance export const fetchPNKBalance = () => ({ type: PNKBalance.FETCH }) -export const buyPNK = formData => ({ +export const buyPNK = amount => ({ type: PNKBalance.BUY, - payload: { amount: formData.amount } + payload: { amount } }) -export const activatePNK = formData => ({ +export const activatePNK = amount => ({ type: PNKBalance.ACTIVATE, - payload: { amount: formData.amount } + payload: { amount } }) -export const transferPNK = formData => ({ +export const transferPNK = amount => ({ type: PNKBalance.TRANSFER, - payload: { amount: formData.amount } + payload: { amount } +}) +export const withdrawPNK = amount => ({ + type: PNKBalance.WITHDRAW, + payload: { amount } }) -export const withdrawPNK = formData => { - console.log(1) - return { - type: PNKBalance.WITHDRAW, - payload: { amount: formData.amount } - } -} // Arbitrator Data export const fetchArbitratorData = () => ({ type: arbitratorData.FETCH }) diff --git a/src/containers/dispute/components/details/index.js b/src/containers/dispute/components/details/index.js index 8e5ee88..b03ce23 100644 --- a/src/containers/dispute/components/details/index.js +++ b/src/containers/dispute/components/details/index.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types' import { ChainData } from '../../../../chainstrap' import { ARBITRATOR_ADDRESS } from '../../../../bootstrap/dapp-api' import { dateToString } from '../../../../utils/date' +import { weiBNToDecimalString } from '../../../../utils/number' import LabelValueGroup from '../../../../components/label-value-group' import TruncatableTextBox from '../../../../components/truncatable-text-box' import * as chainViewConstants from '../../../../constants/chain-view' @@ -120,7 +121,7 @@ class Details extends Component { parameters={chainViewConstants.KLEROS_POC_DISPUTES_PARAMS( disputeID )} - >{`${arbitrationFee} ETH`} + >{`${weiBNToDecimalString(arbitrationFee)} ETH`} ) } ])} diff --git a/src/containers/dispute/components/ruling/index.js b/src/containers/dispute/components/ruling/index.js index ec00205..9e675d6 100644 --- a/src/containers/dispute/components/ruling/index.js +++ b/src/containers/dispute/components/ruling/index.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types' import { ChainData } from '../../../../chainstrap' import { ARBITRATOR_ADDRESS } from '../../../../bootstrap/dapp-api' import { dateToString } from '../../../../utils/date' +import { weiBNToDecimalString } from '../../../../utils/number' import LabelValueGroup from '../../../../components/label-value-group' import * as chainViewConstants from '../../../../constants/chain-view' @@ -57,7 +58,9 @@ const Ruling = ({
{won ? 'Received ' : 'Lost '}
-

{netPNK} PNK

+

+ {weiBNToDecimalString(netPNK)} PNK +

)} @@ -113,7 +116,7 @@ const Ruling = ({ }`} > {won ? '+' : '-'} - {netPNK} + {weiBNToDecimalString(netPNK)} ) } diff --git a/src/containers/dispute/index.js b/src/containers/dispute/index.js index 579e77b..5d3a124 100644 --- a/src/containers/dispute/index.js +++ b/src/containers/dispute/index.js @@ -52,7 +52,7 @@ class Dispute extends PureComponent { handleVoteButtonClick = ({ currentTarget: { id } }) => { const { dispute, voteOnDispute } = this.props voteOnDispute( - dispute.data.disputeId, + dispute.data.disputeID, dispute.data.appealJuror[dispute.data.latestAppealForJuror].draws, id ) @@ -60,12 +60,12 @@ class Dispute extends PureComponent { handleRepartitionButtonClick = () => { const { dispute, repartitionTokens } = this.props - repartitionTokens(dispute.data.disputeId) + repartitionTokens(dispute.data.disputeID) } handleExecuteButtonClick = () => { const { dispute, executeRuling } = this.props - executeRuling(dispute.data.disputeId) + executeRuling(dispute.data.disputeID) } render() { @@ -97,7 +97,7 @@ class Dispute extends PureComponent {

Decision Summary for " {dispute.data.metaEvidence.title} - ", Case #{dispute.data.disputeId} + ", Case #{dispute.data.disputeID}


@@ -114,7 +114,7 @@ class Dispute extends PureComponent { arbitrableContractAddress={ dispute.data.arbitrableContractAddress } - disputeID={dispute.data.disputeId} + disputeID={dispute.data.disputeID} metaEvidence={dispute.data.metaEvidence} /> ) @@ -132,7 +132,7 @@ class Dispute extends PureComponent { arbitrableContractAddress={ dispute.data.arbitrableContractAddress } - disputeID={dispute.data.disputeId} + disputeID={dispute.data.disputeID} appealNumber={e.appealNumber} metaEvidence={dispute.data.metaEvidence} /> @@ -170,7 +170,7 @@ class Dispute extends PureComponent { dispute.data.appealJuror[e.appealNumber] .jurorRuling } - disputeID={dispute.data.disputeId} + disputeID={dispute.data.disputeID} appeals={dispute.data.numberOfAppeals} appealNumber={e.appealNumber} metaEvidence={dispute.data.metaEvidence} diff --git a/src/containers/disputes/components/case-name-cell/index.js b/src/containers/disputes/components/case-name-cell/index.js index b5bb467..1530991 100644 --- a/src/containers/disputes/components/case-name-cell/index.js +++ b/src/containers/disputes/components/case-name-cell/index.js @@ -10,11 +10,11 @@ import * as chainViewConstants from '../../../../constants/chain-view' import './case-name-cell.css' const CaseNameCell = ({ - original: { disputeId, arbitrableContractAddress, title } + original: { disputeID, arbitrableContractAddress, title } }) => (
- +
{title}
@@ -23,11 +23,11 @@ const CaseNameCell = ({ contractAddress={ARBITRATOR_ADDRESS} functionSignature={chainViewConstants.KLEROS_POC_DISPUTES_SIG} parameters={chainViewConstants.KLEROS_POC_DISPUTES_PARAMS( - disputeId + disputeID )} style={{ display: 'block', height: '100%', width: '100%' }} > - Case #{disputeId} + Case #{disputeID}
@@ -37,7 +37,7 @@ const CaseNameCell = ({ CaseNameCell.propTypes = { original: PropTypes.shape({ - disputeId: PropTypes.string.isRequired, + disputeID: PropTypes.string.isRequired, arbitrableContractAddress: PropTypes.string.isRequired, title: PropTypes.string.isRequired }).isRequired diff --git a/src/containers/disputes/components/disputes-table/index.js b/src/containers/disputes/components/disputes-table/index.js index b831539..fb3845b 100644 --- a/src/containers/disputes/components/disputes-table/index.js +++ b/src/containers/disputes/components/disputes-table/index.js @@ -9,8 +9,8 @@ import CaseNameCell from '../case-name-cell' const columns = [ { show: false, - accessor: 'disputeId', - id: 'disputeId' + accessor: 'disputeID', + id: 'disputeID' }, { Header: 'Case Name', @@ -50,7 +50,7 @@ const DisputesTable = ({ disputes }) => ( desc: false }, { - id: 'disputeId', + id: 'disputeID', desc: true } ]} diff --git a/src/containers/disputes/index.js b/src/containers/disputes/index.js index c16f9a0..8b76ce0 100644 --- a/src/containers/disputes/index.js +++ b/src/containers/disputes/index.js @@ -25,8 +25,8 @@ class Disputes extends PureComponent { } componentDidMount() { - const { fetchDisputes } = this.props - fetchDisputes() + const { fetchDisputes, disputes } = this.props + if (disputes && !disputes.data) fetchDisputes() } componentDidUpdate() { diff --git a/src/containers/home/index.js b/src/containers/home/index.js index bd5154f..06aeb16 100644 --- a/src/containers/home/index.js +++ b/src/containers/home/index.js @@ -20,6 +20,7 @@ import NotificationCard from '../../components/notification-card' import DisputeCard from '../../components/dispute-card' import Slider from '../../components/slider' import { dateToString } from '../../utils/date' +import { weiBNToDecimalString, decimalStringToWeiBN } from '../../utils/number' import { camelToTitleCase } from '../../utils/string' import * as arbitratorConstants from '../../constants/arbitrator' import * as chainViewConstants from '../../constants/chain-view' @@ -94,8 +95,9 @@ class Home extends PureComponent { handleActivatePNKFormSubmit = formData => { const { activatePNK } = this.props + const { amount } = formData toastr.removeByType('message') - activatePNK(formData) + activatePNK(decimalStringToWeiBN(amount).toString()) } handleActivatePNKFormButtonClick = () => { @@ -109,10 +111,14 @@ class Home extends PureComponent { validateActivatePNKForm = values => { const { arbitratorData } = this.props const errors = {} - if (arbitratorData.data.minActivatedToken > values.amount) - errors.amount = `You must deposit a minimum of ${ + if ( + arbitratorData.data.minActivatedToken.greaterThan( + decimalStringToWeiBN(values.amount, 'ether') + ) + ) + errors.amount = `You must deposit a minimum of ${decimalStringToWeiBN( arbitratorData.data.minActivatedToken - } PNK.` + ).toString()} PNK.` return errors } @@ -126,7 +132,12 @@ class Home extends PureComponent {
- Activated PNK: {PNKBalance.data.activatedTokens} + Activated PNK:{' '} + {weiBNToDecimalString(PNKBalance.data.activatedTokens)}
- Locked PNK: {PNKBalance.data.lockedTokens} + Locked PNK:{' '} + {weiBNToDecimalString(PNKBalance.data.lockedTokens)}
Session: diff --git a/src/reducers/arbitrator.js b/src/reducers/arbitrator.js index 4a73656..65fb841 100644 --- a/src/reducers/arbitrator.js +++ b/src/reducers/arbitrator.js @@ -7,9 +7,9 @@ const { initialState: PNKBalanceInitialState } = createResource( PropTypes.shape({ - tokenBalance: PropTypes.number.isRequired, - activatedTokens: PropTypes.number.isRequired, - lockedTokens: PropTypes.number.isRequired + tokenBalance: PropTypes.object.isRequired, + activatedTokens: PropTypes.object.isRequired, + lockedTokens: PropTypes.object.isRequired }), { withUpdate: true } ) @@ -24,7 +24,7 @@ const { period: PropTypes.number.isRequired, lastPeriodChange: PropTypes.number.isRequired, timePerPeriod: PropTypes.arrayOf(PropTypes.number.isRequired).isRequired, - minActivatedToken: PropTypes.number.isRequired + minActivatedToken: PropTypes.object.isRequired }), { withUpdate: true } ) diff --git a/src/reducers/dispute.js b/src/reducers/dispute.js index 878018e..536993e 100644 --- a/src/reducers/dispute.js +++ b/src/reducers/dispute.js @@ -11,7 +11,7 @@ const { arbitrableContractAddress: PropTypes.string.isRequired, arbitratorAddress: PropTypes.string.isRequired, arbitrationFeePerJuror: PropTypes.number.isRequired, - disputeId: PropTypes.number.isRequired, + disputeID: PropTypes.number.isRequired, firstSession: PropTypes.number.isRequired, initialNumberJurors: PropTypes.number.isRequired, numberOfAppeals: PropTypes.number.isRequired, @@ -39,7 +39,7 @@ const { partyB: PropTypes.string.isRequired, // Dispute Data - disputeId: PropTypes.number.isRequired, + disputeID: PropTypes.number.isRequired, firstSession: PropTypes.number.isRequired, lastSession: PropTypes.number.isRequired, numberOfAppeals: PropTypes.number.isRequired, diff --git a/src/reducers/notification.js b/src/reducers/notification.js index 9bb1cfd..f8d4f1e 100644 --- a/src/reducers/notification.js +++ b/src/reducers/notification.js @@ -9,7 +9,7 @@ export const _notificationShape = PropTypes.shape({ message: PropTypes.string.isRequired, data: PropTypes.shape({ // TODO - disputeId: PropTypes.number, + disputeID: PropTypes.number, arbitratorAddress: PropTypes.string }).isRequired, _id: PropTypes.string.isRequired, diff --git a/src/sagas/arbitrator.js b/src/sagas/arbitrator.js index ec31029..3eb40a5 100644 --- a/src/sagas/arbitrator.js +++ b/src/sagas/arbitrator.js @@ -44,7 +44,6 @@ function* transferPNK({ payload: { amount } }) { * @returns {object} - The update PNK balance. */ function* withdrawPNK({ payload: { amount } }) { - console.log(amount) return yield call( kleros.arbitrator.withdrawPNK, amount, diff --git a/src/sagas/dispute.js b/src/sagas/dispute.js index 85aeed0..81d1200 100644 --- a/src/sagas/dispute.js +++ b/src/sagas/dispute.js @@ -87,16 +87,13 @@ const parseDispute = d => { */ function* fetchDisputes() { const account = yield select(walletSelectors.getAccount) - const [_disputes, arbitratorData] = yield all([ call(kleros.arbitrator.getDisputesForUser, account), call(fetchArbitratorData) ]) - yield put( action(arbitratorActions.arbitratorData.RECEIVE, { arbitratorData }) ) - const disputes = [] for (const d of _disputes) if (d.arbitrableContractAddress && d.arbitrableContractAddress !== '0x') { @@ -105,16 +102,12 @@ function* fetchDisputes() { d.arbitrableContractAddress ) - const arbitrableData = yield call(kleros.arbitrable.getContractData) + const metaEvidence = yield call(kleros.arbitrable.getMetaEvidence) disputes.push({ ...d, - title: arbitrableData.metaEvidence - ? arbitrableData.metaEvidence.title - : null, - description: arbitrableData.metaEvidence - ? arbitrableData.metaEvidence.description - : null + title: metaEvidence ? metaEvidence.title : null, + description: metaEvidence ? metaEvidence.description : null }) } else disputes.push(d) @@ -130,7 +123,7 @@ function* fetchDisputeDeadlines({ payload: { _disputes } }) { _disputes.map(dispute => call( kleros.disputes.getDisputeDeadline, - dispute.disputeId, + dispute.disputeID, dispute.numberOfAppeals ) ) diff --git a/src/utils/number.js b/src/utils/number.js index 2c79db8..4931f13 100644 --- a/src/utils/number.js +++ b/src/utils/number.js @@ -1,3 +1,4 @@ +import Eth from 'ethjs' /** * Stringifies a number into the preffered Kleros percentage format. * @param {number} n - The number. @@ -6,3 +7,26 @@ export function numberToPercentage(n) { return `${(n * 100).toFixed(2)}%` } + +/** + * Convert a Big Number object of an amount in WEI to a decimal string. + * NOTE: Should never use decimal numbers (toNumber) as precession can be lost. + * For all mathematical opperations convert back to a BN object. Decimal strings + * are only used for display. + * @param {object} bn - The Big Number object. + * @returns {string} The amount represented as a decimal string + */ +export function weiBNToDecimalString(bn) { + // WARNING web3 and ethjs use different BN libraries. + return Eth.fromWei(bn, 'ether').toString() +} + +/** + * Converts a decimal string to a Big Number object. + * @param {string} amount - The amount represented by a decimal string. + * @returns {object} The Big Number object of the amount + */ +export function decimalStringToWeiBN(amount) { + if (amount === '') return Eth.toBN(0) // to avoid errors on inputs return BN(0) for empty string + return Eth.toWei(amount, 'ether') +}