Skip to content

Commit 0b8d638

Browse files
authored
fix: transaction page display and alerts for money account transactions (#29725)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Fix transaction page display and alerts for money account transactions ## **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: ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1342 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **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** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] 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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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** > Expands several transaction-type conditionals to include `moneyAccountDeposit`/`moneyAccountWithdraw`, including post-quote config for withdrawals, which could affect how pay/withdraw transactions are labeled and configured. Coverage is improved with new unit tests, but regressions are possible if type routing is incomplete or mislabeled. > > **Overview** > Improves confirmations/activity transaction details handling for *money account* transactions by treating `moneyAccountDeposit`/`moneyAccountWithdraw` as supported types across the hero amount, summary routing, account row, and fee/total rows (including using *provider fee* labeling and receive-type totals where appropriate). > > Updates pay-related behavior so money-account withdrawals are excluded from insufficient-balance alerts, included in signed/submitted pay-type checks (for deposits), and avoid setting `refundTo`/`isHyperliquidSource` in `useTransactionPayPostQuote`. > > Adds/extends unit tests to cover the new money-account deposit/withdraw cases and the updated fallbacks/labels. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 08b5327. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 4e82ec3 commit 0b8d638

20 files changed

Lines changed: 166 additions & 10 deletions

app/components/Views/confirmations/components/activity/transaction-details-account-row/transaction-details-account-row.test.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,18 @@ describe('TransactionDetailsAccountRow', () => {
6565
const { toJSON } = render();
6666
expect(toJSON()).toBeNull();
6767
});
68+
69+
it.each([
70+
TransactionType.moneyAccountWithdraw,
71+
TransactionType.perpsWithdraw,
72+
TransactionType.predictClaim,
73+
TransactionType.predictWithdraw,
74+
])('renders account row for %s', (type) => {
75+
useTransactionDetailsMock.mockReturnValue({
76+
transactionMeta: { ...TRANSACTION_META_MOCK, type },
77+
});
78+
79+
const { getByText } = render();
80+
expect(getByText(ACCOUNT_NAME_MOCK)).toBeDefined();
81+
});
6882
});

app/components/Views/confirmations/components/activity/transaction-details-account-row/transaction-details-account-row.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { TransactionType } from '@metamask/transaction-controller';
1111
import { hasTransactionType } from '../../../utils/transaction';
1212

