Skip to content

Commit b170211

Browse files
authored
Fix to infinite loading on approve screen (#14756)
1 parent 496d9d8 commit b170211

File tree

6 files changed

+299
-19
lines changed

6 files changed

+299
-19
lines changed

app/_locales/en/messages.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/hooks/useAssetDetails.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
import { useState, useEffect } from 'react';
22
import { useSelector, useDispatch } from 'react-redux';
33
import { parseStandardTokenTransactionData } from '../../shared/modules/transaction.utils';
4-
import { getCollectibles, getTokens } from '../ducks/metamask/metamask';
4+
import { getCollectibles } from '../ducks/metamask/metamask';
55
import { ERC1155, ERC721, ERC20 } from '../helpers/constants/common';
66
import {
77
calcTokenAmount,
88
getAssetDetails,
99
getTokenAddressParam,
1010
getTokenValueParam,
1111
} from '../helpers/utils/token-util';
12-
import { getTokenList } from '../selectors';
1312
import { hideLoadingIndication, showLoadingIndication } from '../store/actions';
1413
import { usePrevious } from './usePrevious';
1514

1615
export function useAssetDetails(tokenAddress, userAddress, transactionData) {
1716
const dispatch = useDispatch();
1817
// state selectors
19-
const tokens = useSelector(getTokens);
2018
const collectibles = useSelector(getCollectibles);
21-
const tokenList = useSelector(getTokenList);
2219

2320
// in-hook state
2421
const [currentAsset, setCurrentAsset] = useState(null);
@@ -36,8 +33,6 @@ export function useAssetDetails(tokenAddress, userAddress, transactionData) {
3633
userAddress,
3734
transactionData,
3835
collectibles,
39-
tokens,
40-
tokenList,
4136
);
4237
setCurrentAsset(assetDetails);
4338
dispatch(hideLoadingIndication());
@@ -58,8 +53,6 @@ export function useAssetDetails(tokenAddress, userAddress, transactionData) {
5853
userAddress,
5954
transactionData,
6055
collectibles,
61-
tokens,
62-
tokenList,
6356
]);
6457

6558
let assetStandard,
@@ -83,11 +76,13 @@ export function useAssetDetails(tokenAddress, userAddress, transactionData) {
8376
balance,
8477
decimals: currentAssetDecimals,
8578
} = currentAsset;
79+
8680
const tokenData = parseStandardTokenTransactionData(transactionData);
8781
assetStandard = standard;
8882
assetAddress = tokenAddress;
89-
tokenSymbol = symbol;
83+
tokenSymbol = symbol ?? '';
9084
tokenImage = image;
85+
9186
toAddress = getTokenAddressParam(tokenData);
9287
if (assetStandard === ERC721 || assetStandard === ERC1155) {
9388
assetName = name;
@@ -101,6 +96,7 @@ export function useAssetDetails(tokenAddress, userAddress, transactionData) {
10196
calcTokenAmount(getTokenValueParam(tokenData), decimals).toString(10);
10297
}
10398
}
99+
104100
return {
105101
assetStandard,
106102
assetName,

ui/hooks/useAssetDetails.test.js

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import React from 'react';
2+
import { Provider } from 'react-redux';
3+
import { renderHook } from '@testing-library/react-hooks';
4+
5+
import configureStore from '../store/store';
6+
import * as tokenUtils from '../helpers/utils/token-util';
7+
import { ERC1155, ERC20, ERC721 } from '../helpers/constants/common';
8+
import { useAssetDetails } from './useAssetDetails';
9+
10+
const renderUseAssetDetails = ({
11+
tokenAddress,
12+
userAddress,
13+
transactionData,
14+
}) => {
15+
const mockState = {
16+
metamask: {
17+
provider: {
18+
type: 'test',
19+
chainId: '0x3',
20+
},
21+
tokenList: {},
22+
},
23+
};
24+
25+
const wrapper = ({ children }) => (
26+
<Provider store={configureStore(mockState)}>{children}</Provider>
27+
);
28+
29+
return renderHook(
30+
() => useAssetDetails(tokenAddress, userAddress, transactionData),
31+
{ wrapper },
32+
);
33+
};
34+
35+
describe('useAssetDetails', () => {
36+
let getAssetDetailsStub;
37+
beforeEach(() => {
38+
getAssetDetailsStub = jest
39+
.spyOn(tokenUtils, 'getAssetDetails')
40+
.mockImplementation(() => Promise.resolve({}));
41+
});
42+
it('should return object with tokenSymbol set to and empty string, when getAssetDetails returns and empty object', async () => {
43+
const toAddress = '000000000000000000000000000000000000dead';
44+
const tokenAddress = '0x1';
45+
46+
const transactionData = `0xa9059cbb000000000000000000000000${toAddress}000000000000000000000000000000000000000000000000016345785d8a0000`;
47+
48+
const { result, waitForNextUpdate } = renderUseAssetDetails({
49+
tokenAddress,
50+
userAddress: '0x111',
51+
transactionData,
52+
});
53+
54+
await waitForNextUpdate();
55+
56+
expect(result.current).toStrictEqual({
57+
assetAddress: tokenAddress,
58+
assetName: undefined,
59+
assetStandard: undefined,
60+
decimals: undefined,
61+
toAddress: `0x${toAddress}`,
62+
tokenAmount: undefined,
63+
tokenId: undefined,
64+
tokenImage: undefined,
65+
tokenSymbol: '',
66+
tokenValue: undefined,
67+
userBalance: undefined,
68+
});
69+
});
70+
71+
it('should return object with correct tokenValues for an ERC20 token', async () => {
72+
const userAddress = '0xf04a5cc80b1e94c69b48f5ee68a08cd2f09a7c3e';
73+
const tokenAddress = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
74+
const toAddress = '000000000000000000000000000000000000dead';
75+
const transactionData = `0xa9059cbb000000000000000000000000${toAddress}00000000000000000000000000000000000000000000000000000000000001f4`;
76+
77+
const standard = ERC20;
78+
const symbol = 'WETH';
79+
const balance = '1';
80+
const decimals = 18;
81+
82+
getAssetDetailsStub.mockImplementation(() =>
83+
Promise.resolve({
84+
standard,
85+
symbol,
86+
balance,
87+
decimals,
88+
}),
89+
);
90+
91+
const { result, waitForNextUpdate } = renderUseAssetDetails({
92+
tokenAddress,
93+
userAddress,
94+
transactionData,
95+
});
96+
97+
await waitForNextUpdate();
98+
99+
expect(result.current).toStrictEqual({
100+
assetAddress: tokenAddress,
101+
assetName: undefined,
102+
assetStandard: standard,
103+
decimals,
104+
toAddress: `0x${toAddress}`,
105+
tokenAmount: '0.0000000000000005',
106+
tokenId: undefined,
107+
tokenImage: undefined,
108+
tokenSymbol: symbol,
109+
tokenValue: undefined,
110+
userBalance: balance,
111+
});
112+
});
113+
114+
it('should return object with correct tokenValues for an ERC721 token', async () => {
115+
const tokenAddress = '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D';
116+
const toAddress = '000000000000000000000000000000000000dead';
117+
const transactionData = `0x23b872dd000000000000000000000000a544eebe103733f22ef62af556023bc918b73d36000000000000000000000000${toAddress}000000000000000000000000000000000000000000000000000000000000000c`;
118+
119+
const symbol = 'BAYC';
120+
const tokenId = '12';
121+
const name = 'BoredApeYachtClub';
122+
const image =
123+
'https://bafybeihw3gvmthmvrenfmcvagtais5tv7r4nmiezgsv7nyknjubxw4lite.ipfs.dweb.link';
124+
const standard = ERC721;
125+
126+
getAssetDetailsStub.mockImplementation(() =>
127+
Promise.resolve({
128+
standard,
129+
symbol,
130+
name,
131+
tokenId,
132+
image,
133+
}),
134+
);
135+
136+
const { result, waitForNextUpdate } = renderUseAssetDetails({
137+
tokenAddress,
138+
transactionData,
139+
});
140+
141+
await waitForNextUpdate();
142+
143+
expect(result.current).toStrictEqual({
144+
assetAddress: tokenAddress,
145+
assetName: name,
146+
assetStandard: standard,
147+
decimals: undefined,
148+
toAddress: `0x${toAddress}`,
149+
tokenId,
150+
tokenImage: image,
151+
tokenSymbol: symbol,
152+
tokenValue: undefined,
153+
userBalance: undefined,
154+
tokenAmount: undefined,
155+
});
156+
});
157+
158+
it('should return object with correct tokenValues for an ERC1155 token', async () => {
159+
const tokenAddress = '0x76BE3b62873462d2142405439777e971754E8E77';
160+
const toAddress = '000000000000000000000000000000000000dead';
161+
const transactionData = `0xf242432a000000000000000000000000a544eebe103733f22ef62af556023bc918b73d36000000000000000000000000000000000000000000000000000000000000dead0000000000000000000000000000000000000000000000000000000000000322000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000`;
162+
163+
const tokenId = '121';
164+
const image =
165+
'https://bafybeihw3gvmthmvrenfmcvagtais5tv7r4nmiezgsv7nyknjubxw4lite.ipfs.dweb.link';
166+
const standard = ERC1155;
167+
168+
getAssetDetailsStub.mockImplementation(() =>
169+
Promise.resolve({
170+
standard,
171+
tokenId,
172+
image,
173+
}),
174+
);
175+
176+
const { result, waitForNextUpdate } = renderUseAssetDetails({
177+
tokenAddress,
178+
transactionData,
179+
});
180+
181+
await waitForNextUpdate();
182+
183+
expect(result.current).toStrictEqual({
184+
assetAddress: tokenAddress,
185+
assetName: undefined,
186+
assetStandard: standard,
187+
decimals: undefined,
188+
toAddress: `0x${toAddress}`,
189+
tokenId: undefined,
190+
tokenImage: image,
191+
tokenSymbol: '',
192+
tokenValue: undefined,
193+
userBalance: undefined,
194+
tokenAmount: undefined,
195+
});
196+
});
197+
});

0 commit comments

Comments
 (0)