diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index f49c27df8..9883154e1 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1836,6 +1836,12 @@ "swapConfirmWithHwWallet": { "message": "Confirm with your hardware wallet" }, + "swapContractDataDisabledErrorDescription": { + "message": "In the Ethereum app on your Ledger, go to \"Settings\" and allow contract data. Then, try your swap again." + }, + "swapContractDataDisabledErrorTitle": { + "message": "Contract data is not enabled on your Ledger" + }, "swapCustom": { "message": "custom" }, diff --git a/shared/constants/swaps.js b/shared/constants/swaps.js index 3f345542b..2843821e5 100644 --- a/shared/constants/swaps.js +++ b/shared/constants/swaps.js @@ -12,6 +12,7 @@ export const QUOTES_EXPIRED_ERROR = 'quotes-expired'; export const SWAP_FAILED_ERROR = 'swap-failed-error'; export const ERROR_FETCHING_QUOTES = 'error-fetching-quotes'; export const QUOTES_NOT_AVAILABLE_ERROR = 'quotes-not-avilable'; +export const CONTRACT_DATA_DISABLED_ERROR = 'contract-data-disabled'; export const OFFLINE_FOR_MAINTENANCE = 'offline-for-maintenance'; export const SWAPS_FETCH_ORDER_CONFLICT = 'swaps-fetch-order-conflict'; diff --git a/ui/ducks/swaps/swaps.js b/ui/ducks/swaps/swaps.js index 3b145a218..a08424869 100644 --- a/ui/ducks/swaps/swaps.js +++ b/ui/ducks/swaps/swaps.js @@ -59,6 +59,7 @@ import { import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, + CONTRACT_DATA_DISABLED_ERROR, SWAP_FAILED_ERROR, SWAPS_FETCH_ORDER_CONFLICT, } from '../../../shared/constants/swaps'; @@ -785,7 +786,10 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { try { await dispatch(updateAndApproveTx(finalTradeTxMeta, true)); } catch (e) { - await dispatch(setSwapsErrorKey(SWAP_FAILED_ERROR)); + const errorKey = e.message.includes('EthAppPleaseEnableContractData') + ? CONTRACT_DATA_DISABLED_ERROR + : SWAP_FAILED_ERROR; + await dispatch(setSwapsErrorKey(errorKey)); history.push(SWAPS_ERROR_ROUTE); return; } diff --git a/ui/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/pages/swaps/awaiting-swap/awaiting-swap.js index 8c0ab018a..6cd28fff3 100644 --- a/ui/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/pages/swaps/awaiting-swap/awaiting-swap.js @@ -33,6 +33,7 @@ import { SWAP_FAILED_ERROR, ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, + CONTRACT_DATA_DISABLED_ERROR, OFFLINE_FOR_MAINTENANCE, SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP, } from '../../../../shared/constants/swaps'; @@ -184,6 +185,11 @@ export default function AwaitingSwap({ descriptionText = t('swapQuotesNotAvailableErrorDescription'); submitText = t('tryAgain'); statusImage = ; + } else if (errorKey === CONTRACT_DATA_DISABLED_ERROR) { + headerText = t('swapContractDataDisabledErrorTitle'); + descriptionText = t('swapContractDataDisabledErrorDescription'); + submitText = t('tryAgain'); + statusImage = ; } else if (!errorKey && !swapComplete) { headerText = t('swapProcessing'); statusImage = ; @@ -283,6 +289,7 @@ AwaitingSwap.propTypes = { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, OFFLINE_FOR_MAINTENANCE, + CONTRACT_DATA_DISABLED_ERROR, ]), submittingSwap: PropTypes.bool, inputValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), diff --git a/ui/pages/swaps/index.js b/ui/pages/swaps/index.js index c70da9bf2..05a0d6d42 100644 --- a/ui/pages/swaps/index.js +++ b/ui/pages/swaps/index.js @@ -48,6 +48,7 @@ import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, SWAP_FAILED_ERROR, + CONTRACT_DATA_DISABLED_ERROR, OFFLINE_FOR_MAINTENANCE, } from '../../../shared/constants/swaps'; @@ -136,7 +137,7 @@ export default function Swap() { tradeTxData?.txReceipt?.status === '0x0'; const conversionError = approveError || tradeError; - if (conversionError) { + if (conversionError && swapsErrorKey !== CONTRACT_DATA_DISABLED_ERROR) { swapsErrorKey = SWAP_FAILED_ERROR; }