1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Merge pull request #12134 from MetaMask/Version-v10.1.1

Version v10.1.1 RC
This commit is contained in:
Alex Donesky 2021-09-21 11:13:53 -05:00 committed by GitHub
commit 5121dffa76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1126 additions and 589 deletions

View File

@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [10.1.1]
### 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
- [#11951](https://github.com/MetaMask/metamask-extension/pull/11951): Adding EIP-1559 support for Ledger hardware
@ -2431,7 +2439,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

View File

@ -1180,6 +1180,21 @@
"ledgerLiveApp": {
"message": "Ledger Live App"
},
"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"
},
"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."
},
@ -1501,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"
},

View File

@ -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.

View File

@ -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

View File

@ -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(

View File

@ -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 () {

View File

@ -1,6 +1,6 @@
{
"name": "metamask-crx",
"version": "10.1.0",
"version": "10.1.1",
"private": true,
"repository": {
"type": "git",
@ -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"
},
@ -102,7 +103,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",

View File

@ -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),
),
},
};
};

View File

@ -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"
}
]
}

View File

@ -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,

View File

@ -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",

View File

@ -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],

View File

@ -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 = (
<Button
onClick={cancelTransaction}
rounded={!detailsModal}
type={detailsModal ? 'raise' : null}
className={classnames({
'transaction-list-item__header-button': !detailsModal,
'transaction-list-item-details__header-button': detailsModal,
})}
disabled={!hasEnoughCancelGas}
>
{t('cancel')}
</Button>
);
return hasEnoughCancelGas ? (
btn
) : (
<Tooltip
title={t('notEnoughGas')}
data-testid="not-enough-gas__tooltip"
position="bottom"
>
<div>{btn}</div>
</Tooltip>
);
}
CancelButton.propTypes = {
transaction: PropTypes.object,
cancelTransaction: PropTypes.func,
detailsModal: PropTypes.bool,
};

View File

@ -0,0 +1 @@
export { default } from './cancel-button';

View File

@ -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}

View File

@ -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 ? (
<Tooltip title={t('notEnoughGas')} position="bottom">
<div>
<Button
type="raised"
onClick={this.handleCancel}
className="transaction-list-item-details__header-button"
disabled
>
{t('cancel')}
</Button>
</div>
</Tooltip>
) : (
<Button
type="raised"
onClick={this.handleCancel}
className="transaction-list-item-details__header-button"
>
{t('cancel')}
</Button>
);
}
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')}
</Button>
)}
{this.renderCancel()}
{showCancel && (
<CancelButton
transaction={transaction}
cancelTransaction={this.handleCancel}
detailsModal
/>
)}
<Tooltip
wrapperClassName="transaction-list-item-details__header-button"
containerClassName="transaction-list-item-details__header-button-tooltip-container"

View File

@ -5,10 +5,7 @@ import { useHistory } from 'react-router-dom';
import ListItem from '../../ui/list-item';
import { useTransactionDisplayData } from '../../../hooks/useTransactionDisplayData';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { useCancelTransaction } from '../../../hooks/useCancelTransaction';
import { useRetryTransaction } from '../../../hooks/useRetryTransaction';
import Button from '../../ui/button';
import Tooltip from '../../ui/tooltip';
import TransactionListItemDetails from '../transaction-list-item-details';
import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes';
import { useShouldShowSpeedUp } from '../../../hooks/useShouldShowSpeedUp';
@ -20,6 +17,9 @@ import {
} from '../../../../shared/constants/transaction';
import { EDIT_GAS_MODES } from '../../../../shared/constants/gas';
import EditGasPopover from '../edit-gas-popover';
import { useMetricEvent } from '../../../hooks/useMetricEvent';
import Button from '../../ui/button';
import CancelButton from '../cancel-button';
export default function TransactionListItem({
transactionGroup,
@ -29,24 +29,50 @@ export default function TransactionListItem({
const history = useHistory();
const { hasCancelled } = transactionGroup;
const [showDetails, setShowDetails] = useState(false);
const [showCancelEditGasPopover, setShowCancelEditGasPopover] = useState(
false,
);
const [showRetryEditGasPopover, setShowRetryEditGasPopover] = useState(false);
const {
initialTransaction: { id },
primaryTransaction: { err, status },
} = transactionGroup;
const {
hasEnoughCancelGas,
cancelTransaction,
showCancelEditGasPopover,
closeCancelEditGasPopover,
customCancelGasSettings,
} = useCancelTransaction(transactionGroup);
const {
retryTransaction,
showRetryEditGasPopover,
closeRetryEditGasPopover,
customRetryGasSettings,
} = useRetryTransaction(transactionGroup);
const speedUpMetricsEvent = useMetricEvent({
eventOpts: {
category: 'Navigation',
action: 'Activity Log',
name: 'Clicked "Speed Up"',
},
});
const cancelMetricsEvent = useMetricEvent({
eventOpts: {
category: 'Navigation',
action: 'Activity Log',
name: 'Clicked "Cancel"',
},
});
const retryTransaction = useCallback(
async (event) => {
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 = (
<Button
onClick={cancelTransaction}
rounded
className="transaction-list-item__header-button"
disabled={!hasEnoughCancelGas}
>
{t('cancel')}
</Button>
);
if (hasCancelled || !isPending || isUnapproved) {
return null;
}
return hasEnoughCancelGas ? (
btn
) : (
<Tooltip title={t('notEnoughGas')} position="bottom">
<div>{btn}</div>
</Tooltip>
);
}, [
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 (
<>
<ListItem
@ -194,7 +191,12 @@ export default function TransactionListItem({
>
<div className="transaction-list-item__pending-actions">
{speedUpButton}
{cancelButton}
{showCancelButton && (
<CancelButton
transaction={transactionGroup.primaryTransaction}
cancelTransaction={cancelTransaction}
/>
)}
</div>
</ListItem>
{showDetails && (
@ -211,35 +213,20 @@ export default function TransactionListItem({
isEarliestNonce={isEarliestNonce}
onCancel={cancelTransaction}
showCancel={isPending && !hasCancelled}
cancelDisabled={!hasEnoughCancelGas}
/>
)}
{showRetryEditGasPopover && (
<EditGasPopover
onClose={closeRetryEditGasPopover}
onClose={() => setShowRetryEditGasPopover(false)}
mode={EDIT_GAS_MODES.SPEED_UP}
transaction={{
...transactionGroup.primaryTransaction,
userFeeLevel: 'custom',
txParams: {
...transactionGroup.primaryTransaction?.txParams,
...customRetryGasSettings,
},
}}
transaction={transactionGroup.primaryTransaction}
/>
)}
{showCancelEditGasPopover && (
<EditGasPopover
onClose={closeCancelEditGasPopover}
onClose={() => setShowCancelEditGasPopover(false)}
mode={EDIT_GAS_MODES.CANCEL}
transaction={{
...transactionGroup.primaryTransaction,
userFeeLevel: 'custom',
txParams: {
...transactionGroup.primaryTransaction?.txParams,
...customCancelGasSettings,
},
}}
transaction={transactionGroup.primaryTransaction}
/>
)}
</>

View File

@ -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(
<TransactionListItem transactionGroup={transactionGroup} />,
);
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(
<TransactionListItem transactionGroup={transactionGroup} />,
);
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(
<TransactionListItem transactionGroup={transactionGroup} />,
);
expect(queryByText('Cancel transaction')).not.toBeInTheDocument();
const cancelButton = getByText('Cancel');
fireEvent.click(cancelButton);
expect(getByText('Cancel transaction')).toBeInTheDocument();
});
});
});

View File

@ -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,
};
}

View File

@ -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',
);
});
});
});
});

