Add ability to stake (#844)
This commit is contained in:
parent
b45f1a1ea9
commit
5a50b9ba97
@ -7,7 +7,7 @@ import { I18nProps } from '@polkadot/ui-app/types';
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import { ValidatorPrefs } from '@polkadot/types';
|
||||
import { Button, InputBalance, InputNumber, Modal } from '@polkadot/ui-app';
|
||||
import { Button, InputAddress, InputBalance, InputNumber, Modal, TxButton } from '@polkadot/ui-app';
|
||||
|
||||
import translate from '../translate';
|
||||
|
||||
@ -15,8 +15,7 @@ type Props = I18nProps & {
|
||||
accountId: string,
|
||||
isOpen: boolean,
|
||||
onClose: () => void,
|
||||
onSetPrefs: (prefs: ValidatorPrefs) => void,
|
||||
validatorPreferences?: ValidatorPrefs
|
||||
preferences: ValidatorPrefs
|
||||
};
|
||||
|
||||
type State = {
|
||||
@ -24,17 +23,17 @@ type State = {
|
||||
validatorPayment?: BN
|
||||
};
|
||||
|
||||
class Preferences extends React.PureComponent<Props, State> {
|
||||
class Staking 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.validatorPreferences) {
|
||||
if (state.unstakeThreshold) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { unstakeThreshold, validatorPayment } = props.validatorPreferences;
|
||||
const { unstakeThreshold, validatorPayment } = props.preferences;
|
||||
|
||||
return {
|
||||
unstakeThreshold: unstakeThreshold.toBn(),
|
||||
@ -51,7 +50,7 @@ class Preferences extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className='staking--Preferences'
|
||||
className='staking--Staking'
|
||||
dimmer='inverted'
|
||||
open
|
||||
size='small'
|
||||
@ -63,21 +62,28 @@ class Preferences extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
private renderButtons () {
|
||||
const { onClose, t } = this.props;
|
||||
const { accountId, onClose, t } = this.props;
|
||||
const { unstakeThreshold, validatorPayment } = this.state;
|
||||
|
||||
return (
|
||||
<Modal.Actions>
|
||||
<Button.Group>
|
||||
<Button
|
||||
isNegative
|
||||
onClick={onClose}
|
||||
label={t('Cancel')}
|
||||
onClick={onClose}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
isPrimary
|
||||
onClick={this.setPrefs}
|
||||
label={t('Set Prefs')}
|
||||
label={t('Stake')}
|
||||
onClick={onClose}
|
||||
params={[{
|
||||
unstakeThreshold,
|
||||
validatorPayment
|
||||
}]}
|
||||
tx='staking.validate'
|
||||
/>
|
||||
</Button.Group>
|
||||
</Modal.Actions>
|
||||
@ -85,15 +91,21 @@ class Preferences extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
private renderContent () {
|
||||
const { t } = this.props;
|
||||
const { accountId, t } = this.props;
|
||||
const { unstakeThreshold, validatorPayment } = this.state;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal.Header>
|
||||
{t('Validator Preferences')}
|
||||
{t('Staking')}
|
||||
</Modal.Header>
|
||||
<Modal.Content className='ui--signer-Signer-Content'>
|
||||
<InputAddress
|
||||
className='medium'
|
||||
isDisabled
|
||||
label={t('account')}
|
||||
value={accountId}
|
||||
/>
|
||||
<InputNumber
|
||||
autoFocus
|
||||
bitLength={32}
|
||||
@ -132,16 +144,6 @@ class Preferences extends React.PureComponent<Props, State> {
|
||||
this.setState({ unstakeThreshold });
|
||||
}
|
||||
}
|
||||
|
||||
private setPrefs = () => {
|
||||
const { onSetPrefs } = this.props;
|
||||
const { unstakeThreshold, validatorPayment } = this.state;
|
||||
|
||||
onSetPrefs(new ValidatorPrefs({
|
||||
unstakeThreshold,
|
||||
validatorPayment
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(Preferences);
|
||||
export default translate(Staking);
|
||||
@ -14,8 +14,8 @@ import { withCalls } from '@polkadot/ui-api';
|
||||
|
||||
import Bonding from './Bonding';
|
||||
import Controller from './Controller';
|
||||
import Staking from './Staking';
|
||||
// import Nominating from './Nominating';
|
||||
// import Preferences from './Preferences';
|
||||
// import UnnominateButton from './UnnominateButton';
|
||||
import translate from '../translate';
|
||||
|
||||
@ -25,9 +25,10 @@ type Props = ApiProps & I18nProps & {
|
||||
balanceArray: (_address: AccountId | string) => Array<Balance> | undefined,
|
||||
name: string,
|
||||
session_nextKeyFor?: Option<AccountId>,
|
||||
staking_bonded?: Option<AccountId>,
|
||||
staking_nominating?: Option<AccountId>,
|
||||
staking_nominatorsFor?: Array<string>,
|
||||
staking_validatorPreferences?: ValidatorPrefs,
|
||||
staking_validators?: ValidatorPrefs,
|
||||
intentions: Array<string>,
|
||||
isValidator: boolean,
|
||||
queueExtrinsic: QueueTx$ExtrinsicAdd
|
||||
@ -36,19 +37,31 @@ type Props = ApiProps & I18nProps & {
|
||||
type State = {
|
||||
isBondingOpen: boolean,
|
||||
isControllerOpen: boolean,
|
||||
nominee: AccountId | null
|
||||
isStakingOpen: boolean,
|
||||
bondedId: AccountId | null,
|
||||
controllerId: AccountId | null,
|
||||
nomineeId: AccountId | null
|
||||
};
|
||||
|
||||
class Account extends React.PureComponent<Props, State> {
|
||||
state: State = {
|
||||
isBondingOpen: false,
|
||||
isControllerOpen: false,
|
||||
nominee: null
|
||||
isStakingOpen: false,
|
||||
bondedId: null,
|
||||
controllerId: null,
|
||||
nomineeId: null
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps ({ staking_nominating }: Props): Partial<State> {
|
||||
static getDerivedStateFromProps ({ session_nextKeyFor, staking_bonded, staking_nominating }: Props): Partial<State> {
|
||||
return {
|
||||
nominee: staking_nominating
|
||||
bondedId: staking_bonded
|
||||
? staking_bonded.unwrapOr(null)
|
||||
: null,
|
||||
controllerId: session_nextKeyFor
|
||||
? session_nextKeyFor.unwrapOr(null)
|
||||
: null,
|
||||
nomineeId: staking_nominating
|
||||
? staking_nominating.unwrapOr(null)
|
||||
: null
|
||||
};
|
||||
@ -61,6 +74,7 @@ class Account extends React.PureComponent<Props, State> {
|
||||
<article className='staking--Account'>
|
||||
{this.renderBonding()}
|
||||
{this.renderController()}
|
||||
{this.renderStaking()}
|
||||
<AddressSummary
|
||||
balance={balanceArray(accountId)}
|
||||
name={name}
|
||||
@ -78,17 +92,17 @@ class Account extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
private renderBonding () {
|
||||
const { accountId, session_nextKeyFor } = this.props;
|
||||
const { isBondingOpen } = this.state;
|
||||
const { accountId } = this.props;
|
||||
const { controllerId, isBondingOpen } = this.state;
|
||||
|
||||
if (!session_nextKeyFor || session_nextKeyFor.isNone) {
|
||||
if (!controllerId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Bonding
|
||||
accountId={accountId}
|
||||
controllerId={session_nextKeyFor.unwrap()}
|
||||
controllerId={controllerId}
|
||||
isOpen={isBondingOpen}
|
||||
onClose={this.toggleBonding}
|
||||
/>
|
||||
@ -96,11 +110,8 @@ class Account extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
private renderController () {
|
||||
const { accountId, session_nextKeyFor } = this.props;
|
||||
const { isControllerOpen } = this.state;
|
||||
const controllerId = session_nextKeyFor
|
||||
? session_nextKeyFor.unwrapOr(null)
|
||||
: null;
|
||||
const { accountId } = this.props;
|
||||
const { controllerId, isControllerOpen } = this.state;
|
||||
|
||||
return (
|
||||
<Controller
|
||||
@ -112,18 +123,36 @@ class Account extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
private renderStaking () {
|
||||
const { accountId, staking_validators } = this.props;
|
||||
const { isStakingOpen } = this.state;
|
||||
|
||||
if (!staking_validators || !isStakingOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Staking
|
||||
accountId={accountId}
|
||||
isOpen
|
||||
onClose={this.toggleStaking}
|
||||
preferences={staking_validators}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private renderNominee () {
|
||||
const { balanceArray } = this.props;
|
||||
const { nominee } = this.state;
|
||||
const { nomineeId } = this.state;
|
||||
|
||||
if (!nominee) {
|
||||
if (!nomineeId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<AddressMini
|
||||
balance={balanceArray(nominee)}
|
||||
value={nominee}
|
||||
balance={balanceArray(nomineeId)}
|
||||
value={nomineeId}
|
||||
withBalance
|
||||
/>
|
||||
);
|
||||
@ -180,7 +209,8 @@ class Account extends React.PureComponent<Props, State> {
|
||||
// }
|
||||
|
||||
private renderButtons () {
|
||||
const { session_nextKeyFor, t } = this.props;
|
||||
const { t } = this.props;
|
||||
const { bondedId, controllerId } = this.state;
|
||||
const buttons = [
|
||||
<Button
|
||||
isPrimary
|
||||
@ -190,7 +220,8 @@ class Account extends React.PureComponent<Props, State> {
|
||||
/>
|
||||
];
|
||||
|
||||
if (session_nextKeyFor && session_nextKeyFor.isSome) {
|
||||
// only display bonmding if we already have a controller
|
||||
if (controllerId) {
|
||||
buttons.push(<Button.Or key='bond.or' />);
|
||||
buttons.push(
|
||||
<Button
|
||||
@ -202,6 +233,19 @@ class Account extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
// only stake/nominate if we already have bonded
|
||||
if (bondedId) {
|
||||
buttons.push(<Button.Or key='stake.or' />);
|
||||
buttons.push(
|
||||
<Button
|
||||
isPrimary
|
||||
key='stake'
|
||||
onClick={this.toggleStaking}
|
||||
label={t('Stake')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button.Group>
|
||||
{buttons}
|
||||
@ -262,6 +306,12 @@ class Account extends React.PureComponent<Props, State> {
|
||||
}));
|
||||
}
|
||||
|
||||
private toggleStaking = () => {
|
||||
this.setState(({ isStakingOpen }) => ({
|
||||
isStakingOpen: !isStakingOpen
|
||||
}));
|
||||
}
|
||||
|
||||
// private toggleNominate = () => {
|
||||
// this.setState(({ isNominateOpen }: State) => ({
|
||||
// isNominateOpen: !isNominateOpen
|
||||
@ -278,8 +328,9 @@ class Account extends React.PureComponent<Props, State> {
|
||||
export default translate(
|
||||
withCalls<Props>(
|
||||
['query.session.nextKeyFor', { paramName: 'accountId' }],
|
||||
['query.staking.bonded', { paramName: 'accountId' }],
|
||||
['query.staking.nominatorsFor', { paramName: 'accountId' }],
|
||||
['query.staking.nominating', { paramName: 'accountId' }],
|
||||
['query.staking.validatorPreferences', { paramName: 'accountId' }]
|
||||
['query.staking.validators', { paramName: 'accountId' }]
|
||||
)(Account)
|
||||
);
|
||||
|
||||
@ -44,6 +44,9 @@ class TxButtonInner extends React.PureComponent<Props & InjectedProps> {
|
||||
|
||||
private send = (): void => {
|
||||
const { accountId, api, onClick, onFailed, onSuccess, onUpdate, params, queueExtrinsic, tx } = this.props;
|
||||
|
||||
assert(tx, 'Expected tx param passed to TxButton');
|
||||
|
||||
const [section, method] = tx.split('.');
|
||||
|
||||
assert(api.tx[section] && api.tx[section][method], `Unable to find api.tx.${section}.${method}`);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user