Skip to content

Conversation

@kernelwhisperer
Copy link
Contributor

@kernelwhisperer kernelwhisperer commented Dec 30, 2025

Summary

Fixes #4127

The issue was that the form validation was not taking into account the isBalancesLoading state.

To Test

As per the issue:

Connect to a wallet (using WC or open the app inside Safe --> most likely you will immediately reproduce the issue)

AR: each time when app is loading after changing a network/connection, 'Couldn't load balances' message appears and is displayed up to 20 seconds

Summary by CodeRabbit

  • New Features

    • Trade form now shows a "Fetching balances" message with a subtle loading indicator while token balances load.
  • Bug Fixes

    • Validation updated to suppress premature balance errors while balance data is still loading, preventing incorrect error states during fetch.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
cowfi Ready Ready Preview Jan 5, 2026 2:40pm
explorer-dev Ready Ready Preview Jan 5, 2026 2:40pm
swap-dev Ready Ready Preview Jan 5, 2026 2:40pm
widget-configurator Ready Ready Preview Jan 5, 2026 2:40pm
2 Skipped Deployments
Project Deployment Review Updated (UTC)
cosmos Ignored Ignored Jan 5, 2026 2:40pm
sdk-tools Ignored Ignored Preview Jan 5, 2026 2:40pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 30, 2025

Walkthrough

Adds a balances-loading flag to trade form validation: exposes isBalancesLoading from the balances hook, extends validation context and types, updates validation logic to show a "balances loading" state instead of a "balances not loaded" error while balances are being fetched, and adds UI for the loading state.

Changes

Cohort / File(s) Summary
Hook / Context
apps/cowswap-frontend/src/modules/tradeFormValidation/hooks/useTradeFormValidationContext.ts
Import useTokensBalances, derive isBalancesLoading, expose it on the returned validation context, and add it to memo deps.
Types
apps/cowswap-frontend/src/modules/tradeFormValidation/types.ts
Added TradeFormValidation.BalancesLoading enum member and isBalancesLoading: boolean to TradeFormValidationCommonContext.
Validation Logic
apps/cowswap-frontend/src/modules/tradeFormValidation/services/validateTradeForm.ts
Updated balance-related checks: return BalancesLoading when isBalancesLoading is true; only return BalancesNotLoaded when balances are not loading and no balance exists; retain BalanceInsufficient checks once balance is present.
UI / i18n
apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx, apps/cowswap-frontend/src/locales/en-US.po
Added BalancesLoading entry in tradeButtonsMap rendering a "Fetching balances" message with CenteredDots; added corresponding i18n string in en-US.po.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant UI as TradeForm UI
participant Hook as useTradeFormValidationContext
participant Balances as useTokensBalances
participant Validator as validateTradeForm
UI->>Hook: request validation context (user input)
Hook->>Balances: subscribe / read balances state
Balances-->>Hook: isBalancesLoading / balances data
Hook-->>UI: context includes isBalancesLoading
UI->>Validator: validateTradeForm(context)
alt balances loading
Validator-->>UI: TradeFormValidation.BalancesLoading
UI-->>UI: show "Fetching balances" + CenteredDots
else balances loaded / available
Validator-->>UI: other validations (ok / BalancesNotLoaded / BalanceInsufficient / ...)
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • elena-zh
  • shoom3301
  • alfetopito

Poem

🐰 Fetching balances, hop by hop,

I nibble bugs until they stop,
Dots a-dancing, soft and light,
No false warnings through the night,
Hooray — the numbers now feel right! 🎉

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: hiding the 'couldn't load balances' message when balances are loading, which directly addresses the PR's primary objective.
Description check ✅ Passed The PR description includes the issue number, a clear explanation of the problem, and testing steps. It follows the template with the main sections populated, though testing steps are somewhat brief.
Linked Issues check ✅ Passed The code changes directly address issue #4127 by adding isBalancesLoading state to validation logic, introducing a BalancesLoading enum state, and updating UI to show 'Fetching balances' during loading, preventing premature error display.
Out of Scope Changes check ✅ Passed All code changes are directly related to fixing the balance loading state issue. The modifications to validation context, validation logic, types, UI rendering, and localization are all scoped to resolving issue #4127.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a92f75 and 2555e61.

📒 Files selected for processing (4)
  • apps/cowswap-frontend/src/locales/en-US.po
  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx
  • apps/cowswap-frontend/src/modules/tradeFormValidation/services/validateTradeForm.ts
  • apps/cowswap-frontend/src/modules/tradeFormValidation/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/cowswap-frontend/src/modules/tradeFormValidation/services/validateTradeForm.ts
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-10-10T20:28:16.565Z
Learnt from: fairlighteth
Repo: cowprotocol/cowswap PR: 6347
File: apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx:49-49
Timestamp: 2025-10-10T20:28:16.565Z
Learning: In apps/cowswap-frontend/src/modules/trade, TradeConfirmation follows a two-layer architecture: TradeConfirmationView (pure/stateless) in pure/TradeConfirmation/index.tsx renders the UI, while TradeConfirmation (container) in containers/TradeConfirmation/index.tsx wraps it to freeze props during pending trades (via useStableTradeConfirmationProps), wire in signing state (useSigningStep), and inject trade confirmation state (useTradeConfirmState). Consuming modules should import the container TradeConfirmation from 'modules/trade' to preserve this stateful behavior.
<!-- [add_learning]
When reviewing component refactoring in apps/cowswap-frontend/src/modules/trade, recognize the pattern where a pure view component (e.g., TradeConfirmationView) is separated from a stateful container (e.g., TradeConfirmation) that wraps it. The container adds runtime state management (prop stabilization, signing state, etc.) while the view remains testable and composable. Do not flag usages that import th...

