Use Network Symbol in Confirmation Modal (#1039)
* Set default unit to 'ETH' instead of 'ether' * Use 'isEtherUnit()' everywhere * Set default unit to empty string * Update isEthUnit to isNetworkUnit * Fix unit conversion for non-ethereum networks * Set default network unit properly * Fix tests * fix typos * Update isNetworkUnit selector * Update isNetworkUnit * Fix validationhelpers tests * Add mock state to tests & Move isNetworkUnit to selectors * Fix validation helper spec * fix unit swap spec
This commit is contained in:
parent
08335fbca0
commit
aabcd3f7a3
|
@ -1,5 +1,5 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider, connect } from 'react-redux';
|
||||||
import { withRouter, Switch, Redirect, HashRouter, Route, BrowserRouter } from 'react-router-dom';
|
import { withRouter, Switch, Redirect, HashRouter, Route, BrowserRouter } from 'react-router-dom';
|
||||||
// Components
|
// Components
|
||||||
import Contracts from 'containers/Tabs/Contracts';
|
import Contracts from 'containers/Tabs/Contracts';
|
||||||
|
@ -15,27 +15,41 @@ import PageNotFound from 'components/PageNotFound';
|
||||||
import LogOutPrompt from 'components/LogOutPrompt';
|
import LogOutPrompt from 'components/LogOutPrompt';
|
||||||
import { TitleBar } from 'components/ui';
|
import { TitleBar } from 'components/ui';
|
||||||
import { Store } from 'redux';
|
import { Store } from 'redux';
|
||||||
import { pollOfflineStatus } from 'actions/config';
|
import { pollOfflineStatus, TPollOfflineStatus } from 'actions/config';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { RouteNotFound } from 'components/RouteNotFound';
|
import { RouteNotFound } from 'components/RouteNotFound';
|
||||||
import { RedirectWithQuery } from 'components/RedirectWithQuery';
|
import { RedirectWithQuery } from 'components/RedirectWithQuery';
|
||||||
import 'what-input';
|
import 'what-input';
|
||||||
|
import { setUnitMeta, TSetUnitMeta } from 'actions/transaction';
|
||||||
|
import { getNetworkUnit } from 'selectors/config';
|
||||||
|
|
||||||
interface Props {
|
interface OwnProps {
|
||||||
store: Store<AppState>;
|
store: Store<AppState>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface StateProps {
|
||||||
|
networkUnit: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DispatchProps {
|
||||||
|
pollOfflineStatus: TPollOfflineStatus;
|
||||||
|
setUnitMeta: TSetUnitMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = OwnProps & StateProps & DispatchProps;
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
error: Error | null;
|
error: Error | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Root extends Component<Props, State> {
|
class RootClass extends Component<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
error: null
|
error: null
|
||||||
};
|
};
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
this.props.store.dispatch(pollOfflineStatus());
|
this.props.pollOfflineStatus();
|
||||||
|
this.props.setUnitMeta(this.props.networkUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidCatch(error: Error) {
|
public componentDidCatch(error: Error) {
|
||||||
|
@ -134,3 +148,14 @@ const LegacyRoutes = withRouter(props => {
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const mapStateToProps = (state: AppState) => {
|
||||||
|
return {
|
||||||
|
networkUnit: getNetworkUnit(state)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, {
|
||||||
|
pollOfflineStatus,
|
||||||
|
setUnitMeta
|
||||||
|
})(RootClass);
|
||||||
|
|
|
@ -5,23 +5,22 @@ import {
|
||||||
SetTokenToMetaAction
|
SetTokenToMetaAction
|
||||||
} from 'actions/transaction';
|
} from 'actions/transaction';
|
||||||
|
|
||||||
type TSetTokenBalance = typeof setTokenValue;
|
export type TSetTokenTo = typeof setTokenTo;
|
||||||
type TSetUnitMeta = typeof setUnitMeta;
|
export const setTokenTo = (payload: SetTokenToMetaAction['payload']): SetTokenToMetaAction => ({
|
||||||
type TSetTokenTo = typeof setTokenTo;
|
|
||||||
|
|
||||||
const setTokenTo = (payload: SetTokenToMetaAction['payload']): SetTokenToMetaAction => ({
|
|
||||||
type: TypeKeys.TOKEN_TO_META_SET,
|
type: TypeKeys.TOKEN_TO_META_SET,
|
||||||
payload
|
payload
|
||||||
});
|
});
|
||||||
|
|
||||||
const setTokenValue = (payload: SetTokenValueMetaAction['payload']): SetTokenValueMetaAction => ({
|
export type TSetTokenValue = typeof setTokenValue;
|
||||||
|
export const setTokenValue = (
|
||||||
|
payload: SetTokenValueMetaAction['payload']
|
||||||
|
): SetTokenValueMetaAction => ({
|
||||||
type: TypeKeys.TOKEN_VALUE_META_SET,
|
type: TypeKeys.TOKEN_VALUE_META_SET,
|
||||||
payload
|
payload
|
||||||
});
|
});
|
||||||
|
|
||||||
const setUnitMeta = (payload: SetUnitMetaAction['payload']): SetUnitMetaAction => ({
|
export type TSetUnitMeta = typeof setUnitMeta;
|
||||||
|
export const setUnitMeta = (payload: SetUnitMetaAction['payload']): SetUnitMetaAction => ({
|
||||||
type: TypeKeys.UNIT_META_SET,
|
type: TypeKeys.UNIT_META_SET,
|
||||||
payload
|
payload
|
||||||
});
|
});
|
||||||
|
|
||||||
export { TSetUnitMeta, TSetTokenBalance, TSetTokenTo, setUnitMeta, setTokenValue, setTokenTo };
|
|
||||||
|
|
|
@ -6,8 +6,7 @@ import { Query } from 'components/renderCbs';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { getUnit } from 'selectors/transaction';
|
import { getUnit } from 'selectors/transaction';
|
||||||
import { getNetworkConfig } from 'selectors/config';
|
import { getNetworkUnit } from 'selectors/config';
|
||||||
import { NetworkConfig } from 'types/network';
|
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
setUnitMeta: TSetUnitMeta;
|
setUnitMeta: TSetUnitMeta;
|
||||||
|
@ -18,21 +17,21 @@ interface StateProps {
|
||||||
tokens: TokenBalance[];
|
tokens: TokenBalance[];
|
||||||
allTokens: MergedToken[];
|
allTokens: MergedToken[];
|
||||||
showAllTokens?: boolean;
|
showAllTokens?: boolean;
|
||||||
network: NetworkConfig;
|
networkUnit: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnitDropdownClass extends Component<DispatchProps & StateProps> {
|
class UnitDropdownClass extends Component<DispatchProps & StateProps> {
|
||||||
public render() {
|
public render() {
|
||||||
const { tokens, allTokens, showAllTokens, unit, network } = this.props;
|
const { tokens, allTokens, showAllTokens, unit, networkUnit } = this.props;
|
||||||
const focusedTokens = showAllTokens ? allTokens : tokens;
|
const focusedTokens = showAllTokens ? allTokens : tokens;
|
||||||
const options = [network.unit, ...getTokenSymbols(focusedTokens)];
|
const options = [networkUnit, ...getTokenSymbols(focusedTokens)];
|
||||||
return (
|
return (
|
||||||
<Query
|
<Query
|
||||||
params={['readOnly']}
|
params={['readOnly']}
|
||||||
withQuery={({ readOnly }) => (
|
withQuery={({ readOnly }) => (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
options={options}
|
options={options}
|
||||||
value={unit === 'ether' ? network.unit : unit}
|
value={unit === 'ether' ? networkUnit : unit}
|
||||||
onChange={this.handleOnChange}
|
onChange={this.handleOnChange}
|
||||||
clearable={false}
|
clearable={false}
|
||||||
searchable={options.length > 10}
|
searchable={options.length > 10}
|
||||||
|
@ -53,7 +52,7 @@ function mapStateToProps(state: AppState) {
|
||||||
tokens: getShownTokenBalances(state, true),
|
tokens: getShownTokenBalances(state, true),
|
||||||
allTokens: getTokens(state),
|
allTokens: getTokens(state),
|
||||||
unit: getUnit(state),
|
unit: getUnit(state),
|
||||||
network: getNetworkConfig(state)
|
networkUnit: getNetworkUnit(state)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { getGasLimit } from 'selectors/transaction';
|
||||||
import { AddressField, AmountField, TXMetaDataPanel } from 'components';
|
import { AddressField, AmountField, TXMetaDataPanel } from 'components';
|
||||||
import { SetGasLimitFieldAction } from 'actions/transaction/actionTypes/fields';
|
import { SetGasLimitFieldAction } from 'actions/transaction/actionTypes/fields';
|
||||||
import { buildEIP681EtherRequest, buildEIP681TokenRequest } from 'libs/values';
|
import { buildEIP681EtherRequest, buildEIP681TokenRequest } from 'libs/values';
|
||||||
import { getNetworkConfig, getSelectedTokenContractAddress } from 'selectors/config';
|
import { getNetworkConfig, getSelectedTokenContractAddress, isNetworkUnit } from 'selectors/config';
|
||||||
import './RequestPayment.scss';
|
import './RequestPayment.scss';
|
||||||
import { reset, TReset, setCurrentTo, TSetCurrentTo } from 'actions/transaction';
|
import { reset, TReset, setCurrentTo, TSetCurrentTo } from 'actions/transaction';
|
||||||
import { NetworkConfig } from 'types/network';
|
import { NetworkConfig } from 'types/network';
|
||||||
|
@ -34,6 +34,7 @@ interface StateProps {
|
||||||
networkConfig: NetworkConfig;
|
networkConfig: NetworkConfig;
|
||||||
decimal: number;
|
decimal: number;
|
||||||
tokenContractAddress: string;
|
tokenContractAddress: string;
|
||||||
|
isNetworkUnit: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ActionProps {
|
interface ActionProps {
|
||||||
|
@ -161,7 +162,7 @@ class RequestPayment extends React.Component<Props, {}> {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit === 'ether') {
|
if (this.props.isNetworkUnit) {
|
||||||
return buildEIP681EtherRequest(currentTo, chainId, currentValue);
|
return buildEIP681EtherRequest(currentTo, chainId, currentValue);
|
||||||
} else {
|
} else {
|
||||||
return buildEIP681TokenRequest(
|
return buildEIP681TokenRequest(
|
||||||
|
@ -184,7 +185,8 @@ function mapStateToProps(state: AppState): StateProps {
|
||||||
gasLimit: getGasLimit(state),
|
gasLimit: getGasLimit(state),
|
||||||
networkConfig: getNetworkConfig(state),
|
networkConfig: getNetworkConfig(state),
|
||||||
decimal: getDecimal(state),
|
decimal: getDecimal(state),
|
||||||
tokenContractAddress: getSelectedTokenContractAddress(state)
|
tokenContractAddress: getSelectedTokenContractAddress(state),
|
||||||
|
isNetworkUnit: isNetworkUnit(state, getUnit(state))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,6 @@ const fromTokenBase = (value: TokenValue, decimal: number) =>
|
||||||
const toTokenBase = (value: string, decimal: number) =>
|
const toTokenBase = (value: string, decimal: number) =>
|
||||||
TokenValue(convertedToBaseUnit(value, decimal));
|
TokenValue(convertedToBaseUnit(value, decimal));
|
||||||
|
|
||||||
const isEtherUnit = (unit: string) => unit === 'ether' || unit === 'ETH';
|
|
||||||
|
|
||||||
const convertTokenBase = (value: TokenValue, oldDecimal: number, newDecimal: number) => {
|
const convertTokenBase = (value: TokenValue, oldDecimal: number, newDecimal: number) => {
|
||||||
if (oldDecimal === newDecimal) {
|
if (oldDecimal === newDecimal) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -115,7 +113,6 @@ const convertTokenBase = (value: TokenValue, oldDecimal: number, newDecimal: num
|
||||||
const gasPricetoBase = (price: number) => toWei(price.toString(), getDecimalFromEtherUnit('gwei'));
|
const gasPricetoBase = (price: number) => toWei(price.toString(), getDecimalFromEtherUnit('gwei'));
|
||||||
|
|
||||||
export {
|
export {
|
||||||
isEtherUnit,
|
|
||||||
Data,
|
Data,
|
||||||
Address,
|
Address,
|
||||||
TokenValue,
|
TokenValue,
|
||||||
|
|
|
@ -14,8 +14,8 @@ import {
|
||||||
import { Reducer } from 'redux';
|
import { Reducer } from 'redux';
|
||||||
|
|
||||||
const INITIAL_STATE: State = {
|
const INITIAL_STATE: State = {
|
||||||
unit: 'ether',
|
unit: '',
|
||||||
previousUnit: 'ether',
|
previousUnit: '',
|
||||||
decimal: getDecimalFromEtherUnit('ether'),
|
decimal: getDecimalFromEtherUnit('ether'),
|
||||||
tokenValue: { raw: '', value: null },
|
tokenValue: { raw: '', value: null },
|
||||||
tokenTo: { raw: '', value: null },
|
tokenTo: { raw: '', value: null },
|
||||||
|
|
|
@ -11,8 +11,7 @@ import {
|
||||||
import { TypeKeys as WalletTK, setTokenBalancePending } from 'actions/wallet';
|
import { TypeKeys as WalletTK, setTokenBalancePending } from 'actions/wallet';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { showNotification } from 'actions/notifications';
|
import { showNotification } from 'actions/notifications';
|
||||||
import { isSupportedUnit } from 'selectors/config';
|
import { isSupportedUnit, isNetworkUnit } from 'selectors/config';
|
||||||
import { isEtherUnit } from 'libs/units';
|
|
||||||
import { showLiteSend, configureLiteSend } from 'actions/swap';
|
import { showLiteSend, configureLiteSend } from 'actions/swap';
|
||||||
import { TypeKeys as SwapTK } from 'actions/swap/constants';
|
import { TypeKeys as SwapTK } from 'actions/swap/constants';
|
||||||
import { isUnlocked, isEtherBalancePending } from 'selectors/wallet';
|
import { isUnlocked, isEtherBalancePending } from 'selectors/wallet';
|
||||||
|
@ -40,9 +39,9 @@ export function* configureLiteSendSaga(): SagaIterator {
|
||||||
if (!unlocked) {
|
if (!unlocked) {
|
||||||
yield take(WalletTK.WALLET_SET);
|
yield take(WalletTK.WALLET_SET);
|
||||||
}
|
}
|
||||||
|
const isNetwrkUnit = yield select(isNetworkUnit, label);
|
||||||
//if it's a token, manually scan for that tokens balance and wait for it to resolve
|
//if it's a token, manually scan for that tokens balance and wait for it to resolve
|
||||||
if (!isEtherUnit(label)) {
|
if (!isNetwrkUnit) {
|
||||||
yield put(setTokenBalancePending({ tokenSymbol: label }));
|
yield put(setTokenBalancePending({ tokenSymbol: label }));
|
||||||
yield take([
|
yield take([
|
||||||
WalletTK.WALLET_SET_TOKEN_BALANCE_FULFILLED,
|
WalletTK.WALLET_SET_TOKEN_BALANCE_FULFILLED,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { meta } from './meta';
|
||||||
import { network } from './network';
|
import { network } from './network';
|
||||||
import { signing } from './signing';
|
import { signing } from './signing';
|
||||||
import { sendEverything } from './sendEverything';
|
import { sendEverything } from './sendEverything';
|
||||||
import { reset } from './reset';
|
import { reset, setDefaultUnit } from './reset';
|
||||||
|
|
||||||
export function* transaction(): SagaIterator {
|
export function* transaction(): SagaIterator {
|
||||||
yield all([
|
yield all([
|
||||||
|
@ -18,6 +18,7 @@ export function* transaction(): SagaIterator {
|
||||||
...network,
|
...network,
|
||||||
...signing,
|
...signing,
|
||||||
...sendEverything,
|
...sendEverything,
|
||||||
...reset
|
...reset,
|
||||||
|
setDefaultUnit
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,9 @@ import {
|
||||||
getValue,
|
getValue,
|
||||||
getDecimalFromUnit
|
getDecimalFromUnit
|
||||||
} from 'selectors/transaction';
|
} from 'selectors/transaction';
|
||||||
|
import { isNetworkUnit } from 'selectors/config';
|
||||||
import { getToken, MergedToken } from 'selectors/wallet';
|
import { getToken, MergedToken } from 'selectors/wallet';
|
||||||
import { isEtherUnit, TokenValue, Address } from 'libs/units';
|
import { TokenValue, Address } from 'libs/units';
|
||||||
import {
|
import {
|
||||||
swapTokenToEther,
|
swapTokenToEther,
|
||||||
swapEtherToToken,
|
swapEtherToToken,
|
||||||
|
@ -23,10 +24,12 @@ import { validateInput, rebaseUserInput, IInput } from 'sagas/transaction/valida
|
||||||
|
|
||||||
export function* handleSetUnitMeta({ payload: currentUnit }: SetUnitMetaAction): SagaIterator {
|
export function* handleSetUnitMeta({ payload: currentUnit }: SetUnitMetaAction): SagaIterator {
|
||||||
const previousUnit: string = yield select(getPreviousUnit);
|
const previousUnit: string = yield select(getPreviousUnit);
|
||||||
const etherToEther = isEtherUnit(currentUnit) && isEtherUnit(previousUnit);
|
const prevUnit = yield select(isNetworkUnit, previousUnit);
|
||||||
const etherToToken = !isEtherUnit(currentUnit) && isEtherUnit(previousUnit);
|
const currUnit = yield select(isNetworkUnit, currentUnit);
|
||||||
const tokenToEther = isEtherUnit(currentUnit) && !isEtherUnit(previousUnit);
|
const etherToEther = currUnit && prevUnit;
|
||||||
const tokenToToken = !isEtherUnit(currentUnit) && !isEtherUnit(previousUnit);
|
const etherToToken = !currUnit && prevUnit;
|
||||||
|
const tokenToEther = currUnit && !prevUnit;
|
||||||
|
const tokenToToken = !currUnit && !prevUnit;
|
||||||
const decimal: number = yield select(getDecimalFromUnit, currentUnit);
|
const decimal: number = yield select(getDecimalFromUnit, currentUnit);
|
||||||
|
|
||||||
if (etherToEther) {
|
if (etherToEther) {
|
||||||
|
|
|
@ -1,10 +1,22 @@
|
||||||
import { SagaIterator } from 'redux-saga';
|
import { SagaIterator } from 'redux-saga';
|
||||||
import { TypeKeys } from 'actions/wallet';
|
import { TypeKeys } from 'actions/wallet';
|
||||||
import { takeEvery, put } from 'redux-saga/effects';
|
import { takeEvery, put, select } from 'redux-saga/effects';
|
||||||
import { reset as resetActionCreator } from 'actions/transaction';
|
import {
|
||||||
|
reset as resetActionCreator,
|
||||||
|
setUnitMeta,
|
||||||
|
TypeKeys as Constants
|
||||||
|
} from 'actions/transaction';
|
||||||
|
import { getNetworkUnit } from 'selectors/config';
|
||||||
|
|
||||||
export function* resetTransactionState(): SagaIterator {
|
export function* resetTransactionState(): SagaIterator {
|
||||||
yield put(resetActionCreator());
|
yield put(resetActionCreator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function* setNetworkUnit(): SagaIterator {
|
||||||
|
const networkUnit = yield select(getNetworkUnit);
|
||||||
|
yield put(setUnitMeta(networkUnit));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setDefaultUnit = takeEvery(Constants.RESET, setNetworkUnit);
|
||||||
|
|
||||||
export const reset = [takeEvery([TypeKeys.WALLET_RESET], resetTransactionState)];
|
export const reset = [takeEvery([TypeKeys.WALLET_RESET], resetTransactionState)];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { TokenValue, Wei, isEtherUnit, toTokenBase } from 'libs/units';
|
import { TokenValue, Wei, toTokenBase } from 'libs/units';
|
||||||
import { SagaIterator } from 'redux-saga';
|
import { SagaIterator } from 'redux-saga';
|
||||||
import { getEtherBalance, getTokenBalance } from 'selectors/wallet';
|
import { getEtherBalance, getTokenBalance } from 'selectors/wallet';
|
||||||
import { getOffline } from 'selectors/config';
|
import { getOffline, isNetworkUnit } from 'selectors/config';
|
||||||
import { select, call } from 'redux-saga/effects';
|
import { select, call } from 'redux-saga/effects';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { getGasLimit, getGasPrice, getUnit, getDecimalFromUnit } from 'selectors/transaction';
|
import { getGasLimit, getGasPrice, getUnit, getDecimalFromUnit } from 'selectors/transaction';
|
||||||
|
@ -48,7 +48,7 @@ export function* validateInput(input: TokenValue | Wei | null, unit: string): Sa
|
||||||
|
|
||||||
const etherBalance: Wei | null = yield select(getEtherBalance);
|
const etherBalance: Wei | null = yield select(getEtherBalance);
|
||||||
const isOffline: boolean = yield select(getOffline);
|
const isOffline: boolean = yield select(getOffline);
|
||||||
const etherTransaction: boolean = yield call(isEtherUnit, unit);
|
const networkUnitTransaction: boolean = yield select(isNetworkUnit, unit);
|
||||||
|
|
||||||
if (isOffline || !etherBalance) {
|
if (isOffline || !etherBalance) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -59,14 +59,14 @@ export function* validateInput(input: TokenValue | Wei | null, unit: string): Sa
|
||||||
// TODO: do gas estimation here if we're switching to a token too, it should cover the last edge case
|
// TODO: do gas estimation here if we're switching to a token too, it should cover the last edge case
|
||||||
|
|
||||||
//make a new transaction for validating ether balances
|
//make a new transaction for validating ether balances
|
||||||
const validationTx = etherTransaction
|
const validationTx = networkUnitTransaction
|
||||||
? yield call(makeCostCalculationTx, input)
|
? yield call(makeCostCalculationTx, input)
|
||||||
: yield call(makeCostCalculationTx, null);
|
: yield call(makeCostCalculationTx, null);
|
||||||
|
|
||||||
// check that they have enough ether, this checks gas cost too
|
// check that they have enough ether, this checks gas cost too
|
||||||
valid = valid && enoughBalanceViaTx(validationTx, etherBalance);
|
valid = valid && enoughBalanceViaTx(validationTx, etherBalance);
|
||||||
|
|
||||||
if (!etherTransaction) {
|
if (!networkUnitTransaction) {
|
||||||
const tokenBalance: TokenValue | null = yield select(getTokenBalance, unit);
|
const tokenBalance: TokenValue | null = yield select(getTokenBalance, unit);
|
||||||
valid = valid && enoughTokensViaInput(input, tokenBalance);
|
valid = valid && enoughTokensViaInput(input, tokenBalance);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,10 @@ export const getNetworkConfig = (state: AppState): StaticNetworkConfig | CustomN
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getNetworkUnit = (state: AppState): string => {
|
||||||
|
return getNetworkConfig(state).unit;
|
||||||
|
};
|
||||||
|
|
||||||
export const getNetworkContracts = (state: AppState): NetworkContract[] | null => {
|
export const getNetworkContracts = (state: AppState): NetworkContract[] | null => {
|
||||||
const network = getStaticNetworkConfig(state);
|
const network = getStaticNetworkConfig(state);
|
||||||
return network ? network.contracts : [];
|
return network ? network.contracts : [];
|
||||||
|
@ -74,3 +78,7 @@ export const getNetworkContracts = (state: AppState): NetworkContract[] | null =
|
||||||
export const getCustomNetworkConfigs = (state: AppState) => getNetworks(state).customNetworks;
|
export const getCustomNetworkConfigs = (state: AppState) => getNetworks(state).customNetworks;
|
||||||
|
|
||||||
export const getStaticNetworkConfigs = (state: AppState) => getNetworks(state).staticNetworks;
|
export const getStaticNetworkConfigs = (state: AppState) => getNetworks(state).staticNetworks;
|
||||||
|
|
||||||
|
export const isNetworkUnit = (state: AppState, unit: string) => {
|
||||||
|
return unit === getNetworkUnit(state);
|
||||||
|
};
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { getUnit } from 'selectors/transaction/meta';
|
import { getUnit } from 'selectors/transaction/meta';
|
||||||
import { isEtherUnit } from 'libs/units';
|
|
||||||
import { SHAPESHIFT_TOKEN_WHITELIST } from 'api/shapeshift';
|
import { SHAPESHIFT_TOKEN_WHITELIST } from 'api/shapeshift';
|
||||||
import { getStaticNetworkConfig } from 'selectors/config';
|
import { getStaticNetworkConfig, isNetworkUnit } from 'selectors/config';
|
||||||
import { Token } from 'types/network';
|
import { Token } from 'types/network';
|
||||||
|
|
||||||
export function getNetworkTokens(state: AppState): Token[] {
|
export function getNetworkTokens(state: AppState): Token[] {
|
||||||
|
@ -19,7 +18,7 @@ export function getSelectedTokenContractAddress(state: AppState): string {
|
||||||
const allTokens = getAllTokens(state);
|
const allTokens = getAllTokens(state);
|
||||||
const currentUnit = getUnit(state);
|
const currentUnit = getUnit(state);
|
||||||
|
|
||||||
if (isEtherUnit(currentUnit)) {
|
if (isNetworkUnit(state, currentUnit)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ export function tokenExists(state: AppState, token: string): boolean {
|
||||||
|
|
||||||
export function isSupportedUnit(state: AppState, unit: string) {
|
export function isSupportedUnit(state: AppState, unit: string) {
|
||||||
const isToken: boolean = tokenExists(state, unit);
|
const isToken: boolean = tokenExists(state, unit);
|
||||||
const isEther: boolean = isEtherUnit(unit);
|
const isEther: boolean = isNetworkUnit(state, unit);
|
||||||
if (!isToken && !isEther) {
|
if (!isToken && !isEther) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { getNetworkConfig } from 'selectors/config';
|
import { getNetworkConfig } from 'selectors/config';
|
||||||
import { getUnit, isEtherTransaction, getParamsFromSerializedTx } from 'selectors/transaction';
|
import { getUnit, getParamsFromSerializedTx } from 'selectors/transaction';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { Wei, TokenValue } from 'libs/units';
|
import { Wei, TokenValue } from 'libs/units';
|
||||||
|
|
||||||
|
@ -9,13 +9,11 @@ export const getRates = (state: AppState) => state.rates;
|
||||||
const getUSDConversionRate = (state: AppState, unit: string) => {
|
const getUSDConversionRate = (state: AppState, unit: string) => {
|
||||||
const { isTestnet } = getNetworkConfig(state);
|
const { isTestnet } = getNetworkConfig(state);
|
||||||
const { rates } = getRates(state);
|
const { rates } = getRates(state);
|
||||||
const isEther = isEtherTransaction(state);
|
|
||||||
const conversionUnit = isEther ? 'ETH' : unit;
|
|
||||||
if (isTestnet) {
|
if (isTestnet) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const conversionRate = rates[conversionUnit];
|
const conversionRate = rates[unit];
|
||||||
|
|
||||||
if (!conversionRate) {
|
if (!conversionRate) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -29,7 +27,6 @@ export const getValueInUSD = (state: AppState, value: TokenValue | Wei) => {
|
||||||
if (!conversionRate) {
|
if (!conversionRate) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendValueUSD = value.muln(conversionRate);
|
const sendValueUSD = value.muln(conversionRate);
|
||||||
return sendValueUSD;
|
return sendValueUSD;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { getTo, getValue } from './fields';
|
import { getTo, getValue } from './fields';
|
||||||
import { getUnit, getTokenTo, getTokenValue } from './meta';
|
import { getUnit, getTokenTo, getTokenValue } from './meta';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { isEtherUnit, TokenValue, Wei, Address } from 'libs/units';
|
import { TokenValue, Wei, Address } from 'libs/units';
|
||||||
import { gasPriceValidator, gasLimitValidator } from 'libs/validators';
|
import { gasPriceValidator, gasLimitValidator } from 'libs/validators';
|
||||||
import { getDataExists, getGasPrice, getGasLimit } from 'selectors/transaction';
|
import { getDataExists, getGasPrice, getGasLimit } from 'selectors/transaction';
|
||||||
|
import { isNetworkUnit } from 'selectors/config';
|
||||||
import { getAddressMessage, AddressMessage } from 'config';
|
import { getAddressMessage, AddressMessage } from 'config';
|
||||||
|
|
||||||
interface ICurrentValue {
|
interface ICurrentValue {
|
||||||
|
@ -18,7 +19,7 @@ interface ICurrentTo {
|
||||||
|
|
||||||
const isEtherTransaction = (state: AppState) => {
|
const isEtherTransaction = (state: AppState) => {
|
||||||
const unit = getUnit(state);
|
const unit = getUnit(state);
|
||||||
const etherUnit = isEtherUnit(unit);
|
const etherUnit = isNetworkUnit(state, unit);
|
||||||
return etherUnit;
|
return etherUnit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { ICurrentTo, ICurrentValue } from 'selectors/transaction';
|
import { ICurrentTo, ICurrentValue } from 'selectors/transaction';
|
||||||
import { isEtherUnit } from 'libs/units';
|
import { isNetworkUnit } from 'selectors/config';
|
||||||
|
|
||||||
export const reduceToValues = (transactionFields: AppState['transaction']['fields']) =>
|
export const reduceToValues = (transactionFields: AppState['transaction']['fields']) =>
|
||||||
Object.keys(transactionFields).reduce(
|
Object.keys(transactionFields).reduce(
|
||||||
(obj, currFieldName) => {
|
(obj, currFieldName) => {
|
||||||
|
@ -12,6 +11,7 @@ export const reduceToValues = (transactionFields: AppState['transaction']['field
|
||||||
);
|
);
|
||||||
|
|
||||||
export const isFullTx = (
|
export const isFullTx = (
|
||||||
|
state: AppState,
|
||||||
transactionFields: AppState['transaction']['fields'],
|
transactionFields: AppState['transaction']['fields'],
|
||||||
currentTo: ICurrentTo,
|
currentTo: ICurrentTo,
|
||||||
currentValue: ICurrentValue,
|
currentValue: ICurrentValue,
|
||||||
|
@ -26,7 +26,7 @@ export const isFullTx = (
|
||||||
isValid && !!v.value,
|
isValid && !!v.value,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (isEtherUnit(unit)) {
|
if (isNetworkUnit(state, unit)) {
|
||||||
// if theres data we can have no current value, and we dont have to check for a to address
|
// if theres data we can have no current value, and we dont have to check for a to address
|
||||||
if (dataExists && validGasCost && !currentValue.value && currentValue.raw === '') {
|
if (dataExists && validGasCost && !currentValue.value && currentValue.raw === '') {
|
||||||
return validPartialParams;
|
return validPartialParams;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { getTransactionState } from './transaction';
|
import { getTransactionState } from './transaction';
|
||||||
import { getDecimalFromEtherUnit, isEtherUnit } from 'libs/units';
|
|
||||||
import { getToken } from 'selectors/wallet';
|
import { getToken } from 'selectors/wallet';
|
||||||
|
import { isNetworkUnit } from 'selectors/config/wallet';
|
||||||
|
import { getDecimalFromEtherUnit } from 'libs/units';
|
||||||
|
|
||||||
const getMetaState = (state: AppState) => getTransactionState(state).meta;
|
const getMetaState = (state: AppState) => getTransactionState(state).meta;
|
||||||
const getFrom = (state: AppState) => getMetaState(state).from;
|
const getFrom = (state: AppState) => getMetaState(state).from;
|
||||||
|
@ -11,7 +12,7 @@ const getTokenValue = (state: AppState) => getMetaState(state).tokenValue;
|
||||||
const getUnit = (state: AppState) => getMetaState(state).unit;
|
const getUnit = (state: AppState) => getMetaState(state).unit;
|
||||||
const getPreviousUnit = (state: AppState) => getMetaState(state).previousUnit;
|
const getPreviousUnit = (state: AppState) => getMetaState(state).previousUnit;
|
||||||
const getDecimalFromUnit = (state: AppState, unit: string) => {
|
const getDecimalFromUnit = (state: AppState, unit: string) => {
|
||||||
if (isEtherUnit(unit)) {
|
if (isNetworkUnit(state, unit)) {
|
||||||
return getDecimalFromEtherUnit('ether');
|
return getDecimalFromEtherUnit('ether');
|
||||||
} else {
|
} else {
|
||||||
const token = getToken(state, unit);
|
const token = getToken(state, unit);
|
||||||
|
|
|
@ -34,6 +34,7 @@ const getTransaction = (state: AppState): IGetTransaction => {
|
||||||
const dataExists = getDataExists(state);
|
const dataExists = getDataExists(state);
|
||||||
const validGasCost = getValidGasCost(state);
|
const validGasCost = getValidGasCost(state);
|
||||||
const isFullTransaction = isFullTx(
|
const isFullTransaction = isFullTx(
|
||||||
|
state,
|
||||||
transactionFields,
|
transactionFields,
|
||||||
currentTo,
|
currentTo,
|
||||||
currentValue,
|
currentValue,
|
||||||
|
|
|
@ -73,13 +73,13 @@ export function formatNumber(num: string, digits?: number): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Comment up this function to make it clear what's happening here.
|
// TODO: Comment up this function to make it clear what's happening here.
|
||||||
export function formatGasLimit(limit: Wei, transactionUnit: string = 'ether') {
|
export function formatGasLimit(limit: Wei, transactionUnit: string = 'ETH') {
|
||||||
let limitStr = limit.toString();
|
let limitStr = limit.toString();
|
||||||
|
|
||||||
// I'm guessing this is some known off-by-one-error from the node?
|
// I'm guessing this is some known off-by-one-error from the node?
|
||||||
// 21k is only the limit for ethereum though, so make sure they're
|
// 21k is only the limit for ethereum though, so make sure they're
|
||||||
// sending ether if we're going to fix it for them.
|
// sending ether if we're going to fix it for them.
|
||||||
if (limitStr === '21001' && transactionUnit === 'ether') {
|
if (limitStr === '21001' && transactionUnit === 'ETH') {
|
||||||
limitStr = '21000';
|
limitStr = '21000';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import CONTRACTS from 'config/contracts';
|
import CONTRACTS from 'config/contracts';
|
||||||
import { isValidETHAddress } from 'libs/validators';
|
import { isValidETHAddress } from 'libs/validators';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
describe('Contracts JSON', () => {
|
describe('Contracts JSON', () => {
|
||||||
Object.keys(CONTRACTS).forEach(network => {
|
Object.keys(CONTRACTS).forEach(network => {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import TOKENS from 'config/tokens';
|
import TOKENS from 'config/tokens';
|
||||||
import { isValidETHAddress } from 'libs/validators';
|
import { isValidETHAddress } from 'libs/validators';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
describe('Tokens JSON', () => {
|
describe('Tokens JSON', () => {
|
||||||
Object.keys(TOKENS).forEach(network => {
|
Object.keys(TOKENS).forEach(network => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import {
|
import {
|
||||||
decryptPrivKey,
|
decryptPrivKey,
|
||||||
decodeCryptojsSalt,
|
decodeCryptojsSalt,
|
||||||
|
@ -5,6 +6,7 @@ import {
|
||||||
decipherBuffer,
|
decipherBuffer,
|
||||||
decryptMnemonicToPrivKey
|
decryptMnemonicToPrivKey
|
||||||
} from '../../common/libs/decrypt';
|
} from '../../common/libs/decrypt';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
// Elements of a V1 encrypted priv key
|
// Elements of a V1 encrypted priv key
|
||||||
const v1 = {
|
const v1 = {
|
||||||
|
@ -42,11 +44,10 @@ describe('decodeCryptojsSalt', () => {
|
||||||
|
|
||||||
describe('evp_kdf', () => {
|
describe('evp_kdf', () => {
|
||||||
it('should derive correct key and iv', () => {
|
it('should derive correct key and iv', () => {
|
||||||
const result = evp_kdf(
|
const result = evp_kdf(new Buffer(v1.pass, 'utf8'), new Buffer(v1.salt, 'base64'), {
|
||||||
new Buffer(v1.pass, 'utf8'),
|
keysize: 32,
|
||||||
new Buffer(v1.salt, 'base64'),
|
ivsize: 16
|
||||||
{ keysize: 32, ivsize: 16 }
|
});
|
||||||
);
|
|
||||||
|
|
||||||
expect(result.key).toBeInstanceOf(Buffer);
|
expect(result.key).toBeInstanceOf(Buffer);
|
||||||
expect(result.iv).toBeInstanceOf(Buffer);
|
expect(result.iv).toBeInstanceOf(Buffer);
|
||||||
|
@ -78,13 +79,11 @@ describe('decipherBuffer', () => {
|
||||||
describe('decryptMnemonicToPrivKey', () => {
|
describe('decryptMnemonicToPrivKey', () => {
|
||||||
const mocks = [
|
const mocks = [
|
||||||
{
|
{
|
||||||
phrase:
|
phrase: 'first catalog away faculty jelly now life kingdom pigeon raise gain accident',
|
||||||
'first catalog away faculty jelly now life kingdom pigeon raise gain accident',
|
|
||||||
pass: '',
|
pass: '',
|
||||||
path: "m/44'/60'/0'/0/8",
|
path: "m/44'/60'/0'/0/8",
|
||||||
address: '0xe2EdC95134bbD88443bc6D55b809F7d0C2f0C854',
|
address: '0xe2EdC95134bbD88443bc6D55b809F7d0C2f0C854',
|
||||||
privKey:
|
privKey: '31e97f395cabc6faa37d8a9d6bb185187c35704e7b976c7a110e2f0eab37c344'
|
||||||
'31e97f395cabc6faa37d8a9d6bb185187c35704e7b976c7a110e2f0eab37c344'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -92,8 +91,7 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: '',
|
pass: '',
|
||||||
path: "m/44'/60'/0'/0/18",
|
path: "m/44'/60'/0'/0/18",
|
||||||
address: '0xB20f8aCA62e18f4586aAEf4720daCac23cC29954',
|
address: '0xB20f8aCA62e18f4586aAEf4720daCac23cC29954',
|
||||||
privKey:
|
privKey: '594ee624ebad54b9469915c3f5eb22127727a5e380a17d24780dbe272996b401'
|
||||||
'594ee624ebad54b9469915c3f5eb22127727a5e380a17d24780dbe272996b401'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -101,8 +99,7 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: '',
|
pass: '',
|
||||||
path: "m/44'/60'/0'/0/24",
|
path: "m/44'/60'/0'/0/24",
|
||||||
address: '0xE6D0932fFDDcB45bf0e18dE4716137dEdD2E4c2c',
|
address: '0xE6D0932fFDDcB45bf0e18dE4716137dEdD2E4c2c',
|
||||||
privKey:
|
privKey: '6aba8bb6018a85af7cb552325b52e397f83cfb56f68cf8937aa14c3875bbb0aa'
|
||||||
'6aba8bb6018a85af7cb552325b52e397f83cfb56f68cf8937aa14c3875bbb0aa'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -110,8 +107,7 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: '',
|
pass: '',
|
||||||
path: "m/44'/60'/0'/0/0",
|
path: "m/44'/60'/0'/0/0",
|
||||||
address: '0xd163f4d95782608b251c4d985846A1754c53D32C',
|
address: '0xd163f4d95782608b251c4d985846A1754c53D32C',
|
||||||
privKey:
|
privKey: '88046b4bdbb1c88945662cb0984258ca1b09df0bb0b38fdc55bcb8998f28aad4'
|
||||||
'88046b4bdbb1c88945662cb0984258ca1b09df0bb0b38fdc55bcb8998f28aad4'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -119,17 +115,14 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: '',
|
pass: '',
|
||||||
path: "m/44'/60'/0'/0/4",
|
path: "m/44'/60'/0'/0/4",
|
||||||
address: '0x04E2df6Fe2a28dd24dbCC49485ff30Fc3ea04822',
|
address: '0x04E2df6Fe2a28dd24dbCC49485ff30Fc3ea04822',
|
||||||
privKey:
|
privKey: 'fc9ad0931a3aee167179c1fd31825b7a7b558b4bb2eb3fb0c04028c98d495907'
|
||||||
'fc9ad0931a3aee167179c1fd31825b7a7b558b4bb2eb3fb0c04028c98d495907'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase: 'stadium river pigeon midnight grit truck fiscal eight hello rescue destroy eyebrow',
|
||||||
'stadium river pigeon midnight grit truck fiscal eight hello rescue destroy eyebrow',
|
|
||||||
pass: 'password',
|
pass: 'password',
|
||||||
path: "m/44'/60'/0'/0/5",
|
path: "m/44'/60'/0'/0/5",
|
||||||
address: '0xe74908668F594f327fd2215A2564Cf79298a136e',
|
address: '0xe74908668F594f327fd2215A2564Cf79298a136e',
|
||||||
privKey:
|
privKey: 'b65abfb2660f71b4b46aed98975f0cc1ebe1fcb3835a7a10b236e4012c93f306'
|
||||||
'b65abfb2660f71b4b46aed98975f0cc1ebe1fcb3835a7a10b236e4012c93f306'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -137,8 +130,7 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: 'password',
|
pass: 'password',
|
||||||
path: "m/44'/60'/0'/0/10",
|
path: "m/44'/60'/0'/0/10",
|
||||||
address: '0x0d20865AfAE9B8a1F867eCd60684FBCDA3Bd1FA5',
|
address: '0x0d20865AfAE9B8a1F867eCd60684FBCDA3Bd1FA5',
|
||||||
privKey:
|
privKey: '29eb9ec0f5586d1935bc4c6bd89e6fb3de76b4fad345fa844efc5432885cfe73'
|
||||||
'29eb9ec0f5586d1935bc4c6bd89e6fb3de76b4fad345fa844efc5432885cfe73'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -146,8 +138,7 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: 'password',
|
pass: 'password',
|
||||||
path: "m/44'/60'/0'/0/7",
|
path: "m/44'/60'/0'/0/7",
|
||||||
address: '0xdd5d6e5dEfD09c3F2BD6d994EE43B59df88c7187',
|
address: '0xdd5d6e5dEfD09c3F2BD6d994EE43B59df88c7187',
|
||||||
privKey:
|
privKey: 'd13404b9b05f6b5bf8e5cf810aa903e4b60ac654b0acf09a8ea0efe174746ae5'
|
||||||
'd13404b9b05f6b5bf8e5cf810aa903e4b60ac654b0acf09a8ea0efe174746ae5'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -155,8 +146,7 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: 'password',
|
pass: 'password',
|
||||||
path: "m/44'/60'/0'/0/11",
|
path: "m/44'/60'/0'/0/11",
|
||||||
address: '0x6d95e7cC28113F9491b2Ec6b621575a5565Fd208',
|
address: '0x6d95e7cC28113F9491b2Ec6b621575a5565Fd208',
|
||||||
privKey:
|
privKey: 'a52329aa3d6f2426f8783a1e5f419997e2628ec9a89cc2b7b182d2eaf7f95a24'
|
||||||
'a52329aa3d6f2426f8783a1e5f419997e2628ec9a89cc2b7b182d2eaf7f95a24'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -164,8 +154,7 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: 'password',
|
pass: 'password',
|
||||||
path: "m/44'/60'/0'/0/4",
|
path: "m/44'/60'/0'/0/4",
|
||||||
address: '0x3e583eF3d3cE5Dd483c86A1E00A479cE11Ca21Cf',
|
address: '0x3e583eF3d3cE5Dd483c86A1E00A479cE11Ca21Cf',
|
||||||
privKey:
|
privKey: '450538d4181c4d8ce076ecb34785198316adebe959d6f9462cfb68a58b1819bc'
|
||||||
'450538d4181c4d8ce076ecb34785198316adebe959d6f9462cfb68a58b1819bc'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
phrase:
|
phrase:
|
||||||
|
@ -173,20 +162,14 @@ describe('decryptMnemonicToPrivKey', () => {
|
||||||
pass: 'password123',
|
pass: 'password123',
|
||||||
path: "m/44'/60'/0'/1",
|
path: "m/44'/60'/0'/1",
|
||||||
address: '0x7545D615643F933c34C3E083E68CC831167F31af',
|
address: '0x7545D615643F933c34C3E083E68CC831167F31af',
|
||||||
privKey:
|
privKey: '0a43098da5ae737843e385b76b44266a9f8f856cb1b943055b5a96188d306d97'
|
||||||
'0a43098da5ae737843e385b76b44266a9f8f856cb1b943055b5a96188d306d97'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
it('should derive correct private key from variable phrase lengths/passwords/paths', () => {
|
it('should derive correct private key from variable phrase lengths/passwords/paths', () => {
|
||||||
mocks.forEach(mock => {
|
mocks.forEach(mock => {
|
||||||
const { phrase, pass, path, privKey, address } = mock;
|
const { phrase, pass, path, privKey, address } = mock;
|
||||||
const derivedPrivKey = decryptMnemonicToPrivKey(
|
const derivedPrivKey = decryptMnemonicToPrivKey(phrase, pass, path, address);
|
||||||
phrase,
|
|
||||||
pass,
|
|
||||||
path,
|
|
||||||
address
|
|
||||||
);
|
|
||||||
expect(derivedPrivKey.toString('hex')).toEqual(privKey);
|
expect(derivedPrivKey.toString('hex')).toEqual(privKey);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { toWei } from 'libs/units';
|
import { toWei } from 'libs/units';
|
||||||
import ERC20 from 'libs/erc20';
|
import ERC20 from 'libs/erc20';
|
||||||
|
configuredStore.getState();
|
||||||
const MYCRYPTO_ADDRESS = '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8';
|
const MYCRYPTO_ADDRESS = '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8';
|
||||||
|
|
||||||
describe('ERC20', () => {
|
describe('ERC20', () => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import {
|
import {
|
||||||
fromWei,
|
fromWei,
|
||||||
Wei,
|
Wei,
|
||||||
|
@ -8,6 +9,7 @@ import {
|
||||||
convertTokenBase,
|
convertTokenBase,
|
||||||
TokenValue
|
TokenValue
|
||||||
} from 'libs/units';
|
} from 'libs/units';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
const Units = {
|
const Units = {
|
||||||
wei: '1',
|
wei: '1',
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import {
|
import {
|
||||||
isValidBTCAddress,
|
isValidBTCAddress,
|
||||||
isValidETHAddress,
|
isValidETHAddress,
|
||||||
|
@ -6,6 +7,7 @@ import {
|
||||||
} from '../../common/libs/validators';
|
} from '../../common/libs/validators';
|
||||||
import { DPaths } from 'config/dpaths';
|
import { DPaths } from 'config/dpaths';
|
||||||
import { valid, invalid } from '../utils/testStrings';
|
import { valid, invalid } from '../utils/testStrings';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
const VALID_BTC_ADDRESS = '1MEWT2SGbqtz6mPCgFcnea8XmWV5Z4Wc6';
|
const VALID_BTC_ADDRESS = '1MEWT2SGbqtz6mPCgFcnea8XmWV5Z4Wc6';
|
||||||
const VALID_ETH_ADDRESS = '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8';
|
const VALID_ETH_ADDRESS = '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Enzyme from 'enzyme';
|
import Enzyme from 'enzyme';
|
||||||
import Adapter from 'enzyme-adapter-react-16';
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
@ -6,6 +7,7 @@ import shallowWithStore from '../utils/shallowWithStore';
|
||||||
import { createMockStore } from 'redux-test-utils';
|
import { createMockStore } from 'redux-test-utils';
|
||||||
import { createMockRouteComponentProps } from '../utils/mockRouteComponentProps';
|
import { createMockRouteComponentProps } from '../utils/mockRouteComponentProps';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
Enzyme.configure({ adapter: new Adapter() });
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { web3SetNode, web3UnsetNode } from 'actions/config';
|
import { web3SetNode, web3UnsetNode } from 'actions/config';
|
||||||
import { staticNodes, INITIAL_STATE } from 'reducers/config/nodes/staticNodes';
|
import { staticNodes, INITIAL_STATE } from 'reducers/config/nodes/staticNodes';
|
||||||
import { EtherscanNode, InfuraNode, RPCNode } from 'libs/nodes';
|
import { EtherscanNode, InfuraNode, RPCNode } from 'libs/nodes';
|
||||||
import { Web3NodeConfig } from 'types/node';
|
import { Web3NodeConfig } from 'types/node';
|
||||||
import { Web3Service } from 'libs/nodes/web3';
|
import { Web3Service } from 'libs/nodes/web3';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
const expectedInitialState = {
|
const expectedInitialState = {
|
||||||
eth_mycrypto: {
|
eth_mycrypto: {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { deterministicWallets, INITIAL_STATE } from 'reducers/deterministicWallets';
|
import { deterministicWallets, INITIAL_STATE } from 'reducers/deterministicWallets';
|
||||||
import * as dWalletActions from 'actions/deterministicWallets';
|
import * as dWalletActions from 'actions/deterministicWallets';
|
||||||
import { TokenValue } from 'libs/units';
|
import { TokenValue } from 'libs/units';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
describe('deterministicWallets reducer', () => {
|
describe('deterministicWallets reducer', () => {
|
||||||
const tokenValues: dWalletActions.ITokenValues = {
|
const tokenValues: dWalletActions.ITokenValues = {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { wallet, INITIAL_STATE } from 'reducers/wallet';
|
import { wallet, INITIAL_STATE } from 'reducers/wallet';
|
||||||
import { Wei } from 'libs/units';
|
import { Wei } from 'libs/units';
|
||||||
import * as walletActions from 'actions/wallet';
|
import * as walletActions from 'actions/wallet';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
describe('wallet reducer', () => {
|
describe('wallet reducer', () => {
|
||||||
it('should handle WALLET_SET', () => {
|
it('should handle WALLET_SET', () => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { Address } from 'libs/units';
|
import { Address } from 'libs/units';
|
||||||
import { call, select, put } from 'redux-saga/effects';
|
import { call, select, put } from 'redux-saga/effects';
|
||||||
import { isValidETHAddress, isValidENSAddress } from 'libs/validators';
|
import { isValidETHAddress, isValidENSAddress } from 'libs/validators';
|
||||||
|
@ -5,6 +6,7 @@ import { setCurrentTo, setField } from 'sagas/transaction/current/currentTo';
|
||||||
import { isEtherTransaction } from 'selectors/transaction';
|
import { isEtherTransaction } from 'selectors/transaction';
|
||||||
import { cloneableGenerator } from 'redux-saga/utils';
|
import { cloneableGenerator } from 'redux-saga/utils';
|
||||||
import { setToField, setTokenTo } from 'actions/transaction';
|
import { setToField, setTokenTo } from 'actions/transaction';
|
||||||
|
configuredStore.getState();
|
||||||
const raw = '0xa';
|
const raw = '0xa';
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { call, put } from 'redux-saga/effects';
|
import { call, put } from 'redux-saga/effects';
|
||||||
import { setDataField, setGasLimitField, setNonceField } from 'actions/transaction/actionCreators';
|
import { setDataField, setGasLimitField, setNonceField } from 'actions/transaction/actionCreators';
|
||||||
|
@ -11,6 +12,7 @@ import {
|
||||||
} from 'sagas/transaction/fields/fields';
|
} from 'sagas/transaction/fields/fields';
|
||||||
import { cloneableGenerator } from 'redux-saga/utils';
|
import { cloneableGenerator } from 'redux-saga/utils';
|
||||||
import { setGasPriceField } from 'actions/transaction';
|
import { setGasPriceField } from 'actions/transaction';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
const itShouldBeDone = gen => {
|
const itShouldBeDone = gen => {
|
||||||
it('should be done', () => {
|
it('should be done', () => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { select, call, put } from 'redux-saga/effects';
|
import { select, call, put } from 'redux-saga/effects';
|
||||||
import { setDataField } from 'actions/transaction';
|
import { setDataField } from 'actions/transaction';
|
||||||
import { encodeTransfer } from 'libs/transaction/utils/token';
|
import { encodeTransfer } from 'libs/transaction/utils/token';
|
||||||
|
@ -6,6 +7,7 @@ import { bufferToHex, toBuffer } from 'ethereumjs-util';
|
||||||
import { getTokenTo, getData } from 'selectors/transaction';
|
import { getTokenTo, getData } from 'selectors/transaction';
|
||||||
import { handleTokenTo, handleTokenValue } from 'sagas/transaction/meta/token';
|
import { handleTokenTo, handleTokenValue } from 'sagas/transaction/meta/token';
|
||||||
import { cloneableGenerator } from 'redux-saga/utils';
|
import { cloneableGenerator } from 'redux-saga/utils';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
const itShouldBeDone = gen => {
|
const itShouldBeDone = gen => {
|
||||||
it('should be done', () => {
|
it('should be done', () => {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { bufferToHex } from 'ethereumjs-util';
|
||||||
import { rebaseUserInput, validateInput } from 'sagas/transaction/validationHelpers';
|
import { rebaseUserInput, validateInput } from 'sagas/transaction/validationHelpers';
|
||||||
import { cloneableGenerator } from 'redux-saga/utils';
|
import { cloneableGenerator } from 'redux-saga/utils';
|
||||||
import { handleSetUnitMeta } from 'sagas/transaction/meta/unitSwap';
|
import { handleSetUnitMeta } from 'sagas/transaction/meta/unitSwap';
|
||||||
|
import { isNetworkUnit } from 'selectors/config';
|
||||||
|
|
||||||
const itShouldBeDone = gen => {
|
const itShouldBeDone = gen => {
|
||||||
it('should be done', () => {
|
it('should be done', () => {
|
||||||
|
@ -27,25 +28,41 @@ const itShouldBeDone = gen => {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('handleSetUnitMeta*', () => {
|
describe('handleSetUnitMeta*', () => {
|
||||||
const expectedStart = (gen, previousUnit, currentUnit) => {
|
const expectedStart = (
|
||||||
|
gen,
|
||||||
|
previousUnit,
|
||||||
|
currentUnit,
|
||||||
|
prevUnitIsNetworkUnit,
|
||||||
|
currUnitIsNetworkUnit
|
||||||
|
) => {
|
||||||
it('should select getPreviousUnit', () => {
|
it('should select getPreviousUnit', () => {
|
||||||
expect(gen.next().value).toEqual(select(getPreviousUnit));
|
expect(gen.next().value).toEqual(select(getPreviousUnit));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should check if prevUnit is a network unit', () => {
|
||||||
|
expect(gen.next(previousUnit).value).toEqual(select(isNetworkUnit, previousUnit));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should check if currUnit is a network unit', () => {
|
||||||
|
expect(gen.next(prevUnitIsNetworkUnit).value).toEqual(select(isNetworkUnit, currentUnit));
|
||||||
|
});
|
||||||
|
|
||||||
it('should select getDeciimalFromUnit with currentUnit', () => {
|
it('should select getDeciimalFromUnit with currentUnit', () => {
|
||||||
expect(gen.next(previousUnit).value).toEqual(select(getDecimalFromUnit, currentUnit));
|
expect(gen.next(currUnitIsNetworkUnit).value).toEqual(
|
||||||
|
select(getDecimalFromUnit, currentUnit)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('etherToEther', () => {
|
describe('etherToEther', () => {
|
||||||
const currentUnit = 'ether';
|
const currentUnit = 'ETH';
|
||||||
const previousUnit = 'ether';
|
const previousUnit = 'ETH';
|
||||||
const action: any = {
|
const action: any = {
|
||||||
payload: currentUnit
|
payload: currentUnit
|
||||||
};
|
};
|
||||||
const gen = handleSetUnitMeta(action);
|
const gen = handleSetUnitMeta(action);
|
||||||
|
|
||||||
expectedStart(gen, previousUnit, currentUnit);
|
expectedStart(gen, previousUnit, currentUnit, true, true);
|
||||||
|
|
||||||
it('should return correctly', () => {
|
it('should return correctly', () => {
|
||||||
expect(gen.next().value).toEqual(undefined);
|
expect(gen.next().value).toEqual(undefined);
|
||||||
|
@ -56,7 +73,7 @@ describe('handleSetUnitMeta*', () => {
|
||||||
|
|
||||||
describe('tokenToEther', () => {
|
describe('tokenToEther', () => {
|
||||||
const previousUnit = 'token';
|
const previousUnit = 'token';
|
||||||
const currentUnit = 'ether';
|
const currentUnit = 'ETH';
|
||||||
const action: any = {
|
const action: any = {
|
||||||
payload: currentUnit
|
payload: currentUnit
|
||||||
};
|
};
|
||||||
|
@ -67,7 +84,7 @@ describe('handleSetUnitMeta*', () => {
|
||||||
const value: any = 'value';
|
const value: any = 'value';
|
||||||
const gen = handleSetUnitMeta(action);
|
const gen = handleSetUnitMeta(action);
|
||||||
|
|
||||||
expectedStart(gen, previousUnit, currentUnit);
|
expectedStart(gen, previousUnit, currentUnit, false, true);
|
||||||
|
|
||||||
it('should select getTokenTo', () => {
|
it('should select getTokenTo', () => {
|
||||||
expect(gen.next(decimal).value).toEqual(select(getTokenTo));
|
expect(gen.next(decimal).value).toEqual(select(getTokenTo));
|
||||||
|
@ -146,7 +163,7 @@ describe('handleSetUnitMeta*', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('etherToToken', () => {
|
describe('etherToToken', () => {
|
||||||
const previousUnit = 'ether';
|
const previousUnit = 'ETH';
|
||||||
const currentUnit = 'token';
|
const currentUnit = 'token';
|
||||||
const action: any = {
|
const action: any = {
|
||||||
payload: currentUnit
|
payload: currentUnit
|
||||||
|
@ -164,7 +181,7 @@ describe('handleSetUnitMeta*', () => {
|
||||||
const gens: any = {};
|
const gens: any = {};
|
||||||
gens.gen = cloneableGenerator(handleSetUnitMeta)(action);
|
gens.gen = cloneableGenerator(handleSetUnitMeta)(action);
|
||||||
|
|
||||||
expectedStart(gens.gen, previousUnit, currentUnit);
|
expectedStart(gens.gen, previousUnit, currentUnit, true, false);
|
||||||
|
|
||||||
sharedLogicA(gens.gen, decimal, currentUnit);
|
sharedLogicA(gens.gen, decimal, currentUnit);
|
||||||
|
|
||||||
|
@ -211,7 +228,7 @@ describe('handleSetUnitMeta*', () => {
|
||||||
const gens: any = {};
|
const gens: any = {};
|
||||||
gens.gen = cloneableGenerator(handleSetUnitMeta)(action);
|
gens.gen = cloneableGenerator(handleSetUnitMeta)(action);
|
||||||
|
|
||||||
expectedStart(gens.gen, previousUnit, currentUnit);
|
expectedStart(gens.gen, previousUnit, currentUnit, false, false);
|
||||||
|
|
||||||
sharedLogicA(gens.gen, decimal, currentUnit);
|
sharedLogicA(gens.gen, decimal, currentUnit);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { apply, put, select } from 'redux-saga/effects';
|
import { apply, put, select } from 'redux-saga/effects';
|
||||||
import { getWalletInst } from 'selectors/wallet';
|
import { getWalletInst } from 'selectors/wallet';
|
||||||
import { getFromSucceeded, getFromFailed } from 'actions/transaction';
|
import { getFromSucceeded, getFromFailed } from 'actions/transaction';
|
||||||
import { showNotification } from 'actions/notifications';
|
import { showNotification } from 'actions/notifications';
|
||||||
import { cloneableGenerator } from 'redux-saga/utils';
|
import { cloneableGenerator } from 'redux-saga/utils';
|
||||||
import { handleFromRequest } from 'sagas/transaction/network/from';
|
import { handleFromRequest } from 'sagas/transaction/network/from';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
describe('handleFromRequest*', () => {
|
describe('handleFromRequest*', () => {
|
||||||
const walletInst: any = {
|
const walletInst: any = {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { getWalletInst } from 'selectors/wallet';
|
import { getWalletInst } from 'selectors/wallet';
|
||||||
import { getNetworkConfig } from 'selectors/config';
|
import { getNetworkConfig } from 'selectors/config';
|
||||||
import { select, call, put, take } from 'redux-saga/effects';
|
import { select, call, put, take } from 'redux-saga/effects';
|
||||||
import { signTransactionFailed, getFromRequested, TypeKeys as TK } from 'actions/transaction';
|
import { signTransactionFailed, getFromRequested, TypeKeys as TK } from 'actions/transaction';
|
||||||
import { showNotification } from 'actions/notifications';
|
import { showNotification } from 'actions/notifications';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
import 'actions/transaction';
|
import 'actions/transaction';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { put, apply, call } from 'redux-saga/effects';
|
import { put, apply, call } from 'redux-saga/effects';
|
||||||
import { signLocalTransactionSucceeded, signWeb3TransactionSucceeded } from 'actions/transaction';
|
import { signLocalTransactionSucceeded, signWeb3TransactionSucceeded } from 'actions/transaction';
|
||||||
import { computeIndexingHash } from 'libs/transaction';
|
import { computeIndexingHash } from 'libs/transaction';
|
||||||
|
@ -5,6 +6,7 @@ import {
|
||||||
signLocalTransactionHandler,
|
signLocalTransactionHandler,
|
||||||
signWeb3TransactionHandler
|
signWeb3TransactionHandler
|
||||||
} from 'sagas/transaction/signing/signing';
|
} from 'sagas/transaction/signing/signing';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
describe('signLocalTransactionHandler*', () => {
|
describe('signLocalTransactionHandler*', () => {
|
||||||
const tx = 'tx';
|
const tx = 'tx';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { select, call } from 'redux-saga/effects';
|
import { select, call } from 'redux-saga/effects';
|
||||||
import { getUnit, getDecimalFromUnit, getGasLimit, getGasPrice } from 'selectors/transaction';
|
import { getUnit, getDecimalFromUnit, getGasLimit, getGasPrice } from 'selectors/transaction';
|
||||||
import { getEtherBalance, getTokenBalance } from 'selectors/wallet';
|
import { getEtherBalance, getTokenBalance } from 'selectors/wallet';
|
||||||
import { isEtherUnit, toTokenBase, Wei } from 'libs/units';
|
import { toTokenBase, Wei } from 'libs/units';
|
||||||
import { makeTransaction } from 'libs/transaction';
|
import { makeTransaction } from 'libs/transaction';
|
||||||
import {
|
import {
|
||||||
rebaseUserInput,
|
rebaseUserInput,
|
||||||
|
@ -9,7 +9,7 @@ import {
|
||||||
makeCostCalculationTx
|
makeCostCalculationTx
|
||||||
} from 'sagas/transaction/validationHelpers';
|
} from 'sagas/transaction/validationHelpers';
|
||||||
import { cloneableGenerator } from 'redux-saga/utils';
|
import { cloneableGenerator } from 'redux-saga/utils';
|
||||||
import { getOffline } from 'selectors/config';
|
import { getOffline, isNetworkUnit } from 'selectors/config';
|
||||||
|
|
||||||
const itShouldBeDone = gen => {
|
const itShouldBeDone = gen => {
|
||||||
it('should be done', () => {
|
it('should be done', () => {
|
||||||
|
@ -80,7 +80,6 @@ describe('validateInput*', () => {
|
||||||
const input: any = 'input';
|
const input: any = 'input';
|
||||||
const unit = 'unit';
|
const unit = 'unit';
|
||||||
const etherBalance = Wei('1000');
|
const etherBalance = Wei('1000');
|
||||||
const isOffline = false;
|
|
||||||
const etherTransaction = true;
|
const etherTransaction = true;
|
||||||
const validationTx = {
|
const validationTx = {
|
||||||
gasLimit: Wei('30'),
|
gasLimit: Wei('30'),
|
||||||
|
@ -101,27 +100,24 @@ describe('validateInput*', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should select getOffline', () => {
|
it('should select getOffline', () => {
|
||||||
gens.clone1 = gens.gen.clone();
|
|
||||||
gens.clone2 = gens.gen.clone();
|
gens.clone2 = gens.gen.clone();
|
||||||
expect(gens.gen.next(etherBalance).value).toEqual(select(getOffline));
|
expect(gens.gen.next(etherBalance).value).toEqual(select(getOffline));
|
||||||
|
gens.clone1 = gens.gen.clone();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call isEtherUnit', () => {
|
it('should call isNetworkUnit', () => {
|
||||||
expect(gens.gen.next(isOffline).value).toEqual(call(isEtherUnit, unit));
|
expect(gens.gen.next(false).value).toEqual(select(isNetworkUnit, unit));
|
||||||
gens.clone3 = gens.gen.clone();
|
gens.clone3 = gens.gen.clone();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true when offline', () => {
|
it('should return true when offline', () => {
|
||||||
gens.clone1.next();
|
expect(gens.clone1.next(true).value).toEqual(select(isNetworkUnit, unit));
|
||||||
gens.clone1.next(true);
|
|
||||||
expect(gens.clone1.next(true).value).toEqual(true);
|
|
||||||
expect(gens.clone1.next().done).toEqual(true);
|
expect(gens.clone1.next().done).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return when !etherBalance', () => {
|
it('should return when !etherBalance', () => {
|
||||||
gens.clone2.next(null);
|
expect(gens.clone2.next(null).value).toEqual(select(getOffline));
|
||||||
gens.clone2.next(false);
|
expect(gens.clone2.next(true).value).toEqual(select(isNetworkUnit, unit));
|
||||||
expect(gens.clone2.next().value).toEqual(true);
|
|
||||||
expect(gens.clone2.next().done).toEqual(true);
|
expect(gens.clone2.next().done).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configuredStore } from 'store';
|
||||||
import { Wei } from 'libs/units';
|
import { Wei } from 'libs/units';
|
||||||
import {
|
import {
|
||||||
toFixedIfLarger,
|
toFixedIfLarger,
|
||||||
|
@ -5,6 +6,7 @@ import {
|
||||||
formatGasLimit,
|
formatGasLimit,
|
||||||
formatMnemonic
|
formatMnemonic
|
||||||
} from '../../common/utils/formatters';
|
} from '../../common/utils/formatters';
|
||||||
|
configuredStore.getState();
|
||||||
|
|
||||||
describe('toFixedIfLarger', () => {
|
describe('toFixedIfLarger', () => {
|
||||||
it('should return same value if decimal isnt longer than default', () => {
|
it('should return same value if decimal isnt longer than default', () => {
|
||||||
|
@ -83,11 +85,11 @@ describe('formatNumber', () => {
|
||||||
|
|
||||||
describe('formatGasLimit', () => {
|
describe('formatGasLimit', () => {
|
||||||
it('should fix transaction gas limit off-by-one errors', () => {
|
it('should fix transaction gas limit off-by-one errors', () => {
|
||||||
expect(formatGasLimit(Wei('21001'), 'ether')).toEqual('21000');
|
expect(formatGasLimit(Wei('21001'), 'ETH')).toEqual('21000');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should mark the gas limit `-1` if you exceed the limit per block', () => {
|
it('should mark the gas limit `-1` if you exceed the limit per block', () => {
|
||||||
expect(formatGasLimit(Wei('999999999999999'), 'ether')).toEqual('-1');
|
expect(formatGasLimit(Wei('999999999999999'), 'ETH')).toEqual('-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not alter a valid gas limit', () => {
|
it('should not alter a valid gas limit', () => {
|
||||||
|
|
Loading…
Reference in New Issue