Skip to content

Commit 5832ebb

Browse files
chore(runway): cherry-pick fix: cp-7.60.0 Generate correct blockchain explorer urls on bridge txs (#23311)
- 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] > Fixes bridge transaction explorer URL generation across EVM and non‑EVM chains with proper fallbacks and updates tests accordingly. > > - **Bridge Hook (`useMultichainBlockExplorerTxUrl`)**: > - Switches to `useBlockExplorer` from `app/components/hooks` and uses `getEvmBlockExplorerUrl` to derive EVM explorer base URLs. > - Falls back to `getEtherscanBaseUrl` and builds links via `@metamask/etherscan-link` when custom explorer is unavailable. > - Determines explorer names via URL for non‑EVM and via `blockExplorer.getBlockExplorerName` for EVM. > - Keeps network image sourcing and chain name resolution, handling unknown networks gracefully. > - **Hook Tests** (`useMultichainBlockExplorerTxUrl.test.tsx`): > - Comprehensive coverage for parameter validation, EVM (mainnet, Optimism, Polygon) and non‑EVM (Solana) paths, fallbacks, explorer name resolution, network image sourcing, and edge cases. > - **Modal Test** (`BlockExplorersModal.test.tsx`): > - Updates expectations to one `Etherscan` and one `Optimistic` button. > - **Block Explorer Hook** (`useBlockExplorer.ts`): > - Exposes `getEvmBlockExplorerUrl` in returned API. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4b8a441. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [f93f627](f93f627) Co-authored-by: George Gkasdrogkas <georgegkas@gmail.com>
1 parent bc8b143 commit 5832ebb

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)