Extra warning & no max on isUnsafeChain (#1588)

This commit is contained in:
Jaco Greeff 2019-09-06 11:43:05 +02:00 committed by GitHub
parent f3744eb568
commit f19202c81e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 54 deletions

View File

@ -17,10 +17,12 @@ import { ZERO_BALANCE, ZERO_FEES } from '@polkadot/react-signer/Checks/constants
import { bnMax } from '@polkadot/util';
import translate from '../../translate';
import detectUnsafe from '../../unsafeChains';
interface Props extends I18nProps, ApiProps, CalculateBalanceProps {
controllerId: string;
isOpen: boolean;
isUnsafeChain: boolean;
onClose: () => void;
stashId: string;
}
@ -92,7 +94,7 @@ class BondExtra extends TxComponent<Props, State> {
}
private renderContent (): React.ReactNode {
const { stashId, t } = this.props;
const { isUnsafeChain, stashId, t } = this.props;
const { maxBalance } = this.state;
const available = <span className='label'>{t('available ')}</span>;
@ -117,7 +119,7 @@ class BondExtra extends TxComponent<Props, State> {
maxValue={maxBalance}
onChange={this.onChangeValue}
onEnter={this.sendTx}
withMax
withMax={!isUnsafeChain}
/>
</Modal.Content>
</>
@ -182,6 +184,10 @@ export default withMulti(
withCalls<Props>(
'derive.balances.fees',
['derive.balances.all', { paramName: 'stashId' }],
['query.system.accountNonce', { paramName: 'stashId' }]
['query.system.accountNonce', { paramName: 'stashId' }],
['rpc.system.chain', {
propName: 'isUnsafeChain',
transform: detectUnsafe
}]
)
);

View File

@ -18,6 +18,7 @@ interface Props extends ApiProps, I18nProps {
bondedId?: string | null;
controllerId: string | null;
defaultController?: string;
isUnsafeChain?: boolean;
onError: (error: string | null) => void;
stashId?: string | null;
}
@ -26,19 +27,23 @@ interface State {
error: string | null;
}
const DISTINCT = 'Distinct stash and controller accounts are recommended to ensure fund security.';
class ValidateController extends React.PureComponent<Props, State> {
public state: State = {
error: null
};
public static getDerivedStateFromProps ({ accountId, bondedId, controllerId, defaultController, onError, stashId, t }: Props, prevState: State): State {
public static getDerivedStateFromProps ({ accountId, bondedId, controllerId, defaultController, isUnsafeChain, onError, stashId, t }: Props, prevState: State): State {
const error = ((): string | null => {
if (defaultController === controllerId) {
// don't show an error if the selected controller is the default
// this applies when changing controller
return null;
} else if (controllerId === accountId) {
return t('Distinct stash and controller accounts are recommended to ensure fund security');
return isUnsafeChain
? t(`${DISTINCT} You will be allowed to make the transaction, but take care to not tie up all funds, only use a portion of the available funds during this period.`)
: t(DISTINCT);
} else if (bondedId) {
return t('A controller account should not map to another stash. This selected controller is a stash, controlled by {{bondedId}}', { replace: { bondedId } });
} else if (stashId) {

View File

@ -7,24 +7,22 @@ import { I18nProps } from '@polkadot/react-components/types';
import React from 'react';
import { Button, Icon, InputAddress, Modal, TxButton, TxComponent } from '@polkadot/react-components';
import { withCalls, withMulti } from '@polkadot/react-api';
import { Text } from '@polkadot/types';
import translate from '../../translate';
import { NO_VALIDATION_CHAINS } from '../NewStake';
import detectUnsafe from '../../unsafeChains';
import InputValidationController from '../Account/InputValidationController';
interface Props extends I18nProps {
defaultControllerId: string;
isUnsafeChain?: boolean;
isValidating?: boolean;
onClose: () => void;
stashId: string;
systemChain?: Text;
}
interface State {
controllerError: string | null;
controllerId: string | null;
ignoreController: boolean;
}
class SetControllerAccount extends TxComponent<Props, State> {
@ -33,25 +31,14 @@ class SetControllerAccount extends TxComponent<Props, State> {
this.state = {
controllerError: null,
controllerId: null,
ignoreController: false
};
}
public static getDerivedStateFromProps ({ systemChain }: Props): Pick<State, any> | null {
if (!systemChain) {
return null;
}
return {
ignoreController: NO_VALIDATION_CHAINS.includes(systemChain.toString())
controllerId: null
};
}
public render (): React.ReactNode {
const { defaultControllerId, onClose, stashId, t } = this.props;
const { controllerError, controllerId, ignoreController } = this.state;
const canSubmit = ignoreController || (!controllerError && !!controllerId && (defaultControllerId !== controllerId));
const { defaultControllerId, isUnsafeChain, onClose, stashId, t } = this.props;
const { controllerError, controllerId } = this.state;
const canSubmit = isUnsafeChain || (!controllerError && !!controllerId && (defaultControllerId !== controllerId));
return (
<Modal
@ -86,8 +73,8 @@ class SetControllerAccount extends TxComponent<Props, State> {
}
private renderContent (): React.ReactNode {
const { defaultControllerId, stashId, t } = this.props;
const { controllerId, controllerError, ignoreController } = this.state;
const { defaultControllerId, isUnsafeChain, stashId, t } = this.props;
const { controllerId, controllerError } = this.state;
return (
<>
@ -106,7 +93,7 @@ class SetControllerAccount extends TxComponent<Props, State> {
className='medium'
defaultValue={defaultControllerId}
help={t('The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.')}
isError={!ignoreController && !!controllerError}
isError={!isUnsafeChain && !!controllerError}
label={t('controller account')}
onChange={this.onChangeController}
type='account'
@ -116,6 +103,7 @@ class SetControllerAccount extends TxComponent<Props, State> {
accountId={stashId}
defaultController={defaultControllerId}
controllerId={controllerId}
isUnsafeChain={isUnsafeChain}
onError={this.onControllerError}
/>
</Modal.Content>
@ -153,6 +141,9 @@ export default withMulti(
SetControllerAccount,
translate,
withCalls<Props>(
['rpc.system.chain', { propName: 'systemChain' }]
['rpc.system.chain', {
propName: 'isUnsafeChain',
transform: detectUnsafe
}]
)
);

View File

@ -11,15 +11,15 @@ import React from 'react';
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
import { Button, Dropdown, InputAddress, InputBalanceBonded, Modal, TxButton, TxComponent } from '@polkadot/react-components';
import { withCalls, withMulti } from '@polkadot/react-api';
import { Text } from '@polkadot/types';
import translate from '../translate';
import detectUnsafe from '../unsafeChains';
import InputValidationController from './Account/InputValidationController';
import { rewardDestinationOptions } from './constants';
interface Props extends ApiProps, I18nProps, CalculateBalanceProps {
isUnsafeChain?: boolean;
onClose: () => void;
systemChain?: Text;
}
interface State {
@ -28,12 +28,9 @@ interface State {
controllerId: string | null;
destination: number;
extrinsic: SubmittableExtrinsic | null;
ignoreController: boolean;
stashId: string | null;
}
export const NO_VALIDATION_CHAINS = ['Development', 'Kusama CC1', 'Kusama'];
class NewStake extends TxComponent<Props, State> {
public state: State;
@ -45,26 +42,15 @@ class NewStake extends TxComponent<Props, State> {
controllerId: null,
destination: 0,
extrinsic: null,
ignoreController: false,
stashId: null
};
}
public static getDerivedStateFromProps ({ systemChain }: Props): Pick<State, any> | null {
if (!systemChain) {
return null;
}
return {
ignoreController: NO_VALIDATION_CHAINS.includes(systemChain.toString())
};
}
public render (): React.ReactNode {
const { onClose, t } = this.props;
const { bondValue, controllerError, controllerId, extrinsic, ignoreController, stashId } = this.state;
const { isUnsafeChain, onClose, t } = this.props;
const { bondValue, controllerError, controllerId, extrinsic, stashId } = this.state;
const hasValue = !!bondValue && bondValue.gtn(0);
const canSubmit = (hasValue && (ignoreController || (!controllerError && !!controllerId)));
const canSubmit = (hasValue && (isUnsafeChain || (!controllerError && !!controllerId)));
return (
<Modal
@ -98,8 +84,8 @@ class NewStake extends TxComponent<Props, State> {
}
private renderContent (): React.ReactNode {
const { t } = this.props;
const { controllerId, controllerError, bondValue, destination, ignoreController, stashId } = this.state;
const { isUnsafeChain, t } = this.props;
const { controllerId, controllerError, bondValue, destination, stashId } = this.state;
const hasValue = !!bondValue && bondValue.gtn(0);
return (
@ -118,7 +104,7 @@ class NewStake extends TxComponent<Props, State> {
<InputAddress
className='medium'
help={t('The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.')}
isError={!ignoreController && !!controllerError}
isError={!isUnsafeChain && !!controllerError}
label={t('controller account')}
onChange={this.onChangeController}
type='account'
@ -127,6 +113,7 @@ class NewStake extends TxComponent<Props, State> {
<InputValidationController
accountId={stashId}
controllerId={controllerId}
isUnsafeChain={isUnsafeChain}
onError={this.onControllerError}
/>
<InputBalanceBonded
@ -141,7 +128,7 @@ class NewStake extends TxComponent<Props, State> {
onChange={this.onChangeValue}
onEnter={this.sendTx}
stashId={stashId}
withMax
withMax={!isUnsafeChain}
/>
<Dropdown
className='medium'
@ -160,7 +147,7 @@ class NewStake extends TxComponent<Props, State> {
private nextState (newState: Partial<State>): void {
this.setState((prevState: State): State => {
const { api } = this.props;
const { bondValue = prevState.bondValue, controllerError = prevState.controllerError, controllerId = prevState.controllerId, destination = prevState.destination, ignoreController = prevState.ignoreController, stashId = prevState.stashId } = newState;
const { bondValue = prevState.bondValue, controllerError = prevState.controllerError, controllerId = prevState.controllerId, destination = prevState.destination, stashId = prevState.stashId } = newState;
const extrinsic = (bondValue && controllerId)
? api.tx.staking.bond(controllerId, bondValue, destination)
: null;
@ -171,7 +158,6 @@ class NewStake extends TxComponent<Props, State> {
controllerId,
destination,
extrinsic,
ignoreController,
stashId
};
});
@ -202,6 +188,9 @@ export default withMulti(
NewStake,
translate,
withCalls<Props>(
['rpc.system.chain', { propName: 'systemChain' }]
['rpc.system.chain', {
propName: 'isUnsafeChain',
transform: detectUnsafe
}]
)
);

View File

@ -0,0 +1,9 @@
// 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.
export const UNSAFE_CHAINS = ['Development', 'Kusama CC1', 'Kusama'];
export default function detectUnsafe (chain: Text | string): boolean {
return UNSAFE_CHAINS.includes(chain.toString());
}