mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Toggle option to enable/disable balance and Token rate checking for using third-party API (#16772)
This commit is contained in:
parent
554939cc66
commit
a0bb4a6c5a
@ -1225,6 +1225,7 @@ const state = {
|
|||||||
useNonceField: false,
|
useNonceField: false,
|
||||||
usePhishDetect: true,
|
usePhishDetect: true,
|
||||||
useTokenDetection: true,
|
useTokenDetection: true,
|
||||||
|
useCurrencyRateCheck: true,
|
||||||
lostIdentities: {},
|
lostIdentities: {},
|
||||||
forgottenPassword: false,
|
forgottenPassword: false,
|
||||||
ipfsGateway: 'dweb.link',
|
ipfsGateway: 'dweb.link',
|
||||||
|
13
app/_locales/en/messages.json
generated
13
app/_locales/en/messages.json
generated
@ -682,6 +682,9 @@
|
|||||||
"close": {
|
"close": {
|
||||||
"message": "Close"
|
"message": "Close"
|
||||||
},
|
},
|
||||||
|
"coingecko": {
|
||||||
|
"message": "CoinGecko"
|
||||||
|
},
|
||||||
"collectibleAddFailedMessage": {
|
"collectibleAddFailedMessage": {
|
||||||
"message": "NFT can’t be added as the ownership details do not match. Make sure you have entered correct information."
|
"message": "NFT can’t be added as the ownership details do not match. Make sure you have entered correct information."
|
||||||
},
|
},
|
||||||
@ -894,9 +897,19 @@
|
|||||||
"createPassword": {
|
"createPassword": {
|
||||||
"message": "Create password"
|
"message": "Create password"
|
||||||
},
|
},
|
||||||
|
"cryptoCompare": {
|
||||||
|
"message": "CryptoCompare"
|
||||||
|
},
|
||||||
"currencyConversion": {
|
"currencyConversion": {
|
||||||
"message": "Currency conversion"
|
"message": "Currency conversion"
|
||||||
},
|
},
|
||||||
|
"currencyRateCheckToggle": {
|
||||||
|
"message": "Show balance and token price checker"
|
||||||
|
},
|
||||||
|
"currencyRateCheckToggleDescription": {
|
||||||
|
"message": "We use $1 and $2 APIs to display your balance and token price. $3",
|
||||||
|
"description": "$1 represents Coingecko, $2 represents CryptoCompare and $3 represents Privacy Policy"
|
||||||
|
},
|
||||||
"currencySymbol": {
|
"currencySymbol": {
|
||||||
"message": "Currency symbol"
|
"message": "Currency symbol"
|
||||||
},
|
},
|
||||||
|
@ -116,7 +116,7 @@ export default class DetectTokensController {
|
|||||||
const tokensToDetect = [];
|
const tokensToDetect = [];
|
||||||
for (const tokenAddress in tokenListUsed) {
|
for (const tokenAddress in tokenListUsed) {
|
||||||
if (
|
if (
|
||||||
!this.tokenAddresses.find(({ address }) =>
|
!this.tokenAddresses.find((address) =>
|
||||||
isEqualCaseInsensitive(address, tokenAddress),
|
isEqualCaseInsensitive(address, tokenAddress),
|
||||||
) &&
|
) &&
|
||||||
!this.hiddenTokens.find((address) =>
|
!this.hiddenTokens.find((address) =>
|
||||||
|
@ -11,8 +11,9 @@ import {
|
|||||||
} from '@metamask/assets-controllers';
|
} from '@metamask/assets-controllers';
|
||||||
import { NETWORK_TYPES } from '../../../shared/constants/network';
|
import { NETWORK_TYPES } from '../../../shared/constants/network';
|
||||||
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
|
import { hexToDecimal } from '../../../shared/lib/metamask-controller-utils';
|
||||||
import DetectTokensController from './detect-tokens';
|
import DetectTokensController from './detect-tokens';
|
||||||
import NetworkController from './network';
|
import NetworkController, { NETWORK_EVENTS } from './network';
|
||||||
import PreferencesController from './preferences';
|
import PreferencesController from './preferences';
|
||||||
|
|
||||||
describe('DetectTokensController', function () {
|
describe('DetectTokensController', function () {
|
||||||
@ -64,14 +65,34 @@ describe('DetectTokensController', function () {
|
|||||||
onPreferencesStateChange: preferences.store.subscribe.bind(
|
onPreferencesStateChange: preferences.store.subscribe.bind(
|
||||||
preferences.store,
|
preferences.store,
|
||||||
),
|
),
|
||||||
onNetworkStateChange: network.store.subscribe.bind(network.store),
|
onNetworkStateChange: (cb) =>
|
||||||
|
network.store.subscribe((networkState) => {
|
||||||
|
const modifiedNetworkState = {
|
||||||
|
...networkState,
|
||||||
|
providerConfig: {
|
||||||
|
...networkState.provider,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return cb(modifiedNetworkState);
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
assetsContractController = new AssetsContractController({
|
assetsContractController = new AssetsContractController({
|
||||||
onPreferencesStateChange: preferences.store.subscribe.bind(
|
onPreferencesStateChange: preferences.store.subscribe.bind(
|
||||||
preferences.store,
|
preferences.store,
|
||||||
),
|
),
|
||||||
onNetworkStateChange: network.store.subscribe.bind(network.store),
|
onNetworkStateChange: (cb) =>
|
||||||
|
network.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => {
|
||||||
|
const networkState = network.store.getState();
|
||||||
|
const modifiedNetworkState = {
|
||||||
|
...networkState,
|
||||||
|
providerConfig: {
|
||||||
|
...networkState.provider,
|
||||||
|
chainId: hexToDecimal(networkState.provider.chainId),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return cb(modifiedNetworkState);
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
sandbox
|
sandbox
|
||||||
|
@ -37,6 +37,7 @@ export default class PreferencesController {
|
|||||||
// set to false will be using the static list from contract-metadata
|
// set to false will be using the static list from contract-metadata
|
||||||
useTokenDetection: false,
|
useTokenDetection: false,
|
||||||
useNftDetection: false,
|
useNftDetection: false,
|
||||||
|
useCurrencyRateCheck: true,
|
||||||
openSeaEnabled: false,
|
openSeaEnabled: false,
|
||||||
advancedGasFee: null,
|
advancedGasFee: null,
|
||||||
|
|
||||||
@ -156,6 +157,15 @@ export default class PreferencesController {
|
|||||||
this.store.updateState({ useNftDetection });
|
this.store.updateState({ useNftDetection });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setter for the `useCurrencyRateCheck` property
|
||||||
|
*
|
||||||
|
* @param {boolean} val - Whether or not the user prefers to use currency rate check for ETH and tokens.
|
||||||
|
*/
|
||||||
|
setUseCurrencyRateCheck(val) {
|
||||||
|
this.store.updateState({ useCurrencyRateCheck: val });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setter for the `openSeaEnabled` property
|
* Setter for the `openSeaEnabled` property
|
||||||
*
|
*
|
||||||
|
@ -367,4 +367,23 @@ describe('preferences controller', function () {
|
|||||||
assert.equal(preferencesController.store.getState().theme, 'dark');
|
assert.equal(preferencesController.store.getState().theme, 'dark');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('setUseCurrencyRateCheck', function () {
|
||||||
|
it('should default to false', function () {
|
||||||
|
const state = preferencesController.store.getState();
|
||||||
|
assert.equal(state.useCurrencyRateCheck, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the useCurrencyRateCheck property in state', function () {
|
||||||
|
assert.equal(
|
||||||
|
preferencesController.store.getState().useCurrencyRateCheck,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
preferencesController.setUseCurrencyRateCheck(false);
|
||||||
|
assert.equal(
|
||||||
|
preferencesController.store.getState().useCurrencyRateCheck,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -266,7 +266,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
this.networkController.store.subscribe((networkState) => {
|
this.networkController.store.subscribe((networkState) => {
|
||||||
const modifiedNetworkState = {
|
const modifiedNetworkState = {
|
||||||
...networkState,
|
...networkState,
|
||||||
provider: {
|
providerConfig: {
|
||||||
...networkState.provider,
|
...networkState.provider,
|
||||||
chainId: hexToDecimal(networkState.provider.chainId),
|
chainId: hexToDecimal(networkState.provider.chainId),
|
||||||
},
|
},
|
||||||
@ -291,9 +291,16 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
onPreferencesStateChange: this.preferencesController.store.subscribe.bind(
|
onPreferencesStateChange: this.preferencesController.store.subscribe.bind(
|
||||||
this.preferencesController.store,
|
this.preferencesController.store,
|
||||||
),
|
),
|
||||||
onNetworkStateChange: this.networkController.store.subscribe.bind(
|
onNetworkStateChange: (cb) =>
|
||||||
this.networkController.store,
|
this.networkController.store.subscribe((networkState) => {
|
||||||
),
|
const modifiedNetworkState = {
|
||||||
|
...networkState,
|
||||||
|
providerConfig: {
|
||||||
|
...networkState.provider,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return cb(modifiedNetworkState);
|
||||||
|
}),
|
||||||
config: { provider: this.provider },
|
config: { provider: this.provider },
|
||||||
state: initState.TokensController,
|
state: initState.TokensController,
|
||||||
});
|
});
|
||||||
@ -307,7 +314,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
const networkState = this.networkController.store.getState();
|
const networkState = this.networkController.store.getState();
|
||||||
const modifiedNetworkState = {
|
const modifiedNetworkState = {
|
||||||
...networkState,
|
...networkState,
|
||||||
provider: {
|
providerConfig: {
|
||||||
...networkState.provider,
|
...networkState.provider,
|
||||||
chainId: hexToDecimal(networkState.provider.chainId),
|
chainId: hexToDecimal(networkState.provider.chainId),
|
||||||
},
|
},
|
||||||
@ -327,9 +334,16 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
this.preferencesController.store.subscribe.bind(
|
this.preferencesController.store.subscribe.bind(
|
||||||
this.preferencesController.store,
|
this.preferencesController.store,
|
||||||
),
|
),
|
||||||
onNetworkStateChange: this.networkController.store.subscribe.bind(
|
onNetworkStateChange: (cb) =>
|
||||||
this.networkController.store,
|
this.networkController.store.subscribe((networkState) => {
|
||||||
),
|
const modifiedNetworkState = {
|
||||||
|
...networkState,
|
||||||
|
providerConfig: {
|
||||||
|
...networkState.provider,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return cb(modifiedNetworkState);
|
||||||
|
}),
|
||||||
getERC721AssetName:
|
getERC721AssetName:
|
||||||
this.assetsContractController.getERC721AssetName.bind(
|
this.assetsContractController.getERC721AssetName.bind(
|
||||||
this.assetsContractController,
|
this.assetsContractController,
|
||||||
@ -504,7 +518,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
this.networkController.store.subscribe((networkState) => {
|
this.networkController.store.subscribe((networkState) => {
|
||||||
const modifiedNetworkState = {
|
const modifiedNetworkState = {
|
||||||
...networkState,
|
...networkState,
|
||||||
provider: {
|
providerConfig: {
|
||||||
...networkState.provider,
|
...networkState.provider,
|
||||||
chainId: hexToDecimal(networkState.provider.chainId),
|
chainId: hexToDecimal(networkState.provider.chainId),
|
||||||
},
|
},
|
||||||
@ -512,9 +526,29 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
return cb(modifiedNetworkState);
|
return cb(modifiedNetworkState);
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
undefined,
|
{
|
||||||
|
disabled:
|
||||||
|
!this.preferencesController.store.getState().useCurrencyRateCheck,
|
||||||
|
},
|
||||||
initState.TokenRatesController,
|
initState.TokenRatesController,
|
||||||
);
|
);
|
||||||
|
this.preferencesController.store.subscribe(
|
||||||
|
previousValueComparator((prevState, currState) => {
|
||||||
|
const { useCurrencyRateCheck: prevUseCurrencyRateCheck } = prevState;
|
||||||
|
const { useCurrencyRateCheck: currUseCurrencyRateCheck } = currState;
|
||||||
|
if (currUseCurrencyRateCheck && !prevUseCurrencyRateCheck) {
|
||||||
|
this.currencyRateController.start();
|
||||||
|
this.tokenRatesController.configure(
|
||||||
|
{ disabled: false },
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
} else if (!currUseCurrencyRateCheck && prevUseCurrencyRateCheck) {
|
||||||
|
this.currencyRateController.stop();
|
||||||
|
this.tokenRatesController.configure({ disabled: true }, false, false);
|
||||||
|
}
|
||||||
|
}, this.preferencesController.store.getState()),
|
||||||
|
);
|
||||||
|
|
||||||
this.ensController = new EnsController({
|
this.ensController = new EnsController({
|
||||||
provider: this.provider,
|
provider: this.provider,
|
||||||
@ -1245,7 +1279,9 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
triggerNetworkrequests() {
|
triggerNetworkrequests() {
|
||||||
this.accountTracker.start();
|
this.accountTracker.start();
|
||||||
this.incomingTransactionsController.start();
|
this.incomingTransactionsController.start();
|
||||||
this.currencyRateController.start();
|
if (this.preferencesController.store.getState().useCurrencyRateCheck) {
|
||||||
|
this.currencyRateController.start();
|
||||||
|
}
|
||||||
if (this.preferencesController.store.getState().useTokenDetection) {
|
if (this.preferencesController.store.getState().useTokenDetection) {
|
||||||
this.tokenListController.start();
|
this.tokenListController.start();
|
||||||
}
|
}
|
||||||
@ -1254,7 +1290,9 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
stopNetworkRequests() {
|
stopNetworkRequests() {
|
||||||
this.accountTracker.stop();
|
this.accountTracker.stop();
|
||||||
this.incomingTransactionsController.stop();
|
this.incomingTransactionsController.stop();
|
||||||
this.currencyRateController.stop();
|
if (this.preferencesController.store.getState().useCurrencyRateCheck) {
|
||||||
|
this.currencyRateController.stop();
|
||||||
|
}
|
||||||
if (this.preferencesController.store.getState().useTokenDetection) {
|
if (this.preferencesController.store.getState().useTokenDetection) {
|
||||||
this.tokenListController.stop();
|
this.tokenListController.stop();
|
||||||
}
|
}
|
||||||
@ -1633,6 +1671,10 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
setUseNftDetection: preferencesController.setUseNftDetection.bind(
|
setUseNftDetection: preferencesController.setUseNftDetection.bind(
|
||||||
preferencesController,
|
preferencesController,
|
||||||
),
|
),
|
||||||
|
setUseCurrencyRateCheck:
|
||||||
|
preferencesController.setUseCurrencyRateCheck.bind(
|
||||||
|
preferencesController,
|
||||||
|
),
|
||||||
setOpenSeaEnabled: preferencesController.setOpenSeaEnabled.bind(
|
setOpenSeaEnabled: preferencesController.setOpenSeaEnabled.bind(
|
||||||
preferencesController,
|
preferencesController,
|
||||||
),
|
),
|
||||||
|
@ -501,6 +501,7 @@
|
|||||||
"URL": true,
|
"URL": true,
|
||||||
"clearInterval": true,
|
"clearInterval": true,
|
||||||
"clearTimeout": true,
|
"clearTimeout": true,
|
||||||
|
"console.info": true,
|
||||||
"console.log": true,
|
"console.log": true,
|
||||||
"setInterval": true,
|
"setInterval": true,
|
||||||
"setTimeout": true
|
"setTimeout": true
|
||||||
@ -508,10 +509,10 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"@ethersproject/contracts": true,
|
"@ethersproject/contracts": true,
|
||||||
"@ethersproject/providers": true,
|
"@ethersproject/providers": true,
|
||||||
"@metamask/assets-controllers>@metamask/contract-metadata": true,
|
|
||||||
"@metamask/assets-controllers>abort-controller": true,
|
"@metamask/assets-controllers>abort-controller": true,
|
||||||
"@metamask/assets-controllers>multiformats": true,
|
"@metamask/assets-controllers>multiformats": true,
|
||||||
"@metamask/base-controller": true,
|
"@metamask/base-controller": true,
|
||||||
|
"@metamask/contract-metadata": true,
|
||||||
"@metamask/controller-utils": true,
|
"@metamask/controller-utils": true,
|
||||||
"@metamask/metamask-eth-abis": true,
|
"@metamask/metamask-eth-abis": true,
|
||||||
"browserify>events": true,
|
"browserify>events": true,
|
||||||
|
@ -501,6 +501,7 @@
|
|||||||
"URL": true,
|
"URL": true,
|
||||||
"clearInterval": true,
|
"clearInterval": true,
|
||||||
"clearTimeout": true,
|
"clearTimeout": true,
|
||||||
|
"console.info": true,
|
||||||
"console.log": true,
|
"console.log": true,
|
||||||
"setInterval": true,
|
"setInterval": true,
|
||||||
"setTimeout": true
|
"setTimeout": true
|
||||||
@ -508,10 +509,10 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"@ethersproject/contracts": true,
|
"@ethersproject/contracts": true,
|
||||||
"@ethersproject/providers": true,
|
"@ethersproject/providers": true,
|
||||||
"@metamask/assets-controllers>@metamask/contract-metadata": true,
|
|
||||||
"@metamask/assets-controllers>abort-controller": true,
|
"@metamask/assets-controllers>abort-controller": true,
|
||||||
"@metamask/assets-controllers>multiformats": true,
|
"@metamask/assets-controllers>multiformats": true,
|
||||||
"@metamask/base-controller": true,
|
"@metamask/base-controller": true,
|
||||||
|
"@metamask/contract-metadata": true,
|
||||||
"@metamask/controller-utils": true,
|
"@metamask/controller-utils": true,
|
||||||
"@metamask/metamask-eth-abis": true,
|
"@metamask/metamask-eth-abis": true,
|
||||||
"browserify>events": true,
|
"browserify>events": true,
|
||||||
|
@ -501,6 +501,7 @@
|
|||||||
"URL": true,
|
"URL": true,
|
||||||
"clearInterval": true,
|
"clearInterval": true,
|
||||||
"clearTimeout": true,
|
"clearTimeout": true,
|
||||||
|
"console.info": true,
|
||||||
"console.log": true,
|
"console.log": true,
|
||||||
"setInterval": true,
|
"setInterval": true,
|
||||||
"setTimeout": true
|
"setTimeout": true
|
||||||
@ -508,10 +509,10 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"@ethersproject/contracts": true,
|
"@ethersproject/contracts": true,
|
||||||
"@ethersproject/providers": true,
|
"@ethersproject/providers": true,
|
||||||
"@metamask/assets-controllers>@metamask/contract-metadata": true,
|
|
||||||
"@metamask/assets-controllers>abort-controller": true,
|
"@metamask/assets-controllers>abort-controller": true,
|
||||||
"@metamask/assets-controllers>multiformats": true,
|
"@metamask/assets-controllers>multiformats": true,
|
||||||
"@metamask/base-controller": true,
|
"@metamask/base-controller": true,
|
||||||
|
"@metamask/contract-metadata": true,
|
||||||
"@metamask/controller-utils": true,
|
"@metamask/controller-utils": true,
|
||||||
"@metamask/metamask-eth-abis": true,
|
"@metamask/metamask-eth-abis": true,
|
||||||
"browserify>events": true,
|
"browserify>events": true,
|
||||||
|
@ -209,7 +209,7 @@
|
|||||||
"@metamask/address-book-controller": "^1.0.0",
|
"@metamask/address-book-controller": "^1.0.0",
|
||||||
"@metamask/announcement-controller": "^1.0.0",
|
"@metamask/announcement-controller": "^1.0.0",
|
||||||
"@metamask/approval-controller": "^1.0.0",
|
"@metamask/approval-controller": "^1.0.0",
|
||||||
"@metamask/assets-controllers": "^1.0.1",
|
"@metamask/assets-controllers": "^3.0.1",
|
||||||
"@metamask/base-controller": "^1.0.0",
|
"@metamask/base-controller": "^1.0.0",
|
||||||
"@metamask/contract-metadata": "^2.1.0",
|
"@metamask/contract-metadata": "^2.1.0",
|
||||||
"@metamask/controller-utils": "^1.0.0",
|
"@metamask/controller-utils": "^1.0.0",
|
||||||
|
@ -5,6 +5,11 @@ _supportLink = 'https://metamask-flask.zendesk.com/hc';
|
|||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
|
||||||
export const SUPPORT_LINK = _supportLink;
|
export const SUPPORT_LINK = _supportLink;
|
||||||
|
|
||||||
|
export const COINGECKO_LINK = 'https://www.coingecko.com/';
|
||||||
|
export const CRYPTOCOMPARE_LINK = 'https://www.cryptocompare.com/';
|
||||||
|
export const PRIVACY_POLICY_LINK = 'https://consensys.net/privacy-policy/';
|
||||||
|
|
||||||
// TODO make sure these links are correct
|
// TODO make sure these links are correct
|
||||||
export const ETHERSCAN_PRIVACY_LINK = 'https://etherscan.io/privacyPolicy';
|
export const ETHERSCAN_PRIVACY_LINK = 'https://etherscan.io/privacyPolicy';
|
||||||
export const CONSENSYS_PRIVACY_LINK = 'https://consensys.net/privacy-policy/';
|
export const CONSENSYS_PRIVACY_LINK = 'https://consensys.net/privacy-policy/';
|
||||||
|
@ -252,6 +252,7 @@
|
|||||||
"unapprovedTypedMessages": {},
|
"unapprovedTypedMessages": {},
|
||||||
"unapprovedTypedMessagesCount": 0,
|
"unapprovedTypedMessagesCount": 0,
|
||||||
"useTokenDetection": true,
|
"useTokenDetection": true,
|
||||||
|
"useCurrencyRateCheck": true,
|
||||||
"advancedGasFee": {
|
"advancedGasFee": {
|
||||||
"maxBaseFee": "75",
|
"maxBaseFee": "75",
|
||||||
"priorityFee": "2"
|
"priorityFee": "2"
|
||||||
|
@ -239,6 +239,7 @@ function defaultFixture() {
|
|||||||
useNonceField: false,
|
useNonceField: false,
|
||||||
usePhishDetect: true,
|
usePhishDetect: true,
|
||||||
useTokenDetection: false,
|
useTokenDetection: false,
|
||||||
|
useCurrencyRateCheck: true,
|
||||||
useMultiAccountBalanceChecker: true,
|
useMultiAccountBalanceChecker: true,
|
||||||
},
|
},
|
||||||
SmartTransactionsController: {
|
SmartTransactionsController: {
|
||||||
@ -352,6 +353,7 @@ function onboardingFixture() {
|
|||||||
useNonceField: false,
|
useNonceField: false,
|
||||||
usePhishDetect: true,
|
usePhishDetect: true,
|
||||||
useTokenDetection: false,
|
useTokenDetection: false,
|
||||||
|
useCurrencyRateCheck: true,
|
||||||
useMultiAccountBalanceChecker: true,
|
useMultiAccountBalanceChecker: true,
|
||||||
},
|
},
|
||||||
SmartTransactionsController: {
|
SmartTransactionsController: {
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
"useNonceField": false,
|
"useNonceField": false,
|
||||||
"usePhishDetect": true,
|
"usePhishDetect": true,
|
||||||
"useTokenDetection": false,
|
"useTokenDetection": false,
|
||||||
|
"useCurrencyRateCheck": true,
|
||||||
"useMultiAccountBalanceChecker": true
|
"useMultiAccountBalanceChecker": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,6 +218,7 @@ export const createSwapsMockStore = () => {
|
|||||||
postTxBalance: '19a61aaaf06e4bd1',
|
postTxBalance: '19a61aaaf06e4bd1',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
useCurrencyRateCheck: true,
|
||||||
conversionRate: 1,
|
conversionRate: 1,
|
||||||
contractExchangeRates: {
|
contractExchangeRates: {
|
||||||
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 2,
|
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 2,
|
||||||
|
@ -16,6 +16,7 @@ describe('CurrencyInput Component', () => {
|
|||||||
preferences: {
|
preferences: {
|
||||||
showFiatInTestnets: true,
|
showFiatInTestnets: true,
|
||||||
},
|
},
|
||||||
|
useCurrencyRateCheck: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
describe('rendering', () => {
|
describe('rendering', () => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import Box from '../../../ui/box';
|
import Box from '../../../ui/box';
|
||||||
import Typography from '../../../ui/typography';
|
import Typography from '../../../ui/typography';
|
||||||
@ -12,6 +13,7 @@ import {
|
|||||||
} from '../../../../helpers/constants/design-system';
|
} from '../../../../helpers/constants/design-system';
|
||||||
import { useTokenTracker } from '../../../../hooks/useTokenTracker';
|
import { useTokenTracker } from '../../../../hooks/useTokenTracker';
|
||||||
import { useTokenFiatAmount } from '../../../../hooks/useTokenFiatAmount';
|
import { useTokenFiatAmount } from '../../../../hooks/useTokenFiatAmount';
|
||||||
|
import { getUseCurrencyRateCheck } from '../../../../selectors';
|
||||||
|
|
||||||
const DetectedTokenValues = ({
|
const DetectedTokenValues = ({
|
||||||
token,
|
token,
|
||||||
@ -30,6 +32,8 @@ const DetectedTokenValues = ({
|
|||||||
token.symbol,
|
token.symbol,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTokenSelection(tokensListDetected[token.address]?.selected);
|
setTokenSelection(tokensListDetected[token.address]?.selected);
|
||||||
}, [tokensListDetected, token.address, tokenSelection, setTokenSelection]);
|
}, [tokensListDetected, token.address, tokenSelection, setTokenSelection]);
|
||||||
@ -46,7 +50,9 @@ const DetectedTokenValues = ({
|
|||||||
{`${balanceString || '0'} ${token.symbol}`}
|
{`${balanceString || '0'} ${token.symbol}`}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant={TYPOGRAPHY.H7} color={COLORS.TEXT_ALTERNATIVE}>
|
<Typography variant={TYPOGRAPHY.H7} color={COLORS.TEXT_ALTERNATIVE}>
|
||||||
{formattedFiatBalance || '$0'}
|
{useCurrencyRateCheck
|
||||||
|
? formattedFiatBalance || '$0' // since formattedFiatBalance will be when teh conversion rate is not obtained, should be replace the `$0` with `N/A`
|
||||||
|
: formattedFiatBalance}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box className="detected-token-values__checkbox">
|
<Box className="detected-token-values__checkbox">
|
||||||
|
@ -5,7 +5,7 @@ import { useSelector } from 'react-redux';
|
|||||||
|
|
||||||
import { COLORS } from '../../../helpers/constants/design-system';
|
import { COLORS } from '../../../helpers/constants/design-system';
|
||||||
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common';
|
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common';
|
||||||
import { getPreferences } from '../../../selectors';
|
import { getPreferences, getUseCurrencyRateCheck } from '../../../selectors';
|
||||||
import { useGasFeeContext } from '../../../contexts/gasFee';
|
import { useGasFeeContext } from '../../../contexts/gasFee';
|
||||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
|
|
||||||
@ -29,6 +29,8 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => {
|
|||||||
|
|
||||||
const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences);
|
const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences);
|
||||||
|
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
|
|
||||||
if (hasSimulationError && !userAcknowledgedGasMissing) {
|
if (hasSimulationError && !userAcknowledgedGasMissing) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -39,14 +41,16 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => {
|
|||||||
detailTitle={<GasDetailsItemTitle />}
|
detailTitle={<GasDetailsItemTitle />}
|
||||||
detailTitleColor={COLORS.TEXT_DEFAULT}
|
detailTitleColor={COLORS.TEXT_DEFAULT}
|
||||||
detailText={
|
detailText={
|
||||||
<div className="gas-details-item__currency-container">
|
useCurrencyRateCheck && (
|
||||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
<div className="gas-details-item__currency-container">
|
||||||
<UserPreferencedCurrencyDisplay
|
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||||
type={SECONDARY}
|
<UserPreferencedCurrencyDisplay
|
||||||
value={hexMinimumTransactionFee}
|
type={SECONDARY}
|
||||||
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
value={hexMinimumTransactionFee}
|
||||||
/>
|
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
detailTotal={
|
detailTotal={
|
||||||
<div className="gas-details-item__currency-container">
|
<div className="gas-details-item__currency-container">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
exports[`Token Cell should match snapshot 1`] = `
|
exports[`Token Cell should match snapshot 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="list-item asset-list-item token-cell"
|
class="list-item asset-list-item token-cell list-item--single-content-row"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -77,15 +77,6 @@ exports[`Token Cell should match snapshot 1`] = `
|
|||||||
</h2>
|
</h2>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
class="list-item__subheading"
|
|
||||||
>
|
|
||||||
<h3
|
|
||||||
title="$0.52 USD"
|
|
||||||
>
|
|
||||||
$0.52 USD
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="list-item__right-content"
|
class="list-item__right-content"
|
||||||
>
|
>
|
||||||
|
@ -219,6 +219,13 @@ export const SETTINGS_CONSTANTS = [
|
|||||||
icon: 'fa fa-flask',
|
icon: 'fa fa-flask',
|
||||||
featureFlag: 'NFTS_V1',
|
featureFlag: 'NFTS_V1',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
tabMessage: (t) => t('securityAndPrivacy'),
|
||||||
|
sectionMessage: (t) => t('currencyRateCheckToggle'),
|
||||||
|
descriptionMessage: (t) => t('currencyRateCheckToggleDescription'),
|
||||||
|
route: `${SECURITY_ROUTE}#price-checker`,
|
||||||
|
icon: 'fa fa-lock',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
tabMessage: (t) => t('alerts'),
|
tabMessage: (t) => t('alerts'),
|
||||||
sectionMessage: (t) => t('alertSettingsUnconnectedAccount'),
|
sectionMessage: (t) => t('alertSettingsUnconnectedAccount'),
|
||||||
|
@ -137,6 +137,10 @@ const t = (key) => {
|
|||||||
return 'Contact us';
|
return 'Contact us';
|
||||||
case 'snaps':
|
case 'snaps':
|
||||||
return 'Snaps';
|
return 'Snaps';
|
||||||
|
case 'currencyRateCheckToggle':
|
||||||
|
return 'Show balance and token price checker';
|
||||||
|
case 'currencyRateCheckToggleDescription':
|
||||||
|
return 'We use Coingecko and CryptoCompare APIs to display your balance and token price. Privacy Policy';
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -165,7 +169,7 @@ describe('Settings Search Utils', () => {
|
|||||||
it('should get good security & privacy section number', () => {
|
it('should get good security & privacy section number', () => {
|
||||||
expect(
|
expect(
|
||||||
getNumberOfSettingsInSection(t, t('securityAndPrivacy')),
|
getNumberOfSettingsInSection(t, t('securityAndPrivacy')),
|
||||||
).toStrictEqual(9);
|
).toStrictEqual(10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get good alerts section number', () => {
|
it('should get good alerts section number', () => {
|
||||||
|
@ -160,6 +160,7 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
insightSnaps: PropTypes.arrayOf(PropTypes.object),
|
insightSnaps: PropTypes.arrayOf(PropTypes.object),
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
assetStandard: PropTypes.string,
|
assetStandard: PropTypes.string,
|
||||||
|
useCurrencyRateCheck: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -349,6 +350,7 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
isMultiLayerFeeNetwork,
|
isMultiLayerFeeNetwork,
|
||||||
nativeCurrency,
|
nativeCurrency,
|
||||||
isBuyableChain,
|
isBuyableChain,
|
||||||
|
useCurrencyRateCheck,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { t } = this.context;
|
const { t } = this.context;
|
||||||
const { userAcknowledgedGasMissing } = this.state;
|
const { userAcknowledgedGasMissing } = this.state;
|
||||||
@ -511,14 +513,16 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
detailText={
|
detailText={
|
||||||
<div className="confirm-page-container-content__currency-container test">
|
useCurrencyRateCheck && (
|
||||||
{renderHeartBeatIfNotInTest()}
|
<div className="confirm-page-container-content__currency-container test">
|
||||||
<UserPreferencedCurrencyDisplay
|
{renderHeartBeatIfNotInTest()}
|
||||||
type={SECONDARY}
|
<UserPreferencedCurrencyDisplay
|
||||||
value={hexMinimumTransactionFee}
|
type={SECONDARY}
|
||||||
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
value={hexMinimumTransactionFee}
|
||||||
/>
|
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
detailTotal={
|
detailTotal={
|
||||||
<div className="confirm-page-container-content__currency-container">
|
<div className="confirm-page-container-content__currency-container">
|
||||||
@ -637,7 +641,7 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
<TransactionDetailItem
|
<TransactionDetailItem
|
||||||
key="total-item"
|
key="total-item"
|
||||||
detailTitle={t('total')}
|
detailTitle={t('total')}
|
||||||
detailText={renderTotalDetailText()}
|
detailText={useCurrencyRateCheck && renderTotalDetailText()}
|
||||||
detailTotal={renderTotalDetailTotal()}
|
detailTotal={renderTotalDetailTotal()}
|
||||||
subTitle={t('transactionDetailGasTotalSubtitle')}
|
subTitle={t('transactionDetailGasTotalSubtitle')}
|
||||||
subText={
|
subText={
|
||||||
|
@ -36,6 +36,7 @@ import {
|
|||||||
getEnsResolutionByAddress,
|
getEnsResolutionByAddress,
|
||||||
getUnapprovedTransaction,
|
getUnapprovedTransaction,
|
||||||
getFullTxData,
|
getFullTxData,
|
||||||
|
getUseCurrencyRateCheck,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
||||||
getInsightSnaps,
|
getInsightSnaps,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
@ -251,6 +252,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
||||||
insightSnaps,
|
insightSnaps,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
useCurrencyRateCheck: getUseCurrencyRateCheck(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,13 +22,20 @@ import {
|
|||||||
showModal,
|
showModal,
|
||||||
setIpfsGateway,
|
setIpfsGateway,
|
||||||
showNetworkDropdown,
|
showNetworkDropdown,
|
||||||
|
setUseCurrencyRateCheck,
|
||||||
} from '../../../store/actions';
|
} from '../../../store/actions';
|
||||||
import { ONBOARDING_PIN_EXTENSION_ROUTE } from '../../../helpers/constants/routes';
|
import { ONBOARDING_PIN_EXTENSION_ROUTE } from '../../../helpers/constants/routes';
|
||||||
import { Icon, TextField } from '../../../components/component-library';
|
import { Icon, TextField } from '../../../components/component-library';
|
||||||
import NetworkDropdown from '../../../components/app/dropdowns/network-dropdown';
|
import NetworkDropdown from '../../../components/app/dropdowns/network-dropdown';
|
||||||
import NetworkDisplay from '../../../components/app/network-display/network-display';
|
import NetworkDisplay from '../../../components/app/network-display/network-display';
|
||||||
|
import {
|
||||||
|
COINGECKO_LINK,
|
||||||
|
CRYPTOCOMPARE_LINK,
|
||||||
|
PRIVACY_POLICY_LINK,
|
||||||
|
} from '../../../../shared/lib/ui-utils';
|
||||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics';
|
import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics';
|
||||||
|
|
||||||
import { Setting } from './setting';
|
import { Setting } from './setting';
|
||||||
|
|
||||||
export default function PrivacySettings() {
|
export default function PrivacySettings() {
|
||||||
@ -37,6 +44,7 @@ export default function PrivacySettings() {
|
|||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [usePhishingDetection, setUsePhishingDetection] = useState(true);
|
const [usePhishingDetection, setUsePhishingDetection] = useState(true);
|
||||||
const [turnOnTokenDetection, setTurnOnTokenDetection] = useState(true);
|
const [turnOnTokenDetection, setTurnOnTokenDetection] = useState(true);
|
||||||
|
const [turnOnCurrencyRateCheck, setTurnOnCurrencyRateCheck] = useState(true);
|
||||||
const [showIncomingTransactions, setShowIncomingTransactions] =
|
const [showIncomingTransactions, setShowIncomingTransactions] =
|
||||||
useState(true);
|
useState(true);
|
||||||
const [
|
const [
|
||||||
@ -60,6 +68,7 @@ export default function PrivacySettings() {
|
|||||||
dispatch(
|
dispatch(
|
||||||
setUseMultiAccountBalanceChecker(isMultiAccountBalanceCheckerEnabled),
|
setUseMultiAccountBalanceChecker(isMultiAccountBalanceCheckerEnabled),
|
||||||
);
|
);
|
||||||
|
dispatch(setUseCurrencyRateCheck(turnOnCurrencyRateCheck));
|
||||||
dispatch(setCompletedOnboarding());
|
dispatch(setCompletedOnboarding());
|
||||||
|
|
||||||
if (ipfsURL && !ipfsError) {
|
if (ipfsURL && !ipfsError) {
|
||||||
@ -254,6 +263,37 @@ export default function PrivacySettings() {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<Setting
|
||||||
|
value={turnOnCurrencyRateCheck}
|
||||||
|
setValue={setTurnOnCurrencyRateCheck}
|
||||||
|
title={t('currencyRateCheckToggle')}
|
||||||
|
description={t('currencyRateCheckToggleDescription', [
|
||||||
|
<a
|
||||||
|
key="coingecko_link"
|
||||||
|
href={COINGECKO_LINK}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{t('coingecko')}
|
||||||
|
</a>,
|
||||||
|
<a
|
||||||
|
key="cryptocompare_link"
|
||||||
|
href={CRYPTOCOMPARE_LINK}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{t('cryptoCompare')}
|
||||||
|
</a>,
|
||||||
|
<a
|
||||||
|
key="privacy_policy_link"
|
||||||
|
href={PRIVACY_POLICY_LINK}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{t('privacyMsg')}
|
||||||
|
</a>,
|
||||||
|
])}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Button type="primary" rounded onClick={handleSubmit}>
|
<Button type="primary" rounded onClick={handleSubmit}>
|
||||||
{t('done')}
|
{t('done')}
|
||||||
|
@ -22,6 +22,7 @@ describe('Privacy Settings Onboarding View', () => {
|
|||||||
const setFeatureFlagStub = jest.fn();
|
const setFeatureFlagStub = jest.fn();
|
||||||
const setUsePhishDetectStub = jest.fn();
|
const setUsePhishDetectStub = jest.fn();
|
||||||
const setUseTokenDetectionStub = jest.fn();
|
const setUseTokenDetectionStub = jest.fn();
|
||||||
|
const setUseCurrencyRateCheckStub = jest.fn();
|
||||||
const completeOnboardingStub = jest
|
const completeOnboardingStub = jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockImplementation(() => Promise.resolve());
|
.mockImplementation(() => Promise.resolve());
|
||||||
@ -31,6 +32,7 @@ describe('Privacy Settings Onboarding View', () => {
|
|||||||
setFeatureFlag: setFeatureFlagStub,
|
setFeatureFlag: setFeatureFlagStub,
|
||||||
setUsePhishDetect: setUsePhishDetectStub,
|
setUsePhishDetect: setUsePhishDetectStub,
|
||||||
setUseTokenDetection: setUseTokenDetectionStub,
|
setUseTokenDetection: setUseTokenDetectionStub,
|
||||||
|
setUseCurrencyRateCheck: setUseCurrencyRateCheckStub,
|
||||||
completeOnboarding: completeOnboardingStub,
|
completeOnboarding: completeOnboardingStub,
|
||||||
setUseMultiAccountBalanceChecker: setUseMultiAccountBalanceCheckerStub,
|
setUseMultiAccountBalanceChecker: setUseMultiAccountBalanceCheckerStub,
|
||||||
});
|
});
|
||||||
@ -45,6 +47,7 @@ describe('Privacy Settings Onboarding View', () => {
|
|||||||
expect(setUsePhishDetectStub).toHaveBeenCalledTimes(0);
|
expect(setUsePhishDetectStub).toHaveBeenCalledTimes(0);
|
||||||
expect(setUseTokenDetectionStub).toHaveBeenCalledTimes(0);
|
expect(setUseTokenDetectionStub).toHaveBeenCalledTimes(0);
|
||||||
expect(setUseMultiAccountBalanceCheckerStub).toHaveBeenCalledTimes(0);
|
expect(setUseMultiAccountBalanceCheckerStub).toHaveBeenCalledTimes(0);
|
||||||
|
expect(setUseCurrencyRateCheckStub).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
const toggles = container.querySelectorAll('input[type=checkbox]');
|
const toggles = container.querySelectorAll('input[type=checkbox]');
|
||||||
const submitButton = getByText('Done');
|
const submitButton = getByText('Done');
|
||||||
@ -54,34 +57,42 @@ describe('Privacy Settings Onboarding View', () => {
|
|||||||
fireEvent.click(toggles[1]);
|
fireEvent.click(toggles[1]);
|
||||||
fireEvent.click(toggles[2]);
|
fireEvent.click(toggles[2]);
|
||||||
fireEvent.click(toggles[3]);
|
fireEvent.click(toggles[3]);
|
||||||
|
fireEvent.click(toggles[4]);
|
||||||
fireEvent.click(submitButton);
|
fireEvent.click(submitButton);
|
||||||
|
|
||||||
expect(setFeatureFlagStub).toHaveBeenCalledTimes(1);
|
expect(setFeatureFlagStub).toHaveBeenCalledTimes(1);
|
||||||
expect(setUsePhishDetectStub).toHaveBeenCalledTimes(1);
|
expect(setUsePhishDetectStub).toHaveBeenCalledTimes(1);
|
||||||
expect(setUseTokenDetectionStub).toHaveBeenCalledTimes(1);
|
expect(setUseTokenDetectionStub).toHaveBeenCalledTimes(1);
|
||||||
expect(setUseMultiAccountBalanceCheckerStub).toHaveBeenCalledTimes(1);
|
expect(setUseMultiAccountBalanceCheckerStub).toHaveBeenCalledTimes(1);
|
||||||
|
expect(setUseCurrencyRateCheckStub).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
expect(setFeatureFlagStub.mock.calls[0][1]).toStrictEqual(false);
|
expect(setFeatureFlagStub.mock.calls[0][1]).toStrictEqual(false);
|
||||||
expect(setUsePhishDetectStub.mock.calls[0][0]).toStrictEqual(false);
|
expect(setUsePhishDetectStub.mock.calls[0][0]).toStrictEqual(false);
|
||||||
expect(setUseTokenDetectionStub.mock.calls[0][0]).toStrictEqual(false);
|
expect(setUseTokenDetectionStub.mock.calls[0][0]).toStrictEqual(false);
|
||||||
expect(setUseMultiAccountBalanceCheckerStub.mock.calls[0][0]).toStrictEqual(
|
expect(setUseMultiAccountBalanceCheckerStub.mock.calls[0][0]).toStrictEqual(
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
expect(setUseCurrencyRateCheckStub.mock.calls[0][0]).toStrictEqual(false);
|
||||||
|
|
||||||
// toggle back to true
|
// toggle back to true
|
||||||
fireEvent.click(toggles[0]);
|
fireEvent.click(toggles[0]);
|
||||||
fireEvent.click(toggles[1]);
|
fireEvent.click(toggles[1]);
|
||||||
fireEvent.click(toggles[2]);
|
fireEvent.click(toggles[2]);
|
||||||
fireEvent.click(toggles[3]);
|
fireEvent.click(toggles[3]);
|
||||||
|
fireEvent.click(toggles[4]);
|
||||||
fireEvent.click(submitButton);
|
fireEvent.click(submitButton);
|
||||||
expect(setFeatureFlagStub).toHaveBeenCalledTimes(2);
|
expect(setFeatureFlagStub).toHaveBeenCalledTimes(2);
|
||||||
expect(setUsePhishDetectStub).toHaveBeenCalledTimes(2);
|
expect(setUsePhishDetectStub).toHaveBeenCalledTimes(2);
|
||||||
expect(setUseTokenDetectionStub).toHaveBeenCalledTimes(2);
|
expect(setUseTokenDetectionStub).toHaveBeenCalledTimes(2);
|
||||||
expect(setUseMultiAccountBalanceCheckerStub).toHaveBeenCalledTimes(2);
|
expect(setUseMultiAccountBalanceCheckerStub).toHaveBeenCalledTimes(2);
|
||||||
|
expect(setUseCurrencyRateCheckStub).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
expect(setFeatureFlagStub.mock.calls[1][1]).toStrictEqual(true);
|
expect(setFeatureFlagStub.mock.calls[1][1]).toStrictEqual(true);
|
||||||
expect(setUsePhishDetectStub.mock.calls[1][0]).toStrictEqual(true);
|
expect(setUsePhishDetectStub.mock.calls[1][0]).toStrictEqual(true);
|
||||||
expect(setUseTokenDetectionStub.mock.calls[1][0]).toStrictEqual(true);
|
expect(setUseTokenDetectionStub.mock.calls[1][0]).toStrictEqual(true);
|
||||||
expect(setUseMultiAccountBalanceCheckerStub.mock.calls[1][0]).toStrictEqual(
|
expect(setUseMultiAccountBalanceCheckerStub.mock.calls[1][0]).toStrictEqual(
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
expect(setUseCurrencyRateCheckStub.mock.calls[1][0]).toStrictEqual(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -38,6 +38,7 @@ import {
|
|||||||
getIsBuyableChain,
|
getIsBuyableChain,
|
||||||
transactionFeeSelector,
|
transactionFeeSelector,
|
||||||
getIsMainnet,
|
getIsMainnet,
|
||||||
|
getUseCurrencyRateCheck,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -57,6 +58,7 @@ export default function GasDisplay({ gasError }) {
|
|||||||
const isMainnet = useSelector(getIsMainnet);
|
const isMainnet = useSelector(getIsMainnet);
|
||||||
const isBuyableChain = useSelector(getIsBuyableChain);
|
const isBuyableChain = useSelector(getIsBuyableChain);
|
||||||
const draftTransaction = useSelector(getCurrentDraftTransaction);
|
const draftTransaction = useSelector(getCurrentDraftTransaction);
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences);
|
const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences);
|
||||||
const { nativeCurrency, provider, unapprovedTxs } = useSelector(
|
const { nativeCurrency, provider, unapprovedTxs } = useSelector(
|
||||||
(state) => state.metamask,
|
(state) => state.metamask,
|
||||||
@ -197,14 +199,16 @@ export default function GasDisplay({ gasError }) {
|
|||||||
}
|
}
|
||||||
detailTitleColor={COLORS.TEXT_DEFAULT}
|
detailTitleColor={COLORS.TEXT_DEFAULT}
|
||||||
detailText={
|
detailText={
|
||||||
<Box className="gas-display__currency-container">
|
useCurrencyRateCheck && (
|
||||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
<Box className="gas-display__currency-container">
|
||||||
<UserPreferencedCurrencyDisplay
|
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||||
type={SECONDARY}
|
<UserPreferencedCurrencyDisplay
|
||||||
value={hexMinimumTransactionFee}
|
type={SECONDARY}
|
||||||
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
value={hexMinimumTransactionFee}
|
||||||
/>
|
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||||
</Box>
|
/>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
detailTotal={
|
detailTotal={
|
||||||
<Box className="gas-display__currency-container">
|
<Box className="gas-display__currency-container">
|
||||||
@ -263,22 +267,24 @@ export default function GasDisplay({ gasError }) {
|
|||||||
key="total-item"
|
key="total-item"
|
||||||
detailTitle={t('total')}
|
detailTitle={t('total')}
|
||||||
detailText={
|
detailText={
|
||||||
<Box
|
useCurrencyRateCheck && (
|
||||||
height={BLOCK_SIZES.MAX}
|
<Box
|
||||||
display={DISPLAY.FLEX}
|
height={BLOCK_SIZES.MAX}
|
||||||
flexDirection={FLEX_DIRECTION.COLUMN}
|
display={DISPLAY.FLEX}
|
||||||
className="gas-display__total-value"
|
flexDirection={FLEX_DIRECTION.COLUMN}
|
||||||
>
|
className="gas-display__total-value"
|
||||||
<LoadingHeartBeat
|
>
|
||||||
estimateUsed={transactionData?.userFeeLevel}
|
<LoadingHeartBeat
|
||||||
/>
|
estimateUsed={transactionData?.userFeeLevel}
|
||||||
<UserPreferencedCurrencyDisplay
|
/>
|
||||||
type={SECONDARY}
|
<UserPreferencedCurrencyDisplay
|
||||||
key="total-detail-text"
|
type={SECONDARY}
|
||||||
value={hexTransactionTotal}
|
key="total-detail-text"
|
||||||
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
value={hexTransactionTotal}
|
||||||
/>
|
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||||
</Box>
|
/>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
detailTotal={detailTotal}
|
detailTotal={detailTotal}
|
||||||
subTitle={t('transactionDetailGasTotalSubtitle')}
|
subTitle={t('transactionDetailGasTotalSubtitle')}
|
||||||
|
@ -236,27 +236,6 @@ exports[`SendContent Component render should match snapshot 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="transaction-detail-item__detail-values"
|
class="transaction-detail-item__detail-values"
|
||||||
>
|
>
|
||||||
<h6
|
|
||||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="box gas-display__currency-container box--flex-direction-row"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="currency-display-component"
|
|
||||||
title="0.0000315"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="currency-display-component__prefix"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="currency-display-component__text"
|
|
||||||
>
|
|
||||||
0.0000315
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</h6>
|
|
||||||
<h6
|
<h6
|
||||||
class="box box--margin-top-1 box--margin-bottom-1 box--margin-left-1 box--flex-direction-row box--text-align-right typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
class="box box--margin-top-1 box--margin-bottom-1 box--margin-left-1 box--flex-direction-row box--text-align-right typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
||||||
>
|
>
|
||||||
|
@ -134,6 +134,103 @@ exports[`Security Tab should match snapshot 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="settings-page__content-padded"
|
class="settings-page__content-padded"
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
class="settings-page__content-row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="settings-page__content-item"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Show balance and token price checker
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="settings-page__content-description"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
We use
|
||||||
|
<a
|
||||||
|
href="https://www.coingecko.com/"
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
CoinGecko
|
||||||
|
</a>
|
||||||
|
and
|
||||||
|
<a
|
||||||
|
href="https://www.cryptocompare.com/"
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
CryptoCompare
|
||||||
|
</a>
|
||||||
|
APIs to display your balance and token price.
|
||||||
|
<a
|
||||||
|
href="https://consensys.net/privacy-policy/"
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Privacy policy
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="settings-page__content-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="settings-page__content-item-col"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="toggle-button toggle-button--on"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="display: flex; width: 52px; align-items: center; justify-content: flex-start; position: relative; cursor: pointer; background-color: transparent; border: 0px; padding: 0px; user-select: none;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width: 40px; height: 24px; padding: 0px; border-radius: 26px; display: flex; align-items: center; justify-content: center; background-color: rgb(242, 244, 246);"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgb(250, 250, 250); margin-top: auto; margin-bottom: auto; line-height: 0; opacity: 1; width: 26px; height: 20px; left: 4px;"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgba(255, 255, 255, 0.6); bottom: 0px; margin-top: auto; margin-bottom: auto; padding-right: 5px; line-height: 0; width: 26px; height: 20px; opacity: 0;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="position: absolute; height: 100%; top: 0px; left: 0px; display: flex; flex: 1; align-self: stretch; align-items: center; justify-content: flex-start;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width: 18px; height: 18px; display: flex; align-self: center; box-shadow: none; border-radius: 50%; box-sizing: border-box; position: relative; background-color: rgb(3, 125, 214); left: 18px;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;"
|
||||||
|
type="checkbox"
|
||||||
|
value="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="toggle-button__status"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="toggle-button__label-off"
|
||||||
|
>
|
||||||
|
Off
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="toggle-button__label-on"
|
||||||
|
>
|
||||||
|
On
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="settings-page__content-row"
|
class="settings-page__content-row"
|
||||||
>
|
>
|
||||||
|
@ -14,6 +14,9 @@ import {
|
|||||||
} from '../../../helpers/utils/settings-search';
|
} from '../../../helpers/utils/settings-search';
|
||||||
import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics';
|
import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics';
|
||||||
import {
|
import {
|
||||||
|
COINGECKO_LINK,
|
||||||
|
CRYPTOCOMPARE_LINK,
|
||||||
|
PRIVACY_POLICY_LINK,
|
||||||
AUTO_DETECT_TOKEN_LEARN_MORE_LINK,
|
AUTO_DETECT_TOKEN_LEARN_MORE_LINK,
|
||||||
CONSENSYS_PRIVACY_LINK,
|
CONSENSYS_PRIVACY_LINK,
|
||||||
ETHERSCAN_PRIVACY_LINK,
|
ETHERSCAN_PRIVACY_LINK,
|
||||||
@ -45,6 +48,8 @@ export default class SecurityTab extends PureComponent {
|
|||||||
ipfsGateway: PropTypes.string.isRequired,
|
ipfsGateway: PropTypes.string.isRequired,
|
||||||
useMultiAccountBalanceChecker: PropTypes.bool.isRequired,
|
useMultiAccountBalanceChecker: PropTypes.bool.isRequired,
|
||||||
setUseMultiAccountBalanceChecker: PropTypes.func.isRequired,
|
setUseMultiAccountBalanceChecker: PropTypes.func.isRequired,
|
||||||
|
useCurrencyRateCheck: PropTypes.bool.isRequired,
|
||||||
|
setUseCurrencyRateCheck: PropTypes.func.isRequired,
|
||||||
useNftDetection: PropTypes.bool,
|
useNftDetection: PropTypes.bool,
|
||||||
setUseNftDetection: PropTypes.func,
|
setUseNftDetection: PropTypes.func,
|
||||||
setOpenSeaEnabled: PropTypes.func,
|
setOpenSeaEnabled: PropTypes.func,
|
||||||
@ -348,7 +353,7 @@ export default class SecurityTab extends PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={this.settingsRefs[7]}
|
ref={this.settingsRefs[4]}
|
||||||
className="settings-page__content-row"
|
className="settings-page__content-row"
|
||||||
data-testid="advanced-setting-gas-fee-estimation"
|
data-testid="advanced-setting-gas-fee-estimation"
|
||||||
>
|
>
|
||||||
@ -395,7 +400,7 @@ export default class SecurityTab extends PureComponent {
|
|||||||
this.props;
|
this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={this.settingsRefs[4]} className="settings-page__content-row">
|
<div ref={this.settingsRefs[8]} className="settings-page__content-row">
|
||||||
<div className="settings-page__content-item">
|
<div className="settings-page__content-item">
|
||||||
<span>{t('useMultiAccountBalanceChecker')}</span>
|
<span>{t('useMultiAccountBalanceChecker')}</span>
|
||||||
<div className="settings-page__content-description">
|
<div className="settings-page__content-description">
|
||||||
@ -437,7 +442,7 @@ export default class SecurityTab extends PureComponent {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={this.settingsRefs[9]} className="settings-page__content-row">
|
<div ref={this.settingsRefs[7]} className="settings-page__content-row">
|
||||||
<div className="settings-page__content-item">
|
<div className="settings-page__content-item">
|
||||||
<span>{t('useCollectibleDetection')}</span>
|
<span>{t('useCollectibleDetection')}</span>
|
||||||
<div className="settings-page__content-description">
|
<div className="settings-page__content-description">
|
||||||
@ -477,6 +482,57 @@ export default class SecurityTab extends PureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderCurrencyRateCheckToggle() {
|
||||||
|
const { t } = this.context;
|
||||||
|
const { useCurrencyRateCheck, setUseCurrencyRateCheck } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={this.settingsRefs[9]} className="settings-page__content-row">
|
||||||
|
<div className="settings-page__content-item">
|
||||||
|
<span>{t('currencyRateCheckToggle')}</span>
|
||||||
|
<div className="settings-page__content-description">
|
||||||
|
{t('currencyRateCheckToggleDescription', [
|
||||||
|
<a
|
||||||
|
key="coingecko_link"
|
||||||
|
href={COINGECKO_LINK}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{t('coingecko')}
|
||||||
|
</a>,
|
||||||
|
<a
|
||||||
|
key="cryptocompare_link"
|
||||||
|
href={CRYPTOCOMPARE_LINK}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{t('cryptoCompare')}
|
||||||
|
</a>,
|
||||||
|
<a
|
||||||
|
key="privacy_policy_link"
|
||||||
|
href={PRIVACY_POLICY_LINK}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{t('privacyMsg')}
|
||||||
|
</a>,
|
||||||
|
])}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="settings-page__content-item">
|
||||||
|
<div className="settings-page__content-item-col">
|
||||||
|
<ToggleButton
|
||||||
|
value={useCurrencyRateCheck}
|
||||||
|
onToggle={(value) => setUseCurrencyRateCheck(!value)}
|
||||||
|
offLabel={t('off')}
|
||||||
|
onLabel={t('on')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { warning } = this.props;
|
const { warning } = this.props;
|
||||||
|
|
||||||
@ -503,6 +559,7 @@ export default class SecurityTab extends PureComponent {
|
|||||||
{this.context.t('transactions')}
|
{this.context.t('transactions')}
|
||||||
</span>
|
</span>
|
||||||
<div className="settings-page__content-padded">
|
<div className="settings-page__content-padded">
|
||||||
|
{this.renderCurrencyRateCheckToggle()}
|
||||||
{this.renderIncomingTransactionsOptIn()}
|
{this.renderIncomingTransactionsOptIn()}
|
||||||
</div>
|
</div>
|
||||||
<span className="settings-page__security-tab-sub-header">
|
<span className="settings-page__security-tab-sub-header">
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
setUseTokenDetection,
|
setUseTokenDetection,
|
||||||
setIpfsGateway,
|
setIpfsGateway,
|
||||||
setUseMultiAccountBalanceChecker,
|
setUseMultiAccountBalanceChecker,
|
||||||
|
setUseCurrencyRateCheck,
|
||||||
setUseNftDetection,
|
setUseNftDetection,
|
||||||
setOpenSeaEnabled,
|
setOpenSeaEnabled,
|
||||||
} from '../../../store/actions';
|
} from '../../../store/actions';
|
||||||
@ -26,6 +27,7 @@ const mapStateToProps = (state) => {
|
|||||||
useTokenDetection,
|
useTokenDetection,
|
||||||
ipfsGateway,
|
ipfsGateway,
|
||||||
useMultiAccountBalanceChecker,
|
useMultiAccountBalanceChecker,
|
||||||
|
useCurrencyRateCheck,
|
||||||
} = metamask;
|
} = metamask;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -36,6 +38,7 @@ const mapStateToProps = (state) => {
|
|||||||
useTokenDetection,
|
useTokenDetection,
|
||||||
ipfsGateway,
|
ipfsGateway,
|
||||||
useMultiAccountBalanceChecker,
|
useMultiAccountBalanceChecker,
|
||||||
|
useCurrencyRateCheck,
|
||||||
useNftDetection: getUseNftDetection(state),
|
useNftDetection: getUseNftDetection(state),
|
||||||
openSeaEnabled: getOpenSeaEnabled(state),
|
openSeaEnabled: getOpenSeaEnabled(state),
|
||||||
};
|
};
|
||||||
@ -48,6 +51,7 @@ const mapDispatchToProps = (dispatch) => {
|
|||||||
setShowIncomingTransactionsFeatureFlag: (shouldShow) =>
|
setShowIncomingTransactionsFeatureFlag: (shouldShow) =>
|
||||||
dispatch(setFeatureFlag('showIncomingTransactions', shouldShow)),
|
dispatch(setFeatureFlag('showIncomingTransactions', shouldShow)),
|
||||||
setUsePhishDetect: (val) => dispatch(setUsePhishDetect(val)),
|
setUsePhishDetect: (val) => dispatch(setUsePhishDetect(val)),
|
||||||
|
setUseCurrencyRateCheck: (val) => dispatch(setUseCurrencyRateCheck(val)),
|
||||||
setUseTokenDetection: (value) => {
|
setUseTokenDetection: (value) => {
|
||||||
return dispatch(setUseTokenDetection(value));
|
return dispatch(setUseTokenDetection(value));
|
||||||
},
|
},
|
||||||
|
@ -8,12 +8,14 @@ import SecurityTab from './security-tab.container';
|
|||||||
const mockSetFeatureFlag = jest.fn();
|
const mockSetFeatureFlag = jest.fn();
|
||||||
const mockSetParticipateInMetaMetrics = jest.fn();
|
const mockSetParticipateInMetaMetrics = jest.fn();
|
||||||
const mockSetUsePhishDetect = jest.fn();
|
const mockSetUsePhishDetect = jest.fn();
|
||||||
|
const mockSetUseCurrencyRateCheck = jest.fn();
|
||||||
|
|
||||||
jest.mock('../../../store/actions.js', () => {
|
jest.mock('../../../store/actions.js', () => {
|
||||||
return {
|
return {
|
||||||
setFeatureFlag: () => mockSetFeatureFlag,
|
setFeatureFlag: () => mockSetFeatureFlag,
|
||||||
setParticipateInMetaMetrics: () => mockSetParticipateInMetaMetrics,
|
setParticipateInMetaMetrics: () => mockSetParticipateInMetaMetrics,
|
||||||
setUsePhishDetect: () => mockSetUsePhishDetect,
|
setUsePhishDetect: () => mockSetUsePhishDetect,
|
||||||
|
setUseCurrencyRateCheck: () => mockSetUseCurrencyRateCheck,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ import {
|
|||||||
getTokenList,
|
getTokenList,
|
||||||
isHardwareWallet,
|
isHardwareWallet,
|
||||||
getHardwareWalletType,
|
getHardwareWalletType,
|
||||||
|
getUseCurrencyRateCheck,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
|
|
||||||
import { getValueFromWeiHex } from '../../../helpers/utils/conversions.util';
|
import { getValueFromWeiHex } from '../../../helpers/utils/conversions.util';
|
||||||
@ -154,6 +155,7 @@ export default function BuildQuote({
|
|||||||
|
|
||||||
const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual);
|
const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual);
|
||||||
const conversionRate = useSelector(getConversionRate);
|
const conversionRate = useSelector(getConversionRate);
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
const hardwareWalletUsed = useSelector(isHardwareWallet);
|
const hardwareWalletUsed = useSelector(isHardwareWallet);
|
||||||
const hardwareWalletType = useSelector(getHardwareWalletType);
|
const hardwareWalletType = useSelector(getHardwareWalletType);
|
||||||
const smartTransactionsOptInStatus = useSelector(
|
const smartTransactionsOptInStatus = useSelector(
|
||||||
@ -255,13 +257,13 @@ export default function BuildQuote({
|
|||||||
fromTokenInputValue || 0,
|
fromTokenInputValue || 0,
|
||||||
fromTokenSymbol,
|
fromTokenSymbol,
|
||||||
{
|
{
|
||||||
showFiat: true,
|
showFiat: useCurrencyRateCheck,
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
const swapFromEthFiatValue = useEthFiatAmount(
|
const swapFromEthFiatValue = useEthFiatAmount(
|
||||||
fromTokenInputValue || 0,
|
fromTokenInputValue || 0,
|
||||||
{ showFiat: true },
|
{ showFiat: useCurrencyRateCheck },
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
const swapFromFiatValue = isSwapsDefaultTokenSymbol(fromTokenSymbol, chainId)
|
const swapFromFiatValue = isSwapsDefaultTokenSymbol(fromTokenSymbol, chainId)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { I18nContext } from '../../../contexts/i18n';
|
import { I18nContext } from '../../../contexts/i18n';
|
||||||
import InfoTooltip from '../../../components/ui/info-tooltip';
|
import InfoTooltip from '../../../components/ui/info-tooltip';
|
||||||
@ -13,6 +14,7 @@ import {
|
|||||||
} from '../../../helpers/constants/design-system';
|
} from '../../../helpers/constants/design-system';
|
||||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
import { EVENT } from '../../../../shared/constants/metametrics';
|
import { EVENT } from '../../../../shared/constants/metametrics';
|
||||||
|
import { getUseCurrencyRateCheck } from '../../../selectors';
|
||||||
|
|
||||||
const GAS_FEES_LEARN_MORE_URL =
|
const GAS_FEES_LEARN_MORE_URL =
|
||||||
'https://community.metamask.io/t/what-is-gas-why-do-transactions-take-so-long/3172';
|
'https://community.metamask.io/t/what-is-gas-why-do-transactions-take-so-long/3172';
|
||||||
@ -30,6 +32,7 @@ export default function FeeCard({
|
|||||||
isBestQuote,
|
isBestQuote,
|
||||||
}) {
|
}) {
|
||||||
const t = useContext(I18nContext);
|
const t = useContext(I18nContext);
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
const getTranslatedNetworkName = () => {
|
const getTranslatedNetworkName = () => {
|
||||||
@ -112,9 +115,10 @@ export default function FeeCard({
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
detailText={primaryFee.fee}
|
detailText={primaryFee.fee}
|
||||||
detailTotal={secondaryFee.fee}
|
detailTotal={useCurrencyRateCheck && secondaryFee.fee}
|
||||||
subText={
|
subText={
|
||||||
secondaryFee?.maxFee !== undefined && (
|
(secondaryFee?.maxFee !== undefined ||
|
||||||
|
primaryFee?.maxFee !== undefined) && (
|
||||||
<>
|
<>
|
||||||
<Typography
|
<Typography
|
||||||
as="span"
|
as="span"
|
||||||
@ -124,7 +128,9 @@ export default function FeeCard({
|
|||||||
>
|
>
|
||||||
{t('maxFee')}
|
{t('maxFee')}
|
||||||
</Typography>
|
</Typography>
|
||||||
{`: ${secondaryFee.maxFee}`}
|
{useCurrencyRateCheck
|
||||||
|
? `: ${secondaryFee.maxFee}`
|
||||||
|
: `: ${primaryFee.maxFee}`}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import configureMockStore from 'redux-mock-store';
|
|
||||||
import thunk from 'redux-thunk';
|
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
renderWithProvider,
|
renderWithProvider,
|
||||||
createSwapsMockStore,
|
|
||||||
setBackgroundConnection,
|
setBackgroundConnection,
|
||||||
MOCKS,
|
MOCKS,
|
||||||
fireEvent,
|
fireEvent,
|
||||||
} from '../../../../test/jest';
|
} from '../../../../test/jest';
|
||||||
import { CHAIN_IDS } from '../../../../shared/constants/network';
|
import { CHAIN_IDS } from '../../../../shared/constants/network';
|
||||||
|
|
||||||
import { checkNetworkAndAccountSupports1559 } from '../../../selectors';
|
import {
|
||||||
|
checkNetworkAndAccountSupports1559,
|
||||||
|
getUseCurrencyRateCheck,
|
||||||
|
} from '../../../selectors';
|
||||||
import {
|
import {
|
||||||
getGasEstimateType,
|
getGasEstimateType,
|
||||||
getGasFeeEstimates,
|
getGasFeeEstimates,
|
||||||
@ -22,8 +22,6 @@ import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../helpers/constants/tran
|
|||||||
|
|
||||||
import FeeCard from '.';
|
import FeeCard from '.';
|
||||||
|
|
||||||
const middleware = [thunk];
|
|
||||||
|
|
||||||
jest.mock('../../../hooks/useGasFeeEstimates', () => ({
|
jest.mock('../../../hooks/useGasFeeEstimates', () => ({
|
||||||
useGasFeeEstimates: jest.fn(),
|
useGasFeeEstimates: jest.fn(),
|
||||||
}));
|
}));
|
||||||
@ -50,6 +48,9 @@ const generateUseSelectorRouter = () => (selector) => {
|
|||||||
if (selector === getIsGasEstimatesLoading) {
|
if (selector === getIsGasEstimatesLoading) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (selector === getUseCurrencyRateCheck) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,13 +110,12 @@ describe('FeeCard', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders the component with EIP-1559 enabled', () => {
|
it('renders the component with EIP-1559 enabled', () => {
|
||||||
const store = configureMockStore(middleware)(createSwapsMockStore());
|
|
||||||
const props = createProps({
|
const props = createProps({
|
||||||
networkAndAccountSupports1559: true,
|
networkAndAccountSupports1559: true,
|
||||||
maxPriorityFeePerGasDecGWEI: '3',
|
maxPriorityFeePerGasDecGWEI: '3',
|
||||||
maxFeePerGasDecGWEI: '4',
|
maxFeePerGasDecGWEI: '4',
|
||||||
});
|
});
|
||||||
const { getByText } = renderWithProvider(<FeeCard {...props} />, store);
|
const { getByText } = renderWithProvider(<FeeCard {...props} />);
|
||||||
expect(getByText('Best of 6 quotes.')).toBeInTheDocument();
|
expect(getByText('Best of 6 quotes.')).toBeInTheDocument();
|
||||||
expect(getByText('Estimated gas fee')).toBeInTheDocument();
|
expect(getByText('Estimated gas fee')).toBeInTheDocument();
|
||||||
expect(getByText('Max fee')).toBeInTheDocument();
|
expect(getByText('Max fee')).toBeInTheDocument();
|
||||||
@ -129,7 +129,6 @@ describe('FeeCard', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders the component with smart transactions enabled and user opted in', () => {
|
it('renders the component with smart transactions enabled and user opted in', () => {
|
||||||
const store = configureMockStore(middleware)(createSwapsMockStore());
|
|
||||||
const props = createProps({
|
const props = createProps({
|
||||||
smartTransactionsOptInStatus: true,
|
smartTransactionsOptInStatus: true,
|
||||||
smartTransactionsEnabled: true,
|
smartTransactionsEnabled: true,
|
||||||
@ -138,7 +137,6 @@ describe('FeeCard', () => {
|
|||||||
});
|
});
|
||||||
const { getByText, queryByTestId } = renderWithProvider(
|
const { getByText, queryByTestId } = renderWithProvider(
|
||||||
<FeeCard {...props} />,
|
<FeeCard {...props} />,
|
||||||
store,
|
|
||||||
);
|
);
|
||||||
expect(getByText('Best of 6 quotes.')).toBeInTheDocument();
|
expect(getByText('Best of 6 quotes.')).toBeInTheDocument();
|
||||||
expect(getByText('Estimated gas fee')).toBeInTheDocument();
|
expect(getByText('Estimated gas fee')).toBeInTheDocument();
|
||||||
@ -149,20 +147,18 @@ describe('FeeCard', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders the component with hidden token approval row', () => {
|
it('renders the component with hidden token approval row', () => {
|
||||||
const store = configureMockStore(middleware)(createSwapsMockStore());
|
|
||||||
const props = createProps({
|
const props = createProps({
|
||||||
hideTokenApprovalRow: true,
|
hideTokenApprovalRow: true,
|
||||||
});
|
});
|
||||||
const { queryByText } = renderWithProvider(<FeeCard {...props} />, store);
|
const { queryByText } = renderWithProvider(<FeeCard {...props} />);
|
||||||
expect(queryByText('Edit limit')).not.toBeInTheDocument();
|
expect(queryByText('Edit limit')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('approves a token', () => {
|
it('approves a token', () => {
|
||||||
const store = configureMockStore(middleware)(createSwapsMockStore());
|
|
||||||
const props = createProps({
|
const props = createProps({
|
||||||
onTokenApprovalClick: jest.fn(),
|
onTokenApprovalClick: jest.fn(),
|
||||||
});
|
});
|
||||||
const { queryByText } = renderWithProvider(<FeeCard {...props} />, store);
|
const { queryByText } = renderWithProvider(<FeeCard {...props} />);
|
||||||
fireEvent.click(queryByText('Edit limit'));
|
fireEvent.click(queryByText('Edit limit'));
|
||||||
expect(props.onTokenApprovalClick).toHaveBeenCalled();
|
expect(props.onTokenApprovalClick).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@ import { I18nContext } from '../../../../contexts/i18n';
|
|||||||
import {
|
import {
|
||||||
getCurrentChainId,
|
getCurrentChainId,
|
||||||
getRpcPrefsForCurrentProvider,
|
getRpcPrefsForCurrentProvider,
|
||||||
|
getUseCurrencyRateCheck,
|
||||||
} from '../../../../selectors';
|
} from '../../../../selectors';
|
||||||
import { EVENT } from '../../../../../shared/constants/metametrics';
|
import { EVENT } from '../../../../../shared/constants/metametrics';
|
||||||
import { SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP } from '../../../../../shared/constants/swaps';
|
import { SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP } from '../../../../../shared/constants/swaps';
|
||||||
@ -36,7 +37,7 @@ export default function ItemList({
|
|||||||
rpcPrefs.blockExplorerUrl ??
|
rpcPrefs.blockExplorerUrl ??
|
||||||
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId] ??
|
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId] ??
|
||||||
null;
|
null;
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
const blockExplorerHostName = getURLHostName(blockExplorerLink);
|
const blockExplorerHostName = getURLHostName(blockExplorerLink);
|
||||||
const trackEvent = useContext(MetaMetricsContext);
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
|
||||||
@ -124,7 +125,7 @@ export default function ItemList({
|
|||||||
{rightPrimaryLabel}
|
{rightPrimaryLabel}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
{rightSecondaryLabel ? (
|
{rightSecondaryLabel && useCurrencyRateCheck ? (
|
||||||
<span className="searchable-item-list__right-secondary-label">
|
<span className="searchable-item-list__right-secondary-label">
|
||||||
{rightSecondaryLabel}
|
{rightSecondaryLabel}
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { I18nContext } from '../../../../contexts/i18n';
|
import { I18nContext } from '../../../../contexts/i18n';
|
||||||
import InfoTooltip from '../../../../components/ui/info-tooltip';
|
import InfoTooltip from '../../../../components/ui/info-tooltip';
|
||||||
import ExchangeRateDisplay from '../../exchange-rate-display';
|
import ExchangeRateDisplay from '../../exchange-rate-display';
|
||||||
|
import { getUseCurrencyRateCheck } from '../../../../selectors';
|
||||||
|
|
||||||
const QuoteDetails = ({
|
const QuoteDetails = ({
|
||||||
slippage,
|
slippage,
|
||||||
@ -18,6 +20,8 @@ const QuoteDetails = ({
|
|||||||
hideEstimatedGasFee,
|
hideEstimatedGasFee,
|
||||||
}) => {
|
}) => {
|
||||||
const t = useContext(I18nContext);
|
const t = useContext(I18nContext);
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="quote-details">
|
<div className="quote-details">
|
||||||
<div className="quote-details__row">
|
<div className="quote-details__row">
|
||||||
@ -67,7 +71,9 @@ const QuoteDetails = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="quote-details__detail-content">
|
<div className="quote-details__detail-content">
|
||||||
<span>{feeInEth}</span>
|
<span>{feeInEth}</span>
|
||||||
<span className="quote-details__light-grey">{` (${networkFees})`}</span>
|
<span className="quote-details__light-grey">
|
||||||
|
{useCurrencyRateCheck && ` (${networkFees})`}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { renderWithProvider } from '../../../../test/jest';
|
import { renderWithProvider } from '../../../../test/jest';
|
||||||
|
import configureStore from '../../../store/store';
|
||||||
|
import mockState from '../../../../test/data/mock-state.json';
|
||||||
import SelectQuotePopover from '.';
|
import SelectQuotePopover from '.';
|
||||||
|
|
||||||
const createProps = (customProps = {}) => {
|
const createProps = (customProps = {}) => {
|
||||||
@ -14,11 +16,13 @@ const createProps = (customProps = {}) => {
|
|||||||
...customProps,
|
...customProps,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
const store = configureStore(mockState);
|
||||||
|
|
||||||
describe('SelectQuotePopover', () => {
|
describe('SelectQuotePopover', () => {
|
||||||
it('renders the component with initial props', () => {
|
it('renders the component with initial props', () => {
|
||||||
const { container } = renderWithProvider(
|
const { container } = renderWithProvider(
|
||||||
<SelectQuotePopover {...createProps()} />,
|
<SelectQuotePopover {...createProps()} />,
|
||||||
|
store,
|
||||||
);
|
);
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useContext, useMemo } from 'react';
|
import React, { useState, useContext, useMemo } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
@ -6,6 +7,7 @@ import SunCheckIcon from '../../../../components/ui/icon/sun-check-icon.componen
|
|||||||
import { I18nContext } from '../../../../contexts/i18n';
|
import { I18nContext } from '../../../../contexts/i18n';
|
||||||
import { QUOTE_DATA_ROWS_PROPTYPES_SHAPE } from '../select-quote-popover-constants';
|
import { QUOTE_DATA_ROWS_PROPTYPES_SHAPE } from '../select-quote-popover-constants';
|
||||||
import InfoTooltip from '../../../../components/ui/info-tooltip';
|
import InfoTooltip from '../../../../components/ui/info-tooltip';
|
||||||
|
import { getUseCurrencyRateCheck } from '../../../../selectors';
|
||||||
|
|
||||||
const ToggleArrows = () => (
|
const ToggleArrows = () => (
|
||||||
<svg
|
<svg
|
||||||
@ -36,6 +38,7 @@ export default function SortList({
|
|||||||
}) {
|
}) {
|
||||||
const t = useContext(I18nContext);
|
const t = useContext(I18nContext);
|
||||||
const [noRowHover, setRowNowHover] = useState(false);
|
const [noRowHover, setRowNowHover] = useState(false);
|
||||||
|
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||||
|
|
||||||
const onColumnHeaderClick = (nextSortColumn) => {
|
const onColumnHeaderClick = (nextSortColumn) => {
|
||||||
if (nextSortColumn === sortColumn) {
|
if (nextSortColumn === sortColumn) {
|
||||||
@ -100,7 +103,7 @@ export default function SortList({
|
|||||||
data-testid="select-quote-popover__network-fees-header"
|
data-testid="select-quote-popover__network-fees-header"
|
||||||
onClick={() => onColumnHeaderClick('rawNetworkFees')}
|
onClick={() => onColumnHeaderClick('rawNetworkFees')}
|
||||||
>
|
>
|
||||||
{!hideEstimatedGasFee && (
|
{!hideEstimatedGasFee && useCurrencyRateCheck && (
|
||||||
<>
|
<>
|
||||||
<span>{t('swapEstimatedNetworkFees')}</span>
|
<span>{t('swapEstimatedNetworkFees')}</span>
|
||||||
<InfoTooltip
|
<InfoTooltip
|
||||||
@ -161,7 +164,7 @@ export default function SortList({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="select-quote-popover__network-fees">
|
<div className="select-quote-popover__network-fees">
|
||||||
{!hideEstimatedGasFee && networkFees}
|
{!hideEstimatedGasFee && useCurrencyRateCheck && networkFees}
|
||||||
</div>
|
</div>
|
||||||
<div className="select-quote-popover__quote-source">
|
<div className="select-quote-popover__quote-source">
|
||||||
<div
|
<div
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { renderWithProvider, fireEvent } from '../../../../../test/jest';
|
import { renderWithProvider, fireEvent } from '../../../../../test/jest';
|
||||||
|
import MockState from '../../../../../test/data/mock-state.json';
|
||||||
|
import configureStore from '../../../../store/store';
|
||||||
import SortList from './sort-list';
|
import SortList from './sort-list';
|
||||||
|
|
||||||
jest.mock(
|
jest.mock(
|
||||||
@ -71,8 +73,12 @@ const createProps = (customProps = {}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('SortList', () => {
|
describe('SortList', () => {
|
||||||
|
const store = configureStore(MockState);
|
||||||
it('renders the component with initial props', () => {
|
it('renders the component with initial props', () => {
|
||||||
const { getByText } = renderWithProvider(<SortList {...createProps()} />);
|
const { getByText } = renderWithProvider(
|
||||||
|
<SortList {...createProps()} />,
|
||||||
|
store,
|
||||||
|
);
|
||||||
expect(getByText('$15.25')).toBeInTheDocument();
|
expect(getByText('$15.25')).toBeInTheDocument();
|
||||||
expect(getByText('$14.26')).toBeInTheDocument();
|
expect(getByText('$14.26')).toBeInTheDocument();
|
||||||
expect(getByText('$13.27')).toBeInTheDocument();
|
expect(getByText('$13.27')).toBeInTheDocument();
|
||||||
@ -89,28 +95,28 @@ describe('SortList', () => {
|
|||||||
|
|
||||||
it('clicks on the "destinationTokenValue" header', () => {
|
it('clicks on the "destinationTokenValue" header', () => {
|
||||||
const props = createProps();
|
const props = createProps();
|
||||||
const { getByTestId } = renderWithProvider(<SortList {...props} />);
|
const { getByTestId } = renderWithProvider(<SortList {...props} />, store);
|
||||||
fireEvent.click(getByTestId('select-quote-popover__receiving'));
|
fireEvent.click(getByTestId('select-quote-popover__receiving'));
|
||||||
expect(props.setSortColumn).toHaveBeenCalledWith('destinationTokenValue');
|
expect(props.setSortColumn).toHaveBeenCalledWith('destinationTokenValue');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clicks on the "rawNetworkFees" header', () => {
|
it('clicks on the "rawNetworkFees" header', () => {
|
||||||
const props = createProps();
|
const props = createProps();
|
||||||
const { getByTestId } = renderWithProvider(<SortList {...props} />);
|
const { getByTestId } = renderWithProvider(<SortList {...props} />, store);
|
||||||
fireEvent.click(getByTestId('select-quote-popover__network-fees-header'));
|
fireEvent.click(getByTestId('select-quote-popover__network-fees-header'));
|
||||||
expect(props.setSortColumn).toHaveBeenCalledWith('rawNetworkFees');
|
expect(props.setSortColumn).toHaveBeenCalledWith('rawNetworkFees');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clicks on the first aggregator', () => {
|
it('clicks on the first aggregator', () => {
|
||||||
const props = createProps();
|
const props = createProps();
|
||||||
const { getByTestId } = renderWithProvider(<SortList {...props} />);
|
const { getByTestId } = renderWithProvider(<SortList {...props} />, store);
|
||||||
fireEvent.click(getByTestId('select-quote-popover-row-0'));
|
fireEvent.click(getByTestId('select-quote-popover-row-0'));
|
||||||
expect(props.onSelect).toHaveBeenCalledWith('Agg1');
|
expect(props.onSelect).toHaveBeenCalledWith('Agg1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clicks on a caret for the first aggregator', () => {
|
it('clicks on a caret for the first aggregator', () => {
|
||||||
const props = createProps();
|
const props = createProps();
|
||||||
const { getByTestId } = renderWithProvider(<SortList {...props} />);
|
const { getByTestId } = renderWithProvider(<SortList {...props} />, store);
|
||||||
fireEvent.click(getByTestId('select-quote-popover__caret-right-0'));
|
fireEvent.click(getByTestId('select-quote-popover__caret-right-0'));
|
||||||
expect(props.onCaretClick).toHaveBeenCalledWith('Agg1');
|
expect(props.onCaretClick).toHaveBeenCalledWith('Agg1');
|
||||||
});
|
});
|
||||||
|
@ -586,9 +586,12 @@ export function getShouldShowFiat(state) {
|
|||||||
const isMainNet = getIsMainnet(state);
|
const isMainNet = getIsMainnet(state);
|
||||||
const isCustomNetwork = getIsCustomNetwork(state);
|
const isCustomNetwork = getIsCustomNetwork(state);
|
||||||
const conversionRate = getConversionRate(state);
|
const conversionRate = getConversionRate(state);
|
||||||
|
const useCurrencyRateCheck = getUseCurrencyRateCheck(state);
|
||||||
const { showFiatInTestnets } = getPreferences(state);
|
const { showFiatInTestnets } = getPreferences(state);
|
||||||
return Boolean(
|
return Boolean(
|
||||||
(isMainNet || isCustomNetwork || showFiatInTestnets) && conversionRate,
|
(isMainNet || isCustomNetwork || showFiatInTestnets) &&
|
||||||
|
useCurrencyRateCheck &&
|
||||||
|
conversionRate,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1388,3 +1391,13 @@ export function getShouldShowSeedPhraseReminder(state) {
|
|||||||
export function getCustomTokenAmount(state) {
|
export function getCustomTokenAmount(state) {
|
||||||
return state.appState.customTokenAmount;
|
return state.appState.customTokenAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To get the useCurrencyRateCheck flag which to check if the user prefers currency conversion
|
||||||
|
*
|
||||||
|
* @param {*} state
|
||||||
|
* @returns Boolean
|
||||||
|
*/
|
||||||
|
export function getUseCurrencyRateCheck(state) {
|
||||||
|
return Boolean(state.metamask.useCurrencyRateCheck);
|
||||||
|
}
|
||||||
|
@ -263,4 +263,9 @@ describe('Selectors', () => {
|
|||||||
mockState.metamask.notifications.test,
|
mockState.metamask.notifications.test,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('#getUseCurrencyRateCheck', () => {
|
||||||
|
const useCurrencyRateCheck = selectors.getUseCurrencyRateCheck(mockState);
|
||||||
|
expect(useCurrencyRateCheck).toStrictEqual(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -2748,6 +2748,19 @@ export function setUseNftDetection(val) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setUseCurrencyRateCheck(val) {
|
||||||
|
return (dispatch) => {
|
||||||
|
dispatch(showLoadingIndication());
|
||||||
|
log.debug(`background.setUseCurrencyRateCheck`);
|
||||||
|
callBackgroundMethod('setUseCurrencyRateCheck', [val], (err) => {
|
||||||
|
dispatch(hideLoadingIndication());
|
||||||
|
if (err) {
|
||||||
|
dispatch(displayWarning(err.message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function setOpenSeaEnabled(val) {
|
export function setOpenSeaEnabled(val) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
dispatch(showLoadingIndication());
|
dispatch(showLoadingIndication());
|
||||||
|
43
yarn.lock
43
yarn.lock
@ -3293,20 +3293,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@metamask/assets-controllers@npm:^1.0.1":
|
"@metamask/assets-controllers@npm:^3.0.1":
|
||||||
version: 1.0.1
|
version: 3.0.1
|
||||||
resolution: "@metamask/assets-controllers@npm:1.0.1"
|
resolution: "@metamask/assets-controllers@npm:3.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@ethersproject/abi": ^5.7.0
|
"@ethersproject/abi": ^5.7.0
|
||||||
"@ethersproject/bignumber": ^5.7.0
|
"@ethersproject/bignumber": ^5.7.0
|
||||||
"@ethersproject/contracts": ^5.7.0
|
"@ethersproject/contracts": ^5.7.0
|
||||||
"@ethersproject/providers": ^5.7.0
|
"@ethersproject/providers": ^5.7.0
|
||||||
"@metamask/base-controller": ~1.1.0
|
"@metamask/base-controller": ^1.1.1
|
||||||
"@metamask/contract-metadata": ^1.35.0
|
"@metamask/contract-metadata": ^2.1.0
|
||||||
"@metamask/controller-utils": ~1.0.0
|
"@metamask/controller-utils": ^1.0.0
|
||||||
"@metamask/metamask-eth-abis": 3.0.0
|
"@metamask/metamask-eth-abis": 3.0.0
|
||||||
"@metamask/network-controller": ~1.0.0
|
"@metamask/network-controller": ^2.0.0
|
||||||
"@metamask/preferences-controller": ~1.0.0
|
"@metamask/preferences-controller": ^1.0.1
|
||||||
"@types/uuid": ^8.3.0
|
"@types/uuid": ^8.3.0
|
||||||
abort-controller: ^3.0.0
|
abort-controller: ^3.0.0
|
||||||
async-mutex: ^0.2.6
|
async-mutex: ^0.2.6
|
||||||
@ -3318,7 +3318,9 @@ __metadata:
|
|||||||
multiformats: ^9.5.2
|
multiformats: ^9.5.2
|
||||||
single-call-balance-checker-abi: ^1.0.0
|
single-call-balance-checker-abi: ^1.0.0
|
||||||
uuid: ^8.3.2
|
uuid: ^8.3.2
|
||||||
checksum: 678f32126aa84de769065581661218a247166ef2e4918290a8e082dd9c7b175d84c5a4d4f431c884dc83201b183f324c2b5047bc69a2ea7825d710470cae5f87
|
peerDependencies:
|
||||||
|
"@metamask/network-controller": ^2.0.0
|
||||||
|
checksum: c356a820929738e3ad83a5cfe20993a1e7c4dac6835b308d8cb32efe8542c339664ae3046a1dedce6ee2a4c45cec5528015309366fa96674837dca7ea001998f
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -3336,7 +3338,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@metamask/base-controller@npm:^1.0.0, @metamask/base-controller@npm:^1.1.1, @metamask/base-controller@npm:~1.1.0":
|
"@metamask/base-controller@npm:^1.0.0, @metamask/base-controller@npm:^1.1.1":
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
resolution: "@metamask/base-controller@npm:1.1.1"
|
resolution: "@metamask/base-controller@npm:1.1.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -3375,13 +3377,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@metamask/contract-metadata@npm:^1.35.0":
|
|
||||||
version: 1.36.0
|
|
||||||
resolution: "@metamask/contract-metadata@npm:1.36.0"
|
|
||||||
checksum: 6b1bc0927536a7ed235f896dcb0dabbce1f7853eef5e58efdd6cc8294c2ef10dd0c46572d20df9df31563fb466a0a162101169d9e1595dd931c7eabb9fa5a7e9
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@metamask/contract-metadata@npm:^2.1.0":
|
"@metamask/contract-metadata@npm:^2.1.0":
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
resolution: "@metamask/contract-metadata@npm:2.1.0"
|
resolution: "@metamask/contract-metadata@npm:2.1.0"
|
||||||
@ -3767,13 +3762,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@metamask/preferences-controller@npm:~1.0.0":
|
"@metamask/preferences-controller@npm:^1.0.1":
|
||||||
version: 1.0.0
|
version: 1.0.1
|
||||||
resolution: "@metamask/preferences-controller@npm:1.0.0"
|
resolution: "@metamask/preferences-controller@npm:1.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@metamask/base-controller": ~1.0.0
|
"@metamask/base-controller": ^1.1.1
|
||||||
"@metamask/controller-utils": ~1.0.0
|
"@metamask/controller-utils": ^1.0.0
|
||||||
checksum: dad15bf468031df470ebeb18fa71c8181f247f9c9fd2eac52f6ee71f77bda61d8b0b7f8dc492d4f4f1602e249dedc38360b5e90ca2902adbcbd7c56bbaec8282
|
checksum: 3ad7dcf40cc1dc6679d37f705418d4d18da2acce120ce6bd09b0e6755484d193139fd85cf2c0b7374d867ab8a03d7f5bc74ebc8c2cdc003d5872f33d34c1e965
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -22758,7 +22753,7 @@ __metadata:
|
|||||||
"@metamask/address-book-controller": ^1.0.0
|
"@metamask/address-book-controller": ^1.0.0
|
||||||
"@metamask/announcement-controller": ^1.0.0
|
"@metamask/announcement-controller": ^1.0.0
|
||||||
"@metamask/approval-controller": ^1.0.0
|
"@metamask/approval-controller": ^1.0.0
|
||||||
"@metamask/assets-controllers": ^1.0.1
|
"@metamask/assets-controllers": ^3.0.1
|
||||||
"@metamask/auto-changelog": ^2.1.0
|
"@metamask/auto-changelog": ^2.1.0
|
||||||
"@metamask/base-controller": ^1.0.0
|
"@metamask/base-controller": ^1.0.0
|
||||||
"@metamask/contract-metadata": ^2.1.0
|
"@metamask/contract-metadata": ^2.1.0
|
||||||
|
Loading…
Reference in New Issue
Block a user