Skip to content

Commit f93f627

Browse files
authored
fix: cp-7.60.0 Generate correct blockchain explorer urls on bridge txs (#23273)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Fix an issue where the blockchain explorer urls were not generated successfully when bridging assets. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Generate correct blockchain explorer URLs when bridging assets ## **Related issues** Fixes: #23171 ## **Manual testing steps** ```gherkin Ensure that the correct blockchain URLs are generated when visiting the transaction details screen after bridging/swapping assets. Also ensure that the correct URLs are also generated for old bridge/swaps transactions (no regressions). ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Corrects multichain block explorer URL generation for bridge transactions with proper EVM/non-EVM handling and comprehensive tests. > > - **Bridge Hook (`useMultichainBlockExplorerTxUrl`)**: > - Uses `useBlockExplorer` to resolve EVM explorer base URLs via `getEvmBlockExplorerUrl` with fallback to `getEtherscanBaseUrl`. > - Builds EVM tx links with `etherscan-link.createCustomExplorerLink`. > - Keeps non-EVM (e.g., Solana) URLs via `getTransactionUrl`; derives explorer name from URL or `useBlockExplorer`. > - Derives `explorerName`, `chainName`, and `networkImageSource` consistently (EVM via CAIP/hex; non-EVM via config). > - **Hook Tests** (`useMultichainBlockExplorerTxUrl.test.tsx`): > - Add extensive coverage for parameter validation, EVM/non-EVM paths, fallback logic, explorer name resolution, network image sourcing, and custom network configs. > - Mocks external utilities (`etherscan-link`, `useBlockExplorer`, `getEtherscanBaseUrl`, network utils). > - **Block Explorer Modal Test** (`BlockExplorersModal.test.tsx`): > - Adjust expectations to show one `Etherscan` and one `Optimistic` button instead of two `Etherscan`. > - **`useBlockExplorer`**: > - Exposes `getEvmBlockExplorerUrl` in the returned API. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fe97a35. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 94507ac commit f93f627

File tree

4 files changed

+529
-53
lines changed

4 files changed

+529
-53
lines changed

app/components/UI/Bridge/components/TransactionDetails/BlockExplorersModal.test.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ describe('BlockExplorersModal', () => {
7171
},
7272
{ state: mockState },
7373
);
74-
const etherscanButtons = getAllByText('Etherscan');
75-
expect(etherscanButtons).toHaveLength(2);
74+
const etherscanButton = getAllByText('Etherscan');
75+
expect(etherscanButton).toHaveLength(1);
76+
77+
const optimisticButton = getAllByText('Optimistic');
78+
expect(optimisticButton).toHaveLength(1);
7679
});
7780

7881
it('should handle missing destination chain transaction hash', () => {

app/components/UI/Bridge/hooks/useMultichainBlockExplorerTxUrl/index.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ import {
33
formatChainIdToCaip,
44
isNonEvmChainId,
55
} from '@metamask/bridge-controller';
6+
import etherscanLink from '@metamask/etherscan-link';
67
import { useSelector } from 'react-redux';
78
import {
89
createProviderConfig,
910
selectEvmNetworkConfigurationsByChainId,
1011
} from '../../../../../selectors/networkController';
1112
import { useMemo } from 'react';
1213
import { NetworkConfiguration } from '@metamask/network-controller';
13-
import useBlockExplorer from '../../../Swaps/utils/useBlockExplorer';
14+
import useBlockExplorer from '../../../../hooks/useBlockExplorer';
1415
import { getTransactionUrl } from '../../../../../core/Multichain/utils';
1516
import {
1617
getBlockExplorerName,
1718
getNetworkImageSource,
1819
} from '../../../../../util/networks';
1920
import { Hex } from '@metamask/utils';
2021
import { selectNonEvmNetworkConfigurationsByChainId } from '../../../../../selectors/multichainNetworkController';
21-
22-
const useEvmBlockExplorer = useBlockExplorer;
22+
import { getEtherscanBaseUrl } from '../../../../../util/etherscan';
2323

2424
const getProviderConfigForNetwork = (networkConfig: NetworkConfiguration) => {
2525
const rpcEndpoint =
@@ -66,10 +66,7 @@ export const useMultichainBlockExplorerTxUrl = ({
6666
[evmNetworkConfig],
6767
);
6868

69-
const evmExplorer = useEvmBlockExplorer(
70-
evmNetworkConfigurations,
71-
evmProviderConfig,
72-
);
69+
const blockExplorer = useBlockExplorer();
7370

7471
// Handle undefined cases
7572
if (!chainId || !txHash) {
@@ -85,7 +82,11 @@ export const useMultichainBlockExplorerTxUrl = ({
8582
explorerTxUrl = getTransactionUrl(txHash, formatChainIdToCaip(chainId));
8683
} else {
8784
// EVM
88-
explorerTxUrl = evmExplorer.tx(txHash);
85+
const baseUrl =
86+
blockExplorer.getEvmBlockExplorerUrl(formatChainIdToHex(chainId)) ??
87+
getEtherscanBaseUrl(evmProviderConfig?.type ?? '');
88+
89+
explorerTxUrl = etherscanLink.createCustomExplorerLink(txHash, baseUrl);
8990
}
9091

9192
// Get network image source
@@ -97,7 +98,7 @@ export const useMultichainBlockExplorerTxUrl = ({
9798
const explorerName =
9899
isNonEvm && explorerTxUrl
99100
? getBlockExplorerName(explorerTxUrl)
100-
: evmExplorer.name;
101+
: blockExplorer.getBlockExplorerName(formatChainIdToCaip(chainId));
101102

102103
const chainName =
103104
isNonEvm && formattedChainId

0 commit comments

Comments
 (0)