Merge branch 'develop' of https://github.com/MyEtherWallet/MyEtherWallet into gas-slider
This commit is contained in:
commit
a7d7bcade7
|
@ -1,6 +1,6 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Query } from 'components/renderCbs';
|
||||
import { ICurrentValue, getCurrentValue, isValidAmount } from 'selectors/transaction';
|
||||
import { ICurrentValue, getCurrentValue, nonStandardTransaction } from 'selectors/transaction';
|
||||
import { AppState } from 'reducers';
|
||||
import { connect } from 'react-redux';
|
||||
import { CallbackProps } from 'components/AmountFieldFactory';
|
||||
|
@ -11,15 +11,15 @@ interface OwnProps {
|
|||
}
|
||||
|
||||
interface StateProps {
|
||||
isNonStandard: boolean;
|
||||
currentValue: ICurrentValue;
|
||||
validAmount: boolean;
|
||||
}
|
||||
|
||||
type Props = OwnProps & StateProps;
|
||||
|
||||
class AmountInputClass extends Component<Props> {
|
||||
public render() {
|
||||
const { currentValue, onChange, withProps, validAmount } = this.props;
|
||||
const { currentValue, onChange, withProps, isNonStandard } = this.props;
|
||||
|
||||
return (
|
||||
<Query
|
||||
|
@ -27,7 +27,7 @@ class AmountInputClass extends Component<Props> {
|
|||
withQuery={({ readOnly }) =>
|
||||
withProps({
|
||||
currentValue,
|
||||
isValid: validAmount,
|
||||
isValid: !!currentValue.value || isNonStandard,
|
||||
readOnly: !!readOnly,
|
||||
onChange
|
||||
})
|
||||
|
@ -39,5 +39,5 @@ class AmountInputClass extends Component<Props> {
|
|||
|
||||
export const AmountInput = connect((state: AppState) => ({
|
||||
currentValue: getCurrentValue(state),
|
||||
validAmount: isValidAmount(state)
|
||||
isNonStandard: nonStandardTransaction(state)
|
||||
}))(AmountInputClass);
|
||||
|
|
|
@ -7,7 +7,6 @@ import { AppState } from 'reducers';
|
|||
import {
|
||||
getTransaction,
|
||||
isNetworkRequestPending,
|
||||
isValidAmount,
|
||||
isValidGasPrice,
|
||||
isValidGasLimit
|
||||
} from 'selectors/transaction';
|
||||
|
@ -18,7 +17,6 @@ interface StateProps {
|
|||
networkRequestPending: boolean;
|
||||
isFullTransaction: boolean;
|
||||
isWeb3Wallet: boolean;
|
||||
validAmount: boolean;
|
||||
validGasPrice: boolean;
|
||||
validGasLimit: boolean;
|
||||
}
|
||||
|
@ -30,17 +28,13 @@ class GenerateTransactionClass extends Component<StateProps> {
|
|||
isWeb3Wallet,
|
||||
transaction,
|
||||
networkRequestPending,
|
||||
validAmount,
|
||||
|
||||
validGasPrice,
|
||||
validGasLimit
|
||||
} = this.props;
|
||||
|
||||
const isButtonDisabled =
|
||||
!isFullTransaction ||
|
||||
networkRequestPending ||
|
||||
!validAmount ||
|
||||
!validGasPrice ||
|
||||
!validGasLimit;
|
||||
!isFullTransaction || networkRequestPending || !validGasPrice || !validGasLimit;
|
||||
return (
|
||||
<WithSigner
|
||||
isWeb3={isWeb3Wallet}
|
||||
|
@ -62,7 +56,6 @@ export const GenerateTransaction = connect((state: AppState) => ({
|
|||
...getTransaction(state),
|
||||
networkRequestPending: isNetworkRequestPending(state),
|
||||
isWeb3Wallet: getWalletType(state).isWeb3Wallet,
|
||||
validAmount: isValidAmount(state, false),
|
||||
validGasPrice: isValidGasPrice(state),
|
||||
validGasLimit: isValidGasLimit(state)
|
||||
}))(GenerateTransactionClass);
|
||||
|
|
|
@ -15,7 +15,7 @@ import { isSupportedUnit } from 'selectors/config';
|
|||
import { isEtherUnit } from 'libs/units';
|
||||
import { showLiteSend, configureLiteSend } from 'actions/swap';
|
||||
import { TypeKeys as SwapTK } from 'actions/swap/constants';
|
||||
import { isUnlocked } from 'selectors/wallet';
|
||||
import { isUnlocked, isEtherBalancePending } from 'selectors/wallet';
|
||||
|
||||
type SwapState = AppState['swap'];
|
||||
|
||||
|
@ -48,6 +48,11 @@ export function* configureLiteSendSaga(): SagaIterator {
|
|||
WalletTK.WALLET_SET_TOKEN_BALANCE_FULFILLED,
|
||||
WalletTK.WALLET_SET_TOKEN_BALANCE_REJECTED
|
||||
]);
|
||||
} else {
|
||||
const etherBalanceResolving: boolean = yield select(isEtherBalancePending);
|
||||
if (etherBalanceResolving) {
|
||||
yield take([WalletTK.WALLET_SET_BALANCE_FULFILLED, WalletTK.WALLET_SET_BALANCE_REJECTED]);
|
||||
}
|
||||
}
|
||||
|
||||
yield put(setUnitMeta(id));
|
||||
|
|
|
@ -3,9 +3,7 @@ import { getUnit, getTokenTo, getTokenValue } from './meta';
|
|||
import { AppState } from 'reducers';
|
||||
import { isEtherUnit, TokenValue, Wei, Address } from 'libs/units';
|
||||
import { gasPriceValidator, gasLimitValidator } from 'libs/validators';
|
||||
import { getDataExists, getValidGasCost, getGasPrice, getGasLimit } from 'selectors/transaction';
|
||||
import { getCurrentBalance } from 'selectors/wallet';
|
||||
import { getOffline } from 'selectors/config';
|
||||
import { getDataExists, getGasPrice, getGasLimit } from 'selectors/transaction';
|
||||
|
||||
interface ICurrentValue {
|
||||
raw: string;
|
||||
|
@ -40,55 +38,6 @@ const isValidCurrentTo = (state: AppState) => {
|
|||
}
|
||||
};
|
||||
|
||||
const isValidAmount = (state: AppState, checkValue: boolean = true): boolean => {
|
||||
const currentValue = getCurrentValue(state);
|
||||
const dataExists = getDataExists(state);
|
||||
const validGasCost = getValidGasCost(state);
|
||||
const isOffline = getOffline(state);
|
||||
|
||||
// If value is an empty string, mark as invalid
|
||||
if (checkValue && !currentValue.raw) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If offline, assume amount is valid
|
||||
if (isOffline) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We do some wallet validation here.
|
||||
// For some reason with MetaMask, sometimes the currentValue.value is not a null
|
||||
// but instead a BN with a value equal to currentValue.raw - even though the wallet
|
||||
// doesn't have enough of a balance.
|
||||
|
||||
// Get the wallet balance (token value or ether value)
|
||||
const walletBalance = getCurrentBalance(state);
|
||||
|
||||
// We ensure that we have a valid walletBalance (token or Ether is fine)
|
||||
if (!walletBalance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isEtherTransaction(state)) {
|
||||
// if data exists with no value, just check if gas is enough
|
||||
if (dataExists && !currentValue.value && currentValue.raw === '') {
|
||||
return validGasCost;
|
||||
}
|
||||
// if the currentValue.value is not null, then compare it against the walletBalance.
|
||||
if (currentValue.value) {
|
||||
return walletBalance.cmp(currentValue.value) > 0;
|
||||
}
|
||||
|
||||
return !!currentValue.value;
|
||||
} else {
|
||||
// if the currentValue.value is not null, then compare it against the walletBalance.
|
||||
if (currentValue.value) {
|
||||
return walletBalance.cmp(currentValue.value) > 0;
|
||||
}
|
||||
return !!currentValue.value;
|
||||
}
|
||||
};
|
||||
|
||||
const isValidGasPrice = (state: AppState): boolean => gasPriceValidator(getGasPrice(state).raw);
|
||||
|
||||
const isValidGasLimit = (state: AppState): boolean => gasLimitValidator(getGasLimit(state).raw);
|
||||
|
@ -100,7 +49,6 @@ export {
|
|||
ICurrentTo,
|
||||
isEtherTransaction,
|
||||
isValidCurrentTo,
|
||||
isValidAmount,
|
||||
isValidGasPrice,
|
||||
isValidGasLimit
|
||||
};
|
||||
|
|
|
@ -108,6 +108,9 @@ export const getWalletType = (state: AppState): IWalletType => {
|
|||
|
||||
export const isUnlocked = (state: AppState) => !!getWalletInst(state);
|
||||
|
||||
export const isEtherBalancePending = (state: AppState): boolean =>
|
||||
getWallet(state).balance.isPending;
|
||||
|
||||
export const getEtherBalance = (state: AppState): Wei | null => getWallet(state).balance.wei;
|
||||
|
||||
export const getCurrentBalance = (state: AppState): Wei | TokenValue | null => {
|
||||
|
|
|
@ -48,62 +48,71 @@ module.exports = function(opts = {}) {
|
|||
// Typescript
|
||||
if (options.isProduction || !process.env.SLOW_BUILD_SPEED) {
|
||||
rules.push(config.typescriptRule);
|
||||
}
|
||||
else {
|
||||
threadLoader.warmup(
|
||||
config.typescriptRule.use[0].options,
|
||||
[config.typescriptRule.use[0].loader]
|
||||
);
|
||||
} else {
|
||||
threadLoader.warmup(config.typescriptRule.use[0].options, [
|
||||
config.typescriptRule.use[0].loader
|
||||
]);
|
||||
rules.push({
|
||||
...config.typescriptRule,
|
||||
use: [{
|
||||
loader: 'thread-loader',
|
||||
options: {
|
||||
workers: 4
|
||||
}
|
||||
}, ...config.typescriptRule.use],
|
||||
use: [
|
||||
{
|
||||
loader: 'thread-loader',
|
||||
options: {
|
||||
workers: 4
|
||||
}
|
||||
},
|
||||
...config.typescriptRule.use
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Styles (CSS, SCSS, LESS)
|
||||
if (options.isProduction) {
|
||||
rules.push({
|
||||
test: /\.css$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
fallback: 'style-loader',
|
||||
use: 'css-loader'
|
||||
})
|
||||
}, {
|
||||
test: /\.scss$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
fallback: 'style-loader',
|
||||
use: ['css-loader', 'sass-loader']
|
||||
})
|
||||
}, {
|
||||
test: /\.less$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
fallback: 'style-loader',
|
||||
use: ['css-loader', 'less-loader']
|
||||
})
|
||||
});
|
||||
rules.push(
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
fallback: 'style-loader',
|
||||
use: 'css-loader'
|
||||
})
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
fallback: 'style-loader',
|
||||
use: ['css-loader', 'sass-loader']
|
||||
})
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
fallback: 'style-loader',
|
||||
use: ['css-loader', 'less-loader']
|
||||
})
|
||||
}
|
||||
);
|
||||
} else {
|
||||
rules.push({
|
||||
test: /\.css$/,
|
||||
include: path.resolve(config.path.src, 'vendor'),
|
||||
use: ['style-loader', 'css-loader']
|
||||
}, {
|
||||
test: /\.scss$/,
|
||||
include: ['components', 'containers', 'sass']
|
||||
.map(dir => path.resolve(config.path.src, dir))
|
||||
.concat([config.path.modules]),
|
||||
rules.push(
|
||||
{
|
||||
test: /\.css$/,
|
||||
include: path.resolve(config.path.src, 'vendor'),
|
||||
use: ['style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
include: ['components', 'containers', 'sass']
|
||||
.map(dir => path.resolve(config.path.src, dir))
|
||||
.concat([config.path.modules]),
|
||||
|
||||
exclude: /node_modules(?!\/font-awesome)/,
|
||||
use: ['style-loader', 'css-loader', 'sass-loader']
|
||||
}, {
|
||||
test: /\.less$/,
|
||||
include: path.resolve(config.path.assets, 'styles'),
|
||||
use: ['style-loader', 'css-loader', 'less-loader']
|
||||
});
|
||||
exclude: /node_modules(?!\/font-awesome)/,
|
||||
use: ['style-loader', 'css-loader', 'sass-loader']
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
include: path.resolve(config.path.assets, 'styles'),
|
||||
use: ['style-loader', 'css-loader', 'less-loader']
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Web workers
|
||||
|
@ -114,10 +123,7 @@ module.exports = function(opts = {}) {
|
|||
|
||||
// Images
|
||||
rules.push({
|
||||
include: [
|
||||
path.resolve(config.path.assets),
|
||||
path.resolve(config.path.modules)
|
||||
],
|
||||
include: [path.resolve(config.path.assets), path.resolve(config.path.modules)],
|
||||
exclude: /node_modules(?!\/font-awesome)/,
|
||||
test: /\.(gif|png|jpe?g|svg)$/i,
|
||||
use: [
|
||||
|
@ -152,10 +158,7 @@ module.exports = function(opts = {}) {
|
|||
|
||||
// Fonts
|
||||
rules.push({
|
||||
include: [
|
||||
path.resolve(config.path.assets),
|
||||
path.resolve(config.path.modules)
|
||||
],
|
||||
include: [path.resolve(config.path.assets), path.resolve(config.path.modules)],
|
||||
exclude: /node_modules(?!\/font-awesome)/,
|
||||
test: /\.(ico|eot|otf|webp|ttf|woff|woff2)(\?.*)?$/,
|
||||
loader: 'file-loader'
|
||||
|
@ -193,21 +196,24 @@ module.exports = function(opts = {}) {
|
|||
'process.env.BUILD_DOWNLOADABLE': JSON.stringify(isDownloadable),
|
||||
'process.env.BUILD_HTML': JSON.stringify(options.isHTMLBuild),
|
||||
'process.env.BUILD_ELECTRON': JSON.stringify(options.isElectronBuild)
|
||||
}),
|
||||
})
|
||||
];
|
||||
|
||||
if (options.isProduction) {
|
||||
plugins.push(
|
||||
new BabelMinifyPlugin({
|
||||
// Mangle seems to be reusing variable identifiers, causing errors
|
||||
mangle: false,
|
||||
// These two on top of a lodash file are causing illegal characters for
|
||||
// safari and ios browsers
|
||||
evaluate: false,
|
||||
propertyLiterals: false,
|
||||
}, {
|
||||
comments: false
|
||||
}),
|
||||
new BabelMinifyPlugin(
|
||||
{
|
||||
// Mangle seems to be reusing variable identifiers, causing errors
|
||||
mangle: false,
|
||||
// These two on top of a lodash file are causing illegal characters for
|
||||
// safari and ios browsers
|
||||
evaluate: false,
|
||||
propertyLiterals: false
|
||||
},
|
||||
{
|
||||
comments: false
|
||||
}
|
||||
),
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
filename: 'vendor.[chunkhash:8].js'
|
||||
|
@ -225,9 +231,8 @@ module.exports = function(opts = {}) {
|
|||
new ProgressPlugin(),
|
||||
new ClearDistPlugin(),
|
||||
new SortCachePlugin()
|
||||
)
|
||||
}
|
||||
else {
|
||||
);
|
||||
} else {
|
||||
plugins.push(
|
||||
new AutoDllPlugin({
|
||||
inject: true, // will inject the DLL bundles to index.html
|
||||
|
@ -235,12 +240,7 @@ module.exports = function(opts = {}) {
|
|||
debug: true,
|
||||
context: path.join(config.path.root),
|
||||
entry: {
|
||||
vendor: [
|
||||
...config.vendorModules,
|
||||
'babel-polyfill',
|
||||
'bootstrap-sass',
|
||||
'font-awesome'
|
||||
]
|
||||
vendor: [...config.vendorModules, 'babel-polyfill', 'bootstrap-sass', 'font-awesome']
|
||||
}
|
||||
}),
|
||||
new HardSourceWebpackPlugin({
|
||||
|
@ -259,19 +259,21 @@ module.exports = function(opts = {}) {
|
|||
if (options.isElectronBuild) {
|
||||
// target: 'electron-renderer' kills scrypt, so manually pull in some
|
||||
// of its configuration instead
|
||||
plugins.push(new webpack.ExternalsPlugin("commonjs", [
|
||||
"desktop-capturer",
|
||||
"electron",
|
||||
"ipc",
|
||||
"ipc-renderer",
|
||||
"remote",
|
||||
"web-frame",
|
||||
"clipboard",
|
||||
"crash-reporter",
|
||||
"native-image",
|
||||
"screen",
|
||||
"shell"
|
||||
]));
|
||||
plugins.push(
|
||||
new webpack.ExternalsPlugin('commonjs', [
|
||||
'desktop-capturer',
|
||||
'electron',
|
||||
'ipc',
|
||||
'ipc-renderer',
|
||||
'remote',
|
||||
'web-frame',
|
||||
'clipboard',
|
||||
'crash-reporter',
|
||||
'native-image',
|
||||
'screen',
|
||||
'shell'
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
@ -281,8 +283,7 @@ module.exports = function(opts = {}) {
|
|||
if (!options.isProduction) {
|
||||
if (process.env.SLOW_BUILD_SPEED) {
|
||||
devtool = 'source-map';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
devtool = 'cheap-module-eval-source-map';
|
||||
}
|
||||
}
|
||||
|
@ -295,11 +296,11 @@ module.exports = function(opts = {}) {
|
|||
filename: options.isProduction ? '[name].[chunkhash:8].js' : '[name].js',
|
||||
publicPath: isDownloadable && options.isProduction ? './' : '/',
|
||||
crossOriginLoading: 'anonymous'
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// The final bundle
|
||||
return {
|
||||
devtool,
|
||||
entry,
|
||||
output,
|
||||
module: { rules },
|
||||
|
@ -318,4 +319,4 @@ module.exports = function(opts = {}) {
|
|||
modules: false
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue