From 972b122d47375609c0535fc2249b4fcffcb6d148 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Fri, 23 Jul 2021 22:10:40 -0230 Subject: [PATCH 1/5] Fix sending maximum of an ERC20 token (#11594) * Fix sending maximum of an ERC20 token * Always update gas limit when send amount updates --- ui/ducks/send/send.js | 5 +- ui/ducks/send/send.test.js | 169 +++++++++++++++++++++++++++++++------ 2 files changed, 143 insertions(+), 31 deletions(-) diff --git a/ui/ducks/send/send.js b/ui/ducks/send/send.js index 33b20cb30..9ab2a8585 100644 --- a/ui/ducks/send/send.js +++ b/ui/ducks/send/send.js @@ -1112,9 +1112,7 @@ export function updateSendAmount(amount) { if (state.send.amount.mode === AMOUNT_MODES.MAX) { await dispatch(actions.updateAmountMode(AMOUNT_MODES.INPUT)); } - if (state.send.asset.type === ASSET_TYPES.TOKEN) { - await dispatch(computeEstimatedGasLimit()); - } + await dispatch(computeEstimatedGasLimit()); }; } @@ -1274,6 +1272,7 @@ export function toggleSendMaxMode() { await dispatch(actions.updateAmountMode(AMOUNT_MODES.MAX)); await dispatch(actions.updateAmountToMax()); } + await dispatch(computeEstimatedGasLimit()); }; } diff --git a/ui/ducks/send/send.test.js b/ui/ducks/send/send.test.js index c9f9fe32d..053a4b895 100644 --- a/ui/ducks/send/send.test.js +++ b/ui/ducks/send/send.test.js @@ -1069,7 +1069,34 @@ describe('Send Slice', () => { }; it('should create an action to update send amount', async () => { - const store = mockStore(defaultSendAmountState); + const sendState = { + metamask: { + blockGasLimit: '', + selectedAddress: '', + provider: { + chainId: '0x1', + }, + }, + ...defaultSendAmountState.send, + send: { + asset: { + details: {}, + }, + gas: { + gasPrice: '', + }, + recipient: { + address: '', + }, + amount: { + value: '', + }, + draftTransaction: { + userInputHexData: '', + }, + }, + }; + const store = mockStore(sendState); const newSendAmount = 'aNewSendAmount'; @@ -1077,35 +1104,73 @@ describe('Send Slice', () => { const actionResult = store.getActions(); - const expectedActionResult = [ - { type: 'send/updateSendAmount', payload: 'aNewSendAmount' }, - ]; + const expectedFirstActionResult = { + type: 'send/updateSendAmount', + payload: 'aNewSendAmount', + }; - expect(actionResult).toStrictEqual(expectedActionResult); + expect(actionResult[0]).toStrictEqual(expectedFirstActionResult); + expect(actionResult[1].type).toStrictEqual( + 'send/computeEstimatedGasLimit/pending', + ); + expect(actionResult[2].type).toStrictEqual( + 'metamask/gas/SET_CUSTOM_GAS_LIMIT', + ); + expect(actionResult[3].type).toStrictEqual( + 'send/computeEstimatedGasLimit/fulfilled', + ); }); it('should create an action to update send amount mode to `INPUT` when mode is `MAX`', async () => { - const maxModeSendState = { + const sendState = { + metamask: { + blockGasLimit: '', + selectedAddress: '', + provider: { + chainId: '0x1', + }, + }, + ...defaultSendAmountState.send, send: { - ...defaultSendAmountState.send, + asset: { + details: {}, + }, + gas: { + gasPrice: '', + }, + recipient: { + address: '', + }, amount: { - mode: AMOUNT_MODES.MAX, + value: '', + }, + draftTransaction: { + userInputHexData: '', }, }, }; - const store = mockStore(maxModeSendState); + const store = mockStore(sendState); await store.dispatch(updateSendAmount()); const actionResult = store.getActions(); - const expectedActionResult = [ - { type: 'send/updateSendAmount', payload: undefined }, - { type: 'send/updateAmountMode', payload: AMOUNT_MODES.INPUT }, - ]; + const expectedFirstActionResult = { + type: 'send/updateSendAmount', + payload: undefined, + }; - expect(actionResult).toStrictEqual(expectedActionResult); + expect(actionResult[0]).toStrictEqual(expectedFirstActionResult); + expect(actionResult[1].type).toStrictEqual( + 'send/computeEstimatedGasLimit/pending', + ); + expect(actionResult[2].type).toStrictEqual( + 'metamask/gas/SET_CUSTOM_GAS_LIMIT', + ); + expect(actionResult[3].type).toStrictEqual( + 'send/computeEstimatedGasLimit/fulfilled', + ); }); it('should create an action computeEstimateGasLimit and change states from pending to fulfilled with token asset types', async () => { @@ -1535,8 +1600,27 @@ describe('Send Slice', () => { it('should create actions to toggle update max mode when send amount mode is not max', async () => { const sendMaxModeState = { send: { + asset: { + type: ASSET_TYPES.TOKEN, + details: {}, + }, + gas: { + gasPrice: '', + }, + recipient: { + address: '', + }, amount: { mode: '', + value: '', + }, + draftTransaction: { + userInputHexData: '', + }, + }, + metamask: { + provider: { + chainId: RINKEBY_CHAIN_ID, }, }, }; @@ -1547,20 +1631,44 @@ describe('Send Slice', () => { const actionResult = store.getActions(); - const expectedActionReslt = [ - { type: 'send/updateAmountMode', payload: AMOUNT_MODES.MAX }, - { type: 'send/updateAmountToMax', payload: undefined }, - ]; - - expect(actionResult).toHaveLength(2); - expect(actionResult).toStrictEqual(expectedActionReslt); + expect(actionResult).toHaveLength(5); + expect(actionResult[0].type).toStrictEqual('send/updateAmountMode'); + expect(actionResult[1].type).toStrictEqual('send/updateAmountToMax'); + expect(actionResult[2].type).toStrictEqual( + 'send/computeEstimatedGasLimit/pending', + ); + expect(actionResult[3].type).toStrictEqual( + 'metamask/gas/SET_CUSTOM_GAS_LIMIT', + ); + expect(actionResult[4].type).toStrictEqual( + 'send/computeEstimatedGasLimit/fulfilled', + ); }); it('should create actions to toggle off max mode when send amount mode is max', async () => { const sendMaxModeState = { send: { + asset: { + type: ASSET_TYPES.TOKEN, + details: {}, + }, + gas: { + gasPrice: '', + }, + recipient: { + address: '', + }, amount: { mode: AMOUNT_MODES.MAX, + value: '', + }, + draftTransaction: { + userInputHexData: '', + }, + }, + metamask: { + provider: { + chainId: RINKEBY_CHAIN_ID, }, }, }; @@ -1570,13 +1678,18 @@ describe('Send Slice', () => { const actionResult = store.getActions(); - const expectedActionReslt = [ - { type: 'send/updateAmountMode', payload: AMOUNT_MODES.INPUT }, - { type: 'send/updateSendAmount', payload: '0x0' }, - ]; - - expect(actionResult).toHaveLength(2); - expect(actionResult).toStrictEqual(expectedActionReslt); + expect(actionResult).toHaveLength(5); + expect(actionResult[0].type).toStrictEqual('send/updateAmountMode'); + expect(actionResult[1].type).toStrictEqual('send/updateSendAmount'); + expect(actionResult[2].type).toStrictEqual( + 'send/computeEstimatedGasLimit/pending', + ); + expect(actionResult[3].type).toStrictEqual( + 'metamask/gas/SET_CUSTOM_GAS_LIMIT', + ); + expect(actionResult[4].type).toStrictEqual( + 'send/computeEstimatedGasLimit/fulfilled', + ); }); }); From 75c7d284c5ef448fe26fa156f3946bd67a3ef881 Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Sat, 24 Jul 2021 00:44:37 +0000 Subject: [PATCH 2/5] Version v9.8.3 --- CHANGELOG.md | 7 ++++++- package.json | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c06c88bd..b691ee795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [9.8.3] +### Uncategorized +- Fix sending maximum of an ERC20 token ([#11594](https://github.com/MetaMask/metamask-extension/pull/11594)) + ## [9.8.2] ### Changed - [1156511545](https://github.com/MetaMask/metamask-extension/pull/11545): Allow MetaMask Swaps to support Polygon network @@ -2344,7 +2348,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Uncategorized - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v9.8.2...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v9.8.3...HEAD +[9.8.3]: https://github.com/MetaMask/metamask-extension/compare/v9.8.2...v9.8.3 [9.8.2]: https://github.com/MetaMask/metamask-extension/compare/v9.8.1...v9.8.2 [9.8.1]: https://github.com/MetaMask/metamask-extension/compare/v9.8.0...v9.8.1 [9.8.0]: https://github.com/MetaMask/metamask-extension/compare/v9.7.1...v9.8.0 diff --git a/package.json b/package.json index 61b05b65f..70ab3b396 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "9.8.2", + "version": "9.8.3", "private": true, "repository": { "type": "git", From 5fe6830ffdf006ac4a0223c1dd7b8b25bf97b748 Mon Sep 17 00:00:00 2001 From: ryanml Date: Sat, 24 Jul 2021 15:50:50 -0700 Subject: [PATCH 3/5] [skip e2e] Update changelog for v9.8.3 (#11601) --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b691ee795..af8e74dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,23 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## [9.8.3] -### Uncategorized -- Fix sending maximum of an ERC20 token ([#11594](https://github.com/MetaMask/metamask-extension/pull/11594)) +### Fixed +- [#11594](https://github.com/MetaMask/metamask-extension/pull/11594): Fixed ERC20 token maximum send ## [9.8.2] ### Changed -- [1156511545](https://github.com/MetaMask/metamask-extension/pull/11545): Allow MetaMask Swaps to support Polygon network +- [#11545](https://github.com/MetaMask/metamask-extension/pull/11545): Allow MetaMask Swaps to support Polygon network ### Fixed -- [11565](https://github.com/MetaMask/metamask-extension/pull/11565): Fix gas limit estimation for some tokens on custom networks -- [11581](https://github.com/MetaMask/metamask-extension/pull/11581): Fixed bug that resulted in sends to some contracts being disabled. +- [#11565](https://github.com/MetaMask/metamask-extension/pull/11565): Fix gas limit estimation for some tokens on custom networks +- [#11581](https://github.com/MetaMask/metamask-extension/pull/11581): Fixed bug that resulted in sends to some contracts being disabled. ## [9.8.1] ### Changed - Adjusting transaction metrics values ### Fixed -- [11538](https://github.com/MetaMask/metamask-extension/pull/11538): Fixed bug that prevented users from continuing to swap after going 'back' from the View Quote page of the swaps flow. +- [#11538](https://github.com/MetaMask/metamask-extension/pull/11538): Fixed bug that prevented users from continuing to swap after going 'back' from the View Quote page of the swaps flow. ## [9.8.0] ### Added From c72f1c5ae9d1f4e9247f2c6e1995ea85103a4486 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 26 Jul 2021 11:33:05 -0230 Subject: [PATCH 4/5] Ensure that the send flow state recipient nickname gets set if recipient address is in addressBook (#11610) --- CHANGELOG.md | 1 + ui/ducks/send/send.js | 16 +++++++-- ui/ducks/send/send.test.js | 68 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af8e74dd8..b5da4b270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [9.8.3] ### Fixed - [#11594](https://github.com/MetaMask/metamask-extension/pull/11594): Fixed ERC20 token maximum send +- [#11610](https://github.com/MetaMask/metamask-extension/pull/11610): Fixed nickname display upon pasting saved address in send flow ## [9.8.2] ### Changed diff --git a/ui/ducks/send/send.js b/ui/ducks/send/send.js index 9ab2a8585..30ddb2d80 100644 --- a/ui/ducks/send/send.js +++ b/ui/ducks/send/send.js @@ -1209,6 +1209,10 @@ export function useMyAccountsForRecipientSearch() { * address results in hex data changing because the recipient address is * encoded in the data instead of being in the 'to' field. The to field in a * token send will always be the token contract address. + * If no nickname is provided, the address book state will be checked to see if + * a nickname for the passed address has already been saved. This ensures the + * (temporary) send state recipient nickname is consistent with the address book + * nickname which has already been persisted to state. * @param {Object} recipient - Recipient information * @param {string} recipient.address - hex address to send the transaction to * @param {string} [recipient.nickname] - Alias for the address to display @@ -1216,8 +1220,16 @@ export function useMyAccountsForRecipientSearch() { * @returns {void} */ export function updateRecipient({ address, nickname }) { - return async (dispatch) => { - await dispatch(actions.updateRecipient({ address, nickname })); + return async (dispatch, getState) => { + const state = getState(); + const nicknameFromAddressBook = + getAddressBookEntry(state, address)?.name ?? ''; + await dispatch( + actions.updateRecipient({ + address, + nickname: nickname || nicknameFromAddressBook, + }), + ); await dispatch(computeEstimatedGasLimit()); }; } diff --git a/ui/ducks/send/send.test.js b/ui/ducks/send/send.test.js index 053a4b895..998e3306f 100644 --- a/ui/ducks/send/send.test.js +++ b/ui/ducks/send/send.test.js @@ -1419,6 +1419,7 @@ describe('Send Slice', () => { const updateRecipientState = { metamask: { + addressBook: {}, provider: { chainId: '0x1', }, @@ -1464,9 +1465,75 @@ describe('Send Slice', () => { ); }); + it('should update recipient nickname if the passed address exists in the addressBook state but no nickname param is provided', async () => { + global.eth = { + getCode: sinon.stub(), + }; + + const TEST_RECIPIENT_ADDRESS = + '0x0000000000000000000000000000000000000001'; + const TEST_RECIPIENT_NAME = 'The 1 address'; + + const updateRecipientState = { + metamask: { + addressBook: { + '0x1': [ + { + address: TEST_RECIPIENT_ADDRESS, + name: TEST_RECIPIENT_NAME, + }, + ], + }, + provider: { + chainId: '0x1', + }, + }, + send: { + account: { + balance: '', + }, + asset: { + type: '', + }, + gas: { + gasPrice: '', + }, + recipient: { + address: '', + }, + amount: { + value: '', + }, + draftTransaction: { + userInputHexData: '', + }, + }, + }; + + const store = mockStore(updateRecipientState); + + await store.dispatch( + updateRecipient({ + address: '0x0000000000000000000000000000000000000001', + nickname: '', + }), + ); + + const actionResult = store.getActions(); + expect(actionResult).toHaveLength(4); + expect(actionResult[0].type).toStrictEqual('send/updateRecipient'); + expect(actionResult[0].payload.address).toStrictEqual( + TEST_RECIPIENT_ADDRESS, + ); + expect(actionResult[0].payload.nickname).toStrictEqual( + TEST_RECIPIENT_NAME, + ); + }); + it('should create actions to reset recipient input and ens, calculate gas and then validate input', async () => { const tokenState = { metamask: { + addressBook: {}, blockGasLimit: '', selectedAddress: '', provider: { @@ -1520,6 +1587,7 @@ describe('Send Slice', () => { it('should create actions to reset recipient input and ens then validates input', async () => { const updateRecipientState = { metamask: { + addressBook: {}, provider: { chainId: '', }, From 0cbc06a7938ec89489a86b544138a80ee54308e5 Mon Sep 17 00:00:00 2001 From: ryanml Date: Mon, 26 Jul 2021 10:34:46 -0700 Subject: [PATCH 5/5] Fixing PR links in 9.8.1 and 9.8.2 (Changelog) (#11617)