diff --git a/package.json b/package.json index 9ace489bcb3f..4b2b5c0525d8 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,10 @@ "packages/*" ], "resolutions": { - "@polkadot/api": "^0.97.0-beta.39", - "@polkadot/api-contract": "^0.97.0-beta.39", + "@polkadot/api": "^0.97.0-beta.40", + "@polkadot/api-contract": "^0.97.0-beta.40", "@polkadot/keyring": "^1.7.1", - "@polkadot/types": "^0.97.0-beta.39", + "@polkadot/types": "^0.97.0-beta.40", "@polkadot/util": "^1.7.1", "@polkadot/util-crypto": "^1.7.1", "babel-core": "^7.0.0-bridge.0", diff --git a/packages/app-contracts/package.json b/packages/app-contracts/package.json index 412dda00363d..54b7076b4cfa 100644 --- a/packages/app-contracts/package.json +++ b/packages/app-contracts/package.json @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.4", - "@polkadot/api-contract": "^0.97.0-beta.39", + "@polkadot/api-contract": "^0.97.0-beta.40", "@polkadot/react-components": "^0.37.0-beta.134" } } diff --git a/packages/app-staking/src/Actions/Account/Validate.tsx b/packages/app-staking/src/Actions/Account/Validate.tsx index a5ab177d8d8e..bb802f132135 100644 --- a/packages/app-staking/src/Actions/Account/Validate.tsx +++ b/packages/app-staking/src/Actions/Account/Validate.tsx @@ -2,14 +2,15 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ValidatorPrefs, ValidatorPrefs0to145 } from '@polkadot/types/interfaces'; +import { ValidatorPrefs, ValidatorPrefsTo145, ValidatorPrefsTo196 } from '@polkadot/types/interfaces'; import { ApiProps } from '@polkadot/react-api/types'; import { I18nProps } from '@polkadot/react-components/types'; import BN from 'bn.js'; import React from 'react'; -import { withApi, withMulti } from '@polkadot/react-api'; +import { registry, withApi, withMulti } from '@polkadot/react-api'; import { Button, InputAddress, InputBalance, InputNumber, Modal, TxButton, TxComponent } from '@polkadot/react-components'; +import { createType } from '@polkadot/types'; import InputValidationUnstakeThreshold from './InputValidationUnstakeThreshold'; import translate from '../../translate'; @@ -19,17 +20,24 @@ interface Props extends ApiProps, I18nProps { isOpen: boolean; onClose: () => void; stashId: string; - validatorPrefs?: ValidatorPrefs | ValidatorPrefs0to145; + validatorPrefs?: ValidatorPrefs | ValidatorPrefsTo145 | ValidatorPrefsTo196; } interface State { - unstakeThreshold?: BN; + hasCommission: boolean; + commission: BN; + unstakeThreshold: BN; unstakeThresholdError: string | null; - validatorPayment?: BN; + validatorPayment: BN; } +const COMM_MUL = new BN(10000000); +const MAX_COMM = new BN(100); + class Validate extends TxComponent { public state: State = { + hasCommission: !!(createType(registry, 'ValidatorPrefs').commission), + commission: new BN(0), unstakeThreshold: new BN(3), unstakeThresholdError: null, validatorPayment: new BN(0) @@ -87,7 +95,7 @@ class Validate extends TxComponent { private renderButtons (): React.ReactNode { const { controllerId, isSubstrateV2, onClose, t } = this.props; - const { unstakeThreshold, unstakeThresholdError, validatorPayment } = this.state; + const { commission, hasCommission, unstakeThreshold, unstakeThresholdError, validatorPayment } = this.state; return ( @@ -108,7 +116,9 @@ class Validate extends TxComponent { onClick={onClose} params={[ isSubstrateV2 - ? { validatorPayment } + ? hasCommission + ? { commission } + : { validatorPayment } : { unstakeThreshold, validatorPayment } ]} tx='staking.validate' @@ -121,8 +131,8 @@ class Validate extends TxComponent { private renderContent (): React.ReactNode { const { controllerId, isSubstrateV2, stashId, t, validatorPrefs } = this.props; - const { unstakeThreshold, unstakeThresholdError } = this.state; - const defaultThreshold = validatorPrefs && (validatorPrefs as ValidatorPrefs0to145).unstakeThreshold && (validatorPrefs as ValidatorPrefs0to145).unstakeThreshold.toBn(); + const { hasCommission, unstakeThreshold, unstakeThresholdError } = this.state; + const defaultThreshold = validatorPrefs && (validatorPrefs as ValidatorPrefsTo145).unstakeThreshold && (validatorPrefs as ValidatorPrefsTo145).unstakeThreshold.toBn(); return ( <> @@ -161,30 +171,42 @@ class Validate extends TxComponent { /> )} - + { + hasCommission + ? + : + } ); } + private onChangeCommission = (commission?: BN): void => { + commission && this.setState({ commission: commission.mul(COMM_MUL) }); + } + private onChangePayment = (validatorPayment?: BN): void => { - if (validatorPayment) { - this.setState({ validatorPayment }); - } + validatorPayment && this.setState({ validatorPayment }); } private onChangeThreshold = (unstakeThreshold?: BN): void => { - if (unstakeThreshold) { - this.setState({ unstakeThreshold }); - } + unstakeThreshold && this.setState({ unstakeThreshold }); } private onUnstakeThresholdError = (unstakeThresholdError: string | null): void => { diff --git a/packages/app-staking/src/Targets/Validator.tsx b/packages/app-staking/src/Targets/Validator.tsx index 70c143463fef..e2a5025a95ac 100644 --- a/packages/app-staking/src/Targets/Validator.tsx +++ b/packages/app-staking/src/Targets/Validator.tsx @@ -17,7 +17,7 @@ interface Props extends I18nProps { toggleFavorite: (accountId: string) => void; } -function Validator ({ info: { accountId, bondOther, bondOwn, bondTotal, commission, isFavorite, isNominating, key, numNominators, rankOverall, rewardPayout }, toggleFavorite }: Props): React.ReactElement { +function Validator ({ info: { accountId, bondOther, bondOwn, bondTotal, commissionPer, isCommission, isFavorite, isNominating, key, numNominators, rankOverall, rewardPayout, validatorPayment }, toggleFavorite }: Props): React.ReactElement { const _onFavorite = (): void => toggleFavorite(key); const _onQueryStats = (): void => { window.location.hash = `/staking/query/${key}`; @@ -34,7 +34,13 @@ function Validator ({ info: { accountId, bondOther, bondOwn, bondTotal, commissi {formatNumber(rankOverall)} - + + { + isCommission + ? `${commissionPer.toFixed(2)}%` + : + } + {formatNumber(numNominators)} diff --git a/packages/app-staking/src/Targets/index.tsx b/packages/app-staking/src/Targets/index.tsx index 003db8219cb0..b3ebd3b5eee1 100644 --- a/packages/app-staking/src/Targets/index.tsx +++ b/packages/app-staking/src/Targets/index.tsx @@ -4,6 +4,7 @@ import { DerivedStakingElected } from '@polkadot/api-derive/types'; import { I18nProps } from '@polkadot/react-components/types'; +import { ValidatorPrefs, ValidatorPrefsTo196 } from '@polkadot/types/interfaces'; import { ComponentProps } from '../types'; import { ValidatorInfo } from './types'; @@ -18,6 +19,8 @@ import translate from '../translate'; import Summary from './Summary'; import Validator from './Validator'; +const PERBILL = new BN(1000000000); + interface Props extends I18nProps, ComponentProps { } @@ -34,9 +37,9 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] { return info; }) - .sort((a, b): number => b.commission.cmp(a.commission)) + .sort((a, b): number => b.validatorPayment.cmp(a.validatorPayment)) .map((info, index): ValidatorInfo => { - info.rankCommission = index + 1; + info.rankPayment = index + 1; return info; }) @@ -48,13 +51,13 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] { }) .sort((a, b): number => a.rankReward === b.rankReward - ? a.rankCommission === b.rankCommission + ? a.rankPayment === b.rankPayment ? a.rankBonded === b.rankBonded ? 0 : a.rankBonded < b.rankBonded ? 1 : -1 - : a.rankCommission < b.rankCommission + : a.rankPayment < b.rankPayment ? 1 : -1 : a.rankReward < b.rankReward @@ -96,19 +99,24 @@ function Targets ({ className, sessionRewards, t }: Props): React.ReactElement

{ + console.error((validatorPrefs as ValidatorPrefs).commission.toString()); + const exposure = stakers || { total: api.createType('Compact'), own: api.createType('Compact'), others: api.createType('Vec') }; - const prefs = validatorPrefs || { - validatorPayment: api.createType('Compact') + const prefs = (validatorPrefs as (ValidatorPrefs | ValidatorPrefsTo196)) || { + commission: api.createType('Compact') }; const bondOwn = exposure.own.unwrap(); const bondTotal = exposure.total.unwrap(); - const commission = prefs.validatorPayment.unwrap(); + const perValidatorReward = lastReward.divn(numValidators); + const validatorPayment = (prefs as ValidatorPrefsTo196).validatorPayment + ? (prefs as ValidatorPrefsTo196).validatorPayment.unwrap() as BN + : (prefs as ValidatorPrefs).commission.unwrap().mul(perValidatorReward).div(PERBILL); const key = accountId.toString(); - const rewardSplit = lastReward.divn(numValidators).sub(commission); + const rewardSplit = perValidatorReward.sub(validatorPayment); const calcAmount = amount || new BN(0); const rewardPayout = rewardSplit.gtn(0) ? calcAmount.mul(rewardSplit).div(calcAmount.add(bondTotal)) @@ -125,17 +133,19 @@ function Targets ({ className, sessionRewards, t }: Props): React.ReactElement

- {validatorPrefsDisplay.unstakeThreshold && (stakingInfo.validatorPrefs as ValidatorPrefs0to145).unstakeThreshold && ( + {validatorPrefsDisplay.unstakeThreshold && (stakingInfo.validatorPrefs as any as ValidatorPrefsTo145).unstakeThreshold && ( <>