mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 01:47:00 +01:00
Feature/mmi 3009 confirm transaction base code fences (#19335)
* Added code fences * Continue working on this ticket * Fixed policies * Added compliance-row component * Fixed tests and css * Fixed invalid locale * Fixing linting * Add optional check * Fixing issues * Fixed storybook * Added missing dependency * ran lavamoat auto * ran dedupe and lavamoat * lint * Removed compliance row * Removed unneeded package * Removed unneeded proptyes * updates mmi packages * updating lavamoat * formatting main * Fixed conflicts * updates lock file * Moved code fences to have them all in the same place * Updated yarn.lock and lavamoat * remove linebreak * Improved logic in order to not have many code fences and improve readability * Fixing proptypes issues with eslint * runs lavamoat auto * Testing fixes issue e2e tests * Testing issues * Reverting code fences container * Fixing issue with binding * Added code fences in proptypes * Reverting code fences * Removed institutional from main lavamoat * Added code fences in confirm transaction base component * Adding tests for handleMainSubmit * Improving code * Added test for handleMainSubmit * Removed waitFor --------- Co-authored-by: Antonio Regadas <antonio.regadas@consensys.net> Co-authored-by: António Regadas <apregadas@gmail.com>
This commit is contained in:
parent
5f57ad159b
commit
2070e5e42a
59
shared/modules/updateTxData.js
Normal file
59
shared/modules/updateTxData.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { TransactionType } from '../constants/transaction';
|
||||||
|
|
||||||
|
export default function updateTxData({
|
||||||
|
txData,
|
||||||
|
maxFeePerGas,
|
||||||
|
customTokenAmount,
|
||||||
|
dappProposedTokenAmount,
|
||||||
|
currentTokenBalance,
|
||||||
|
maxPriorityFeePerGas,
|
||||||
|
baseFeePerGas,
|
||||||
|
addToAddressBookIfNew,
|
||||||
|
toAccounts,
|
||||||
|
toAddress,
|
||||||
|
name,
|
||||||
|
}) {
|
||||||
|
if (txData.type === TransactionType.simpleSend) {
|
||||||
|
addToAddressBookIfNew(toAddress, toAccounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseFeePerGas) {
|
||||||
|
txData.estimatedBaseFee = baseFeePerGas;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
txData.contractMethodName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dappProposedTokenAmount) {
|
||||||
|
txData.dappProposedTokenAmount = dappProposedTokenAmount;
|
||||||
|
txData.originalApprovalAmount = dappProposedTokenAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customTokenAmount) {
|
||||||
|
txData.customTokenAmount = customTokenAmount;
|
||||||
|
txData.finalApprovalAmount = customTokenAmount;
|
||||||
|
} else if (dappProposedTokenAmount !== undefined) {
|
||||||
|
txData.finalApprovalAmount = dappProposedTokenAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTokenBalance) {
|
||||||
|
txData.currentTokenBalance = currentTokenBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxFeePerGas) {
|
||||||
|
txData.txParams = {
|
||||||
|
...txData.txParams,
|
||||||
|
maxFeePerGas,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxPriorityFeePerGas) {
|
||||||
|
txData.txParams = {
|
||||||
|
...txData.txParams,
|
||||||
|
maxPriorityFeePerGas,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return txData;
|
||||||
|
}
|
102
shared/modules/updateTxData.test.js
Normal file
102
shared/modules/updateTxData.test.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import { TransactionType } from '../constants/transaction';
|
||||||
|
import updateTxData from './updateTxData';
|
||||||
|
|
||||||
|
describe('updateTxData', () => {
|
||||||
|
const mockAddToAddressBookIfNew = jest.fn();
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
mockAddToAddressBookIfNew.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add to address book if txData type is simpleSend', () => {
|
||||||
|
const txData = {
|
||||||
|
type: TransactionType.simpleSend,
|
||||||
|
};
|
||||||
|
updateTxData({
|
||||||
|
txData,
|
||||||
|
addToAddressBookIfNew: mockAddToAddressBookIfNew,
|
||||||
|
toAccounts: 'mockToAccounts',
|
||||||
|
toAddress: 'mockToAddress',
|
||||||
|
});
|
||||||
|
expect(mockAddToAddressBookIfNew).toHaveBeenCalledWith(
|
||||||
|
'mockToAddress',
|
||||||
|
'mockToAccounts',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update estimatedBaseFee if baseFeePerGas is provided', () => {
|
||||||
|
const txData = {};
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
baseFeePerGas: 'mockBaseFeePerGas',
|
||||||
|
});
|
||||||
|
expect(result.estimatedBaseFee).toBe('mockBaseFeePerGas');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update contractMethodName if name is provided', () => {
|
||||||
|
const txData = {};
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
name: 'mockName',
|
||||||
|
});
|
||||||
|
expect(result.contractMethodName).toBe('mockName');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update dappProposedTokenAmount and originalApprovalAmount if dappProposedTokenAmount is provided', () => {
|
||||||
|
const txData = {};
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
dappProposedTokenAmount: 'mockDappProposedTokenAmount',
|
||||||
|
});
|
||||||
|
expect(result.dappProposedTokenAmount).toBe('mockDappProposedTokenAmount');
|
||||||
|
expect(result.originalApprovalAmount).toBe('mockDappProposedTokenAmount');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update customTokenAmount and finalApprovalAmount if customTokenAmount is provided', () => {
|
||||||
|
const txData = {};
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
customTokenAmount: 'mockCustomTokenAmount',
|
||||||
|
});
|
||||||
|
expect(result.customTokenAmount).toBe('mockCustomTokenAmount');
|
||||||
|
expect(result.finalApprovalAmount).toBe('mockCustomTokenAmount');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update finalApprovalAmount if dappProposedTokenAmount is provided but customTokenAmount is not', () => {
|
||||||
|
const txData = {};
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
dappProposedTokenAmount: 'mockDappProposedTokenAmount',
|
||||||
|
});
|
||||||
|
expect(result.finalApprovalAmount).toBe('mockDappProposedTokenAmount');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update currentTokenBalance if currentTokenBalance is provided', () => {
|
||||||
|
const txData = {};
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
currentTokenBalance: 'mockCurrentTokenBalance',
|
||||||
|
});
|
||||||
|
expect(result.currentTokenBalance).toBe('mockCurrentTokenBalance');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update maxFeePerGas in txParams if maxFeePerGas is provided', () => {
|
||||||
|
const txData = { txParams: {} };
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
maxFeePerGas: 'mockMaxFeePerGas',
|
||||||
|
});
|
||||||
|
expect(result.txParams.maxFeePerGas).toBe('mockMaxFeePerGas');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update maxPriorityFeePerGas in txParams if maxPriorityFeePerGas is provided', () => {
|
||||||
|
const txData = { txParams: {} };
|
||||||
|
const result = updateTxData({
|
||||||
|
txData,
|
||||||
|
maxPriorityFeePerGas: 'mockMaxPriorityFeePerGas',
|
||||||
|
});
|
||||||
|
expect(result.txParams.maxPriorityFeePerGas).toBe(
|
||||||
|
'mockMaxPriorityFeePerGas',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -54,6 +54,7 @@ import { ConfirmData } from '../../components/app/confirm-data';
|
|||||||
import { ConfirmTitle } from '../../components/app/confirm-title';
|
import { ConfirmTitle } from '../../components/app/confirm-title';
|
||||||
import { ConfirmSubTitle } from '../../components/app/confirm-subtitle';
|
import { ConfirmSubTitle } from '../../components/app/confirm-subtitle';
|
||||||
import { ConfirmGasDisplay } from '../../components/app/confirm-gas-display';
|
import { ConfirmGasDisplay } from '../../components/app/confirm-gas-display';
|
||||||
|
import updateTxData from '../../../shared/modules/updateTxData';
|
||||||
|
|
||||||
export default class ConfirmTransactionBase extends Component {
|
export default class ConfirmTransactionBase extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -133,13 +134,16 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
hardwareWalletRequiresConnection: PropTypes.bool,
|
hardwareWalletRequiresConnection: PropTypes.bool,
|
||||||
isMultiLayerFeeNetwork: PropTypes.bool,
|
isMultiLayerFeeNetwork: PropTypes.bool,
|
||||||
isBuyableChain: PropTypes.bool,
|
isBuyableChain: PropTypes.bool,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
|
||||||
accountType: PropTypes.string,
|
|
||||||
isNoteToTraderSupported: PropTypes.bool,
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
isApprovalOrRejection: PropTypes.bool,
|
isApprovalOrRejection: PropTypes.bool,
|
||||||
assetStandard: PropTypes.string,
|
assetStandard: PropTypes.string,
|
||||||
useCurrencyRateCheck: PropTypes.bool,
|
useCurrencyRateCheck: PropTypes.bool,
|
||||||
|
isNotification: PropTypes.bool,
|
||||||
|
accountType: PropTypes.string,
|
||||||
|
setWaitForConfirmDeepLinkDialog: PropTypes.func,
|
||||||
|
showTransactionsFailedModal: PropTypes.func,
|
||||||
|
showCustodianDeepLink: PropTypes.func,
|
||||||
|
isNoteToTraderSupported: PropTypes.bool,
|
||||||
|
isMainBetaFlask: PropTypes.bool,
|
||||||
displayAccountBalanceHeader: PropTypes.bool,
|
displayAccountBalanceHeader: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -594,91 +598,49 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit() {
|
handleSubmit() {
|
||||||
|
const { submitting } = this.state;
|
||||||
|
|
||||||
|
if (submitting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.isMainBetaFlask
|
||||||
|
? this.handleMainSubmit()
|
||||||
|
: this.handleMMISubmit();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMainSubmit() {
|
||||||
const {
|
const {
|
||||||
sendTransaction,
|
sendTransaction,
|
||||||
txData,
|
txData,
|
||||||
history,
|
history,
|
||||||
mostRecentOverviewPage,
|
mostRecentOverviewPage,
|
||||||
updateCustomNonce,
|
updateCustomNonce,
|
||||||
|
methodData,
|
||||||
maxFeePerGas,
|
maxFeePerGas,
|
||||||
customTokenAmount,
|
customTokenAmount,
|
||||||
dappProposedTokenAmount,
|
dappProposedTokenAmount,
|
||||||
currentTokenBalance,
|
currentTokenBalance,
|
||||||
maxPriorityFeePerGas,
|
maxPriorityFeePerGas,
|
||||||
baseFeePerGas,
|
baseFeePerGas,
|
||||||
methodData,
|
|
||||||
addToAddressBookIfNew,
|
addToAddressBookIfNew,
|
||||||
toAccounts,
|
toAccounts,
|
||||||
toAddress,
|
toAddress,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
|
||||||
accountType,
|
|
||||||
isNoteToTraderSupported,
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const {
|
|
||||||
submitting,
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
|
||||||
noteText,
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
} = this.state;
|
|
||||||
const { name } = methodData;
|
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
updateTxData({
|
||||||
if (accountType === 'custody') {
|
txData,
|
||||||
txData.custodyStatus = 'created';
|
maxFeePerGas,
|
||||||
|
customTokenAmount,
|
||||||
if (isNoteToTraderSupported) {
|
dappProposedTokenAmount,
|
||||||
txData.metadata = {
|
currentTokenBalance,
|
||||||
note: noteText,
|
maxPriorityFeePerGas,
|
||||||
};
|
baseFeePerGas,
|
||||||
}
|
addToAddressBookIfNew,
|
||||||
}
|
toAccounts,
|
||||||
///: END:ONLY_INCLUDE_IN
|
toAddress,
|
||||||
|
name: methodData.name,
|
||||||
if (txData.type === TransactionType.simpleSend) {
|
});
|
||||||
addToAddressBookIfNew(toAddress, toAccounts);
|
|
||||||
}
|
|
||||||
if (submitting) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (baseFeePerGas) {
|
|
||||||
txData.estimatedBaseFee = baseFeePerGas;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
txData.contractMethodName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dappProposedTokenAmount) {
|
|
||||||
txData.dappProposedTokenAmount = dappProposedTokenAmount;
|
|
||||||
txData.originalApprovalAmount = dappProposedTokenAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (customTokenAmount) {
|
|
||||||
txData.customTokenAmount = customTokenAmount;
|
|
||||||
txData.finalApprovalAmount = customTokenAmount;
|
|
||||||
} else if (dappProposedTokenAmount !== undefined) {
|
|
||||||
txData.finalApprovalAmount = dappProposedTokenAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentTokenBalance) {
|
|
||||||
txData.currentTokenBalance = currentTokenBalance;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxFeePerGas) {
|
|
||||||
txData.txParams = {
|
|
||||||
...txData.txParams,
|
|
||||||
maxFeePerGas,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxPriorityFeePerGas) {
|
|
||||||
txData.txParams = {
|
|
||||||
...txData.txParams,
|
|
||||||
maxPriorityFeePerGas,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
@ -708,11 +670,128 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
if (!this._isMounted) {
|
if (!this._isMounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.setState({
|
||||||
|
submitting: false,
|
||||||
|
submitError: error.message,
|
||||||
|
});
|
||||||
|
updateCustomNonce('');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMMISubmit() {
|
||||||
|
const {
|
||||||
|
sendTransaction,
|
||||||
|
txData,
|
||||||
|
history,
|
||||||
|
mostRecentOverviewPage,
|
||||||
|
updateCustomNonce,
|
||||||
|
unapprovedTxCount,
|
||||||
|
accountType,
|
||||||
|
isNotification,
|
||||||
|
setWaitForConfirmDeepLinkDialog,
|
||||||
|
showTransactionsFailedModal,
|
||||||
|
fromAddress,
|
||||||
|
isNoteToTraderSupported,
|
||||||
|
methodData,
|
||||||
|
maxFeePerGas,
|
||||||
|
customTokenAmount,
|
||||||
|
dappProposedTokenAmount,
|
||||||
|
currentTokenBalance,
|
||||||
|
maxPriorityFeePerGas,
|
||||||
|
baseFeePerGas,
|
||||||
|
addToAddressBookIfNew,
|
||||||
|
toAccounts,
|
||||||
|
toAddress,
|
||||||
|
} = this.props;
|
||||||
|
const { noteText } = this.state;
|
||||||
|
|
||||||
|
if (accountType === 'custody') {
|
||||||
|
txData.custodyStatus = 'created';
|
||||||
|
|
||||||
|
if (isNoteToTraderSupported) {
|
||||||
|
txData.metadata = {
|
||||||
|
note: noteText,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTxData({
|
||||||
|
txData,
|
||||||
|
maxFeePerGas,
|
||||||
|
customTokenAmount,
|
||||||
|
dappProposedTokenAmount,
|
||||||
|
currentTokenBalance,
|
||||||
|
maxPriorityFeePerGas,
|
||||||
|
baseFeePerGas,
|
||||||
|
addToAddressBookIfNew,
|
||||||
|
toAccounts,
|
||||||
|
toAddress,
|
||||||
|
name: methodData.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
submitting: true,
|
||||||
|
submitError: null,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this._removeBeforeUnload();
|
||||||
|
|
||||||
|
if (txData.custodyStatus) {
|
||||||
|
setWaitForConfirmDeepLinkDialog(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendTransaction(txData)
|
||||||
|
.then(() => {
|
||||||
|
if (!this._isMounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txData.custodyStatus) {
|
||||||
|
this.props.showCustodianDeepLink({
|
||||||
|
fromAddress,
|
||||||
|
closeNotification: isNotification && unapprovedTxCount === 1,
|
||||||
|
txId: txData.id,
|
||||||
|
onDeepLinkFetched: () => {
|
||||||
|
this.context.trackEvent({
|
||||||
|
category: 'MMI',
|
||||||
|
event: 'Show deeplink for transaction',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDeepLinkShown: () => {
|
||||||
|
this.props.clearConfirmTransaction();
|
||||||
|
this.setState({ submitting: false }, () => {
|
||||||
|
history.push(mostRecentOverviewPage);
|
||||||
|
updateCustomNonce('');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
submitting: false,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
history.push(mostRecentOverviewPage);
|
||||||
|
updateCustomNonce('');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (!this._isMounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showTransactionsFailedModal(error.message, isNotification);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
submitting: false,
|
submitting: false,
|
||||||
submitError: error.message,
|
submitError: error.message,
|
||||||
});
|
});
|
||||||
|
setWaitForConfirmDeepLinkDialog(true);
|
||||||
updateCustomNonce('');
|
updateCustomNonce('');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -855,7 +934,6 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
userAcknowledgedGasMissing,
|
userAcknowledgedGasMissing,
|
||||||
showWarningModal,
|
showWarningModal,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
const { name } = methodData;
|
const { name } = methodData;
|
||||||
const { valid, errorKey } = this.getErrorKey();
|
const { valid, errorKey } = this.getErrorKey();
|
||||||
const hasSimulationError = Boolean(txData.simulationFails);
|
const hasSimulationError = Boolean(txData.simulationFails);
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { compose } from 'redux';
|
import { compose } from 'redux';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
import { showCustodianDeepLink } from '@metamask-institutional/extension';
|
||||||
|
import { mmiActionsFactory } from '../../store/institutional/institution-background';
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck';
|
import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -48,7 +51,12 @@ import {
|
|||||||
getSendToAccounts,
|
getSendToAccounts,
|
||||||
getProviderConfig,
|
getProviderConfig,
|
||||||
} from '../../ducks/metamask/metamask';
|
} from '../../ducks/metamask/metamask';
|
||||||
import { addHexPrefix } from '../../../app/scripts/lib/util';
|
import {
|
||||||
|
addHexPrefix,
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
getEnvironmentType,
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
} from '../../../app/scripts/lib/util';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
parseStandardTokenTransactionData,
|
parseStandardTokenTransactionData,
|
||||||
@ -63,8 +71,11 @@ import {
|
|||||||
import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app';
|
import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app';
|
||||||
import { isLegacyTransaction } from '../../helpers/utils/transactions.util';
|
import { isLegacyTransaction } from '../../helpers/utils/transactions.util';
|
||||||
import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas';
|
import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas';
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
import { getAccountType } from '../../selectors/selectors';
|
import { getAccountType } from '../../selectors/selectors';
|
||||||
|
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../shared/constants/app';
|
||||||
|
import { getIsNoteToTraderSupported } from '../../selectors/institutional/selectors';
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
import {
|
import {
|
||||||
TransactionStatus,
|
TransactionStatus,
|
||||||
@ -100,6 +111,11 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
const { id: paramsTransactionId } = params;
|
const { id: paramsTransactionId } = params;
|
||||||
const isMainnet = getIsMainnet(state);
|
const isMainnet = getIsMainnet(state);
|
||||||
|
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
const envType = getEnvironmentType();
|
||||||
|
const isNotification = envType === ENVIRONMENT_TYPE_NOTIFICATION;
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
|
||||||
const isGasEstimatesLoading = getIsGasEstimatesLoading(state);
|
const isGasEstimatesLoading = getIsGasEstimatesLoading(state);
|
||||||
const gasLoadingAnimationIsShowing = getGasLoadingAnimationIsShowing(state);
|
const gasLoadingAnimationIsShowing = getGasLoadingAnimationIsShowing(state);
|
||||||
const isBuyableChain = getIsBuyableChain(state);
|
const isBuyableChain = getIsBuyableChain(state);
|
||||||
@ -199,29 +215,20 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
txParamsAreDappSuggested(fullTxData);
|
txParamsAreDappSuggested(fullTxData);
|
||||||
const fromAddressIsLedger = isAddressLedger(state, fromAddress);
|
const fromAddressIsLedger = isAddressLedger(state, fromAddress);
|
||||||
const nativeCurrency = getNativeCurrency(state);
|
const nativeCurrency = getNativeCurrency(state);
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
const accountType = getAccountType(state, fromAddress);
|
||||||
|
const fromChecksumHexAddress = toChecksumHexAddress(fromAddress);
|
||||||
|
const isNoteToTraderSupported = getIsNoteToTraderSupported(
|
||||||
|
state,
|
||||||
|
fromChecksumHexAddress,
|
||||||
|
);
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
|
||||||
const hardwareWalletRequiresConnection =
|
const hardwareWalletRequiresConnection =
|
||||||
doesAddressRequireLedgerHidConnection(state, fromAddress);
|
doesAddressRequireLedgerHidConnection(state, fromAddress);
|
||||||
|
|
||||||
const isMultiLayerFeeNetwork = getIsMultiLayerFeeNetwork(state);
|
const isMultiLayerFeeNetwork = getIsMultiLayerFeeNetwork(state);
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
|
||||||
const accountType = getAccountType(state);
|
|
||||||
|
|
||||||
const fromChecksumHexAddress = toChecksumHexAddress(fromAddress);
|
|
||||||
let isNoteToTraderSupported = false;
|
|
||||||
if (
|
|
||||||
state.metamask.custodyAccountDetails &&
|
|
||||||
state.metamask.custodyAccountDetails[fromChecksumHexAddress]
|
|
||||||
) {
|
|
||||||
const { custodianName } =
|
|
||||||
state.metamask.custodyAccountDetails[fromChecksumHexAddress];
|
|
||||||
isNoteToTraderSupported = state.metamask.mmiConfiguration?.custodians?.find(
|
|
||||||
(custodian) => custodian.name === custodianName,
|
|
||||||
)?.isNoteToTraderSupported;
|
|
||||||
}
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
balance,
|
balance,
|
||||||
fromAddress,
|
fromAddress,
|
||||||
@ -275,11 +282,15 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
accountType,
|
accountType,
|
||||||
isNoteToTraderSupported,
|
isNoteToTraderSupported,
|
||||||
|
isNotification,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mapDispatchToProps = (dispatch) => {
|
export const mapDispatchToProps = (dispatch) => {
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
const mmiActions = mmiActionsFactory();
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
return {
|
return {
|
||||||
tryReverseResolveAddress: (address) => {
|
tryReverseResolveAddress: (address) => {
|
||||||
return dispatch(tryReverseResolveAddress(address));
|
return dispatch(tryReverseResolveAddress(address));
|
||||||
@ -316,6 +327,45 @@ export const mapDispatchToProps = (dispatch) => {
|
|||||||
dispatch(addToAddressBook(hexPrefixedAddress, nickname));
|
dispatch(addToAddressBook(hexPrefixedAddress, nickname));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
getCustodianConfirmDeepLink: (id) =>
|
||||||
|
dispatch(mmiActions.getCustodianConfirmDeepLink(id)),
|
||||||
|
showCustodyConfirmLink: ({ link, address, closeNotification, custodyId }) =>
|
||||||
|
dispatch(
|
||||||
|
mmiActions.showCustodyConfirmLink({
|
||||||
|
link,
|
||||||
|
address,
|
||||||
|
closeNotification,
|
||||||
|
custodyId,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
showTransactionsFailedModal: (errorMessage, closeNotification) =>
|
||||||
|
dispatch(
|
||||||
|
showModal({
|
||||||
|
name: 'TRANSACTION_FAILED',
|
||||||
|
errorMessage,
|
||||||
|
closeNotification,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
showCustodianDeepLink: ({
|
||||||
|
txId,
|
||||||
|
fromAddress,
|
||||||
|
closeNotification,
|
||||||
|
onDeepLinkFetched,
|
||||||
|
onDeepLinkShown,
|
||||||
|
}) =>
|
||||||
|
showCustodianDeepLink({
|
||||||
|
dispatch,
|
||||||
|
mmiActions,
|
||||||
|
txId,
|
||||||
|
fromAddress,
|
||||||
|
closeNotification,
|
||||||
|
onDeepLinkFetched,
|
||||||
|
onDeepLinkShown,
|
||||||
|
}),
|
||||||
|
setWaitForConfirmDeepLinkDialog: (wait) =>
|
||||||
|
dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)),
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -328,6 +378,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
|||||||
...otherDispatchProps
|
...otherDispatchProps
|
||||||
} = dispatchProps;
|
} = dispatchProps;
|
||||||
|
|
||||||
|
let isMainBetaFlask = false;
|
||||||
|
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask)
|
||||||
|
isMainBetaFlask = true;
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...stateProps,
|
...stateProps,
|
||||||
...otherDispatchProps,
|
...otherDispatchProps,
|
||||||
@ -341,6 +397,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
|||||||
transaction: txData,
|
transaction: txData,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
isMainBetaFlask,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import configureMockStore from 'redux-mock-store';
|
import configureMockStore from 'redux-mock-store';
|
||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
|
import { fireEvent } from '@testing-library/react';
|
||||||
|
|
||||||
import { renderWithProvider } from '../../../test/lib/render-helpers';
|
import { renderWithProvider } from '../../../test/lib/render-helpers';
|
||||||
import { setBackgroundConnection } from '../../../test/jest';
|
import { setBackgroundConnection } from '../../../test/jest';
|
||||||
@ -235,6 +236,70 @@ describe('Confirm Transaction Base', () => {
|
|||||||
expect(getByTestId('transaction-note')).toBeInTheDocument();
|
expect(getByTestId('transaction-note')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handleMainSubmit calls sendTransaction with correct arguments', async () => {
|
||||||
|
const newMockedStore = {
|
||||||
|
...mockedStore,
|
||||||
|
appState: {
|
||||||
|
...mockedStore.appState,
|
||||||
|
gasLoadingAnimationIsShowing: false,
|
||||||
|
},
|
||||||
|
metamask: {
|
||||||
|
...mockedStore.metamask,
|
||||||
|
accounts: {
|
||||||
|
[mockTxParamsFromAddress]: {
|
||||||
|
balance: '0x1000000000000000000',
|
||||||
|
address: mockTxParamsFromAddress,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gasEstimateType: GasEstimateTypes.feeMarket,
|
||||||
|
networkDetails: {
|
||||||
|
...mockedStore.metamask.networkDetails,
|
||||||
|
EIPS: {
|
||||||
|
1559: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
customGas: {
|
||||||
|
gasLimit: '0x5208',
|
||||||
|
gasPrice: '0x59682f00',
|
||||||
|
},
|
||||||
|
noGasPrice: false,
|
||||||
|
},
|
||||||
|
send: {
|
||||||
|
...mockedStore.send,
|
||||||
|
gas: {
|
||||||
|
...mockedStore.send.gas,
|
||||||
|
gasEstimateType: GasEstimateTypes.legacy,
|
||||||
|
gasFeeEstimates: {
|
||||||
|
low: '0',
|
||||||
|
medium: '1',
|
||||||
|
high: '2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hasSimulationError: false,
|
||||||
|
userAcknowledgedGasMissing: false,
|
||||||
|
submitting: false,
|
||||||
|
hardwareWalletRequiresConnection: false,
|
||||||
|
gasIsLoading: false,
|
||||||
|
gasFeeIsCustom: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const store = configureMockStore(middleware)(newMockedStore);
|
||||||
|
const sendTransaction = jest.fn().mockResolvedValue();
|
||||||
|
|
||||||
|
const { getByTestId } = renderWithProvider(
|
||||||
|
<ConfirmTransactionBase
|
||||||
|
actionKey="confirm"
|
||||||
|
sendTransaction={sendTransaction}
|
||||||
|
toAddress={mockPropsToAddress}
|
||||||
|
toAccounts={[{ address: mockPropsToAddress }]}
|
||||||
|
/>,
|
||||||
|
store,
|
||||||
|
);
|
||||||
|
const confirmButton = getByTestId('page-container-footer-next');
|
||||||
|
fireEvent.click(confirmButton);
|
||||||
|
expect(sendTransaction).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
describe('when rendering the recipient value', () => {
|
describe('when rendering the recipient value', () => {
|
||||||
describe(`when the transaction is a ${TransactionType.simpleSend} type`, () => {
|
describe(`when the transaction is a ${TransactionType.simpleSend} type`, () => {
|
||||||
it(`should use txParams.to address`, () => {
|
it(`should use txParams.to address`, () => {
|
||||||
|
@ -78,3 +78,16 @@ export function getMMIConfiguration(state) {
|
|||||||
export function getInteractiveReplacementToken(state) {
|
export function getInteractiveReplacementToken(state) {
|
||||||
return state.metamask.interactiveReplacementToken || {};
|
return state.metamask.interactiveReplacementToken || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getIsNoteToTraderSupported(state, fromChecksumHexAddress) {
|
||||||
|
let isNoteToTraderSupported = false;
|
||||||
|
if (state.metamask.custodyAccountDetails?.[fromChecksumHexAddress]) {
|
||||||
|
const { custodianName } =
|
||||||
|
state.metamask.custodyAccountDetails[fromChecksumHexAddress];
|
||||||
|
|
||||||
|
isNoteToTraderSupported = state.metamask.mmiConfiguration?.custodians?.find(
|
||||||
|
(custodian) => custodian.name === custodianName,
|
||||||
|
)?.isNoteToTraderSupported;
|
||||||
|
}
|
||||||
|
return isNoteToTraderSupported;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user