Add setting of ValidatorPrefs (#624)

* Add setting of ValidatorPrefs

* Bump API

* Pull through initial values in InputNumber
This commit is contained in:
Jaco Greeff 2019-01-21 14:10:52 +01:00 committed by GitHub
parent b73043e2f7
commit e86fb8de43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 266 additions and 68 deletions

View File

@ -9,11 +9,12 @@ import { QueueTx$ExtrinsicAdd } from '@polkadot/ui-app/Status/types';
import { ApiProps } from '@polkadot/ui-api/types';
import React from 'react';
import { AccountId, Balance } from '@polkadot/types';
import { AccountId, Balance, ValidatorPrefs } from '@polkadot/types';
import { AddressMini, AddressSummary, Button } from '@polkadot/ui-app/index';
import { withCall, withMulti } from '@polkadot/ui-api/index';
import Nominating from './Nominating';
import Preferences from './Preferences';
import UnnominateButton from './UnnominateButton';
import translate from '../translate';
@ -32,7 +33,8 @@ type Props = ApiProps & I18nProps & {
type State = {
isNominateOpen: boolean,
isNominating: boolean
isNominating: boolean,
isPrefsOpen: boolean
};
class Account extends React.PureComponent<Props, State> {
@ -41,7 +43,8 @@ class Account extends React.PureComponent<Props, State> {
this.state = {
isNominateOpen: false,
isNominating: false
isNominating: false,
isPrefsOpen: false
};
}
@ -55,7 +58,7 @@ class Account extends React.PureComponent<Props, State> {
render () {
const { accountId, balanceArray, intentions, name } = this.props;
const { isNominateOpen } = this.state;
const { isNominateOpen, isPrefsOpen } = this.state;
return (
<article className='staking--Account'>
@ -65,6 +68,12 @@ class Account extends React.PureComponent<Props, State> {
onNominate={this.nominate}
intentions={intentions}
/>
<Preferences
accountId={accountId}
isOpen={isPrefsOpen}
onClose={this.togglePrefs}
onSetPrefs={this.setPrefs}
/>
<AddressSummary
balance={balanceArray(accountId)}
name={name}
@ -162,6 +171,12 @@ class Account extends React.PureComponent<Props, State> {
onClick={this.unstake}
text={t('Unstake')}
/>
<Button.Or />
<Button
isPrimary
onClick={this.togglePrefs}
text={t('Set Prefs')}
/>
</Button.Group>
);
}
@ -183,6 +198,14 @@ class Account extends React.PureComponent<Props, State> {
);
}
private togglePrefs = () => {
this.setState(
({ isPrefsOpen }: State) => ({
isPrefsOpen: !isPrefsOpen
})
);
}
private nominate = (nominee: string) => {
const { api } = this.props;
@ -197,6 +220,14 @@ class Account extends React.PureComponent<Props, State> {
this.send(api.tx.staking.unnominate(index));
}
private setPrefs = (prefs: ValidatorPrefs) => {
const { api } = this.props;
this.send(api.tx.staking.registerPreferences(this.getIntentionIndex(), prefs));
this.togglePrefs();
}
private stake = () => {
const { api } = this.props;
@ -206,9 +237,13 @@ class Account extends React.PureComponent<Props, State> {
private unstake = () => {
const { api } = this.props;
this.send(api.tx.staking.unstake(this.getIntentionIndex()));
}
private getIntentionIndex (): number {
const { accountId, intentions } = this.props;
this.send(api.tx.staking.unstake(intentions.indexOf(accountId)));
return intentions.indexOf(accountId);
}
}

View File

@ -23,7 +23,7 @@ type State = {
nominee: string
};
class Nominating extends React.PureComponent<Props> {
class Nominating extends React.PureComponent<Props, State> {
state: State;
constructor (props: Props) {
@ -48,6 +48,7 @@ class Nominating extends React.PureComponent<Props> {
className='staking--Nominating'
dimmer='inverted'
open
size='small'
style={style}
>
{this.renderContent()}

View File

@ -0,0 +1,152 @@
// Copyright 2017-2019 @polkadot/ui-staking authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/ui-app/types';
import BN from 'bn.js';
import React from 'react';
import { ValidatorPrefs } from '@polkadot/types';
import { withCall, withMulti } from '@polkadot/ui-api/index';
import { Button, InputNumber, Modal } from '@polkadot/ui-app/index';
import translate from '../translate';
type Props = I18nProps & {
accountId: string,
isOpen: boolean,
onClose: () => void,
onSetPrefs: (prefs: ValidatorPrefs) => void,
staking_validatorPreferences?: ValidatorPrefs
};
type State = {
unstakeThreshold?: BN,
validatorPayment?: BN
};
class Preferences extends React.PureComponent<Props, State> {
state: State = {};
// inject the preferences are returned via RPC once into the state (from this
// point forward it will be entirely managed by the actual inputs)
static getDerivedStateFromProps (props: Props, state: State): State | null {
if (state.unstakeThreshold || !props.staking_validatorPreferences) {
return null;
}
const { unstakeThreshold, validatorPayment } = props.staking_validatorPreferences;
return {
unstakeThreshold: unstakeThreshold.toBn(),
validatorPayment: validatorPayment.toBn()
};
}
render () {
const { isOpen, style } = this.props;
if (!isOpen) {
return null;
}
return (
<Modal
className='staking--Nominating'
dimmer='inverted'
open
size='small'
style={style}
>
{this.renderContent()}
{this.renderButtons()}
</Modal>
);
}
private renderButtons () {
const { onClose, t } = this.props;
return (
<Modal.Actions>
<Button.Group>
<Button
isNegative
onClick={onClose}
text={t('Cancel')}
/>
<Button.Or />
<Button
isPrimary
onClick={this.setPrefs}
text={t('Set Prefs')}
/>
</Button.Group>
</Modal.Actions>
);
}
private renderContent () {
const { t } = this.props;
const { unstakeThreshold, validatorPayment } = this.state;
return [
<Modal.Header key='header'>
{t('Validator Preferences')}
</Modal.Header>,
<Modal.Content className='ui--signer-Signer-Content' key='content'>
<InputNumber
bitLength={32}
className='medium'
label={t('unstake threshold')}
onChange={this.onChangeThreshold}
value={
unstakeThreshold
? unstakeThreshold.toString()
: '0'
}
/>
<InputNumber
bitLength={128}
className='medium'
isSi
label={t('payment preferences')}
onChange={this.onChangePayment}
value={
validatorPayment
? validatorPayment.toString()
: '0'
}
/>
</Modal.Content>
];
}
private onChangePayment = (validatorPayment?: BN) => {
if (validatorPayment) {
this.setState({ validatorPayment });
}
}
private onChangeThreshold = (unstakeThreshold: BN = new BN(0)) => {
if (unstakeThreshold) {
this.setState({ unstakeThreshold });
}
}
private setPrefs = () => {
const { onSetPrefs } = this.props;
const { unstakeThreshold, validatorPayment } = this.state;
onSetPrefs(new ValidatorPrefs({
unstakeThreshold,
validatorPayment
}));
}
}
export default withMulti(
Preferences,
translate,
withCall('query.staking.validatorPreferences', { paramName: 'accountId' })
);

View File

@ -31,8 +31,8 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.2.0",
"@polkadot/api": "^0.40.11",
"@polkadot/types": "^0.40.11",
"@polkadot/api": "^0.40.12",
"@polkadot/types": "^0.40.12",
"rxjs-compat": "^6.3.2"
}
}

View File

@ -11,10 +11,10 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.2.0",
"@polkadot/extrinsics": "^0.40.11",
"@polkadot/extrinsics": "^0.40.12",
"@polkadot/keyring": "^0.33.35",
"@polkadot/storage": "^0.40.11",
"@polkadot/types": "^0.40.11",
"@polkadot/storage": "^0.40.12",
"@polkadot/types": "^0.40.12",
"@polkadot/ui-api": "^0.22.32",
"@polkadot/ui-identicon": "^0.25.7",
"@polkadot/ui-keyring": "^0.25.7",

View File

@ -7,6 +7,7 @@ import { BareProps, BitLength, I18nProps } from './types';
import BN from 'bn.js';
import React from 'react';
import { balanceFormat, calcSi } from '@polkadot/ui-reactive/util/index';
import { isUndefined } from '@polkadot/util';
import classes from './util/classes';
import { BitLengthOption } from './constants';
@ -25,6 +26,7 @@ type Props = BareProps & I18nProps & {
maxLength?: number,
onChange: (value?: BN) => void,
placeholder?: string,
value?: BN | string,
withLabel?: boolean
};
@ -52,7 +54,7 @@ class InputNumber extends React.PureComponent<Props, State> {
this.state = {
isPreKeyDown: false,
isValid: false,
isValid: !isUndefined(this.props.value),
siOptions: balanceFormat.getOptions().map(({ power, text, value }) => ({
value,
text: power === 0
@ -60,7 +62,9 @@ class InputNumber extends React.PureComponent<Props, State> {
: text
})),
siUnit: '-',
valueBN: new BN(0)
valueBN: this.props.value
? new BN(this.props.value)
: new BN(0)
};
}

View File

@ -224,6 +224,10 @@ header .ui--Button-Group {
}
}
.ui--Labelled {
text-align: left;
}
.ui--Static {
overflow: hidden;
word-break: break-all;

View File

@ -31,8 +31,8 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.2.0",
"@polkadot/api": "^0.40.11",
"@polkadot/types": "^0.40.11",
"@polkadot/api": "^0.40.12",
"@polkadot/types": "^0.40.12",
"rxjs-compat": "^6.3.2"
}
}

View File

@ -299,6 +299,8 @@ class Signer extends React.PureComponent<Props, State> {
private async makeExtrinsicCall (extrinsic: SubmittableExtrinsic, id: number, extrinsicCall: (...params: Array<any>) => any, ..._params: Array<any>): Promise<void> {
const { queueSetTxStatus } = this.props;
console.log('makeExtrinsicCall: extrinsic ::', extrinsic.toHex());
try {
const unsubscribe = await extrinsicCall.apply(extrinsic, [..._params, async (result: SubmittableSendResult) => {
if (!result || !result.type || !result.status) {
@ -307,7 +309,7 @@ class Signer extends React.PureComponent<Props, State> {
const status = result.type.toLowerCase() as QueueTx$Status;
console.log('submitAndWatchExtrinsic: updated status ::', result);
console.log('makeExtrinsicCall: updated status ::', result);
queueSetTxStatus(id, status, result);

104
yarn.lock
View File

@ -1385,31 +1385,31 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@polkadot/api-derive@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.40.11.tgz#cbbf2e4d442e7ed251da290cea06978456e4bc4e"
integrity sha512-QGwupV2uVO2LJ6F3ZgAl7ntmnB0Fb4k3CdrXjZTYVm4OA+CWBixwEswvUCinRdN+pcNcoJdbzXkM4FcQItKLUw==
"@polkadot/api-derive@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.40.12.tgz#c7c542737c7d3a23aa8883cc3f68279b965af6ab"
integrity sha512-l6QTMjaAR14UJA4KbirHElOei/Au7fDq56gCkzb3pNK580ispfBhqEcq8HmDLEX294PtH8urycScJ9hxSYgNeg==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/api" "^0.40.11"
"@polkadot/types" "^0.40.11"
"@polkadot/api" "^0.40.12"
"@polkadot/types" "^0.40.12"
"@types/memoizee" "^0.4.2"
"@types/rx" "^4.1.1"
memoizee "^0.4.14"
rxjs "^6.3.3"
"@polkadot/api@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.40.11.tgz#9c28f3c9559f3ce9dbfa6e431684efacee121f51"
integrity sha512-SNO3wpFye4PEb9GkNJFTNxZO3n1r/QTkduiOL8/lcb+J67NQr2cpe91ZTguyR0PHqg3/6P7enOmt4odkJKvO3w==
"@polkadot/api@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.40.12.tgz#ed65d1db174be5d6841e725e0cd15dd81bb6abc5"
integrity sha512-E1G5St/7R7yuq0eQP640FeOkpt68mPavcWKPdBTRedCIqG0nBMclhLxum2uH6YfXD7CBX9eY362PRA+aHqmXzw==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/api-derive" "^0.40.11"
"@polkadot/extrinsics" "^0.40.11"
"@polkadot/rpc-provider" "^0.40.11"
"@polkadot/rpc-rx" "^0.40.11"
"@polkadot/storage" "^0.40.11"
"@polkadot/types" "^0.40.11"
"@polkadot/api-derive" "^0.40.12"
"@polkadot/extrinsics" "^0.40.12"
"@polkadot/rpc-provider" "^0.40.12"
"@polkadot/rpc-rx" "^0.40.12"
"@polkadot/storage" "^0.40.12"
"@polkadot/types" "^0.40.12"
"@types/rx" "^4.1.1"
rxjs "^6.3.3"
@ -1489,19 +1489,19 @@
typedoc-plugin-no-inherit "^1.1.2"
typescript "^3.2.2"
"@polkadot/extrinsics@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/extrinsics/-/extrinsics-0.40.11.tgz#1b431acb6605abae68a2f0ab025b1797bffccb84"
integrity sha512-uZY+cwKVNosVh6kuJIO5nknuJKnGKUM46QHSLEareIph5cATMS+MTDJBLqY5OSebCYVrlRhA0ovSLUfZRhPrMA==
"@polkadot/extrinsics@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/extrinsics/-/extrinsics-0.40.12.tgz#dd250b5bd55765da987a6d405279e66987d9d114"
integrity sha512-NB+Dl8XMm48rA8zlnN7tA2dhHftamoqeGONG1Qf76LqJqxsLUHIlijmJyoEEIPO0moa2wVDP6ALurxAF8o6H6g==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/types" "^0.40.11"
"@polkadot/types" "^0.40.12"
"@polkadot/util" "^0.33.35"
"@polkadot/jsonrpc@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.40.11.tgz#e4f33c8df608871f6a2631a4bc902da38e7e60f7"
integrity sha512-rWdDV/rhPhch64w6eqhenSzPqrlfGSe7HRvtSyRRk7cQezg0bZFnlthDvbEWFOfU335ZqOxaMVYrXJwFYjFG4Q==
"@polkadot/jsonrpc@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.40.12.tgz#a40500ffd24bec58efe5ad2d62141a5d6887ff7c"
integrity sha512-3nCT2yBkXRBqjczqZfX/ajFZ4og5MmLEn+FNEEpan2Q+I7fEoBr6wXp7gVkpek+yVIS2jHkoQBNBYm7F50xRCQ==
dependencies:
"@babel/runtime" "^7.2.0"
@ -1516,25 +1516,25 @@
"@types/bs58" "^4.0.0"
bs58 "^4.0.1"
"@polkadot/rpc-core@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.40.11.tgz#678fb10b0185a47258a49337b1e2135ba1ea1ebc"
integrity sha512-4M3MlAKxfPPChdluA0kYljAgJvwVLU1uRjwQq1HLB8CA4tuyTrpjklf0Zcw8GixVfyI9HP91R1lnFyvl0eo+ag==
"@polkadot/rpc-core@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.40.12.tgz#ff7dbbbacaed1b7324cd07b6c0fed55b21eccecf"
integrity sha512-SNqwqvXAUZOmQtoMVMClj4Tk0MIzQNp9RhtGx9bkVWVTfoj3MKwvOGjKznBtlcrm4Eo99Vgc5gkGXGPWhZXrwA==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/jsonrpc" "^0.40.11"
"@polkadot/rpc-provider" "^0.40.11"
"@polkadot/types" "^0.40.11"
"@polkadot/jsonrpc" "^0.40.12"
"@polkadot/rpc-provider" "^0.40.12"
"@polkadot/types" "^0.40.12"
"@polkadot/util" "^0.33.35"
"@polkadot/rpc-provider@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.40.11.tgz#92f25badae7274fe79afe74c59ea654d6be64481"
integrity sha512-QB4L1GmYNhSxcY1C6jCrJxHMRF9O/yAZrlQ+Fkq4HEuMPG6brpz/KlmQokkBQLCqT6mm7yOS7TTjhvKLWRAtug==
"@polkadot/rpc-provider@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.40.12.tgz#3609d72127d531a0af50bdca7d286f9ad772da97"
integrity sha512-9cbaBSt6ez+pmO7pBx7yt7DrtK28m3SlpzbGZfTMRUbRRGhJhdEs0hQ5UZDL9hAeQ/cOvqjGWUgI0u1EsN58xw==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/keyring" "^0.33.35"
"@polkadot/storage" "^0.40.11"
"@polkadot/storage" "^0.40.12"
"@polkadot/util" "^0.33.35"
"@polkadot/util-crypto" "^0.33.35"
"@types/nock" "^9.3.0"
@ -1542,25 +1542,25 @@
isomorphic-fetch "^2.2.1"
websocket "^1.0.28"
"@polkadot/rpc-rx@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-rx/-/rpc-rx-0.40.11.tgz#7f97f1e6f47816d40dc982f93567c32bbbbacdd9"
integrity sha512-txxB7HxUNqmBF8a71ubkNQlqIbQY0/JgP8ORu9eKiPMSgHRcbv/IrByWNyV2TUVTsAZU7akNlB4V2ov2C/U1yg==
"@polkadot/rpc-rx@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-rx/-/rpc-rx-0.40.12.tgz#b923e466ab45c589809371420c4b66c4d498cd14"
integrity sha512-atfvFKoKBhbEtl/28NBtA2d+N0sAfsfYGf/grOwusQBeLRPbGFVEXkWKPTdkxPLHy6Wi8GfFfh+uDjCMC/VpwQ==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/rpc-core" "^0.40.11"
"@polkadot/rpc-provider" "^0.40.11"
"@polkadot/rpc-core" "^0.40.12"
"@polkadot/rpc-provider" "^0.40.12"
"@types/rx" "^4.1.1"
rxjs "^6.3.3"
"@polkadot/storage@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/storage/-/storage-0.40.11.tgz#e3b0a0b21b839a15383fa8f8828811dbd2b60c87"
integrity sha512-xy4Sv+0joHGBTYhPKDfenyt4qVuNmFnomTT2QXAB0I279EcDCo4CBNGPzbA8TLNkf/h1SMvTg4fljMRbyLgBwg==
"@polkadot/storage@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/storage/-/storage-0.40.12.tgz#c25c5c1437082fa38736c89939a21d2a2eae3ac2"
integrity sha512-ab8slPQ65pnSH/BMGoE7AzDNZaR2hdx0NE9+hyg6YL8lyyK/TvGNCTnstlWUReKi0IphKkelYRfrLyBFx3SHvg==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/keyring" "^0.33.35"
"@polkadot/types" "^0.40.11"
"@polkadot/types" "^0.40.12"
"@polkadot/util" "^0.33.35"
"@polkadot/util-crypto" "^0.33.35"
@ -1569,10 +1569,10 @@
resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.1.51.tgz#4ce26923b3d34c026e14081975718b716c988483"
integrity sha512-p+uQIZqxtlQGTQoNcd8mED66qfyPA4qy8HmCMpUYDaFHKNpZ7qun0dqSoT0NvUB32KTSQitKhf/N0att8sEdow==
"@polkadot/types@^0.40.11":
version "0.40.11"
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.40.11.tgz#59c785fcdcf11030abf8e5f65108a225f1b696c7"
integrity sha512-vP+zFNAHfyUb989HelsXCrqxENTUAJuQVKiD9BzhtTfNt9OLVT4DhUmQsanpbCAgElT7ge+2OJWvZpThUxse9Q==
"@polkadot/types@^0.40.12":
version "0.40.12"
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.40.12.tgz#a4506c80db0ab123537dbb6418de7a3f485dba2d"
integrity sha512-/wdc2oHOvBZDDCCd2luhTTDRe808ETsbI/fyJq5kR/VZILhK4ary4UbZhWP7zh88S/MY6qiIY3JBbjOzAZGTjw==
dependencies:
"@babel/runtime" "^7.2.0"
"@polkadot/keyring" "^0.33.35"