prefer chainId when building block explorer urls (#10587)

feature/default_network_editable
Brad Decker 4 years ago committed by GitHub
parent 92680cf56f
commit 38fe75b7d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      app/scripts/metamask-controller.js
  2. 10
      app/scripts/platforms/extension.js
  3. 6
      package.json
  4. 96
      shared/modules/tests/transaction.utils.test.js
  5. 31
      shared/modules/transaction.utils.js
  6. 30
      ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js
  7. 35
      ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js
  8. 18
      ui/app/components/app/transaction-activity-log/transaction-activity-log.component.js
  9. 7
      ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js
  10. 10
      ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js
  11. 5
      ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js
  12. 14
      ui/app/helpers/utils/transactions.util.js
  13. 43
      ui/app/helpers/utils/transactions.util.test.js
  14. 10
      ui/app/pages/asset/components/token-asset.js
  15. 17
      ui/app/pages/swaps/awaiting-swap/awaiting-swap.js
  16. 18
      ui/app/pages/swaps/index.js

@ -319,7 +319,15 @@ export default class MetamaskController extends EventEmitter {
status === TRANSACTION_STATUSES.FAILED
) {
const txMeta = this.txController.txStateManager.getTx(txId);
this.platform.showTransactionNotification(txMeta);
const frequentRpcListDetail = this.preferencesController.getFrequentRpcListDetail();
let rpcPrefs = {};
if (txMeta.chainId) {
const rpcSettings = frequentRpcListDetail.find(
(rpc) => txMeta.chainId === rpc.chainId,
);
rpcPrefs = rpcSettings?.rpcPrefs ?? {};
}
this.platform.showTransactionNotification(txMeta, rpcPrefs);
const { txReceipt } = txMeta;
if (txReceipt && txReceipt.status === '0x0') {

@ -1,8 +1,8 @@
import extension from 'extensionizer';
import { createExplorerLink as explorerLink } from '@metamask/etherscan-link';
import { getEnvironmentType, checkForError } from '../lib/util';
import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app';
import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction';
import { getBlockExplorerUrlForTx } from '../../../shared/modules/transaction.utils';
export default class ExtensionPlatform {
//
@ -110,7 +110,7 @@ export default class ExtensionPlatform {
}
}
showTransactionNotification(txMeta) {
showTransactionNotification(txMeta, rpcPrefs) {
const { status, txReceipt: { status: receiptStatus } = {} } = txMeta;
if (status === TRANSACTION_STATUSES.CONFIRMED) {
@ -120,7 +120,7 @@ export default class ExtensionPlatform {
txMeta,
'Transaction encountered an error.',
)
: this._showConfirmedTransaction(txMeta);
: this._showConfirmedTransaction(txMeta, rpcPrefs);
} else if (status === TRANSACTION_STATUSES.FAILED) {
this._showFailedTransaction(txMeta);
}
@ -189,10 +189,10 @@ export default class ExtensionPlatform {
});
}
_showConfirmedTransaction(txMeta) {
_showConfirmedTransaction(txMeta, rpcPrefs) {
this._subscribeToNotificationClicked();
const url = explorerLink(txMeta.hash, txMeta.metamaskNetworkId);
const url = getBlockExplorerUrlForTx(txMeta, rpcPrefs);
const nonce = parseInt(txMeta.txParams.nonce, 16);
const title = 'Confirmed transaction';

@ -20,9 +20,9 @@
"forwarder": "node ./development/static-server.js ./node_modules/@metamask/forwarder/dist/ --port 9010",
"dapp-forwarder": "concurrently -k -n forwarder,dapp -p '[{time}][{name}]' 'yarn forwarder' 'yarn dapp'",
"sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080",
"test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/*.test.js\" \"ui/app/**/*.test.js\"",
"test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/*.test.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"",
"test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*.test.js",
"test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/{,**/!(permissions)}/*.test.js\" \"ui/app/**/*.test.js\"",
"test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/{,**/!(permissions)}/*.test.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"",
"test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.test.js\"",
"test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive",
"test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh",
@ -45,7 +45,7 @@
"verify-locales": "node ./development/verify-locale-strings.js",
"verify-locales:fix": "node ./development/verify-locale-strings.js --fix",
"mozilla-lint": "addons-linter dist/firefox",
"watch": "mocha --watch --require test/env.js --require test/setup.js --reporter min --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\"",
"watch": "mocha --watch --require test/env.js --require test/setup.js --reporter min --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"",
"devtools:react": "react-devtools",
"devtools:redux": "remotedev --hostname=localhost --port=8000",
"start:dev": "concurrently -k -n build,react,redux yarn:start yarn:devtools:react yarn:devtools:redux",

@ -0,0 +1,96 @@
import assert from 'assert';
import {
MAINNET_CHAIN_ID,
MAINNET_NETWORK_ID,
ROPSTEN_CHAIN_ID,
ROPSTEN_NETWORK_ID,
} from '../../constants/network';
import { getBlockExplorerUrlForTx } from '../transaction.utils';
const tests = [
{
expected: 'https://etherscan.io/tx/0xabcd',
transaction: {
metamaskNetworkId: MAINNET_NETWORK_ID,
hash: '0xabcd',
},
},
{
expected: 'https://ropsten.etherscan.io/tx/0xdef0',
transaction: {
metamaskNetworkId: ROPSTEN_NETWORK_ID,
hash: '0xdef0',
},
rpcPrefs: {},
},
{
// test handling of `blockExplorerUrl` for a custom RPC
expected: 'https://block.explorer/tx/0xabcd',
transaction: {
metamaskNetworkId: '31',
hash: '0xabcd',
},
rpcPrefs: {
blockExplorerUrl: 'https://block.explorer',
},
},
{
// test handling of trailing `/` in `blockExplorerUrl` for a custom RPC
expected: 'https://another.block.explorer/tx/0xdef0',
transaction: {
networkId: '33',
hash: '0xdef0',
},
rpcPrefs: {
blockExplorerUrl: 'https://another.block.explorer/',
},
},
{
expected: 'https://etherscan.io/tx/0xabcd',
transaction: {
chainId: MAINNET_CHAIN_ID,
hash: '0xabcd',
},
},
{
expected: 'https://ropsten.etherscan.io/tx/0xdef0',
transaction: {
chainId: ROPSTEN_CHAIN_ID,
hash: '0xdef0',
},
rpcPrefs: {},
},
{
// test handling of `blockExplorerUrl` for a custom RPC
expected: 'https://block.explorer/tx/0xabcd',
transaction: {
chainId: '0x1f',
hash: '0xabcd',
},
rpcPrefs: {
blockExplorerUrl: 'https://block.explorer',
},
},
{
// test handling of trailing `/` in `blockExplorerUrl` for a custom RPC
expected: 'https://another.block.explorer/tx/0xdef0',
transaction: {
chainId: '0x21',
hash: '0xdef0',
},
rpcPrefs: {
blockExplorerUrl: 'https://another.block.explorer/',
},
},
];
describe('getBlockExplorerUrlForTx', function () {
tests.forEach((test) => {
it(`should return '${test.expected}' for transaction with hash: '${test.transaction.hash}'`, function () {
assert.strictEqual(
getBlockExplorerUrlForTx(test.transaction, test.rpcPrefs),
test.expected,
);
});
});
});

@ -1,6 +1,37 @@
import {
createExplorerLink,
createExplorerLinkForChain,
} from '@metamask/etherscan-link';
export function transactionMatchesNetwork(transaction, chainId, networkId) {
if (typeof transaction.chainId !== 'undefined') {
return transaction.chainId === chainId;
}
return transaction.metamaskNetworkId === networkId;
}
/**
* build the etherscan link for a transaction by either chainId, if available
* or metamaskNetworkId as a fallback. If rpcPrefs is provided will build the
* url for the provided blockExplorerUrl.
*
* @param {Object} transaction - a transaction object from state
* @param {string} [transaction.metamaskNetworkId] - network id tx occurred on
* @param {string} [transaction.chainId] - chain id tx occurred on
* @param {string} [transaction.hash] - hash of the transaction
* @param {Object} [rpcPrefs] - the rpc preferences for the current RPC network
* @param {string} [rpcPrefs.blockExplorerUrl] - the block explorer url for RPC
* networks
* @returns {string}
*/
export function getBlockExplorerUrlForTx(transaction, rpcPrefs = {}) {
if (rpcPrefs.blockExplorerUrl) {
return `${rpcPrefs.blockExplorerUrl.replace(/\/+$/u, '')}/tx/${
transaction.hash
}`;
}
if (transaction.chainId) {
return createExplorerLinkForChain(transaction.hash, transaction.chainId);
}
return createExplorerLink(transaction.hash, transaction.metamaskNetworkId);
}

@ -19,12 +19,42 @@ describe('TransactionActivityLog container', function () {
metamask: {
conversionRate: 280.45,
nativeCurrency: 'ETH',
frequentRpcListDetail: [],
},
};
assert.deepStrictEqual(mapStateToProps(mockState), {
conversionRate: 280.45,
nativeCurrency: 'ETH',
rpcPrefs: {},
});
});
it('should return the correct props when on a custom network', function () {
const mockState = {
metamask: {
conversionRate: 280.45,
nativeCurrency: 'ETH',
frequentRpcListDetail: [
{
rpcUrl: 'https://customnetwork.com/',
rpcPrefs: {
blockExplorerUrl: 'https://customblockexplorer.com/',
},
},
],
provider: {
rpcUrl: 'https://customnetwork.com/',
},
},
};
assert.deepStrictEqual(mapStateToProps(mockState), {
conversionRate: 280.45,
nativeCurrency: 'ETH',
rpcPrefs: {
blockExplorerUrl: 'https://customblockexplorer.com/',
},
});
});
});

@ -1,4 +1,8 @@
import assert from 'assert';
import {
ROPSTEN_CHAIN_ID,
ROPSTEN_NETWORK_ID,
} from '../../../../../../shared/constants/network';
import {
TRANSACTION_STATUSES,
TRANSACTION_TYPES,
@ -24,7 +28,8 @@ describe('TransactionActivityLog utils', function () {
id: 6400627574331058,
time: 1543958845581,
status: TRANSACTION_STATUSES.UNAPPROVED,
metamaskNetworkId: '3',
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
loadingDefaults: true,
txParams: {
from: '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706',
@ -71,7 +76,8 @@ describe('TransactionActivityLog utils', function () {
],
id: 6400627574331058,
loadingDefaults: false,
metamaskNetworkId: '3',
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
status: TRANSACTION_STATUSES.DROPPED,
submittedTime: 1543958848135,
time: 1543958845581,
@ -93,7 +99,8 @@ describe('TransactionActivityLog utils', function () {
id: 6400627574331060,
time: 1543958857697,
status: TRANSACTION_STATUSES.UNAPPROVED,
metamaskNetworkId: '3',
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
loadingDefaults: false,
txParams: {
from: '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706',
@ -163,7 +170,8 @@ describe('TransactionActivityLog utils', function () {
id: 6400627574331060,
lastGasPrice: '0x4190ab00',
loadingDefaults: false,
metamaskNetworkId: '3',
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
status: TRANSACTION_STATUSES.CONFIRMED,
submittedTime: 1543958860054,
time: 1543958857697,
@ -185,6 +193,8 @@ describe('TransactionActivityLog utils', function () {
const expected = [
{
id: 6400627574331058,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
hash:
'0xa14f13d36b3901e352ce3a7acb9b47b001e5a3370f06232a0953c6fc6fad91b3',
eventKey: 'transactionCreated',
@ -193,6 +203,8 @@ describe('TransactionActivityLog utils', function () {
},
{
id: 6400627574331058,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
hash:
'0xa14f13d36b3901e352ce3a7acb9b47b001e5a3370f06232a0953c6fc6fad91b3',
eventKey: 'transactionSubmitted',
@ -201,6 +213,8 @@ describe('TransactionActivityLog utils', function () {
},
{
id: 6400627574331060,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
hash:
'0xecbe181ee67c4291d04a7cb9ffbf1d5d831e4fbaa89994fd06bab5dd4cc79b33',
eventKey: 'transactionResubmitted',
@ -209,6 +223,8 @@ describe('TransactionActivityLog utils', function () {
},
{
id: 6400627574331060,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
hash:
'0xecbe181ee67c4291d04a7cb9ffbf1d5d831e4fbaa89994fd06bab5dd4cc79b33',
eventKey: 'transactionConfirmed',
@ -249,7 +265,8 @@ describe('TransactionActivityLog utils', function () {
{
id: 5559712943815343,
loadingDefaults: true,
metamaskNetworkId: '3',
metamaskNetworkId: ROPSTEN_NETWORK_ID,
chainId: ROPSTEN_CHAIN_ID,
status: TRANSACTION_STATUSES.UNAPPROVED,
time: 1535507561452,
txParams: {
@ -389,6 +406,8 @@ describe('TransactionActivityLog utils', function () {
value: '0x2386f26fc10000',
},
hash: '0xabc',
chainId: ROPSTEN_CHAIN_ID,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
};
const expectedResult = [
@ -398,6 +417,8 @@ describe('TransactionActivityLog utils', function () {
value: '0x2386f26fc10000',
id: 1,
hash: '0xabc',
chainId: ROPSTEN_CHAIN_ID,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
},
{
eventKey: 'transactionSubmitted',
@ -405,6 +426,8 @@ describe('TransactionActivityLog utils', function () {
value: '0x2632e314a000',
id: 1,
hash: '0xabc',
chainId: ROPSTEN_CHAIN_ID,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
},
{
eventKey: 'transactionConfirmed',
@ -412,6 +435,8 @@ describe('TransactionActivityLog utils', function () {
value: '0x2632e314a000',
id: 1,
hash: '0xabc',
chainId: ROPSTEN_CHAIN_ID,
metamaskNetworkId: ROPSTEN_NETWORK_ID,
},
];

@ -1,13 +1,13 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { createExplorerLink } from '@metamask/etherscan-link';
import {
getEthConversionFromWeiHex,
getValueFromWeiHex,
} from '../../../helpers/utils/conversions.util';
import { formatDate } from '../../../helpers/utils/util';
import { getBlockExplorerUrlForTx } from '../../../../../shared/modules/transaction.utils';
import TransactionActivityLogIcon from './transaction-activity-log-icon';
import { CONFIRMED_STATUS } from './transaction-activity-log.constants';
@ -28,14 +28,14 @@ export default class TransactionActivityLog extends PureComponent {
onRetry: PropTypes.func,
primaryTransaction: PropTypes.object,
isEarliestNonce: PropTypes.bool,
rpcPrefs: PropTypes.object,
};
handleActivityClick = (hash) => {
const { primaryTransaction } = this.props;
const { metamaskNetworkId } = primaryTransaction;
const etherscanUrl = createExplorerLink(hash, metamaskNetworkId);
handleActivityClick = (activity) => {
const etherscanUrl = getBlockExplorerUrlForTx(
activity,
this.props.rpcPrefs,
);
global.platform.openTab({ url: etherscanUrl });
};
@ -79,7 +79,7 @@ export default class TransactionActivityLog extends PureComponent {
renderActivity(activity, index) {
const { conversionRate, nativeCurrency } = this.props;
const { eventKey, value, timestamp, hash } = activity;
const { eventKey, value, timestamp } = activity;
const ethValue =
index === 0
? `${getValueFromWeiHex({
@ -111,7 +111,7 @@ export default class TransactionActivityLog extends PureComponent {
<div
className="transaction-activity-log__activity-text"
title={activityText}
onClick={() => this.handleActivityClick(hash)}
onClick={() => this.handleActivityClick(activity)}
>
{activityText}
</div>

@ -1,6 +1,10 @@
import { connect } from 'react-redux';
import { findLastIndex } from 'lodash';
import { conversionRateSelector, getNativeCurrency } from '../../../selectors';
import {
conversionRateSelector,
getNativeCurrency,
getRpcPrefsForCurrentProvider,
} from '../../../selectors';
import TransactionActivityLog from './transaction-activity-log.component';
import { combineTransactionHistories } from './transaction-activity-log.util';
import {
@ -15,6 +19,7 @@ const mapStateToProps = (state) => {
return {
conversionRate: conversionRateSelector(state),
nativeCurrency: getNativeCurrency(state),
rpcPrefs: getRpcPrefsForCurrentProvider(state),
};
};

@ -49,6 +49,8 @@ const statusHash = {
export function getActivities(transaction, isFirstTransaction = false) {
const {
id,
chainId,
metamaskNetworkId,
hash,
history = [],
txParams: { gas: paramsGasLimit, gasPrice: paramsGasPrice },
@ -76,6 +78,8 @@ export function getActivities(transaction, isFirstTransaction = false) {
return acc.concat({
id,
hash,
chainId,
metamaskNetworkId,
eventKey: TRANSACTION_CREATED_EVENT,
timestamp,
value,
@ -127,6 +131,8 @@ export function getActivities(transaction, isFirstTransaction = false) {
hash,
eventKey,
timestamp,
chainId,
metamaskNetworkId,
value: gasFee,
});
}
@ -165,6 +171,8 @@ export function getActivities(transaction, isFirstTransaction = false) {
events.push({
id,
hash,
chainId,
metamaskNetworkId,
eventKey: TRANSACTION_UPDATED_EVENT,
timestamp,
});
@ -185,6 +193,8 @@ export function getActivities(transaction, isFirstTransaction = false) {
? historyActivities.concat({
id,
hash,
chainId,
metamaskNetworkId,
eventKey: TRANSACTION_ERRORED_EVENT,
})
: historyActivities;

@ -1,7 +1,6 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import copyToClipboard from 'copy-to-clipboard';
import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util';
import SenderToRecipient from '../../ui/sender-to-recipient';
import { FLAT_VARIANT } from '../../ui/sender-to-recipient/sender-to-recipient.constants';
import TransactionActivityLog from '../transaction-activity-log';
@ -10,6 +9,7 @@ import Button from '../../ui/button';
import Tooltip from '../../ui/tooltip';
import Copy from '../../ui/icon/copy-icon.component';
import Popover from '../../ui/popover';
import { getBlockExplorerUrlForTx } from '../../../../../shared/modules/transaction.utils';
export default class TransactionListItemDetails extends PureComponent {
static contextTypes = {
@ -51,7 +51,6 @@ export default class TransactionListItemDetails extends PureComponent {
transactionGroup: { primaryTransaction },
rpcPrefs,
} = this.props;
const { hash, metamaskNetworkId } = primaryTransaction;
this.context.metricsEvent({
eventOpts: {
@ -62,7 +61,7 @@ export default class TransactionListItemDetails extends PureComponent {
});
global.platform.openTab({
url: getBlockExplorerUrlForTx(metamaskNetworkId, hash, rpcPrefs),
url: getBlockExplorerUrlForTx(primaryTransaction, rpcPrefs),
});
};

@ -2,7 +2,6 @@ import { MethodRegistry } from 'eth-method-registry';
import abi from 'human-standard-token-abi';
import { ethers } from 'ethers';
import log from 'loglevel';
import { createExplorerLink } from '@metamask/etherscan-link';
import { addHexPrefix } from '../../../../app/scripts/lib/util';
import {
@ -193,19 +192,6 @@ export function getStatusKey(transaction) {
return transaction.status;
}
/**
* Returns an external block explorer URL at which a transaction can be viewed.
* @param {number} networkId
* @param {string} hash
* @param {Object} rpcPrefs
*/
export function getBlockExplorerUrlForTx(networkId, hash, rpcPrefs = {}) {
if (rpcPrefs.blockExplorerUrl) {
return `${rpcPrefs.blockExplorerUrl.replace(/\/+$/u, '')}/tx/${hash}`;
}
return createExplorerLink(hash, networkId);
}
/**
* Returns a title for the given transaction category.
*

@ -60,47 +60,4 @@ describe('Transactions utils', function () {
});
});
});
describe('getBlockExplorerUrlForTx', function () {
it('should return the correct block explorer url for a transaction', function () {
const tests = [
{
expected: 'https://etherscan.io/tx/0xabcd',
networkId: '1',
hash: '0xabcd',
},
{
expected: 'https://ropsten.etherscan.io/tx/0xdef0',
networkId: '3',
hash: '0xdef0',
rpcPrefs: {},
},
{
// test handling of `blockExplorerUrl` for a custom RPC
expected: 'https://block.explorer/tx/0xabcd',
networkId: '31',
hash: '0xabcd',
rpcPrefs: {
blockExplorerUrl: 'https://block.explorer',
},
},
{
// test handling of trailing `/` in `blockExplorerUrl` for a custom RPC
expected: 'https://another.block.explorer/tx/0xdef0',
networkId: '33',
hash: '0xdef0',
rpcPrefs: {
blockExplorerUrl: 'https://another.block.explorer/',
},
},
];
tests.forEach(({ expected, networkId, hash, rpcPrefs }) => {
assert.strictEqual(
utils.getBlockExplorerUrlForTx(networkId, hash, rpcPrefs),
expected,
);
});
});
});
});

@ -2,12 +2,12 @@ import React from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { createTokenTrackerLink } from '@metamask/etherscan-link';
import { createTokenTrackerLinkForChain } from '@metamask/etherscan-link';
import TransactionList from '../../../components/app/transaction-list';
import { TokenOverview } from '../../../components/app/wallet-overview';
import {
getCurrentNetworkId,
getCurrentChainId,
getSelectedIdentity,
} from '../../../selectors/selectors';
import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
@ -18,7 +18,7 @@ import TokenOptions from './token-options';
export default function TokenAsset({ token }) {
const dispatch = useDispatch();
const network = useSelector(getCurrentNetworkId);
const chainId = useSelector(getCurrentChainId);
const selectedIdentity = useSelector(getSelectedIdentity);
const selectedAccountName = selectedIdentity.name;
const selectedAddress = selectedIdentity.address;
@ -36,9 +36,9 @@ export default function TokenAsset({ token }) {
dispatch(showModal({ name: 'HIDE_TOKEN_CONFIRMATION', token }))
}
onViewEtherscan={() => {
const url = createTokenTrackerLink(
const url = createTokenTrackerLinkForChain(
token.address,
network,
chainId,
selectedAddress,
);
global.platform.openTab({ url });

@ -6,7 +6,12 @@ import { useHistory } from 'react-router-dom';
import { I18nContext } from '../../../contexts/i18n';
import { useNewMetricEvent } from '../../../hooks/useMetricEvent';
import { MetaMetricsContext } from '../../../contexts/metametrics.new';
import { getCurrentCurrency, getUSDConversionRate } from '../../../selectors';
import {
getCurrentChainId,
getCurrentCurrency,
getRpcPrefsForCurrentProvider,
getUSDConversionRate,
} from '../../../selectors';
import {
getUsedQuote,
getFetchParams,
@ -19,7 +24,6 @@ import {
} from '../../../ducks/swaps/swaps';
import Mascot from '../../../components/ui/mascot';
import PulseLoader from '../../../components/ui/pulse-loader';
import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util';
import {
QUOTES_EXPIRED_ERROR,
SWAP_FAILED_ERROR,
@ -31,6 +35,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';
@ -40,9 +45,7 @@ export default function AwaitingSwap({
swapComplete,
errorKey,
txHash,
networkId,
tokensReceived,
rpcPrefs,
submittingSwap,
inputValue,
maxSlippage,
@ -60,6 +63,8 @@ export default function AwaitingSwap({
const swapsGasPrice = useSelector(getUsedSwapsGasPrice);
const currentCurrency = useSelector(getCurrentCurrency);
const usdConversionRate = useSelector(getUSDConversionRate);
const chainId = useSelector(getCurrentChainId);
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
const [trackedQuotesExpiredEvent, setTrackedQuotesExpiredEvent] = useState(
false,
@ -96,7 +101,7 @@ export default function AwaitingSwap({
});
const blockExplorerUrl =
txHash && getBlockExplorerUrlForTx(networkId, txHash, rpcPrefs);
txHash && getBlockExplorerUrlForTx({ chainId, hash: txHash }, rpcPrefs);
let headerText;
let statusImage;
@ -240,10 +245,8 @@ export default function AwaitingSwap({
AwaitingSwap.propTypes = {
swapComplete: PropTypes.bool,
networkId: PropTypes.string.isRequired,
txHash: PropTypes.string,
tokensReceived: PropTypes.string,
rpcPrefs: PropTypes.object.isRequired,
errorKey: PropTypes.oneOf([
QUOTES_EXPIRED_ERROR,
SWAP_FAILED_ERROR,

@ -11,7 +11,6 @@ import BigNumber from 'bignumber.js';
import { I18nContext } from '../../contexts/i18n';
import {
getSelectedAccount,
getCurrentNetworkId,
getCurrentChainId,
} from '../../selectors/selectors';
import {
@ -55,10 +54,7 @@ import {
setBackgroundSwapRouteState,
setSwapsErrorKey,
} from '../../store/actions';
import {
currentNetworkTxListSelector,
getRpcPrefsForCurrentProvider,
} from '../../selectors';
import { currentNetworkTxListSelector } from '../../selectors';
import { useNewMetricEvent } from '../../hooks/useMetricEvent';
import FeatureToggledRoute from '../../helpers/higher-order-components/feature-toggled-route';
@ -97,8 +93,6 @@ export default function Swap() {
const tradeTxId = useSelector(getTradeTxId);
const approveTxId = useSelector(getApproveTxId);
const aggregatorMetadata = useSelector(getAggregatorMetadata);
const networkId = useSelector(getCurrentNetworkId);
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
const fetchingQuotes = useSelector(getFetchingQuotes);
let swapsErrorKey = useSelector(getSwapsErrorKey);
const swapsEnabled = useSelector(getSwapsFeatureLiveness);
@ -317,8 +311,6 @@ export default function Swap() {
swapComplete={false}
errorKey={swapsErrorKey}
txHash={tradeTxData?.hash}
networkId={networkId}
rpcPrefs={rpcPrefs}
inputValue={inputValue}
maxSlippage={maxSlippage}
submittedTime={tradeTxData?.submittedTime}
@ -364,11 +356,7 @@ export default function Swap() {
exact
render={() => {
return swapsEnabled === false ? (
<AwaitingSwap
errorKey={OFFLINE_FOR_MAINTENANCE}
networkId={networkId}
rpcPrefs={rpcPrefs}
/>
<AwaitingSwap errorKey={OFFLINE_FOR_MAINTENANCE} />
) : (
<Redirect to={{ pathname: BUILD_QUOTE_ROUTE }} />
);
@ -381,13 +369,11 @@ export default function Swap() {
return routeState === 'awaiting' || tradeTxData ? (
<AwaitingSwap
swapComplete={tradeConfirmed}
networkId={networkId}
txHash={tradeTxData?.hash}
tokensReceived={tokensReceived}
submittingSwap={
routeState === 'awaiting' && !(approveTxId || tradeTxId)
}
rpcPrefs={rpcPrefs}
inputValue={inputValue}
maxSlippage={maxSlippage}
/>

Loading…
Cancel
Save