Skip to content

Commit f58da28

Browse files
committed
chore(runway): cherry-pick fix: cp-12.18.0 Infinite loader on approve request (#32548)
<!-- 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** <!-- 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? --> This PR aims to fix infinite loader on `approve` request described here: #32489 (comment) [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/32548?quickstart=1) ## **Related issues** Fixes: #32489 ## **Manual testing steps** 1. Connect to a dapp 2. Switch to Base 3. Select WETH 4. Trigger Approval ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/9ac4185c-f921-4178-ae51-2edb608578e2 ## **Pre-merge author checklist** - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/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-extension/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 12c3d6b commit f58da28

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

test/integration/confirmations/transactions/erc20-approve.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ describe('ERC20 Approve Confirmation', () => {
145145
beforeEach(() => {
146146
jest.resetAllMocks();
147147
setupSubmitRequestToBackgroundMocks({
148-
getTokenStandardAndDetails: {
148+
getTokenStandardAndDetailsByChain: {
149149
standard: TokenStandard.ERC20,
150150
},
151151
});

test/integration/confirmations/transactions/increase-allowance.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ describe('ERC20 increaseAllowance Confirmation', () => {
144144
beforeEach(() => {
145145
jest.resetAllMocks();
146146
setupSubmitRequestToBackgroundMocks({
147-
getTokenStandardAndDetails: {
147+
getTokenStandardAndDetailsByChain: {
148148
standard: TokenStandard.ERC20,
149149
},
150150
});

ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts

+23-14
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,29 @@ import {
66
} from '../../../../../../../../test/data/confirmations/contract-interaction';
77
import mockState from '../../../../../../../../test/data/mock-state.json';
88
import { renderHookWithProvider } from '../../../../../../../../test/lib/render-helpers';
9-
import { getTokenStandardAndDetails } from '../../../../../../../store/actions';
9+
import { getTokenStandardAndDetailsByChain } from '../../../../../../../store/actions';
1010
import { useIsNFT } from './use-is-nft';
1111

1212
jest.mock('../../../../../../../store/actions', () => ({
1313
...jest.requireActual('../../../../../../../store/actions'),
14-
getTokenStandardAndDetails: jest.fn(),
14+
getTokenStandardAndDetailsByChain: jest.fn(),
1515
}));
1616

1717
describe('useIsNFT', () => {
18-
it('identifies NFT in token with 0 decimals', async () => {
19-
const getTokenStandardAndDetailsMock = jest
20-
.fn()
21-
.mockImplementation(() => ({ standard: TokenStandard.ERC721 }));
18+
const mockGetTokenStandardAndDetailsByChain = jest.mocked(
19+
getTokenStandardAndDetailsByChain,
20+
);
2221

23-
(getTokenStandardAndDetails as jest.Mock).mockImplementation(
24-
getTokenStandardAndDetailsMock,
22+
beforeEach(() => {
23+
jest.clearAllMocks();
24+
mockGetTokenStandardAndDetailsByChain.mockImplementation(() =>
25+
Promise.resolve({
26+
standard: TokenStandard.ERC721,
27+
}),
2528
);
29+
});
2630

31+
it('identifies NFT in token with 0 decimals', async () => {
2732
const transactionMeta = genUnapprovedContractInteractionConfirmation({
2833
address: CONTRACT_INTERACTION_SENDER_ADDRESS,
2934
}) as TransactionMeta;
@@ -36,15 +41,19 @@ describe('useIsNFT', () => {
3641
await waitForNextUpdate();
3742

3843
expect(result.current.isNFT).toMatchInlineSnapshot(`true`);
44+
expect(mockGetTokenStandardAndDetailsByChain).toHaveBeenCalledWith(
45+
transactionMeta.txParams.to,
46+
transactionMeta.txParams.from,
47+
undefined,
48+
transactionMeta.chainId,
49+
);
3950
});
4051

4152
it('identifies fungible in token with greater than 0 decimals', async () => {
42-
const getTokenStandardAndDetailsMock = jest
43-
.fn()
44-
.mockImplementation(() => ({ standard: TokenStandard.ERC20 }));
45-
46-
(getTokenStandardAndDetails as jest.Mock).mockImplementation(
47-
getTokenStandardAndDetailsMock,
53+
mockGetTokenStandardAndDetailsByChain.mockImplementation(() =>
54+
Promise.resolve({
55+
standard: TokenStandard.ERC20,
56+
}),
4857
);
4958

5059
const transactionMeta = genUnapprovedContractInteractionConfirmation({

ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { TransactionMeta } from '@metamask/transaction-controller';
22
import { TokenStandard } from '../../../../../../../../shared/constants/transaction';
33
import { useAsyncResult } from '../../../../../../../hooks/useAsync';
4-
import { getTokenStandardAndDetails } from '../../../../../../../store/actions';
4+
import { getTokenStandardAndDetailsByChain } from '../../../../../../../store/actions';
55

66
export const useIsNFT = (
77
transactionMeta: TransactionMeta,
88
): { isNFT: boolean; pending: boolean } => {
99
const { value, pending } = useAsyncResult(async () => {
10-
return await getTokenStandardAndDetails(
10+
return await getTokenStandardAndDetailsByChain(
1111
transactionMeta?.txParams?.to as string,
12+
transactionMeta?.txParams?.from as string,
13+
undefined,
14+
transactionMeta?.chainId as string,
1215
);
1316
}, [transactionMeta?.txParams?.to]);
1417

0 commit comments

Comments
 (0)