mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
Show a tx link and the "create a new swap" link for STX (#14995)
This commit is contained in:
parent
6553b9a29b
commit
8cbfa2ea9e
@ -17,7 +17,6 @@ import {
|
||||
getUSDConversionRate,
|
||||
isHardwareWallet,
|
||||
getHardwareWalletType,
|
||||
getSwapsDefaultToken,
|
||||
} from '../../../selectors';
|
||||
|
||||
import {
|
||||
@ -34,10 +33,8 @@ import {
|
||||
getCurrentSmartTransactionsEnabled,
|
||||
getFromTokenInputValue,
|
||||
getMaxSlippage,
|
||||
setSwapsFromToken,
|
||||
} from '../../../ducks/swaps/swaps';
|
||||
import Mascot from '../../../components/ui/mascot';
|
||||
import Box from '../../../components/ui/box';
|
||||
import {
|
||||
QUOTES_EXPIRED_ERROR,
|
||||
SWAP_FAILED_ERROR,
|
||||
@ -56,10 +53,11 @@ import { stopPollingForQuotes } from '../../../store/actions';
|
||||
import { getRenderableNetworkFeesForQuote } from '../swaps.util';
|
||||
import SwapsFooter from '../swaps-footer';
|
||||
|
||||
import CreateNewSwap from '../create-new-swap';
|
||||
import ViewOnBlockExplorer from '../view-on-block-explorer';
|
||||
import SwapFailureIcon from './swap-failure-icon';
|
||||
import SwapSuccessIcon from './swap-success-icon';
|
||||
import QuotesTimeoutIcon from './quotes-timeout-icon';
|
||||
import ViewOnEtherScanLink from './view-on-ether-scan-link';
|
||||
|
||||
export default function AwaitingSwap({
|
||||
swapComplete,
|
||||
@ -85,8 +83,6 @@ export default function AwaitingSwap({
|
||||
const usdConversionRate = useSelector(getUSDConversionRate);
|
||||
const chainId = useSelector(getCurrentChainId);
|
||||
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider, shallowEqual);
|
||||
const defaultSwapsToken = useSelector(getSwapsDefaultToken, isEqual);
|
||||
|
||||
const [trackedQuotesExpiredEvent, setTrackedQuotesExpiredEvent] = useState(
|
||||
false,
|
||||
);
|
||||
@ -141,11 +137,6 @@ export default function AwaitingSwap({
|
||||
{ blockExplorerUrl: baseNetworkUrl },
|
||||
);
|
||||
|
||||
const isCustomBlockExplorerUrl = Boolean(
|
||||
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId] ||
|
||||
rpcPrefs.blockExplorerUrl,
|
||||
);
|
||||
|
||||
let headerText;
|
||||
let statusImage;
|
||||
let descriptionText;
|
||||
@ -173,10 +164,9 @@ export default function AwaitingSwap({
|
||||
submitText = t('tryAgain');
|
||||
statusImage = <SwapFailureIcon />;
|
||||
content = blockExplorerUrl && (
|
||||
<ViewOnEtherScanLink
|
||||
txHash={txHash}
|
||||
<ViewOnBlockExplorer
|
||||
blockExplorerUrl={blockExplorerUrl}
|
||||
isCustomBlockExplorerUrl={isCustomBlockExplorerUrl}
|
||||
sensitiveTrackingProperties={sensitiveProperties}
|
||||
/>
|
||||
);
|
||||
} else if (errorKey === QUOTES_EXPIRED_ERROR) {
|
||||
@ -221,10 +211,9 @@ export default function AwaitingSwap({
|
||||
</span>,
|
||||
]);
|
||||
content = blockExplorerUrl && (
|
||||
<ViewOnEtherScanLink
|
||||
txHash={txHash}
|
||||
<ViewOnBlockExplorer
|
||||
blockExplorerUrl={blockExplorerUrl}
|
||||
isCustomBlockExplorerUrl={isCustomBlockExplorerUrl}
|
||||
sensitiveTrackingProperties={sensitiveProperties}
|
||||
/>
|
||||
);
|
||||
} else if (!errorKey && swapComplete) {
|
||||
@ -240,35 +229,13 @@ export default function AwaitingSwap({
|
||||
</span>,
|
||||
]);
|
||||
content = blockExplorerUrl && (
|
||||
<ViewOnEtherScanLink
|
||||
txHash={txHash}
|
||||
<ViewOnBlockExplorer
|
||||
blockExplorerUrl={blockExplorerUrl}
|
||||
isCustomBlockExplorerUrl={isCustomBlockExplorerUrl}
|
||||
sensitiveTrackingProperties={sensitiveProperties}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const MakeAnotherSwap = () => {
|
||||
return (
|
||||
<Box marginBottom={3}>
|
||||
<a
|
||||
href="#"
|
||||
onClick={async () => {
|
||||
trackEvent({
|
||||
event: 'Make Another Swap',
|
||||
category: EVENT.CATEGORIES.SWAPS,
|
||||
sensitiveProperties,
|
||||
});
|
||||
await dispatch(navigateBackToBuildQuote(history));
|
||||
dispatch(setSwapsFromToken(defaultSwapsToken));
|
||||
}}
|
||||
>
|
||||
{t('makeAnotherSwap')}
|
||||
</a>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (errorKey) {
|
||||
// If there was an error, stop polling for quotes.
|
||||
@ -291,7 +258,9 @@ export default function AwaitingSwap({
|
||||
<div className="awaiting-swap__main-description">{descriptionText}</div>
|
||||
{content}
|
||||
</div>
|
||||
{!errorKey && swapComplete ? <MakeAnotherSwap /> : null}
|
||||
{!errorKey && swapComplete ? (
|
||||
<CreateNewSwap sensitiveTrackingProperties={sensitiveProperties} />
|
||||
) : null}
|
||||
<SwapsFooter
|
||||
onSubmit={async () => {
|
||||
if (errorKey === OFFLINE_FOR_MAINTENANCE) {
|
||||
|
@ -20,10 +20,6 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary-default);
|
||||
}
|
||||
|
||||
&__status-image {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 16px;
|
||||
@ -64,7 +60,6 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__view-on-etherscan,
|
||||
&__support-link {
|
||||
color: var(--color-primary-default);
|
||||
margin-top: 24px;
|
||||
@ -75,20 +70,6 @@
|
||||
@include H6;
|
||||
}
|
||||
|
||||
&__view-on-etherscan {
|
||||
@include H7;
|
||||
|
||||
transition: opacity 1s ease-in-out;
|
||||
}
|
||||
|
||||
&__view-on-etherscan--invisible {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&__view-on-etherscan--visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&__amount-and-symbol {
|
||||
color: var(--color-text-default);
|
||||
font-weight: bold;
|
||||
|
@ -1,21 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ViewOnEtherScanLink renders the component with a custom block explorer link 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="awaiting-swap__view-on-etherscan awaiting-swap__view-on-etherscan--visible"
|
||||
>
|
||||
View Swap at custom-blockchain.explorer
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ViewOnEtherScanLink renders the component with initial props 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="awaiting-swap__view-on-etherscan awaiting-swap__view-on-etherscan--visible"
|
||||
>
|
||||
View Swap on Etherscan
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -1 +0,0 @@
|
||||
export { default } from './view-on-ether-scan-link';
|
@ -1,50 +0,0 @@
|
||||
import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { I18nContext } from '../../../../contexts/i18n';
|
||||
import { getURLHostName } from '../../../../helpers/utils/util';
|
||||
import { MetaMetricsContext } from '../../../../contexts/metametrics';
|
||||
import { EVENT } from '../../../../../shared/constants/metametrics';
|
||||
|
||||
export default function ViewOnEtherScanLink({
|
||||
txHash,
|
||||
blockExplorerUrl,
|
||||
isCustomBlockExplorerUrl,
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames('awaiting-swap__view-on-etherscan', {
|
||||
'awaiting-swap__view-on-etherscan--visible': txHash,
|
||||
'awaiting-swap__view-on-etherscan--invisible': !txHash,
|
||||
})}
|
||||
onClick={() => {
|
||||
trackEvent({
|
||||
event: 'Clicked Block Explorer Link',
|
||||
category: EVENT.CATEGORIES.SWAPS,
|
||||
properties: {
|
||||
link_type: 'Transaction Block Explorer',
|
||||
action: 'Swap Transaction',
|
||||
block_explorer_domain: getURLHostName(blockExplorerUrl),
|
||||
},
|
||||
});
|
||||
global.platform.openTab({ url: blockExplorerUrl });
|
||||
}}
|
||||
>
|
||||
{isCustomBlockExplorerUrl
|
||||
? t('viewOnCustomBlockExplorer', [
|
||||
t('blockExplorerSwapAction'),
|
||||
getURLHostName(blockExplorerUrl),
|
||||
])
|
||||
: t('viewOnEtherscan', [t('blockExplorerSwapAction')])}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ViewOnEtherScanLink.propTypes = {
|
||||
txHash: PropTypes.string,
|
||||
blockExplorerUrl: PropTypes.string,
|
||||
isCustomBlockExplorerUrl: PropTypes.bool,
|
||||
};
|
@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { renderWithProvider } from '../../../../../test/jest';
|
||||
import ViewOnEtherScanLink from '.';
|
||||
|
||||
const createProps = (customProps = {}) => {
|
||||
return {
|
||||
txHash:
|
||||
'0x58e5a0fc7fbc849eddc100d44e86276168a8c7baaa5604e44ba6f5eb8ba1b7eb',
|
||||
blockExplorerUrl: 'https://block.explorer',
|
||||
isCustomBlockExplorerUrl: false,
|
||||
...customProps,
|
||||
};
|
||||
};
|
||||
|
||||
describe('ViewOnEtherScanLink', () => {
|
||||
it('renders the component with initial props', () => {
|
||||
const { container, getByText } = renderWithProvider(
|
||||
<ViewOnEtherScanLink {...createProps()} />,
|
||||
);
|
||||
expect(getByText('View Swap on Etherscan')).toBeInTheDocument();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders the component with a custom block explorer link', () => {
|
||||
const { container, getByText } = renderWithProvider(
|
||||
<ViewOnEtherScanLink
|
||||
{...createProps({
|
||||
blockExplorerUrl: 'https://custom-blockchain.explorer',
|
||||
isCustomBlockExplorerUrl: true,
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
getByText('View Swap at custom-blockchain.explorer'),
|
||||
).toBeInTheDocument();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
47
ui/pages/swaps/create-new-swap/create-new-swap.js
Normal file
47
ui/pages/swaps/create-new-swap/create-new-swap.js
Normal file
@ -0,0 +1,47 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
import Box from '../../../components/ui/box';
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||
import { EVENT } from '../../../../shared/constants/metametrics';
|
||||
import {
|
||||
navigateBackToBuildQuote,
|
||||
setSwapsFromToken,
|
||||
} from '../../../ducks/swaps/swaps';
|
||||
import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { getSwapsDefaultToken } from '../../../selectors';
|
||||
|
||||
export default function CreateNewSwap({ sensitiveTrackingProperties }) {
|
||||
const t = useContext(I18nContext);
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const defaultSwapsToken = useSelector(getSwapsDefaultToken, isEqual);
|
||||
|
||||
return (
|
||||
<Box marginBottom={3} className="create-new-swap">
|
||||
<button
|
||||
onClick={async () => {
|
||||
trackEvent({
|
||||
event: 'Make Another Swap',
|
||||
category: EVENT.CATEGORIES.SWAPS,
|
||||
sensitiveProperties: sensitiveTrackingProperties,
|
||||
});
|
||||
history.push(DEFAULT_ROUTE); // It cleans up Swaps state.
|
||||
await dispatch(navigateBackToBuildQuote(history));
|
||||
dispatch(setSwapsFromToken(defaultSwapsToken));
|
||||
}}
|
||||
>
|
||||
{t('makeAnotherSwap')}
|
||||
</button>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
CreateNewSwap.propTypes = {
|
||||
sensitiveTrackingProperties: PropTypes.object.isRequired,
|
||||
};
|
27
ui/pages/swaps/create-new-swap/create-new-swap.test.js
Normal file
27
ui/pages/swaps/create-new-swap/create-new-swap.test.js
Normal file
@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
|
||||
import {
|
||||
renderWithProvider,
|
||||
createSwapsMockStore,
|
||||
} from '../../../../test/jest';
|
||||
import CreateNewSwap from '.';
|
||||
|
||||
const createProps = (customProps = {}) => {
|
||||
return {
|
||||
sensitiveProperties: {},
|
||||
...customProps,
|
||||
};
|
||||
};
|
||||
|
||||
describe('CreateNewSwap', () => {
|
||||
it('renders the component with initial props', () => {
|
||||
const store = configureMockStore()(createSwapsMockStore());
|
||||
const props = createProps();
|
||||
const { getByText } = renderWithProvider(
|
||||
<CreateNewSwap {...props} />,
|
||||
store,
|
||||
);
|
||||
expect(getByText('Create a new swap')).toBeInTheDocument();
|
||||
});
|
||||
});
|
1
ui/pages/swaps/create-new-swap/index.js
Normal file
1
ui/pages/swaps/create-new-swap/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './create-new-swap';
|
8
ui/pages/swaps/create-new-swap/index.scss
Normal file
8
ui/pages/swaps/create-new-swap/index.scss
Normal file
@ -0,0 +1,8 @@
|
||||
.create-new-swap {
|
||||
button {
|
||||
@include H5;
|
||||
|
||||
color: var(--color-primary-default);
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
@import 'swaps-footer/index';
|
||||
@import 'view-quote/index';
|
||||
@import 'import-token/index';
|
||||
@import 'create-new-swap/index';
|
||||
@import 'view-on-block-explorer/index';
|
||||
|
||||
.swaps {
|
||||
display: flex;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { getBlockExplorerLink } from '@metamask/etherscan-link';
|
||||
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import {
|
||||
@ -22,7 +23,9 @@ import {
|
||||
getUSDConversionRate,
|
||||
conversionRateSelector,
|
||||
getCurrentCurrency,
|
||||
getRpcPrefsForCurrentProvider,
|
||||
} from '../../../selectors';
|
||||
import { SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP } from '../../../../shared/constants/swaps';
|
||||
import { getNativeCurrency } from '../../../ducks/metamask/metamask';
|
||||
import {
|
||||
DEFAULT_ROUTE,
|
||||
@ -54,6 +57,8 @@ import {
|
||||
getFeeForSmartTransaction,
|
||||
} from '../swaps.util';
|
||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||
import CreateNewSwap from '../create-new-swap';
|
||||
import ViewOnBlockExplorer from '../view-on-block-explorer';
|
||||
import SuccessIcon from './success-icon';
|
||||
import RevertedIcon from './reverted-icon';
|
||||
import CanceledIcon from './canceled-icon';
|
||||
@ -79,12 +84,17 @@ export default function SmartTransactionStatus() {
|
||||
const smartTransactionsOptInStatus = useSelector(
|
||||
getSmartTransactionsOptInStatus,
|
||||
);
|
||||
const chainId = useSelector(getCurrentChainId);
|
||||
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider, shallowEqual);
|
||||
const swapsNetworkConfig = useSelector(getSwapsNetworkConfig);
|
||||
const smartTransactionsEnabled = useSelector(getSmartTransactionsEnabled);
|
||||
const currentSmartTransactionsEnabled = useSelector(
|
||||
getCurrentSmartTransactionsEnabled,
|
||||
);
|
||||
const chainId = useSelector(getCurrentChainId);
|
||||
const baseNetworkUrl =
|
||||
rpcPrefs.blockExplorerUrl ??
|
||||
SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId] ??
|
||||
null;
|
||||
const nativeCurrencySymbol = useSelector(getNativeCurrency);
|
||||
const conversionRate = useSelector(conversionRateSelector);
|
||||
const USDConversionRate = useSelector(getUSDConversionRate);
|
||||
@ -139,6 +149,7 @@ export default function SmartTransactionStatus() {
|
||||
const showCloseButtonOnly =
|
||||
isSmartTransactionPending ||
|
||||
smartTransactionStatus === SMART_TRANSACTION_STATUSES.SUCCESS;
|
||||
const txHash = latestSmartTransaction?.statusMetadata?.minedHash;
|
||||
|
||||
useEffect(() => {
|
||||
trackEvent({
|
||||
@ -190,6 +201,7 @@ export default function SmartTransactionStatus() {
|
||||
let description;
|
||||
let subDescription;
|
||||
let icon;
|
||||
let blockExplorerUrl;
|
||||
if (isSmartTransactionPending) {
|
||||
if (cancelSwapLinkClicked) {
|
||||
headerText = t('stxTryingToCancel');
|
||||
@ -238,6 +250,12 @@ export default function SmartTransactionStatus() {
|
||||
]);
|
||||
icon = <RevertedIcon />;
|
||||
}
|
||||
if (txHash && latestSmartTransactionUuid) {
|
||||
blockExplorerUrl = getBlockExplorerLink(
|
||||
{ hash: txHash, chainId },
|
||||
{ blockExplorerUrl: baseNetworkUrl },
|
||||
);
|
||||
}
|
||||
|
||||
const showCancelSwapLink =
|
||||
latestSmartTransaction.cancellable && !cancelSwapLinkClicked;
|
||||
@ -397,12 +415,18 @@ export default function SmartTransactionStatus() {
|
||||
{description && (
|
||||
<Typography
|
||||
variant={TYPOGRAPHY.H6}
|
||||
boxProps={{ marginTop: 0 }}
|
||||
boxProps={{ ...(blockExplorerUrl && { margin: [1, 0, 0] }) }}
|
||||
color={COLORS.TEXT_ALTERNATIVE}
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
{blockExplorerUrl && (
|
||||
<ViewOnBlockExplorer
|
||||
blockExplorerUrl={blockExplorerUrl}
|
||||
sensitiveTrackingProperties={sensitiveProperties}
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
marginTop={3}
|
||||
className="smart-transaction-status__background-animation smart-transaction-status__background-animation--bottom"
|
||||
@ -420,6 +444,9 @@ export default function SmartTransactionStatus() {
|
||||
{showCancelSwapLink &&
|
||||
latestSmartTransactionUuid &&
|
||||
isSmartTransactionPending && <CancelSwap />}
|
||||
{smartTransactionStatus === SMART_TRANSACTION_STATUSES.SUCCESS ? (
|
||||
<CreateNewSwap sensitiveTrackingProperties={sensitiveProperties} />
|
||||
) : null}
|
||||
<SwapsFooter
|
||||
onSubmit={async () => {
|
||||
if (showCloseButtonOnly) {
|
||||
|
@ -0,0 +1,13 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ViewOnBlockExplorer renders the component with initial props 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="box view-on-block-explorer box--margin-top-6 box--flex-direction-row"
|
||||
>
|
||||
<button>
|
||||
View Swap at etherscan.io
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
1
ui/pages/swaps/view-on-block-explorer/index.js
Normal file
1
ui/pages/swaps/view-on-block-explorer/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './view-on-block-explorer';
|
8
ui/pages/swaps/view-on-block-explorer/index.scss
Normal file
8
ui/pages/swaps/view-on-block-explorer/index.scss
Normal file
@ -0,0 +1,8 @@
|
||||
.view-on-block-explorer {
|
||||
button {
|
||||
@include H7;
|
||||
|
||||
color: var(--color-primary-default);
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Box from '../../../components/ui/box';
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import { getURLHostName } from '../../../helpers/utils/util';
|
||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||
import { EVENT } from '../../../../shared/constants/metametrics';
|
||||
|
||||
export default function ViewOnBlockExplorer({
|
||||
blockExplorerUrl,
|
||||
sensitiveTrackingProperties,
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
const blockExplorerHostName = getURLHostName(blockExplorerUrl);
|
||||
|
||||
return (
|
||||
<Box marginTop={6} className="view-on-block-explorer">
|
||||
<button
|
||||
onClick={() => {
|
||||
trackEvent({
|
||||
event: 'Clicked Block Explorer Link',
|
||||
category: EVENT.CATEGORIES.SWAPS,
|
||||
sensitiveProperties: sensitiveTrackingProperties,
|
||||
properties: {
|
||||
link_type: 'Transaction Block Explorer',
|
||||
action: 'Swap Transaction',
|
||||
block_explorer_domain: blockExplorerHostName,
|
||||
},
|
||||
});
|
||||
global.platform.openTab({ url: blockExplorerUrl });
|
||||
}}
|
||||
>
|
||||
{t('viewOnCustomBlockExplorer', [
|
||||
t('blockExplorerSwapAction'),
|
||||
blockExplorerHostName,
|
||||
])}
|
||||
</button>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
ViewOnBlockExplorer.propTypes = {
|
||||
blockExplorerUrl: PropTypes.string.isRequired,
|
||||
sensitiveTrackingProperties: PropTypes.object.isRequired,
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
import { renderWithProvider } from '../../../../test/jest';
|
||||
import ViewOnBlockExplorer from '.';
|
||||
|
||||
const createProps = (customProps = {}) => {
|
||||
return {
|
||||
txHash:
|
||||
'0x58e5a0fc7fbc849eddc100d44e86276168a8c7baaa5604e44ba6f5eb8ba1b7eb',
|
||||
blockExplorerUrl: 'https://etherscan.io',
|
||||
...customProps,
|
||||
};
|
||||
};
|
||||
|
||||
describe('ViewOnBlockExplorer', () => {
|
||||
it('renders the component with initial props', () => {
|
||||
const { container, getByText } = renderWithProvider(
|
||||
<ViewOnBlockExplorer {...createProps()} />,
|
||||
);
|
||||
expect(getByText('View Swap at etherscan.io')).toBeInTheDocument();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user