Skip to content

Commit ed09cd4

Browse files
feat: Integrate deeplink and dapp initated transfer confirmations (#14916)
<!-- 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 aims to integrate deeplink and dapp initated redesigned transfer confirmations. **Labels:** Note that transfer confirmations can only be activated by setting env variable. Since this indicates feature is not yet released - `no-changelog` `No QA Needed` is added to the PR. ## **Related issues** Fixes: MetaMask/MetaMask-planning#4771 ## **Manual testing steps** - Deeplink and dapp initiated transfer confirmations will show redesigned transfer confirmation. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** Deeplink native transfer https://github.com/user-attachments/assets/855dfe42-f69d-472e-8625-46460b8e5350 Deeplink ETH USDC transfer https://github.com/user-attachments/assets/49d28788-e36c-4d4f-bea9-a65bda5ddc7b Deeplink Linea USDC transfer https://github.com/user-attachments/assets/26408d45-6876-46e1-bdf5-ab52e995b336 DApp initiated transfers https://github.com/user-attachments/assets/fc79886a-2c4c-49f4-bb79-e54b64007812 ## **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. --------- Co-authored-by: Nico MASSART <[email protected]>
1 parent 7ee569e commit ed09cd4

38 files changed

+697
-66
lines changed

app/components/UI/SimulationDetails/SimulationDetails.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ export const SimulationDetails: React.FC<SimulationDetailsProps> = ({
140140
isTransactionsRedesign = false,
141141
}: SimulationDetailsProps) => {
142142
const { styles } = useStyles(styleSheet, { isTransactionsRedesign });
143-
const { chainId, id: transactionId, simulationData } = transaction;
144-
const balanceChangesResult = useBalanceChanges({ chainId, simulationData });
143+
const { chainId, id: transactionId, simulationData, networkClientId } = transaction;
144+
const balanceChangesResult = useBalanceChanges({ chainId, simulationData, networkClientId });
145145
const loading = !simulationData || balanceChangesResult.pending;
146146

147147
useSimulationMetrics({

app/components/UI/SimulationDetails/useBalanceChanges.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const mockFetchTokenContractExchangeRates =
4343
fetchTokenContractExchangeRates as jest.Mock;
4444

4545
const ETH_TO_FIAT_RATE = 3;
46-
46+
const NETWORK_CLIENT_ID_MOCK = 'mainnet';
4747
const ERC20_TOKEN_ADDRESS_1_MOCK: Hex = '0x0erc20_1';
4848
const ERC20_TOKEN_ADDRESS_2_MOCK: Hex = '0x0erc20_2';
4949
const ERC20_TOKEN_ADDRESS_3_MOCK: Hex = '0x0erc20_3';
@@ -103,6 +103,7 @@ describe('useBalanceChanges', () => {
103103
useBalanceChanges({
104104
chainId: CHAIN_ID_MOCK,
105105
simulationData: undefined,
106+
networkClientId: NETWORK_CLIENT_ID_MOCK,
106107
}),
107108
);
108109
expect(result.current).toEqual({ pending: true, value: [] });
@@ -127,6 +128,7 @@ describe('useBalanceChanges', () => {
127128
useBalanceChanges({
128129
chainId: CHAIN_ID_MOCK,
129130
simulationData,
131+
networkClientId: NETWORK_CLIENT_ID_MOCK,
130132
}),
131133
);
132134

@@ -154,6 +156,7 @@ describe('useBalanceChanges', () => {
154156
useBalanceChanges({
155157
chainId: CHAIN_ID_MOCK,
156158
simulationData,
159+
networkClientId: NETWORK_CLIENT_ID_MOCK,
157160
}),
158161
);
159162

@@ -174,6 +177,7 @@ describe('useBalanceChanges', () => {
174177
useBalanceChanges({
175178
chainId: CHAIN_ID_MOCK,
176179
simulationData,
180+
networkClientId: NETWORK_CLIENT_ID_MOCK,
177181
}),
178182
);
179183
};
@@ -327,6 +331,7 @@ describe('useBalanceChanges', () => {
327331
useBalanceChanges({
328332
chainId: CHAIN_ID_MOCK,
329333
simulationData,
334+
networkClientId: NETWORK_CLIENT_ID_MOCK,
330335
}),
331336
);
332337
};
@@ -394,6 +399,7 @@ describe('useBalanceChanges', () => {
394399
useBalanceChanges({
395400
chainId: CHAIN_ID_MOCK,
396401
simulationData,
402+
networkClientId: NETWORK_CLIENT_ID_MOCK,
397403
}),
398404
);
399405

app/components/UI/SimulationDetails/useBalanceChanges.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ function getAssetAmount(
6060
}
6161

6262
// Fetches the decimals for the given token address.
63-
async function fetchErc20Decimals(address: Hex): Promise<number> {
63+
async function fetchErc20Decimals(address: Hex, networkClientId: string): Promise<number> {
6464
try {
65-
const { decimals } = await getTokenDetails(address);
65+
const { decimals } = await getTokenDetails(address,undefined,undefined,networkClientId);
6666
return decimals ? parseInt(decimals, 10) : ERC20_DEFAULT_DECIMALS;
6767
} catch {
6868
return ERC20_DEFAULT_DECIMALS;
@@ -72,12 +72,13 @@ async function fetchErc20Decimals(address: Hex): Promise<number> {
7272
// Fetches token details for all the token addresses in the SimulationTokenBalanceChanges
7373
async function fetchAllErc20Decimals(
7474
addresses: Hex[],
75+
networkClientId: string,
7576
): Promise<Record<Hex, number>> {
7677
const uniqueAddresses = [
7778
...new Set(addresses.map((address) => address.toLowerCase() as Hex)),
7879
];
7980
const allDecimals = await Promise.all(
80-
uniqueAddresses.map(fetchErc20Decimals),
81+
uniqueAddresses.map((address) => fetchErc20Decimals(address, networkClientId)),
8182
);
8283
return Object.fromEntries(
8384
allDecimals.map((decimals, i) => [uniqueAddresses[i], decimals]),
@@ -183,9 +184,11 @@ function getTokenBalanceChanges(
183184
export default function useBalanceChanges({
184185
chainId,
185186
simulationData,
187+
networkClientId,
186188
}: {
187189
chainId: Hex;
188190
simulationData?: SimulationData;
191+
networkClientId: string;
189192
}): { pending: boolean; value: BalanceChange[] } {
190193
const nativeFiatRate = useSelector((state: RootState) => selectConversionRateByChainId(state, chainId)) as number;
191194
const fiatCurrency = useSelector(selectCurrentCurrency);
@@ -202,7 +205,7 @@ export default function useBalanceChanges({
202205
.map((tbc: any) => tbc.address);
203206

204207
const erc20Decimals = useAsyncResultOrThrow(
205-
() => fetchAllErc20Decimals(erc20TokenAddresses),
208+
() => fetchAllErc20Decimals(erc20TokenAddresses, networkClientId),
206209
[JSON.stringify(erc20TokenAddresses)],
207210
);
208211

app/components/Views/confirmations/components/confirm/confirm-component.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ jest.mock('../../../../../core/Engine', () => ({
8787
},
8888
},
8989
},
90+
TokenListController: {
91+
fetchTokenList: jest.fn(),
92+
},
9093
},
9194
controllerMessenger: {
9295
subscribe: jest.fn(),

app/components/Views/confirmations/components/confirm/confirm-root.test.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ jest.mock('@react-navigation/native', () => ({
1919
}),
2020
}));
2121

22+
jest.mock('../../../../../core/Engine', () => ({
23+
context: {
24+
TokenListController: {
25+
fetchTokenList: jest.fn(),
26+
},
27+
},
28+
}));
29+
2230
describe('Confirm', () => {
2331
beforeEach(() => {
2432
jest.clearAllMocks();

app/components/Views/confirmations/components/footer/footer.test.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ const mockTrackAlertMetrics = jest.fn();
5151
trackAlertMetrics: mockTrackAlertMetrics,
5252
});
5353

54+
jest.mock('../../../../../core/Engine', () => ({
55+
context: {
56+
TokenListController: {
57+
fetchTokenList: jest.fn(),
58+
},
59+
},
60+
}));
61+
5462
const ALERT_MESSAGE_MOCK = 'This is a test alert message.';
5563
const ALERT_DETAILS_MOCK = ['Detail 1', 'Detail 2'];
5664
const mockAlerts = [

app/components/Views/confirmations/components/info/transfer/transfer.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ jest.mock('../../../../../../core/Engine', () => ({
1616
startPolling: jest.fn(),
1717
stopPollingByPollingToken: jest.fn(),
1818
},
19+
TokenListController: {
20+
fetchTokenList: jest.fn(),
21+
},
1922
},
2023
}));
2124

app/components/Views/confirmations/components/rows/transactions/advanced-details-row/advanced-details-row.test.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ jest.mock('../../../../../../hooks/useEditNonce', () => ({
2525
useEditNonce: jest.fn(),
2626
}));
2727

28+
jest.mock('../../../../../../../core/Engine', () => ({
29+
context: {
30+
TokenListController: {
31+
fetchTokenList: jest.fn(),
32+
},
33+
},
34+
}));
35+
2836
describe('AdvancedDetailsRow', () => {
2937
const mockUseEditNonce = {
3038
setShowNonceModal: jest.fn(),

app/components/Views/confirmations/components/rows/transactions/from-to/from-to.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ jest.mock('../../../../../../../core/Engine', () => ({
1717
NetworkController: {
1818
getNetworkConfigurationByNetworkClientId: jest.fn(),
1919
},
20+
TokenListController: {
21+
fetchTokenList: jest.fn(),
22+
},
2023
},
2124
}));
2225

app/components/Views/confirmations/components/rows/transactions/gas-fee-details/gas-fee-details.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ jest.mock('../../../../../../../core/Engine', () => ({
1919
NetworkController: {
2020
getNetworkConfigurationByNetworkClientId: jest.fn(),
2121
},
22+
TokenListController: {
23+
fetchTokenList: jest.fn(),
24+
},
2225
},
2326
}));
2427

0 commit comments

Comments
 (0)