Applied to files:

  • apps/cowswap-frontend/src/modules/tradeFormValidation/types.ts
  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx
  • apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-12-30T18:49:03.377Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts:27-31
Timestamp: 2025-12-30T18:49:03.377Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts, when restrictedLists.isLoaded is false or geoStatus.isLoading is true, the code intentionally proceeds with the import immediately without blocking. This allows imports to proceed during loading states, deferring consent checks to trade time when necessary data isn't yet available.

Applied to files:

  • apps/cowswap-frontend/src/modules/tradeFormValidation/types.ts
  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx
📚 Learning: 2025-07-24T16:42:53.154Z
Learnt from: cowdan
Repo: cowprotocol/cowswap PR: 6009
File: apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/HighFeeWarningTooltipContent.tsx:23-33
Timestamp: 2025-07-24T16:42:53.154Z
Learning: In apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/HighFeeWarningTooltipContent.tsx, the use of toFixed(2) for percentage formatting in tooltip content is intentional and differs from the banner message formatting that uses toSignificant(2, undefined, Rounding.ROUND_DOWN). This formatting difference serves different UX purposes and should not be flagged as inconsistent.

Applied to files:

  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx
  • apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-09-25T08:49:32.256Z
Learnt from: shoom3301
Repo: cowprotocol/cowswap PR: 6299
File: apps/cowswap-frontend/src/entities/bridgeProvider/useBridgeSupportedNetworks.test.tsx:62-67
Timestamp: 2025-09-25T08:49:32.256Z
Learning: In the cowswap-frontend codebase, when testing hooks that use multiple bridge providers, both providers are always properly mocked as complete jest.Mocked<BridgeProvider<BridgeQuoteResult>> objects with all required methods stubbed, ensuring no undefined returns that could break the hook logic.

Applied to files:

  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx
📚 Learning: 2025-08-12T06:33:19.348Z
Learnt from: shoom3301
Repo: cowprotocol/cowswap PR: 6137
File: libs/tokens/src/state/tokens/allTokensAtom.ts:34-65
Timestamp: 2025-08-12T06:33:19.348Z
Learning: In libs/tokens/src/utils/parseTokenInfo.ts, the parseTokenInfo() function returns a new instance of TokenInfo using object spread syntax ({ ...token, ... }), making it safe to mutate properties like lpTokenProvider on the returned object without side effects.

Applied to files:

  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Cypress
  • GitHub Check: Setup
🔇 Additional comments (5)
apps/cowswap-frontend/src/locales/en-US.po (1)

5629-5632: New “Fetching balances” i18n entry looks correct

String is clear, neutral, and matches the new BalancesLoading button state usage; no i18n issues spotted.

apps/cowswap-frontend/src/modules/tradeFormValidation/types.ts (2)

32-36: BalancesLoading enum member is well-placed and consistent

Adding BalancesLoading under the Balances section cleanly models the new loading state and aligns with existing naming (BalancesNotLoaded, BalanceInsufficient). No issues here.


56-77: New isBalancesLoading flag fits context; ensure all producers set it

Extending TradeFormValidationCommonContext with isBalancesLoading: boolean is consistent with other is* flags and gives validation the info it needs. Just double‑check all factories/providers of this context now populate isBalancesLoading to avoid undefined or stale defaults.

apps/cowswap-frontend/src/modules/tradeFormValidation/pure/TradeFormButtons/tradeButtonsMap.tsx (2)

5-5: LGTM! Clean import addition.

The CenteredDots import is appropriately added to support the new loading indicator for the balances loading state.


257-264: Well-structured loading state implementation.

The new BalancesLoading entry follows the established pattern and is appropriately placed before BalancesNotLoaded to ensure the loading state is displayed while balances are being fetched. The TradeFormValidation.BalancesLoading enum value is properly defined, and the validation logic in validateTradeForm.ts correctly routes to this state when isBalancesLoading is true, suppressing the BalancesNotLoaded state during loading. The use of CenteredDots with the smaller prop provides a clear visual indicator that aligns well with the "Fetching balances" message.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kernelwhisperer kernelwhisperer self-assigned this Dec 30, 2025
@kernelwhisperer kernelwhisperer requested review from a team December 30, 2025 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

'Couldn't load balances' message is displayed after a wallet connection

3 participants