Skip to content

Commit b83ac8f

Browse files
fix: cp-7.45.0 use correct default etherscan link on tx details (#14847)
## **Description** This updates the default etherscan link to be `etherscan.io` ## **Related issues** Fixes: #14767 ## **Manual testing steps** See repro steps in issue . ## **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.
1 parent 42a5fdf commit b83ac8f

File tree

2 files changed

+114
-92
lines changed

2 files changed

+114
-92
lines changed

app/components/UI/TransactionElement/TransactionDetails/index.test.tsx

Lines changed: 113 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../../util/test/accountsCo
77
import renderWithProvider from '../../../../util/test/renderWithProvider';
88
import { createStackNavigator } from '@react-navigation/stack';
99
import { mockNetworkState } from '../../../../util/test/network';
10+
import type { NetworkState } from '@metamask/network-controller';
1011

1112
const Stack = createStackNavigator();
1213
const mockEthQuery = {
@@ -55,13 +56,6 @@ const initialState = {
5556
...backgroundState,
5657
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
5758
},
58-
// NetworkController: {
59-
// ...mockNetworkState({
60-
// chainId: '0x89',
61-
// id: 'Polygon',
62-
// nickname: 'Polygon',
63-
// }),
64-
// },
6559
SmartTransactionsController: {
6660
smartTransactionsState: {
6761
liveness: 'live',
@@ -219,112 +213,140 @@ describe('TransactionDetails', () => {
219213
expect(toJSON()).toMatchSnapshot();
220214
});
221215

222-
it('should view transaction details on etherscan', () => {
216+
const arrangeBlockExplorerTest = () => {
223217
jest.mocked(query).mockResolvedValueOnce(123).mockResolvedValueOnce({
224218
timestamp: 1234,
225219
l1Fee: '0x1',
226220
});
227221

228-
const { getByText } = renderComponent({
229-
state: {
230-
...initialState,
231-
engine: {
232-
...initialState.engine,
233-
backgroundState: {
234-
...initialState.engine.backgroundState,
235-
NetworkController: {
236-
'0x1': {
237-
chainId: '0x1',
238-
blockExplorerUrls: [],
239-
rpcEndpoints: [
240-
{
241-
rpcUrl: 'https://mainnet.infura.io/v3/123',
242-
chainId: '0x1',
243-
nickname: 'Mainnet',
244-
ticker: 'ETH',
245-
},
246-
],
247-
defaultRpcEndpointIndex: 0,
248-
name: 'Mainnet',
249-
nativeCurrency: 'ETH',
250-
},
222+
const mockState = {
223+
...initialState,
224+
engine: {
225+
...initialState.engine,
226+
backgroundState: {
227+
...initialState.engine.backgroundState,
228+
NetworkController: {
229+
'0x1': {
230+
chainId: '0x1',
231+
blockExplorerUrls: [],
232+
rpcEndpoints: [
233+
{
234+
rpcUrl: 'https://mainnet.infura.io/v3/123',
235+
chainId: '0x1',
236+
nickname: 'Mainnet',
237+
ticker: 'ETH',
238+
},
239+
],
240+
defaultRpcEndpointIndex: 0,
241+
name: 'Mainnet',
242+
nativeCurrency: 'ETH',
251243
},
252-
},
244+
} as unknown as NetworkState,
253245
},
254246
},
255-
hash: '0x3',
256-
txParams: {
257-
multiLayerL1FeeTotal: '0x1',
247+
};
248+
249+
const mockProps = {
250+
networkId: '0x1',
251+
};
252+
253+
return {
254+
mockState,
255+
mockProps,
256+
};
257+
};
258+
259+
const arrangeActAssertBlockExplorerTest = (props: {
260+
buttonText: string;
261+
expectedUrl: string;
262+
overrideMocks?: (
263+
mocks: ReturnType<typeof arrangeBlockExplorerTest>,
264+
) => void;
265+
}) => {
266+
// Arrange
267+
const mocks = arrangeBlockExplorerTest();
268+
props.overrideMocks?.(mocks);
269+
270+
const { getByText } = renderComponent({
271+
state: mocks.mockState,
272+
networkId: mocks.mockProps.networkId,
273+
});
274+
275+
fireEvent.press(getByText(props.buttonText));
276+
277+
expect(navigationMock.push).toHaveBeenCalledWith('Webview', {
278+
params: expect.objectContaining({ url: props.expectedUrl }),
279+
screen: 'SimpleWebview',
280+
});
281+
};
282+
283+
it('should view transaction details on etherscan', () => {
284+
arrangeActAssertBlockExplorerTest({
285+
overrideMocks: (mocks) => {
286+
mocks.mockState.engine.backgroundState.NetworkController =
287+
mockNetworkState({
288+
chainId: '0x1',
289+
id: 'mainnet',
290+
nickname: 'Ethereum Mainnet',
291+
ticker: 'ETH',
292+
});
293+
mocks.mockProps.networkId = '0x1';
258294
},
295+
buttonText: 'VIEW ON Etherscan',
296+
expectedUrl: 'https://etherscan.io/tx/0x3',
259297
});
260-
const etherscanButton = getByText('VIEW ON Etherscan');
261-
expect(etherscanButton).toBeDefined();
262-
fireEvent.press(etherscanButton);
263-
expect(navigationMock.push).toHaveBeenCalled();
264298
});
265299

266300
it('should display explorer link for linea mainnet', () => {
267-
jest.mocked(query).mockResolvedValueOnce(123).mockResolvedValueOnce({
268-
timestamp: 1234,
269-
l1Fee: '0x1',
270-
});
271-
272-
const { getByText } = renderComponent({
273-
state: {
274-
...initialState,
275-
engine: {
276-
...initialState.engine,
277-
backgroundState: {
278-
...initialState.engine.backgroundState,
279-
NetworkController: {
280-
...mockNetworkState({
281-
chainId: '0xe708',
282-
id: 'linea',
283-
nickname: 'Linea Mainnet',
284-
ticker: 'ETH',
285-
}),
286-
},
287-
},
288-
},
301+
arrangeActAssertBlockExplorerTest({
302+
overrideMocks: (mocks) => {
303+
mocks.mockState.engine.backgroundState.NetworkController =
304+
mockNetworkState({
305+
chainId: '0xe708',
306+
id: 'linea',
307+
nickname: 'Linea Mainnet',
308+
ticker: 'ETH',
309+
});
310+
mocks.mockProps.networkId = '0xe708';
289311
},
290-
networkId: '0xe708',
312+
buttonText: 'VIEW ON Lineascan',
313+
expectedUrl: 'https://lineascan.build/tx/0x3',
291314
});
292-
const etherscanButton = getByText('VIEW ON Lineascan');
293-
expect(etherscanButton).toBeDefined();
294-
fireEvent.press(etherscanButton);
295-
expect(navigationMock.push).toHaveBeenCalled();
296315
});
297316

298317
it('should display explorer link for sepolia mainnet', () => {
299-
jest.mocked(query).mockResolvedValueOnce(123).mockResolvedValueOnce({
300-
timestamp: 1234,
301-
l1Fee: '0x1',
318+
arrangeActAssertBlockExplorerTest({
319+
overrideMocks: (mocks) => {
320+
mocks.mockState.engine.backgroundState.NetworkController =
321+
mockNetworkState({
322+
chainId: '0xaa36a7',
323+
id: 'sepolia',
324+
nickname: 'Sepolia Mainnet',
325+
ticker: 'ETH',
326+
});
327+
mocks.mockProps.networkId = '0xaa36a7';
328+
},
329+
buttonText: 'VIEW ON Sepolia',
330+
expectedUrl: 'https://sepolia.etherscan.io/tx/0x3',
302331
});
332+
});
303333

304-
const { getByText } = renderComponent({
305-
state: {
306-
...initialState,
307-
engine: {
308-
...initialState.engine,
309-
backgroundState: {
310-
...initialState.engine.backgroundState,
311-
NetworkController: {
312-
...mockNetworkState({
313-
chainId: '0xaa36a7',
314-
id: 'sepolia',
315-
nickname: 'Sepolia Mainnet',
316-
ticker: 'ETH',
317-
}),
318-
},
319-
},
320-
},
334+
it('should display explorer link for custom network', () => {
335+
arrangeActAssertBlockExplorerTest({
336+
overrideMocks: (mocks) => {
337+
mocks.mockState.engine.backgroundState.NetworkController =
338+
mockNetworkState({
339+
chainId: '0x1337',
340+
id: '123-123-123',
341+
nickname: 'My Custom Network',
342+
ticker: 'FOO',
343+
blockExplorerUrl: 'https://custom-block-explorer.net',
344+
});
345+
mocks.mockProps.networkId = '0x1337';
321346
},
322-
networkId: '0xaa36a7',
347+
buttonText: 'VIEW ON Custom-block-explorer',
348+
expectedUrl: 'https://custom-block-explorer.net/tx/0x3',
323349
});
324-
const etherscanButton = getByText('VIEW ON Sepolia');
325-
expect(etherscanButton).toBeDefined();
326-
fireEvent.press(etherscanButton);
327-
expect(navigationMock.push).toHaveBeenCalled();
328350
});
329351

330352
it('should render speed up and cancel buttons', async () => {

app/constants/urls.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const MM_ETHERSCAN_URL = 'https://etherscamdb.info/domain/meta-mask.com';
5050
export const LINEA_GOERLI_BLOCK_EXPLORER = 'https://goerli.lineascan.build';
5151
export const LINEA_SEPOLIA_BLOCK_EXPLORER = 'https://sepolia.lineascan.build';
5252
export const LINEA_MAINNET_BLOCK_EXPLORER = 'https://lineascan.build';
53-
export const MAINNET_BLOCK_EXPLORER = 'https://etherscan.com';
53+
export const MAINNET_BLOCK_EXPLORER = 'https://etherscan.io';
5454
export const SEPOLIA_BLOCK_EXPLORER = 'https://sepolia.etherscan.io';
5555

5656
// Rpcs

0 commit comments

Comments
 (0)