View File

@ -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;
}

View File

@ -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,
};
}

View File

@ -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);
});
});
});

View File

@ -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 Typography from '../../components/ui/typography/typography';
import { COLORS } from '../../helpers/constants/design-system';
import {
COLORS,
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,
showLedgerSteps: PropTypes.bool.isRequired,
isFirefox: PropTypes.bool.isRequired,
};
state = {
@ -295,6 +303,8 @@ export default class ConfirmTransactionBase extends Component {
primaryTotalTextOverrideMaxAmount,
maxFeePerGas,
maxPriorityFeePerGas,
showLedgerSteps,
isFirefox,
} = this.props;
const { t } = this.context;
@ -393,6 +403,46 @@ export default class ConfirmTransactionBase extends Component {
</div>
) : null;
const renderLedgerLiveStep = (text, show = true) => {
return (
show && (
<Typography
boxProps={{ margin: 0 }}
color={COLORS.PRIMARY3}
fontWeight={FONT_WEIGHT.BOLD}
variant={TYPOGRAPHY.H7}
>
{text}
</Typography>
)
);
};
const ledgerInstructionField = showLedgerSteps ? (
<div>
<div className="confirm-detail-row">
<Dialog type="message">
<div className="ledger-live-dialog">
{renderLedgerLiveStep(t('ledgerLiveDialogHeader'))}
{renderLedgerLiveStep(
`- ${t('ledgerLiveDialogStepOne')}`,
!isFirefox,
)}
{renderLedgerLiveStep(
`- ${t('ledgerLiveDialogStepTwo')}`,
!isFirefox,
)}
{renderLedgerLiveStep(`- ${t('ledgerLiveDialogStepThree')}`)}
{renderLedgerLiveStep(
`- ${t('ledgerLiveDialogStepFour')}`,
Boolean(txData.txParams?.data),
)}
</div>
</Dialog>
</div>
</div>
) : null;
return (
<div className="confirm-page-container-content__details">
<TransactionDetail
@ -507,6 +557,7 @@ export default class ConfirmTransactionBase extends Component {
]}
/>
{nonceField}
{ledgerInstructionField}
</div>
);
}

View File

@ -29,12 +29,16 @@ import {
getShouldShowFiat,
checkNetworkAndAccountSupports1559,
getPreferences,
getHardwareWalletType,
} 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 showLedgerSteps = getHardwareWalletType(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,
showLedgerSteps,
isFirefox,
};
};

View File

@ -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,
};
}

318
yarn.lock
View File

@ -3040,25 +3040,21 @@
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.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==
"@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/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/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 +3072,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"
@ -4131,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"
@ -5194,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"
@ -5208,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"
@ -5891,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"
@ -8271,7 +8270,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==
@ -9441,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"
@ -9548,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"
@ -9576,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"
@ -9772,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"
@ -10775,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==
@ -10785,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"
@ -10851,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==
@ -11222,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"
@ -12394,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==
@ -12716,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"
@ -13196,7 +13189,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==
@ -13275,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=
@ -13504,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"
@ -14588,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"
@ -14618,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==
@ -14626,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"
@ -14788,6 +14774,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 +19328,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==
@ -19902,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==
@ -21105,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"
@ -22379,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"
@ -23441,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==
@ -24461,7 +24451,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==
@ -25119,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"
@ -25237,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"
@ -26101,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"
@ -26322,7 +26313,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==
@ -26534,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"
@ -27819,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"
@ -28763,7 +28767,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==