diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5bf134cd11bd..20f528c3d830 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [7.58.2]
+
+### Fixed
+
+- fix(card): cp-7.58.2 delegation issues ([#22476](https://github.com/MetaMask/metamask-mobile/pull/22476)
+- fix: pressability measureAsyncOnUI only running on Android cp-7.58.2 ([#22464](https://github.com/MetaMask/metamask-mobile/pull/22464)
+- fix(card): cp-7.58.2 CardHome and SpendingLimit UI issues ([#22448](https://github.com/MetaMask/metamask-mobile/pull/22448)
+- fix(card): UI issues on Authentication/Delegation ([#22433](https://github.com/MetaMask/metamask-mobile/pull/22433)
+- fix: cp-7.58.2 update close position calculation with funding fees and live data ([#22344](https://github.com/MetaMask/metamask-mobile/pull/22344)
+
+## [7.58.1]
+
+### Fixed
+
+- fix: Android In-App Browser Crash ([#22269](https://github.com/MetaMask/metamask-mobile/pull/22269))
+- fix: cp-75.8.1 remove selected network reference from bridge getBridgeERC20Allowance handler ([#22230](https://github.com/MetaMask/metamask-mobile/pull/22230))
+- fix(card): add temporary fix for crashing KYC webview on Android ([#22238](https://github.com/MetaMask/metamask-mobile/pull/22238))
+- fix(card): Onboarding UI issues ([#22263](https://github.com/MetaMask/metamask-mobile/pull/22263))
+- fix(card): delegation issues ([#22249](https://github.com/MetaMask/metamask-mobile/pull/22249))
+
+### Changed
+
+- refactor(card): sonarcloud maintainability issues ([#22268](https://github.com/MetaMask/metamask-mobile/pull/22268))
+
## [7.58.0]
### Added
@@ -8783,7 +8807,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#957](https://github.com/MetaMask/metamask-mobile/pull/957): fix timeouts (#957)
- [#954](https://github.com/MetaMask/metamask-mobile/pull/954): Bugfix: onboarding navigation (#954)
-[Unreleased]: https://github.com/MetaMask/metamask-mobile/compare/v7.58.0...HEAD
+[Unreleased]: https://github.com/MetaMask/metamask-mobile/compare/v7.58.2...HEAD
+[7.58.2]: https://github.com/MetaMask/metamask-mobile/compare/v7.58.1...v7.58.2
+[7.58.1]: https://github.com/MetaMask/metamask-mobile/compare/v7.58.0...v7.58.1
[7.58.0]: https://github.com/MetaMask/metamask-mobile/compare/v7.57.2...v7.58.0
[7.57.2]: https://github.com/MetaMask/metamask-mobile/compare/v7.57.1...v7.57.2
[7.57.1]: https://github.com/MetaMask/metamask-mobile/compare/v7.57.0...v7.57.1
diff --git a/app/components/Nav/Main/MainNavigator.js b/app/components/Nav/Main/MainNavigator.js
index 97a4a62f0acd..703a68aad012 100644
--- a/app/components/Nav/Main/MainNavigator.js
+++ b/app/components/Nav/Main/MainNavigator.js
@@ -942,8 +942,8 @@ const MainNavigator = () => {
// Get feature flag state for conditional Predict screen registration
const predictEnabledFlag = useSelector(selectPredictEnabledFlag);
const isPredictEnabled = useMemo(
- () => predictEnabledFlag && isEvmSelected,
- [predictEnabledFlag, isEvmSelected],
+ () => predictEnabledFlag,
+ [predictEnabledFlag],
);
const { enabled: isSendRedesignEnabled } = useSelector(
selectSendRedesignFlags,
diff --git a/app/components/UI/Card/hooks/useAssetBalances.test.ts b/app/components/UI/Card/hooks/useAssetBalances.test.ts
index 3dd96b16e369..2615aba97a6c 100644
--- a/app/components/UI/Card/hooks/useAssetBalances.test.ts
+++ b/app/components/UI/Card/hooks/useAssetBalances.test.ts
@@ -382,7 +382,7 @@ describe('useAssetBalances', () => {
mockUseTokensWithBalance.mockReturnValue([
{
address: mockEvmToken.address?.toLowerCase() || '',
- chainId: mockEvmToken.caipChainId,
+ chainId: '0xe708', // Use hex format, not CAIP format
balance: '250.75',
balanceFiat: '$250.75',
symbol: 'USDC',
@@ -449,7 +449,7 @@ describe('useAssetBalances', () => {
mockUseTokensWithBalance.mockReturnValue([
{
address: mockNotEnabledToken.address?.toLowerCase() || '',
- chainId: mockNotEnabledToken.caipChainId,
+ chainId: '0xe708', // Use hex format, not CAIP format
balance: '200.75',
balanceFiat: '$200.75',
symbol: 'DAI',
@@ -559,7 +559,7 @@ describe('useAssetBalances', () => {
mockUseTokensWithBalance.mockReturnValue([
{
address: mockEvmToken.address?.toLowerCase() || '',
- chainId: mockEvmToken.caipChainId,
+ chainId: '0xe708', // Use hex format, not CAIP format
balance: '125.50',
balanceFiat: '$125.50',
symbol: 'USDC',
diff --git a/app/components/UI/Card/hooks/useAssetBalances.tsx b/app/components/UI/Card/hooks/useAssetBalances.tsx
index 7ba8a6df2b3d..8f9389881476 100644
--- a/app/components/UI/Card/hooks/useAssetBalances.tsx
+++ b/app/components/UI/Card/hooks/useAssetBalances.tsx
@@ -71,6 +71,7 @@ export const useAssetBalances = (
}
}
});
+
return map;
});
@@ -114,6 +115,7 @@ export const useAssetBalances = (
}
}
});
+
return map;
});
@@ -487,8 +489,13 @@ export const useAssetBalances = (
: safeFormatChainIdToHex(token.caipChainId);
// Find the token in tokensWithBalance
+ // Note: tokensWithBalance uses hex chainId (e.g., "0xe708") while token has CAIP chainId (e.g., "eip155:59144")
+ // We need to use assetChainId which is already normalized to the correct format
+ // Also need case-insensitive address comparison since tokensWithBalance may have checksum addresses
const filteredToken = tokensWithBalance.find(
- (t) => t.address === assetAddress && t.chainId === token.caipChainId,
+ (t) =>
+ t.address?.toLowerCase() === assetAddress?.toLowerCase() &&
+ t.chainId === assetChainId,
);
// Get wallet asset as fallback
diff --git a/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.test.tsx b/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.test.tsx
index 573ee49e5cb5..b17feae1289e 100644
--- a/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.test.tsx
+++ b/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.test.tsx
@@ -41,7 +41,7 @@ jest.mock('../../../../../component-library/components/Icons/Icon', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
default: ({ name, ...props }: any) => ,
IconName: {
- Details: 'Details',
+ Warning: 'Warning',
},
IconColor: {
Muted: 'Muted',
@@ -146,7 +146,6 @@ describe('PerpsConnectionErrorView', () => {
);
expect(getByText('perps.errors.connectionFailed.title')).toBeTruthy();
- expect(getByText('perps.errors.connectionFailed.description')).toBeTruthy();
expect(getByText('perps.errors.connectionFailed.retry')).toBeTruthy();
});
diff --git a/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.tsx b/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.tsx
index d205342e50a1..de934cfcd604 100644
--- a/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.tsx
+++ b/app/components/UI/Perps/components/PerpsConnectionErrorView/PerpsConnectionErrorView.tsx
@@ -85,7 +85,7 @@ const PerpsConnectionErrorView: React.FC = ({
= ({
{strings('perps.errors.connectionFailed.title')}
-
- {strings('perps.errors.connectionFailed.description')}
-
-
{/* Only show debug details in development */}
{shouldShowDebugDetails && (
{
expect(
getByText(strings('perps.errors.connectionFailed.title')),
).toBeTruthy();
- expect(
- getByText(strings('perps.errors.connectionFailed.description')),
- ).toBeTruthy();
const retryButton = getByText(
strings('perps.errors.connectionFailed.retry'),
diff --git a/app/components/UI/Perps/components/PerpsErrorState/PerpsErrorState.tsx b/app/components/UI/Perps/components/PerpsErrorState/PerpsErrorState.tsx
index 1c250a3de0c2..c3ff5d620bef 100644
--- a/app/components/UI/Perps/components/PerpsErrorState/PerpsErrorState.tsx
+++ b/app/components/UI/Perps/components/PerpsErrorState/PerpsErrorState.tsx
@@ -45,9 +45,9 @@ const PerpsErrorState: React.FC = ({
switch (errorType) {
case PerpsErrorType.CONNECTION_FAILED:
return {
- icon: IconName.Wifi,
+ icon: IconName.Warning,
title: strings('perps.errors.connectionFailed.title'),
- description: strings('perps.errors.connectionFailed.description'),
+ description: undefined,
primaryAction: {
label: strings('perps.errors.connectionFailed.retry'),
onPress: onRetry,
@@ -97,13 +97,15 @@ const PerpsErrorState: React.FC = ({
>
{errorContent.title}
-
- {errorContent.description}
-
+ {errorContent.description && (
+
+ {errorContent.description}
+
+ )}
{errorContent.primaryAction?.onPress && (