feat(balances): align the total USD label with the extension ("$0.00" vs "--") - #978
Conversation
The Tokens and Collectibles tab spinners used the near-white `secondary` color while the Home fiat-total spinner uses `foreground.primary`, so the three loading states on the same screen didn't match. Point both tab spinners at `foreground.primary`. The Tokens one also read from the hardcoded dark-only `THEME` constant; it now goes through `themeColors`, so it's theme-aware like the other two. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ports the extension's getTotalUsdLabel rule (stellar/freighter#2960) so both clients agree on when a total is a known zero and when it could not be read: - "--" when the balances fetch failed, or a funded account on a priced network resolved no prices - "$0.00" when the network prices no tokens (testnet/futurenet) or the account is unfunded — a real zero, not a stand-in - the formatted total otherwise, a genuine zero included The decision lives in one helper (helpers/balances.getTotalUsdLabel, with NO_FIAT_VALUE in helpers/formatAmount, mirroring the extension's split) and is used by both the Home header and the wallets list, so the two can never disagree. The wallets list needs inputs only its fetch cycle holds (funded state, whether anything priced, whether the fetch failed), so accountsFiatTotals now stores a resolved { label, hasError } entry per account instead of a nullable BigNumber. hasError keeps a failed account eligible for the next retry, and non-mainnet pre-fills every row with the known zero rather than leaving rows to interpret a missing entry. hasDecimals moved from helpers/balances to helpers/formatAmount (next to its main caller) so the balances -> formatAmount dependency runs one way only, matching the extension's module layout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Ports the extension’s total-USD display rules to mobile and aligns balance-related loading indicators.
Changes:
- Centralizes
$0.00versus--label selection. - Stores resolved per-account fiat labels and retry state.
- Updates Home/wallet rows, spinner colors, and tests.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/hooks/useTotalBalance.ts |
Derives the Home total label. |
src/hooks/useTokenFiatConverter/index.ts |
Updates hasDecimals import. |
src/hooks/useSyncAccountsFiatTotals.ts |
Synchronizes funded/error state. |
src/helpers/formatAmount.ts |
Adds placeholder and moves hasDecimals. |
src/helpers/balances.ts |
Adds centralized label helper. |
src/ducks/accountsFiatTotals.ts |
Stores and fetches resolved labels. |
src/components/screens/HomeScreen/ManageAccountBottomSheet.tsx |
Updates fiat-total types. |
src/components/screens/HomeScreen/HomeScreen.tsx |
Displays the resolved label. |
src/components/screens/HomeScreen/AccountItemRow.tsx |
Renders labels and retry spinners. |
src/components/CollectiblesGrid.tsx |
Aligns spinner color. |
src/components/BalancesList.tsx |
Aligns spinner color. |
__tests__/hooks/useSyncAccountsFiatTotals.test.tsx |
Updates synchronization coverage. |
__tests__/helpers/getTotalUsdLabel.test.ts |
Tests label-selection rules. |
__tests__/ducks/accountsFiatTotals.test.ts |
Updates totals-store coverage. |
__tests__/components/screens/HomeScreen/ManageAccountBottomSheet.test.tsx |
Updates label fixtures. |
__tests__/components/screens/HomeScreen/AccountItemRow.test.tsx |
Tests labels and loading states. |
__tests__/components/screens/HomeScreen.test.tsx |
Tests Home label rendering. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
iOS Simulator preview build is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-46dd7dd180d450924e1f (SDF collaborators only — install instructions in the release description) |
The Home header showed "--" while the same account's row in the wallets sheet showed "$0.00", which is exactly the disagreement this helper exists to prevent. fetchedPublicKey/fetchedNetwork are stamped only on a successful response, and clearAccountData nulls them, so a first-ever balances failure — or the first after an account switch — left the sync guard with no proof the snapshot belonged to this account. It returned early, the active row never got an entry, and the row fell back to a confident "$0.00". A failed fetch now syncs regardless of the stamp. That is safe because getTotalUsdLabel checks hasError first and never reads the balances snapshot in that branch, so the guard's real purpose — never attributing a previous account's numbers to a new one — is untouched. An in-flight fetch is still awaited, since an error is only worth writing once the request has settled. Refs PR #978 review comment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Code reviewNo issues found. Checked for bugs and AGENTS.md compliance. 🤖 Generated with Claude Code |
Nit:
|
piyalbasu
left a comment
There was a problem hiding this comment.
Approved with just 1 NIT comment
…alance Home reads only totalLabel, so the bare formatted sum had no production consumers left — it survived just in the test mocks. Leaving it exported is a footgun given the hook's own docs steer consumers away from it: it reads as a confident $0.00 when prices are missing, which is the whole reason totalLabel exists. Removing it also retires the formatFiatAmount import, and the totalLabel doc no longer points at a field that isn't there. Refs PR #978 review comment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Fixed in d6d38f7 — took fix 1. Confirmed it had zero production consumers (only the hook and six One thing worth flagging while in here: |
Ports the extension's
$0.00vs--rule to mobile, so both clients say the same thing about an account's total USD value.Follows the behavior agreed in stellar/freighter#2960 — see this comment for the rule and the extension screenshots.
The rule
One helper decides it:
getTotalUsdLabelinsrc/helpers/balances.ts, ported from the extension's helper of the same name (NO_FIAT_VALUElives inhelpers/formatAmount.ts, mirroring the extension's split).----$0.00$0.00$0.00included$0.00asserts a known zero;--means the total couldn't be determined. Both the Home header and every wallets-list row call the same helper, so the two can't disagree.Tests: new
getTotalUsdLabelsuite mirrors the extension's case-for-case, plus updated coverage for the wallets list and Home header.Screenshots
Mainnet happy path (all priced)
Mainnet with prices erroring
Mainnet for unfunded account
Testnet in all cases
Always the same UI regardless of prices erroring, since we use no prices there.