1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

Relocate send state into send duck from metamask duck (#11252)

This commit is contained in:
Brad Decker 2021-06-10 12:53:15 -05:00 committed by GitHub
parent 5afd1c9fa6
commit 9e509d0c9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 520 additions and 837 deletions

View File

@ -10,7 +10,7 @@ import InfoIcon from '../../ui/icon/info-icon.component';
import Button from '../../ui/button';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { useMetricEvent } from '../../../hooks/useMetricEvent';
import { updateSendToken } from '../../../store/actions';
import { updateSendToken } from '../../../ducks/send/send.duck';
import { SEND_ROUTE } from '../../../helpers/constants/routes';
import { SEVERITIES } from '../../../helpers/constants/design-system';

View File

@ -1,6 +1,6 @@
import sinon from 'sinon';
import { hideModal, setGasLimit, setGasPrice } from '../../../../store/actions';
import { hideModal } from '../../../../store/actions';
import {
setCustomGasPrice,
@ -8,7 +8,11 @@ import {
resetCustomData,
} from '../../../../ducks/gas/gas.duck';
import { hideGasButtonGroup } from '../../../../ducks/send/send.duck';
import {
hideGasButtonGroup,
setGasLimit,
setGasPrice,
} from '../../../../ducks/send/send.duck';
let mapDispatchToProps;
let mergeProps;
@ -29,7 +33,7 @@ jest.mock('../../../../selectors', () => ({
getDefaultActiveButtonIndex: (a, b) => a + b,
getCurrentEthBalance: (state) => state.metamask.balance || '0x0',
getSendToken: () => null,
getTokenBalance: (state) => state.metamask.send.tokenBalance || '0x0',
getTokenBalance: (state) => state.send.tokenBalance || '0x0',
getCustomGasPrice: (state) => state.gas.customData.price || '0x0',
getCustomGasLimit: (state) => state.gas.customData.limit || '0x0',
getCurrentCurrency: jest.fn().mockReturnValue('usd'),
@ -44,8 +48,6 @@ jest.mock('../../../../selectors', () => ({
jest.mock('../../../../store/actions', () => ({
hideModal: jest.fn(),
setGasLimit: jest.fn(),
setGasPrice: jest.fn(),
updateTransaction: jest.fn(),
}));
@ -57,6 +59,8 @@ jest.mock('../../../../ducks/gas/gas.duck', () => ({
jest.mock('../../../../ducks/send/send.duck', () => ({
hideGasButtonGroup: jest.fn(),
setGasLimit: jest.fn(),
setGasPrice: jest.fn(),
}));
require('./gas-modal-page-container.container');

View File

@ -2,13 +2,9 @@ import { connect } from 'react-redux';
import { addHexPrefix } from '../../../../../app/scripts/lib/util';
import {
hideModal,
setGasLimit,
setGasPrice,
createRetryTransaction,
createSpeedUpTransaction,
hideSidebar,
updateSendAmount,
setGasTotal,
updateTransaction,
} from '../../../../store/actions';
import {
@ -19,6 +15,10 @@ import {
} from '../../../../ducks/gas/gas.duck';
import {
hideGasButtonGroup,
setGasLimit,
setGasPrice,
setGasTotal,
updateSendAmount,
updateSendErrors,
} from '../../../../ducks/send/send.duck';
import {
@ -60,7 +60,10 @@ import { GAS_LIMITS } from '../../../../../shared/constants/gas';
import GasModalPageContainer from './gas-modal-page-container.component';
const mapStateToProps = (state, ownProps) => {
const { currentNetworkTxList, send } = state.metamask;
const {
metamask: { currentNetworkTxList },
send,
} = state;
const { modalState: { props: modalProps } = {} } = state.appState.modal || {};
const { txData = {} } = modalProps || {};
const { transaction = {}, onSubmit } = ownProps;

View File

@ -17,7 +17,7 @@ import {
} from '../../../hooks/useMetricEvent';
import { useTokenTracker } from '../../../hooks/useTokenTracker';
import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount';
import { updateSendToken } from '../../../store/actions';
import { updateSendToken } from '../../../ducks/send/send.duck';
import { setSwapsFromToken } from '../../../ducks/swaps/swaps';
import {
getAssetImages,

View File

@ -37,7 +37,6 @@ export default function reduceApp(state = {}, action) {
warning: null,
buyView: {},
isMouseUser: false,
gasIsLoading: false,
defaultHdPaths: {
trezor: `m/44'/60'/0'/0`,
ledger: `m/44'/60'/0'/0/0`,
@ -293,18 +292,6 @@ export default function reduceApp(state = {}, action) {
isMouseUser: action.value,
};
case actionConstants.GAS_LOADING_STARTED:
return {
...appState,
gasIsLoading: true,
};
case actionConstants.GAS_LOADING_FINISHED:
return {
...appState,
gasIsLoading: false,
};
case actionConstants.SET_SELECTED_SETTINGS_RPC_URL:
return {
...appState,
@ -377,3 +364,8 @@ export function hideWhatsNewPopup() {
type: actionConstants.HIDE_WHATS_NEW_POPUP,
};
}
// Selectors
export function getQrCodeData(state) {
return state.appState.qrCodeData;
}

View File

@ -352,22 +352,4 @@ describe('App State', () => {
expect(state.isMouseUser).toStrictEqual(true);
});
it('sets gas loading', () => {
const state = reduceApp(metamaskState, {
type: actions.GAS_LOADING_STARTED,
});
expect(state.gasIsLoading).toStrictEqual(true);
});
it('unsets gas loading', () => {
const gasLoadingState = { gasIsLoading: true };
const oldState = { ...metamaskState, ...gasLoadingState };
const state = reduceApp(oldState, {
type: actions.GAS_LOADING_FINISHED,
});
expect(state.gasIsLoading).toStrictEqual(false);
});
});

View File

@ -19,22 +19,6 @@ export default function reduceMetamask(state = {}, action) {
tokens: [],
pendingTokens: {},
customNonceValue: '',
send: {
gasLimit: null,
gasPrice: null,
gasTotal: null,
tokenBalance: '0x0',
from: '',
to: '',
amount: '0',
memo: '',
errors: {},
maxModeOn: false,
editingTransactionId: null,
toNickname: '',
ensResolution: null,
ensResolutionError: '',
},
useBlockie: false,
featureFlags: {},
welcomeScreenSeen: false,
@ -106,28 +90,11 @@ export default function reduceMetamask(state = {}, action) {
tokens: action.newTokens,
};
// metamask.send
case actionConstants.UPDATE_GAS_LIMIT:
return {
...metamaskState,
send: {
...metamaskState.send,
gasLimit: action.value,
},
};
case actionConstants.UPDATE_CUSTOM_NONCE:
return {
...metamaskState,
customNonceValue: action.value,
};
case actionConstants.UPDATE_GAS_PRICE:
return {
...metamaskState,
send: {
...metamaskState.send,
gasPrice: action.value,
},
};
case actionConstants.TOGGLE_ACCOUNT_MENU:
return {
@ -135,139 +102,6 @@ export default function reduceMetamask(state = {}, action) {
isAccountMenuOpen: !metamaskState.isAccountMenuOpen,
};
case actionConstants.UPDATE_GAS_TOTAL:
return {
...metamaskState,
send: {
...metamaskState.send,
gasTotal: action.value,
},
};
case actionConstants.UPDATE_SEND_TOKEN_BALANCE:
return {
...metamaskState,
send: {
...metamaskState.send,
tokenBalance: action.value,
},
};
case actionConstants.UPDATE_SEND_HEX_DATA:
return {
...metamaskState,
send: {
...metamaskState.send,
data: action.value,
},
};
case actionConstants.UPDATE_SEND_TO:
return {
...metamaskState,
send: {
...metamaskState.send,
to: action.value.to,
toNickname: action.value.nickname,
},
};
case actionConstants.UPDATE_SEND_AMOUNT:
return {
...metamaskState,
send: {
...metamaskState.send,
amount: action.value,
},
};
case actionConstants.UPDATE_MAX_MODE:
return {
...metamaskState,
send: {
...metamaskState.send,
maxModeOn: action.value,
},
};
case actionConstants.UPDATE_SEND:
return Object.assign(metamaskState, {
send: {
...metamaskState.send,
...action.value,
},
});
case actionConstants.UPDATE_SEND_TOKEN: {
const newSend = {
...metamaskState.send,
token: action.value,
};
// erase token-related state when switching back to native currency
if (newSend.editingTransactionId && !newSend.token) {
const unapprovedTx =
newSend?.unapprovedTxs?.[newSend.editingTransactionId] || {};
const txParams = unapprovedTx.txParams || {};
Object.assign(newSend, {
tokenBalance: null,
balance: '0',
from: unapprovedTx.from || '',
unapprovedTxs: {
...newSend.unapprovedTxs,
[newSend.editingTransactionId]: {
...unapprovedTx,
txParams: {
...txParams,
data: '',
},
},
},
});
}
return Object.assign(metamaskState, {
send: newSend,
});
}
case actionConstants.UPDATE_SEND_ENS_RESOLUTION:
return {
...metamaskState,
send: {
...metamaskState.send,
ensResolution: action.payload,
ensResolutionError: '',
},
};
case actionConstants.UPDATE_SEND_ENS_RESOLUTION_ERROR:
return {
...metamaskState,
send: {
...metamaskState.send,
ensResolution: null,
ensResolutionError: action.payload,
},
};
case actionConstants.CLEAR_SEND:
return {
...metamaskState,
send: {
gasLimit: null,
gasPrice: null,
gasTotal: null,
tokenBalance: null,
from: '',
to: '',
amount: '0x0',
memo: '',
errors: {},
maxModeOn: false,
editingTransactionId: null,
toNickname: '',
},
};
case actionConstants.UPDATE_TRANSACTION_PARAMS: {
const { id: txId, value } = action;
let { currentNetworkTxList } = metamaskState;

View File

@ -150,13 +150,11 @@ describe('MetaMask Reducers', () => {
{},
{
type: actionConstants.SHOW_ACCOUNT_DETAIL,
value: 'test address',
},
);
expect(state.isUnlocked).toStrictEqual(true);
expect(state.isInitialized).toStrictEqual(true);
expect(state.selectedAddress).toStrictEqual('test address');
});
it('sets account label', () => {
@ -194,30 +192,6 @@ describe('MetaMask Reducers', () => {
expect(state.tokens).toStrictEqual(newTokens);
});
it('updates send gas limit', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_GAS_LIMIT,
value: '0xGasLimit',
},
);
expect(state.send.gasLimit).toStrictEqual('0xGasLimit');
});
it('updates send gas price', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_GAS_PRICE,
value: '0xGasPrice',
},
);
expect(state.send.gasPrice).toStrictEqual('0xGasPrice');
});
it('toggles account menu', () => {
const state = reduceMetamask(
{},
@ -229,153 +203,6 @@ describe('MetaMask Reducers', () => {
expect(state.isAccountMenuOpen).toStrictEqual(true);
});
it('updates gas total', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_GAS_TOTAL,
value: '0xGasTotal',
},
);
expect(state.send.gasTotal).toStrictEqual('0xGasTotal');
});
it('updates send token balance', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_SEND_TOKEN_BALANCE,
value: '0xTokenBalance',
},
);
expect(state.send.tokenBalance).toStrictEqual('0xTokenBalance');
});
it('updates data', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_SEND_HEX_DATA,
value: '0xData',
},
);
expect(state.send.data).toStrictEqual('0xData');
});
it('updates send to', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_SEND_TO,
value: {
to: '0xAddress',
nickname: 'nickname',
},
},
);
expect(state.send.to).toStrictEqual('0xAddress');
expect(state.send.toNickname).toStrictEqual('nickname');
});
it('update send amount', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_SEND_AMOUNT,
value: '0xAmount',
},
);
expect(state.send.amount).toStrictEqual('0xAmount');
});
it('updates max mode', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_MAX_MODE,
value: true,
},
);
expect(state.send.maxModeOn).toStrictEqual(true);
});
it('update send', () => {
const value = {
gasLimit: '0xGasLimit',
gasPrice: '0xGasPrice',
gasTotal: '0xGasTotal',
tokenBalance: '0xBalance',
from: '0xAddress',
to: '0xAddress',
toNickname: '',
maxModeOn: false,
amount: '0xAmount',
memo: '0xMemo',
errors: {},
editingTransactionId: 22,
ensResolution: null,
ensResolutionError: '',
};
const sendState = reduceMetamask(
{},
{
type: actionConstants.UPDATE_SEND,
value,
},
);
expect(sendState.send).toStrictEqual(value);
});
it('clears send', () => {
const initStateSend = {
send: {
gasLimit: null,
gasPrice: null,
gasTotal: null,
tokenBalance: null,
from: '',
to: '',
amount: '0x0',
memo: '',
errors: {},
maxModeOn: false,
editingTransactionId: null,
toNickname: '',
},
};
const sendState = {
send: {
gasLimit: '0xGasLimit',
gasPrice: '0xGasPrice',
gasTotal: '0xGasTotal',
tokenBalance: '0xBalance',
from: '0xAddress',
to: '0xAddress',
toNickname: '',
maxModeOn: false,
amount: '0xAmount',
memo: '0xMemo',
errors: {},
editingTransactionId: 22,
},
};
const state = reduceMetamask(sendState, {
type: actionConstants.CLEAR_SEND,
});
expect(state.send).toStrictEqual(initStateSend.send);
});
it('updates value of tx by id', () => {
const oldState = {
currentNetworkTxList: [
@ -480,32 +307,6 @@ describe('MetaMask Reducers', () => {
expect(state.pendingTokens).toStrictEqual({});
});
it('update ensResolution', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_SEND_ENS_RESOLUTION,
payload: '0x1337',
},
);
expect(state.send.ensResolution).toStrictEqual('0x1337');
expect(state.send.ensResolutionError).toStrictEqual('');
});
it('update ensResolutionError', () => {
const state = reduceMetamask(
{},
{
type: actionConstants.UPDATE_SEND_ENS_RESOLUTION_ERROR,
payload: 'ens name not found',
},
);
expect(state.send.ensResolutionError).toStrictEqual('ens name not found');
expect(state.send.ensResolution).toBeNull();
});
describe('metamask state selectors', () => {
describe('getBlockGasLimit', () => {
it('should return the current block gas limit', () => {

View File

@ -12,8 +12,22 @@ describe('Send Duck', () => {
};
const initState = {
toDropdownOpen: false,
errors: {},
gasButtonGroupShown: true,
errors: {},
gasLimit: null,
gasPrice: null,
gasTotal: null,
tokenBalance: '0x0',
from: '',
to: '',
amount: '0',
memo: '',
maxModeOn: false,
editingTransactionId: null,
toNickname: '',
ensResolution: null,
ensResolutionError: '',
gasIsLoading: false,
};
const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN';
const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN';

View File

@ -1,3 +1,11 @@
import log from 'loglevel';
import { estimateGas } from '../../store/actions';
import { setCustomGasLimit } from '../gas/gas.duck';
import {
estimateGasForSend,
calcTokenBalance,
} from '../../pages/send/send.utils';
// Actions
const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN';
const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN';
@ -5,11 +13,40 @@ const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS';
const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE';
const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP';
const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP';
const UPDATE_GAS_LIMIT = 'UPDATE_GAS_LIMIT';
const UPDATE_GAS_PRICE = 'UPDATE_GAS_PRICE';
const UPDATE_GAS_TOTAL = 'UPDATE_GAS_TOTAL';
const UPDATE_SEND_HEX_DATA = 'UPDATE_SEND_HEX_DATA';
const UPDATE_SEND_TOKEN_BALANCE = 'UPDATE_SEND_TOKEN_BALANCE';
const UPDATE_SEND_TO = 'UPDATE_SEND_TO';
const UPDATE_SEND_AMOUNT = 'UPDATE_SEND_AMOUNT';
const UPDATE_MAX_MODE = 'UPDATE_MAX_MODE';
const UPDATE_SEND = 'UPDATE_SEND';
const UPDATE_SEND_TOKEN = 'UPDATE_SEND_TOKEN';
const CLEAR_SEND = 'CLEAR_SEND';
const GAS_LOADING_STARTED = 'GAS_LOADING_STARTED';
const GAS_LOADING_FINISHED = 'GAS_LOADING_FINISHED';
const UPDATE_SEND_ENS_RESOLUTION = 'UPDATE_SEND_ENS_RESOLUTION';
const UPDATE_SEND_ENS_RESOLUTION_ERROR = 'UPDATE_SEND_ENS_RESOLUTION_ERROR';
const initState = {
toDropdownOpen: false,
gasButtonGroupShown: true,
errors: {},
gasLimit: null,
gasPrice: null,
gasTotal: null,
tokenBalance: '0x0',
from: '',
to: '',
amount: '0',
memo: '',
maxModeOn: false,
editingTransactionId: null,
toNickname: '',
ensResolution: null,
ensResolutionError: '',
gasIsLoading: false,
};
// Reducer
@ -43,8 +80,118 @@ export default function reducer(state = initState, action) {
...state,
gasButtonGroupShown: false,
};
case UPDATE_GAS_LIMIT:
return {
...state,
gasLimit: action.value,
};
case UPDATE_GAS_PRICE:
return {
...state,
gasPrice: action.value,
};
case RESET_SEND_STATE:
return { ...initState };
case UPDATE_GAS_TOTAL:
return {
...state,
gasTotal: action.value,
};
case UPDATE_SEND_TOKEN_BALANCE:
return {
...state,
tokenBalance: action.value,
};
case UPDATE_SEND_HEX_DATA:
return {
...state,
data: action.value,
};
case UPDATE_SEND_TO:
return {
...state,
to: action.value.to,
toNickname: action.value.nickname,
};
case UPDATE_SEND_AMOUNT:
return {
...state,
amount: action.value,
};
case UPDATE_MAX_MODE:
return {
...state,
maxModeOn: action.value,
};
case UPDATE_SEND:
return Object.assign(state, action.value);
case UPDATE_SEND_TOKEN: {
const newSend = {
...state,
token: action.value,
};
// erase token-related state when switching back to native currency
if (newSend.editingTransactionId && !newSend.token) {
const unapprovedTx =
newSend?.unapprovedTxs?.[newSend.editingTransactionId] || {};
const txParams = unapprovedTx.txParams || {};
Object.assign(newSend, {
tokenBalance: null,
balance: '0',
from: unapprovedTx.from || '',
unapprovedTxs: {
...newSend.unapprovedTxs,
[newSend.editingTransactionId]: {
...unapprovedTx,
txParams: {
...txParams,
data: '',
},
},
},
});
}
return Object.assign(state, newSend);
}
case UPDATE_SEND_ENS_RESOLUTION:
return {
...state,
ensResolution: action.payload,
ensResolutionError: '',
};
case UPDATE_SEND_ENS_RESOLUTION_ERROR:
return {
...state,
ensResolution: null,
ensResolutionError: action.payload,
};
case CLEAR_SEND:
return {
...state,
gasLimit: null,
gasPrice: null,
gasTotal: null,
tokenBalance: null,
from: '',
to: '',
amount: '0x0',
memo: '',
errors: {},
maxModeOn: false,
editingTransactionId: null,
toNickname: '',
};
case GAS_LOADING_STARTED:
return {
...state,
gasIsLoading: true,
};
case GAS_LOADING_FINISHED:
return {
...state,
gasIsLoading: false,
};
default:
return state;
}
@ -77,3 +224,159 @@ export function updateSendErrors(errorObject) {
export function resetSendState() {
return { type: RESET_SEND_STATE };
}
export function setGasLimit(gasLimit) {
return {
type: UPDATE_GAS_LIMIT,
value: gasLimit,
};
}
export function setGasPrice(gasPrice) {
return {
type: UPDATE_GAS_PRICE,
value: gasPrice,
};
}
export function setGasTotal(gasTotal) {
return {
type: UPDATE_GAS_TOTAL,
value: gasTotal,
};
}
export function updateGasData({
gasPrice,
blockGasLimit,
selectedAddress,
sendToken,
to,
value,
data,
}) {
return (dispatch) => {
dispatch(gasLoadingStarted());
return estimateGasForSend({
estimateGasMethod: estimateGas,
blockGasLimit,
selectedAddress,
sendToken,
to,
value,
estimateGasPrice: gasPrice,
data,
})
.then((gas) => {
dispatch(setGasLimit(gas));
dispatch(setCustomGasLimit(gas));
dispatch(updateSendErrors({ gasLoadingError: null }));
dispatch(gasLoadingFinished());
})
.catch((err) => {
log.error(err);
dispatch(updateSendErrors({ gasLoadingError: 'gasLoadingError' }));
dispatch(gasLoadingFinished());
});
};
}
export function gasLoadingStarted() {
return {
type: GAS_LOADING_STARTED,
};
}
export function gasLoadingFinished() {
return {
type: GAS_LOADING_FINISHED,
};
}
export function updateSendTokenBalance({ sendToken, tokenContract, address }) {
return (dispatch) => {
const tokenBalancePromise = tokenContract
? tokenContract.balanceOf(address)
: Promise.resolve();
return tokenBalancePromise
.then((usersToken) => {
if (usersToken) {
const newTokenBalance = calcTokenBalance({ sendToken, usersToken });
dispatch(setSendTokenBalance(newTokenBalance));
}
})
.catch((err) => {
log.error(err);
updateSendErrors({ tokenBalance: 'tokenBalanceError' });
});
};
}
export function setSendTokenBalance(tokenBalance) {
return {
type: UPDATE_SEND_TOKEN_BALANCE,
value: tokenBalance,
};
}
export function updateSendHexData(value) {
return {
type: UPDATE_SEND_HEX_DATA,
value,
};
}
export function updateSendTo(to, nickname = '') {
return {
type: UPDATE_SEND_TO,
value: { to, nickname },
};
}
export function updateSendAmount(amount) {
return {
type: UPDATE_SEND_AMOUNT,
value: amount,
};
}
export function setMaxModeTo(bool) {
return {
type: UPDATE_MAX_MODE,
value: bool,
};
}
export function updateSend(newSend) {
return {
type: UPDATE_SEND,
value: newSend,
};
}
export function updateSendToken(token) {
return {
type: UPDATE_SEND_TOKEN,
value: token,
};
}
export function clearSend() {
return {
type: CLEAR_SEND,
};
}
export function updateSendEnsResolution(ensResolution) {
return {
type: UPDATE_SEND_ENS_RESOLUTION,
payload: ensResolution,
};
}
export function updateSendEnsResolutionError(errorMessage) {
return {
type: UPDATE_SEND_ENS_RESOLUTION_ERROR,
payload: errorMessage,
};
}

View File

@ -1,7 +1,7 @@
import { connect } from 'react-redux';
import { compose } from 'redux';
import { withRouter } from 'react-router-dom';
import { updateSend } from '../../store/actions';
import { updateSend } from '../../ducks/send/send.duck';
import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck';
import ConfirmSendEther from './confirm-send-ether.component';

View File

@ -2,13 +2,14 @@ import { connect } from 'react-redux';
import { compose } from 'redux';
import { withRouter } from 'react-router-dom';
import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck';
import { updateSend, showSendTokenPage } from '../../store/actions';
import { showSendTokenPage } from '../../store/actions';
import { conversionUtil } from '../../helpers/utils/conversion-util';
import {
getTokenValueParam,
getTokenAddressParam,
} from '../../helpers/utils/token-util';
import { sendTokenTokenAmountAndToAddressSelector } from '../../selectors';
import { updateSend } from '../../ducks/send/send.duck';
import ConfirmSendToken from './confirm-send-token.component';
const mapStateToProps = (state) => {

View File

@ -38,7 +38,7 @@ function mapStateToProps(state) {
unapprovedMsgCount,
unapprovedPersonalMsgCount,
unapprovedTypedMessagesCount,
send: state.metamask.send,
send: state.send,
currentNetworkTxList: state.metamask.currentNetworkTxList,
};
}

View File

@ -19,7 +19,8 @@ import ConfirmTransaction from './confirm-transaction.component';
const mapStateToProps = (state, ownProps) => {
const {
metamask: { send, unapprovedTxs },
metamask: { unapprovedTxs },
send,
} = state;
const {
match: { params = {} },

View File

@ -7,7 +7,7 @@ import {
getAddressBookEntry,
} from '../../../../selectors';
import { updateSendTo } from '../../../../store/actions';
import { updateSendTo } from '../../../../ducks/send/send.duck';
import AddRecipient from './add-recipient.component';
export default connect(mapStateToProps, mapDispatchToProps)(AddRecipient);

View File

@ -1,6 +1,5 @@
import sinon from 'sinon';
import { updateSendTo } from '../../../../store/actions';
import { updateSendTo } from '../../../../ducks/send/send.duck';
let mapStateToProps;
let mapDispatchToProps;
@ -24,7 +23,7 @@ jest.mock('../../../../selectors', () => ({
],
}));
jest.mock('../../../../store/actions', () => ({
jest.mock('../../../../ducks/send/send.duck.js', () => ({
updateSendTo: jest.fn(),
}));

View File

@ -7,8 +7,11 @@ import {
getSendMaxModeState,
getBasicGasEstimateLoadingStatus,
} from '../../../../../selectors';
import { updateSendAmount, setMaxModeTo } from '../../../../../store/actions';
import { updateSendErrors } from '../../../../../ducks/send/send.duck';
import {
updateSendErrors,
updateSendAmount,
setMaxModeTo,
} from '../../../../../ducks/send/send.duck';
import { calcMaxAmount } from './amount-max-button.utils';
import AmountMaxButton from './amount-max-button.component';

View File

@ -1,8 +1,10 @@
import sinon from 'sinon';
import { setMaxModeTo, updateSendAmount } from '../../../../../store/actions';
import { updateSendErrors } from '../../../../../ducks/send/send.duck';
import {
updateSendErrors,
setMaxModeTo,
updateSendAmount,
} from '../../../../../ducks/send/send.duck';
let mapStateToProps;
let mapDispatchToProps;
@ -28,11 +30,9 @@ jest.mock('./amount-max-button.utils.js', () => ({
calcMaxAmount: (mockObj) => mockObj.val + 1,
}));
jest.mock('../../../../../store/actions', () => ({
jest.mock('../../../../../ducks/send/send.duck', () => ({
setMaxModeTo: jest.fn(),
updateSendAmount: jest.fn(),
}));
jest.mock('../../../../../ducks/send/send.duck', () => ({
updateSendErrors: jest.fn(),
}));

View File

@ -10,8 +10,11 @@ import {
sendAmountIsInError,
} from '../../../../selectors';
import { getAmountErrorObject, getGasFeeErrorObject } from '../../send.utils';
import { setMaxModeTo, updateSendAmount } from '../../../../store/actions';
import { updateSendErrors } from '../../../../ducks/send/send.duck';
import {
updateSendErrors,
setMaxModeTo,
updateSendAmount,
} from '../../../../ducks/send/send.duck';
import { getConversionRate } from '../../../../ducks/metamask/metamask';
import SendAmountRow from './send-amount-row.component';

View File

@ -1,8 +1,10 @@
import sinon from 'sinon';
import { setMaxModeTo, updateSendAmount } from '../../../../store/actions';
import { updateSendErrors } from '../../../../ducks/send/send.duck';
import {
updateSendErrors,
setMaxModeTo,
updateSendAmount,
} from '../../../../ducks/send/send.duck';
let mapDispatchToProps;
@ -28,13 +30,10 @@ jest.mock('../../send.utils', () => ({
}),
}));
jest.mock('../../../../store/actions', () => ({
setMaxModeTo: jest.fn(),
updateSendAmount: jest.fn(),
}));
jest.mock('../../../../ducks/send/send.duck', () => ({
updateSendErrors: jest.fn(),
setMaxModeTo: jest.fn(),
updateSendAmount: jest.fn(),
}));
require('./send-amount-row.container.js');

View File

@ -6,7 +6,7 @@ import {
getSendTokenAddress,
getAssetImages,
} from '../../../../selectors';
import { updateSendToken } from '../../../../store/actions';
import { updateSendToken } from '../../../../ducks/send/send.duck';
import SendAssetRow from './send-asset-row.component';
function mapStateToProps(state) {

View File

@ -25,20 +25,18 @@ import { calcMaxAmount } from '../send-amount-row/amount-max-button/amount-max-b
import {
showGasButtonGroup,
updateSendErrors,
setGasPrice,
setGasLimit,
setGasTotal,
updateSendAmount,
} from '../../../../ducks/send/send.duck';
import {
resetCustomData,
setCustomGasPrice,
setCustomGasLimit,
} from '../../../../ducks/gas/gas.duck';
import {
showModal,
setGasPrice,
setGasLimit,
setGasTotal,
updateSendAmount,
} from '../../../../store/actions';
import { getConversionRate } from '../../../../ducks/metamask/metamask';
import { showModal } from '../../../../store/actions';
import SendGasRow from './send-gas-row.component';
export default connect(

View File

@ -1,11 +1,6 @@
import sinon from 'sinon';
import {
showModal,
setGasPrice,
setGasTotal,
setGasLimit,
} from '../../../../store/actions';
import { showModal } from '../../../../store/actions';
import {
resetCustomData,
@ -13,7 +8,12 @@ import {
setCustomGasLimit,
} from '../../../../ducks/gas/gas.duck';
import { showGasButtonGroup } from '../../../../ducks/send/send.duck';
import {
showGasButtonGroup,
setGasPrice,
setGasTotal,
setGasLimit,
} from '../../../../ducks/send/send.duck';
let mapDispatchToProps;
let mergeProps;
@ -39,13 +39,13 @@ jest.mock('../../send.utils.js', () => ({
jest.mock('../../../../store/actions', () => ({
showModal: jest.fn(),
setGasPrice: jest.fn(),
setGasTotal: jest.fn(),
setGasLimit: jest.fn(),
}));
jest.mock('../../../../ducks/send/send.duck', () => ({
showGasButtonGroup: jest.fn(),
setGasPrice: jest.fn(),
setGasTotal: jest.fn(),
setGasLimit: jest.fn(),
}));
jest.mock('../../../../ducks/gas/gas.duck', () => ({

View File

@ -1,12 +1,12 @@
import { connect } from 'react-redux';
import { updateSendHexData } from '../../../../store/actions';
import { updateSendHexData } from '../../../../ducks/send/send.duck';
import SendHexDataRow from './send-hex-data-row.component';
export default connect(mapStateToProps, mapDispatchToProps)(SendHexDataRow);
function mapStateToProps(state) {
return {
data: state.metamask.send.data,
data: state.send.data,
};
}

View File

@ -1,7 +1,6 @@
import { connect } from 'react-redux';
import {
addToAddressBook,
clearSend,
signTokenTx,
signTx,
updateTransaction,
@ -30,6 +29,7 @@ import {
getSendToAccounts,
getUnapprovedTxs,
} from '../../../ducks/metamask/metamask';
import { clearSend } from '../../../ducks/send/send.duck';
import SendFooter from './send-footer.component';
import {
addressIsNew,
@ -88,7 +88,7 @@ function mapDispatchToProps(dispatch) {
to,
});
sendToken
return sendToken
? dispatch(signTokenTx(sendToken.address, to, amount, txParams))
: dispatch(signTx(txParams));
},

View File

@ -1,11 +1,7 @@
import sinon from 'sinon';
import { clearSend } from '../../../ducks/send/send.duck';
import {
clearSend,
signTx,
signTokenTx,
addToAddressBook,
} from '../../../store/actions';
import { signTx, signTokenTx, addToAddressBook } from '../../../store/actions';
import {
addressIsNew,
constructTxParams,
@ -23,12 +19,15 @@ jest.mock('react-redux', () => ({
jest.mock('../../../store/actions.js', () => ({
addToAddressBook: jest.fn(),
clearSend: jest.fn(),
signTokenTx: jest.fn(),
signTx: jest.fn(),
updateTransaction: jest.fn(),
}));
jest.mock('../../../ducks/send/send.duck.js', () => ({
clearSend: jest.fn(),
}));
jest.mock('../../../selectors/send.js', () => ({
getGasLimit: (s) => `mockGasLimit:${s}`,
getGasPrice: (s) => `mockGasPrice:${s}`,

View File

@ -1,5 +1,5 @@
import { connect } from 'react-redux';
import { clearSend } from '../../../store/actions';
import { clearSend } from '../../../ducks/send/send.duck';
import { getTitleKey } from '../../../selectors';
import { getMostRecentOverviewPage } from '../../../ducks/history/history';
import SendHeader from './send-header.component';

View File

@ -23,17 +23,17 @@ import {
getCurrentChainId,
} from '../../selectors';
import { showQrScanner, qrCodeDetected } from '../../store/actions';
import {
resetSendState,
updateSendErrors,
updateSendTo,
updateSendTokenBalance,
updateGasData,
setGasTotal,
showQrScanner,
qrCodeDetected,
updateSendEnsResolution,
updateSendEnsResolutionError,
} from '../../store/actions';
import { resetSendState, updateSendErrors } from '../../ducks/send/send.duck';
} from '../../ducks/send/send.duck';
import { fetchBasicGasEstimates } from '../../ducks/gas/gas.duck';
import {
getBlockGasLimit,

View File

@ -4,9 +4,9 @@ import {
updateSendTokenBalance,
updateGasData,
setGasTotal,
} from '../../store/actions';
import { updateSendErrors, resetSendState } from '../../ducks/send/send.duck';
updateSendErrors,
resetSendState,
} from '../../ducks/send/send.duck';
let mapDispatchToProps;
@ -25,14 +25,12 @@ jest.mock('redux', () => ({
compose: (_, arg2) => () => arg2(),
}));
jest.mock('../../store/actions', () => ({
updateSendTokenBalance: jest.fn(),
updateGasData: jest.fn(),
setGasTotal: jest.fn(),
}));
jest.mock('../../ducks/send/send.duck', () => ({
updateSendErrors: jest.fn(),
resetSendState: jest.fn(),
updateSendTokenBalance: jest.fn(),
updateGasData: jest.fn(),
setGasTotal: jest.fn(),
}));
jest.mock('./send.utils.js', () => ({

View File

@ -296,9 +296,7 @@ export function getRenderableEstimateDataForSmallButtonsFromGWEI(state) {
const isMainnet = getIsMainnet(state);
const showFiat = isMainnet || Boolean(showFiatInTestnets);
const gasLimit =
state.metamask.send.gasLimit ||
getCustomGasLimit(state) ||
GAS_LIMITS.SIMPLE;
state.send.gasLimit || getCustomGasLimit(state) || GAS_LIMITS.SIMPLE;
const { conversionRate } = state.metamask;
const currentCurrency = getCurrentCurrency(state);
const {

View File

@ -111,10 +111,8 @@ describe('custom-gas selectors', () => {
});
it('should return false gas.basicEstimates.price 0x28bed01600 (175) (checkSend=true)', () => {
const mockState = {
metamask: {
send: {
gasPrice: '0x28bed0160',
},
send: {
gasPrice: '0x28bed0160',
},
gas: {
customData: { price: null },
@ -125,10 +123,8 @@ describe('custom-gas selectors', () => {
});
it('should return true gas.basicEstimates.price 0x30e4f9b400 (210) (checkSend=true)', () => {
const mockState = {
metamask: {
send: {
gasPrice: '0x30e4f9b400',
},
send: {
gasPrice: '0x30e4f9b400',
},
gas: {
customData: { price: null },
@ -221,9 +217,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: false,
},
@ -232,6 +225,9 @@ describe('custom-gas selectors', () => {
chainId: '0x1',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
@ -272,9 +268,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: false,
},
@ -283,6 +276,9 @@ describe('custom-gas selectors', () => {
chainId: '0x4',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
@ -323,9 +319,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: true,
},
@ -334,6 +327,9 @@ describe('custom-gas selectors', () => {
chainId: '0x4',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
safeLow: 5,
@ -368,9 +364,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: true,
},
@ -379,6 +372,9 @@ describe('custom-gas selectors', () => {
chainId: '0x1',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
safeLow: 5,
@ -429,9 +425,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 255.71,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: false,
},
@ -440,6 +433,9 @@ describe('custom-gas selectors', () => {
chainId: '0x1',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
safeLow: 25,
@ -474,9 +470,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: false,
},
@ -485,6 +478,9 @@ describe('custom-gas selectors', () => {
chainId: '0x1',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
@ -525,9 +521,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: false,
},
@ -536,6 +529,9 @@ describe('custom-gas selectors', () => {
chainId: '0x4',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
blockTime: 14.16326530612245,
@ -576,9 +572,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: true,
},
@ -587,6 +580,9 @@ describe('custom-gas selectors', () => {
chainId: '0x4',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
safeLow: 50,
@ -621,9 +617,6 @@ describe('custom-gas selectors', () => {
metamask: {
conversionRate: 2557.1,
currentCurrency: 'usd',
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
preferences: {
showFiatInTestnets: true,
},
@ -632,6 +625,9 @@ describe('custom-gas selectors', () => {
chainId: '0x1',
},
},
send: {
gasLimit: GAS_LIMITS.SIMPLE,
},
gas: {
basicEstimates: {
safeLow: 50,

View File

@ -150,21 +150,6 @@ const state = {
},
],
selectedAddress: '0xd85a4b6a394794842887b8284293d69163007bbb',
send: {
gasLimit: '0xFFFF',
gasPrice: '0xaa',
gasTotal: '0xb451dc41b578',
tokenBalance: 3434,
from: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb',
to: '0x987fedabc',
amount: '0x080',
memo: '',
errors: {
someError: null,
},
maxModeOn: false,
editingTransactionId: 97531,
},
unapprovedTxs: {
4768706228115573: {
id: 4768706228115573,
@ -210,8 +195,19 @@ const state = {
identities: {},
send: {
fromDropdownOpen: false,
toDropdownOpen: false,
errors: { someError: null },
gasLimit: '0xFFFF',
gasPrice: '0xaa',
gasTotal: '0xb451dc41b578',
tokenBalance: 3434,
from: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb',
to: '0x987fedabc',
amount: '0x080',
memo: '',
errors: {
someError: null,
},
maxModeOn: false,
editingTransactionId: 97531,
},
};

View File

@ -7,11 +7,11 @@ import {
} from '.';
export function getGasLimit(state) {
return state.metamask.send.gasLimit || '0';
return state.send.gasLimit || '0';
}
export function getGasPrice(state) {
return state.metamask.send.gasPrice || getAveragePriceEstimateInHexWEI(state);
return state.send.gasPrice || getAveragePriceEstimateInHexWEI(state);
}
export function getGasTotal(state) {
@ -24,7 +24,7 @@ export function getPrimaryCurrency(state) {
}
export function getSendToken(state) {
return state.metamask.send.token;
return state.send.token;
}
export function getSendTokenAddress(state) {
@ -39,15 +39,15 @@ export function getSendTokenContract(state) {
}
export function getSendAmount(state) {
return state.metamask.send.amount;
return state.send.amount;
}
export function getSendHexData(state) {
return state.metamask.send.data;
return state.send.data;
}
export function getSendEditingTransactionId(state) {
return state.metamask.send.editingTransactionId;
return state.send.editingTransactionId;
}
export function getSendErrors(state) {
@ -59,7 +59,7 @@ export function sendAmountIsInError(state) {
}
export function getSendFrom(state) {
return state.metamask.send.from;
return state.send.from;
}
export function getSendFromBalance(state) {
@ -75,27 +75,27 @@ export function getSendFromObject(state) {
}
export function getSendMaxModeState(state) {
return state.metamask.send.maxModeOn;
return state.send.maxModeOn;
}
export function getSendTo(state) {
return state.metamask.send.to;
return state.send.to;
}
export function getSendToNickname(state) {
return state.metamask.send.toNickname;
return state.send.toNickname;
}
export function getTokenBalance(state) {
return state.metamask.send.tokenBalance;
return state.send.tokenBalance;
}
export function getSendEnsResolution(state) {
return state.metamask.send.ensResolution;
return state.send.ensResolution;
}
export function getSendEnsResolutionError(state) {
return state.metamask.send.ensResolutionError;
return state.send.ensResolutionError;
}
export function getQrCodeData(state) {

View File

@ -111,7 +111,7 @@ describe('send selectors', () => {
it('should return the symbol of the send token', () => {
expect(
getPrimaryCurrency({
metamask: { send: { token: { symbol: 'DEF' } } },
send: { token: { symbol: 'DEF' } },
}),
).toStrictEqual('DEF');
});
@ -121,13 +121,11 @@ describe('send selectors', () => {
it('should return the current send token if set', () => {
expect(
getSendToken({
metamask: {
send: {
token: {
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3',
decimals: 4,
symbol: 'DEF',
},
send: {
token: {
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3',
decimals: 4,
symbol: 'DEF',
},
},
}),
@ -143,13 +141,11 @@ describe('send selectors', () => {
it('should return the contract at the send token address', () => {
expect(
getSendTokenContract({
metamask: {
send: {
token: {
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3',
decimals: 4,
symbol: 'DEF',
},
send: {
token: {
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3',
decimals: 4,
symbol: 'DEF',
},
},
}),
@ -157,10 +153,7 @@ describe('send selectors', () => {
});
it('should return null if send token is not set', () => {
const modifiedMetamaskState = { ...mockState.metamask, send: {} };
expect(
getSendTokenContract({ ...mockState, metamask: modifiedMetamaskState }),
).toBeNull();
expect(getSendTokenContract({ ...mockState, send: {} })).toBeNull();
});
});
@ -197,11 +190,10 @@ describe('send selectors', () => {
it('should get the selected account balance if the send.from does not exist', () => {
const editedMockState = {
metamask: {
...mockState.metamask,
send: {
from: null,
},
...mockState,
send: {
...mockState.send,
from: null,
},
};
expect(getSendFromBalance(editedMockState)).toStrictEqual('0x0');
@ -220,11 +212,9 @@ describe('send selectors', () => {
it('should return the current account if send.from does not exist', () => {
const editedMockState = {
metamask: {
...mockState.metamask,
send: {
from: null,
},
...mockState,
send: {
from: null,
},
};
expect(getSendFromObject(editedMockState)).toStrictEqual({
@ -339,9 +329,7 @@ describe('send selectors', () => {
describe('send-header selectors', () => {
const getMetamaskSendMockState = (send) => {
return {
metamask: {
send: { ...send },
},
send: { ...send },
};
};

View File

@ -39,24 +39,6 @@ export const COMPLETED_TX = 'COMPLETED_TX';
export const TRANSACTION_ERROR = 'TRANSACTION_ERROR';
export const UPDATE_TRANSACTION_PARAMS = 'UPDATE_TRANSACTION_PARAMS';
export const SET_NEXT_NONCE = 'SET_NEXT_NONCE';
// send screen
export const UPDATE_GAS_LIMIT = 'UPDATE_GAS_LIMIT';
export const UPDATE_GAS_PRICE = 'UPDATE_GAS_PRICE';
export const UPDATE_GAS_TOTAL = 'UPDATE_GAS_TOTAL';
export const UPDATE_SEND_HEX_DATA = 'UPDATE_SEND_HEX_DATA';
export const UPDATE_SEND_TOKEN_BALANCE = 'UPDATE_SEND_TOKEN_BALANCE';
export const UPDATE_SEND_TO = 'UPDATE_SEND_TO';
export const UPDATE_SEND_AMOUNT = 'UPDATE_SEND_AMOUNT';
export const UPDATE_SEND_ERRORS = 'UPDATE_SEND_ERRORS';
export const UPDATE_MAX_MODE = 'UPDATE_MAX_MODE';
export const UPDATE_SEND = 'UPDATE_SEND';
export const UPDATE_SEND_TOKEN = 'UPDATE_SEND_TOKEN';
export const CLEAR_SEND = 'CLEAR_SEND';
export const GAS_LOADING_STARTED = 'GAS_LOADING_STARTED';
export const GAS_LOADING_FINISHED = 'GAS_LOADING_FINISHED';
export const UPDATE_SEND_ENS_RESOLUTION = 'UPDATE_SEND_ENS_RESOLUTION';
export const UPDATE_SEND_ENS_RESOLUTION_ERROR =
'UPDATE_SEND_ENS_RESOLUTION_ERROR';
// config screen
export const SET_RPC_TARGET = 'SET_RPC_TARGET';
export const SET_PROVIDER_TYPE = 'SET_PROVIDER_TYPE';

View File

@ -3,7 +3,6 @@ import pify from 'pify';
import log from 'loglevel';
import { capitalize } from 'lodash';
import getBuyEthUrl from '../../app/scripts/lib/buy-eth-url';
import { calcTokenBalance, estimateGasForSend } from '../pages/send/send.utils';
import {
fetchLocale,
loadRelativeTimeFormatLocaleData,
@ -13,7 +12,6 @@ import { getSymbolAndDecimals } from '../helpers/utils/token-util';
import switchDirection from '../helpers/utils/switch-direction';
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../shared/constants/app';
import { hasUnconfirmedTransactions } from '../helpers/utils/confirm-tx.util';
import { setCustomGasLimit } from '../ducks/gas/gas.duck';
import txHelper from '../helpers/utils/tx-helper';
import { getEnvironmentType, addHexPrefix } from '../../app/scripts/lib/util';
import {
@ -24,6 +22,7 @@ import { switchedToUnconnectedAccount } from '../ducks/alerts/unconnected-accoun
import { getUnconnectedAccountAlertEnabledness } from '../ducks/metamask/metamask';
import { LISTED_CONTRACT_ADDRESSES } from '../../shared/constants/tokens';
import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils';
import { clearSend } from '../ducks/send/send.duck';
import * as actionConstants from './actionConstants';
let background = null;
@ -38,7 +37,6 @@ export function goHome() {
type: actionConstants.GO_HOME,
};
}
// async actions
export function tryUnlockMetamask(password) {
@ -624,138 +622,18 @@ export function signTypedMsg(msgData) {
}
export function signTx(txData) {
return (dispatch) => {
return async (dispatch) => {
dispatch(showLoadingIndication());
global.ethQuery.sendTransaction(txData, (err) => {
if (err) {
dispatch(displayWarning(err.message));
}
});
dispatch(hideLoadingIndication());
dispatch(showConfTxPage());
};
}
export function setGasLimit(gasLimit) {
return {
type: actionConstants.UPDATE_GAS_LIMIT,
value: gasLimit,
};
}
export function setGasPrice(gasPrice) {
return {
type: actionConstants.UPDATE_GAS_PRICE,
value: gasPrice,
};
}
export function setGasTotal(gasTotal) {
return {
type: actionConstants.UPDATE_GAS_TOTAL,
value: gasTotal,
};
}
export function updateGasData({
gasPrice,
blockGasLimit,
selectedAddress,
sendToken,
to,
value,
data,
}) {
return (dispatch) => {
dispatch(gasLoadingStarted());
return estimateGasForSend({
estimateGasMethod: promisifiedBackground.estimateGas,
blockGasLimit,
selectedAddress,
sendToken,
to,
value,
estimateGasPrice: gasPrice,
data,
})
.then((gas) => {
dispatch(setGasLimit(gas));
dispatch(setCustomGasLimit(gas));
dispatch(updateSendErrors({ gasLoadingError: null }));
dispatch(gasLoadingFinished());
})
.catch((err) => {
log.error(err);
dispatch(updateSendErrors({ gasLoadingError: 'gasLoadingError' }));
dispatch(gasLoadingFinished());
});
};
}
export function gasLoadingStarted() {
return {
type: actionConstants.GAS_LOADING_STARTED,
};
}
export function gasLoadingFinished() {
return {
type: actionConstants.GAS_LOADING_FINISHED,
};
}
export function updateSendTokenBalance({ sendToken, tokenContract, address }) {
return (dispatch) => {
const tokenBalancePromise = tokenContract
? tokenContract.balanceOf(address)
: Promise.resolve();
return tokenBalancePromise
.then((usersToken) => {
if (usersToken) {
const newTokenBalance = calcTokenBalance({ sendToken, usersToken });
dispatch(setSendTokenBalance(newTokenBalance));
}
})
.catch((err) => {
log.error(err);
updateSendErrors({ tokenBalance: 'tokenBalanceError' });
});
};
}
export function updateSendErrors(errorObject) {
return {
type: actionConstants.UPDATE_SEND_ERRORS,
value: errorObject,
};
}
export function setSendTokenBalance(tokenBalance) {
return {
type: actionConstants.UPDATE_SEND_TOKEN_BALANCE,
value: tokenBalance,
};
}
export function updateSendHexData(value) {
return {
type: actionConstants.UPDATE_SEND_HEX_DATA,
value,
};
}
export function updateSendTo(to, nickname = '') {
return {
type: actionConstants.UPDATE_SEND_TO,
value: { to, nickname },
};
}
export function updateSendAmount(amount) {
return {
type: actionConstants.UPDATE_SEND_AMOUNT,
value: amount,
};
}
export function updateCustomNonce(value) {
return {
type: actionConstants.UPDATE_CUSTOM_NONCE,
@ -763,57 +641,15 @@ export function updateCustomNonce(value) {
};
}
export function setMaxModeTo(bool) {
return {
type: actionConstants.UPDATE_MAX_MODE,
value: bool,
};
}
export function updateSend(newSend) {
return {
type: actionConstants.UPDATE_SEND,
value: newSend,
};
}
export function updateSendToken(token) {
return {
type: actionConstants.UPDATE_SEND_TOKEN,
value: token,
};
}
export function clearSend() {
return {
type: actionConstants.CLEAR_SEND,
};
}
export function updateSendEnsResolution(ensResolution) {
return {
type: actionConstants.UPDATE_SEND_ENS_RESOLUTION,
payload: ensResolution,
};
}
export function updateSendEnsResolutionError(errorMessage) {
return {
type: actionConstants.UPDATE_SEND_ENS_RESOLUTION_ERROR,
payload: errorMessage,
};
}
export function signTokenTx(tokenAddress, toAddress, amount, txData) {
return async (dispatch) => {
dispatch(showLoadingIndication());
try {
const token = global.eth.contract(abi).at(tokenAddress);
const txPromise = token.transfer(toAddress, addHexPrefix(amount), txData);
token.transfer(toAddress, addHexPrefix(amount), txData);
dispatch(showConfTxPage());
dispatch(hideLoadingIndication());
await txPromise;
} catch (error) {
dispatch(hideLoadingIndication());
dispatch(displayWarning(error.message));
@ -2590,18 +2426,6 @@ export function setRecoveryPhraseReminderLastShown(lastShown) {
};
}
export async function setAlertEnabledness(alertId, enabledness) {
await promisifiedBackground.setAlertEnabledness(alertId, enabledness);
}
export async function setUnconnectedAccountAlertShown(origin) {
await promisifiedBackground.setUnconnectedAccountAlertShown(origin);
}
export async function setWeb3ShimUsageAlertDismissed(origin) {
await promisifiedBackground.setWeb3ShimUsageAlertDismissed(origin);
}
export function loadingMethodDataStarted() {
return {
type: actionConstants.LOADING_METHOD_DATA_STARTED,
@ -2868,6 +2692,18 @@ export function setLedgerLivePreference(value) {
};
}
// Wrappers around promisifedBackground
/**
* The "actions" below are not actions nor action creators. They cannot use
* dispatch nor should they be dispatched when used. Instead they can be
* called directly. These wrappers will be moved into their location at some
* point in the future.
*/
export function estimateGas(params) {
return promisifiedBackground.estimateGas(params);
}
// MetaMetrics
/**
* @typedef {import('../../shared/constants/metametrics').MetaMetricsEventPayload} MetaMetricsEventPayload
@ -2899,3 +2735,15 @@ export function updateViewedNotifications(notificationIdViewedStatusMap) {
notificationIdViewedStatusMap,
);
}
export async function setAlertEnabledness(alertId, enabledness) {
await promisifiedBackground.setAlertEnabledness(alertId, enabledness);
}
export async function setUnconnectedAccountAlertShown(origin) {
await promisifiedBackground.setUnconnectedAccountAlertShown(origin);
}
export async function setWeb3ShimUsageAlertDismissed(origin) {
await promisifiedBackground.setWeb3ShimUsageAlertDismissed(origin);
}

View File

@ -838,7 +838,9 @@ describe('Actions', () => {
it('errors in when sendTransaction throws', async () => {
const store = mockStore();
const expectedActions = [
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
{ type: 'DISPLAY_WARNING', value: 'error' },
{ type: 'HIDE_LOADING_INDICATION' },
{ type: 'SHOW_CONF_TX_PAGE', id: undefined },
];
@ -853,67 +855,6 @@ describe('Actions', () => {
});
});
describe('#updatedGasData', () => {
it('errors when get code does not return', async () => {
const store = mockStore();
background.estimateGas = sinon.stub().rejects();
actions._setBackgroundConnection(background);
global.eth = {
getCode: sinon.stub().rejects(),
};
const expectedActions = [
{ type: 'GAS_LOADING_STARTED' },
{
type: 'UPDATE_SEND_ERRORS',
value: { gasLoadingError: 'gasLoadingError' },
},
{ type: 'GAS_LOADING_FINISHED' },
];
const mockData = {
gasPrice: '0x3b9aca00', //
blockGasLimit: '0x6ad79a', // 7002010
selectedAddress: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc',
to: '0xEC1Adf982415D2Ef5ec55899b9Bfb8BC0f29251B',
value: '0xde0b6b3a7640000', // 1000000000000000000
};
await store.dispatch(actions.updateGasData(mockData));
expect(store.getActions()).toStrictEqual(expectedActions);
});
it('returns default gas limit for basic eth transaction', async () => {
const mockData = {
gasPrice: '0x3b9aca00',
blockGasLimit: '0x6ad79a', // 7002010
selectedAddress: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc',
to: '0xEC1Adf982415D2Ef5ec55899b9Bfb8BC0f29251B',
value: '0xde0b6b3a7640000', // 1000000000000000000
};
global.eth = {
getCode: sinon.stub().returns('0x'),
};
const store = mockStore();
const expectedActions = [
{ type: 'GAS_LOADING_STARTED' },
{ type: 'UPDATE_GAS_LIMIT', value: GAS_LIMITS.SIMPLE },
{ type: 'metamask/gas/SET_CUSTOM_GAS_LIMIT', value: GAS_LIMITS.SIMPLE },
{ type: 'UPDATE_SEND_ERRORS', value: { gasLoadingError: null } },
{ type: 'GAS_LOADING_FINISHED' },
];
await store.dispatch(actions.updateGasData(mockData));
expect(store.getActions()).toStrictEqual(expectedActions);
});
});
describe('#signTokenTx', () => {
it('calls eth.contract', async () => {
global.eth = {