diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index f9b9f4d27..0a0d720d5 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -445,7 +445,7 @@ export default class TransactionController extends EventEmitter { * @param {string} editableParams.gasPrice * @returns {TransactionMeta} the txMeta of the updated transaction */ - updateEditableParams(txId, { data, from, to, value, gas, gasPrice }) { + async updateEditableParams(txId, { data, from, to, value, gas, gasPrice }) { this._throwErrorIfNotUnapprovedTx(txId, 'updateEditableParams'); const editableParams = { @@ -461,7 +461,20 @@ export default class TransactionController extends EventEmitter { // only update what is defined editableParams.txParams = pickBy(editableParams.txParams); + + // update transaction type in case it has changes + const transactionBeforeEdit = this._getTransaction(txId); + const { type } = await determineTransactionType( + { + ...transactionBeforeEdit.txParams, + ...editableParams.txParams, + }, + this.query, + ); + editableParams.type = type; + const note = `Update Editable Params for ${txId}`; + this._updateTransaction(txId, editableParams, note); return this._getTransaction(txId); } diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index a324c56fe..422aaadd7 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -2245,4 +2245,125 @@ describe('Transaction Controller', function () { assert.equal(result.destinationTokenAddress, VALID_ADDRESS_TWO); // not updated even though it's passed in to update }); }); + + describe('updateEditableParams', function () { + let txStateManager; + + beforeEach(function () { + txStateManager = txController.txStateManager; + txStateManager.addTransaction({ + id: '1', + status: TRANSACTION_STATUSES.UNAPPROVED, + metamaskNetworkId: currentNetworkId, + txParams: { + gas: '0x001', + gasPrice: '0x002', + // max fees can not be mixed with gasPrice + // maxPriorityFeePerGas: '0x003', + // maxFeePerGas: '0x004', + to: VALID_ADDRESS, + from: VALID_ADDRESS, + }, + estimateUsed: '0x005', + estimatedBaseFee: '0x006', + decEstimatedBaseFee: '6', + type: 'simpleSend', + userEditedGasLimit: '0x008', + userFeeLevel: 'medium', + }); + }); + + it('updates editible params when type changes from simple send to token transfer', async function () { + // test update gasFees + await txController.updateEditableParams('1', { + data: + '0xa9059cbb000000000000000000000000e18035bf8712672935fdb4e5e431b1a0183d2dfc0000000000000000000000000000000000000000000000000de0b6b3a7640000', + }); + const result = txStateManager.getTransaction('1'); + assert.equal( + result.txParams.data, + '0xa9059cbb000000000000000000000000e18035bf8712672935fdb4e5e431b1a0183d2dfc0000000000000000000000000000000000000000000000000de0b6b3a7640000', + ); + assert.equal(result.type, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER); + }); + + it('updates editible params when type changes from token transfer to simple send', async function () { + // test update gasFees + txStateManager.addTransaction({ + id: '2', + status: TRANSACTION_STATUSES.UNAPPROVED, + metamaskNetworkId: currentNetworkId, + txParams: { + gas: '0x001', + gasPrice: '0x002', + // max fees can not be mixed with gasPrice + // maxPriorityFeePerGas: '0x003', + // maxFeePerGas: '0x004', + to: VALID_ADDRESS, + from: VALID_ADDRESS, + data: + '0xa9059cbb000000000000000000000000e18035bf8712672935fdb4e5e431b1a0183d2dfc0000000000000000000000000000000000000000000000000de0b6b3a7640000', + }, + estimateUsed: '0x005', + estimatedBaseFee: '0x006', + decEstimatedBaseFee: '6', + type: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, + userEditedGasLimit: '0x008', + userFeeLevel: 'medium', + }); + await txController.updateEditableParams('2', { + data: '0x', + }); + const result = txStateManager.getTransaction('2'); + assert.equal(result.txParams.data, '0x'); + assert.equal(result.type, TRANSACTION_TYPES.SIMPLE_SEND); + }); + + it('updates editible params when type changes from simpleSend to contract interaction', async function () { + // test update gasFees + txStateManager.addTransaction({ + id: '3', + status: TRANSACTION_STATUSES.UNAPPROVED, + metamaskNetworkId: currentNetworkId, + txParams: { + gas: '0x001', + gasPrice: '0x002', + // max fees can not be mixed with gasPrice + // maxPriorityFeePerGas: '0x003', + // maxFeePerGas: '0x004', + to: VALID_ADDRESS, + from: VALID_ADDRESS, + }, + estimateUsed: '0x005', + estimatedBaseFee: '0x006', + decEstimatedBaseFee: '6', + type: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, + userEditedGasLimit: '0x008', + userFeeLevel: 'medium', + }); + providerResultStub.eth_getCode = '0x5'; + await txController.updateEditableParams('3', { + data: '0x123', + }); + const result = txStateManager.getTransaction('3'); + assert.equal(result.txParams.data, '0x123'); + assert.equal(result.type, TRANSACTION_TYPES.CONTRACT_INTERACTION); + }); + + it('updates editible params when type does not change', async function () { + // test update gasFees + await txController.updateEditableParams('1', { + data: '0x123', + gas: '0xabc', + from: VALID_ADDRESS_TWO, + }); + const result = txStateManager.getTransaction('1'); + assert.equal(result.txParams.data, '0x123'); + assert.equal(result.txParams.gas, '0xabc'); + assert.equal(result.txParams.from, VALID_ADDRESS_TWO); + assert.equal(result.txParams.to, VALID_ADDRESS); + assert.equal(result.txParams.gasPrice, '0x002'); + assert.equal(result.type, TRANSACTION_TYPES.SIMPLE_SEND); + }); + }); }); diff --git a/ui/ducks/send/send.js b/ui/ducks/send/send.js index af588fcac..3e81bc09d 100644 --- a/ui/ducks/send/send.js +++ b/ui/ducks/send/send.js @@ -2006,6 +2006,7 @@ export function signTransaction() { eip1559support ? eip1559OnlyTxParamsToUpdate : txParams, ), }; + await dispatch( addHistoryEntry( `sendFlow - user clicked next and transaction should be updated in controller`,