1313
const TRANSACTION_TYPES = [
14+
TransactionType.moneyAccountWithdraw,
1415
TransactionType.perpsWithdraw,
1516
TransactionType.predictClaim,
1617
TransactionType.predictWithdraw,

app/components/Views/confirmations/components/activity/transaction-details-bridge-fee-row/transaction-details-bridge-fee-row.test.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,20 @@ describe('TransactionDetailsBridgeFeeRow', () => {
6868
expect(getByText('Provider fee')).toBeOnTheScreen();
6969
});
7070

71+
it('renders "Provider fee" label for money account withdrawals', () => {
72+
useTransactionDetailsMock.mockReturnValue({
73+
transactionMeta: {
74+
type: TransactionType.moneyAccountWithdraw,
75+
metamaskPay: {
76+
bridgeFeeFiat: BRIDGE_FEE_FIAT_MOCK,
77+
},
78+
} as unknown as TransactionMeta,
79+
});
80+
81+
const { getByText } = render();
82+
expect(getByText('Provider fee')).toBeOnTheScreen();
83+
});
84+
7185
it('renders nothing if no bridge fee fiat', () => {
7286
useTransactionDetailsMock.mockReturnValue({
7387
transactionMeta: {

app/components/Views/confirmations/components/activity/transaction-details-bridge-fee-row/transaction-details-bridge-fee-row.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ export function TransactionDetailsBridgeFeeRow() {
1616
const { bridgeFeeFiat } = metamaskPay || {};
1717

1818
const isWithdraw = hasTransactionType(transactionMeta, [
19-
TransactionType.predictWithdraw,
19+
TransactionType.moneyAccountWithdraw,
2020
TransactionType.perpsWithdraw,
21+
TransactionType.predictWithdraw,
2122
]);
2223

2324
const label = isWithdraw

app/components/Views/confirmations/components/activity/transaction-details-hero/transaction-details-hero.test.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,19 @@ describe('TransactionDetailsHero', () => {
218218
const { queryByTestId } = render();
219219
expect(queryByTestId('transaction-details-hero')).toBeNull();
220220
});
221+
222+
it.each([
223+
TransactionType.moneyAccountDeposit,
224+
TransactionType.moneyAccountWithdraw,
225+
])('renders hero amount for %s', (type) => {
226+
useTransactionDetailsMock.mockReturnValue({
227+
transactionMeta: {
228+
...TRANSACTION_META_MOCK,
229+
type,
230+
} as unknown as TransactionMeta,
231+
});
232+
233+
const { getByText } = render();
234+
expect(getByText('$123.46')).toBeDefined();
235+
});
221236
});

app/components/Views/confirmations/components/activity/transaction-details-hero/transaction-details-hero.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import { RootState } from '../../../../../../reducers';
3232
import useNetworkInfo from '../../../hooks/useNetworkInfo';
3333

3434
const SUPPORTED_TYPES = [
35+
TransactionType.moneyAccountDeposit,
36+
TransactionType.moneyAccountWithdraw,
3537
TransactionType.musdClaim,
3638
TransactionType.musdConversion,
3739
TransactionType.perpsDeposit,

app/components/Views/confirmations/components/activity/transaction-details-network-fee-row/transaction-details-network-fee-row.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,15 @@ describe('TransactionDetailsNetworkFeeRow', () => {
6565

6666
expect(toJSON()).toBeNull();
6767
});
68+
69+
it('renders calculated network fee for moneyAccountWithdraw fallback', () => {
70+
useTransactionDetailsMock.mockReturnValue({
71+
transactionMeta: {
72+
type: TransactionType.moneyAccountWithdraw,
73+
} as unknown as TransactionMeta,
74+
});
75+
76+
const { getByText } = render();
77+
expect(getByText(`$${CALCULATED_FEE_MOCK}`)).toBeDefined();
78+
});
6879
});

app/components/Views/confirmations/components/activity/transaction-details-network-fee-row/transaction-details-network-fee-row.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { TransactionDetailsSelectorIDs } from '../TransactionDetailsModal.testId
1111
import { usePayFiatFormatter } from '../../../hooks/pay/usePayFiatFormatter';
1212

1313
const FALLBACK_TYPES = [
14+
TransactionType.moneyAccountWithdraw,
1415
TransactionType.perpsWithdraw,
1516
TransactionType.predictClaim,
1617
TransactionType.predictWithdraw,

app/components/Views/confirmations/components/activity/transaction-details-summary/transaction-details-summary.test.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ describe('TransactionDetailsSummary', () => {
128128
expect(getByText('ReceiveSummaryLine')).toBeDefined();
129129
});
130130

131+
it('routes moneyAccountDeposit to ReceiveSummaryLine', () => {
132+
const { getByText } = render({
133+
transactions: [
134+
{
135+
id: transactionIdMock,
136+
chainId: '0x1',
137+
type: TransactionType.moneyAccountDeposit,
138+
},
139+
],
140+
});
141+
142+
expect(getByText('ReceiveSummaryLine')).toBeDefined();
143+
});
144+
131145
it('routes unsupported types to DefaultSummaryLine', () => {
132146
const { getByText } = render({
133147
transactions: [

app/components/Views/confirmations/components/activity/transaction-details-summary/transaction-details-summary.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ function SummaryLine({
114114

115115
if (
116116
hasTransactionType(transactionMeta, [
117+
TransactionType.moneyAccountDeposit,
117118
TransactionType.perpsDeposit,
118119
TransactionType.predictDeposit,
119120
TransactionType.musdConversion,

0 commit comments

Comments
 (0)