Skip to content

Commit c247eb6

Browse files
authored
feat: Move MM fee into a tooltip for Predict Withdraw (#26637)
## **Description** Moves MM fee into a tooltip for Predict Withdraw and use "Provider fee" instead of "Bridge Provider fee" in a tooltip. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: null ## **Manual testing steps** 1. Open Predict Withdraw 2. Select a token for withdraw 3. On the overview page click on the tooltip for Transaction fee ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes fee presentation and the `Transaction fee` total calculation to include the MetaMask fee, which could affect user-visible pricing and requires careful validation of totals across transaction types. > > **Overview** > Updates the confirmation `Transaction fee` row to **include the MetaMask fee in the displayed total** and removes the dedicated `metamask-fee-row` (and its loading skeleton) from the main list. > > Moves the MetaMask fee breakdown into the transaction-fee tooltip alongside network and provider fees, and renames the tooltip label from *Bridge provider fee* to **Provider fee** (adds new `confirm.label.provider_fee` locale string). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 25f47bb. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
1 parent 8e8d86f commit c247eb6

3 files changed

Lines changed: 59 additions & 75 deletions

File tree

app/components/Views/confirmations/components/rows/bridge-fee-row/bridge-fee-row.test.tsx

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ describe('BridgeFeeRow', () => {
8686
expect(getByTestId(ConfirmationRowComponentIDs.NETWORK_FEE)).toBeDefined();
8787
expect(getByText('$0.23')).toBeDefined();
8888
expect(queryByText('$1.23')).toBeNull();
89-
expect(queryByTestId('metamask-fee-row')).toBeDefined();
89+
expect(queryByTestId('metamask-fee-row')).toBeNull();
9090
expect(queryByTestId('bridge-fee-row')).toBeNull();
9191
});
9292

@@ -125,10 +125,10 @@ describe('BridgeFeeRow', () => {
125125
it('renders skeletons if quotes loading', async () => {
126126
useIsTransactionPayLoadingMock.mockReturnValue(true);
127127

128-
const { getByTestId } = render();
128+
const { getByTestId, queryByTestId } = render();
129129

130130
expect(getByTestId('bridge-fee-row-skeleton')).toBeDefined();
131-
expect(getByTestId('metamask-fee-row-skeleton')).toBeDefined();
131+
expect(queryByTestId('metamask-fee-row-skeleton')).toBeNull();
132132
});
133133

134134
it('does not render tooltip if no quotes', async () => {
@@ -137,42 +137,52 @@ describe('BridgeFeeRow', () => {
137137
expect(queryByTestId('info-row-tooltip-open-btn')).toBeNull();
138138
});
139139

140-
it('renders metamask fee from totals', () => {
140+
it('includes metamask fee in transaction fee total', () => {
141141
useTransactionTotalsMock.mockReturnValue({
142142
fees: {
143-
provider: { usd: '0.03' },
144-
sourceNetwork: { estimate: { usd: '0.01' } },
143+
provider: { usd: '0' },
144+
sourceNetwork: { estimate: { usd: '0' } },
145145
targetNetwork: { usd: '0' },
146-
metaMask: { usd: '0.00435', fiat: '0.00435' },
146+
metaMask: { usd: '0.50', fiat: '0.50' },
147147
},
148148
} as TransactionPayTotals);
149149

150150
const { getByText } = render();
151151

152-
expect(getByText('<$0.01')).toBeOnTheScreen();
152+
expect(getByText('$0.50')).toBeOnTheScreen();
153153
});
154154

155-
it('renders metamask fee as $0 when fee is zero', () => {
155+
it('transaction fee total is correct when metamask fee is zero', () => {
156156
useTransactionTotalsMock.mockReturnValue({
157157
fees: {
158-
provider: { usd: '0.03' },
159-
sourceNetwork: { estimate: { usd: '0.01' } },
160-
targetNetwork: { usd: '0' },
158+
provider: { usd: '1.00' },
159+
sourceNetwork: { estimate: { usd: '0.20' } },
160+
targetNetwork: { usd: '0.03' },
161161
metaMask: { usd: '0', fiat: '0' },
162162
},
163163
} as TransactionPayTotals);
164164

165165
const { getByText } = render();
166166

167-
expect(getByText('$0')).toBeOnTheScreen();
167+
expect(getByText('$1.23')).toBeOnTheScreen();
168168
});
169169

170-
it('does not render metamask fee if no quotes', async () => {
171-
useTransactionPayQuotesMock.mockReturnValue([]);
170+
it('renders metamask fee in tooltip', async () => {
171+
useTransactionTotalsMock.mockReturnValue({
172+
fees: {
173+
provider: { usd: '0.05' },
174+
sourceNetwork: { estimate: { usd: '0.01' } },
175+
targetNetwork: { usd: '0' },
176+
metaMask: { usd: '0.50', fiat: '0.50' },
177+
},
178+
} as TransactionPayTotals);
172179

173-
const { getByTestId, queryByTestId } = render();
180+
const { getByTestId, getByText } = render();
174181

175-
expect(getByTestId('bridge-fee-row')).toBeDefined();
176-
expect(queryByTestId('metamask-fee-row')).toBeNull();
182+
await act(async () => {
183+
fireEvent.press(getByTestId('info-row-tooltip-open-btn'));
184+
});
185+
186+
expect(getByText('$0.50')).toBeOnTheScreen();
177187
});
178188
});

app/components/Views/confirmations/components/rows/bridge-fee-row/bridge-fee-row.tsx

Lines changed: 29 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { ReactNode, useMemo } from 'react';
2-
import InfoRow from '../../UI/info-row';
32
import { useTransactionMetadataOrThrow } from '../../../hooks/transactions/useTransactionMetadataRequest';
43
import Text, {
54
TextColor,
@@ -44,28 +43,22 @@ export function BridgeFeeRow() {
4443

4544
if (hasTransactionType(transactionMetadata, NETWORK_FEE_ONLY_TYPES)) {
4645
return (
47-
<>
48-
<NetworkFeeRow
49-
totals={totals}
50-
hasAlert={hasAlert}
51-
isLoading={isLoading}
52-
/>
53-
<MetaMaskFeeRow quotes={quotes} totals={totals} isLoading={isLoading} />
54-
</>
55-
);
56-
}
57-
58-
return (
59-
<>
60-
<TransactionFeeRow
46+
<NetworkFeeRow
6147
totals={totals}
62-
quotes={quotes}
63-
transactionMeta={transactionMetadata}
6448
hasAlert={hasAlert}
6549
isLoading={isLoading}
6650
/>
67-
<MetaMaskFeeRow quotes={quotes} totals={totals} isLoading={isLoading} />
68-
</>
51+
);
52+
}
53+
54+
return (
55+
<TransactionFeeRow
56+
totals={totals}
57+
quotes={quotes}
58+
transactionMeta={transactionMetadata}
59+
hasAlert={hasAlert}
60+
isLoading={isLoading}
61+
/>
6962
);
7063
}
7164

@@ -88,7 +81,8 @@ function TransactionFeeRow({
8881
if (!totals?.fees) return '';
8982

9083
return formatFiat(
91-
new BigNumber(totals.fees.provider.usd)
84+
new BigNumber(totals.fees.metaMask.usd ?? 0)
85+
.plus(totals.fees.provider.usd)
9286
.plus(totals.fees.sourceNetwork.estimate.usd)
9387
.plus(totals.fees.targetNetwork.usd),
9488
);
@@ -174,41 +168,6 @@ function NetworkFeeRow({
174168
);
175169
}
176170

177-
function MetaMaskFeeRow({
178-
quotes,
179-
totals,
180-
isLoading,
181-
}: {
182-
quotes?: TransactionPayQuote<Json>[];
183-
totals?: TransactionPayTotals;
184-
isLoading: boolean;
185-
}) {
186-
const formatFiat = useFiatFormatter({ currency: 'usd' });
187-
188-
const hasQuotes = Boolean(quotes?.length);
189-
190-
const metamaskFeeUsd = useMemo(
191-
() => formatFiat(new BigNumber(totals?.fees.metaMask.usd ?? 0)),
192-
[totals, formatFiat],
193-
);
194-
195-
if (isLoading) return <InfoRowSkeleton testId="metamask-fee-row-skeleton" />;
196-
197-
if (!hasQuotes) return null;
198-
199-
return (
200-
<InfoRow
201-
testID="metamask-fee-row"
202-
label={strings('confirm.label.metamask_fee')}
203-
rowVariant={InfoRowVariant.Small}
204-
>
205-
<Text variant={TextVariant.BodyMD} color={TextColor.Alternative}>
206-
{metamaskFeeUsd}
207-
</Text>
208-
</InfoRow>
209-
);
210-
}
211-
212171
function Tooltip({
213172
transactionMeta,
214173
totals,
@@ -265,6 +224,11 @@ function FeesTooltip({
265224
[totals, formatFiat],
266225
);
267226

227+
const metaMaskFeeUsd = useMemo(
228+
() => formatFiat(new BigNumber(totals.fees.metaMask.usd ?? 0)),
229+
[totals, formatFiat],
230+
);
231+
268232
return (
269233
<Box gap={14}>
270234
<Text>{message}</Text>
@@ -282,10 +246,19 @@ function FeesTooltip({
282246
justifyContent={JustifyContent.spaceBetween}
283247
>
284248
<Text color={TextColor.Alternative}>
285-
{strings('confirm.label.bridge_fee')}
249+
{strings('confirm.label.provider_fee')}
286250
</Text>
287251
<Text color={TextColor.Alternative}>{providerFeeUsd}</Text>
288252
</Box>
253+
<Box
254+
flexDirection={FlexDirection.Row}
255+
justifyContent={JustifyContent.spaceBetween}
256+
>
257+
<Text color={TextColor.Alternative}>
258+
{strings('confirm.label.metamask_fee')}
259+
</Text>
260+
<Text color={TextColor.Alternative}>{metaMaskFeeUsd}</Text>
261+
</Box>
289262
</Box>
290263
);
291264
}

locales/languages/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6318,7 +6318,8 @@
63186318
"transaction_fees": "Transaction fees",
63196319
"metamask_fee": "MetaMask fee",
63206320
"network_fee": "Network fee",
6321-
"bridge_fee": "Bridge provider fee"
6321+
"bridge_fee": "Bridge provider fee",
6322+
"provider_fee": "Provider fee"
63226323
},
63236324
"title": {
63246325
"signature": "Signature request",

0 commit comments

Comments
 (0)