diff --git a/eslint-suppressions.json b/eslint-suppressions.json
index 884886d8b..793459a30 100644
--- a/eslint-suppressions.json
+++ b/eslint-suppressions.json
@@ -795,11 +795,6 @@
"count": 1
}
},
- "packages/solana-wallet-snap/src/features/confirmation/components/AssetChange/AssetChange.tsx": {
- "@typescript-eslint/no-shadow": {
- "count": 1
- }
- },
"packages/solana-wallet-snap/src/features/confirmation/components/BasicNullableField/BasicNullableField.tsx": {
"@typescript-eslint/explicit-function-return-type": {
"count": 1
@@ -808,16 +803,6 @@
"count": 1
}
},
- "packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.tsx": {
- "@typescript-eslint/no-shadow": {
- "count": 1
- }
- },
- "packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChangesHeader.tsx": {
- "@typescript-eslint/no-shadow": {
- "count": 1
- }
- },
"packages/solana-wallet-snap/src/features/confirmation/components/Instruction/Instruction.tsx": {
"@typescript-eslint/explicit-function-return-type": {
"count": 2
diff --git a/packages/solana-wallet-snap/CHANGELOG.md b/packages/solana-wallet-snap/CHANGELOG.md
index 2a15d06fb..ab0e26d4a 100644
--- a/packages/solana-wallet-snap/CHANGELOG.md
+++ b/packages/solana-wallet-snap/CHANGELOG.md
@@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **BREAKING** Bump `@metamask/keyring-api` from `^23.7.0` to `^24.1.0` ([#214](https://github.com/MetaMask/internal-snaps/pull/214))
- **BREAKING** Bump `@metamask/keyring-snap-sdk` from `^9.2.1` to `^10.0.0` ([#214](https://github.com/MetaMask/internal-snaps/pull/214))
- **BREAKING** Bump `@metamask/snaps-sdk` from `^11.2.0` to `^12.0.1` ([#214](https://github.com/MetaMask/internal-snaps/pull/214))
+- Render the confirmation "Estimated changes" section with the shared `EstimatedChanges` component from `@metamask/snap-networks-utils` ([#384](https://github.com/MetaMask/internal-snaps/pull/384))
+ - Estimated changes from the previous scan now stay visible while a confirmation re-scans, instead of showing a loading skeleton
### Removed
diff --git a/packages/solana-wallet-snap/jest.config.js b/packages/solana-wallet-snap/jest.config.js
index 12459b455..b787d50ce 100644
--- a/packages/solana-wallet-snap/jest.config.js
+++ b/packages/solana-wallet-snap/jest.config.js
@@ -27,10 +27,10 @@ module.exports = {
coverageThreshold: {
global: {
- branches: 68.38,
- functions: 78.28,
- lines: 87.1,
- statements: 87.24,
+ branches: 69,
+ functions: 79.01,
+ lines: 87.2,
+ statements: 87.37,
},
},
};
diff --git a/packages/solana-wallet-snap/snap.manifest.json b/packages/solana-wallet-snap/snap.manifest.json
index 576d3c81d..0b8571f8f 100644
--- a/packages/solana-wallet-snap/snap.manifest.json
+++ b/packages/solana-wallet-snap/snap.manifest.json
@@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/internal-snaps.git"
},
"source": {
- "shasum": "JcoWP+Q/tJLW3D8uvcA0dYPPvQhgSut5+27i+w0RNMY=",
+ "shasum": "urQPGAYX3VKpvLrahiRnEZXB4FZfanxpgEwTiLwKOJY=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
diff --git a/packages/solana-wallet-snap/src/features/confirmation/components/AssetChange/AssetChange.tsx b/packages/solana-wallet-snap/src/features/confirmation/components/AssetChange/AssetChange.tsx
deleted file mode 100644
index 390641f47..000000000
--- a/packages/solana-wallet-snap/src/features/confirmation/components/AssetChange/AssetChange.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import type { SnapComponent } from '@metamask/snaps-sdk/jsx';
-import { Box, Image, Text } from '@metamask/snaps-sdk/jsx';
-
-import type { TransactionScanAssetChange } from '../../../../core/services/transaction-scan/types';
-import type { Preferences } from '../../../../core/types/snap';
-import { formatCryptoBalance } from '../../../../core/utils/formatCryptoBalance';
-import { formatFiat } from '../../../../core/utils/formatFiat';
-
-export const AssetChange: SnapComponent<{
- asset: TransactionScanAssetChange;
- preferences: Preferences;
-}> = ({ asset, preferences }) => {
- const changeType = asset.type;
-
- return (
-
-
-
- {changeType === 'in' ? '+' : '-'}
- {formatCryptoBalance(asset.value ?? 0, preferences.locale)}
-
- {asset.logo ? (
-
-
-
- ) : null}
- {asset.symbol ?? ''}
-
- {asset.price ? (
-
- {formatFiat(
- asset.price.toString(),
- preferences.currency,
- preferences.locale,
- )}
-
- ) : null}
-
- );
-};
diff --git a/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.test.tsx b/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.test.tsx
new file mode 100644
index 000000000..51bccf10f
--- /dev/null
+++ b/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.test.tsx
@@ -0,0 +1,58 @@
+import type { TransactionScanAssetChange } from '../../../../core/services/transaction-scan/types';
+import type { Preferences } from '../../../../core/types/snap';
+import { EstimatedChanges } from './EstimatedChanges';
+
+const preferences = { locale: 'en', currency: 'usd' } as Preferences;
+
+const sol: TransactionScanAssetChange = {
+ type: 'out',
+ value: 1.5,
+ price: 300,
+ symbol: 'SOL',
+ name: 'Solana',
+ logo: 'https://example.com/sol.png',
+};
+
+const render = (
+ props: Partial[0]>,
+): string =>
+ JSON.stringify(
+ EstimatedChanges({
+ changes: { assets: [sol] },
+ scanStatus: 'SUCCESS',
+ scanFetchStatus: 'fetched',
+ preferences,
+ ...props,
+ }),
+ );
+
+describe('EstimatedChanges', () => {
+ it('renders formatted amounts, fiat and translated labels', () => {
+ const serialized = render({});
+
+ expect(serialized).toContain('Estimated changes');
+ expect(serialized).toContain('You send');
+ expect(serialized).toContain('-1.5 SOL');
+ expect(serialized).toContain('$300.00');
+ expect(serialized).toContain(sol.logo);
+ });
+
+ it('omits fiat when the asset has no price', () => {
+ const serialized = render({
+ changes: { assets: [{ ...sol, price: null }] },
+ });
+
+ expect(serialized).not.toContain('$');
+ });
+
+ it('renders not available when the scan result is an error', () => {
+ const serialized = render({ changes: null, scanStatus: 'ERROR' });
+
+ expect(serialized).toContain('Not available');
+ expect(serialized).not.toContain('No changes');
+ });
+
+ it('renders no changes when there are no estimated changes', () => {
+ expect(render({ changes: null })).toContain('No changes');
+ });
+});
diff --git a/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.tsx b/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.tsx
index 172b3ee0d..78f241153 100644
--- a/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.tsx
+++ b/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChanges.tsx
@@ -1,4 +1,4 @@
-import { Box, Section, Text } from '@metamask/snaps-sdk/jsx';
+import { EstimatedChanges as SharedEstimatedChanges } from '@metamask/snap-networks-utils';
import type { SnapComponent } from '@metamask/snaps-sdk/jsx';
import type {
@@ -6,10 +6,9 @@ import type {
TransactionScanStatus,
} from '../../../../core/services/transaction-scan/types';
import type { FetchStatus, Preferences } from '../../../../core/types/snap';
+import { formatCryptoBalance } from '../../../../core/utils/formatCryptoBalance';
+import { formatFiat } from '../../../../core/utils/formatFiat';
import { i18n } from '../../../../core/utils/i18n';
-import { AssetChange } from '../AssetChange/AssetChange';
-import { EstimatedChangesHeader } from './EstimatedChangesHeader';
-import { EstimatedChangesSkeleton } from './EstimatedChangesSkeleton';
type EstimatedChangesProps = {
changes: TransactionScanEstimatedChanges | null;
@@ -25,74 +24,32 @@ export const EstimatedChanges: SnapComponent = ({
scanStatus,
}) => {
const translate = i18n(preferences.locale);
-
- const isFetching = scanFetchStatus === 'fetching';
- const isFetched = scanFetchStatus === 'fetched';
- const isError = scanFetchStatus === 'error';
-
- if (isFetching) {
- return ;
- }
-
- if (isError || (isFetched && scanStatus === 'ERROR')) {
- return (
-
-
-
- {translate('confirmation.estimatedChanges.notAvailable')}
-
-
- );
- }
-
- const send = changes?.assets.filter((asset) => asset.type === 'out') ?? [];
- const receive = changes?.assets.filter((asset) => asset.type === 'in') ?? [];
-
- const hasChanges = send.length > 0 || receive.length > 0;
-
- if (isFetched && !hasChanges) {
- return (
-
-
-
- {translate('confirmation.estimatedChanges.noChanges')}
-
-
- );
- }
+ const { locale, currency } = preferences;
return (
-
-
- {send?.length > 0 ? (
-
-
- {translate('confirmation.estimatedChanges.send')}
-
-
-
- {send?.map((asset) => (
-
- ))}
-
-
-
- ) : null}
- {null}
- {receive?.length > 0 ? (
-
-
- {translate('confirmation.estimatedChanges.receive')}
-
-
-
- {receive?.map((asset) => (
-
- ))}
-
-
-
- ) : null}
-
+ ({
+ type: asset.type,
+ value:
+ asset.value === null
+ ? null
+ : formatCryptoBalance(asset.value, locale),
+ symbol: asset.symbol,
+ logo: asset.logo,
+ fiat: asset.price
+ ? formatFiat(asset.price.toString(), currency, locale)
+ : null,
+ }))}
+ labels={{
+ title: translate('confirmation.estimatedChanges'),
+ tooltip: translate('confirmation.estimatedChanges.tooltip'),
+ send: translate('confirmation.estimatedChanges.send'),
+ receive: translate('confirmation.estimatedChanges.receive'),
+ notAvailable: translate('confirmation.estimatedChanges.notAvailable'),
+ noChanges: translate('confirmation.estimatedChanges.noChanges'),
+ }}
+ scanFetchStatus={scanFetchStatus}
+ scanError={scanStatus === 'ERROR'}
+ />
);
};
diff --git a/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChangesHeader.tsx b/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChangesHeader.tsx
deleted file mode 100644
index 5d1965de7..000000000
--- a/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChangesHeader.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import type { SnapComponent } from '@metamask/snaps-sdk/jsx';
-import { Icon, Text, Tooltip, Box } from '@metamask/snaps-sdk/jsx';
-
-import type { Preferences } from '../../../../core/types/snap';
-import { i18n } from '../../../../core/utils/i18n';
-
-export const EstimatedChangesHeader: SnapComponent<{
- preferences: Preferences;
-}> = ({ preferences }) => {
- const translate = i18n(preferences.locale);
-
- return (
-
-
- {translate('confirmation.estimatedChanges')}
-
-
-
-
-
- );
-};
diff --git a/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChangesSkeleton.tsx b/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChangesSkeleton.tsx
deleted file mode 100644
index 3821024fd..000000000
--- a/packages/solana-wallet-snap/src/features/confirmation/components/EstimatedChanges/EstimatedChangesSkeleton.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { SnapComponent } from '@metamask/snaps-sdk/jsx';
-import { Box, Section, Skeleton } from '@metamask/snaps-sdk/jsx';
-
-import type { Preferences } from '../../../../core/types/snap';
-import { EstimatedChangesHeader } from './EstimatedChangesHeader';
-
-export const EstimatedChangesSkeleton: SnapComponent<{
- preferences: Preferences;
-}> = ({ preferences }) => {
- return (
-
- );
-};