Skip to content

Commit e6f9a52

Browse files
authored
Merge branch 'main' into ogp/4797
2 parents 9fd5145 + 115a061 commit e6f9a52

File tree

63 files changed

+799
-718
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+799
-718
lines changed

.github/workflows/create-release-pr-v2.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020

2121
create-release-pr:
2222
needs: generate-build-version
23-
uses: MetaMask/github-tools/.github/workflows/create-release-pr.yml@3e0b0204e41b576263b9060945de3b3b9b8c5448
23+
uses: MetaMask/github-tools/.github/workflows/create-release-pr.yml@d1ba843333b920fc9b0e1823fd519b7a64d07f5f
2424
with:
2525
platform: mobile
2626
base-branch: ${{ inputs.base-branch }}

.github/workflows/create-release-pr.yml

-57
This file was deleted.

app/components/UI/AssetOverview/TokenDetails/TokenDetailsList/TokenDetailsList.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ const TokenDetailsList: React.FC<TokenDetailsListProps> = ({
7474
</TouchableOpacity>
7575
</TokenDetailsListItem>
7676
)}
77-
{tokenDetails.tokenDecimal && (
77+
{Boolean(tokenDetails.tokenDecimal) && (
7878
<TokenDetailsListItem
7979
label={strings('token.token_decimal')}
80-
value={tokenDetails.tokenDecimal}
80+
value={tokenDetails.tokenDecimal ?? undefined}
8181
style={styles.listItem}
8282
/>
8383
)}

app/components/UI/BasicFunctionality/BasicFunctionalityModal/BasicFunctionalityModal.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { MetaMetricsEvents } from '../../../../core/Analytics';
3131
import { useEnableNotifications } from '../../../../util/notifications/hooks/useNotifications';
3232
import { useMetrics } from '../../../hooks/useMetrics';
3333
import { selectIsMetamaskNotificationsEnabled } from '../../../../selectors/notifications';
34-
import { selectIsProfileSyncingEnabled } from '../../../../selectors/identity';
34+
import { selectIsBackupAndSyncEnabled } from '../../../../selectors/identity';
3535

3636
interface Props {
3737
route: {
@@ -51,7 +51,7 @@ const BasicFunctionalityModal = ({ route }: Props) => {
5151
const isEnabled = useSelector(
5252
(state: RootState) => state?.settings?.basicFunctionalityEnabled,
5353
);
54-
const isProfileSyncingEnabled = useSelector(selectIsProfileSyncingEnabled);
54+
const isBackupAndSyncEnabled = useSelector(selectIsBackupAndSyncEnabled);
5555
const isNotificationsFeatureEnabled = useSelector(
5656
selectIsMetamaskNotificationsEnabled,
5757
);
@@ -86,7 +86,7 @@ const BasicFunctionalityModal = ({ route }: Props) => {
8686
was_notifications_on: isEnabled
8787
? isNotificationsFeatureEnabled
8888
: false,
89-
was_profile_syncing_on: isEnabled ? isProfileSyncingEnabled : false,
89+
was_profile_syncing_on: isEnabled ? isBackupAndSyncEnabled : false,
9090
})
9191
.build(),
9292
);

app/components/UI/Bridge/Views/BridgeView/index.tsx

+21-28
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import {
3434
selectIsEvmSolanaBridge,
3535
selectIsSolanaSwap,
3636
setSlippage,
37+
selectIsSubmittingTx,
38+
setIsSubmittingTx,
3739
} from '../../../../../core/redux/slices/bridge';
3840
import {
3941
useNavigation,
@@ -46,7 +48,6 @@ import { strings } from '../../../../../../locales/i18n';
4648
import useSubmitBridgeTx from '../../../../../util/bridge/hooks/useSubmitBridgeTx';
4749
import Engine from '../../../../../core/Engine';
4850
import Routes from '../../../../../constants/navigation/Routes';
49-
import { selectBasicFunctionalityEnabled } from '../../../../../selectors/settings';
5051
import ButtonIcon from '../../../../../component-library/components/Buttons/ButtonIcon';
5152
import QuoteDetailsCard from '../../components/QuoteDetailsCard';
5253
import { useBridgeQuoteRequest } from '../../hooks/useBridgeQuoteRequest';
@@ -70,11 +71,16 @@ import { useSwitchTokens } from '../../hooks/useSwitchTokens';
7071

7172
const BridgeView = () => {
7273
const [isInputFocused, setIsInputFocused] = useState(false);
73-
const [isSubmittingTx, setIsSubmittingTx] = useState(false);
74-
// The same as getUseExternalServices in Extension
75-
const isBasicFunctionalityEnabled = useSelector(
76-
selectBasicFunctionalityEnabled,
77-
);
74+
const isSubmittingTx = useSelector(selectIsSubmittingTx);
75+
76+
// Ref necessary to avoid race condition between Redux state and component state
77+
// Without it, the component would reset the bridge state when it shouldn't
78+
const isSubmittingTxRef = useRef(isSubmittingTx);
79+
80+
// Update ref when Redux state changes
81+
useEffect(() => {
82+
isSubmittingTxRef.current = isSubmittingTx;
83+
}, [isSubmittingTx]);
7884

7985
const { styles } = useStyles(createStyles, {});
8086
const dispatch = useDispatch();
@@ -175,10 +181,13 @@ const BridgeView = () => {
175181
// Reset bridge state when component unmounts
176182
useEffect(
177183
() => () => {
178-
dispatch(resetBridgeState());
179-
// Clear bridge controller state if available
180-
if (Engine.context.BridgeController?.resetState) {
181-
Engine.context.BridgeController.resetState();
184+
// Only reset state if we're not in the middle of a transaction
185+
if (!isSubmittingTxRef.current) {
186+
dispatch(resetBridgeState());
187+
// Clear bridge controller state if available
188+
if (Engine.context.BridgeController?.resetState) {
189+
Engine.context.BridgeController.resetState();
190+
}
182191
}
183192
},
184193
[dispatch],
@@ -188,23 +197,6 @@ const BridgeView = () => {
188197
navigation.setOptions(getBridgeNavbar(navigation, route, colors));
189198
}, [navigation, route, colors]);
190199

191-
useEffect(() => {
192-
const setBridgeFeatureFlags = async () => {
193-
try {
194-
if (
195-
isBasicFunctionalityEnabled &&
196-
Engine.context.BridgeController?.setBridgeFeatureFlags
197-
) {
198-
await Engine.context.BridgeController.setBridgeFeatureFlags();
199-
}
200-
} catch (error) {
201-
console.error('Error setting bridge feature flags', error);
202-
}
203-
};
204-
205-
setBridgeFeatureFlags();
206-
}, [isBasicFunctionalityEnabled]);
207-
208200
const hasTrackedPageView = useRef(false);
209201
useEffect(() => {
210202
const shouldTrackPageView = sourceToken && !hasTrackedPageView.current;
@@ -248,11 +240,12 @@ const BridgeView = () => {
248240

249241
const handleContinue = async () => {
250242
if (activeQuote) {
251-
setIsSubmittingTx(true);
243+
dispatch(setIsSubmittingTx(true));
252244
await submitBridgeTx({
253245
quoteResponse: activeQuote,
254246
});
255247
navigation.navigate(Routes.TRANSACTIONS_VIEW);
248+
dispatch(setIsSubmittingTx(false));
256249
}
257250
};
258251

app/components/UI/Bridge/_mocks_/bridgeControllerState.ts

-20
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
import {
2-
BridgeFeatureFlagsKey,
3-
formatChainIdToCaip,
4-
} from '@metamask/bridge-controller';
51
import { Hex } from '@metamask/utils';
62

73
export const mockChainId = '0x1' as Hex;
8-
const ethChainId = '0x1' as Hex;
9-
const optimismChainId = '0xa' as Hex;
104

115
// Ethereum tokens
126
export const ethToken1Address =
@@ -19,20 +13,6 @@ export const optimismToken1Address =
1913
'0x0000000000000000000000000000000000000003' as Hex;
2014

2115
export const defaultBridgeControllerState = {
22-
bridgeFeatureFlags: {
23-
[BridgeFeatureFlagsKey.MOBILE_CONFIG]: {
24-
chains: {
25-
[formatChainIdToCaip(ethChainId)]: {
26-
isActiveSrc: true,
27-
isActiveDest: true,
28-
},
29-
[formatChainIdToCaip(optimismChainId)]: {
30-
isActiveSrc: true,
31-
isActiveDest: true,
32-
},
33-
},
34-
},
35-
},
3616
quoteRequest: {},
3717
quotes: [],
3818
quotesInitialLoadTime: null,

app/components/UI/Bridge/_mocks_/bridgeReducerState.ts

+1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ export const mockBridgeReducerState: BridgeState = {
2727
selectedSourceChainIds: ['0x1'],
2828
selectedDestChainId: '0xa',
2929
slippage: '0.5',
30+
isSubmittingTx: false,
3031
};

app/components/UI/Bridge/_mocks_/initialState.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { defaultBridgeControllerState } from './bridgeControllerState';
22
import { CaipAssetId, Hex } from '@metamask/utils';
33
import { SolScope } from '@metamask/keyring-api';
44
import { ethers } from 'ethers';
5-
import { StatusTypes } from '@metamask/bridge-controller';
5+
import { formatChainIdToCaip, StatusTypes } from '@metamask/bridge-controller';
66

77
export const ethChainId = '0x1' as Hex;
88
export const optimismChainId = '0xa' as Hex;
@@ -34,6 +34,25 @@ export const solanaToken2Address =
3434
export const initialState = {
3535
engine: {
3636
backgroundState: {
37+
RemoteFeatureFlagController: {
38+
remoteFeatureFlags: {
39+
bridgeConfig: {
40+
maxRefreshCount: 5,
41+
refreshRate: 30000,
42+
support: true,
43+
chains: {
44+
[formatChainIdToCaip(ethChainId)]: {
45+
isActiveSrc: true,
46+
isActiveDest: true,
47+
},
48+
[formatChainIdToCaip(optimismChainId)]: {
49+
isActiveSrc: true,
50+
isActiveDest: true,
51+
},
52+
},
53+
},
54+
},
55+
},
3756
BridgeController: defaultBridgeControllerState,
3857
TokenBalancesController: {
3958
tokenBalances: {

app/components/UI/Bridge/components/BridgeDestNetworkSelector/BridgeDestNetworkSelector.test.tsx

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import { BridgeDestNetworkSelector } from '.';
44
import Routes from '../../../../../constants/navigation/Routes';
55
import { Hex } from '@metamask/utils';
66
import { setSelectedDestChainId } from '../../../../../core/redux/slices/bridge';
7-
import {
8-
BridgeFeatureFlagsKey,
9-
formatChainIdToCaip,
10-
} from '@metamask/bridge-controller';
7+
import { formatChainIdToCaip } from '@metamask/bridge-controller';
118
import { initialState } from '../../_mocks_/initialState';
129

1310
const mockNavigate = jest.fn();
@@ -100,9 +97,12 @@ describe('BridgeDestNetworkSelector', () => {
10097
...initialState.engine,
10198
backgroundState: {
10299
...initialState.engine.backgroundState,
103-
BridgeController: {
104-
bridgeFeatureFlags: {
105-
[BridgeFeatureFlagsKey.MOBILE_CONFIG]: {
100+
RemoteFeatureFlagController: {
101+
remoteFeatureFlags: {
102+
bridgeConfig: {
103+
maxRefreshCount: 5,
104+
refreshRate: 30000,
105+
support: true,
106106
chains: {
107107
[formatChainIdToCaip(mockChainId)]: {
108108
isActiveSrc: true,

app/components/UI/Bridge/components/QuoteExpiredModal/QuoteExpiredModal.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,22 @@ import { useStyles } from '../../../../../component-library/hooks';
1818
import createStyles from './QuoteExpiredModal.styles';
1919
import { useBridgeQuoteRequest } from '../../hooks/useBridgeQuoteRequest';
2020
import Engine from '../../../../../core/Engine';
21+
import { setIsSubmittingTx } from '../../../../../core/redux/slices/bridge';
22+
import { useDispatch } from 'react-redux';
2123

2224
const QuoteExpiredModal = () => {
2325
const navigation = useNavigation();
2426
const sheetRef = useRef<BottomSheetRef>(null);
2527
const { styles } = useStyles(createStyles, {});
2628
const updateQuoteParams = useBridgeQuoteRequest();
29+
const dispatch = useDispatch();
2730

2831
const handleClose = () => {
2932
navigation.goBack();
3033
};
3134

3235
const handleGetNewQuote = () => {
36+
dispatch(setIsSubmittingTx(false));
3337
// Reset bridge controller state
3438
if (Engine.context.BridgeController?.resetState) {
3539
Engine.context.BridgeController.resetState();

app/components/UI/Bridge/components/TokenInputArea/index.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,10 @@ export const TokenInputArea = forwardRef<
200200
const { quoteRequest } = useSelector(selectBridgeControllerState);
201201
const isInsufficientBalance = quoteRequest?.insufficientBal;
202202

203-
const nonEvmMultichainAssetRates = useSelector(selectMultichainAssetsRates);
203+
let nonEvmMultichainAssetRates = {};
204+
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
205+
nonEvmMultichainAssetRates = useSelector(selectMultichainAssetsRates);
206+
///: END:ONLY_INCLUDE_IF(keyring-snaps)
204207

205208
const fiatValue = getDisplayFiatValue({
206209
token,

app/components/UI/Bridge/components/TransactionDetails/BlockExplorersModal.test.tsx

+11-9
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import {
44
TransactionMeta,
55
TransactionStatus,
66
} from '@metamask/transaction-controller';
7-
import {
8-
BridgeFeatureFlagsKey,
9-
formatChainIdToCaip,
10-
} from '@metamask/bridge-controller';
7+
import { formatChainIdToCaip } from '@metamask/bridge-controller';
118
import { Hex } from '@metamask/utils';
129
import initialBackgroundState from '../../../../../util/test/initial-background-state.json';
1310
import { renderScreen } from '../../../../../util/test/renderWithProvider';
@@ -99,8 +96,16 @@ describe('BlockExplorersModal', () => {
9996
},
10097
},
10198
BridgeController: {
102-
bridgeFeatureFlags: {
103-
[BridgeFeatureFlagsKey.MOBILE_CONFIG]: {
99+
quoteRequest: {
100+
slippage: 0.5,
101+
},
102+
},
103+
RemoteFeatureFlagController: {
104+
remoteFeatureFlags: {
105+
bridgeConfig: {
106+
maxRefreshCount: 5,
107+
refreshRate: 30000,
108+
support: true,
104109
chains: {
105110
[formatChainIdToCaip(mockChainId)]: {
106111
isActiveSrc: true,
@@ -113,9 +118,6 @@ describe('BlockExplorersModal', () => {
113118
},
114119
},
115120
},
116-
quoteRequest: {
117-
slippage: 0.5,
118-
},
119121
},
120122
TokenBalancesController: {
121123
tokenBalances: {

0 commit comments

Comments
 (0)