Skip to content

Commit 67febaf

Browse files
feat: track input_amount_preset on quick option press (#26442)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> This PR tracks `input_amount_preset` when the user clicks on a quick preset source input amount, e.g. 25%, 50%. ## **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** Resolves: https://consensyssoftware.atlassian.net/browse/SWAPS-3893 ## **Manual testing steps** ```gherkin Feature: Quick options metrics Scenario: user is on Swaps screen Given user is on Swaps screen When user clicks on quick options, e.g. 25%, 50% Then that event is tracked ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> <img width="1056" height="345" alt="Screenshot 2026-02-23 at 3 17 15 PM" src="https://github.com/user-attachments/assets/8754094d-3062-496d-b920-161017406b7e" /> https://github.com/user-attachments/assets/7b21d196-15d9-49e6-935c-e0742496879b ## **Pre-merge author checklist** - [x] 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). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] 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** > Adds new analytics emission on percentage/max quick-pick actions and bumps `@metamask/bridge-controller`, which could affect event schemas/behavior but does not change core swap/bridge execution logic. > > **Overview** > Adds analytics tracking for source-amount quick picks in `GaslessQuickPickOptions`: pressing `25%/50%/75%/90%` (or `Max`) now emits `UnifiedSwapBridgeEventName.InputChanged` with the corresponding `input_amount_preset` (via a new `PERCENTAGE_TO_PRESET` mapping). > > Removes the `useTopTokens` hook and its unit tests, and updates dependencies by replacing the patched `@metamask/bridge-controller` with `^67.3.0` (lockfile updated accordingly). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 734acac. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 7774958 commit 67febaf

7 files changed

Lines changed: 90 additions & 529 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { InputAmountPreset } from '@metamask/bridge-controller';
2+
3+
export const PERCENTAGE_TO_PRESET = {
4+
25: InputAmountPreset.PERCENT_25,
5+
50: InputAmountPreset.PERCENT_50,
6+
75: InputAmountPreset.PERCENT_75,
7+
90: InputAmountPreset.PERCENT_90,
8+
} as const;

app/components/UI/Bridge/components/GaslessQuickPickOptions/index.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ import { BridgeToken } from '../../types';
66
import { CHAIN_IDS } from '@metamask/transaction-controller';
77
import { BigNumber } from 'ethers';
88

9+
jest.mock('../../../../../core/Engine', () => ({
10+
__esModule: true,
11+
default: {
12+
context: {
13+
BridgeController: {
14+
trackUnifiedSwapBridgeEvent: jest.fn(),
15+
},
16+
},
17+
},
18+
}));
19+
920
// Mock useLatestBalance to control tokenBalance in tests
1021
jest.mock('../../hooks/useLatestBalance', () => ({
1122
useLatestBalance: jest.fn(),

app/components/UI/Bridge/components/GaslessQuickPickOptions/index.tsx

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import { KeypadChangeData, Keys } from '../../../../Base/Keypad';
66
import { useLatestBalance } from '../../hooks/useLatestBalance';
77
import { BridgeToken } from '../../types';
88
import { BigNumber } from 'bignumber.js';
9+
import Engine from '../../../../../core/Engine';
10+
import {
11+
InputAmountPreset,
12+
UnifiedSwapBridgeEventName,
13+
} from '@metamask/bridge-controller';
14+
import { PERCENTAGE_TO_PRESET } from './constants';
915

1016
interface GaslessQuickPickOptionsProps {
1117
token?: BridgeToken;
@@ -26,8 +32,19 @@ export const GaslessQuickPickOptions = ({
2632
chainId: token?.chainId,
2733
});
2834

35+
const trackInputAmountPreset = useCallback((preset: InputAmountPreset) => {
36+
Engine.context.BridgeController.trackUnifiedSwapBridgeEvent(
37+
UnifiedSwapBridgeEventName.InputChanged,
38+
{
39+
input: 'token_amount_source',
40+
input_value: '',
41+
input_amount_preset: preset,
42+
},
43+
);
44+
}, []);
45+
2946
const onQuickOptionPress = useCallback(
30-
(percentage: number) => () => {
47+
(percentage: keyof typeof PERCENTAGE_TO_PRESET) => () => {
3148
if (!tokenBalance?.displayBalance) return '0';
3249

3350
const balance = new BigNumber(tokenBalance.displayBalance);
@@ -40,8 +57,13 @@ export const GaslessQuickPickOptions = ({
4057
valueAsNumber: Number(amount),
4158
pressedKey: Keys.Initial,
4259
});
60+
61+
const preset = PERCENTAGE_TO_PRESET[percentage];
62+
if (preset) {
63+
trackInputAmountPreset(preset);
64+
}
4365
},
44-
[tokenBalance, onChange, token?.decimals],
66+
[tokenBalance, onChange, token?.decimals, trackInputAmountPreset],
4567
);
4668

4769
const standardQuickPickOptions = useMemo(
@@ -67,6 +89,11 @@ export const GaslessQuickPickOptions = ({
6789
[onQuickOptionPress],
6890
);
6991

92+
const handleMaxPress = useCallback(() => {
93+
onMaxPress();
94+
trackInputAmountPreset(InputAmountPreset.MAX);
95+
}, [onMaxPress, trackInputAmountPreset]);
96+
7097
const gasslessQuickPickOptions = useMemo(
7198
() =>
7299
[
@@ -84,10 +111,10 @@ export const GaslessQuickPickOptions = ({
84111
},
85112
{
86113
label: 'Max',
87-
onPress: onMaxPress,
114+
onPress: handleMaxPress,
88115
},
89116
] satisfies QuickPickButtonOption[],
90-
[onMaxPress, onQuickOptionPress],
117+
[handleMaxPress, onQuickOptionPress],
91118
);
92119

93120
const shouldRenderMaxOption = useShouldRenderMaxOption(

0 commit comments

Comments
 (0)