diff --git a/packages/tron-wallet-snap/CHANGELOG.md b/packages/tron-wallet-snap/CHANGELOG.md
index 9eb0ce5e4..d6dc30f85 100644
--- a/packages/tron-wallet-snap/CHANGELOG.md
+++ b/packages/tron-wallet-snap/CHANGELOG.md
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Estimated changes from the previous scan now stay visible while a confirmation re-scans, instead of showing a loading skeleton
- Render the confirmation security alert banner with the shared `TransactionAlert` component from `@metamask/snap-networks-utils` ([#414](https://github.com/MetaMask/internal-snaps/pull/414))
- A "Checking for security issues" banner is now shown while the transaction scan is in progress, instead of a loading skeleton
+- Render the confirmation fee asset rows with the shared `Asset` component from `@metamask/snap-networks-utils` ([#429](https://github.com/MetaMask/internal-snaps/pull/429))
- `listAccountAssets` and `getAccountBalances` now fetch live assets and balances from the chain through the Snap's TronGrid clients instead of returning persisted state. ([#388](https://github.com/MetaMask/internal-snaps/pull/388))
### Fixed
diff --git a/packages/tron-wallet-snap/images/question-mark.svg b/packages/tron-wallet-snap/images/question-mark.svg
deleted file mode 100644
index 8d2165746..000000000
--- a/packages/tron-wallet-snap/images/question-mark.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/packages/tron-wallet-snap/jest.config.js b/packages/tron-wallet-snap/jest.config.js
index dfaaaeced..cebb2aa6e 100644
--- a/packages/tron-wallet-snap/jest.config.js
+++ b/packages/tron-wallet-snap/jest.config.js
@@ -5,10 +5,7 @@ module.exports = {
preset: '@metamask/snaps-jest',
transform: {
'^.+\\.(t|j)sx?$': 'ts-jest',
- },
- moduleNameMapper: {
- ...baseConfig.moduleNameMapper,
- '\\.svg$': 'jest-transform-stub',
+ '^.+\\.svg$': '/../../jest.svg-transformer.js',
},
testMatch: ['**/src/**/?(*.)+(spec|test).[tj]s?(x)'],
setupFilesAfterEnv: [
@@ -19,10 +16,10 @@ module.exports = {
// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
global: {
- branches: 71.17,
- functions: 80.95,
- lines: 85.91,
- statements: 85.9,
+ branches: 71.79,
+ functions: 81.56,
+ lines: 86.19,
+ statements: 86.18,
},
},
};
diff --git a/packages/tron-wallet-snap/package.json b/packages/tron-wallet-snap/package.json
index 032b031c1..938c02371 100644
--- a/packages/tron-wallet-snap/package.json
+++ b/packages/tron-wallet-snap/package.json
@@ -68,7 +68,6 @@
"ethers": "^6.15.0",
"jest": "30.0.3",
"jest-it-up": "^2.0.2",
- "jest-transform-stub": "2.0.0",
"lodash": "^4.17.21",
"oxfmt": "^0.45.0",
"tronweb": "patch:tronweb@npm%3A6.1.0#~/.yarn/patches/tronweb-npm-6.1.0-771b242b6a.patch",
diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json
index 7fb609f4a..69f25e24d 100644
--- a/packages/tron-wallet-snap/snap.manifest.json
+++ b/packages/tron-wallet-snap/snap.manifest.json
@@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/internal-snaps.git"
},
"source": {
- "shasum": "24Wu8vP5kufsOQxcQ8q8/FNuN/mDP/LFW7PxF98D3Uo=",
+ "shasum": "Ts+SpwPXHGuDCZNLn1PfTPwMX8ECWdp46bKrlYUr1vc=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
diff --git a/packages/tron-wallet-snap/src/ui/confirmation/components/Asset/Asset.tsx b/packages/tron-wallet-snap/src/ui/confirmation/components/Asset/Asset.tsx
deleted file mode 100644
index bbb84dc02..000000000
--- a/packages/tron-wallet-snap/src/ui/confirmation/components/Asset/Asset.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import type { CaipAssetType, ComponentOrElement } from '@metamask/snaps-sdk';
-import {
- Box,
- Icon,
- Image,
- Skeleton,
- Text as SnapText,
-} from '@metamask/snaps-sdk/jsx';
-
-import questionMarkSvg from '../../../../../images/question-mark.svg';
-import { KnownCaip19Id } from '../../../../constants';
-import type { Preferences } from '../../../../types/snap';
-import { formatFiat } from '../../../../utils/formatFiat';
-import { tokenToFiat } from '../../../../utils/tokenToFiat';
-
-type AssetProps = {
- caipId: CaipAssetType;
- symbol: string;
- amount: string;
- iconUrl?: string;
- showAmount?: boolean;
- price?: number | null;
- preferences?: Preferences;
- priceLoading?: boolean;
-};
-
-/**
- * Asset component for displaying assets with optional icon, amount, and price.
- * Pure component with no business logic - just visual display.
- *
- * @param props - The props for the asset component.
- * @returns The rendered asset element.
- */
-export const Asset = (props: AssetProps): ComponentOrElement => {
- const { caipId, symbol, amount, iconUrl, price, preferences, priceLoading } =
- props;
-
- const fiatValue =
- preferences && price
- ? formatFiat(
- tokenToFiat(amount, price),
- preferences.currency,
- preferences.locale,
- )
- : '';
-
- const showPriceInfo = preferences !== undefined;
- const showSkeleton = showPriceInfo && priceLoading;
- const showFiat = showPriceInfo && !priceLoading && fiatValue;
-
- const isBandwidth =
- caipId === KnownCaip19Id.BandwidthMainnet ||
- caipId === KnownCaip19Id.BandwidthNile ||
- caipId === KnownCaip19Id.BandwidthShasta;
-
- const isEnergy =
- caipId === KnownCaip19Id.EnergyMainnet ||
- caipId === KnownCaip19Id.EnergyNile ||
- caipId === KnownCaip19Id.EnergyShasta;
-
- const isNormalAsset = !isBandwidth && !isEnergy;
- const iconSrc = iconUrl ?? questionMarkSvg;
-
- return (
-
- {showSkeleton ? : null}
- {showFiat ? {fiatValue} : null}
-
- {isBandwidth ? : null}
- {isEnergy ? : null}
- {isNormalAsset ? (
-
- ) : null}
-
- {`${amount} ${symbol}`}
-
- );
-};
diff --git a/packages/tron-wallet-snap/src/ui/confirmation/components/Fees.test.tsx b/packages/tron-wallet-snap/src/ui/confirmation/components/Fees.test.tsx
new file mode 100644
index 000000000..255d207c0
--- /dev/null
+++ b/packages/tron-wallet-snap/src/ui/confirmation/components/Fees.test.tsx
@@ -0,0 +1,97 @@
+import { FeeType } from '@metamask/keyring-api';
+
+import { KnownCaip19Id } from '../../../constants';
+import type { ComputeFeeResult } from '../../../services/send/types';
+import { FetchStatus } from '../../../types/snap';
+import type { Preferences } from '../../../types/snap';
+import { formatFiat } from '../../../utils/formatFiat';
+import { tokenToFiat } from '../../../utils/tokenToFiat';
+import { Fees } from './Fees';
+
+const preferences = {
+ locale: 'en',
+ currency: 'usd',
+} as Preferences;
+
+const trxFee = {
+ type: FeeType.Base,
+ asset: {
+ unit: 'TRX',
+ type: KnownCaip19Id.TrxMainnet,
+ amount: '1.5',
+ fungible: true,
+ iconUrl: 'https://icon.example/trx.png',
+ },
+} as ComputeFeeResult[number];
+
+const resourceFee = (unit: string, type: string): ComputeFeeResult[number] =>
+ ({
+ type: FeeType.Base,
+ asset: { unit, type, amount: '100', fungible: true },
+ }) as ComputeFeeResult[number];
+
+const tokenPrices = {
+ [KnownCaip19Id.TrxMainnet]: { price: 0.2 },
+} as never;
+
+const fiat = formatFiat(tokenToFiat('1.5', 0.2), 'usd', 'en');
+
+describe('Fees', () => {
+ it('renders the fiat value before the TRX fee with its icon', () => {
+ const serialized = JSON.stringify(
+ Fees({ fees: [trxFee], preferences, tokenPrices }),
+ );
+
+ expect(serialized).toContain('"children":"1.5 TRX"');
+ expect(serialized).toContain('"src":"https://icon.example/trx.png"');
+ expect(serialized.indexOf(fiat)).toBeGreaterThan(-1);
+ expect(serialized.indexOf(fiat)).toBeLessThan(
+ serialized.indexOf('1.5 TRX'),
+ );
+ });
+
+ it('renders a skeleton instead of the fiat value while prices load', () => {
+ const serialized = JSON.stringify(
+ Fees({
+ fees: [trxFee],
+ preferences,
+ tokenPrices,
+ tokenPricesFetchStatus: FetchStatus.Fetching,
+ }),
+ );
+
+ expect(serialized).toContain('"type":"Skeleton"');
+ expect(serialized).not.toContain(fiat);
+ });
+
+ it('renders only the fee when there is no price', () => {
+ const serialized = JSON.stringify(Fees({ fees: [trxFee], preferences }));
+
+ expect(serialized).toContain('"children":"1.5 TRX"');
+ expect(serialized).not.toContain(fiat);
+ expect(serialized).not.toContain('"type":"Skeleton"');
+ });
+
+ it('renders resource fees with their icons after the TRX fee', () => {
+ const serialized = JSON.stringify(
+ Fees({
+ fees: [
+ resourceFee('ENERGY', KnownCaip19Id.EnergyMainnet),
+ resourceFee('BANDWIDTH', KnownCaip19Id.BandwidthNile),
+ trxFee,
+ ],
+ preferences,
+ }),
+ );
+
+ expect(serialized).toContain('"name":"flash"');
+ expect(serialized).toContain('"name":"connect"');
+ expect(serialized.indexOf('1.5 TRX')).toBeLessThan(
+ serialized.indexOf('100 ENERGY'),
+ );
+ expect(serialized.indexOf('100 ENERGY')).toBeLessThan(
+ serialized.indexOf('100 BANDWIDTH'),
+ );
+ expect(serialized.match(/"type":"Image"/gu)).toHaveLength(1);
+ });
+});
diff --git a/packages/tron-wallet-snap/src/ui/confirmation/components/Fees.tsx b/packages/tron-wallet-snap/src/ui/confirmation/components/Fees.tsx
index 027a116ab..fd917646b 100644
--- a/packages/tron-wallet-snap/src/ui/confirmation/components/Fees.tsx
+++ b/packages/tron-wallet-snap/src/ui/confirmation/components/Fees.tsx
@@ -1,13 +1,26 @@
+import { Asset } from '@metamask/snap-networks-utils';
import type { ComponentOrElement } from '@metamask/snaps-sdk';
import { Box, Text as SnapText } from '@metamask/snaps-sdk/jsx';
+import type { IconProps } from '@metamask/snaps-sdk/jsx';
import type { SpotPrices } from '../../../clients/price-api/types';
+import { KnownCaip19Id } from '../../../constants';
import type { ComputeFeeResult } from '../../../services/send/types';
import { FetchStatus } from '../../../types/snap';
import type { Preferences } from '../../../types/snap';
+import { formatFiat } from '../../../utils/formatFiat';
import { i18n } from '../../../utils/i18n';
import { isFetchStatusLoadingOrFetching } from '../../../utils/isFetchStatusLoadingOrFetching';
-import { Asset } from './Asset/Asset';
+import { tokenToFiat } from '../../../utils/tokenToFiat';
+
+const RESOURCE_ICONS: Partial> = {
+ [KnownCaip19Id.BandwidthMainnet]: 'connect',
+ [KnownCaip19Id.BandwidthNile]: 'connect',
+ [KnownCaip19Id.BandwidthShasta]: 'connect',
+ [KnownCaip19Id.EnergyMainnet]: 'flash',
+ [KnownCaip19Id.EnergyNile]: 'flash',
+ [KnownCaip19Id.EnergyShasta]: 'flash',
+};
type FeesProps = {
fees: ComputeFeeResult;
@@ -68,13 +81,20 @@ export const Fees = ({
{/* Right side - fee value with asset display including price */}
);
diff --git a/yarn.lock b/yarn.lock
index b56ebc580..fa50b1418 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3944,7 +3944,6 @@ __metadata:
ethers: "npm:^6.15.0"
jest: "npm:30.0.3"
jest-it-up: "npm:^2.0.2"
- jest-transform-stub: "npm:2.0.0"
lodash: "npm:^4.17.21"
oxfmt: "npm:^0.45.0"
tronweb: "patch:tronweb@npm%3A6.1.0#~/.yarn/patches/tronweb-npm-6.1.0-771b242b6a.patch"