From b0a510562e2121461495b808f06acdee6b416c97 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Wed, 15 Sep 2021 10:59:51 -0500 Subject: [PATCH 01/12] Fix gas api overcalling (#12069) * Move gasEstimation calls onto edit-gas-popover instead of transaction list item * delete useCancelTransaction and useRetryTransaction hooks consolidate gasFee calls into cancel button component. * add tests * update component name * addressing feedback * fix failing e2e test * followup fix e2e tests * change useIncrementedGasFees to accept single transaction rather than transactionGroup as argument * remove unnecessary change to fixture * only ever pass primary transaction to useIncrementedGasFees * remove unnecessary optional chaining --- test/data/mock-pending-transaction-data.json | 234 +++++++++++++++ test/data/transaction-data.json | 266 ++++++++++++++++++ test/e2e/fixtures/send-edit/state.json | 17 ++ .../app/cancel-button/cancel-button.js | 64 +++++ ui/components/app/cancel-button/index.js | 1 + .../edit-gas-popover.component.js | 37 ++- ...transaction-list-item-details.component.js | 43 +-- .../transaction-list-item.component.js | 125 ++++---- .../transaction-list-item.component.test.js | 139 +++++++++ ui/hooks/useCancelTransaction.js | 55 ---- ui/hooks/useCancelTransaction.test.js | 114 -------- ui/hooks/useIncrementedGasFees.js | 20 +- ui/hooks/useRetryTransaction.js | 48 ---- ui/hooks/useRetryTransaction.test.js | 77 ----- 14 files changed, 823 insertions(+), 417 deletions(-) create mode 100644 test/data/mock-pending-transaction-data.json create mode 100644 ui/components/app/cancel-button/cancel-button.js create mode 100644 ui/components/app/cancel-button/index.js create mode 100644 ui/components/app/transaction-list-item/transaction-list-item.component.test.js delete mode 100644 ui/hooks/useCancelTransaction.js delete mode 100644 ui/hooks/useCancelTransaction.test.js delete mode 100644 ui/hooks/useRetryTransaction.js delete mode 100644 ui/hooks/useRetryTransaction.test.js diff --git a/test/data/mock-pending-transaction-data.json b/test/data/mock-pending-transaction-data.json new file mode 100644 index 000000000..46c4452f5 --- /dev/null +++ b/test/data/mock-pending-transaction-data.json @@ -0,0 +1,234 @@ +{ + "hasCancelled": false, + "hasRetried": false, + "initialTransaction": { + "id": 6854191329910881, + "time": 1631558469046, + "status": "approved", + "metamaskNetworkId": "42", + "chainId": "0x2a", + "loadingDefaults": false, + "dappSuggestedGasFees": null, + "txParams": { + "from": "0x0853dccd30e0582df80b16ec014092160b48e797", + "to": "0x8d09d17af2e20f51a9b598cb9edd01489a26ae27", + "value": "0x38d7ea4c68000", + "gas": "0x5208", + "maxFeePerGas": "0x47868c00", + "maxPriorityFeePerGas": "0x47868c00", + "type": "0x2" + }, + "origin": "metamask", + "type": "sentEther", + "history": [ + { + "id": 6854191329910881, + "time": 1631558469046, + "status": "unapproved", + "metamaskNetworkId": "42", + "chainId": "0x2a", + "loadingDefaults": true, + "dappSuggestedGasFees": null, + "txParams": { + "from": "0x0853dccd30e0582df80b16ec014092160b48e797", + "to": "0x8d09d17af2e20f51a9b598cb9edd01489a26ae27", + "value": "0x38d7ea4c68000", + "gas": "0x5208", + "maxFeePerGas": "0x47868c00", + "maxPriorityFeePerGas": "0x47868c00", + "type": "0x2" + }, + "origin": "metamask", + "type": "sentEther" + }, + [ + { + "op": "replace", + "path": "/loadingDefaults", + "value": false, + "note": "Added new unapproved transaction.", + "timestamp": 1631558469059 + }, + { + "op": "add", + "path": "/userFeeLevel", + "value": "medium" + } + ], + [ + { + "op": "add", + "path": "/estimatedBaseFee", + "value": "0", + "note": "confTx: user approved transaction", + "timestamp": 1631558472917 + } + ], + [ + { + "op": "replace", + "path": "/status", + "value": "approved", + "note": "txStateManager: setting status to approved", + "timestamp": 1631558472925 + } + ] + ], + "userFeeLevel": "medium", + "estimatedBaseFee": "0" + }, + "primaryTransaction": { + "id": 6854191329910881, + "time": 1631558469046, + "status": "approved", + "metamaskNetworkId": "42", + "chainId": "0x2a", + "loadingDefaults": false, + "dappSuggestedGasFees": null, + "txParams": { + "from": "0x0853dccd30e0582df80b16ec014092160b48e797", + "to": "0x8d09d17af2e20f51a9b598cb9edd01489a26ae27", + "value": "0x38d7ea4c68000", + "gas": "0x5208", + "maxFeePerGas": "0x47868c00", + "maxPriorityFeePerGas": "0x47868c00", + "type": "0x2" + }, + "origin": "metamask", + "type": "sentEther", + "history": [ + { + "id": 6854191329910881, + "time": 1631558469046, + "status": "unapproved", + "metamaskNetworkId": "42", + "chainId": "0x2a", + "loadingDefaults": true, + "dappSuggestedGasFees": null, + "txParams": { + "from": "0x0853dccd30e0582df80b16ec014092160b48e797", + "to": "0x8d09d17af2e20f51a9b598cb9edd01489a26ae27", + "value": "0x38d7ea4c68000", + "gas": "0x5208", + "maxFeePerGas": "0x47868c00", + "maxPriorityFeePerGas": "0x47868c00", + "type": "0x2" + }, + "origin": "metamask", + "type": "sentEther" + }, + [ + { + "op": "replace", + "path": "/loadingDefaults", + "value": false, + "note": "Added new unapproved transaction.", + "timestamp": 1631558469059 + }, + { + "op": "add", + "path": "/userFeeLevel", + "value": "medium" + } + ], + [ + { + "op": "add", + "path": "/estimatedBaseFee", + "value": "0", + "note": "confTx: user approved transaction", + "timestamp": 1631558472917 + } + ], + [ + { + "op": "replace", + "path": "/status", + "value": "approved", + "note": "txStateManager: setting status to approved", + "timestamp": 1631558472925 + } + ] + ], + "userFeeLevel": "medium", + "estimatedBaseFee": "0" + }, + "transactions": [ + { + "id": 6854191329910881, + "time": 1631558469046, + "status": "approved", + "metamaskNetworkId": "42", + "chainId": "0x2a", + "loadingDefaults": false, + "dappSuggestedGasFees": null, + "txParams": { + "from": "0x0853dccd30e0582df80b16ec014092160b48e797", + "to": "0x8d09d17af2e20f51a9b598cb9edd01489a26ae27", + "value": "0x38d7ea4c68000", + "gas": "0x5208", + "maxFeePerGas": "0x47868c00", + "maxPriorityFeePerGas": "0x47868c00", + "type": "0x2" + }, + "origin": "metamask", + "type": "sentEther", + "history": [ + { + "id": 6854191329910881, + "time": 1631558469046, + "status": "unapproved", + "metamaskNetworkId": "42", + "chainId": "0x2a", + "loadingDefaults": true, + "dappSuggestedGasFees": null, + "txParams": { + "from": "0x0853dccd30e0582df80b16ec014092160b48e797", + "to": "0x8d09d17af2e20f51a9b598cb9edd01489a26ae27", + "value": "0x38d7ea4c68000", + "gas": "0x5208", + "maxFeePerGas": "0x47868c00", + "maxPriorityFeePerGas": "0x47868c00", + "type": "0x2" + }, + "origin": "metamask", + "type": "sentEther" + }, + [ + { + "op": "replace", + "path": "/loadingDefaults", + "value": false, + "note": "Added new unapproved transaction.", + "timestamp": 1631558469059 + }, + { + "op": "add", + "path": "/userFeeLevel", + "value": "medium" + } + ], + [ + { + "op": "add", + "path": "/estimatedBaseFee", + "value": "0", + "note": "confTx: user approved transaction", + "timestamp": 1631558472917 + } + ], + [ + { + "op": "replace", + "path": "/status", + "value": "approved", + "note": "txStateManager: setting status to approved", + "timestamp": 1631558472925 + } + ] + ], + "userFeeLevel": "medium", + "estimatedBaseFee": "0" + } + ] +} diff --git a/test/data/transaction-data.json b/test/data/transaction-data.json index 37e7659dd..740e522d1 100644 --- a/test/data/transaction-data.json +++ b/test/data/transaction-data.json @@ -61,6 +61,68 @@ "transactionIndex": "0" } }, + "transactions": [ + { + "id": 4243712234858512, + "time": 1589314601567, + "status": "confirmed", + "metamaskNetworkId": "4", + "loadingDefaults": false, + "txParams": { + "from": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "to": "0xffe5bc4e8f1f969934d773fa67da095d2e491a97", + "nonce": "0xc", + "value": "0xde0b6b3a7640000", + "gas": "0x5208", + "gasPrice": "0x2540be400" + }, + "origin": "metamask", + "type": "sentEther", + "nonceDetails": { + "params": { + "highestLocallyConfirmed": 12, + "highestSuggested": 12, + "nextNetworkNonce": 12 + }, + "local": { + "name": "local", + "nonce": 12, + "details": { + "startPoint": 12, + "highest": 12 + } + }, + "network": { + "name": "network", + "nonce": 12, + "details": { + "blockNumber": "0x62d5dc", + "baseCount": 12 + } + } + }, + "r": "0xe0b79a8e33b15460ea79b05a5fb16bc067a796592eeb4edc5007c88615c12595", + "s": "0x1c834a25f1df07af5122996a40e99e554a40dc971a25041bc6e31638846c4f58", + "v": "0x2c", + "rawTx": "0xf86c0c8502540be40082520894ffe5bc4e8f1f969934d773fa67da095d2e491a97880de0b6b3a7640000802ca0e0b79a8e33b15460ea79b05a5fb16bc067a796592eeb4edc5007c88615c12595a01c834a25f1df07af5122996a40e99e554a40dc971a25041bc6e31638846c4f58", + "hash": "0x06bb79b856f5eb67025e4c4ffff44bca26ae135d1c3e6bd9a4193f422dcecca2", + "submittedTime": 1589314602908, + "txReceipt": { + "blockHash": "0xb9d2d71153b66146fde74b14b1c1ffc0588eb4a02ff464e32a4db9ae4bbfad8a", + "blockNumber": "62d5de", + "contractAddress": null, + "cumulativeGasUsed": "5208", + "from": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "gasUsed": "5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0xffe5bc4e8f1f969934d773fa67da095d2e491a97", + "transactionHash": "0x06bb79b856f5eb67025e4c4ffff44bca26ae135d1c3e6bd9a4193f422dcecca2", + "transactionIndex": "0" + } + } + ], "primaryTransaction": { "id": 4243712234858512, "time": 1589314601567, @@ -186,6 +248,68 @@ "transactionIndex": "0" } }, + "transactions": [ + { + "id": 4243712234858507, + "time": 1589314355872, + "status": "confirmed", + "metamaskNetworkId": "4", + "loadingDefaults": false, + "txParams": { + "from": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "to": "0x0ccc8aeeaf5ce790f3b448325981a143fdef8848", + "nonce": "0xb", + "value": "0x1bc16d674ec80000", + "gas": "0x5208", + "gasPrice": "0x2540be400" + }, + "origin": "metamask", + "type": "sentEther", + "nonceDetails": { + "params": { + "highestLocallyConfirmed": 0, + "highestSuggested": 10, + "nextNetworkNonce": 10 + }, + "local": { + "name": "local", + "nonce": 11, + "details": { + "startPoint": 10, + "highest": 11 + } + }, + "network": { + "name": "network", + "nonce": 10, + "details": { + "blockNumber": "0x62d5cc", + "baseCount": 10 + } + } + }, + "r": "0xe6828baea0a93a52779ffa5ea55e927781fb7d4be58107a29c75d314d433d055", + "s": "0x10613f984c57b8928d8ed9fce16ddda5746767e5f68f4c8fc29542e86a61f458", + "v": "0x2b", + "rawTx": "0xf86c0b8502540be400825208940ccc8aeeaf5ce790f3b448325981a143fdef8848881bc16d674ec80000802ba0e6828baea0a93a52779ffa5ea55e927781fb7d4be58107a29c75d314d433d055a010613f984c57b8928d8ed9fce16ddda5746767e5f68f4c8fc29542e86a61f458", + "hash": "0x2ccb9e2c0c64399ebc5c4ac70bebc5b537248458dee6cbce32df4b50c9e73bbd", + "submittedTime": 1589314356907, + "txReceipt": { + "blockHash": "0xfa3c8b63aaba2ef64ab328af72811dd5110a7641bd435cc6fbdfd9ea0d334542", + "blockNumber": "62d5ce", + "contractAddress": null, + "cumulativeGasUsed": "5208", + "from": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "gasUsed": "5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0ccc8aeeaf5ce790f3b448325981a143fdef8848", + "transactionHash": "0x2ccb9e2c0c64399ebc5c4ac70bebc5b537248458dee6cbce32df4b50c9e73bbd", + "transactionIndex": "0" + } + } + ], "primaryTransaction": { "id": 4243712234858507, "time": 1589314355872, @@ -312,6 +436,69 @@ "transactionIndex": "1" } }, + "transactions": [ + { + "id": 4243712234858506, + "time": 1589314345433, + "status": "confirmed", + "metamaskNetworkId": "4", + "loadingDefaults": false, + "txParams": { + "from": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "to": "0xffe5bc4e8f1f969934d773fa67da095d2e491a97", + "nonce": "0xa", + "value": "0x1bc16d674ec80000", + "gas": "0x5208", + "gasPrice": "0x306dc4200" + }, + "origin": "metamask", + "type": "sentEther", + "nonceDetails": { + "params": { + "highestLocallyConfirmed": 0, + "highestSuggested": 10, + "nextNetworkNonce": 10 + }, + "local": { + "name": "local", + "nonce": 10, + "details": { + "startPoint": 10, + "highest": 10 + } + }, + "network": { + "name": "network", + "nonce": 10, + "details": { + "blockNumber": "0x62d5cb", + "baseCount": 10 + } + } + }, + "r": "0x94b120a1df80be3dfad057b7ccac866b6b7583b63d61e5b021811c8b7ffc9a3b", + "s": "0x1778de08e29a4c8dfc3aa3e2c2338e98494ebd2c380c901d0dfba95126dde65f", + "v": "0x2c", + "rawTx": "0xf86c0a850306dc420082520894ffe5bc4e8f1f969934d773fa67da095d2e491a97881bc16d674ec80000802ca094b120a1df80be3dfad057b7ccac866b6b7583b63d61e5b021811c8b7ffc9a3ba01778de08e29a4c8dfc3aa3e2c2338e98494ebd2c380c901d0dfba95126dde65f", + "hash": "0x52604fd8d329894a747d8cf521cbbc4adb35eb9a91e3a3ba3ee32d8729c16536", + "submittedTime": 1589314348235, + "firstRetryBlockNumber": "0x62d5cc", + "txReceipt": { + "blockHash": "0x3d61a8d8a0e79e0e7a3a9206bf62f9a8e47791c527cd85cb4fcf800609234115", + "blockNumber": "62d5cd", + "contractAddress": null, + "cumulativeGasUsed": "a810", + "from": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "gasUsed": "5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0xffe5bc4e8f1f969934d773fa67da095d2e491a97", + "transactionHash": "0x52604fd8d329894a747d8cf521cbbc4adb35eb9a91e3a3ba3ee32d8729c16536", + "transactionIndex": "1" + } + } + ], "primaryTransaction": { "id": 4243712234858506, "time": 1589314345433, @@ -394,6 +581,25 @@ "hash": "0x5ca26d1cdcabef1ac2ad5b2b38604c9ced65d143efc7525f848c46f28e0e4116", "type": "incoming" }, + "transactions": [ + { + "blockNumber": "6477257", + "id": 4243712234858505, + "metamaskNetworkId": "4", + "status": "confirmed", + "time": 1589314295000, + "txParams": { + "from": "0x31b98d14007bdee637298086988a0bbd31184523", + "gas": "0x5208", + "gasPrice": "0x3b9aca00", + "nonce": "0x56540", + "to": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "value": "0x1043561a882930000" + }, + "hash": "0x5ca26d1cdcabef1ac2ad5b2b38604c9ced65d143efc7525f848c46f28e0e4116", + "type": "incoming" + } + ], "primaryTransaction": { "blockNumber": "6477257", "id": 4243712234858505, @@ -432,6 +638,25 @@ "hash": "0xa42b2b433e5bd2616b52e30792aedb6a3c374a752a95d43d99e2a8b143937889", "type": "incoming" }, + "transactions": [ + { + "blockNumber": "6454493", + "id": 4243712234858475, + "metamaskNetworkId": "4", + "status": "confirmed", + "time": 1588972833000, + "txParams": { + "from": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "gas": "0x5208", + "gasPrice": "0x24e160300", + "nonce": "0x8", + "to": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "value": "0x0" + }, + "hash": "0xa42b2b433e5bd2616b52e30792aedb6a3c374a752a95d43d99e2a8b143937889", + "type": "incoming" + } + ], "primaryTransaction": { "blockNumber": "6454493", "id": 4243712234858475, @@ -470,6 +695,25 @@ "hash": "0xbcb195f393f4468945b4045cd41bcdbc2f19ad75ae92a32cf153a3004e42009a", "type": "incoming" }, + "transactions": [ + { + "blockNumber": "6195526", + "id": 4243712234858466, + "metamaskNetworkId": "4", + "status": "confirmed", + "time": 1585087013000, + "txParams": { + "from": "0xee014609ef9e09776ac5fe00bdbfef57bcdefebb", + "gas": "0x5208", + "gasPrice": "0x77359400", + "nonce": "0x3", + "to": "0x9eca64466f257793eaa52fcfff5066894b76a149", + "value": "0xde0b6b3a7640000" + }, + "hash": "0xbcb195f393f4468945b4045cd41bcdbc2f19ad75ae92a32cf153a3004e42009a", + "type": "incoming" + } + ], "primaryTransaction": { "blockNumber": "6195526", "id": 4243712234858466, @@ -510,6 +754,28 @@ "sourceTokenSymbol": "ETH", "type": "swap" }, + "transactions": [ + { + "blockNumber": "6195527", + "id": 4243712234858467, + "metamaskNetworkId": "4", + "status": "confirmed", + "time": 1585088013000, + "txParams": { + "from": "0xee014609ef9e09776ac5fe00bdbfef57bcdefebb", + "gas": "0x5208", + "gasPrice": "0x77359400", + "nonce": "0x3", + "to": "0xabca64466f257793eaa52fcfff5066894b76a149", + "value": "0xde0b6b3a7640000" + }, + "hash": "0xbcb195f393f4468945b4045cd41bcdbc2f19ad75ae92a32cf153a3004e42009a", + "type": "swap", + "destinationTokenSymbol": "ABC", + "destinationTokenAddress": "0xabca64466f257793eaa52fcfff5066894b76a149", + "sourceTokenSymbol": "ETH" + } + ], "primaryTransaction": { "blockNumber": "6195527", "id": 4243712234858467, diff --git a/test/e2e/fixtures/send-edit/state.json b/test/e2e/fixtures/send-edit/state.json index 6c9658c28..3070c06a6 100644 --- a/test/e2e/fixtures/send-edit/state.json +++ b/test/e2e/fixtures/send-edit/state.json @@ -130,6 +130,23 @@ "transactions": { "4046084157914634": { "chainId": "0x539", + "primaryTransaction": { + "chainId": "0x539", + "id": 4046084157914634, + "loadingDefaults": true, + "metamaskNetworkId": "1337", + "origin": "metamask", + "status": "unapproved", + "time": 1617228030067, + "txParams": { + "from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "gas": "0x61a8", + "gasPrice": "0x2540be400", + "to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970", + "value": "0xde0b6b3a7640000" + }, + "type": "sentEther" + }, "history": [ { "chainId": "0x539", diff --git a/ui/components/app/cancel-button/cancel-button.js b/ui/components/app/cancel-button/cancel-button.js new file mode 100644 index 000000000..978af4076 --- /dev/null +++ b/ui/components/app/cancel-button/cancel-button.js @@ -0,0 +1,64 @@ +import { Tooltip } from '@material-ui/core'; +import React from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import classnames from 'classnames'; +import Button from '../../ui/button'; +import { getMaximumGasTotalInHexWei } from '../../../../shared/modules/gas.utils'; +import { getConversionRate } from '../../../ducks/metamask/metamask'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useIncrementedGasFees } from '../../../hooks/useIncrementedGasFees'; +import { isBalanceSufficient } from '../../../pages/send/send.utils'; +import { getSelectedAccount } from '../../../selectors'; + +export default function CancelButton({ + cancelTransaction, + transaction, + detailsModal, +}) { + const t = useI18nContext(); + + const customCancelGasSettings = useIncrementedGasFees(transaction); + + const selectedAccount = useSelector(getSelectedAccount); + const conversionRate = useSelector(getConversionRate); + + const hasEnoughCancelGas = isBalanceSufficient({ + amount: '0x0', + gasTotal: getMaximumGasTotalInHexWei(customCancelGasSettings), + balance: selectedAccount.balance, + conversionRate, + }); + + const btn = ( + + ); + return hasEnoughCancelGas ? ( + btn + ) : ( + +
{btn}
+
+ ); +} + +CancelButton.propTypes = { + transaction: PropTypes.object, + cancelTransaction: PropTypes.func, + detailsModal: PropTypes.bool, +}; diff --git a/ui/components/app/cancel-button/index.js b/ui/components/app/cancel-button/index.js new file mode 100644 index 000000000..ae48b25c8 --- /dev/null +++ b/ui/components/app/cancel-button/index.js @@ -0,0 +1 @@ +export { default } from './cancel-button'; diff --git a/ui/components/app/edit-gas-popover/edit-gas-popover.component.js b/ui/components/app/edit-gas-popover/edit-gas-popover.component.js index bac3e7d77..1aef021eb 100644 --- a/ui/components/app/edit-gas-popover/edit-gas-popover.component.js +++ b/ui/components/app/edit-gas-popover/edit-gas-popover.component.js @@ -29,6 +29,7 @@ import { } from '../../../store/actions'; import LoadingHeartBeat from '../../ui/loading-heartbeat'; import { checkNetworkAndAccountSupports1559 } from '../../../selectors'; +import { useIncrementedGasFees } from '../../../hooks/useIncrementedGasFees'; export default function EditGasPopover({ popoverTitle = '', @@ -64,6 +65,19 @@ export default function EditGasPopover({ ] = useState(false); const minimumGasLimitDec = hexToDecimal(minimumGasLimit); + const updatedCustomGasSettings = useIncrementedGasFees(transaction); + + let updatedTransaction = transaction; + if (mode === EDIT_GAS_MODES.SPEED_UP || mode === EDIT_GAS_MODES.CANCEL) { + updatedTransaction = { + ...transaction, + userFeeLevel: 'custom', + txParams: { + ...transaction.txParams, + ...updatedCustomGasSettings, + }, + }; + } const { maxPriorityFeePerGas, @@ -91,10 +105,15 @@ export default function EditGasPopover({ balanceError, estimatesUnavailableWarning, estimatedBaseFee, - } = useGasFeeInputs(defaultEstimateToUse, transaction, minimumGasLimit, mode); + } = useGasFeeInputs( + defaultEstimateToUse, + updatedTransaction, + minimumGasLimit, + mode, + ); const txParamsHaveBeenCustomized = - estimateToUse === 'custom' || txParamsAreDappSuggested(transaction); + estimateToUse === 'custom' || txParamsAreDappSuggested(updatedTransaction); /** * Temporary placeholder, this should be managed by the parent component but @@ -113,7 +132,7 @@ export default function EditGasPopover({ }, [showSidebar, onClose, dispatch]); const onSubmit = useCallback(() => { - if (!transaction || !mode) { + if (!updatedTransaction || !mode) { closePopover(); } @@ -132,14 +151,14 @@ export default function EditGasPopover({ gasPrice: decGWEIToHexWEI(gasPrice), }; - const cleanTransactionParams = { ...transaction.txParams }; + const cleanTransactionParams = { ...updatedTransaction.txParams }; if (networkAndAccountSupport1559) { delete cleanTransactionParams.gasPrice; } const updatedTxMeta = { - ...transaction, + ...updatedTransaction, userFeeLevel: estimateToUse || 'custom', txParams: { ...cleanTransactionParams, @@ -150,14 +169,14 @@ export default function EditGasPopover({ switch (mode) { case EDIT_GAS_MODES.CANCEL: dispatch( - createCancelTransaction(transaction.id, newGasSettings, { + createCancelTransaction(updatedTransaction.id, newGasSettings, { estimatedBaseFee, }), ); break; case EDIT_GAS_MODES.SPEED_UP: dispatch( - createSpeedUpTransaction(transaction.id, newGasSettings, { + createSpeedUpTransaction(updatedTransaction.id, newGasSettings, { estimatedBaseFee, }), ); @@ -178,7 +197,7 @@ export default function EditGasPopover({ closePopover(); }, [ - transaction, + updatedTransaction, mode, dispatch, closePopover, @@ -263,7 +282,7 @@ export default function EditGasPopover({ estimatedMaximumFiat={estimatedMaximumFiat} onEducationClick={() => setShowEducationContent(true)} mode={mode} - transaction={transaction} + transaction={updatedTransaction} gasErrors={gasErrors} gasWarnings={gasWarnings} onManualChange={onManualChange} diff --git a/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js b/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js index d822e2f76..973b2d0c9 100644 --- a/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js +++ b/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js @@ -9,6 +9,7 @@ import TransactionBreakdown from '../transaction-breakdown'; import Button from '../../ui/button'; import Tooltip from '../../ui/tooltip'; import Copy from '../../ui/icon/copy-icon.component'; +import CancelButton from '../cancel-button'; import Popover from '../../ui/popover'; import { SECOND } from '../../../../shared/constants/time'; import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction'; @@ -31,7 +32,6 @@ export default class TransactionListItemDetails extends PureComponent { showSpeedUp: PropTypes.bool, showRetry: PropTypes.bool, isEarliestNonce: PropTypes.bool, - cancelDisabled: PropTypes.bool, primaryCurrency: PropTypes.string, transactionGroup: PropTypes.object, title: PropTypes.string.isRequired, @@ -115,38 +115,6 @@ export default class TransactionListItemDetails extends PureComponent { } } - renderCancel() { - const { t } = this.context; - const { showCancel, cancelDisabled } = this.props; - - if (!showCancel) { - return null; - } - - return cancelDisabled ? ( - -
- -
-
- ) : ( - - ); - } - render() { const { t } = this.context; const { justCopied } = this.state; @@ -164,6 +132,7 @@ export default class TransactionListItemDetails extends PureComponent { title, onClose, recipientNickname, + showCancel, } = this.props; const { primaryTransaction: transaction, @@ -186,7 +155,13 @@ export default class TransactionListItemDetails extends PureComponent { {t('speedUp')} )} - {this.renderCancel()} + {showCancel && ( + + )} { + event.stopPropagation(); + setShowRetryEditGasPopover(true); + speedUpMetricsEvent(); + }, + [speedUpMetricsEvent], + ); + + const cancelTransaction = useCallback( + (event) => { + event.stopPropagation(); + setShowCancelEditGasPopover(true); + cancelMetricsEvent(); + }, + [cancelMetricsEvent], + ); + const shouldShowSpeedUp = useShouldShowSpeedUp( transactionGroup, isEarliestNonce, @@ -90,37 +116,6 @@ export default function TransactionListItem({ setShowDetails((prev) => !prev); }, [isUnapproved, history, id]); - const cancelButton = useMemo(() => { - const btn = ( - - ); - if (hasCancelled || !isPending || isUnapproved) { - return null; - } - - return hasEnoughCancelGas ? ( - btn - ) : ( - -
{btn}
-
- ); - }, [ - isPending, - t, - isUnapproved, - hasEnoughCancelGas, - cancelTransaction, - hasCancelled, - ]); - const speedUpButton = useMemo(() => { if (!shouldShowSpeedUp || !isPending || isUnapproved) { return null; @@ -140,11 +135,13 @@ export default function TransactionListItem({ isUnapproved, t, isPending, - retryTransaction, hasCancelled, + retryTransaction, cancelTransaction, ]); + const showCancelButton = !hasCancelled && isPending && !isUnapproved; + return ( <>
{speedUpButton} - {cancelButton} + {showCancelButton && ( + + )}
{showDetails && ( @@ -211,35 +213,20 @@ export default function TransactionListItem({ isEarliestNonce={isEarliestNonce} onCancel={cancelTransaction} showCancel={isPending && !hasCancelled} - cancelDisabled={!hasEnoughCancelGas} /> )} {showRetryEditGasPopover && ( setShowRetryEditGasPopover(false)} mode={EDIT_GAS_MODES.SPEED_UP} - transaction={{ - ...transactionGroup.primaryTransaction, - userFeeLevel: 'custom', - txParams: { - ...transactionGroup.primaryTransaction?.txParams, - ...customRetryGasSettings, - }, - }} + transaction={transactionGroup.primaryTransaction} /> )} {showCancelEditGasPopover && ( setShowCancelEditGasPopover(false)} mode={EDIT_GAS_MODES.CANCEL} - transaction={{ - ...transactionGroup.primaryTransaction, - userFeeLevel: 'custom', - txParams: { - ...transactionGroup.primaryTransaction?.txParams, - ...customCancelGasSettings, - }, - }} + transaction={transactionGroup.primaryTransaction} /> )} diff --git a/ui/components/app/transaction-list-item/transaction-list-item.component.test.js b/ui/components/app/transaction-list-item/transaction-list-item.component.test.js new file mode 100644 index 000000000..0d7da539e --- /dev/null +++ b/ui/components/app/transaction-list-item/transaction-list-item.component.test.js @@ -0,0 +1,139 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { fireEvent } from '@testing-library/react'; +import transactionGroup from '../../../../test/data/mock-pending-transaction-data.json'; +import { + getConversionRate, + getSelectedAccount, + getTokenExchangeRates, + getPreferences, + getShouldShowFiat, +} from '../../../selectors'; +import { + renderWithProvider, + setBackgroundConnection, +} from '../../../../test/jest'; + +import { useGasFeeEstimates } from '../../../hooks/useGasFeeEstimates'; +import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas'; +import TransactionListItem from './transaction-list-item.component'; + +const FEE_MARKET_ESTIMATE_RETURN_VALUE = { + gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET, + gasFeeEstimates: { + low: { + minWaitTimeEstimate: 180000, + maxWaitTimeEstimate: 300000, + suggestedMaxPriorityFeePerGas: '3', + suggestedMaxFeePerGas: '53', + }, + medium: { + minWaitTimeEstimate: 15000, + maxWaitTimeEstimate: 60000, + suggestedMaxPriorityFeePerGas: '7', + suggestedMaxFeePerGas: '70', + }, + high: { + minWaitTimeEstimate: 0, + maxWaitTimeEstimate: 15000, + suggestedMaxPriorityFeePerGas: '10', + suggestedMaxFeePerGas: '100', + }, + estimatedBaseFee: '50', + }, + estimatedGasFeeTimeBounds: {}, +}; + +jest.mock('react-redux', () => { + const actual = jest.requireActual('react-redux'); + + return { + ...actual, + useSelector: jest.fn(), + useDispatch: jest.fn(), + }; +}); + +jest.mock('../../../hooks/useGasFeeEstimates', () => ({ + useGasFeeEstimates: jest.fn(), +})); + +setBackgroundConnection({ + getGasFeeTimeEstimate: jest.fn(), + getGasFeeEstimatesAndStartPolling: jest.fn(), +}); + +const generateUseSelectorRouter = (opts) => (selector) => { + if (selector === getConversionRate) { + return 1; + } else if (selector === getSelectedAccount) { + return { + balance: opts.balance ?? '2AA1EFB94E0000', + }; + } else if (selector === getTokenExchangeRates) { + return opts.tokenExchangeRates ?? {}; + } else if (selector === getPreferences) { + return ( + opts.preferences ?? { + useNativeCurrencyAsPrimaryCurrency: true, + } + ); + } else if (selector === getShouldShowFiat) { + return opts.shouldShowFiat ?? false; + } + return undefined; +}; + +describe('TransactionListItem', () => { + describe('when account has insufficient balance to cover gas', function () { + beforeAll(function () { + useGasFeeEstimates.mockImplementation( + () => FEE_MARKET_ESTIMATE_RETURN_VALUE, + ); + }); + + afterAll(function () { + useGasFeeEstimates.restore(); + }); + + it(`should indicate account has insufficient funds to cover gas price for cancellation of pending transaction`, function () { + useSelector.mockImplementation( + generateUseSelectorRouter({ + balance: '0x3', + }), + ); + const { queryByTestId } = renderWithProvider( + , + ); + expect(queryByTestId('not-enough-gas__tooltip')).toBeInTheDocument(); + }); + + it('should not disable "cancel" button when user has sufficient funds', function () { + useSelector.mockImplementation( + generateUseSelectorRouter({ + balance: '2AA1EFB94E0000', + }), + ); + const { queryByTestId } = renderWithProvider( + , + ); + expect(queryByTestId('not-enough-gas__tooltip')).not.toBeInTheDocument(); + }); + + it(`should open the edit gas popover when cancel is clicked`, function () { + useSelector.mockImplementation( + generateUseSelectorRouter({ + balance: '2AA1EFB94E0000', + }), + ); + const { getByText, queryByText } = renderWithProvider( + , + ); + expect(queryByText('Cancel transaction')).not.toBeInTheDocument(); + + const cancelButton = getByText('Cancel'); + fireEvent.click(cancelButton); + expect(getByText('Cancel transaction')).toBeInTheDocument(); + }); + }); +}); diff --git a/ui/hooks/useCancelTransaction.js b/ui/hooks/useCancelTransaction.js deleted file mode 100644 index b62cff96a..000000000 --- a/ui/hooks/useCancelTransaction.js +++ /dev/null @@ -1,55 +0,0 @@ -import { useSelector } from 'react-redux'; -import { useCallback, useState } from 'react'; -import { isBalanceSufficient } from '../pages/send/send.utils'; -import { getSelectedAccount } from '../selectors'; -import { getConversionRate } from '../ducks/metamask/metamask'; - -import { getMaximumGasTotalInHexWei } from '../../shared/modules/gas.utils'; -import { useIncrementedGasFees } from './useIncrementedGasFees'; - -/** - * Determine whether a transaction can be cancelled and provide a method to - * kick off the process of cancellation. - * - * Provides a reusable hook that, given a transactionGroup, will return - * whether or not the account has enough funds to cover the gas cancellation - * fee, and a method for beginning the cancellation process - * @param {Object} transactionGroup - * @return {[boolean, Function]} - */ -export function useCancelTransaction(transactionGroup) { - const { primaryTransaction } = transactionGroup; - - const customCancelGasSettings = useIncrementedGasFees(transactionGroup); - - const selectedAccount = useSelector(getSelectedAccount); - const conversionRate = useSelector(getConversionRate); - - const [showCancelEditGasPopover, setShowCancelEditGasPopover] = useState( - false, - ); - - const closeCancelEditGasPopover = () => setShowCancelEditGasPopover(false); - - const cancelTransaction = useCallback((event) => { - event.stopPropagation(); - return setShowCancelEditGasPopover(true); - }, []); - - const hasEnoughCancelGas = - primaryTransaction.txParams && - isBalanceSufficient({ - amount: '0x0', - gasTotal: getMaximumGasTotalInHexWei(customCancelGasSettings), - balance: selectedAccount.balance, - conversionRate, - }); - - return { - hasEnoughCancelGas, - customCancelGasSettings, - cancelTransaction, - showCancelEditGasPopover, - closeCancelEditGasPopover, - }; -} diff --git a/ui/hooks/useCancelTransaction.test.js b/ui/hooks/useCancelTransaction.test.js deleted file mode 100644 index 7108b4513..000000000 --- a/ui/hooks/useCancelTransaction.test.js +++ /dev/null @@ -1,114 +0,0 @@ -import * as reactRedux from 'react-redux'; -import { renderHook } from '@testing-library/react-hooks'; -import sinon from 'sinon'; -import transactions from '../../test/data/transaction-data.json'; -import { getConversionRate, getSelectedAccount } from '../selectors'; -import { increaseLastGasPrice } from '../helpers/utils/confirm-tx.util'; -import { useCancelTransaction } from './useCancelTransaction'; - -jest.mock('../store/actions', () => ({ - disconnectGasFeeEstimatePoller: jest.fn(), - getGasFeeEstimatesAndStartPolling: jest - .fn() - .mockImplementation(() => Promise.resolve()), - addPollingTokenToAppState: jest.fn(), -})); - -describe('useCancelTransaction', function () { - let useSelector; - const dispatch = sinon.spy(); - - beforeAll(function () { - sinon.stub(reactRedux, 'useDispatch').returns(dispatch); - }); - - afterEach(function () { - dispatch.resetHistory(); - }); - - afterAll(function () { - sinon.restore(); - }); - - describe('when account has insufficient balance to cover gas', function () { - beforeAll(function () { - useSelector = sinon.stub(reactRedux, 'useSelector'); - useSelector.callsFake((selector) => { - if (selector === getConversionRate) { - return 280.46; - } else if (selector === getSelectedAccount) { - return { - balance: '0x3', - }; - } - return undefined; - }); - }); - afterAll(function () { - useSelector.restore(); - }); - transactions.forEach((transactionGroup) => { - const originalGasPrice = - transactionGroup.primaryTransaction.txParams?.gasPrice; - const gasPrice = - originalGasPrice && increaseLastGasPrice(originalGasPrice); - const transactionId = transactionGroup.initialTransaction.id; - it(`should indicate account has insufficient funds to cover ${gasPrice} gas price`, function () { - const { result } = renderHook(() => - useCancelTransaction(transactionGroup), - ); - expect(result.current.hasEnoughCancelGas).toStrictEqual(false); - }); - it(`should return a function that opens the gas sidebar onsubmit kicks off cancellation for id ${transactionId}`, function () { - const { result } = renderHook(() => - useCancelTransaction(transactionGroup), - ); - expect(typeof result.current.cancelTransaction).toStrictEqual( - 'function', - ); - }); - }); - }); - - describe('when account has sufficient balance to cover gas', function () { - beforeAll(function () { - useSelector = sinon.stub(reactRedux, 'useSelector'); - useSelector.callsFake((selector) => { - if (selector === getConversionRate) { - return 280.46; - } else if (selector === getSelectedAccount) { - return { - balance: '0x9C2007651B2500000', - }; - } - return undefined; - }); - }); - - afterAll(function () { - useSelector.restore(); - }); - - transactions.forEach((transactionGroup) => { - const originalGasPrice = - transactionGroup.primaryTransaction.txParams?.gasPrice; - const gasPrice = - originalGasPrice && increaseLastGasPrice(originalGasPrice); - const transactionId = transactionGroup.initialTransaction.id; - it(`should indicate account has funds to cover ${gasPrice} gas price`, function () { - const { result } = renderHook(() => - useCancelTransaction(transactionGroup), - ); - expect(result.current.hasEnoughCancelGas).toStrictEqual(true); - }); - it(`should return a function that opens the gas popover onsubmit kicks off cancellation for id ${transactionId}`, function () { - const { result } = renderHook(() => - useCancelTransaction(transactionGroup), - ); - expect(typeof result.current.cancelTransaction).toStrictEqual( - 'function', - ); - }); - }); - }); -}); diff --git a/ui/hooks/useIncrementedGasFees.js b/ui/hooks/useIncrementedGasFees.js index b00043e35..6466d63e5 100644 --- a/ui/hooks/useIncrementedGasFees.js +++ b/ui/hooks/useIncrementedGasFees.js @@ -50,14 +50,12 @@ function getHighestIncrementedFee(originalFee, currentEstimate) { * discarded by the network to avoid DoS attacks. This hook returns an object * that either has gasPrice or maxFeePerGas/maxPriorityFeePerGas specified. In * addition the gasLimit will also be included. - * @param {} transactionGroup + * @param {} transaction * @returns {import( * '../../app/scripts/controllers/transactions' * ).CustomGasSettings} - Gas settings for cancellations/speed ups */ -export function useIncrementedGasFees(transactionGroup) { - const { primaryTransaction } = transactionGroup; - +export function useIncrementedGasFees(transaction) { const { gasFeeEstimates = {} } = useGasFeeEstimates(); // We memoize this value so that it can be relied upon in other hooks. @@ -68,8 +66,8 @@ export function useIncrementedGasFees(transactionGroup) { // do not have txParams. This is why we use optional chaining on the // txParams object in this hook. const temporaryGasSettings = { - gasLimit: primaryTransaction.txParams?.gas, - gas: primaryTransaction.txParams?.gas, + gasLimit: transaction.txParams?.gas, + gas: transaction.txParams?.gas, }; const suggestedMaxFeePerGas = @@ -77,10 +75,10 @@ export function useIncrementedGasFees(transactionGroup) { const suggestedMaxPriorityFeePerGas = gasFeeEstimates?.medium?.suggestedMaxPriorityFeePerGas ?? '0'; - if (isEIP1559Transaction(primaryTransaction)) { - const transactionMaxFeePerGas = primaryTransaction.txParams?.maxFeePerGas; + if (isEIP1559Transaction(transaction)) { + const transactionMaxFeePerGas = transaction.txParams?.maxFeePerGas; const transactionMaxPriorityFeePerGas = - primaryTransaction.txParams?.maxPriorityFeePerGas; + transaction.txParams?.maxPriorityFeePerGas; temporaryGasSettings.maxFeePerGas = transactionMaxFeePerGas === undefined || @@ -99,7 +97,7 @@ export function useIncrementedGasFees(transactionGroup) { suggestedMaxPriorityFeePerGas, ); } else { - const transactionGasPrice = primaryTransaction.txParams?.gasPrice; + const transactionGasPrice = transaction.txParams?.gasPrice; temporaryGasSettings.gasPrice = transactionGasPrice === undefined || transactionGasPrice.startsWith('-') ? '0x0' @@ -109,7 +107,7 @@ export function useIncrementedGasFees(transactionGroup) { ); } return temporaryGasSettings; - }, [primaryTransaction, gasFeeEstimates]); + }, [transaction, gasFeeEstimates]); return customGasSettings; } diff --git a/ui/hooks/useRetryTransaction.js b/ui/hooks/useRetryTransaction.js deleted file mode 100644 index e580a9da8..000000000 --- a/ui/hooks/useRetryTransaction.js +++ /dev/null @@ -1,48 +0,0 @@ -import { useCallback, useState } from 'react'; -import { useMetricEvent } from './useMetricEvent'; -import { useIncrementedGasFees } from './useIncrementedGasFees'; - -/** - * @typedef {Object} RetryTransactionReturnValue - * @property {(event: Event) => void} retryTransaction - open edit gas popover - * to begin setting retry gas fees - * @property {boolean} showRetryEditGasPopover - Whether to show the popover - * @property {() => void} closeRetryEditGasPopover - close the popover. - */ - -/** - * Provides a reusable hook that, given a transactionGroup, will return - * a method for beginning the retry process - * @param {Object} transactionGroup - the transaction group - * @return {RetryTransactionReturnValue} - */ - -export function useRetryTransaction(transactionGroup) { - const customRetryGasSettings = useIncrementedGasFees(transactionGroup); - const trackMetricsEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Activity Log', - name: 'Clicked "Speed Up"', - }, - }); - const [showRetryEditGasPopover, setShowRetryEditGasPopover] = useState(false); - - const closeRetryEditGasPopover = () => setShowRetryEditGasPopover(false); - - const retryTransaction = useCallback( - async (event) => { - event.stopPropagation(); - setShowRetryEditGasPopover(true); - trackMetricsEvent(); - }, - [trackMetricsEvent], - ); - - return { - retryTransaction, - showRetryEditGasPopover, - closeRetryEditGasPopover, - customRetryGasSettings, - }; -} diff --git a/ui/hooks/useRetryTransaction.test.js b/ui/hooks/useRetryTransaction.test.js deleted file mode 100644 index f2457ca1d..000000000 --- a/ui/hooks/useRetryTransaction.test.js +++ /dev/null @@ -1,77 +0,0 @@ -import * as reactRedux from 'react-redux'; -import { renderHook, act } from '@testing-library/react-hooks'; -import sinon from 'sinon'; -import transactions from '../../test/data/transaction-data.json'; -import { getIsMainnet } from '../selectors'; -import * as methodDataHook from './useMethodData'; -import * as metricEventHook from './useMetricEvent'; -import { useRetryTransaction } from './useRetryTransaction'; - -jest.mock('./useGasFeeEstimates', () => ({ - useGasFeeEstimates: jest.fn().mockImplementation(() => Promise.resolve({})), -})); - -describe('useRetryTransaction', () => { - describe('when transaction meets retry enabled criteria', () => { - let useSelector; - const dispatch = sinon.spy(() => Promise.resolve({ blockTime: 0 })); - const trackEvent = sinon.spy(); - const event = { - preventDefault: () => undefined, - stopPropagation: () => undefined, - }; - beforeAll(() => { - sinon.stub(reactRedux, 'useDispatch').returns(dispatch); - sinon.stub(methodDataHook, 'useMethodData').returns({}); - sinon.stub(metricEventHook, 'useMetricEvent').returns(trackEvent); - useSelector = sinon.stub(reactRedux, 'useSelector'); - useSelector.callsFake((selector) => { - if (selector === getIsMainnet) { - return true; - } - return undefined; - }); - }); - - afterEach(() => { - dispatch.resetHistory(); - trackEvent.resetHistory(); - }); - - afterAll(() => { - sinon.restore(); - }); - - const retryEnabledTransaction = { - ...transactions[0], - transactions: [ - { - submittedTime: new Date() - 5001, - }, - ], - hasRetried: false, - }; - - it('retryTransaction function should track metrics', () => { - const { result } = renderHook(() => - useRetryTransaction(retryEnabledTransaction, true), - ); - const { retryTransaction } = result.current; - act(() => { - retryTransaction(event); - }); - expect(trackEvent.calledOnce).toStrictEqual(true); - }); - - it('retryTransaction function should show retry popover', async () => { - const { result } = renderHook(() => - useRetryTransaction(retryEnabledTransaction, true), - ); - const { retryTransaction } = result.current; - await act(async () => { - await retryTransaction(event); - }); - expect(result.current.showRetryEditGasPopover).toStrictEqual(true); - }); - }); -}); From c5c5d266db64dd9d74fb455d7c8f062a14ad6d92 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 Sep 2021 16:33:05 -0500 Subject: [PATCH 02/12] Lockfile cleanup --- yarn.lock | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index 80cf68a8f..7bc14072b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3050,15 +3050,21 @@ resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.28.0.tgz#76796f5010aa4aa6d28bf6fe36392017cea687cb" integrity sha512-QZj6Y1nmSs9BHufBS1GSuPX5TVFa5gbtMhEo/KRuSdKyY43OdlbBKuyT36/l5p30krlzfMX8bN0MAWqw3g0Bog== -"@metamask/controllers@^14.0.2": - version "14.0.2" - resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-14.0.2.tgz#5b7cc044e6c5442e9728a6923ab7d29c7a07b2f3" - integrity sha512-abR1GTDxyOI2+2+jl8xv0WweFzHTmiuvvfe1y7qFtVKHpswO4p+xUjT7UmyDFe4nxsjqf6npct7ZDeS/EjEudg== +"@metamask/contract-metadata@^1.29.0": + version "1.29.0" + resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.29.0.tgz#4ca86a2f03d4dad4350d09216a7fe92f9dd21c8e" + integrity sha512-wxsC0ZCyhPKqThvmsL8+2zVWGWPqofSo8HNtOuOnQM9oGbXX9294imJ3T+A/Lov8fkX4jAWZOeNV0uR80zkNtA== + +"@metamask/controllers@^16.0.0": + version "16.0.0" + resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-16.0.0.tgz#2c13550a5c7d47a0061a3f3de25e6becdc8531ad" + integrity sha512-zqByf/KXlSK+WdCh5AvFIbmiqpdMGfXxZAVHruKRqxsW9QFOXaIHpshiBZlSH+QLCJuli0sjyheRMFufeTuqkQ== dependencies: "@ethereumjs/common" "^2.3.1" "@ethereumjs/tx" "^3.2.1" - "@metamask/contract-metadata" "^1.28.0" + "@metamask/contract-metadata" "^1.29.0" "@types/uuid" "^8.3.0" + abort-controller "^3.0.0" async-mutex "^0.2.6" babel-runtime "^6.26.0" eth-ens-namehash "^2.0.8" @@ -3076,7 +3082,7 @@ ethjs-util "^0.1.6" human-standard-collectible-abi "^1.0.2" human-standard-token-abi "^2.0.0" - immer "^8.0.1" + immer "^9.0.6" isomorphic-fetch "^3.0.0" jsonschema "^1.2.4" nanoid "^3.1.12" @@ -8271,7 +8277,7 @@ chokidar@^2.0.0, chokidar@^2.1.1, chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1: +chownr@^1.1.1, chownr@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -13196,7 +13202,7 @@ fs-extra@^9.0.0: jsonfile "^6.0.1" universalify "^1.0.0" -fs-minipass@^1.2.5: +fs-minipass@^1.2.5, fs-minipass@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== @@ -14788,6 +14794,11 @@ immer@^8.0.0, immer@^8.0.1: resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== +immer@^9.0.6: + version "9.0.6" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.6.tgz#7a96bf2674d06c8143e327cbf73539388ddf1a73" + integrity sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ== + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -19337,7 +19348,7 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" -minizlib@^1.2.1: +minizlib@^1.2.1, minizlib@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== @@ -24461,7 +24472,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@~5.1.2: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -26322,7 +26333,20 @@ tar@6.0.2: mkdirp "^1.0.3" yallist "^4.0.0" -tar@^4, tar@^4.0.2: +tar@^4: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + +tar@^4.0.2: version "4.4.15" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.15.tgz#3caced4f39ebd46ddda4d6203d48493a919697f8" integrity sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA== @@ -28763,7 +28787,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3, yallist@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== From 049c863f83402ffdae605245ef510a66cab65594 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Tue, 31 Aug 2021 12:27:13 -0700 Subject: [PATCH 03/12] @metamask/controllers@15.0.0 (#11975) Adds the latest version of `@metamask/controllers`, and updates our usage of the `ApprovalController`, which has been migrated to `BaseControllerV2`. Of [the new `controllers` release](https://github.com/MetaMask/controllers/releases/tag/v15.0.0), only the `ApprovalController` migration should be breaking. This is the first time we use events on the `ControllerMessenger` to update the badge, so I turned the messenger into a property on the main `MetaMaskController` in order to subscribe to events on it in `background.js`. I confirmed that the badge does indeed update during local QA. As it turns out, [MetaMask/controllers#571](https://github.com/MetaMask/controllers/pull/571) was breaking for a single unit test case, which is now handled during setup and teardown for the related test suite (`metamask-controller.test.js`). --- app/scripts/background.js | 6 +++++- app/scripts/controllers/permissions/index.js | 2 +- app/scripts/metamask-controller.js | 19 ++++++++++++------- app/scripts/metamask-controller.test.js | 2 ++ test/mocks/permission-controller.js | 3 ++- yarn.lock | 12 +----------- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/app/scripts/background.js b/app/scripts/background.js index 56044213c..a8ff096f6 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -435,12 +435,16 @@ function setupController(initState, initLangCode) { METAMASK_CONTROLLER_EVENTS.UPDATE_BADGE, updateBadge, ); - controller.approvalController.subscribe(updateBadge); controller.appStateController.on( METAMASK_CONTROLLER_EVENTS.UPDATE_BADGE, updateBadge, ); + controller.controllerMessenger.subscribe( + METAMASK_CONTROLLER_EVENTS.APPROVAL_STATE_CHANGE, + updateBadge, + ); + /** * Updates the Web Extension's "badge" number, on the little fox in the toolbar. * The number reflects the current number of pending transactions or message signatures needing user approval. diff --git a/app/scripts/controllers/permissions/index.js b/app/scripts/controllers/permissions/index.js index 281c4e8a3..061782c23 100644 --- a/app/scripts/controllers/permissions/index.js +++ b/app/scripts/controllers/permissions/index.js @@ -249,7 +249,7 @@ export class PermissionsController { approved.permissions, accounts, ); - this.approvals.resolve(id, approved.permissions); + this.approvals.accept(id, approved.permissions); } } catch (err) { // if finalization fails, reject the request diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 115110620..804a73542 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -76,6 +76,8 @@ export const METAMASK_CONTROLLER_EVENTS = { // Fired after state changes that impact the extension badge (unapproved msg count) // The process of updating the badge happens in app/scripts/background.js. UPDATE_BADGE: 'updateBadge', + // TODO: Add this and similar enums to @metamask/controllers and export them + APPROVAL_STATE_CHANGE: 'ApprovalController:stateChange', }; export default class MetamaskController extends EventEmitter { @@ -106,12 +108,12 @@ export default class MetamaskController extends EventEmitter { this.getRequestAccountTabIds = opts.getRequestAccountTabIds; this.getOpenMetamaskTabsIds = opts.getOpenMetamaskTabsIds; - const controllerMessenger = new ControllerMessenger(); + this.controllerMessenger = new ControllerMessenger(); // observable state store this.store = new ComposableObservableStore({ state: initState, - controllerMessenger, + controllerMessenger: this.controllerMessenger, }); // external connections by origin @@ -131,6 +133,9 @@ export default class MetamaskController extends EventEmitter { // controller initialization order matters this.approvalController = new ApprovalController({ + messenger: this.controllerMessenger.getRestricted({ + name: 'ApprovalController', + }), showApprovalRequest: opts.showUserConfirmation, }); @@ -169,7 +174,7 @@ export default class MetamaskController extends EventEmitter { initState: initState.MetaMetricsController, }); - const gasFeeMessenger = controllerMessenger.getRestricted({ + const gasFeeMessenger = this.controllerMessenger.getRestricted({ name: 'GasFeeController', }); @@ -210,7 +215,7 @@ export default class MetamaskController extends EventEmitter { preferencesStore: this.preferencesController.store, }); - const currencyRateMessenger = controllerMessenger.getRestricted({ + const currencyRateMessenger = this.controllerMessenger.getRestricted({ name: 'CurrencyRateController', }); this.currencyRateController = new CurrencyRateController({ @@ -219,7 +224,7 @@ export default class MetamaskController extends EventEmitter { state: initState.CurrencyController, }); - const tokenListMessenger = controllerMessenger.getRestricted({ + const tokenListMessenger = this.controllerMessenger.getRestricted({ name: 'TokenListController', }); this.tokenListController = new TokenListController({ @@ -569,7 +574,7 @@ export default class MetamaskController extends EventEmitter { GasFeeController: this.gasFeeController, TokenListController: this.tokenListController, }, - controllerMessenger, + controllerMessenger: this.controllerMessenger, }); this.memStore.subscribe(this.sendUpdate.bind(this)); @@ -1097,7 +1102,7 @@ export default class MetamaskController extends EventEmitter { // approval controller resolvePendingApproval: nodeify( - approvalController.resolve, + approvalController.accept, approvalController, ), rejectPendingApproval: nodeify( diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index f75bf7b50..ced33df13 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -109,6 +109,7 @@ describe('MetaMaskController', function () { const noop = () => undefined; before(async function () { + globalThis.AbortController = window.AbortController; await ganacheServer.start(); }); @@ -157,6 +158,7 @@ describe('MetaMaskController', function () { after(async function () { await ganacheServer.quit(); + delete globalThis.AbortController; }); describe('#getAccounts', function () { diff --git a/test/mocks/permission-controller.js b/test/mocks/permission-controller.js index 1a2ee0d20..048fcde01 100644 --- a/test/mocks/permission-controller.js +++ b/test/mocks/permission-controller.js @@ -1,7 +1,7 @@ import { ethErrors, errorCodes } from 'eth-rpc-errors'; import deepFreeze from 'deep-freeze-strict'; -import { ApprovalController } from '@metamask/controllers'; +import { ApprovalController, ControllerMessenger } from '@metamask/controllers'; import _getRestrictedMethods from '../../app/scripts/controllers/permissions/restrictedMethods'; @@ -70,6 +70,7 @@ const getRestrictedMethods = (permController) => { export function getPermControllerOpts() { return { approvals: new ApprovalController({ + messenger: new ControllerMessenger(), showApprovalRequest: noop, }), getKeyringAccounts: async () => [...keyringAccounts], diff --git a/yarn.lock b/yarn.lock index 7bc14072b..aa181a049 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3040,17 +3040,7 @@ semver "^7.3.5" yargs "^17.0.1" -"@metamask/contract-metadata@^1.19.0": - version "1.25.0" - resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.25.0.tgz#442ace91fb40165310764b68d8096d0017bb0492" - integrity sha512-yhmYB9CQPv0dckNcPoWDcgtrdUp0OgK0uvkRE5QIBv4b3qENI1/03BztvK2ijbTuMlORUpjPq7/1MQDUPoRPVw== - -"@metamask/contract-metadata@^1.28.0": - version "1.28.0" - resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.28.0.tgz#76796f5010aa4aa6d28bf6fe36392017cea687cb" - integrity sha512-QZj6Y1nmSs9BHufBS1GSuPX5TVFa5gbtMhEo/KRuSdKyY43OdlbBKuyT36/l5p30krlzfMX8bN0MAWqw3g0Bog== - -"@metamask/contract-metadata@^1.29.0": +"@metamask/contract-metadata@^1.19.0", "@metamask/contract-metadata@^1.28.0", "@metamask/contract-metadata@^1.29.0": version "1.29.0" resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.29.0.tgz#4ca86a2f03d4dad4350d09216a7fe92f9dd21c8e" integrity sha512-wxsC0ZCyhPKqThvmsL8+2zVWGWPqofSo8HNtOuOnQM9oGbXX9294imJ3T+A/Lov8fkX4jAWZOeNV0uR80zkNtA== From 05c4b9691ec321fd51f8c51fdaf1aea61cbba37a Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Thu, 16 Sep 2021 15:42:09 -0500 Subject: [PATCH 04/12] bump @metamask/controllers to v16.0.0 (#12133) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 71d4aa3f1..0841d59f8 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "@fortawesome/fontawesome-free": "^5.13.0", "@material-ui/core": "^4.11.0", "@metamask/contract-metadata": "^1.28.0", - "@metamask/controllers": "^14.0.2", + "@metamask/controllers": "^16.0.0", "@metamask/eth-ledger-bridge-keyring": "^0.7.0", "@metamask/eth-token-tracker": "^3.0.1", "@metamask/etherscan-link": "^2.1.0", From 6fb6a8e35a33b5337476bd461c301d9939dd5b2b Mon Sep 17 00:00:00 2001 From: ryanml Date: Tue, 7 Sep 2021 14:46:15 -0700 Subject: [PATCH 05/12] Adding usage instructions for Ledger Live users to confirmation screen (#12020) * Adding usage instructions for Ledger Live users to confirmation screen * Using design system components * Hiding first step on Firefox --- app/_locales/en/messages.json | 12 ++++ .../confirm-transaction-base.component.js | 59 ++++++++++++++++++- .../confirm-transaction-base.container.js | 8 +++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 8928ca36e..75c12fc61 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1180,6 +1180,18 @@ "ledgerLiveApp": { "message": "Ledger Live App" }, + "ledgerLiveDialogHeader": { + "message": "Prior to clicking confirm:" + }, + "ledgerLiveDialogStepOne": { + "message": "Enable Use Ledger Live under Settings > Advanced" + }, + "ledgerLiveDialogStepThree": { + "message": "Plug in your Ledger device and select the Ethereum app" + }, + "ledgerLiveDialogStepTwo": { + "message": "Open and unlock Ledger Live App" + }, "ledgerLocked": { "message": "Cannot connect to Ledger device. Please make sure your device is unlocked and Ethereum app is opened." }, diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 84080d842..2bf5e91ea 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -35,8 +35,14 @@ import TransactionDetailItem from '../../components/app/transaction-detail-item/ import InfoTooltip from '../../components/ui/info-tooltip/info-tooltip'; import LoadingHeartBeat from '../../components/ui/loading-heartbeat'; import GasTiming from '../../components/app/gas-timing/gas-timing.component'; +import Dialog from '../../components/ui/dialog'; -import { COLORS } from '../../helpers/constants/design-system'; +import { + COLORS, + FONT_STYLE, + FONT_WEIGHT, + TYPOGRAPHY, +} from '../../helpers/constants/design-system'; import { disconnectGasFeeEstimatePoller, getGasFeeEstimatesAndStartPolling, @@ -117,6 +123,8 @@ export default class ConfirmTransactionBase extends Component { maxPriorityFeePerGas: PropTypes.string, baseFeePerGas: PropTypes.string, gasFeeIsCustom: PropTypes.bool, + isLedgerAccount: PropTypes.bool.isRequired, + isFirefox: PropTypes.bool.isRequired, }; state = { @@ -295,6 +303,9 @@ export default class ConfirmTransactionBase extends Component { primaryTotalTextOverrideMaxAmount, maxFeePerGas, maxPriorityFeePerGas, + isMainnet, + isLedgerAccount, + isFirefox, } = this.props; const { t } = this.context; @@ -393,6 +404,51 @@ export default class ConfirmTransactionBase extends Component { ) : null; + const ledgerInstructionField = isLedgerAccount ? ( +
+
+ +
+ + {t('ledgerLiveDialogHeader')} + + {!isFirefox && ( + + {`- ${t('ledgerLiveDialogStepOne')}`} + + )} + + {`- ${t('ledgerLiveDialogStepTwo')}`} + + + {`- ${t('ledgerLiveDialogStepThree')}`} + +
+
+
+
+ ) : null; + return (
{nonceField} + {ledgerInstructionField}
); } diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js index a5ebc4a73..251edb1ca 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -29,12 +29,16 @@ import { getShouldShowFiat, checkNetworkAndAccountSupports1559, getPreferences, + getAccountType, } from '../../selectors'; import { getMostRecentOverviewPage } from '../../ducks/history/history'; import { transactionMatchesNetwork, txParamsAreDappSuggested, } from '../../../shared/modules/transaction.utils'; +import { KEYRING_TYPES } from '../../../shared/constants/hardware-wallets'; +import { getPlatform } from '../../../app/scripts/lib/util'; +import { PLATFORM_FIREFOX } from '../../../shared/constants/app'; import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils'; import { updateTransactionGasFees, @@ -161,6 +165,8 @@ const mapStateToProps = (state, ownProps) => { const gasFeeIsCustom = fullTxData.userFeeLevel === 'custom' || txParamsAreDappSuggested(fullTxData); + const isLedgerAccount = getAccountType(state) === KEYRING_TYPES.LEDGER; + const isFirefox = getPlatform() === PLATFORM_FIREFOX; return { balance, @@ -208,6 +214,8 @@ const mapStateToProps = (state, ownProps) => { maxPriorityFeePerGas: gasEstimationObject.maxPriorityFeePerGas, baseFeePerGas: gasEstimationObject.baseFeePerGas, gasFeeIsCustom, + isLedgerAccount, + isFirefox, }; }; From 4e08c245528b40a88683b7732bc6865daa633967 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 17 Sep 2021 09:19:20 -0500 Subject: [PATCH 06/12] fixing merge issues --- .../confirm-transaction-base.component.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 2bf5e91ea..0c0b39513 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -36,10 +36,10 @@ import InfoTooltip from '../../components/ui/info-tooltip/info-tooltip'; import LoadingHeartBeat from '../../components/ui/loading-heartbeat'; import GasTiming from '../../components/app/gas-timing/gas-timing.component'; import Dialog from '../../components/ui/dialog'; +import Typography from '../../components/ui/typography/typography'; import { COLORS, - FONT_STYLE, FONT_WEIGHT, TYPOGRAPHY, } from '../../helpers/constants/design-system'; @@ -303,7 +303,6 @@ export default class ConfirmTransactionBase extends Component { primaryTotalTextOverrideMaxAmount, maxFeePerGas, maxPriorityFeePerGas, - isMainnet, isLedgerAccount, isFirefox, } = this.props; From 8310b551fbcbf551411a70aa6f598cc783767380 Mon Sep 17 00:00:00 2001 From: ryanml Date: Thu, 16 Sep 2021 09:52:42 -0700 Subject: [PATCH 07/12] Adding "Enable smart contract data" step to Ledger Instructions (Confirmation Screen) (#12115) --- app/_locales/en/messages.json | 3 + .../confirm-transaction-base.component.js | 58 ++++++++----------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 75c12fc61..09e48d287 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1183,6 +1183,9 @@ "ledgerLiveDialogHeader": { "message": "Prior to clicking confirm:" }, + "ledgerLiveDialogStepFour": { + "message": "Enable smart contract data on your Ledger device" + }, "ledgerLiveDialogStepOne": { "message": "Enable Use Ledger Live under Settings > Advanced" }, diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 0c0b39513..6714f0a9d 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -403,45 +403,37 @@ export default class ConfirmTransactionBase extends Component { ) : null; + const renderLedgerLiveStep = (text, show = true) => { + return ( + show && ( + + {text} + + ) + ); + }; + const ledgerInstructionField = isLedgerAccount ? (
- - {t('ledgerLiveDialogHeader')} - - {!isFirefox && ( - - {`- ${t('ledgerLiveDialogStepOne')}`} - + {renderLedgerLiveStep(t('ledgerLiveDialogHeader'))} + {renderLedgerLiveStep( + `- ${t('ledgerLiveDialogStepOne')}`, + !isFirefox, + )} + {renderLedgerLiveStep(`- ${t('ledgerLiveDialogStepTwo')}`)} + {renderLedgerLiveStep(`- ${t('ledgerLiveDialogStepThree')}`)} + {renderLedgerLiveStep( + `- ${t('ledgerLiveDialogStepFour')}`, + Boolean(txData.txParams?.data), )} - - {`- ${t('ledgerLiveDialogStepTwo')}`} - - - {`- ${t('ledgerLiveDialogStepThree')}`} -
From 3f5dcbf69736a2a7f0bbab80460d307293c3943c Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Thu, 16 Sep 2021 21:05:37 +0000 Subject: [PATCH 08/12] Version v10.1.1 --- CHANGELOG.md | 8 +++++++- package.json | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 165e7c8b3..c8cd1214a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.1.1] +### Uncategorized +- bump @metamask/controllers to v16.0.0 ([#12133](https://github.com/MetaMask/metamask-extension/pull/12133)) +- Fix gas api overcalling ([#12069](https://github.com/MetaMask/metamask-extension/pull/12069)) + ## [10.1.0] ### Added - [#11951](https://github.com/MetaMask/metamask-extension/pull/11951): Adding EIP-1559 support for Ledger hardware @@ -2431,7 +2436,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/v10.1.0...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.1.1...HEAD +[10.1.1]: https://github.com/MetaMask/metamask-extension/compare/v10.1.0...v10.1.1 [10.1.0]: https://github.com/MetaMask/metamask-extension/compare/v10.0.3...v10.1.0 [10.0.3]: https://github.com/MetaMask/metamask-extension/compare/v10.0.2...v10.0.3 [10.0.2]: https://github.com/MetaMask/metamask-extension/compare/v10.0.1...v10.0.2 diff --git a/package.json b/package.json index 0841d59f8..c1fe52856 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.1.0", + "version": "10.1.1", "private": true, "repository": { "type": "git", From d2e9de106b9dde4d859a8102c9a286677407fb6e Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Fri, 17 Sep 2021 14:20:16 -0230 Subject: [PATCH 09/12] Add notification about need for ledger firmware update (#12144) * Add notification about need for ledger firmware update * Update messaging for ledger firmware notice * Code cleanup --- app/_locales/en/messages.json | 12 ++++++++++++ shared/notifications/index.js | 15 +++++++++++++++ ui/selectors/selectors.js | 6 +++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 09e48d287..3f4fe103d 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1516,6 +1516,18 @@ "message": "Ledger Support Update for Chrome Users", "description": "Title for a notification in the 'See What's New' popup. Lets users know about the Ledger support update" }, + "notifications7DescriptionOne": { + "message": "MetaMask v10.1.0 included new support for EIP-1559 transactions when using Ledger devices.", + "description": "Description of a notification in the 'See What's New' popup. Describes changes for ledger and EIP1559 in v10.1.0" + }, + "notifications7DescriptionTwo": { + "message": "To complete transactions on Ethereum Mainnet, make sure your Ledger device has the latest firmware.", + "description": "Description of a notification in the 'See What's New' popup. Describes the need to update ledger firmware." + }, + "notifications7Title": { + "message": "Ledger firmware update", + "description": "Title for a notification in the 'See What's New' popup. Notifies ledger users of the need to update firmware." + }, "ofTextNofM": { "message": "of" }, diff --git a/shared/notifications/index.js b/shared/notifications/index.js index 96f1f4fec..4649fce00 100644 --- a/shared/notifications/index.js +++ b/shared/notifications/index.js @@ -30,6 +30,10 @@ export const UI_NOTIFICATIONS = { id: 6, date: '2021-05-26', }, + 7: { + id: 7, + date: '2021-09-17', + }, }; export const getTranslatedUINoficiations = (t, locale) => { @@ -82,5 +86,16 @@ export const getTranslatedUINoficiations = (t, locale) => { new Date(UI_NOTIFICATIONS[6].date), ), }, + 7: { + ...UI_NOTIFICATIONS[7], + title: t('notifications7Title'), + description: [ + t('notifications7DescriptionOne'), + t('notifications7DescriptionTwo'), + ], + date: new Intl.DateTimeFormat(formattedLocale).format( + new Date(UI_NOTIFICATIONS[7].date), + ), + }, }; }; diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index c0b6fb4e5..a84b18237 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -547,13 +547,17 @@ export function getShowWhatsNewPopup(state) { * @returns {Object} */ function getAllowedNotificationIds(state) { + const currentKeyring = getCurrentKeyring(state); + const currentKeyringIsLedger = currentKeyring?.type === KEYRING_TYPES.LEDGER; + return { 1: true, 2: true, 3: true, 4: getCurrentChainId(state) === BSC_CHAIN_ID, 5: true, - 6: true, + 6: currentKeyringIsLedger, + 7: currentKeyringIsLedger, }; } From f200876b54bb71e0094598d9ec94c9e33eea9ff5 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 17 Sep 2021 15:14:52 -0500 Subject: [PATCH 10/12] [skip e2e] Update changelog for v10.1.1 (#12135) --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8cd1214a..13defa672 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## [10.1.1] -### Uncategorized -- bump @metamask/controllers to v16.0.0 ([#12133](https://github.com/MetaMask/metamask-extension/pull/12133)) -- Fix gas api overcalling ([#12069](https://github.com/MetaMask/metamask-extension/pull/12069)) +### Added +- [#12020](https://github.com/MetaMask/metamask-extension/pull/12020): Adds instructions for ledger live users on transaction confirm screen +- [#12144](https://github.com/MetaMask/metamask-extension/pull/12144): Add What's New notification about ledger EIP-1559 support and firmware updates + +### Fixed +- [#12069](https://github.com/MetaMask/metamask-extension/pull/12069): Fixes bug where suggestedGasFee api is called excessively. ## [10.1.0] ### Added From a58211c0dd779e8e10a227b0ef5a544822482613 Mon Sep 17 00:00:00 2001 From: ryanml Date: Mon, 20 Sep 2021 13:19:35 -0700 Subject: [PATCH 11/12] Fixing ledger steps display (Confirm TX) (#12163) * Fixing ledger steps display (Confirm TX) * Hiding step two on Firefox --- .../confirm-transaction-base.component.js | 11 +++++++---- .../confirm-transaction-base.container.js | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 6714f0a9d..c9a70540e 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -123,7 +123,7 @@ export default class ConfirmTransactionBase extends Component { maxPriorityFeePerGas: PropTypes.string, baseFeePerGas: PropTypes.string, gasFeeIsCustom: PropTypes.bool, - isLedgerAccount: PropTypes.bool.isRequired, + showLedgerSteps: PropTypes.bool.isRequired, isFirefox: PropTypes.bool.isRequired, }; @@ -303,7 +303,7 @@ export default class ConfirmTransactionBase extends Component { primaryTotalTextOverrideMaxAmount, maxFeePerGas, maxPriorityFeePerGas, - isLedgerAccount, + showLedgerSteps, isFirefox, } = this.props; const { t } = this.context; @@ -418,7 +418,7 @@ export default class ConfirmTransactionBase extends Component { ); }; - const ledgerInstructionField = isLedgerAccount ? ( + const ledgerInstructionField = showLedgerSteps ? (
@@ -428,7 +428,10 @@ export default class ConfirmTransactionBase extends Component { `- ${t('ledgerLiveDialogStepOne')}`, !isFirefox, )} - {renderLedgerLiveStep(`- ${t('ledgerLiveDialogStepTwo')}`)} + {renderLedgerLiveStep( + `- ${t('ledgerLiveDialogStepTwo')}`, + !isFirefox, + )} {renderLedgerLiveStep(`- ${t('ledgerLiveDialogStepThree')}`)} {renderLedgerLiveStep( `- ${t('ledgerLiveDialogStepFour')}`, diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js index 251edb1ca..c85406b36 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -29,7 +29,7 @@ import { getShouldShowFiat, checkNetworkAndAccountSupports1559, getPreferences, - getAccountType, + getHardwareWalletType, } from '../../selectors'; import { getMostRecentOverviewPage } from '../../ducks/history/history'; import { @@ -165,7 +165,7 @@ const mapStateToProps = (state, ownProps) => { const gasFeeIsCustom = fullTxData.userFeeLevel === 'custom' || txParamsAreDappSuggested(fullTxData); - const isLedgerAccount = getAccountType(state) === KEYRING_TYPES.LEDGER; + const showLedgerSteps = getHardwareWalletType(state) === KEYRING_TYPES.LEDGER; const isFirefox = getPlatform() === PLATFORM_FIREFOX; return { @@ -214,7 +214,7 @@ const mapStateToProps = (state, ownProps) => { maxPriorityFeePerGas: gasEstimationObject.maxPriorityFeePerGas, baseFeePerGas: gasEstimationObject.baseFeePerGas, gasFeeIsCustom, - isLedgerAccount, + showLedgerSteps, isFirefox, }; }; From 9204e65c7eea09447e9d59a668b3369524782d4c Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Tue, 21 Sep 2021 10:12:51 -0500 Subject: [PATCH 12/12] fix pubnub dep vulnerabiltiy (#12170) --- package.json | 1 + yarn.lock | 262 +++++++++++++++++++++++++-------------------------- 2 files changed, 127 insertions(+), 136 deletions(-) diff --git a/package.json b/package.json index c1fe52856..880543a3e 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "analytics-node/axios": "^0.21.1", "ganache-core/lodash": "^4.17.21", "netmask": "^2.0.1", + "pubnub/superagent-proxy": "^3.0.0", "pull-ws": "^3.3.2", "ws": "^7.4.6" }, diff --git a/yarn.lock b/yarn.lock index aa181a049..5b2e3ac71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4127,6 +4127,11 @@ "@babel/runtime" "^7.10.3" "@testing-library/dom" "^7.17.1" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@trezor/blockchain-link@^1.0.17": version "1.0.17" resolved "https://registry.yarnpkg.com/@trezor/blockchain-link/-/blockchain-link-1.0.17.tgz#3155b44ee9beb71326986d404385ede673519b3c" @@ -5190,13 +5195,6 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== - dependencies: - es6-promisify "^5.0.0" - agent-base@6: version "6.0.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4" @@ -5204,12 +5202,12 @@ agent-base@6: dependencies: debug "4" -agent-base@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" - integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== +agent-base@^6.0.0, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: - es6-promisify "^5.0.0" + debug "4" agentkeepalive@^3.5.2: version "3.5.2" @@ -5887,18 +5885,23 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types@0.x.x, ast-types@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" - integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== - dependencies: - tslib "^2.0.1" +ast-module-types@^2.3.2, ast-module-types@^2.4.0, ast-module-types@^2.7.0, ast-module-types@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/ast-module-types/-/ast-module-types-2.7.1.tgz#3f7989ef8dfa1fdb82dfe0ab02bdfc7c77a57dd3" + integrity sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw== ast-types@^0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== +ast-types@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" + integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== + dependencies: + tslib "^2.0.1" + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -9437,10 +9440,10 @@ data-queue@0.0.3: resolved "https://registry.yarnpkg.com/data-queue/-/data-queue-0.0.3.tgz#47ab5b634d4a3bbf7bb4ab625a4175b8cf9d44b1" integrity sha512-6YOUFa/+lXklPO42RF4zIzzphG01Jp1eoWolzkQb6z5oVsSThLibZ63VmAze3KuIMTglFt551q8j0Zaswx5vGQ== -data-uri-to-buffer@1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" - integrity sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ== +data-uri-to-buffer@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== data-urls@^2.0.0: version "2.0.0" @@ -9544,13 +9547,6 @@ debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, de dependencies: ms "2.0.0" -debug@3.1.0, debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - debug@3.2.6, debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -9572,13 +9568,20 @@ debug@4.1.0: dependencies: ms "^2.1.1" -debug@^4.2.0: +debug@^4.0.0, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -9768,14 +9771,15 @@ defined@^1.0.0, defined@~1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= -degenerator@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" - integrity sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU= +degenerator@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-3.0.1.tgz#7ef78ec0c8577a544477308ddf1d2d6e88d51f5b" + integrity sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ== dependencies: - ast-types "0.x.x" - escodegen "1.x.x" - esprima "3.x.x" + ast-types "^0.13.2" + escodegen "^1.8.1" + esprima "^4.0.0" + vm2 "^3.9.3" del@^2.0.2: version "2.2.2" @@ -10771,7 +10775,7 @@ es6-map@^0.1.3, es6-map@^0.1.5: es6-symbol "~3.1.1" event-emitter "~0.3.5" -es6-promise@^4.0.3, es6-promise@^4.2.8: +es6-promise@^4.2.8: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== @@ -10781,13 +10785,6 @@ es6-promisify@6.0.2: resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-6.0.2.tgz#525c23725b8510f5f1f2feb5a1fbad93a93e29b4" integrity sha512-eO6vFm0JvqGzjWIQA6QVKjxpmELfhWbDUWHm1rPfIbn55mhKPiAa5xpLmQWJrNa629ZIeQ8ZvMAi13kvrjK6Mg== -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= - dependencies: - es6-promise "^4.0.3" - es6-set@^0.1.5, es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" @@ -10847,7 +10844,7 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escodegen@1.x.x, escodegen@^1.11.1, escodegen@^1.9.0: +escodegen@^1.11.1, escodegen@^1.8.1, escodegen@^1.9.0: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== @@ -11218,11 +11215,6 @@ espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" -esprima@3.x.x: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= - esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -12390,7 +12382,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@3, extend@3.0.2, extend@^3.0.0, extend@~3.0.2: +extend@3.0.2, extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -12712,11 +12704,16 @@ file-type@^8.0.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== -file-uri-to-path@1, file-uri-to-path@1.0.0: +file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +file-uri-to-path@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz#7b415aeba227d575851e0a5b0c640d7656403fba" + integrity sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg== + filelist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb" @@ -13271,7 +13268,7 @@ fsm@^1.0.2: dependencies: split "~0.3.0" -ftp@~0.3.10: +ftp@^0.3.10: version "0.3.10" resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0= @@ -13500,17 +13497,17 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-uri@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.2.tgz#5c795e71326f6ca1286f2fc82575cd2bab2af578" - integrity sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw== +get-uri@3: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c" + integrity sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg== dependencies: - data-uri-to-buffer "1" - debug "2" - extend "3" - file-uri-to-path "1" - ftp "~0.3.10" - readable-stream "2" + "@tootallnate/once" "1" + data-uri-to-buffer "3" + debug "4" + file-uri-to-path "2" + fs-extra "^8.1.0" + ftp "^0.3.10" get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" @@ -14584,13 +14581,14 @@ http-parser-js@>=0.4.0: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1" integrity sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE= -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== +http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: - agent-base "4" - debug "3.1.0" + "@tootallnate/once" "1" + agent-base "6" + debug "4" http-signature@~1.2.0: version "1.2.0" @@ -14614,7 +14612,7 @@ https-did-resolver@^0.1.0: did-resolver "0.0.6" xmlhttprequest "^1.8.0" -https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: +https-proxy-agent@5, https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== @@ -14622,14 +14620,6 @@ https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: agent-base "6" debug "4" -https-proxy-agent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.0.tgz#0106efa5d63d6d6f3ab87c999fa4877a3fd1ff97" - integrity sha512-y4jAxNEihqvBI5F3SaO2rtsjIOnnNA8sEbuiP+UhJZJHeM2NRm6c09ax2tgqme+SgUUvjao2fJXF4h3D6Cb2HQ== - dependencies: - agent-base "^4.3.0" - debug "^3.1.0" - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -19903,7 +19893,7 @@ nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== -netmask@^1.0.6, netmask@^2.0.1: +netmask@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.1.tgz#5a5cbdcbb7b6de650870e15e83d3e9553a414cf4" integrity sha512-gB8eG6ubxz67c7O2gaGiyWdRUIbH61q7anjgueDqCC9kvIs/b4CTtCMaQKeJbv1/Y7FT19I4zKwYmjnjInRQsg== @@ -21106,30 +21096,29 @@ p-whilst@^1.0.0: resolved "https://registry.yarnpkg.com/p-whilst/-/p-whilst-1.0.0.tgz#54668ead7f934799fc00f1e5230fd6addeb8e7e6" integrity sha1-VGaOrX+TR5n8APHlIw/Wrd645+Y= -pac-proxy-agent@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz#115b1e58f92576cac2eba718593ca7b0e37de2ad" - integrity sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ== +pac-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz#b718f76475a6a5415c2efbe256c1c971c84f635e" + integrity sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ== dependencies: - agent-base "^4.2.0" - debug "^4.1.1" - get-uri "^2.0.0" - http-proxy-agent "^2.1.0" - https-proxy-agent "^3.0.0" - pac-resolver "^3.0.0" + "@tootallnate/once" "1" + agent-base "6" + debug "4" + get-uri "3" + http-proxy-agent "^4.0.1" + https-proxy-agent "5" + pac-resolver "^5.0.0" raw-body "^2.2.0" - socks-proxy-agent "^4.0.1" + socks-proxy-agent "5" -pac-resolver@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-3.0.0.tgz#6aea30787db0a891704deb7800a722a7615a6f26" - integrity sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA== +pac-resolver@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-5.0.0.tgz#1d717a127b3d7a9407a16d6e1b012b13b9ba8dc0" + integrity sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA== dependencies: - co "^4.6.0" - degenerator "^1.0.4" + degenerator "^3.0.1" ip "^1.1.5" - netmask "^1.0.6" - thunkify "^2.1.2" + netmask "^2.0.1" package-hash@^4.0.0: version "4.0.0" @@ -22380,19 +22369,19 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.0" -proxy-agent@3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-3.1.1.tgz#7e04e06bf36afa624a1540be247b47c970bd3014" - integrity sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw== +proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-5.0.0.tgz#d31405c10d6e8431fde96cba7a0c027ce01d633b" + integrity sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g== dependencies: - agent-base "^4.2.0" + agent-base "^6.0.0" debug "4" - http-proxy-agent "^2.1.0" - https-proxy-agent "^3.0.0" + http-proxy-agent "^4.0.0" + https-proxy-agent "^5.0.0" lru-cache "^5.1.1" - pac-proxy-agent "^3.0.1" + pac-proxy-agent "^5.0.0" proxy-from-env "^1.0.0" - socks-proxy-agent "^4.0.1" + socks-proxy-agent "^5.0.0" proxy-from-env@^1.0.0, proxy-from-env@^1.1.0: version "1.1.0" @@ -23442,7 +23431,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.3, readable-stream@~2.3.5, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.3, readable-stream@~2.3.5, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -25120,16 +25109,16 @@ slide@~1.1.3: resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= -smart-buffer@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d" - integrity sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw== - smart-buffer@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== +smart-buffer@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -25238,21 +25227,22 @@ socketcluster-client@^14.2.1: uuid "3.2.1" ws "7.1.0" -socks-proxy-agent@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" - integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== +socks-proxy-agent@5, socks-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" + integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== dependencies: - agent-base "~4.2.1" - socks "~2.3.2" + agent-base "^6.0.2" + debug "4" + socks "^2.3.3" -socks@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.2.tgz#ade388e9e6d87fdb11649c15746c578922a5883e" - integrity sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ== +socks@^2.3.3: + version "2.6.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" + integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== dependencies: ip "^1.1.5" - smart-buffer "4.0.2" + smart-buffer "^4.1.0" sonic-boom@^0.7.5: version "0.7.5" @@ -26102,13 +26092,13 @@ summary@0.3.x: resolved "https://registry.yarnpkg.com/summary/-/summary-0.3.2.tgz#3d7439b30dab3449dfd66840a822838d4a4a8561" integrity sha1-PXQ5sw2rNEnf1mhAqCKDjUpKhWE= -superagent-proxy@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/superagent-proxy/-/superagent-proxy-2.0.0.tgz#9f57515cd660e2e9ce55c0e6bd70f92eb07c3ee0" - integrity sha512-TktJma5jPdiH1BNN+reF/RMW3b8aBTCV7KlLFV0uYcREgNf3pvo7Rdt564OcFHwkGb3mYEhHuWPBhSbOwiNaYw== +superagent-proxy@^2.0.0, superagent-proxy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/superagent-proxy/-/superagent-proxy-3.0.0.tgz#e1a17ccba25883599e18d2974020fe83ee7d95d1" + integrity sha512-wAlRInOeDFyd9pyonrkJspdRAxdLrcsZ6aSnS+8+nu4x1aXbz6FWSTT9M6Ibze+eG60szlL7JA8wEIV7bPWuyQ== dependencies: - debug "^3.1.0" - proxy-agent "3" + debug "^4.3.2" + proxy-agent "^5.0.0" superagent@^3.8.1: version "3.8.3" @@ -26548,11 +26538,6 @@ through@2, "through@>=2.2.7 <3", through@^2.3.6, through@~2.3, through@~2.3.1, t resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -thunkify@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" - integrity sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0= - thunky@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" @@ -27833,6 +27818,11 @@ vm-browserify@^1.0.0, vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +vm2@^3.9.3: + version "3.9.3" + resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.3.tgz#29917f6cc081cc43a3f580c26c5b553fd3c91f40" + integrity sha512-smLS+18RjXYMl9joyJxMNI9l4w7biW8ilSDaVRvFBDwOH8P0BK1ognFQTpg0wyQ6wIKLTblHJvROW692L/E53Q== + w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"