-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: fetch latest src token balance
- Loading branch information
Showing
5 changed files
with
165 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { BigNumber } from 'ethers'; | ||
import { renderHookWithProvider } from '../../../test/lib/render-helpers'; | ||
import { CHAIN_IDS } from '../../../shared/constants/network'; | ||
import { createBridgeMockStore } from '../../../test/jest/mock-store'; | ||
import { zeroAddress } from '../../__mocks__/ethereumjs-util'; | ||
import { createTestProviderTools } from '../../../test/stub/provider'; | ||
import * as tokenutil from '../../../shared/lib/token-util'; | ||
import useLatestBalance from './useLatestBalance'; | ||
|
||
const mockGetBalance = jest.fn(); | ||
jest.mock('@ethersproject/providers', () => { | ||
return { | ||
Web3Provider: jest.fn().mockImplementation(() => { | ||
return { | ||
getBalance: mockGetBalance, | ||
}; | ||
}), | ||
}; | ||
}); | ||
|
||
const mockFetchTokenBalance = jest.spyOn(tokenutil, 'fetchTokenBalance'); | ||
jest.mock('../../../shared/lib/token-util', () => ({ | ||
...jest.requireActual('../../../shared/lib/token-util'), | ||
fetchTokenBalance: jest.fn(), | ||
})); | ||
|
||
const renderUseLatestBalance = ( | ||
token: { address: string; decimals?: number | string }, | ||
chainId: string, | ||
mockStoreState: object, | ||
) => | ||
renderHookWithProvider( | ||
() => useLatestBalance(token as any, chainId as any), | ||
mockStoreState, | ||
); | ||
|
||
describe('useLatestBalance', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
const { provider } = createTestProviderTools({ | ||
networkId: 'Ethereum', | ||
chainId: CHAIN_IDS.MAINNET, | ||
}); | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
global.ethereumProvider = provider as any; | ||
}); | ||
|
||
it('returns formattedBalance for native asset in current chain', async () => { | ||
mockGetBalance.mockResolvedValue(BigNumber.from('1000000000000000000')); | ||
|
||
const { result, waitForNextUpdate } = renderUseLatestBalance( | ||
{ address: zeroAddress() }, | ||
CHAIN_IDS.MAINNET, | ||
createBridgeMockStore(), | ||
); | ||
|
||
await waitForNextUpdate(); | ||
expect(result.current.formattedBalance).toStrictEqual('1'); | ||
|
||
expect(mockGetBalance).toHaveBeenCalledTimes(1); | ||
expect(mockGetBalance).toHaveBeenCalledWith( | ||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', | ||
); | ||
expect(mockFetchTokenBalance).toHaveBeenCalledTimes(0); | ||
}); | ||
|
||
it('returns formattedBalance for ERC20 asset in current chain', async () => { | ||
mockFetchTokenBalance.mockResolvedValueOnce(BigNumber.from('15390000')); | ||
|
||
const { result, waitForNextUpdate } = renderUseLatestBalance( | ||
{ address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', decimals: '6' }, | ||
CHAIN_IDS.MAINNET, | ||
createBridgeMockStore(), | ||
); | ||
|
||
await waitForNextUpdate(); | ||
expect(result.current.formattedBalance).toStrictEqual('15.39'); | ||
|
||
expect(mockFetchTokenBalance).toHaveBeenCalledTimes(1); | ||
expect(mockFetchTokenBalance).toHaveBeenCalledWith( | ||
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', | ||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', | ||
global.ethereumProvider, | ||
); | ||
expect(mockGetBalance).toHaveBeenCalledTimes(0); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { useSelector } from 'react-redux'; | ||
import { zeroAddress } from 'ethereumjs-util'; | ||
import { Web3Provider } from '@ethersproject/providers'; | ||
import { Hex } from '@metamask/utils'; | ||
import { BigNumber } from 'ethers'; | ||
import { Numeric } from '../../../shared/modules/Numeric'; | ||
import { DEFAULT_PRECISION } from '../useCurrencyDisplay'; | ||
import { fetchTokenBalance } from '../../../shared/lib/token-util'; | ||
import { | ||
getCurrentChainId, | ||
getSelectedInternalAccount, | ||
SwapsEthToken, | ||
} from '../../selectors'; | ||
import { SwapsTokenObject } from '../../../shared/constants/swaps'; | ||
import { useAsyncResult } from '../useAsyncResult'; | ||
|
||
/** | ||
* Custom hook to fetch and format the latest balance of a given token or native asset. | ||
* | ||
* @param token - The token object for which the balance is to be fetched. Can be null. | ||
* @param chainId - The chain ID to be used for fetching the balance. Optional. | ||
* @returns An object containing the formatted balance as a string. | ||
*/ | ||
const useLatestBalance = ( | ||
token: SwapsTokenObject | SwapsEthToken | null, | ||
chainId?: Hex, | ||
) => { | ||
const { address: selectedAddress } = useSelector(getSelectedInternalAccount); | ||
const currentChainId = useSelector(getCurrentChainId); | ||
|
||
const { value: latestBalance } = useAsyncResult<BigNumber>(async () => { | ||
if (token && chainId && currentChainId === chainId) { | ||
if (!token.address || token.address === zeroAddress()) { | ||
const ethersProvider = new Web3Provider(global.ethereumProvider); | ||
return await ethersProvider.getBalance(selectedAddress); | ||
} | ||
return await fetchTokenBalance( | ||
token.address, | ||
selectedAddress, | ||
global.ethereumProvider, | ||
); | ||
} | ||
// TODO implement fetching balance on non-active chain and update unit test | ||
return undefined; | ||
}, [token, selectedAddress, global.ethereumProvider]); | ||
|
||
return { | ||
formattedBalance: | ||
token && latestBalance | ||
? Numeric.from(latestBalance.toString(), 10) | ||
.shiftedBy(token?.decimals ? Number(token.decimals) : 18) | ||
.round(DEFAULT_PRECISION) | ||
.toString() | ||
: undefined, | ||
}; | ||
}; | ||
|
||
export default useLatestBalance; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters