Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable STX by default with migration and notification #12857

Open
wants to merge 51 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8252ebe
wip: first stab at migration for stx by default.
httpJunkie Jan 7, 2025
6e2cb2e
feat: enable STX by default with migration 65:
httpJunkie Jan 7, 2025
dfaf2c4
fix: export State for test
httpJunkie Jan 7, 2025
3b451b1
fix: add explicit null checks (alongside `typeof`) in migration 65 er…
httpJunkie Jan 7, 2025
ebaa6d2
test: create initial test for STX by default migration.
httpJunkie Jan 8, 2025
f91d3be
test: continued work on STX by default migration test.
httpJunkie Jan 8, 2025
a6ab361
test: continued work on STX by default migration test
httpJunkie Jan 8, 2025
c1c58d2
test: continued work on STX by default migration test
httpJunkie Jan 8, 2025
fdd0210
test: continued work on STX by default migration test
httpJunkie Jan 8, 2025
68ce7ae
test: continued work on STX by default migration test
httpJunkie Jan 8, 2025
54b561f
feat: create banner component for STX enabled
httpJunkie Jan 8, 2025
53fb3aa
fix: comment out code that is not yet being used
httpJunkie Jan 8, 2025
a3eed30
feat: Updated string references to use new locale keys
httpJunkie Jan 8, 2025
0c570ef
feat: create useSmartTransactionsEnabled hook
httpJunkie Jan 8, 2025
5b3ae78
feat: implement test for hook
httpJunkie Jan 8, 2025
8fbcce4
test: add test for SmartTransactionsEnabledBanner
httpJunkie Jan 8, 2025
a504eb7
feat: update SmartTransactionsEnabledBanner and useTransactionsEnabled
httpJunkie Jan 9, 2025
e95a6fa
feat: add action to store settings
httpJunkie Jan 9, 2025
e9f2846
feat: add smartTransactionsBannerDismissed preferenceController and i…
httpJunkie Jan 9, 2025
b4f2132
feat: add SmartTransactionsEnabledBanner to TransactionReview
httpJunkie Jan 9, 2025
f0cdee7
feat: increase migration number temporarily to avoid conflicts
httpJunkie Jan 14, 2025
2674cfa
Merge branch 'main' into feat/enable-stx-migration
httpJunkie Jan 14, 2025
c346158
feat: remove temporary migration file used to try and setup state, th…
httpJunkie Jan 14, 2025
1cc1453
Merge branch 'main' into feat/enable-stx-migration
httpJunkie Jan 14, 2025
6f64bf2
feat: remove SmartTransactionsEnabledBanner from TransactionReview, e…
httpJunkie Jan 14, 2025
dccd1ef
feat: update SmartTransactionsEnabledBanner to dismiss ALert when lin…
httpJunkie Jan 15, 2025
9be5ae1
fix: update useSmartTransactionsEnabled.test.ts
httpJunkie Jan 15, 2025
00730de
fix: update useSmartTransactionsEnabled hook to add additional checks…
httpJunkie Jan 15, 2025
7133f70
feat: update and improve useSmartTransactionsEnabled
httpJunkie Jan 16, 2025
921ad78
fix: move smartTransactionsBannerDismissed to featureFlags
httpJunkie Jan 16, 2025
971bdca
Merge branch 'main' into feat/enable-stx-migration
httpJunkie Jan 16, 2025
cad3fe3
feat: add banner alert to ApproveTransactionReview and TransactionReview
httpJunkie Jan 16, 2025
378cdcb
feat: add SmartTransactionsEnabledBanner to Swaps Quotes VIew
httpJunkie Jan 16, 2025
e11721c
fix: temporary code to reset `smartTransactionsBannerDismissed` for q…
httpJunkie Jan 16, 2025
f0d6ac6
feat: update QuickView and placement of the the SmartTransactionsEnab…
httpJunkie Jan 16, 2025
02bc56c
fix: update naming convention of SmartTransactionsEnableBanner on Tra…
httpJunkie Jan 16, 2025
bea3655
Merge branch 'main' into feat/enable-stx-migration
httpJunkie Jan 16, 2025
9f7bb23
fix: remove devTestId from TransactionReview view
httpJunkie Jan 17, 2025
76f5758
Merge branch 'feat/enable-stx-migration' of github.com:MetaMask/metam…
httpJunkie Jan 17, 2025
7efc46a
fix: remove dev testing code from `useSmartTransactionsEnabled` hook.
httpJunkie Jan 17, 2025
17a7eeb
Merge branch 'feat/enable-stx-migration' of github.com:MetaMask/metam…
httpJunkie Jan 17, 2025
d745beb
fix: refactor `useSmartTransactionsEnabled` hook to use selectors ins…
httpJunkie Jan 17, 2025
d767fe1
refactor: move smartTransactionsMigrationApplied into PreferencesCont…
httpJunkie Jan 17, 2025
ab77e91
fix: addressing Daniels comments
httpJunkie Jan 17, 2025
ed2a08b
test: update snapshots for:
httpJunkie Jan 17, 2025
badf5c0
test: fix migration test
httpJunkie Jan 17, 2025
08e81ae
fix: update testID values after component name change to be consistent
httpJunkie Jan 17, 2025
3d2e813
test: update location of `smartTransactionsMigrationApplied` to be wi…
httpJunkie Jan 17, 2025
ef8f1ed
test: update snapshot for Approval to account for our component and s…
httpJunkie Jan 17, 2025
6456e04
Merge branch 'main' into feat/enable-stx-migration
httpJunkie Jan 17, 2025
45524be
feat: update migration to #067 from #096
httpJunkie Jan 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/components/UI/Swaps/QuotesView.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ import { selectGasFeeControllerEstimateType } from '../../../selectors/gasFeeCon
import { addSwapsTransaction } from '../../../util/swaps/swaps-transactions';
import { getTransaction1559GasFeeEstimates } from './utils/gas';
import { getGlobalEthQuery } from '../../../util/networks/global-network';
import SmartTransactionsMigrationBanner from '../../Views/confirmations/components/SmartTransactionsMigrationBanner/SmartTransactionsMigrationBanner';

const LOG_PREFIX = 'Swaps';
const POLLING_INTERVAL = 30000;
Expand Down Expand Up @@ -148,6 +149,11 @@ const createStyles = (colors) =>
marginVertical: 10,
width: '100%',
},
smartTransactionsMigrationBanner: {
paddingHorizontal: 20,
marginBottom: -8,
width: '100%',
},
timerWrapper: {
backgroundColor: colors.background.alternative,
borderRadius: 20,
Expand Down Expand Up @@ -1788,7 +1794,11 @@ function SwapsQuotesView({
keyboardShouldPersistTaps="handled"
>
<View style={styles.topBar}>
<View style={styles.smartTransactionsMigrationBanner}>
<SmartTransactionsMigrationBanner />
</View>
{(!hasEnoughTokenBalance || !hasEnoughEthBalance) && (
<>
<View style={styles.alertBar}>
<Alert small type={AlertType.Info}>
<Text reset bold>
Expand All @@ -1810,6 +1820,7 @@ function SwapsQuotesView({
)}
</Alert>
</View>
</>
)}
{!!selectedQuote &&
hasEnoughTokenBalance &&
Expand Down
14 changes: 9 additions & 5 deletions app/components/Views/confirmations/SendFlow/Confirm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ import {
} from './validation';
import { buildTransactionParams } from '../../../../../util/confirmation/transactions';
import { updateTransactionToMaxValue } from './utils';
import SmartTransactionsMigrationBanner from '../../components/SmartTransactionsMigrationBanner/SmartTransactionsMigrationBanner';

const EDIT = 'edit';
const EDIT_NONCE = 'edit_nonce';
Expand Down Expand Up @@ -1413,11 +1414,14 @@ class Confirm extends PureComponent {
/>
<ScrollView style={baseStyles.flexGrow} ref={this.setScrollViewRef}>
{this.state.transactionMeta?.id && (
<TransactionBlockaidBanner
transactionId={this.state.transactionMeta.id}
style={styles.blockaidBanner}
onContactUsClicked={this.onContactUsClicked}
/>
<>
<TransactionBlockaidBanner
transactionId={this.state.transactionMeta.id}
style={styles.blockaidBanner}
onContactUsClicked={this.onContactUsClicked}
/>
<SmartTransactionsMigrationBanner style={styles.smartTransactionsMigrationBanner}/>
</>
)}
{!selectedAsset.tokenId ? (
<View style={styles.amountWrapper}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ const createStyles = (colors: any) =>
marginRight: 24,
marginBottom: 24,
},
smartTransactionsMigrationBanner: {
marginBottom: -8,
marginHorizontal: 16,
},
});

export default createStyles;
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ import SDKConnect from '../../../../../core/SDKConnect/SDKConnect';
import DevLogger from '../../../../../core/SDKConnect/utils/DevLogger';
import { WC2Manager } from '../../../../../core/WalletConnect/WalletConnectV2';
import { WALLET_CONNECT_ORIGIN } from '../../../../../util/walletconnect';

import SmartTransactionsMigrationBanner from '../SmartTransactionsMigrationBanner/SmartTransactionsMigrationBanner';
const { ORIGIN_DEEPLINK, ORIGIN_QR_CODE } = AppConstants.DEEPLINKS;
const POLLING_INTERVAL_ESTIMATED_L1_FEE = 30000;

Expand Down Expand Up @@ -922,6 +922,7 @@ class ApproveTransactionReview extends PureComponent {
style={styles.blockaidWarning}
onContactUsClicked={this.onContactUsClicked}
/>
<SmartTransactionsMigrationBanner style={styles.smartTransactionsMigrationBanner} />
<Text variant={TextVariant.HeadingMD} style={styles.title}>
{this.getTrustTitle(
originIsDeeplink,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ const createStyles = (colors: any) =>
marginTop: 20,
marginHorizontal: 10,
},
SmartTransactionsMigrationBanner: {
marginHorizontal: 16,
marginBottom: -8,
},
});

export default createStyles;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { StyleSheet, ViewStyle } from 'react-native';
import { Theme } from '../../../../../util/theme/models';

const styleSheet = (params: { theme: Theme; vars: { style?: ViewStyle } }) =>
StyleSheet.create({
banner: {
marginTop: 16,
marginBottom: 16,
...params.vars.style,
},
textContainer: {
flexWrap: 'wrap',
},
link: {
color: params.theme.colors.primary.default,
},
description: {
color: params.theme.colors.text.default,
}
});

export default styleSheet;
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import SmartTransactionsMigrationBanner from './SmartTransactionsMigrationBanner';
import Engine from '../../../../../core/Engine';

jest.mock('../../../../../core/Engine', () => ({
context: {
PreferencesController: {
setFeatureFlag: jest.fn(),
},
},
}));

jest.mock('../../../../../../locales/i18n', () => ({
strings: jest.fn((key) => key),
}));

describe('SmartTransactionsMigrationBanner', () => {
const mockStore = configureMockStore();
const mockSetFeatureFlag = jest.mocked(Engine.context.PreferencesController.setFeatureFlag);

const createMockState = (override = {}) => ({
engine: {
backgroundState: {
PreferencesController: {
smartTransactionsOptInStatus: true,
smartTransactionsMigrationApplied: true,
featureFlags: {
smartTransactionsBannerDismissed: false,
},
...override,
},
},
},
});

beforeEach(() => {
jest.clearAllMocks();
});

it('renders nothing when banner should be hidden', () => {
const store = mockStore(createMockState({
featureFlags: { smartTransactionsBannerDismissed: true },
}));

const { queryByTestId } = render(
<Provider store={store}>
<SmartTransactionsMigrationBanner />
</Provider>
);
expect(queryByTestId('smart-transactions-enabled-banner')).toBeNull();
});

it('renders banner when conditions are met', () => {
const store = mockStore(createMockState());

const { getByTestId, getByText } = render(
<Provider store={store}>
<SmartTransactionsMigrationBanner />
</Provider>
);

expect(getByTestId('smart-transactions-enabled-banner')).toBeDefined();
expect(getByText('smart_transactions_enabled.title')).toBeDefined();
expect(getByText('smart_transactions_enabled.link')).toBeDefined();
});

it('calls setFeatureFlag when close button is pressed', () => {
const store = mockStore(createMockState());

const { getByTestId } = render(
<Provider store={store}>
<SmartTransactionsMigrationBanner />
</Provider>
);

fireEvent.press(getByTestId('banner-close-button-icon'));
expect(mockSetFeatureFlag).toHaveBeenCalledWith(
'smartTransactionsBannerDismissed',
true,
);
});

it('accepts and applies custom styles', () => {
const store = mockStore(createMockState());
const customStyle = { marginTop: 20 };

const { getByTestId } = render(
<Provider store={store}>
<SmartTransactionsMigrationBanner style={customStyle} />
</Provider>
);

const banner = getByTestId('smart-transactions-enabled-banner');
expect(banner.props.style).toMatchObject(expect.objectContaining(customStyle));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useCallback, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { Linking } from 'react-native';
import BannerAlert from '../../../../../component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert';
import { BannerAlertSeverity } from '../../../../../component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert.types';
import { strings } from '../../../../../../locales/i18n';
import AppConstants from '../../../../../core/AppConstants';
import Text from '../../../../../component-library/components/Texts/Text';
import { useStyles } from '../../../../../component-library/hooks/useStyles';
import styleSheet from './SmartTransactionsMigrationBanner.styles';
import { SmartTransactionsMigrationBannerProps } from './SmartTransactionsMigrationBanner.types';
import Engine from '../../../../../core/Engine';
import Logger from '../../../../../util/Logger';
import {
selectSmartTransactionsMigrationApplied,
selectSmartTransactionsBannerDismissed,
selectSmartTransactionsOptInStatus
} from '../../../../../selectors/preferencesController';

const SMART_TRANSACTIONS_LEARN_MORE = AppConstants.URLS.SMART_TXS;

const SmartTransactionsMigrationBanner = ({
style,
}: SmartTransactionsMigrationBannerProps) => {
const { styles } = useStyles(styleSheet, { style });
const isEnabled = useSelector(selectSmartTransactionsOptInStatus);
const isMigrationApplied = useSelector(selectSmartTransactionsMigrationApplied);
const isBannerDismissed = useSelector(selectSmartTransactionsBannerDismissed);

const shouldShowBanner = useMemo(
() => isEnabled && isMigrationApplied && !isBannerDismissed,
[isEnabled, isMigrationApplied, isBannerDismissed]
);

const dismissBanner = useCallback(async () => {
try {
const { PreferencesController } = Engine.context;
PreferencesController.setFeatureFlag('smartTransactionsBannerDismissed', true);
} catch (error) {
Logger.error(error as Error, 'Failed to dismiss banner:');
}
}, []);

if (!shouldShowBanner) {
return null;
}

const handleLearnMore = () => {
Linking.openURL(SMART_TRANSACTIONS_LEARN_MORE);
dan437 marked this conversation as resolved.
Show resolved Hide resolved
dismissBanner();
};

return (
<BannerAlert
severity={BannerAlertSeverity.Info}
title={strings('smart_transactions_enabled.title')}
description={
<Text style={styles.textContainer}>
<Text onPress={handleLearnMore} style={styles.link}>
{strings('smart_transactions_enabled.link')}
</Text>
<Text style={styles.description}>
{' '}{strings('smart_transactions_enabled.description')}
</Text>
</Text>
}
onClose={dismissBanner}
style={styles.banner}
testID="smart-transactions-enabled-banner"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would call it after the component's name, in this case: smart-transactions-migration-banner

/>
);
};

export default SmartTransactionsMigrationBanner;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ViewStyle } from 'react-native';

export interface SmartTransactionsMigrationBannerProps {
style?: ViewStyle;
}

export type SmartTransactionsMigrationBannerStyleSheetVars = Pick<
SmartTransactionsMigrationBannerProps,
'style'
>;
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import TransactionReviewData from './TransactionReviewData';
import TransactionReviewInformation from './TransactionReviewInformation';
import TransactionReviewSummary from './TransactionReviewSummary';
import DevLogger from '../../../../../core/SDKConnect/utils/DevLogger';

import SmartTransactionsMigrationBanner from '../SmartTransactionsMigrationBanner/SmartTransactionsMigrationBanner';
const POLLING_INTERVAL_ESTIMATED_L1_FEE = 30000;

let intervalIdForEstimatedL1Fee;
Expand Down Expand Up @@ -120,6 +120,10 @@ const createStyles = (colors) =>
marginHorizontal: 16,
marginBottom: -8,
},
SmartTransactionsMigrationBanner: {
marginHorizontal: 16,
marginBottom: -8,
},
});

/**
Expand Down Expand Up @@ -496,6 +500,7 @@ class TransactionReview extends PureComponent {
}

renderTransactionReview = () => {
Logger.log('TransactionReview RENDER TEST');
dan437 marked this conversation as resolved.
Show resolved Hide resolved
const {
transactionConfirmed,
primaryCurrency,
Expand Down Expand Up @@ -597,6 +602,9 @@ class TransactionReview extends PureComponent {
onContactUsClicked={this.onContactUsClicked}
/>
</View>
<View style={styles.SmartTransactionsMigrationBanner}>
<SmartTransactionsMigrationBanner />
</View>
{to && (
<View style={styles.accountWrapper}>
<AccountFromToInfoCard
Expand Down
12 changes: 12 additions & 0 deletions app/selectors/preferencesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,15 @@
(preferencesControllerState: PreferencesState) =>
preferencesControllerState.privacyMode,
);

export const selectSmartTransactionsMigrationApplied = createSelector(
selectPreferencesControllerState,
(preferencesControllerState: PreferencesState) =>
preferencesControllerState.smartTransactionsMigrationApplied ?? false,

Check failure on line 153 in app/selectors/preferencesController.ts

View workflow job for this annotation

GitHub Actions / scripts (lint:tsc)

Property 'smartTransactionsMigrationApplied' does not exist on type 'PreferencesState'.
);

export const selectSmartTransactionsBannerDismissed = createSelector(
selectPreferencesControllerState,
(preferencesControllerState: PreferencesState) =>
preferencesControllerState.featureFlags?.smartTransactionsBannerDismissed ?? false,
);
Loading
Loading