Skip to content

Commit a77c6c8

Browse files
committed
chore: merge main resolve conflict
2 parents 14803fa + 7cb245e commit a77c6c8

37 files changed

Lines changed: 3081 additions & 76 deletions

app/actions/user/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
type SetIsConnectionRemovedAction,
2727
type SetMultichainAccountsIntroModalSeenAction,
2828
type SetMusdConversionEducationSeenAction,
29+
type SetMusdConversionAssetDetailCtaSeenAction,
2930
UserActionType,
3031
} from './types';
3132

@@ -226,3 +227,12 @@ export function setMusdConversionEducationSeen(
226227
payload: { seen },
227228
};
228229
}
230+
231+
export function setMusdConversionAssetDetailCtaSeen(
232+
key: string,
233+
): SetMusdConversionAssetDetailCtaSeenAction {
234+
return {
235+
type: UserActionType.SET_MUSD_CONVERSION_ASSET_DETAIL_CTA_SEEN,
236+
payload: { key },
237+
};
238+
}

app/actions/user/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export enum UserActionType {
2929
SET_IS_CONNECTION_REMOVED = 'SET_IS_CONNECTION_REMOVED',
3030
SET_MULTICHAIN_ACCOUNTS_INTRO_MODAL_SEEN = 'SET_MULTICHAIN_ACCOUNTS_INTRO_MODAL_SEEN',
3131
SET_MUSD_CONVERSION_EDUCATION_SEEN = 'SET_MUSD_CONVERSION_EDUCATION_SEEN',
32+
SET_MUSD_CONVERSION_ASSET_DETAIL_CTA_SEEN = 'SET_MUSD_CONVERSION_ASSET_DETAIL_CTA_SEEN',
3233
}
3334

3435
// User actions
@@ -115,6 +116,11 @@ export type SetMusdConversionEducationSeenAction =
115116
payload: { seen: boolean };
116117
};
117118

119+
export type SetMusdConversionAssetDetailCtaSeenAction =
120+
Action<UserActionType.SET_MUSD_CONVERSION_ASSET_DETAIL_CTA_SEEN> & {
121+
payload: { key: string };
122+
};
123+
118124
/**
119125
* User actions union type
120126
*/
@@ -144,4 +150,5 @@ export type UserAction =
144150
| SetExistingUserAction
145151
| SetIsConnectionRemovedAction
146152
| SetMultichainAccountsIntroModalSeenAction
147-
| SetMusdConversionEducationSeenAction;
153+
| SetMusdConversionEducationSeenAction
154+
| SetMusdConversionAssetDetailCtaSeenAction;

