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