Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use max in send flow #13304

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ exports[`Amount should convert ERC-20 token value to USD 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -1148,7 +1148,7 @@ exports[`Amount should convert ETH to USD 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -1864,7 +1864,7 @@ exports[`Amount should convert USD to ERC-20 token value 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -2597,7 +2597,7 @@ exports[`Amount should convert USD to ETH 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -3330,7 +3330,7 @@ exports[`Amount should display correct balance 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -4045,7 +4045,7 @@ exports[`Amount should not show a warning when conversion rate is available 1`]
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -5434,15 +5434,15 @@ exports[`Amount should proceed if balance is sufficient while on Native primary
}
>
<TouchableOpacity
disabled={true}
disabled={false}
onPress={[Function]}
style={{}}
>
<Text
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -6228,7 +6228,7 @@ exports[`Amount should render correctly 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -6938,7 +6938,7 @@ exports[`Amount should show a warning when conversion rate is not available 1`]
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -7565,15 +7565,15 @@ exports[`Amount should show an error message if balance is insufficient 1`] = `
}
>
<TouchableOpacity
disabled={true}
disabled={false}
onPress={[Function]}
style={{}}
>
<Text
style={
{
"alignSelf": "flex-end",
"color": "#6a737d",
"color": "#0376c9",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down
22 changes: 2 additions & 20 deletions app/components/Views/confirmations/SendFlow/Amount/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { PureComponent } from 'react';
import BigNumber from 'bignumber.js';
import { fontStyles } from '../../../../../styles/common';
import {
StyleSheet,
Expand Down Expand Up @@ -165,13 +164,6 @@ const createStyles = (colors) =>
alignSelf: 'flex-end',
textTransform: 'uppercase',
},
maxTextDisabled: {
...fontStyles.normal,
fontSize: 12,
color: colors.text.alternative,
alignSelf: 'flex-end',
textTransform: 'uppercase',
},
actionMax: {
flexDirection: 'row',
alignItems: 'center',
Expand Down Expand Up @@ -1465,10 +1457,6 @@ class Amount extends PureComponent {
const colors = this.context.colors || mockTheme.colors;
const styles = createStyles(colors);

const isEstimateedTotalGasValid = estimatedTotalGas
? BigNumber(estimatedTotalGas).gt(0)
: false;

return (
<SafeAreaView
edges={['bottom']}
Expand Down Expand Up @@ -1528,16 +1516,10 @@ class Amount extends PureComponent {
{!selectedAsset.tokenId && (
<TouchableOpacity
style={styles.actionMaxTouchable}
disabled={!isEstimateedTotalGasValid}
disabled={!estimatedTotalGas}
onPress={this.useMax}
>
<Text
style={
isEstimateedTotalGasValid
? styles.maxText
: styles.maxTextDisabled
}
>
<Text style={styles.maxText}>
{strings('transaction.use_max')}
</Text>
</TouchableOpacity>
Expand Down
47 changes: 25 additions & 22 deletions app/components/Views/confirmations/SendFlow/Confirm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,10 @@ class Confirm extends PureComponent {
this.props.gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET;
const haveGasFeeMaxNativeChanged = isEIP1559Transaction
? EIP1559GasTransaction.gasFeeMaxNative !==
prevState.EIP1559GasTransaction.gasFeeMaxNative
prevState.EIP1559GasTransaction.gasFeeMaxNative
: legacyGasTransaction.gasFeeMaxNative !==
prevState.legacyGasTransaction.gasFeeMaxNative;
prevState.legacyGasTransaction.gasFeeMaxNative;
const isControllerTransactionAdded = Boolean(!prevState.transactionMeta?.id && transactionId);

const haveGasPropertiesChanged =
(this.props.gasFeeEstimates &&
Expand All @@ -625,33 +626,34 @@ class Confirm extends PureComponent {
this.scrollView.scrollToEnd({ animated: true });
}

if (
transactionId &&
maxValueMode &&
selectedAsset.isETH &&
!isEmpty(gasFeeEstimates) &&
(haveGasFeeMaxNativeChanged || isControllerTransactionAdded)
) {
updateTransactionToMaxValue({
transactionId,
isEIP1559Transaction,
EIP1559GasTransaction,
legacyGasTransaction,
accountBalance: accounts[from].balance,
setTransactionValue: this.props.setTransactionValue,
});

// In order to prevent race condition do not remove this early return.
// Another update will be triggered by `updateEditableParams` and validateAmount will be called next update.
return;
}

if (haveGasPropertiesChanged) {
const gasEstimateTypeChanged =
prevProps.gasEstimateType !== this.props.gasEstimateType;
const gasSelected = gasEstimateTypeChanged
? AppConstants.GAS_OPTIONS.MEDIUM
: this.state.gasSelected;

if (
maxValueMode &&
selectedAsset.isETH &&
!isEmpty(gasFeeEstimates) &&
haveGasFeeMaxNativeChanged
) {
updateTransactionToMaxValue({
transactionId,
isEIP1559Transaction,
EIP1559GasTransaction,
legacyGasTransaction,
accountBalance: accounts[from].balance,
setTransactionValue: this.props.setTransactionValue,
});

// In order to prevent race condition do not remove this early return.
// Another update will be triggered by `updateEditableParams` and validateAmount will be called next update.
return;
}

if (
(!this.state.stopUpdateGas && !this.state.advancedGasInserted) ||
gasEstimateTypeChanged
Expand Down Expand Up @@ -1621,6 +1623,7 @@ const mapStateToProps = (state) => {
transactionMetadata: selectCurrentTransactionMetadata(state),
useTransactionSimulations: selectUseTransactionSimulations(state),
securityAlertResponse: selectCurrentTransactionSecurityAlertResponse(state),
maxValueMode: state.transaction.maxValueMode,
};
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { updateTransactionToMaxValue } from './utils';
import { BN } from 'ethereumjs-util';
import { toWei } from '../../../../../util/number';
import { hexToBN } from '@metamask/controller-utils';

// Mock the Engine and its context
jest.mock('../../../../../util/transaction-controller', () => ({
Expand All @@ -13,8 +13,8 @@ describe('updateTransactionToMaxValue', () => {
it('should update the transaction value correctly', async () => {
const transactionId = 'testTransactionId';
const isEIP1559Transaction = true;
const EIP1559GasTransaction = { gasFeeMaxNative: '0.01' };
const legacyGasTransaction = { gasFeeMaxNative: '0.02' };
const EIP1559GasTransaction = { gasFeeMaxHex: '0x01' };
const legacyGasTransaction = { gasFeeMaxHex: '0x02' };
const accountBalance = '0x2386f26fc10000'; // 0.1 ether in wei
const setTransactionValue = jest.fn();

Expand All @@ -29,7 +29,7 @@ describe('updateTransactionToMaxValue', () => {

// Calculate expected max transaction value
const accountBalanceBN = new BN('2386f26fc10000', 16); // 0.1 ether in wei
const transactionFeeMax = new BN(toWei('0.01', 'ether'), 10);
const transactionFeeMax = hexToBN(EIP1559GasTransaction.gasFeeMaxHex);
const expectedMaxTransactionValueBN =
accountBalanceBN.sub(transactionFeeMax);
const expectedMaxTransactionValueHex =
Expand Down
21 changes: 11 additions & 10 deletions app/components/Views/confirmations/SendFlow/Confirm/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { BN } from 'ethereumjs-util';
import type { TransactionMeta } from '@metamask/transaction-controller';
import { remove0x, add0x } from '@metamask/utils';
import { toWei } from '../../../../../util/number';
import { hexToBN } from '@metamask/controller-utils';
import { updateEditableParams } from '../../../../../util/transaction-controller';

export const updateTransactionToMaxValue = async ({
Expand All @@ -15,28 +14,30 @@ export const updateTransactionToMaxValue = async ({
transactionId: string;
isEIP1559Transaction: boolean;
EIP1559GasTransaction: {
gasFeeMaxNative: string;
gasFeeMaxHex: string;
};
legacyGasTransaction: {
gasFeeMaxNative: string;
gasFeeMaxHex: string;
};
accountBalance: string;
setTransactionValue: (value: string) => void;
}) => {
const { gasFeeMaxNative } = isEIP1559Transaction
const { gasFeeMaxHex } = isEIP1559Transaction
? EIP1559GasTransaction
: legacyGasTransaction;

const accountBalanceBN = new BN(remove0x(accountBalance), 16);
const transactionFeeMax = new BN(toWei(gasFeeMaxNative, 'ether'), 16);
const transactionFeeMax = hexToBN(gasFeeMaxHex);

const maxTransactionValueBN = accountBalanceBN.sub(transactionFeeMax);

const maxTransactionValueHex = add0x(maxTransactionValueBN.toString(16));

const txMeta = (await updateEditableParams(transactionId, {
value: maxTransactionValueHex,
})) as TransactionMeta;
if (transactionId) {
await updateEditableParams(transactionId, {
value: maxTransactionValueHex,
});
}

setTransactionValue(txMeta.txParams.value as string);
setTransactionValue(maxTransactionValueHex);
};
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ const mapStateToProps = (state) => {
),
ambiguousAddressEntries: state.user.ambiguousAddressEntries,
};
}
};

const mapDispatchToProps = (dispatch) => ({
setRecipient: (
Expand Down
1 change: 1 addition & 0 deletions app/core/GasPolling/GasPolling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ describe('GetEIP1559TransactionData', () => {
gasFeeMinConversion: '0.09',
gasFeeMinNative: '0.00005',
gasLimitHex: '0x8163' as Hex,
gasFeeMaxHex: '0x01',
maxPriorityFeeConversion: '0.09',
maxPriorityFeeNative: '0.00005',
renderableGasFeeMaxConversion: '$0.09',
Expand Down
2 changes: 2 additions & 0 deletions app/util/transactions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,7 @@ export const parseTransactionEIP1559 = (
gasFeeMinConversion,
renderableGasFeeMinConversion,
gasFeeMaxNative,
gasFeeMaxHex,
renderableGasFeeMaxNative,
gasFeeMaxConversion,
renderableGasFeeMaxConversion,
Expand Down Expand Up @@ -1242,6 +1243,7 @@ export const parseTransactionEIP1559 = (
gasFeeMinConversion,
renderableGasFeeMinConversion,
gasFeeMaxNative,
gasFeeMaxHex,
renderableGasFeeMaxNative,
gasFeeMaxConversion,
renderableGasFeeMaxConversion,
Expand Down
14 changes: 8 additions & 6 deletions e2e/pages/Send/SendView.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import TestHelpers from '../../helpers';
import Gestures from '../../utils/Gestures';
import Matchers from '../../utils/Matchers';
import { SendViewSelectorsIDs } from '../../selectors/SendFlow/SendView.selectors';
import {AddAddressModalSelectorsIDs} from '../../selectors/SendFlow/AddAddressModal.selectors'
import Assertions from '../../utils/Assertions';

import { AddAddressModalSelectorsIDs } from '../../selectors/SendFlow/AddAddressModal.selectors';

class SendView {
get cancelButton() {
Expand Down Expand Up @@ -32,7 +30,9 @@ class SendView {
}

get sendAddressConfirmation() {
return Matchers.getElementByID(AddAddressModalSelectorsIDs.ADD_ADDRESS_BUTTON);
return Matchers.getElementByID(
AddAddressModalSelectorsIDs.ADD_ADDRESS_BUTTON,
);
}

get removeAddressButton() {
Expand Down Expand Up @@ -88,8 +88,10 @@ class SendView {
await TestHelpers.delay(1000);
}

async splitAddressText(){
const attributes = await (await this.sendAddressConfirmation).getAttributes();
async splitAddressText() {
const attributes = await (
await this.sendAddressConfirmation
).getAttributes();
return await attributes.label.split(' ');
}
}
Expand Down
Loading