diff --git a/common/actions/transaction/actionCreators/fields.ts b/common/actions/transaction/actionCreators/fields.ts
index 6df955db..0660cc3e 100644
--- a/common/actions/transaction/actionCreators/fields.ts
+++ b/common/actions/transaction/actionCreators/fields.ts
@@ -20,7 +20,8 @@ import {
SetScheduleTimezoneAction,
SetScheduleGasPriceFieldAction,
SetScheduleGasLimitFieldAction,
- SetScheduleDepositFieldAction
+ SetScheduleDepositFieldAction,
+ SetScheduleParamsValidityAction
} from '../actionTypes';
import { TypeKeys } from 'actions/transaction/constants';
@@ -162,6 +163,12 @@ const setScheduleDepositField = (payload: SetScheduleDepositFieldAction['payload
payload
});
+type TSetScheduleParamsValidity = typeof setScheduleParamsValidity;
+const setScheduleParamsValidity = (payload: SetScheduleParamsValidityAction['payload']) => ({
+ type: TypeKeys.SCHEDULE_PARAMS_VALIDITY_SET,
+ payload
+});
+
type TReset = typeof reset;
const reset = (payload: ResetAction['payload'] = { include: {}, exclude: {} }): ResetAction => ({
type: TypeKeys.RESET,
@@ -190,6 +197,7 @@ export {
TSetScheduleGasPriceField,
TSetScheduleGasLimitField,
TSetScheduleDepositField,
+ TSetScheduleParamsValidity,
TReset,
inputGasLimit,
inputGasPrice,
@@ -212,5 +220,6 @@ export {
setScheduleGasPriceField,
setScheduleGasLimitField,
setScheduleDepositField,
+ setScheduleParamsValidity,
reset
};
diff --git a/common/actions/transaction/actionTypes/fields.ts b/common/actions/transaction/actionTypes/fields.ts
index c7de7d8c..cf2b0469 100644
--- a/common/actions/transaction/actionTypes/fields.ts
+++ b/common/actions/transaction/actionTypes/fields.ts
@@ -163,6 +163,14 @@ interface SetScheduleDepositFieldAction {
};
}
+interface SetScheduleParamsValidityAction {
+ type: TypeKeys.SCHEDULE_PARAMS_VALIDITY_SET;
+ payload: {
+ raw: boolean;
+ value: boolean;
+ };
+}
+
type InputFieldAction = InputNonceAction | InputGasLimitAction | InputDataAction;
type FieldAction =
@@ -181,7 +189,8 @@ type FieldAction =
| SetScheduleGasPriceFieldAction
| SetScheduleGasLimitFieldAction
| SetScheduleDepositFieldAction
- | SetScheduleTimezoneAction;
+ | SetScheduleTimezoneAction
+ | SetScheduleParamsValidityAction;
export {
InputGasLimitAction,
@@ -208,5 +217,6 @@ export {
SetScheduleGasPriceFieldAction,
SetScheduleGasLimitFieldAction,
SetScheduleDepositFieldAction,
- SetScheduleTimezoneAction
+ SetScheduleTimezoneAction,
+ SetScheduleParamsValidityAction
};
diff --git a/common/actions/transaction/constants.ts b/common/actions/transaction/constants.ts
index 9480442b..f07ff6c0 100644
--- a/common/actions/transaction/constants.ts
+++ b/common/actions/transaction/constants.ts
@@ -57,6 +57,7 @@ export enum TypeKeys {
SCHEDULE_TYPE_SET = 'SCHEDULE_TYPE_SET',
SCHEDULING_TOGGLE_SET = 'SCHEDULING_TOGGLE_SET',
SCHEDULE_DEPOSIT_FIELD_SET = 'SCHEDULE_DEPOSIT_FIELD_SET',
+ SCHEDULE_PARAMS_VALIDITY_SET = 'SCHEDULE_PARAMS_VALIDITY_SET',
TOKEN_TO_META_SET = 'TOKEN_TO_META_SET',
UNIT_META_SET = 'UNIT_META_SET',
diff --git a/common/containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButton.tsx b/common/containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButton.tsx
index 8291d74f..3fdf26d4 100644
--- a/common/containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButton.tsx
+++ b/common/containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButton.tsx
@@ -1,32 +1,48 @@
-import React from 'react';
+import React, { Component } from 'react';
import translate from 'translations';
import { ConfirmationModal } from 'components/ConfirmationModal';
import { SigningStatus } from 'components';
import { SendScheduleTransactionButtonFactory } from 'containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButtonFactory';
+import { connect } from 'react-redux';
+import { AppState } from 'reducers';
+import { getScheduleParamsValidity } from 'selectors/transaction';
-export const SendScheduleTransactionButton: React.SFC<{
+interface Props {
className?: string;
signing?: boolean;
customModal?: typeof ConfirmationModal;
-}> = ({ signing, customModal, className }) => (
-
- (
-
-
-
- )}
- />
-
-
-);
+ paramsValidity: boolean;
+}
+
+class SendScheduleTransactionButtonClass extends Component {
+ public render() {
+ const { className, customModal, paramsValidity, signing } = this.props;
+
+ return (
+
+ (
+
+
+
+ )}
+ />
+
+
+ );
+ }
+}
+
+export const SendScheduleTransactionButton = connect((state: AppState) => ({
+ paramsValidity: getScheduleParamsValidity(state).value
+}))(SendScheduleTransactionButtonClass);
diff --git a/common/containers/Tabs/ScheduleTransaction/sagas/transaction/network/index.ts b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/network/index.ts
new file mode 100644
index 00000000..74378fb8
--- /dev/null
+++ b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/network/index.ts
@@ -0,0 +1,3 @@
+import { schedulingParamsValidity } from './paramsValidity';
+
+export const schedulingTransactionNetworkSagas = [schedulingParamsValidity];
diff --git a/common/containers/Tabs/ScheduleTransaction/sagas/transaction/network/paramsValidity.ts b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/network/paramsValidity.ts
new file mode 100644
index 00000000..e0db1d61
--- /dev/null
+++ b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/network/paramsValidity.ts
@@ -0,0 +1,149 @@
+import { SagaIterator, delay } from 'redux-saga';
+import { select, fork, call, take, apply, put } from 'redux-saga/effects';
+import { getOffline, getNodeLib } from 'selectors/config';
+import {
+ ICurrentSchedulingToggle,
+ ICurrentWindowSize
+} from 'containers/Tabs/ScheduleTransaction/selectors';
+import {
+ getSchedulingToggle,
+ getScheduleTimestamp,
+ getScheduleTimezone
+} from '../../../selectors/fields';
+import {
+ TypeKeys,
+ SetScheduleParamsValidityAction,
+ setScheduleParamsValidity
+} from 'actions/transaction';
+import {
+ getCurrentTo,
+ getCurrentValue,
+ getData,
+ getScheduleType,
+ getWindowStart,
+ getWindowSize,
+ getTimeBounty,
+ getScheduleGasPrice,
+ getScheduleGasLimit,
+ getScheduleDeposit
+} from 'selectors/transaction';
+import { getWalletInst } from 'selectors/wallet';
+import {
+ EAC_SCHEDULING_CONFIG,
+ calcEACEndowment,
+ getValidateRequestParamsData,
+ EAC_ADDRESSES,
+ parseSchedulingParametersValidity
+} from 'libs/scheduling';
+import { gasPriceToBase } from 'libs/units';
+import BN from 'bn.js';
+import { bufferToHex } from 'ethereumjs-util';
+import RequestFactory from 'libs/scheduling/contracts/RequestFactory';
+import { dateTimeToUnixTimestamp, windowSizeBlockToMin } from 'selectors/transaction/helpers';
+
+export function* shouldValidateParams(): SagaIterator {
+ while (true) {
+ yield take([
+ TypeKeys.TO_FIELD_SET,
+ TypeKeys.DATA_FIELD_SET,
+ TypeKeys.CURRENT_TIME_BOUNTY_SET,
+ TypeKeys.WINDOW_SIZE_FIELD_SET,
+ TypeKeys.WINDOW_START_FIELD_SET,
+ TypeKeys.SCHEDULE_TIMESTAMP_FIELD_SET,
+ TypeKeys.TIME_BOUNTY_FIELD_SET,
+ TypeKeys.SCHEDULE_TYPE_SET,
+ TypeKeys.SCHEDULING_TOGGLE_SET,
+ TypeKeys.SCHEDULE_TIMEZONE_SET
+ ]);
+
+ yield call(delay, 250);
+
+ const isOffline: boolean = yield select(getOffline);
+ const schedulingToggle: ICurrentSchedulingToggle = yield select(getSchedulingToggle);
+ const scheduling = Boolean(schedulingToggle && schedulingToggle.value);
+
+ if (isOffline || !scheduling) {
+ continue;
+ }
+
+ yield call(checkSchedulingParametersValidity);
+ }
+}
+
+function* checkSchedulingParametersValidity() {
+ const currentTo = yield select(getCurrentTo);
+ const currentValue = yield select(getCurrentValue);
+ const callData = yield select(getData);
+ const scheduleType = yield select(getScheduleType);
+ const windowStart = yield select(getWindowStart);
+ const windowSize: ICurrentWindowSize = yield select(getWindowSize);
+ const timeBounty = yield select(getTimeBounty);
+ const scheduleGasPrice = yield select(getScheduleGasPrice);
+ const scheduleGasLimit = yield select(getScheduleGasLimit);
+ const deposit = yield select(getScheduleDeposit);
+ const node = yield select(getNodeLib);
+ const wallet = yield select(getWalletInst);
+ const scheduleTimestamp = yield select(getScheduleTimestamp);
+ const scheduleTimezone = yield select(getScheduleTimezone);
+
+ if (
+ !currentValue.value ||
+ !currentTo.value ||
+ !scheduleGasPrice.value ||
+ !wallet ||
+ !windowSize.value
+ ) {
+ return;
+ }
+
+ const callGasLimit = scheduleGasLimit.value || EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_LIMIT_FALLBACK;
+
+ const endowment = calcEACEndowment(
+ callGasLimit,
+ currentValue.value || new BN(0),
+ scheduleGasPrice.value || gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK),
+ timeBounty.value
+ );
+
+ const fromAddress = yield apply(wallet, wallet.getAddressString);
+
+ const data = getValidateRequestParamsData(
+ bufferToHex(currentTo.value),
+ callData.value ? bufferToHex(callData.value) : '',
+ callGasLimit,
+ currentValue.value,
+ windowSizeBlockToMin(windowSize.value, scheduleType.value) || 0,
+ scheduleType.value === 'time'
+ ? dateTimeToUnixTimestamp(scheduleTimestamp, scheduleTimezone.value)
+ : windowStart.value,
+ scheduleGasPrice.value,
+ timeBounty.value,
+ deposit.value || new BN(0),
+ scheduleType.value === 'time',
+ endowment,
+ fromAddress
+ );
+
+ const callResult: string = yield apply(node, node.sendCallRequest, [
+ {
+ to: EAC_ADDRESSES.KOVAN.requestFactory,
+ data
+ }
+ ]);
+
+ const { paramsValidity } = RequestFactory.validateRequestParams.decodeOutput(callResult);
+
+ const errors = parseSchedulingParametersValidity(paramsValidity);
+ const paramsValid = errors.length === 0;
+
+ yield call(setField, {
+ raw: paramsValid,
+ value: paramsValid
+ });
+}
+
+export function* setField(payload: SetScheduleParamsValidityAction['payload']) {
+ yield put(setScheduleParamsValidity(payload));
+}
+
+export const schedulingParamsValidity = fork(shouldValidateParams);
diff --git a/common/containers/Tabs/ScheduleTransaction/selectors/fields.ts b/common/containers/Tabs/ScheduleTransaction/selectors/fields.ts
index 07a5d261..85da5024 100644
--- a/common/containers/Tabs/ScheduleTransaction/selectors/fields.ts
+++ b/common/containers/Tabs/ScheduleTransaction/selectors/fields.ts
@@ -11,6 +11,7 @@ const getSchedulingToggle = (state: AppState) => getFields(state).schedulingTogg
const getScheduleGasLimit = (state: AppState) => getFields(state).scheduleGasLimit;
const getScheduleGasPrice = (state: AppState) => getFields(state).scheduleGasPrice;
const getScheduleDeposit = (state: AppState) => getFields(state).scheduleDeposit;
+const getScheduleParamsValidity = (state: AppState) => getFields(state).scheduleParamsValidity;
const schedulingFields = [
'windowStart',
@@ -20,7 +21,8 @@ const schedulingFields = [
'schedulingToggle',
'scheduleDeposit',
'scheduleGasLimit',
- 'scheduleGasPrice'
+ 'scheduleGasPrice',
+ 'scheduleParamsValidity'
];
export {
@@ -34,5 +36,6 @@ export {
getScheduleGasLimit,
getScheduleGasPrice,
getScheduleDeposit,
- schedulingFields
+ schedulingFields,
+ getScheduleParamsValidity
};
diff --git a/common/containers/Tabs/ScheduleTransaction/selectors/transaction.ts b/common/containers/Tabs/ScheduleTransaction/selectors/transaction.ts
index 48c349b6..d1ab1a56 100644
--- a/common/containers/Tabs/ScheduleTransaction/selectors/transaction.ts
+++ b/common/containers/Tabs/ScheduleTransaction/selectors/transaction.ts
@@ -1,6 +1,5 @@
import { AppState } from 'reducers';
import {
- IGetTransaction,
getCurrentTo,
getCurrentValue,
getFields,
@@ -21,7 +20,8 @@ import {
isValidScheduleDeposit,
getScheduleDeposit,
getScheduleTimestamp,
- getScheduleTimezone
+ getScheduleTimezone,
+ IGetTransaction
} from 'selectors/transaction';
import { Address, gasPriceToBase } from 'libs/units';
import {
@@ -43,7 +43,7 @@ import {
import EthTx from 'ethereumjs-tx';
import { getLatestBlock } from 'selectors/config';
-const getSchedulingTransaction = (state: AppState): IGetTransaction => {
+export const getSchedulingTransaction = (state: AppState): IGetTransaction => {
const currentTo = getCurrentTo(state);
const currentValue = getCurrentValue(state);
const transactionFields = getFields(state);
@@ -69,6 +69,13 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
const depositValid = isValidScheduleDeposit(state);
const deposit = getScheduleDeposit(state);
+ const endowment = calcEACEndowment(
+ scheduleGasLimit.value || EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_LIMIT_FALLBACK,
+ currentValue.value || new BN(0),
+ scheduleGasPrice.value || gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK),
+ timeBounty.value
+ );
+
const isFullTransaction =
isFullTx(state, transactionFields, currentTo, currentValue, dataExists, validGasCost, unit) &&
(windowStartValid || scheduleTimestampValid) &&
@@ -77,26 +84,23 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
scheduleGasLimitValid &&
depositValid;
- const transactionData = getScheduleData(
- currentTo.raw,
- callData.raw,
- scheduleGasLimit.value,
- currentValue.value,
- windowSizeBlockToMin(windowSize.value, scheduleType.value),
- scheduleType.value === 'time'
- ? dateTimeToUnixTimestamp(scheduleTimestamp, scheduleTimezone.value)
- : windowStart.value,
- scheduleGasPrice.value,
- timeBounty.value,
- deposit.value
- );
+ let transactionData = null;
- const endowment = calcEACEndowment(
- scheduleGasLimit.value || EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_LIMIT_FALLBACK,
- currentValue.value || new BN(0),
- scheduleGasPrice.value || gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK),
- timeBounty.value
- );
+ if (isFullTransaction) {
+ transactionData = getScheduleData(
+ currentTo.raw,
+ callData.raw,
+ scheduleGasLimit.value,
+ currentValue.value,
+ windowSizeBlockToMin(windowSize.value, scheduleType.value),
+ scheduleType.value === 'time'
+ ? dateTimeToUnixTimestamp(scheduleTimestamp, scheduleTimezone.value)
+ : windowStart.value,
+ scheduleGasPrice.value,
+ timeBounty.value,
+ deposit.value
+ );
+ }
const transactionOptions = {
to: Address(
@@ -122,5 +126,3 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
isFullTransaction
};
};
-
-export { getSchedulingTransaction };
diff --git a/common/libs/contracts/ABIFunction.ts b/common/libs/contracts/ABIFunction.ts
index cb27143c..2453368b 100644
--- a/common/libs/contracts/ABIFunction.ts
+++ b/common/libs/contracts/ABIFunction.ts
@@ -120,7 +120,7 @@ export default class AbiFunction {
this.inputNames.map(name => {
const type = this.funcParams[name].type;
//TODO: parse args based on type
- if (!suppliedArgs[name]) {
+ if (typeof suppliedArgs[name] === 'undefined') {
throw Error(
`Expected argument "${name}" of type "${type}" missing, suppliedArgs: ${JSON.stringify(
suppliedArgs,
diff --git a/common/libs/scheduling/contracts/RequestFactory.ts b/common/libs/scheduling/contracts/RequestFactory.ts
new file mode 100644
index 00000000..8524afa7
--- /dev/null
+++ b/common/libs/scheduling/contracts/RequestFactory.ts
@@ -0,0 +1,58 @@
+import Contract from 'libs/contracts';
+
+interface ABIFunc {
+ encodeInput(x: T): string;
+ decodeInput(argStr: string): T;
+ decodeOutput(argStr: string): K;
+}
+
+type address = any;
+type uint256 = any;
+type bytes = any;
+
+interface IRequestFactory {
+ validateRequestParams: ABIFunc<
+ { _addressArgs: address[]; _uintArgs: uint256[]; _callData: bytes; _endowment: uint256 },
+ { paramsValidity: boolean[] }
+ >;
+}
+
+const requestFactoryAbi = [
+ {
+ constant: true,
+ inputs: [
+ {
+ name: '_addressArgs',
+ type: 'address[3]'
+ },
+ {
+ name: '_uintArgs',
+ type: 'uint256[12]'
+ },
+ {
+ name: '_callData',
+ type: 'bytes'
+ },
+ {
+ name: '_endowment',
+ type: 'uint256'
+ }
+ ],
+ name: 'validateRequestParams',
+ outputs: [
+ {
+ name: '',
+ type: 'bool[6]'
+ }
+ ],
+ payable: false,
+ stateMutability: 'view',
+ type: 'function'
+ }
+];
+
+const outputMappings = {
+ validateRequestParams: ['paramsValidity']
+};
+
+export default (new Contract(requestFactoryAbi, outputMappings) as any) as IRequestFactory;
diff --git a/common/libs/scheduling.ts b/common/libs/scheduling/index.ts
similarity index 63%
rename from common/libs/scheduling.ts
rename to common/libs/scheduling/index.ts
index aacc13af..4cab1f96 100644
--- a/common/libs/scheduling.ts
+++ b/common/libs/scheduling/index.ts
@@ -1,7 +1,8 @@
import BN from 'bn.js';
import abi from 'ethereumjs-abi';
-import { toWei, Units } from './units';
+import { toWei, Units } from '../units';
import { toBuffer } from 'ethereumjs-util';
+import RequestFactory from './contracts/RequestFactory';
const TIME_BOUNTY_MIN = new BN('1');
@@ -25,6 +26,7 @@ export const EAC_SCHEDULING_CONFIG = {
export const EAC_ADDRESSES = {
KOVAN: {
blockScheduler: '0x1afc19a7e642761ba2b55d2a45b32c7ef08269d1',
+ requestFactory: '0x496e2b6089bde77293a994469b08e9f266d87adb',
timestampScheduler: '0xc6370807f0164bdf10a66c08d0dab1028dbe80a3'
}
};
@@ -106,6 +108,67 @@ export const getScheduleData = (
]);
};
+export const parseSchedulingParametersValidity = (isValid: boolean[]) => {
+ const Errors = [
+ 'InsufficientEndowment',
+ 'ReservedWindowBiggerThanExecutionWindow',
+ 'InvalidTemporalUnit',
+ 'ExecutionWindowTooSoon',
+ 'CallGasTooHigh',
+ 'EmptyToAddress'
+ ];
+ const errors: string[] = [];
+
+ isValid.forEach((boolIsTrue, index) => {
+ if (!boolIsTrue) {
+ errors.push(Errors[index]);
+ }
+ });
+
+ return errors;
+};
+
+export const getValidateRequestParamsData = (
+ toAddress: string,
+ callData = '',
+ callGas: BN,
+ callValue: any,
+ windowSize: number,
+ windowStart: BN,
+ gasPrice: BN,
+ timeBounty: BN,
+ requiredDeposit: BN,
+ isTimestamp: boolean,
+ endowment: BN,
+ fromAddress: string
+): string => {
+ const temporalUnit = isTimestamp ? 2 : 1;
+ const freezePeriod = isTimestamp ? 3 * 60 : 10; // 3 minutes or 10 blocks
+ const reservedWindowSize = isTimestamp ? 5 * 60 : 16; // 5 minutes or 16 blocks
+ const claimWindowSize = isTimestamp ? 60 * 60 : 255; // 60 minutes or 255 blocks
+ const feeRecipient = '0x0'; // stub
+
+ return RequestFactory.validateRequestParams.encodeInput({
+ _addressArgs: [fromAddress, feeRecipient, toAddress],
+ _uintArgs: [
+ EAC_SCHEDULING_CONFIG.FEE,
+ timeBounty,
+ claimWindowSize,
+ freezePeriod,
+ reservedWindowSize,
+ temporalUnit,
+ windowSize,
+ windowStart,
+ callGas,
+ callValue,
+ gasPrice,
+ requiredDeposit
+ ],
+ _callData: callData,
+ _endowment: endowment
+ });
+};
+
export const getTXDetailsCheckURL = (txHash: string) => {
return `${EAC_SCHEDULING_CONFIG.DAPP_ADDRESS}/awaiting/scheduler/${txHash}`;
};
diff --git a/common/reducers/transaction/fields/fields.ts b/common/reducers/transaction/fields/fields.ts
index 8c9255b9..7ac9e408 100644
--- a/common/reducers/transaction/fields/fields.ts
+++ b/common/reducers/transaction/fields/fields.ts
@@ -44,7 +44,8 @@ const INITIAL_STATE: State = {
raw: EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK.toString(),
value: gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK)
},
- scheduleDeposit: { raw: '', value: null }
+ scheduleDeposit: { raw: '', value: null },
+ scheduleParamsValidity: { raw: true, value: true }
};
const updateField = (key: keyof State): Reducer => (state: State, action: FieldAction) => ({
@@ -114,6 +115,8 @@ export const fields = (
return updateField('scheduleGasPrice')(state, action);
case TK.SCHEDULE_DEPOSIT_FIELD_SET:
return updateField('scheduleDeposit')(state, action);
+ case TK.SCHEDULE_PARAMS_VALIDITY_SET:
+ return updateField('scheduleParamsValidity')(state, action);
case TK.TOKEN_TO_ETHER_SWAP:
return tokenToEther(state, action);
case TK.ETHER_TO_TOKEN_SWAP:
diff --git a/common/reducers/transaction/fields/typings.ts b/common/reducers/transaction/fields/typings.ts
index 6d338bc6..8447d986 100644
--- a/common/reducers/transaction/fields/typings.ts
+++ b/common/reducers/transaction/fields/typings.ts
@@ -11,7 +11,8 @@ import {
SetScheduleGasPriceFieldAction,
SetScheduleGasLimitFieldAction,
SetScheduleDepositFieldAction,
- SetScheduleTimezoneAction
+ SetScheduleTimezoneAction,
+ SetScheduleParamsValidityAction
} from 'actions/transaction';
import { Wei } from 'libs/units';
@@ -32,4 +33,5 @@ export interface State {
scheduleGasLimit: SetScheduleGasLimitFieldAction['payload'];
scheduleGasPrice: SetScheduleGasPriceFieldAction['payload'];
scheduleDeposit: SetScheduleDepositFieldAction['payload'];
+ scheduleParamsValidity: SetScheduleParamsValidityAction['payload'];
}
diff --git a/common/sagas/transaction/network/index.ts b/common/sagas/transaction/network/index.ts
index 9d6168d5..668ddeac 100644
--- a/common/sagas/transaction/network/index.ts
+++ b/common/sagas/transaction/network/index.ts
@@ -1,4 +1,6 @@
import { from } from './from';
import { gas } from './gas';
import { nonce } from './nonce';
-export const network = [from, ...gas, nonce];
+import { schedulingTransactionNetworkSagas } from '../../../containers/Tabs/ScheduleTransaction/sagas/transaction/network';
+
+export const network = [from, ...gas, nonce, ...schedulingTransactionNetworkSagas];
diff --git a/spec/reducers/transaction/fields/fields.spec.ts b/spec/reducers/transaction/fields/fields.spec.ts
index bb20c77c..9bb3163b 100644
--- a/spec/reducers/transaction/fields/fields.spec.ts
+++ b/spec/reducers/transaction/fields/fields.spec.ts
@@ -33,7 +33,8 @@ describe('fields reducer', () => {
value: gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK)
},
scheduleGasLimit: { raw: '21000', value: new BN(21000) },
- scheduleDeposit: { raw: '', value: null }
+ scheduleDeposit: { raw: '', value: null },
+ scheduleParamsValidity: { raw: true, value: true }
};
const testPayload = { raw: 'test', value: null };
diff --git a/spec/selectors/transaction/fields.spec.ts b/spec/selectors/transaction/fields.spec.ts
index d3e04d23..b1686c08 100644
--- a/spec/selectors/transaction/fields.spec.ts
+++ b/spec/selectors/transaction/fields.spec.ts
@@ -81,6 +81,10 @@ describe('fields selector', () => {
scheduleDeposit: {
raw: '1000000000',
value: Wei('1000000000')
+ },
+ scheduleParamsValidity: {
+ raw: false,
+ value: false
}
};
diff --git a/spec/selectors/transaction/helpers.spec.ts b/spec/selectors/transaction/helpers.spec.ts
index e9f26d4f..0bf0b3ba 100644
--- a/spec/selectors/transaction/helpers.spec.ts
+++ b/spec/selectors/transaction/helpers.spec.ts
@@ -85,6 +85,10 @@ describe('helpers selector', () => {
scheduleDeposit: {
raw: '1000000000',
value: Wei('1000000000')
+ },
+ scheduleParamsValidity: {
+ raw: false,
+ value: false
}
}
};
@@ -106,7 +110,8 @@ describe('helpers selector', () => {
scheduleTimezone: moment.tz.guess(),
scheduleGasPrice: Wei('1500'),
scheduleGasLimit: Wei('21000'),
- scheduleDeposit: Wei('1000000000')
+ scheduleDeposit: Wei('1000000000'),
+ scheduleParamsValidity: false
};
expect(reduceToValues(state.transaction.fields)).toEqual(values);
});