Use correct block explorer name and link in swaps when on custom network (#10743)

* Use correct block explorer name and link in swaps when on custom network.

* Fix up custom etherscan link code in build-quote.js

* Use blockExplorerUrl hostname instead of 'blockExplorerBaseUrl'

* Use correct etherscan-link method for token links in build-quote

* Create correct token link in build-quote for mainnet AND custom networks

* Block explorer url improvements in awaiting-swap.js and build-quote.js

* Use swapVerifyTokenExplanation message with substitutable block explorer for all applicable locales

* Ensure that block explorer links are not shown in awaiting-swap if no url is available
feature/default_network_editable
Dan J Miller 4 years ago committed by GitHub
parent 254164aec4
commit d8fd4b8271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/_locales/en/messages.json
  2. 3
      app/_locales/es/messages.json
  3. 3
      app/_locales/es_419/messages.json
  4. 3
      app/_locales/hi/messages.json
  5. 3
      app/_locales/id/messages.json
  6. 3
      app/_locales/it/messages.json
  7. 3
      app/_locales/ja/messages.json
  8. 3
      app/_locales/ko/messages.json
  9. 3
      app/_locales/ru/messages.json
  10. 3
      app/_locales/tl/messages.json
  11. 3
      app/_locales/vi/messages.json
  12. 3
      app/_locales/zh_CN/messages.json
  13. 6
      shared/constants/swaps.js
  14. 27
      ui/app/pages/swaps/awaiting-swap/awaiting-swap.js
  15. 2
      ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/view-on-ether-scan-link.js
  16. 99
      ui/app/pages/swaps/build-quote/build-quote.js

@ -1937,7 +1937,8 @@
"message": "Using the best quote"
},
"swapVerifyTokenExplanation": {
"message": "Multiple tokens can use the same name and symbol. Check Etherscan to verify this is the token you're looking for."
"message": "Multiple tokens can use the same name and symbol. Check $1 to verify this is the token you're looking for.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "View $1"

@ -1805,7 +1805,8 @@
"message": "Utilizando la mejor cotización"
},
"swapVerifyTokenExplanation": {
"message": "Varios tokens pueden usar el mismo nombre y símbolo. Verifique Etherscan para verificar que este es el token que está buscando."
"message": "Varios tokens pueden usar el mismo nombre y símbolo. Verifique $1 para verificar que este es el token que está buscando.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "Ver $1"

@ -1805,7 +1805,8 @@
"message": "Utilizando la mejor cotización"
},
"swapVerifyTokenExplanation": {
"message": "Varios tokens pueden usar el mismo nombre y símbolo. Verifique Etherscan para verificar que este es el token que está buscando."
"message": "Varios tokens pueden usar el mismo nombre y símbolo. Verifique $1 para verificar que este es el token que está buscando.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "Ver $1"

@ -1772,7 +1772,8 @@
"message": "अजत"
},
"swapVerifyTokenExplanation": {
"message": "एकिक टकन एक हम और परतक क उपयग कर सकत। यह सतित करनिए Etherscan कच करि यह वहकन ह, जिसक आप तलश कर रह।"
"message": "एकिक टकन एक हम और परतक क उपयग कर सकत। यह सतित करनिए $1 कच करि यह वहकन ह, जिसक आप तलश कर रह।",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "$1 द"

@ -1772,7 +1772,8 @@
"message": "Tidak diketahui"
},
"swapVerifyTokenExplanation": {
"message": "Beberapa token dapat menggunakan simbol dan nama yang sama. Periksa Etherscan untuk memverifikasi inilah token yang Anda cari."
"message": "Beberapa token dapat menggunakan simbol dan nama yang sama. Periksa $1 untuk memverifikasi inilah token yang Anda cari.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "Lihat $1"

@ -1828,7 +1828,8 @@
"message": "Quotazione migliore"
},
"swapVerifyTokenExplanation": {
"message": "Più token possono usare lo stesso nome e simbolo. Verifica su Etherscan che questo sia il token che stai cercando."
"message": "Più token possono usare lo stesso nome e simbolo. Verifica su $1 che questo sia il token che stai cercando.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "Vedi $1"

@ -1805,7 +1805,8 @@
"message": "最適な見積を使用する"
},
"swapVerifyTokenExplanation": {
"message": "複数のトークンが同じ名前とシンボルであることがあります。Etherscanで実際のトークンでを確認してください。"
"message": "複数のトークンが同じ名前とシンボルであることがあります。$1で実際のトークンでを確認してください。",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "$1 を表示"

@ -1769,7 +1769,8 @@
"message": "알 수 없음"
},
"swapVerifyTokenExplanation": {
"message": "여러 토큰이 같은 이름과 기호를 사용할 수 있습니다. Etherscan을 확인하여 이것이 원하는 토큰인지 확인하세요."
"message": "여러 토큰이 같은 이름과 기호를 사용할 수 있습니다. $1을 확인하여 이것이 원하는 토큰인지 확인하세요.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "$1 보기"

@ -1772,7 +1772,8 @@
"message": "Неизвестный"
},
"swapVerifyTokenExplanation": {
"message": "Несколько токенов могут использовать одно и то же имя и символ. Проверьте Etherscan, чтобы убедиться, что это именно тот токен, который вы ищете."
"message": "Несколько токенов могут использовать одно и то же имя и символ. Проверьте $1, чтобы убедиться, что это именно тот токен, который вы ищете.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "Просмотреть $1"

@ -1769,7 +1769,8 @@
"message": "Hindi Alam"
},
"swapVerifyTokenExplanation": {
"message": "Maaaring gamitin ng maraming token ang iisang pangalan at simbolo. Suriin ang Etherscan para ma-verify na ito ang token na hinahanap mo."
"message": "Maaaring gamitin ng maraming token ang iisang pangalan at simbolo. Suriin ang $1 para ma-verify na ito ang token na hinahanap mo.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "Tingnan ang $1"

@ -1772,7 +1772,8 @@
"message": "Không xác định"
},
"swapVerifyTokenExplanation": {
"message": "Nhiều token có thể dùng cùng một tên và ký hiệu. Hãy kiểm tra trên Etherscan để xác minh xem đây có phải là token bạn đang tìm kiếm không."
"message": "Nhiều token có thể dùng cùng một tên và ký hiệu. Hãy kiểm tra trên $1 để xác minh xem đây có phải là token bạn đang tìm kiếm không.",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "Xem $1"

@ -1805,7 +1805,8 @@
"message": "使用最好的报价"
},
"swapVerifyTokenExplanation": {
"message": "多个代币可以使用相同的名称和符号。检查 Etherscan(以太坊浏览器)以确认这是您正在寻找的代币。"
"message": "多个代币可以使用相同的名称和符号。检查 $1(以太坊浏览器)以确认这是您正在寻找的代币。",
"description": "This appears in a tooltip next to the verifyThisTokenOn message. It gives the user more information about why they should check the token on a block explorer. $1 will be the name or url of the block explorer, which will be the translation of 'etherscan' or a block explorer url specified for a custom network."
},
"swapViewToken": {
"message": "查看 $1"

@ -51,6 +51,8 @@ const BNB_CHAIN_ID = '0x38';
const SWAPS_TESTNET_CHAIN_ID = '0x539';
const SWAPS_TESTNET_HOST = 'https://metaswap-api.airswap-dev.codefi.network';
const BSC_DEFAULT_BLOCK_EXPLORER_URL = 'https://bscscan.com/';
export const ALLOWED_SWAPS_CHAIN_IDS = {
[MAINNET_CHAIN_ID]: true,
[SWAPS_TESTNET_CHAIN_ID]: true,
@ -74,3 +76,7 @@ export const SWAPS_CHAINID_DEFAULT_TOKEN_MAP = {
[SWAPS_TESTNET_CHAIN_ID]: TEST_ETH_SWAPS_TOKEN_OBJECT,
[BNB_CHAIN_ID]: BNB_SWAPS_TOKEN_OBJECT,
};
export const SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP = {
[BNB_CHAIN_ID]: BSC_DEFAULT_BLOCK_EXPLORER_URL,
};

@ -3,6 +3,7 @@ import React, { useContext, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { createCustomExplorerLink } from '@metamask/etherscan-link';
import { I18nContext } from '../../../contexts/i18n';
import { useNewMetricEvent } from '../../../hooks/useMetricEvent';
import { MetaMetricsContext } from '../../../contexts/metametrics.new';
@ -31,7 +32,9 @@ import {
ERROR_FETCHING_QUOTES,
QUOTES_NOT_AVAILABLE_ERROR,
OFFLINE_FOR_MAINTENANCE,
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP,
} from '../../../../../shared/constants/swaps';
import { CHAIN_ID_TO_TYPE_MAP as VALID_INFURA_CHAIN_IDS } from '../../../../../shared/constants/network';
import { isSwapsDefaultTokenSymbol } from '../../../../../shared/modules/swaps.utils';
import PulseLoader from '../../../components/ui/pulse-loader';
@ -40,6 +43,7 @@ import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes';
import { getRenderableNetworkFeesForQuote } from '../swaps.util';
import SwapsFooter from '../swaps-footer';
import { getBlockExplorerUrlForTx } from '../../../../../shared/modules/transaction.utils';
import SwapFailureIcon from './swap-failure-icon';
import SwapSuccessIcon from './swap-success-icon';
import QuotesTimeoutIcon from './quotes-timeout-icon';
@ -105,8 +109,21 @@ export default function AwaitingSwap({
category: 'swaps',
});
const blockExplorerUrl =
txHash && getBlockExplorerUrlForTx({ chainId, hash: txHash }, rpcPrefs);
let blockExplorerUrl;
if (txHash && rpcPrefs.blockExplorerUrl) {
blockExplorerUrl = getBlockExplorerUrlForTx({ hash: txHash }, rpcPrefs);
} else if (txHash && SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId]) {
blockExplorerUrl = createCustomExplorerLink(
txHash,
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId],
);
} else if (txHash && VALID_INFURA_CHAIN_IDS[chainId]) {
blockExplorerUrl = getBlockExplorerUrlForTx({ chainId, hash: txHash });
}
const isCustomBlockExplorerUrl =
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId] ||
rpcPrefs.blockExplorerUrl;
let headerText;
let statusImage;
@ -138,7 +155,7 @@ export default function AwaitingSwap({
<ViewOnEtherScanLink
txHash={txHash}
blockExplorerUrl={blockExplorerUrl}
isCustomBlockExplorerUrl={Boolean(rpcPrefs.blockExplorerUrl)}
isCustomBlockExplorerUrl={isCustomBlockExplorerUrl}
/>
);
} else if (errorKey === QUOTES_EXPIRED_ERROR) {
@ -177,7 +194,7 @@ export default function AwaitingSwap({
<ViewOnEtherScanLink
txHash={txHash}
blockExplorerUrl={blockExplorerUrl}
isCustomBlockExplorerUrl={Boolean(rpcPrefs.blockExplorerUrl)}
isCustomBlockExplorerUrl={isCustomBlockExplorerUrl}
/>
);
} else if (!errorKey && swapComplete) {
@ -196,7 +213,7 @@ export default function AwaitingSwap({
<ViewOnEtherScanLink
txHash={txHash}
blockExplorerUrl={blockExplorerUrl}
isCustomBlockExplorerUrl={Boolean(rpcPrefs.blockExplorerUrl)}
isCustomBlockExplorerUrl={isCustomBlockExplorerUrl}
/>
);
}

@ -18,7 +18,7 @@ export default function ViewOnEtherScanLink({
onClick={() => global.platform.openTab({ url: blockExplorerUrl })}
>
{isCustomBlockExplorerUrl
? t('viewOnCustomBlockExplorer', [blockExplorerUrl])
? t('viewOnCustomBlockExplorer', [new URL(blockExplorerUrl).hostname])
: t('viewOnEtherscan')}
</div>
);

@ -4,6 +4,10 @@ import { useDispatch, useSelector } from 'react-redux';
import classnames from 'classnames';
import { uniqBy, isEqual } from 'lodash';
import { useHistory } from 'react-router-dom';
import {
createCustomTokenTrackerLink,
createTokenTrackerLinkForChain,
} from '@metamask/etherscan-link';
import { MetaMetricsContext } from '../../../contexts/metametrics.new';
import {
useTokensToSearch,
@ -34,6 +38,7 @@ import {
getConversionRate,
getCurrentCurrency,
getCurrentChainId,
getRpcPrefsForCurrentProvider,
} from '../../../selectors';
import {
getValueFromWeiHex,
@ -49,6 +54,7 @@ import {
isSwapsDefaultTokenAddress,
isSwapsDefaultTokenSymbol,
} from '../../../../../shared/modules/swaps.utils';
import { SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP } from '../../../../../shared/constants/swaps';
import { resetSwapsPostFetchState, removeToken } from '../../../store/actions';
import { fetchTokenPrice, fetchTokenBalance } from '../swaps.util';
@ -90,6 +96,7 @@ export default function BuildQuote({
const toToken = useSelector(getToToken) || destinationTokenInfo;
const defaultSwapsToken = useSelector(getSwapsDefaultToken);
const chainId = useSelector(getCurrentChainId);
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual);
const conversionRate = useSelector(getConversionRate);
@ -215,6 +222,30 @@ export default function BuildQuote({
);
};
let blockExplorerTokenLink;
let blockExplorerLabel;
if (rpcPrefs.blockExplorerUrl) {
blockExplorerTokenLink = createCustomTokenTrackerLink(
selectedToToken.address,
rpcPrefs.blockExplorerUrl,
);
blockExplorerLabel = new URL(rpcPrefs.blockExplorerUrl).hostname;
} else if (SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId]) {
blockExplorerTokenLink = createCustomTokenTrackerLink(
selectedToToken.address,
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId],
);
blockExplorerLabel = new URL(
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId],
).hostname;
} else {
blockExplorerTokenLink = createTokenTrackerLinkForChain(
selectedToToken.address,
chainId,
);
blockExplorerLabel = t('etherscan');
}
const { destinationTokenAddedForSwap } = fetchParams || {};
const { address: toAddress } = toToken || {};
const onToSelect = useCallback(
@ -412,17 +443,18 @@ export default function BuildQuote({
: t('swapTokenVerificationNoSource')}
</div>
<div>
{t('verifyThisTokenOn', [
<a
className="build-quote__token-etherscan-link build-quote__underline"
key="build-quote-etherscan-link"
href={`https://etherscan.io/token/${selectedToToken.address}`}
target="_blank"
rel="noopener noreferrer"
>
{t('etherscan')}
</a>,
])}
{blockExplorerTokenLink &&
t('verifyThisTokenOn', [
<a
className="build-quote__token-etherscan-link build-quote__underline"
key="build-quote-etherscan-link"
href={blockExplorerTokenLink}
target="_blank"
rel="noopener noreferrer"
>
{blockExplorerLabel}
</a>,
])}
</div>
</div>
}
@ -436,7 +468,10 @@ export default function BuildQuote({
}
type="warning"
withRightButton
infoTooltipText={t('swapVerifyTokenExplanation')}
infoTooltipText={
blockExplorerTokenLink &&
t('swapVerifyTokenExplanation', [blockExplorerLabel])
}
/>
) : (
<div className="build-quote__token-message">
@ -446,23 +481,29 @@ export default function BuildQuote({
>
{t('swapTokenVerificationSources', [occurances])}
</span>
{t('swapTokenVerificationMessage', [
<a
className="build-quote__token-etherscan-link"
key="build-quote-etherscan-link"
href={`https://etherscan.io/token/${selectedToToken.address}`}
target="_blank"
rel="noopener noreferrer"
>
{t('etherscan')}
</a>,
])}
<InfoTooltip
position="top"
contentText={t('swapVerifyTokenExplanation')}
containerClassName="build-quote__token-tooltip-container"
key="token-verification-info-tooltip"
/>
{blockExplorerTokenLink && (
<>
{t('swapTokenVerificationMessage', [
<a
className="build-quote__token-etherscan-link"
key="build-quote-etherscan-link"
href={blockExplorerTokenLink}
target="_blank"
rel="noopener noreferrer"
>
{blockExplorerLabel}
</a>,
])}
<InfoTooltip
position="top"
contentText={t('swapVerifyTokenExplanation', [
blockExplorerLabel,
])}
containerClassName="build-quote__token-tooltip-container"
key="token-verification-info-tooltip"
/>
</>
)}
</div>
))}
<div className="build-quote__slippage-buttons-container">

Loading…
Cancel
Save