mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-02-10 18:16:45 +00:00
[FEATURE] Gas estimation for scheduling
This commit is contained in:
parent
dde63beae3
commit
40be251e7b
@ -9,9 +9,14 @@ import { Input } from 'components/ui';
|
|||||||
interface Props {
|
interface Props {
|
||||||
customLabel?: string;
|
customLabel?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
hideGasCalculationSpinner?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GasLimitField: React.SFC<Props> = ({ customLabel, disabled }) => (
|
export const GasLimitField: React.SFC<Props> = ({
|
||||||
|
customLabel,
|
||||||
|
disabled,
|
||||||
|
hideGasCalculationSpinner
|
||||||
|
}) => (
|
||||||
<GasLimitFieldFactory
|
<GasLimitFieldFactory
|
||||||
withProps={({ gasLimit: { raw }, onChange, readOnly, gasEstimationPending }) => (
|
withProps={({ gasLimit: { raw }, onChange, readOnly, gasEstimationPending }) => (
|
||||||
<div className="input-group-wrapper">
|
<div className="input-group-wrapper">
|
||||||
@ -19,7 +24,10 @@ export const GasLimitField: React.SFC<Props> = ({ customLabel, disabled }) => (
|
|||||||
<div className="input-group-header">
|
<div className="input-group-header">
|
||||||
{customLabel ? customLabel : translate('TRANS_GAS')}
|
{customLabel ? customLabel : translate('TRANS_GAS')}
|
||||||
<div className="flex-spacer" />
|
<div className="flex-spacer" />
|
||||||
<InlineSpinner active={gasEstimationPending} text="Calculating" />
|
<InlineSpinner
|
||||||
|
active={!hideGasCalculationSpinner && gasEstimationPending}
|
||||||
|
text="Calculating"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
className={gasLimitValidator(raw) ? 'is-valid' : 'is-invalid'}
|
className={gasLimitValidator(raw) ? 'is-valid' : 'is-invalid'}
|
||||||
|
@ -102,6 +102,7 @@ class AdvancedGas extends React.Component<Props, State> {
|
|||||||
<GasLimitField
|
<GasLimitField
|
||||||
customLabel={translateRaw('OFFLINE_STEP2_LABEL_4')}
|
customLabel={translateRaw('OFFLINE_STEP2_LABEL_4')}
|
||||||
disabled={scheduling}
|
disabled={scheduling}
|
||||||
|
hideGasCalculationSpinner={scheduling}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -3,12 +3,17 @@ import React from 'react';
|
|||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { setScheduleGasLimitField, TSetScheduleGasLimitField } from 'actions/transaction';
|
import { setScheduleGasLimitField, TSetScheduleGasLimitField } from 'actions/transaction';
|
||||||
import { translateRaw } from 'translations';
|
import { translateRaw } from 'translations';
|
||||||
import { Input } from 'components/ui';
|
import { Input, InlineSpinner } from 'components/ui';
|
||||||
import { getScheduleGasLimit, isValidScheduleGasLimit } from 'selectors/transaction';
|
import {
|
||||||
|
getScheduleGasLimit,
|
||||||
|
isValidScheduleGasLimit,
|
||||||
|
getGasEstimationPending
|
||||||
|
} from 'selectors/transaction';
|
||||||
import { Wei } from 'libs/units';
|
import { Wei } from 'libs/units';
|
||||||
import { EAC_SCHEDULING_CONFIG } from 'libs/scheduling';
|
import { EAC_SCHEDULING_CONFIG } from 'libs/scheduling';
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
|
gasEstimationPending: boolean;
|
||||||
scheduleGasLimit: any;
|
scheduleGasLimit: any;
|
||||||
validScheduleGasLimit: boolean;
|
validScheduleGasLimit: boolean;
|
||||||
}
|
}
|
||||||
@ -21,12 +26,16 @@ type Props = OwnProps & DispatchProps;
|
|||||||
|
|
||||||
class ScheduleGasLimitFieldClass extends React.Component<Props> {
|
class ScheduleGasLimitFieldClass extends React.Component<Props> {
|
||||||
public render() {
|
public render() {
|
||||||
const { scheduleGasLimit, validScheduleGasLimit } = this.props;
|
const { gasEstimationPending, scheduleGasLimit, validScheduleGasLimit } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="input-group-wrapper">
|
<div className="input-group-wrapper">
|
||||||
<label className="input-group">
|
<label className="input-group">
|
||||||
<div className="input-group-header">{translateRaw('SCHEDULE_GAS_LIMIT')}</div>
|
<div className="input-group-header">
|
||||||
|
{translateRaw('SCHEDULE_GAS_LIMIT')}
|
||||||
|
<div className="flex-spacer" />
|
||||||
|
<InlineSpinner active={gasEstimationPending} text="Calculating" />
|
||||||
|
</div>
|
||||||
<Input
|
<Input
|
||||||
className={!!scheduleGasLimit.raw && !validScheduleGasLimit ? 'invalid' : ''}
|
className={!!scheduleGasLimit.raw && !validScheduleGasLimit ? 'invalid' : ''}
|
||||||
type="number"
|
type="number"
|
||||||
@ -51,6 +60,7 @@ class ScheduleGasLimitFieldClass extends React.Component<Props> {
|
|||||||
|
|
||||||
export const ScheduleGasLimitField = connect(
|
export const ScheduleGasLimitField = connect(
|
||||||
(state: AppState) => ({
|
(state: AppState) => ({
|
||||||
|
gasEstimationPending: getGasEstimationPending(state),
|
||||||
scheduleGasLimit: getScheduleGasLimit(state),
|
scheduleGasLimit: getScheduleGasLimit(state),
|
||||||
validScheduleGasLimit: isValidScheduleGasLimit(state)
|
validScheduleGasLimit: isValidScheduleGasLimit(state)
|
||||||
}),
|
}),
|
||||||
|
@ -15,10 +15,10 @@ import { INode } from 'libs/nodes/INode';
|
|||||||
import { getNodeLib, getOffline, getAutoGasLimitEnabled } from 'selectors/config';
|
import { getNodeLib, getOffline, getAutoGasLimitEnabled } from 'selectors/config';
|
||||||
import { getWalletInst } from 'selectors/wallet';
|
import { getWalletInst } from 'selectors/wallet';
|
||||||
import { getTransaction, IGetTransaction, getCurrentToAddressMessage } from 'selectors/transaction';
|
import { getTransaction, IGetTransaction, getCurrentToAddressMessage } from 'selectors/transaction';
|
||||||
|
import { getSchedulingToggle } from 'containers/Tabs/ScheduleTransaction/selectors/fields';
|
||||||
import {
|
import {
|
||||||
EstimateGasRequestedAction,
|
EstimateGasRequestedAction,
|
||||||
setGasLimitField,
|
setGasLimitField,
|
||||||
estimateGasFailed,
|
|
||||||
estimateGasTimedout,
|
estimateGasTimedout,
|
||||||
estimateGasSucceeded,
|
estimateGasSucceeded,
|
||||||
TypeKeys,
|
TypeKeys,
|
||||||
@ -27,7 +27,10 @@ import {
|
|||||||
SetDataFieldAction,
|
SetDataFieldAction,
|
||||||
SwapEtherToTokenAction,
|
SwapEtherToTokenAction,
|
||||||
SwapTokenToTokenAction,
|
SwapTokenToTokenAction,
|
||||||
SwapTokenToEtherAction
|
SwapTokenToEtherAction,
|
||||||
|
SetSchedulingToggleAction,
|
||||||
|
setScheduleGasLimitField,
|
||||||
|
estimateGasFailed
|
||||||
} from 'actions/transaction';
|
} from 'actions/transaction';
|
||||||
import { TypeKeys as ConfigTypeKeys, ToggleAutoGasLimitAction } from 'actions/config';
|
import { TypeKeys as ConfigTypeKeys, ToggleAutoGasLimitAction } from 'actions/config';
|
||||||
import { IWallet } from 'libs/wallet';
|
import { IWallet } from 'libs/wallet';
|
||||||
@ -104,7 +107,19 @@ export function* estimateGas(): SagaIterator {
|
|||||||
timeout: call(delay, 10000)
|
timeout: call(delay, 10000)
|
||||||
});
|
});
|
||||||
if (gasLimit) {
|
if (gasLimit) {
|
||||||
yield put(setGasLimitField({ raw: gasLimit.toString(), value: gasLimit }));
|
const gasSetOptions = {
|
||||||
|
raw: gasLimit.toString(),
|
||||||
|
value: gasLimit
|
||||||
|
};
|
||||||
|
|
||||||
|
const scheduling: SetSchedulingToggleAction['payload'] = yield select(getSchedulingToggle);
|
||||||
|
|
||||||
|
if (scheduling && scheduling.value) {
|
||||||
|
yield put(setScheduleGasLimitField(gasSetOptions));
|
||||||
|
} else {
|
||||||
|
yield put(setGasLimitField(gasSetOptions));
|
||||||
|
}
|
||||||
|
|
||||||
yield put(estimateGasSucceeded());
|
yield put(estimateGasSucceeded());
|
||||||
} else {
|
} else {
|
||||||
yield put(estimateGasTimedout());
|
yield put(estimateGasTimedout());
|
||||||
|
@ -4,13 +4,15 @@ import BN from 'bn.js';
|
|||||||
import { getNodeLib, getOffline, getAutoGasLimitEnabled } from 'selectors/config';
|
import { getNodeLib, getOffline, getAutoGasLimitEnabled } from 'selectors/config';
|
||||||
import { getWalletInst } from 'selectors/wallet';
|
import { getWalletInst } from 'selectors/wallet';
|
||||||
import { getTransaction, getCurrentToAddressMessage } from 'selectors/transaction';
|
import { getTransaction, getCurrentToAddressMessage } from 'selectors/transaction';
|
||||||
|
import { getSchedulingToggle } from 'containers/Tabs/ScheduleTransaction/selectors/fields';
|
||||||
import {
|
import {
|
||||||
setGasLimitField,
|
setGasLimitField,
|
||||||
estimateGasFailed,
|
estimateGasFailed,
|
||||||
estimateGasSucceeded,
|
estimateGasSucceeded,
|
||||||
TypeKeys,
|
TypeKeys,
|
||||||
estimateGasRequested,
|
estimateGasRequested,
|
||||||
estimateGasTimedout
|
estimateGasTimedout,
|
||||||
|
setScheduleGasLimitField
|
||||||
} from 'actions/transaction';
|
} from 'actions/transaction';
|
||||||
import { makeTransaction, getTransactionFields } from 'libs/transaction';
|
import { makeTransaction, getTransactionFields } from 'libs/transaction';
|
||||||
import {
|
import {
|
||||||
@ -113,6 +115,10 @@ describe('estimateGas*', () => {
|
|||||||
const unsuccessfulGasEstimationResult = {
|
const unsuccessfulGasEstimationResult = {
|
||||||
gasLimit: null
|
gasLimit: null
|
||||||
};
|
};
|
||||||
|
const gasSetOptions = {
|
||||||
|
raw: gasLimit.toString(),
|
||||||
|
value: gasLimit
|
||||||
|
};
|
||||||
|
|
||||||
const gens: { [name: string]: any } = {};
|
const gens: { [name: string]: any } = {};
|
||||||
gens.successCase = cloneableGenerator(estimateGas)();
|
gens.successCase = cloneableGenerator(estimateGas)();
|
||||||
@ -175,15 +181,25 @@ describe('estimateGas*', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should put setGasLimitField', () => {
|
it('should select getSchedulingToggle', () => {
|
||||||
gens.timeOutCase = gens.successCase.clone();
|
gens.timeOutCase = gens.successCase.clone();
|
||||||
expect(gens.successCase.next(successfulGasEstimationResult).value).toEqual(
|
expect(gens.successCase.next(successfulGasEstimationResult).value).toEqual(
|
||||||
put(
|
select(getSchedulingToggle)
|
||||||
setGasLimitField({
|
);
|
||||||
raw: gasLimit.toString(),
|
});
|
||||||
value: gasLimit
|
|
||||||
})
|
it('should put setGasLimitField', () => {
|
||||||
)
|
gens.scheduleCase = gens.successCase.clone();
|
||||||
|
const notScheduling = null as any;
|
||||||
|
expect(gens.successCase.next(notScheduling).value).toEqual(
|
||||||
|
put(setGasLimitField(gasSetOptions))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should put setScheduleGasLimitField', () => {
|
||||||
|
const scheduling = { value: true } as any;
|
||||||
|
expect(gens.scheduleCase.next(scheduling).value).toEqual(
|
||||||
|
put(setScheduleGasLimitField(gasSetOptions))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user