Skip to content

Commit 49ec292

Browse files
authored
feat(money): MUSD-827 Money Home design-review polishes (MetaMask#30437)
## **Description** Applies the seven design-review polishes called out for MUSD-827 on the Money Account Home surface: - **Item 1** — `MoneyMusdTokenRow` subtitle on Home now reads `${balance} • mUSD` instead of just `mUSD`. The row consumes the existing `useMoneyAccountBalance` hook's `musdFiatFormatted` field (spendable mUSD only — not the aggregated total). - **Item 2** — "No MetaMask fee" badge on stables/aTokens rows in the Earn Crypto section → "No fee". - **Item 3** — "Convert" button label on per-asset rows in the Earn Crypto section → "Add". The locale key name stays `convert` so call sites are untouched. - **Item 4** — The move-mUSD row in `MoneyAddMoneySheet` is hidden when the user has no mUSD balance (`totalFiatRaw` non-positive or unparseable). An unparseable value fails open and keeps the row visible. - **Item 5** — When that row is shown, its label changes from "Transfer your $X mUSD" → "Add your $X mUSD". The now-dead `move_musd_no_amount` key is removed from `en.json`. - **Item 8** — `MoneyHowItWorksView` description 1 is updated to mention "curated by Veda and Steakhouse Financial" and to drop the em dash; a new description 3 paragraph "Money account is powered by Monad." renders after description 2. - **Item 10** — The small How-It-Works tile in `MoneyCondensedInfoCards` swaps `mm_how_it_works.png` for the new green bar-chart icon exported from Figma (committed separately at the top of the branch as `c3b1fc37af`). Items 6, 7, and 9 from the parent design review are intentionally out of scope (handled by MUSD-824, ticketed separately, and out-of-scope per design direction respectively). Only `locales/languages/en.json` is touched — non-English translations come from the localization pipeline. ## **Changelog** CHANGELOG entry: Polished the Money Account Home with the spendable mUSD balance in the token row subtitle, a "No fee" badge and "Add" button on Earn Crypto rows, a hidden "Add your $X mUSD" entry on the Add money sheet when the balance is zero, a refreshed "How it works" description and a new Monad attribution paragraph, and an updated How It Works tile image. ## **Related issues** Fixes: [MUSD-827](https://consensyssoftware.atlassian.net/browse/MUSD-827) ## **Manual testing steps** ```gherkin Feature: MUSD-827 Money Home design-review polishes Scenario: mUSD row subtitle on Home Given the user has a positive mUSD spendable balance When the user opens the Money tab Then the mUSD row subtitle reads "$<balance> • mUSD" (e.g. "$1.00 • mUSD") Scenario: Earn Crypto badge label Given the user has stablecoin or aToken balances eligible for the Earn Crypto section When the user scrolls to the Earn Crypto section on Money Home Then each subsidised-fee row shows the badge "No fee" And the per-asset action button reads "Add" Scenario: Add money sheet hides the move-mUSD row when balance is zero Given the user has $0 spendable mUSD When the user opens the Add money sheet from the Money Home Add button Then the sheet shows only "Convert crypto", "Deposit funds", and the disabled "Receive from external wallet" row And the "Add your $X mUSD" row is not rendered Scenario: Add money sheet shows the move-mUSD row with positive balance Given the user has a positive spendable mUSD balance (e.g. $12.34) When the user opens the Add money sheet from the Money Home Add button Then the third row reads "Add your $12.34 mUSD" Scenario: How It Works full screen Given the user is on the Money tab When the user opens "How it works" Then description 1 mentions "curated by Veda and Steakhouse Financial" And a third paragraph reads "Money account is powered by Monad." Scenario: How It Works tile image Given the user is on the Money tab in milestone or empty state When the user views the condensed info cards row Then the How-It-Works tile shows the new green bar-chart icon ``` ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [MUSD-827]: https://consensyssoftware.atlassian.net/browse/MUSD-827?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Primarily UI copy/label updates, but it also changes when the Add Money sheet shows the mUSD move/add option based on parsed balances, which could hide a user action if balance/rates are miscomputed. > > **Overview** > Polishes Money surfaces around mUSD and Earn Crypto CTAs: the Money Home mUSD row now displays a formatted spendable balance in its subtitle (via `useMusdBalance`), and per-token Earn Crypto actions/badges switch to **“Add”** and **“No fee”**. > > Updates the Add Money sheet to source balances from `useMusdBalance`, **hide the mUSD move/add row when the user has no balance**, and format the label as **“Add your {amount} mUSD”** (falling back to token amount when fiat rates are unavailable). The How It Works screen copy is refreshed and adds a third description paragraph attributing Monad; tests and `en.json` strings are updated accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c2ea309. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 8c73d92 commit 49ec292

14 files changed

Lines changed: 245 additions & 86 deletions

File tree

app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.test.tsx

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { act, fireEvent } from '@testing-library/react-native';
2+
import { act, fireEvent, within } from '@testing-library/react-native';
33
import { Linking } from 'react-native';
44
import renderWithProvider from '../../../../../util/test/renderWithProvider';
55
import MoneyHomeView from './MoneyHomeView';
@@ -28,6 +28,7 @@ import { useMoneyAccountCardLinkage } from '../../../Card/hooks/useMoneyAccountC
2828
import { getDetectedGeolocation } from '../../../../../reducers/fiatOrders';
2929
import { moneyFormatFiat } from '../../utils/moneyFormatFiat';
3030
import { useMusdConversion } from '../../../Earn/hooks/useMusdConversion';
31+
import { useMusdBalance } from '../../../Earn/hooks/useMusdBalance';
3132

3233
const mockGoBack = jest.fn();
3334
const mockNavigate = jest.fn();
@@ -83,6 +84,10 @@ jest.mock('../../../Earn/hooks/useMusdConversion', () => ({
8384
useMusdConversion: jest.fn(),
8485
}));
8586

87+
jest.mock('../../../Earn/hooks/useMusdBalance', () => ({
88+
useMusdBalance: jest.fn(),
89+
}));
90+
8691
jest.mock('../../../../../core/NavigationService', () => ({
8792
__esModule: true,
8893
default: {
@@ -124,6 +129,8 @@ const mockUseMusdConversion = jest.mocked(useMusdConversion);
124129

125130
const mockUseMoneyAccountBalance = jest.mocked(useMoneyAccountBalance);
126131

132+
const mockUseMusdBalance = jest.mocked(useMusdBalance);
133+
127134
jest.mock(
128135
'../../../../UI/Assets/components/AssetLogo/AssetLogo',
129136
() => 'AssetLogo',
@@ -227,6 +234,17 @@ describe('MoneyHomeView', () => {
227234
},
228235
} as ReturnType<typeof useMoneyAccountBalance>);
229236

237+
mockUseMusdBalance.mockReturnValue({
238+
hasMusdBalanceOnAnyChain: true,
239+
hasMusdBalanceOnChain: () => true,
240+
tokenBalanceByChain: {},
241+
fiatBalanceByChain: {},
242+
fiatBalanceFormattedByChain: {},
243+
tokenBalanceAggregated: '1',
244+
fiatBalanceAggregated: '1',
245+
fiatBalanceAggregatedFormatted: '$1.00',
246+
} as ReturnType<typeof useMusdBalance>);
247+
230248
// Activity list renders when there are at least 10 transactions; pad the
231249
// mock set so the activity-related assertions below find the View all button.
232250
const paddedTransactions = Array.from({ length: 10 }, (_, index) => ({
@@ -883,9 +901,16 @@ describe('MoneyHomeView', () => {
883901
});
884902

885903
it('initiates a custom conversion when a token Convert button is pressed', async () => {
886-
const { getByText } = renderWithProvider(<MoneyHomeView />);
904+
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
887905

888-
fireEvent.press(getByText(strings('money.potential_earnings.convert')));
906+
const potentialEarnings = getByTestId(
907+
MoneyPotentialEarningsTestIds.CONTAINER,
908+
);
909+
fireEvent.press(
910+
within(potentialEarnings).getByText(
911+
strings('money.potential_earnings.add'),
912+
),
913+
);
889914

890915
expect(mockInitiateCustomConversion).toHaveBeenCalledWith(
891916
expect.objectContaining({
@@ -902,9 +927,16 @@ describe('MoneyHomeView', () => {
902927
);
903928
const Logger = jest.requireMock('../../../../../util/Logger');
904929

905-
const { getByText } = renderWithProvider(<MoneyHomeView />);
930+
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
906931

907-
fireEvent.press(getByText(strings('money.potential_earnings.convert')));
932+
const potentialEarnings = getByTestId(
933+
MoneyPotentialEarningsTestIds.CONTAINER,
934+
);
935+
fireEvent.press(
936+
within(potentialEarnings).getByText(
937+
strings('money.potential_earnings.add'),
938+
),
939+
);
908940

909941
await Promise.resolve();
910942

app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { MoneyHomeViewTestIds } from './MoneyHomeView.testIds';
2525
import styleSheet from './MoneyHomeView.styles';
2626
import { useMusdConversionTokens } from '../../../Earn/hooks/useMusdConversionTokens';
2727
import { useMusdConversion } from '../../../Earn/hooks/useMusdConversion';
28+
import { useMusdBalance } from '../../../Earn/hooks/useMusdBalance';
2829
import { useMoneyAccountTransactions } from '../../hooks/useMoneyAccountTransactions';
2930
import useMoneyAccountBalance from '../../hooks/useMoneyAccountBalance';
3031
import { selectCurrentCurrency } from '../../../../../selectors/currencyRateController';
@@ -64,6 +65,8 @@ const MoneyHomeView = () => {
6465
isAggregatedBalanceLoading,
6566
apyPercent,
6667
} = useMoneyAccountBalance();
68+
const { fiatBalanceAggregatedFormatted: musdFiatFormatted } =
69+
useMusdBalance();
6770

6871
const { tokens: conversionTokens } = useMusdConversionTokens();
6972
const { initiateCustomConversion } = useMusdConversion();
@@ -293,6 +296,7 @@ const MoneyHomeView = () => {
293296
<MoneyMusdTokenRow
294297
onPress={handleMusdRowPress}
295298
onAddPress={handleAddPress}
299+
balance={musdFiatFormatted}
296300
/>
297301
<Divider />
298302
</>

app/components/UI/Money/Views/MoneyHowItWorksView/MoneyHowItWorksView.test.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ jest.mock('../../../../../../locales/i18n', () => ({
3838
'Deposit mUSD into your Money account and earn up to 4% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.',
3939
'money.how_it_works_page.description_2':
4040
'Your Money balance is your spending balance. Link your MetaMask Card to spend at 150M+ merchants worldwide. Your money keeps earning until the moment you use it.',
41+
'money.how_it_works_page.description_3':
42+
'Money account is powered by Monad.',
4143
'money.how_it_works_page.faq_title': 'Frequently asked questions',
4244
'money.how_it_works_page.faq_placeholder_answer': 'Coming soon.',
4345
'money.how_it_works_page.faq_q1': 'How does the 4% APY work?',
@@ -86,6 +88,17 @@ describe('MoneyHowItWorksView', () => {
8688
).toBeOnTheScreen();
8789
});
8890

91+
it('renders the Monad attribution as the third description paragraph', () => {
92+
const { getByTestId, getByText } = renderWithProvider(
93+
<MoneyHowItWorksView />,
94+
);
95+
96+
expect(
97+
getByTestId(MoneyHowItWorksViewTestIds.DESCRIPTION_3),
98+
).toBeOnTheScreen();
99+
expect(getByText('Money account is powered by Monad.')).toBeOnTheScreen();
100+
});
101+
89102
it('renders the FAQ title', () => {
90103
const { getByTestId } = renderWithProvider(<MoneyHowItWorksView />);
91104

app/components/UI/Money/Views/MoneyHowItWorksView/MoneyHowItWorksView.testIds.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const MoneyHowItWorksViewTestIds = {
66
SECTION_TITLE: 'money-how-it-works-view-section-title',
77
DESCRIPTION_1: 'money-how-it-works-view-description-1',
88
DESCRIPTION_2: 'money-how-it-works-view-description-2',
9+
DESCRIPTION_3: 'money-how-it-works-view-description-3',
910
FAQ_TITLE: 'money-how-it-works-view-faq-title',
1011
FAQ_ITEM: (n: number) => `money-how-it-works-view-faq-item-${n}`,
1112
};

app/components/UI/Money/Views/MoneyHowItWorksView/MoneyHowItWorksView.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ const MoneyHowItWorksView = () => {
184184
>
185185
{strings('money.how_it_works_page.description_2')}
186186
</Text>
187+
<Text
188+
variant={TextVariant.BodyMd}
189+
color={TextColor.TextAlternative}
190+
testID={MoneyHowItWorksViewTestIds.DESCRIPTION_3}
191+
>
192+
{strings('money.how_it_works_page.description_3')}
193+
</Text>
187194
</Box>
188195

189196
<SectionDivider />

app/components/UI/Money/components/MoneyAddMoneySheet/MoneyAddMoneySheet.test.tsx

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import MoneyAddMoneySheet from './MoneyAddMoneySheet';
55
import { MoneyAddMoneySheetTestIds } from './MoneyAddMoneySheet.testIds';
66
import { useMusdConversionFlowData } from '../../../Earn/hooks/useMusdConversionFlowData';
77
import { useRampNavigation } from '../../../Ramp/hooks/useRampNavigation';
8-
import useMoneyAccountBalance from '../../hooks/useMoneyAccountBalance';
8+
import { useMusdBalance } from '../../../Earn/hooks/useMusdBalance';
99
import { useMoneyAccountDeposit } from '../../hooks/useMoneyAccount';
1010
import {
1111
MUSD_CONVERSION_DEFAULT_CHAIN_ID,
@@ -38,9 +38,8 @@ jest.mock('../../../Ramp/hooks/useRampNavigation', () => ({
3838
useRampNavigation: jest.fn(),
3939
}));
4040

41-
jest.mock('../../hooks/useMoneyAccountBalance', () => ({
42-
__esModule: true,
43-
default: jest.fn(),
41+
jest.mock('../../../Earn/hooks/useMusdBalance', () => ({
42+
useMusdBalance: jest.fn(),
4443
}));
4544

4645
jest.mock('../../hooks/useMoneyAccount', () => ({
@@ -87,8 +86,11 @@ describe('MoneyAddMoneySheet', () => {
8786
(useRampNavigation as jest.Mock).mockReturnValue({
8887
goToBuy: mockGoToBuy,
8988
});
90-
(useMoneyAccountBalance as jest.Mock).mockReturnValue({
91-
totalFiatFormatted: '$1,203.89',
89+
(useMusdBalance as jest.Mock).mockReturnValue({
90+
fiatBalanceAggregated: '1203.89',
91+
fiatBalanceAggregatedFormatted: '$1,203.89',
92+
hasMusdBalanceOnAnyChain: true,
93+
tokenBalanceAggregated: '1203.89',
9294
});
9395
(useMoneyAccountDeposit as jest.Mock).mockReturnValue({
9496
initiateDeposit: mockInitiateDeposit,
@@ -102,7 +104,7 @@ describe('MoneyAddMoneySheet', () => {
102104

103105
expect(getByText('Convert crypto')).toBeOnTheScreen();
104106
expect(getByText('Deposit funds')).toBeOnTheScreen();
105-
expect(getByText('Transfer your $1,203.89 mUSD')).toBeOnTheScreen();
107+
expect(getByText('Add your $1,203.89 mUSD')).toBeOnTheScreen();
106108
expect(getByText('Receive from external wallet')).toBeOnTheScreen();
107109
expect(getByText('Coming soon')).toBeOnTheScreen();
108110
expect(
@@ -139,21 +141,81 @@ describe('MoneyAddMoneySheet', () => {
139141
});
140142

141143
it('preserves the locale fiat prefix in the Move mUSD row', () => {
142-
(useMoneyAccountBalance as jest.Mock).mockReturnValue({
143-
totalFiatFormatted: 'CA$1,500.00',
144+
(useMusdBalance as jest.Mock).mockReturnValue({
145+
fiatBalanceAggregated: '1500.00',
146+
fiatBalanceAggregatedFormatted: 'CA$1,500.00',
147+
hasMusdBalanceOnAnyChain: true,
148+
tokenBalanceAggregated: '1500.00',
144149
});
145150
const { getByText } = renderWithProvider(<MoneyAddMoneySheet />);
146151

147-
expect(getByText('Transfer your CA$1,500.00 mUSD')).toBeOnTheScreen();
152+
expect(getByText('Add your CA$1,500.00 mUSD')).toBeOnTheScreen();
148153
});
149154

150-
it('falls back to the no-amount copy when the mUSD balance is unavailable', () => {
151-
(useMoneyAccountBalance as jest.Mock).mockReturnValue({
152-
totalFiatFormatted: undefined,
155+
it('hides the move-mUSD row when the selected EVM account has no mUSD tokens or fiat balance', () => {
156+
(useMusdBalance as jest.Mock).mockReturnValue({
157+
fiatBalanceAggregated: undefined,
158+
fiatBalanceAggregatedFormatted: '$0.00',
159+
hasMusdBalanceOnAnyChain: false,
160+
tokenBalanceAggregated: '0',
153161
});
154-
const { getByText } = renderWithProvider(<MoneyAddMoneySheet />);
155162

156-
expect(getByText('Transfer your mUSD')).toBeOnTheScreen();
163+
const { queryByTestId } = renderWithProvider(<MoneyAddMoneySheet />);
164+
165+
expect(
166+
queryByTestId(MoneyAddMoneySheetTestIds.MOVE_MUSD_OPTION),
167+
).toBeNull();
168+
});
169+
170+
it('hides the move-mUSD row when the selected EVM account mUSD fiat balance is zero', () => {
171+
(useMusdBalance as jest.Mock).mockReturnValue({
172+
fiatBalanceAggregated: '0',
173+
fiatBalanceAggregatedFormatted: '$0.00',
174+
hasMusdBalanceOnAnyChain: false,
175+
tokenBalanceAggregated: '0',
176+
});
177+
178+
const { queryByTestId } = renderWithProvider(<MoneyAddMoneySheet />);
179+
180+
expect(
181+
queryByTestId(MoneyAddMoneySheetTestIds.MOVE_MUSD_OPTION),
182+
).toBeNull();
183+
});
184+
185+
it('shows the move-mUSD row with the "Add your $X mUSD" label when the selected EVM account mUSD fiat balance is positive', () => {
186+
(useMusdBalance as jest.Mock).mockReturnValue({
187+
fiatBalanceAggregated: '12.34',
188+
fiatBalanceAggregatedFormatted: '$12.34',
189+
hasMusdBalanceOnAnyChain: true,
190+
tokenBalanceAggregated: '12.34',
191+
});
192+
193+
const { getByTestId, getByText } = renderWithProvider(
194+
<MoneyAddMoneySheet />,
195+
);
196+
197+
expect(
198+
getByTestId(MoneyAddMoneySheetTestIds.MOVE_MUSD_OPTION),
199+
).toBeOnTheScreen();
200+
expect(getByText('Add your $12.34 mUSD')).toBeOnTheScreen();
201+
});
202+
203+
it('shows the move-mUSD row with the token amount when the user has mUSD tokens but rates are unavailable', () => {
204+
(useMusdBalance as jest.Mock).mockReturnValue({
205+
fiatBalanceAggregated: undefined,
206+
fiatBalanceAggregatedFormatted: '$0.00',
207+
hasMusdBalanceOnAnyChain: true,
208+
tokenBalanceAggregated: '42.5',
209+
});
210+
211+
const { getByTestId, getByText } = renderWithProvider(
212+
<MoneyAddMoneySheet />,
213+
);
214+
215+
expect(
216+
getByTestId(MoneyAddMoneySheetTestIds.MOVE_MUSD_OPTION),
217+
).toBeOnTheScreen();
218+
expect(getByText('Add your 42.50 mUSD')).toBeOnTheScreen();
157219
});
158220

159221
it('navigates to the Ramps buy flow with mUSD pre-selected when Deposit funds is pressed', () => {

app/components/UI/Money/components/MoneyAddMoneySheet/MoneyAddMoneySheet.tsx

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useCallback, useRef } from 'react';
22
import { TouchableOpacity, View } from 'react-native';
33
import { useNavigation } from '@react-navigation/native';
4+
import BigNumber from 'bignumber.js';
45
import {
56
BottomSheet,
67
BottomSheetHeader,
@@ -18,7 +19,7 @@ import Tag from '../../../../../component-library/components/Tags/Tag';
1819
import { strings } from '../../../../../../locales/i18n';
1920
import { useStyles } from '../../../../../component-library/hooks';
2021
import { useMusdConversionFlowData } from '../../../Earn/hooks/useMusdConversionFlowData';
21-
import useMoneyAccountBalance from '../../hooks/useMoneyAccountBalance';
22+
import { useMusdBalance } from '../../../Earn/hooks/useMusdBalance';
2223
import {
2324
MUSD_CONVERSION_DEFAULT_CHAIN_ID,
2425
MUSD_TOKEN_ASSET_ID_BY_CHAIN,
@@ -42,7 +43,12 @@ const MoneyAddMoneySheet: React.FC = () => {
4243
const navigation = useNavigation();
4344
const { styles } = useStyles(styleSheet, {});
4445

45-
const { totalFiatFormatted } = useMoneyAccountBalance();
46+
const {
47+
fiatBalanceAggregated,
48+
fiatBalanceAggregatedFormatted,
49+
hasMusdBalanceOnAnyChain,
50+
tokenBalanceAggregated,
51+
} = useMusdBalance();
4652
const { getChainIdForBuyFlow } = useMusdConversionFlowData();
4753
const { goToBuy } = useRampNavigation();
4854
const { initiateDeposit } = useMoneyAccountDeposit();
@@ -79,16 +85,19 @@ const MoneyAddMoneySheet: React.FC = () => {
7985
sheetRef.current?.onCloseBottomSheet();
8086
}, []);
8187

82-
let moveMusdLabel: string;
83-
if (totalFiatFormatted) {
84-
moveMusdLabel = strings('money.add_money_sheet.move_musd', {
85-
amount: totalFiatFormatted,
86-
});
87-
} else {
88-
moveMusdLabel = strings('money.add_money_sheet.move_musd_no_amount');
89-
}
88+
const parsedMusdFiat = Number(fiatBalanceAggregated);
89+
const hasParsedFiatBalance =
90+
Number.isFinite(parsedMusdFiat) && parsedMusdFiat > 0;
91+
const hasMusdBalance = hasMusdBalanceOnAnyChain || hasParsedFiatBalance;
92+
93+
const moveMusdAmount = hasParsedFiatBalance
94+
? fiatBalanceAggregatedFormatted
95+
: new BigNumber(tokenBalanceAggregated).toFixed(2);
96+
const moveMusdLabel = hasMusdBalance
97+
? strings('money.add_money_sheet.move_musd', { amount: moveMusdAmount })
98+
: '';
9099

91-
const options: Option[] = [
100+
const baseOptions: Option[] = [
92101
{
93102
label: strings('money.add_money_sheet.convert_crypto'),
94103
description: strings('money.add_money_sheet.convert_crypto_description'),
@@ -105,16 +114,22 @@ const MoneyAddMoneySheet: React.FC = () => {
105114
onPress: handleDepositFunds,
106115
testID: MoneyAddMoneySheetTestIds.DEPOSIT_FUNDS_OPTION,
107116
},
108-
{
109-
label: moveMusdLabel,
110-
description: strings('money.add_money_sheet.move_musd_description'),
111-
descriptionTestID: MoneyAddMoneySheetTestIds.MOVE_MUSD_DESCRIPTION,
112-
icon: IconName.Add,
113-
onPress: handleMoveMusd,
114-
testID: MoneyAddMoneySheetTestIds.MOVE_MUSD_OPTION,
115-
},
116117
];
117118

119+
const options: Option[] = hasMusdBalance
120+
? [
121+
...baseOptions,
122+
{
123+
label: moveMusdLabel,
124+
description: strings('money.add_money_sheet.move_musd_description'),
125+
descriptionTestID: MoneyAddMoneySheetTestIds.MOVE_MUSD_DESCRIPTION,
126+
icon: IconName.Add,
127+
onPress: handleMoveMusd,
128+
testID: MoneyAddMoneySheetTestIds.MOVE_MUSD_OPTION,
129+
},
130+
]
131+
: baseOptions;
132+
118133
return (
119134
<BottomSheet
120135
ref={sheetRef}

0 commit comments

Comments
 (0)