diff --git a/.changeset/five-spoons-burn.md b/.changeset/five-spoons-burn.md new file mode 100644 index 0000000000..76919e4535 --- /dev/null +++ b/.changeset/five-spoons-burn.md @@ -0,0 +1,23 @@ +--- +'@apps/laboratory': patch +'@reown/appkit-core': patch +'@apps/demo': patch +'@apps/gallery': patch +'@reown/appkit-adapter-ethers': patch +'@reown/appkit-adapter-ethers5': patch +'@reown/appkit-adapter-polkadot': patch +'@reown/appkit-adapter-solana': patch +'@reown/appkit-adapter-wagmi': patch +'@reown/appkit': patch +'@reown/appkit-utils': patch +'@reown/appkit-cdn': patch +'@reown/appkit-common': patch +'@reown/appkit-experimental': patch +'@reown/appkit-polyfills': patch +'@reown/appkit-scaffold-ui': patch +'@reown/appkit-siwe': patch +'@reown/appkit-ui': patch +'@reown/appkit-wallet': patch +--- + +Refactored token balance error message and ensured that token balances are only fetched again after 5 seconds if the token balance API fails. \ No newline at end of file diff --git a/apps/laboratory/tests/email.spec.ts b/apps/laboratory/tests/email.spec.ts index 9518129f38..f29d47d0d7 100644 --- a/apps/laboratory/tests/email.spec.ts +++ b/apps/laboratory/tests/email.spec.ts @@ -100,9 +100,18 @@ emailTest('it should show names feature only for EVM networks', async ({ library emailTest('it should show loading on page refresh', async () => { await page.page.reload() await validator.expectConnectButtonLoading() + await validator.expectAccountButtonReady() +}) + +emailTest('it should show snackbar error if failed to fetch token balance', async () => { + await page.page.context().setOffline(true) + await page.openAccount() + await validator.expectSnackbar('Token Balance Unavailable') + await page.closeModal() }) emailTest('it should disconnect correctly', async () => { + await page.page.context().setOffline(false) await page.goToSettings() await page.disconnect() await validator.expectDisconnected() diff --git a/apps/laboratory/tests/shared/validators/ModalValidator.ts b/apps/laboratory/tests/shared/validators/ModalValidator.ts index a4922f1eaa..24027d17b6 100644 --- a/apps/laboratory/tests/shared/validators/ModalValidator.ts +++ b/apps/laboratory/tests/shared/validators/ModalValidator.ts @@ -292,6 +292,11 @@ export class ModalValidator { await expect(connectButton).toContainText('Connecting...') } + async expectAccountButtonReady() { + const accountButton = this.page.getByTestId('account-button') + await expect(accountButton).toBeVisible({ timeout: MAX_WAIT }) + } + async expectAccountSwitched(oldAddress: string) { const address = this.page.getByTestId('w3m-address') await expect(address).not.toHaveText(oldAddress) diff --git a/packages/core/src/controllers/AccountController.ts b/packages/core/src/controllers/AccountController.ts index 4ace12b837..61d201bd6a 100644 --- a/packages/core/src/controllers/AccountController.ts +++ b/packages/core/src/controllers/AccountController.ts @@ -16,6 +16,7 @@ import type { W3mFrameTypes } from '@reown/appkit-wallet' import { ChainController } from './ChainController.js' import { proxy, ref } from 'valtio/vanilla' import type UniversalProvider from '@walletconnect/universal-provider' +import { ConstantsUtil } from '../utils/ConstantsUtil.js' // -- Types --------------------------------------------- // export interface AccountControllerState { @@ -40,6 +41,7 @@ export interface AccountControllerState { provider?: UniversalProvider | Provider | CombinedProvider status?: 'reconnecting' | 'connected' | 'disconnected' | 'connecting' siweStatus?: 'uninitialized' | 'ready' | 'loading' | 'success' | 'rejected' | 'error' + lastRetry?: number } // -- State --------------------------------------------- // @@ -227,6 +229,13 @@ export const AccountController = { const caipAddress = ChainController.state.activeCaipAddress const address = caipAddress ? CoreHelperUtil.getPlainAddress(caipAddress) : undefined + if ( + state.lastRetry && + !CoreHelperUtil.isAllowedRetry(state.lastRetry, ConstantsUtil.FIVE_SEC_MS) + ) { + return + } + try { if (address && chainId && chain) { const response = await BlockchainApiController.getBalance(address, chainId) @@ -237,9 +246,12 @@ export const AccountController = { this.setTokenBalance(filteredBalances, chain) SwapController.setBalances(SwapApiUtil.mapBalancesToSwapTokens(response.balances)) + state.lastRetry = undefined } } catch (error) { - SnackController.showError('Failed to fetch token balance') + state.lastRetry = Date.now() + + SnackController.showError('Token Balance Unavailable') } }, diff --git a/packages/core/src/utils/CoreHelperUtil.ts b/packages/core/src/utils/CoreHelperUtil.ts index 3b0d98a54b..30d80f161b 100644 --- a/packages/core/src/utils/CoreHelperUtil.ts +++ b/packages/core/src/utils/CoreHelperUtil.ts @@ -42,8 +42,8 @@ export const CoreHelperUtil = { return expiry ? expiry - Date.now() <= ConstantsUtil.TEN_SEC_MS : true }, - isAllowedRetry(lastRetry: number) { - return Date.now() - lastRetry >= ConstantsUtil.ONE_SEC_MS + isAllowedRetry(lastRetry: number, differenceMs = ConstantsUtil.ONE_SEC_MS) { + return Date.now() - lastRetry >= differenceMs }, copyToClopboard(text: string) {