Merge pull request #11600 from MetaMask/Version-v9.8.3

Version v9.8.3 RC
feature/default_network_editable
ryanml 3 years ago committed by GitHub
commit 447cb03621
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      CHANGELOG.md
  2. 2
      package.json
  3. 21
      ui/ducks/send/send.js
  4. 237
      ui/ducks/send/send.test.js

@ -6,20 +6,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [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] ## [9.8.2]
### Changed ### 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 ### Fixed
- [11565](https://github.com/MetaMask/metamask-extension/pull/11565): Fix gas limit estimation for some tokens on custom networks - [#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. - [#11581](https://github.com/MetaMask/metamask-extension/pull/11581): Fixed bug that resulted in sends to some contracts being disabled.
## [9.8.1] ## [9.8.1]
### Changed ### Changed
- Adjusting transaction metrics values - Adjusting transaction metrics values
### Fixed ### 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] ## [9.8.0]
### Added ### Added
@ -2344,7 +2349,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Uncategorized ### Uncategorized
- Added the ability to restore accounts from seed words. - 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.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.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 [9.8.0]: https://github.com/MetaMask/metamask-extension/compare/v9.7.1...v9.8.0

@ -1,6 +1,6 @@
{ {
"name": "metamask-crx", "name": "metamask-crx",
"version": "9.8.2", "version": "9.8.3",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",

@ -1112,9 +1112,7 @@ export function updateSendAmount(amount) {
if (state.send.amount.mode === AMOUNT_MODES.MAX) { if (state.send.amount.mode === AMOUNT_MODES.MAX) {
await dispatch(actions.updateAmountMode(AMOUNT_MODES.INPUT)); await dispatch(actions.updateAmountMode(AMOUNT_MODES.INPUT));
} }
if (state.send.asset.type === ASSET_TYPES.TOKEN) { await dispatch(computeEstimatedGasLimit());
await dispatch(computeEstimatedGasLimit());
}
}; };
} }
@ -1211,6 +1209,10 @@ export function useMyAccountsForRecipientSearch() {
* address results in hex data changing because the recipient address is * 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 * 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. * 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 {Object} recipient - Recipient information
* @param {string} recipient.address - hex address to send the transaction to * @param {string} recipient.address - hex address to send the transaction to
* @param {string} [recipient.nickname] - Alias for the address to display * @param {string} [recipient.nickname] - Alias for the address to display
@ -1218,8 +1220,16 @@ export function useMyAccountsForRecipientSearch() {
* @returns {void} * @returns {void}
*/ */
export function updateRecipient({ address, nickname }) { export function updateRecipient({ address, nickname }) {
return async (dispatch) => { return async (dispatch, getState) => {
await dispatch(actions.updateRecipient({ address, nickname })); const state = getState();
const nicknameFromAddressBook =
getAddressBookEntry(state, address)?.name ?? '';
await dispatch(
actions.updateRecipient({
address,
nickname: nickname || nicknameFromAddressBook,
}),
);
await dispatch(computeEstimatedGasLimit()); await dispatch(computeEstimatedGasLimit());
}; };
} }
@ -1274,6 +1284,7 @@ export function toggleSendMaxMode() {
await dispatch(actions.updateAmountMode(AMOUNT_MODES.MAX)); await dispatch(actions.updateAmountMode(AMOUNT_MODES.MAX));
await dispatch(actions.updateAmountToMax()); await dispatch(actions.updateAmountToMax());
} }
await dispatch(computeEstimatedGasLimit());
}; };
} }

@ -1069,7 +1069,34 @@ describe('Send Slice', () => {
}; };
it('should create an action to update send amount', async () => { 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'; const newSendAmount = 'aNewSendAmount';
@ -1077,35 +1104,73 @@ describe('Send Slice', () => {
const actionResult = store.getActions(); const actionResult = store.getActions();
const expectedActionResult = [ const expectedFirstActionResult = {
{ type: 'send/updateSendAmount', payload: 'aNewSendAmount' }, 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 () => { 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: { send: {
...defaultSendAmountState.send, asset: {
details: {},
},
gas: {
gasPrice: '',
},
recipient: {
address: '',
},
amount: { amount: {
mode: AMOUNT_MODES.MAX, value: '',
},
draftTransaction: {
userInputHexData: '',
}, },
}, },
}; };
const store = mockStore(maxModeSendState); const store = mockStore(sendState);
await store.dispatch(updateSendAmount()); await store.dispatch(updateSendAmount());
const actionResult = store.getActions(); const actionResult = store.getActions();
const expectedActionResult = [ const expectedFirstActionResult = {
{ type: 'send/updateSendAmount', payload: undefined }, type: 'send/updateSendAmount',
{ type: 'send/updateAmountMode', payload: AMOUNT_MODES.INPUT }, 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 () => { it('should create an action computeEstimateGasLimit and change states from pending to fulfilled with token asset types', async () => {
@ -1354,6 +1419,7 @@ describe('Send Slice', () => {
const updateRecipientState = { const updateRecipientState = {
metamask: { metamask: {
addressBook: {},
provider: { provider: {
chainId: '0x1', chainId: '0x1',
}, },
@ -1399,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 () => { it('should create actions to reset recipient input and ens, calculate gas and then validate input', async () => {
const tokenState = { const tokenState = {
metamask: { metamask: {
addressBook: {},
blockGasLimit: '', blockGasLimit: '',
selectedAddress: '', selectedAddress: '',
provider: { provider: {
@ -1455,6 +1587,7 @@ describe('Send Slice', () => {
it('should create actions to reset recipient input and ens then validates input', async () => { it('should create actions to reset recipient input and ens then validates input', async () => {
const updateRecipientState = { const updateRecipientState = {
metamask: { metamask: {
addressBook: {},
provider: { provider: {
chainId: '', chainId: '',
}, },
@ -1535,8 +1668,27 @@ describe('Send Slice', () => {
it('should create actions to toggle update max mode when send amount mode is not max', async () => { it('should create actions to toggle update max mode when send amount mode is not max', async () => {
const sendMaxModeState = { const sendMaxModeState = {
send: { send: {
asset: {
type: ASSET_TYPES.TOKEN,
details: {},
},
gas: {
gasPrice: '',
},
recipient: {
address: '',
},
amount: { amount: {
mode: '', mode: '',
value: '',
},
draftTransaction: {
userInputHexData: '',
},
},
metamask: {
provider: {
chainId: RINKEBY_CHAIN_ID,
}, },
}, },
}; };
@ -1547,20 +1699,44 @@ describe('Send Slice', () => {
const actionResult = store.getActions(); const actionResult = store.getActions();
const expectedActionReslt = [ expect(actionResult).toHaveLength(5);
{ type: 'send/updateAmountMode', payload: AMOUNT_MODES.MAX }, expect(actionResult[0].type).toStrictEqual('send/updateAmountMode');
{ type: 'send/updateAmountToMax', payload: undefined }, expect(actionResult[1].type).toStrictEqual('send/updateAmountToMax');
]; expect(actionResult[2].type).toStrictEqual(
'send/computeEstimatedGasLimit/pending',
expect(actionResult).toHaveLength(2); );
expect(actionResult).toStrictEqual(expectedActionReslt); 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 () => { it('should create actions to toggle off max mode when send amount mode is max', async () => {
const sendMaxModeState = { const sendMaxModeState = {
send: { send: {
asset: {
type: ASSET_TYPES.TOKEN,
details: {},
},
gas: {
gasPrice: '',
},
recipient: {
address: '',
},
amount: { amount: {
mode: AMOUNT_MODES.MAX, mode: AMOUNT_MODES.MAX,
value: '',
},
draftTransaction: {
userInputHexData: '',
},
},
metamask: {
provider: {
chainId: RINKEBY_CHAIN_ID,
}, },
}, },
}; };
@ -1570,13 +1746,18 @@ describe('Send Slice', () => {
const actionResult = store.getActions(); const actionResult = store.getActions();
const expectedActionReslt = [ expect(actionResult).toHaveLength(5);
{ type: 'send/updateAmountMode', payload: AMOUNT_MODES.INPUT }, expect(actionResult[0].type).toStrictEqual('send/updateAmountMode');
{ type: 'send/updateSendAmount', payload: '0x0' }, expect(actionResult[1].type).toStrictEqual('send/updateSendAmount');
]; expect(actionResult[2].type).toStrictEqual(
'send/computeEstimatedGasLimit/pending',
expect(actionResult).toHaveLength(2); );
expect(actionResult).toStrictEqual(expectedActionReslt); expect(actionResult[3].type).toStrictEqual(
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
);
expect(actionResult[4].type).toStrictEqual(
'send/computeEstimatedGasLimit/fulfilled',
);
}); });
}); });

Loading…
Cancel
Save