mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-02-10 10:07:00 +00:00
[FEATURE] Add Window Size field.
This commit is contained in:
parent
09b1062db1
commit
68cc3182ca
@ -12,6 +12,7 @@ import {
|
||||
ResetAction,
|
||||
SetGasPriceFieldAction,
|
||||
SetTimeBountyFieldAction,
|
||||
SetWindowSizeFieldAction,
|
||||
SetWindowStartFieldAction,
|
||||
SetScheduleTimestampFieldAction,
|
||||
SetScheduleTypeAction
|
||||
@ -92,6 +93,14 @@ const setGasPriceField = (payload: SetGasPriceFieldAction['payload']): SetGasPri
|
||||
payload
|
||||
});
|
||||
|
||||
type TSetWindowSizeField = typeof setWindowSizeField;
|
||||
const setWindowSizeField = (
|
||||
payload: SetWindowSizeFieldAction['payload']
|
||||
): SetWindowSizeFieldAction => ({
|
||||
type: TypeKeys.WINDOW_SIZE_FIELD_SET,
|
||||
payload
|
||||
});
|
||||
|
||||
type TSetWindowStartField = typeof setWindowStartField;
|
||||
const setWindowStartField = (
|
||||
payload: SetWindowStartFieldAction['payload']
|
||||
@ -132,6 +141,7 @@ export {
|
||||
TSetNonceField,
|
||||
TSetValueField,
|
||||
TSetGasPriceField,
|
||||
TSetWindowSizeField,
|
||||
TSetWindowStartField,
|
||||
TSetTimeBountyField,
|
||||
TSetScheduleTimestampField,
|
||||
@ -149,6 +159,7 @@ export {
|
||||
setNonceField,
|
||||
setValueField,
|
||||
setGasPriceField,
|
||||
setWindowSizeField,
|
||||
setWindowStartField,
|
||||
setScheduleTimestampField,
|
||||
setScheduleType,
|
||||
|
@ -5,6 +5,7 @@ export * from './sign';
|
||||
export * from './broadcast';
|
||||
export * from './current';
|
||||
export * from './timeBounty';
|
||||
export * from './windowSize';
|
||||
export * from './windowStart';
|
||||
export * from './scheduleTimestamp';
|
||||
export * from './scheduleType';
|
||||
|
12
common/actions/transaction/actionCreators/windowSize.ts
Normal file
12
common/actions/transaction/actionCreators/windowSize.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { SetCurrentWindowSizeAction } from '../actionTypes/windowSize';
|
||||
import { TypeKeys } from '../';
|
||||
|
||||
type TSetCurrentWindowSize = typeof setCurrentWindowSize;
|
||||
const setCurrentWindowSize = (
|
||||
payload: SetCurrentWindowSizeAction['payload']
|
||||
): SetCurrentWindowSizeAction => ({
|
||||
type: TypeKeys.CURRENT_WINDOW_SIZE_SET,
|
||||
payload
|
||||
});
|
||||
|
||||
export { setCurrentWindowSize, TSetCurrentWindowSize };
|
@ -91,6 +91,14 @@ interface SetValueFieldAction {
|
||||
};
|
||||
}
|
||||
|
||||
interface SetWindowSizeFieldAction {
|
||||
type: TypeKeys.WINDOW_SIZE_FIELD_SET;
|
||||
payload: {
|
||||
raw: string;
|
||||
value: number | null;
|
||||
};
|
||||
}
|
||||
|
||||
interface SetWindowStartFieldAction {
|
||||
type: TypeKeys.WINDOW_START_FIELD_SET;
|
||||
payload: {
|
||||
@ -125,6 +133,7 @@ type FieldAction =
|
||||
| SetValueFieldAction
|
||||
| SetGasPriceFieldAction
|
||||
| SetTimeBountyFieldAction
|
||||
| SetWindowSizeFieldAction
|
||||
| SetWindowStartFieldAction
|
||||
| SetScheduleTimestampFieldAction
|
||||
| SetScheduleTypeAction;
|
||||
@ -146,6 +155,7 @@ export {
|
||||
InputFieldAction,
|
||||
SetGasPriceFieldAction,
|
||||
SetTimeBountyFieldAction,
|
||||
SetWindowSizeFieldAction,
|
||||
SetWindowStartFieldAction,
|
||||
SetScheduleTimestampFieldAction,
|
||||
SetScheduleTypeAction
|
||||
|
12
common/actions/transaction/actionTypes/windowSize.ts
Normal file
12
common/actions/transaction/actionTypes/windowSize.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { TypeKeys } from '../constants';
|
||||
|
||||
/* user input */
|
||||
|
||||
interface SetCurrentWindowSizeAction {
|
||||
type: TypeKeys.CURRENT_WINDOW_SIZE_SET;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
type CurrentAction = SetCurrentWindowSizeAction;
|
||||
|
||||
export { SetCurrentWindowSizeAction, CurrentAction };
|
@ -26,6 +26,7 @@ export enum TypeKeys {
|
||||
CURRENT_VALUE_SET = 'CURRENT_VALUE_SET',
|
||||
CURRENT_TO_SET = 'CURRENT_TO_SET',
|
||||
CURRENT_TIME_BOUNTY_SET = 'CURRENT_TIME_BOUNTY_SET',
|
||||
CURRENT_WINDOW_SIZE_SET = 'CURRENT_WINDOW_SIZE_SET',
|
||||
CURRENT_WINDOW_START_SET = 'CURRENT_WINDOW_START_SET',
|
||||
CURRENT_SCHEDULE_TIMESTAMP_SET = 'CURRENT_SCHEDULE_TIMESTAMP_SET',
|
||||
CURRENT_SCHEDULE_TYPE = 'CURRENT_SCHEDULE_TYPE',
|
||||
@ -45,6 +46,7 @@ export enum TypeKeys {
|
||||
NONCE_FIELD_SET = 'NONCE_FIELD_SET',
|
||||
GAS_PRICE_FIELD_SET = 'GAS_PRICE_FIELD_SET',
|
||||
TIME_BOUNTY_FIELD_SET = 'TIME_BOUNTY_FIELD_SET',
|
||||
WINDOW_SIZE_FIELD_SET = 'WINDOW_SIZE_FIELD_SET',
|
||||
WINDOW_START_FIELD_SET = 'WINDOW_START_FIELD_SET',
|
||||
SCHEDULE_TIMESTAMP_FIELD_SET = 'SCHEDULE_TIMESTAMP_FIELD_SET',
|
||||
SCHEDULE_TIMEZONE_SET = 'SCHEDULE_TIMEZONE_SET',
|
||||
|
@ -25,7 +25,7 @@ const TransactionSucceeded = ({ txHash, blockExplorer, scheduling }: Transaction
|
||||
if (scheduling) {
|
||||
scheduleDetailsBtn = (
|
||||
<a href={getTXDetailsCheckURL(txHash)} className="btn btn-xs">
|
||||
{translate('SCHEDULE_check')}
|
||||
{translate('SCHEDULE_CHECK')}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class ScheduleTimezoneDropDownClass extends Component<DispatchProps> {
|
||||
return (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('SCHEDULE_timezone')}</div>
|
||||
<div className="input-group-header">{translate('SCHEDULE_TIMEZONE')}</div>
|
||||
<Query
|
||||
params={['readOnly']}
|
||||
withQuery={({ readOnly }) => (
|
||||
|
@ -33,7 +33,7 @@ class ScheduleTypeClass extends Component<Props> {
|
||||
onChange={this.handleOnChange}
|
||||
checked={currentScheduleType.value === 'time'}
|
||||
/>
|
||||
{translate('SCHEDULE_type_time')}
|
||||
{translate('SCHEDULE_TYPE_TIME')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -47,7 +47,7 @@ class ScheduleTypeClass extends Component<Props> {
|
||||
onChange={this.handleOnChange}
|
||||
checked={currentScheduleType.value === 'block'}
|
||||
/>
|
||||
{translate('SCHEDULE_type_block')}
|
||||
{translate('SCHEDULE_TYPE_BLOCK')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -21,6 +21,7 @@ export type Param =
|
||||
| 'value'
|
||||
| 'gaslimit'
|
||||
| 'limit'
|
||||
| 'windowSize'
|
||||
| 'windowStart'
|
||||
| 'scheduleTimestamp'
|
||||
| 'timeBounty';
|
||||
|
@ -12,12 +12,12 @@ export const TimeBountyField: React.SFC<Props> = ({ isReadOnly }) => (
|
||||
withProps={({ currentTimeBounty, isValid, onChange, readOnly }) => (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('SCHEDULE_timebounty')}</div>
|
||||
<div className="input-group-header">{translate('SCHEDULE_TIMEBOUNTY')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${isValid ? '' : 'invalid'}`}
|
||||
type="text"
|
||||
value={currentTimeBounty.raw}
|
||||
placeholder={translateRaw('SCHEDULE_timebounty_placeholder')}
|
||||
placeholder={translateRaw('SCHEDULE_TIMEBOUNTY_PLACEHOLDER')}
|
||||
readOnly={!!(isReadOnly || readOnly)}
|
||||
spellCheck={false}
|
||||
onChange={onChange}
|
||||
|
@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { Input } from 'components/ui';
|
||||
import { WindowSizeFieldFactory } from './WindowSizeFieldFactory';
|
||||
|
||||
interface Props {
|
||||
isReadOnly?: boolean;
|
||||
}
|
||||
|
||||
export const WindowSizeField: React.SFC<Props> = ({ isReadOnly }) => (
|
||||
<WindowSizeFieldFactory
|
||||
withProps={({ currentWindowSize, isValid, onChange, readOnly }) => (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('SCHEDULE_WINDOW_SIZE_BLOCKS')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${isValid ? '' : 'invalid'}`}
|
||||
type="text"
|
||||
value={currentWindowSize.raw}
|
||||
placeholder={translateRaw('SCHEDULE_WINDOW_SIZE_BLOCKS_PLACEHOLDER')}
|
||||
readOnly={!!(isReadOnly || readOnly)}
|
||||
spellCheck={false}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
);
|
@ -0,0 +1,61 @@
|
||||
import { Query } from 'components/renderCbs';
|
||||
import { setCurrentWindowSize, TSetCurrentWindowSize } from 'actions/transaction';
|
||||
import { WindowSizeInputFactory } from './WindowSizeInputFactory';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { ICurrentWindowSize } from 'selectors/transaction';
|
||||
|
||||
interface DispatchProps {
|
||||
setCurrentWindowSize: TSetCurrentWindowSize;
|
||||
}
|
||||
|
||||
interface OwnProps {
|
||||
windowSize: string | null;
|
||||
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
||||
}
|
||||
|
||||
export interface CallbackProps {
|
||||
isValid: boolean;
|
||||
readOnly: boolean;
|
||||
currentWindowSize: ICurrentWindowSize;
|
||||
onChange(ev: React.FormEvent<HTMLInputElement>): void;
|
||||
}
|
||||
|
||||
type Props = DispatchProps & OwnProps;
|
||||
|
||||
class WindowSizeFieldFactoryClass extends React.Component<Props> {
|
||||
public componentDidMount() {
|
||||
const { windowSize } = this.props;
|
||||
if (windowSize) {
|
||||
this.props.setCurrentWindowSize(windowSize);
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<WindowSizeInputFactory onChange={this.setWindowSize} withProps={this.props.withProps} />
|
||||
);
|
||||
}
|
||||
|
||||
private setWindowSize = (ev: React.FormEvent<HTMLInputElement>) => {
|
||||
const { value } = ev.currentTarget;
|
||||
this.props.setCurrentWindowSize(value);
|
||||
};
|
||||
}
|
||||
|
||||
const WindowSizeFieldFactory = connect(null, { setCurrentWindowSize })(WindowSizeFieldFactoryClass);
|
||||
|
||||
interface DefaultWindowSizeFieldProps {
|
||||
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
||||
}
|
||||
|
||||
const DefaultWindowSizeField: React.SFC<DefaultWindowSizeFieldProps> = ({ withProps }) => (
|
||||
<Query
|
||||
params={['windowSize']}
|
||||
withQuery={({ windowSize }) => (
|
||||
<WindowSizeFieldFactory windowSize={windowSize} withProps={withProps} />
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
export { DefaultWindowSizeField as WindowSizeFieldFactory };
|
@ -0,0 +1,54 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Query } from 'components/renderCbs';
|
||||
import {
|
||||
getCurrentWindowSize,
|
||||
ICurrentWindowSize,
|
||||
isValidCurrentWindowSize
|
||||
} from 'selectors/transaction';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import { getResolvingDomain } from 'selectors/ens';
|
||||
import { CallbackProps } from './WindowSizeFieldFactory';
|
||||
|
||||
interface StateProps {
|
||||
currentWindowSize: ICurrentWindowSize;
|
||||
isValid: boolean;
|
||||
isResolving: boolean;
|
||||
}
|
||||
|
||||
interface OwnProps {
|
||||
onChange(ev: React.FormEvent<HTMLInputElement>): void;
|
||||
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
||||
}
|
||||
|
||||
type Props = OwnProps & StateProps;
|
||||
|
||||
class WindowSizeInputFactoryClass extends Component<Props> {
|
||||
public render() {
|
||||
const { currentWindowSize, onChange, isValid, withProps } = this.props;
|
||||
|
||||
return (
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-11">
|
||||
<Query
|
||||
params={['readOnly']}
|
||||
withQuery={({ readOnly }) =>
|
||||
withProps({
|
||||
currentWindowSize,
|
||||
isValid,
|
||||
onChange,
|
||||
readOnly: !!readOnly || this.props.isResolving
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const WindowSizeInputFactory = connect((state: AppState) => ({
|
||||
currentWindowSize: getCurrentWindowSize(state),
|
||||
isResolving: getResolvingDomain(state),
|
||||
isValid: isValidCurrentWindowSize(state)
|
||||
}))(WindowSizeInputFactoryClass);
|
@ -0,0 +1 @@
|
||||
export * from './WindowSizeFieldFactory';
|
@ -12,12 +12,12 @@ export const WindowStartField: React.SFC<Props> = ({ isReadOnly }) => (
|
||||
withProps={({ currentWindowStart, isValid, onChange, readOnly }) => (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('SCHEDULE_block')}</div>
|
||||
<div className="input-group-header">{translate('SCHEDULE_BLOCK')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${isValid ? '' : 'invalid'}`}
|
||||
type="text"
|
||||
value={currentWindowStart.raw}
|
||||
placeholder={translate('SCHEDULE_block_placeholder', true)}
|
||||
placeholder={translateRaw('SCHEDULE_BLOCK_PLACEHOLDER')}
|
||||
readOnly={!!(isReadOnly || readOnly)}
|
||||
spellCheck={false}
|
||||
onChange={onChange}
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import { getResolvingDomain } from 'selectors/ens';
|
||||
import { CallbackProps } from 'containers/Tabs/ScheduleTransaction/components/Fields/WindowStart/WindowStartFieldFactory';
|
||||
import { CallbackProps } from './WindowStartFieldFactory';
|
||||
|
||||
interface StateProps {
|
||||
currentWindowStart: ICurrentWindowStart;
|
||||
|
@ -7,7 +7,7 @@ export const GenerateScheduleTransactionButton: React.SFC<{}> = () => {
|
||||
<ScheduleTransactionFactory
|
||||
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
||||
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
|
||||
{isWeb3Wallet ? translate('SCHEDULE_schedule') : translate('DEP_signtx')}
|
||||
{isWeb3Wallet ? translate('SCHEDULE_SCHEDULE') : translate('DEP_signtx')}
|
||||
</button>
|
||||
)}
|
||||
/>
|
||||
|
@ -22,7 +22,7 @@ export const SendScheduleTransactionButton: React.SFC<{
|
||||
!!signing ? (signTx(), openModal()) : openModal();
|
||||
}}
|
||||
>
|
||||
{translate('SCHEDULE_schedule')}
|
||||
{translate('SCHEDULE_SCHEDULE')}
|
||||
</button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
@ -1,2 +1,3 @@
|
||||
export * from './Fields/WindowStart/WindowStartField';
|
||||
export * from './Fields/TimeBounty/TimeBountyField';
|
||||
export * from './Fields/WindowSize/WindowSizeField';
|
||||
|
@ -0,0 +1,23 @@
|
||||
import { setWindowSizeField } from 'actions/transaction/actionCreators/fields';
|
||||
import { call, put, takeLatest } from 'redux-saga/effects';
|
||||
import { SagaIterator } from 'redux-saga';
|
||||
import { TypeKeys } from 'actions/transaction/constants';
|
||||
import { SetWindowSizeFieldAction } from 'actions/transaction';
|
||||
import { SetCurrentWindowSizeAction } from 'actions/transaction/actionTypes/windowSize';
|
||||
|
||||
export function* setCurrentWindowSize({ payload: raw }: SetCurrentWindowSizeAction): SagaIterator {
|
||||
let value: number | null = null;
|
||||
|
||||
value = parseInt(raw, 10);
|
||||
|
||||
yield call(setField, { value, raw });
|
||||
}
|
||||
|
||||
export function* setField(payload: SetWindowSizeFieldAction['payload']) {
|
||||
yield put(setWindowSizeField(payload));
|
||||
}
|
||||
|
||||
export const currentWindowSize = takeLatest(
|
||||
[TypeKeys.CURRENT_WINDOW_SIZE_SET],
|
||||
setCurrentWindowSize
|
||||
);
|
@ -1,8 +1,10 @@
|
||||
import { currentWindowSize } from './currentWindowSize';
|
||||
import { currentWindowStart } from './currentWindowStart';
|
||||
import { currentScheduleTimestamp } from './currentScheduleTimestamp';
|
||||
import { currentTimeBounty } from './currentTimeBounty';
|
||||
|
||||
export const schedulingCurrentSagas = [
|
||||
currentWindowSize,
|
||||
currentWindowStart,
|
||||
currentScheduleTimestamp,
|
||||
currentTimeBounty
|
||||
|
@ -14,7 +14,6 @@ export const EAC_SCHEDULING_CONFIG = {
|
||||
TIME_BOUNTY_MIN,
|
||||
TIME_BOUNTY_DEFAULT: TIME_BOUNTY_MIN,
|
||||
TIME_BOUNTY_MAX: toWei('900', Units.ether.length - 1), // 900 ETH
|
||||
WINDOW_SIZE_IN_BLOCKS: 90,
|
||||
SCHEDULE_TIMESTAMP_FORMAT: 'YYYY-MM-DD HH:mm:ss',
|
||||
DEFAULT_SCHEDULING_METHOD: 'time'
|
||||
};
|
||||
@ -54,13 +53,20 @@ export const getScheduleData = (
|
||||
callData = '',
|
||||
callGas: number,
|
||||
callValue: BN | null,
|
||||
windowSize: number,
|
||||
windowSize: number | null,
|
||||
windowStart: any,
|
||||
gasPrice: BN | null,
|
||||
timeBounty: BN | null,
|
||||
requiredDeposit: any
|
||||
) => {
|
||||
if (!callValue || !gasPrice || !windowStart || !timeBounty || timeBounty.lt(new BN(0))) {
|
||||
if (
|
||||
!callValue ||
|
||||
!gasPrice ||
|
||||
!windowStart ||
|
||||
!windowSize ||
|
||||
!timeBounty ||
|
||||
timeBounty.lt(new BN(0))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ const INITIAL_STATE: State = {
|
||||
data: { raw: '', value: null },
|
||||
nonce: { raw: '', value: null },
|
||||
value: { raw: '', value: null },
|
||||
windowSize: { raw: '', value: null },
|
||||
windowStart: { raw: '', value: null },
|
||||
scheduleTimestamp: { raw: '', value: null },
|
||||
gasLimit: { raw: '21000', value: new BN(21000) },
|
||||
@ -82,6 +83,8 @@ export const fields = (
|
||||
return updateField('gasPrice')(state, action);
|
||||
case TK.TIME_BOUNTY_FIELD_SET:
|
||||
return updateField('timeBounty')(state, action);
|
||||
case TK.WINDOW_SIZE_FIELD_SET:
|
||||
return updateField('windowSize')(state, action);
|
||||
case TK.WINDOW_START_FIELD_SET:
|
||||
return updateField('windowStart')(state, action);
|
||||
case TK.SCHEDULE_TIMESTAMP_FIELD_SET:
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
SetDataFieldAction,
|
||||
SetNonceFieldAction,
|
||||
SetGasLimitFieldAction,
|
||||
SetWindowSizeFieldAction,
|
||||
SetWindowStartFieldAction,
|
||||
SetScheduleTimestampFieldAction,
|
||||
SetScheduleTypeAction
|
||||
@ -17,6 +18,7 @@ export interface State {
|
||||
gasLimit: SetGasLimitFieldAction['payload'];
|
||||
gasPrice: { raw: string; value: Wei };
|
||||
timeBounty: { raw: string; value: Wei };
|
||||
windowSize: SetWindowSizeFieldAction['payload'];
|
||||
windowStart: SetWindowStartFieldAction['payload'];
|
||||
scheduleTimestamp: SetScheduleTimestampFieldAction['payload'];
|
||||
scheduleType: SetScheduleTypeAction['payload'];
|
||||
|
@ -11,6 +11,7 @@ const getGasPrice = (state: AppState) => getFields(state).gasPrice;
|
||||
const getValue = (state: AppState) => getFields(state).value;
|
||||
const getNonce = (state: AppState) => getFields(state).nonce;
|
||||
const getTimeBounty = (state: AppState) => getFields(state).timeBounty;
|
||||
const getWindowSize = (state: AppState) => getFields(state).windowSize;
|
||||
const getWindowStart = (state: AppState) => getFields(state).windowStart;
|
||||
const getScheduleTimestamp = (state: AppState) => getFields(state).scheduleTimestamp;
|
||||
const getScheduleType = (state: AppState) => getFields(state).scheduleType;
|
||||
@ -41,6 +42,7 @@ export {
|
||||
getDataExists,
|
||||
getValidGasCost,
|
||||
getTimeBounty,
|
||||
getWindowSize,
|
||||
getWindowStart,
|
||||
getScheduleTimestamp,
|
||||
getScheduleType
|
||||
|
@ -30,6 +30,7 @@ export const isFullTx = (
|
||||
const partialParamsToCheck = { ...rest };
|
||||
|
||||
delete partialParamsToCheck.windowStart;
|
||||
delete partialParamsToCheck.windowSize;
|
||||
delete partialParamsToCheck.scheduleTimestamp;
|
||||
|
||||
const validPartialParams = Object.values(partialParamsToCheck).reduce<boolean>(
|
||||
@ -61,6 +62,12 @@ export const isFullTx = (
|
||||
}
|
||||
};
|
||||
|
||||
export const isWindowSizeValid = (transactionFields: AppState['transaction']['fields']) => {
|
||||
const { windowSize } = transactionFields;
|
||||
|
||||
return Boolean(windowSize && windowSize.value);
|
||||
};
|
||||
|
||||
export const isWindowStartValid = (
|
||||
transactionFields: AppState['transaction']['fields'],
|
||||
latestBlock: string
|
||||
|
@ -4,6 +4,7 @@ export * from './fields';
|
||||
export * from './meta';
|
||||
export * from './sign';
|
||||
export * from './current';
|
||||
export * from './windowSize';
|
||||
export * from './windowStart';
|
||||
export * from './timeBounty';
|
||||
export * from './scheduleTimestamp';
|
||||
|
@ -6,7 +6,8 @@ import {
|
||||
getWindowStart,
|
||||
getNonce,
|
||||
getTimeBounty,
|
||||
getScheduleType
|
||||
getScheduleType,
|
||||
getWindowSize
|
||||
} from './fields';
|
||||
import { makeTransaction, IHexStrTransaction } from 'libs/transaction';
|
||||
import EthTx from 'ethereumjs-tx';
|
||||
@ -15,7 +16,8 @@ import {
|
||||
reduceToValues,
|
||||
isFullTx,
|
||||
isWindowStartValid,
|
||||
isScheduleTimestampValid
|
||||
isScheduleTimestampValid,
|
||||
isWindowSizeValid
|
||||
} from 'selectors/transaction/helpers';
|
||||
import {
|
||||
getGasPrice,
|
||||
@ -75,23 +77,26 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
|
||||
const validGasCost = getValidGasCost(state);
|
||||
const scheduleType = getScheduleType(state);
|
||||
const windowStart = getWindowStart(state);
|
||||
const windowSize = getWindowSize(state);
|
||||
const gasLimit = getGasLimit(state);
|
||||
const nonce = getNonce(state);
|
||||
const gasPrice = getGasPrice(state);
|
||||
const timeBounty = getTimeBounty(state);
|
||||
const windowSizeValid = isWindowSizeValid(transactionFields);
|
||||
const windowStartValid = isWindowStartValid(transactionFields, getLatestBlock(state));
|
||||
const scheduleTimestampValid = isScheduleTimestampValid(transactionFields);
|
||||
|
||||
const isFullTransaction =
|
||||
isFullTx(state, transactionFields, currentTo, currentValue, dataExists, validGasCost, unit) &&
|
||||
(windowStartValid || scheduleTimestampValid);
|
||||
(windowStartValid || scheduleTimestampValid) &&
|
||||
windowSizeValid;
|
||||
|
||||
const transactionData = getScheduleData(
|
||||
currentTo.raw,
|
||||
callData.raw,
|
||||
parseInt(gasLimit.raw, 10),
|
||||
currentValue.value,
|
||||
EAC_SCHEDULING_CONFIG.WINDOW_SIZE_IN_BLOCKS,
|
||||
windowSize.value,
|
||||
windowStart.value,
|
||||
gasPrice.value,
|
||||
timeBounty.value,
|
||||
|
17
common/selectors/transaction/windowSize.ts
Normal file
17
common/selectors/transaction/windowSize.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { AppState } from 'reducers';
|
||||
import { getWindowSize } from './fields';
|
||||
|
||||
interface ICurrentWindowSize {
|
||||
raw: string;
|
||||
value: number | null;
|
||||
}
|
||||
|
||||
const isValidCurrentWindowSize = (state: AppState) => {
|
||||
const currentWindowSize = getWindowSize(state);
|
||||
|
||||
return currentWindowSize && currentWindowSize.value && currentWindowSize.value > 0;
|
||||
};
|
||||
|
||||
const getCurrentWindowSize = (state: AppState): ICurrentWindowSize => getWindowSize(state);
|
||||
|
||||
export { getCurrentWindowSize, ICurrentWindowSize, isValidCurrentWindowSize };
|
@ -17,6 +17,7 @@ describe('fields reducer', () => {
|
||||
raw: fromWei(EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT, 'ether'),
|
||||
value: EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT
|
||||
},
|
||||
windowSize: { raw: '', value: null },
|
||||
windowStart: { raw: '', value: null },
|
||||
scheduleTimestamp: { raw: '', value: null },
|
||||
scheduleType: {
|
||||
|
@ -44,6 +44,10 @@ describe('fields selector', () => {
|
||||
raw: '1500',
|
||||
value: Wei('1500')
|
||||
},
|
||||
windowSize: {
|
||||
raw: '',
|
||||
value: null
|
||||
},
|
||||
windowStart: {
|
||||
raw: '',
|
||||
value: null
|
||||
|
@ -48,6 +48,10 @@ describe('helpers selector', () => {
|
||||
raw: '1500',
|
||||
value: Wei('1500')
|
||||
},
|
||||
windowSize: {
|
||||
raw: '',
|
||||
value: null
|
||||
},
|
||||
windowStart: {
|
||||
raw: '',
|
||||
value: null
|
||||
@ -72,6 +76,7 @@ describe('helpers selector', () => {
|
||||
to: new Buffer([0, 1, 2, 3]),
|
||||
value: Wei('1000000000'),
|
||||
timeBounty: Wei('1500'),
|
||||
windowSize: null,
|
||||
windowStart: null,
|
||||
scheduleTimestamp: null,
|
||||
scheduleType: 'time'
|
||||
|
Loading…
x
Reference in New Issue
Block a user