app/components/UI/AssetOverview/AssetOverview.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ import DSText, {
112112
} from '../../../component-library/components/Texts/Text';
113113
import { getTokenExchangeRate } from '../Bridge/utils/exchange-rates';
114114
import { isNonEvmChainId } from '../../../core/Multichain/utils';
115+
import MerklRewards from '../Earn/components/MerklRewards';
116+
import { selectMerklCampaignClaimingEnabledFlag } from '../Earn/selectors/featureFlags';
115117
///: BEGIN:ONLY_INCLUDE_IF(tron)
116118
import {
117119
selectTronResourcesBySelectedAccountGroup,
@@ -217,6 +219,9 @@ const AssetOverview: React.FC<AssetOverviewProps> = ({
217219
const allTokenMarketData = useSelector(selectTokenMarketData);
218220
const selectedChainId = useSelector(selectEvmChainId);
219221
const isPerpsEnabled = useSelector(selectPerpsEnabledFlag);
222+
const isMerklCampaignClaimingEnabled = useSelector(
223+
selectMerklCampaignClaimingEnabledFlag,
224+
);
220225
const { navigateToSendPage } = useSendNavigation();
221226

222227
const nativeCurrency = useSelector((state: RootState) =>
@@ -826,6 +831,7 @@ const AssetOverview: React.FC<AssetOverviewProps> = ({
826831
)
827832
///: END:ONLY_INCLUDE_IF
828833
}
834+
{isMerklCampaignClaimingEnabled && <MerklRewards asset={asset} />}
829835
{isPerpsEnabled && hasPerpsMarket && marketData && (
830836
<>
831837
<View style={styles.perpsPositionHeader}>

app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.test.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import renderWithProvider from '../../../../../util/test/renderWithProvider';
1313
import { strings } from '../../../../../../locales/i18n';
1414
import { useMusdConversion } from '../../hooks/useMusdConversion';
1515
import { useParams } from '../../../../../util/navigation/navUtils';
16+
import { MUSD_CONVERSION_APY } from '../../constants/musd';
1617

1718
const FIXED_NOW_MS = 1730000000000;
1819
const mockTrackEvent = jest.fn();
@@ -160,10 +161,18 @@ describe('EarnMusdConversionEducationView', () => {
160161
);
161162

162163
expect(
163-
getByText(strings('earn.musd_conversion.education.heading')),
164+
getByText(
165+
strings('earn.musd_conversion.education.heading', {
166+
percentage: MUSD_CONVERSION_APY,
167+
}),
168+
),
164169
).toBeOnTheScreen();
165170
expect(
166-
getByText(strings('earn.musd_conversion.education.description')),
171+
getByText(
172+
strings('earn.musd_conversion.education.description', {
173+
percentage: MUSD_CONVERSION_APY,
174+
}),
175+
),
167176
).toBeOnTheScreen();
168177
expect(
169178
getByText(strings('earn.musd_conversion.education.primary_button')),

app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
import { strings } from '../../../../../../locales/i18n';
2828
import { MetaMetricsEvents, useMetrics } from '../../../../hooks/useMetrics';
2929
import { MUSD_EVENTS_CONSTANTS } from '../../constants/events';
30+
import { MUSD_CONVERSION_APY } from '../../constants/musd';
3031
interface EarnMusdConversionEducationViewRouteParams {
3132
/**
3233
* The payment token to preselect in the confirmation screen
@@ -180,10 +181,14 @@ const EarnMusdConversionEducationView = () => {
180181
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
181182
<View style={styles.content}>
182183
<Text style={styles.heading} numberOfLines={3} adjustsFontSizeToFit>
183-
{strings('earn.musd_conversion.education.heading')}
184+
{strings('earn.musd_conversion.education.heading', {
185+
percentage: MUSD_CONVERSION_APY,
186+
})}
184187
</Text>
185188
<Text variant={TextVariant.BodyMD} style={styles.bodyText}>
186-
{strings('earn.musd_conversion.education.description')}
189+
{strings('earn.musd_conversion.education.description', {
190+
percentage: MUSD_CONVERSION_APY,
191+
})}
187192
</Text>
188193
</View>
189194
<View style={styles.imageContainer}>

app/components/UI/Earn/components/EarnLendingBalance/EarnLendingBalance.test.tsx

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,54 @@ describe('EarnLendingBalance', () => {
737737
expect(queryByTestId(EARN_EMPTY_STATE_CTA_TEST_ID)).toBeNull();
738738
});
739739

740+
it('updates user state when close button is pressed on mUSD CTA', async () => {
741+
(
742+
selectStablecoinLendingEnabledFlag as jest.MockedFunction<
743+
typeof selectStablecoinLendingEnabledFlag
744+
>
745+
).mockReturnValue(false);
746+
747+
(
748+
selectIsMusdConversionFlowEnabledFlag as jest.MockedFunction<
749+
typeof selectIsMusdConversionFlowEnabledFlag
750+
>
751+
).mockReturnValue(true);
752+
753+
(
754+
useMusdConversionTokens as jest.MockedFunction<
755+
typeof useMusdConversionTokens
756+
>
757+
).mockReturnValue({
758+
isConversionToken: jest.fn().mockReturnValue(true),
759+
filterAllowedTokens: jest.fn().mockReturnValue([]),
760+
isMusdSupportedOnChain: jest.fn().mockReturnValue(true),
761+
getMusdOutputChainId: jest.fn().mockReturnValue('0x1'),
762+
tokens: [],
763+
});
764+
765+
mockShouldShowAssetOverviewCta.mockReturnValue(true);
766+
767+
const { getByTestId, store } = renderWithProvider(
768+
<EarnLendingBalance asset={mockDaiMainnet} />,
769+
{ state: mockInitialState },
770+
);
771+
772+
const closeButton = getByTestId(
773+
EARN_TEST_IDS.MUSD.ASSET_OVERVIEW_CONVERSION_CTA_CLOSE_BUTTON,
774+
);
775+
776+
await act(async () => {
777+
fireEvent.press(closeButton);
778+
});
779+
780+
const expectedCtaKey = '0x1-0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
781+
const updatedState = store.getState();
782+
783+
expect(
784+
updatedState.user.musdConversionAssetDetailCtasSeen[expectedCtaKey],
785+
).toBe(true);
786+
});
787+
740788
it('hides mUSD conversion CTA when user is geo-blocked', () => {
741789
const mockEmptyReceiptToken = {
742790
...mockADAIMainnet,
@@ -754,18 +802,6 @@ describe('EarnLendingBalance', () => {
754802
earnToken: mockDaiMainnet,
755803
});
756804

757-
(
758-
selectStablecoinLendingEnabledFlag as jest.MockedFunction<
759-
typeof selectStablecoinLendingEnabledFlag
760-
>
761-
).mockReturnValue(false);
762-
763-
(
764-
selectIsMusdConversionFlowEnabledFlag as jest.MockedFunction<
765-
typeof selectIsMusdConversionFlowEnabledFlag
766-
>
767-
).mockReturnValue(true);
768-
769805
// Geo-blocked: shouldShowAssetOverviewCta returns false
770806
mockShouldShowAssetOverviewCta.mockReturnValue(false);
771807

@@ -816,7 +852,6 @@ describe('EarnLendingBalance', () => {
816852
<EarnLendingBalance asset={mockDaiMainnet} />,
817853
{ state: mockInitialState },
818854
);
819-
820855
// mUSD CTA visible because geo-eligible (useMusdCtaVisibility returns true)
821856
expect(
822857
getByTestId(EARN_TEST_IDS.MUSD.ASSET_OVERVIEW_CONVERSION_CTA),

app/components/UI/Earn/components/EarnLendingBalance/index.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { Hex } from '@metamask/utils';
1+
import { Hex, add0x } from '@metamask/utils';
22
import { useNavigation } from '@react-navigation/native';
33
import BigNumber from 'bignumber.js';
4-
import React, { useMemo } from 'react';
4+
import React, { useMemo, useCallback } from 'react';
55
import { View } from 'react-native';
6-
import { useSelector } from 'react-redux';
6+
import { useSelector, useDispatch } from 'react-redux';
77
import { strings } from '../../../../../../locales/i18n';
88
import PercentageChange from '../../../../../component-library/components-temp/Price/PercentageChange';
99
import { AvatarSize } from '../../../../../component-library/components/Avatars/Avatar';
@@ -34,6 +34,8 @@ import { useTokenPricePercentageChange } from '../../../Tokens/hooks/useTokenPri
3434
import { TokenI } from '../../../Tokens/types';
3535
import { EARN_EXPERIENCES } from '../../constants/experiences';
3636
import { selectStablecoinLendingEnabledFlag } from '../../selectors/featureFlags';
37+
import { setMusdConversionAssetDetailCtaSeen } from '../../../../../actions/user';
38+
import { toHexadecimal } from '../../../../../util/number';
3739
import Earnings from '../Earnings';
3840
import EarnEmptyStateCta from '../EmptyStateCta';
3941
import styleSheet from './EarnLendingBalance.styles';
@@ -56,6 +58,7 @@ export interface EarnLendingBalanceProps {
5658
const { selectEarnTokenPair, selectEarnOutputToken } = earnSelectors;
5759
const EarnLendingBalance = ({ asset }: EarnLendingBalanceProps) => {
5860
const { shouldShowAssetOverviewCta } = useMusdCtaVisibility();
61+
const dispatch = useDispatch();
5962

6063
const { trackEvent, createEventBuilder } = useMetrics();
6164

@@ -171,9 +174,18 @@ const EarnLendingBalance = ({ asset }: EarnLendingBalanceProps) => {
171174
}
172175
};
173176

177+
const handleMusdConversionAssetDetailCtaSeen = useCallback(() => {
178+
if (!asset?.address || !asset?.chainId) return;
179+
const ctaKey = `${add0x(toHexadecimal(asset.chainId))}-${asset.address.toLowerCase()}`;
180+
dispatch(setMusdConversionAssetDetailCtaSeen(ctaKey));
181+
}, [asset?.address, asset?.chainId, dispatch]);
182+
174183
const renderMusdConversionCta = () => (
175184
<View style={styles.musdConversionCta}>
176-
<MusdConversionAssetOverviewCta asset={asset} />
185+
<MusdConversionAssetOverviewCta
186+
asset={asset}
187+
onDismiss={handleMusdConversionAssetDetailCtaSeen}
188+
/>
177189
</View>
178190
);
179191

0 commit comments

Comments
 (0)