Extra warning & no max on isUnsafeChain (#1588)
This commit is contained in:
parent
f3744eb568
commit
f19202c81e
@ -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
|
||||
}]
|
||||
)
|
||||
);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
}]
|
||||
)
|
||||
);
|
||||
|
||||
@ -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
|
||||
}]
|
||||
)
|
||||
);
|
||||
|
||||
9
packages/app-staking/src/unsafeChains.ts
Normal file
9
packages/app-staking/src/unsafeChains.ts
Normal 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());
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user