Skip to content

Commit 7ac581c

Browse files
sahar-fehridarkwingseaonabergeron
authored
fix: account tracker controller with useMultiPolling (#28277)
## **Description** Adds Multi chain polling for the token account tracker controller. We will have a separate PR to add the following e2e: 1- polling doesn't start with the wallet locked 2- once we unlock the wallet, polling starts with the wallet networks: we should check that the mocked requests for polling are happening 3- once we add a new account, polling is updated: we should check new requests including the new address happen [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/28277?quickstart=1) ## **Related issues** Fixes: Related: #28402 ## **Manual testing steps** This should not result in any new visual changes/new errors 1. Go to this page... 2. 3. ## **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 Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.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-extension/blob/develop/.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: David Walsh <[email protected]> Co-authored-by: seaona <[email protected]> Co-authored-by: Brian Bergeron <[email protected]>
1 parent 39528b0 commit 7ac581c

File tree

10 files changed

+281
-63
lines changed

10 files changed

+281
-63
lines changed

app/scripts/metamask-controller.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -2629,13 +2629,11 @@ export default class MetamaskController extends EventEmitter {
26292629
}
26302630

26312631
triggerNetworkrequests() {
2632-
this.accountTrackerController.start();
26332632
this.txController.startIncomingTransactionPolling();
26342633
this.tokenDetectionController.enable();
26352634
}
26362635

26372636
stopNetworkRequests() {
2638-
this.accountTrackerController.stop();
26392637
this.txController.stopIncomingTransactionPolling();
26402638
this.tokenDetectionController.disable();
26412639
}
@@ -3274,6 +3272,7 @@ export default class MetamaskController extends EventEmitter {
32743272
approvalController,
32753273
phishingController,
32763274
tokenRatesController,
3275+
accountTrackerController,
32773276
// Notification Controllers
32783277
authenticationController,
32793278
userStorageController,
@@ -4060,6 +4059,14 @@ export default class MetamaskController extends EventEmitter {
40604059
tokenRatesController.stopPollingByPollingToken.bind(
40614060
tokenRatesController,
40624061
),
4062+
accountTrackerStartPolling:
4063+
accountTrackerController.startPollingByNetworkClientId.bind(
4064+
accountTrackerController,
4065+
),
4066+
accountTrackerStopPollingByPollingToken:
4067+
accountTrackerController.stopPollingByPollingToken.bind(
4068+
accountTrackerController,
4069+
),
40634070

40644071
tokenDetectionStartPolling: tokenDetectionController.startPolling.bind(
40654072
tokenDetectionController,
@@ -6718,6 +6725,7 @@ export default class MetamaskController extends EventEmitter {
67186725
this.tokenListController.stopAllPolling();
67196726
this.tokenBalancesController.stopAllPolling();
67206727
this.appStateController.clearPollingTokens();
6728+
this.accountTrackerController.stopAllPolling();
67216729
} catch (error) {
67226730
console.error(error);
67236731
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { MockttpServer } from 'mockttp';
2+
3+
const CONTRACT_ADDRESS = {
4+
BalanceCheckerEthereumMainnet: '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39',
5+
BalanceCheckerLineaMainnet: '0xf62e6a41561b3650a69bb03199c735e3e3328c0d',
6+
};
7+
8+
const infuraUrl: string =
9+
'https://mainnet.infura.io/v3/00000000000000000000000000000000';
10+
const infuraLineaMainnetUrl: string =
11+
'https://linea-mainnet.infura.io/v3/00000000000000000000000000000000';
12+
const infuraLineaSepoliaUrl: string =
13+
'https://linea-sepolia.infura.io/v3/00000000000000000000000000000000';
14+
const infuraSepoliaUrl: string =
15+
'https://sepolia.infura.io/v3/00000000000000000000000000000000';
16+
17+
/**
18+
* Mocks multi network balance polling requests.
19+
*
20+
* @param mockServer - The mock server instance to set up the mocks on.
21+
* @returns A promise that resolves when all mocks have been set up.
22+
*/
23+
export async function mockMultiNetworkBalancePolling(
24+
mockServer: MockttpServer,
25+
): Promise<void> {
26+
await mockServer
27+
.forPost(infuraUrl)
28+
.withJsonBodyIncluding({ method: 'eth_getBalance' })
29+
.thenCallback(() => ({
30+
statusCode: 200,
31+
json: {
32+
jsonrpc: '2.0',
33+
id: '1111111111111111',
34+
result: '0x1158E460913D00000',
35+
},
36+
}));
37+
38+
await mockServer
39+
.forPost(infuraSepoliaUrl)
40+
.withJsonBodyIncluding({ method: 'eth_getBalance' })
41+
.thenCallback(() => ({
42+
statusCode: 200,
43+
json: {
44+
jsonrpc: '2.0',
45+
id: '6183194981233610',
46+
result: '0x1158E460913D00000',
47+
},
48+
}));
49+
50+
await mockServer
51+
.forPost(infuraLineaMainnetUrl)
52+
.withJsonBodyIncluding({ method: 'eth_getBalance' })
53+
.thenCallback(() => ({
54+
statusCode: 200,
55+
json: {
56+
jsonrpc: '2.0',
57+
id: '6183194981233610',
58+
result: '0x1158E460913D00000',
59+
},
60+
}));
61+
62+
await mockServer
63+
.forPost(infuraLineaSepoliaUrl)
64+
.withJsonBodyIncluding({ method: 'eth_getBalance' })
65+
.thenCallback(() => ({
66+
statusCode: 200,
67+
json: {
68+
jsonrpc: '2.0',
69+
id: '6183194981233610',
70+
result: '0x1158E460913D00000',
71+
},
72+
}));
73+
74+
await mockServer
75+
.forPost(infuraUrl)
76+
.withJsonBodyIncluding({ method: 'net_version' })
77+
.thenCallback(() => ({
78+
statusCode: 200,
79+
json: {
80+
jsonrpc: '2.0',
81+
id: '6183194981233610',
82+
result: '0x1',
83+
},
84+
}));
85+
86+
await mockServer
87+
.forPost(infuraLineaMainnetUrl)
88+
.withJsonBodyIncluding({ method: 'eth_call' })
89+
.thenCallback(() => ({
90+
statusCode: 200,
91+
json: {
92+
jsonrpc: '2.0',
93+
id: '1111111111111111',
94+
result:
95+
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000001158E460913D000000000000000000000000000000000000000000000000000000001699651aa88200000000000000000000000000000000000000000000000000001beca58919dc0000000000000000000000000000000000000000000000000000974189179054f0000000000000000000000000000000000000000000000000001d9ae54845818000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110d9316ec0000000000000000000000000000000000000000000000000000000000000000000',
96+
},
97+
}));
98+
99+
await mockServer
100+
.forPost(infuraUrl)
101+
.withJsonBodyIncluding({
102+
method: 'eth_call',
103+
params: [
104+
{
105+
to: CONTRACT_ADDRESS.BalanceCheckerEthereumMainnet,
106+
},
107+
],
108+
})
109+
.thenCallback(() => ({
110+
statusCode: 200,
111+
json: {
112+
jsonrpc: '2.0',
113+
id: '6183194981233610',
114+
result:
115+
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000001158E460913D000000000000000000000000000000000000000000000000000000001699651aa88200000000000000000000000000000000000000000000000000001beca58919dc0000000000000000000000000000000000000000000000000000974189179054f0000000000000000000000000000000000000000000000000001d9ae54845818000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110d9316ec0000000000000000000000000000000000000000000000000000000000000000000',
116+
},
117+
}));
118+
119+
await mockServer
120+
.forGet(
121+
'https://accounts.api.cx.metamask.io/v2/accounts/0x5cfe73b6021e818b776b421b1c4db2474086a7e1/balances',
122+
)
123+
.withQuery({
124+
networks: 1,
125+
})
126+
.thenCallback(() => ({
127+
statusCode: 200,
128+
json: {
129+
count: 0,
130+
balances: [
131+
{
132+
object: 'token',
133+
address: '0x0000000000000000000000000000000000000000',
134+
symbol: 'ETH',
135+
name: 'Ether',
136+
type: 'native',
137+
timestamp: '2015-07-30T03:26:13.000Z',
138+
decimals: 18,
139+
chainId: 1,
140+
balance: '20',
141+
},
142+
],
143+
unprocessedNetworks: [],
144+
},
145+
}));
146+
}

test/e2e/mock-e2e.js

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const blacklistedHosts = [
4343
'goerli.infura.io',
4444
'mainnet.infura.io',
4545
'sepolia.infura.io',
46+
'linea-mainnet.infura.io',
47+
'linea-sepolia.infura.io',
4648
];
4749
const {
4850
mockEmptyStalelistAndHotlist,

test/e2e/tests/ppom/ppom-blockaid-alert-simple-send.spec.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ const {
88
logInWithBalanceValidation,
99
WINDOW_TITLES,
1010
} = require('../../helpers');
11+
const {
12+
mockMultiNetworkBalancePolling,
13+
} = require('../../mock-balance-polling/mock-balance-polling');
1114
const { SECURITY_ALERTS_PROD_API_BASE_URL } = require('./constants');
1215
const { mockServerJsonRpc } = require('./mocks/mock-server-json-rpc');
1316

@@ -32,13 +35,13 @@ const SEND_REQUEST_BASE_MOCK = {
3235
};
3336

3437
async function mockInfura(mockServer) {
38+
await mockMultiNetworkBalancePolling(mockServer);
3539
await mockServerJsonRpc(mockServer, [
3640
['eth_blockNumber'],
3741
['eth_call'],
3842
['eth_estimateGas'],
3943
['eth_feeHistory'],
4044
['eth_gasPrice'],
41-
['eth_getBalance'],
4245
['eth_getBlockByNumber'],
4346
['eth_getCode'],
4447
['eth_getTransactionCount'],

test/e2e/tests/smart-transactions/mock-requests-for-swap-test.ts

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { MockttpServer } from 'mockttp';
22
import { mockEthDaiTrade } from '../swaps/shared';
3+
import { mockMultiNetworkBalancePolling } from '../../mock-balance-polling/mock-balance-polling';
4+
import { mockServerJsonRpc } from '../ppom/mocks/mock-server-json-rpc';
35

46
const STX_UUID = '0d506aaa-5e38-4cab-ad09-2039cb7a0f33';
57

@@ -288,18 +290,14 @@ const GET_TRANSACTION_BY_HASH_RESPONSE = {
288290
};
289291

290292
export const mockSwapRequests = async (mockServer: MockttpServer) => {
291-
await mockEthDaiTrade(mockServer);
293+
await mockMultiNetworkBalancePolling(mockServer);
292294

293-
await mockServer
294-
.forJsonRpcRequest({
295-
method: 'eth_getBalance',
296-
params: ['0x5cfe73b6021e818b776b421b1c4db2474086a7e1'],
297-
})
298-
.thenJson(200, {
299-
id: 3806592044086814,
300-
jsonrpc: '2.0',
301-
result: '0x1bc16d674ec80000', // 2 ETH
302-
});
295+
await mockServerJsonRpc(mockServer, [
296+
['eth_blockNumber'],
297+
['eth_getBlockByNumber'],
298+
['eth_chainId', { result: `0x1` }],
299+
]);
300+
await mockEthDaiTrade(mockServer);
303301

304302
await mockServer
305303
.forPost('https://transaction.api.cx.metamask.io/networks/1/getFees')

test/e2e/tests/smart-transactions/smart-transactions.spec.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
import FixtureBuilder from '../../fixture-builder';
88
import { unlockWallet, withFixtures } from '../../helpers';
99
import { Driver } from '../../webdriver/driver';
10-
import { CHAIN_IDS } from '../../../../shared/constants/network';
1110
import { mockSwapRequests } from './mock-requests-for-swap-test';
1211

1312
export async function withFixturesForSmartTransactions(
@@ -20,10 +19,9 @@ export async function withFixturesForSmartTransactions(
2019
},
2120
test: (args: { driver: Driver }) => Promise<void>,
2221
) {
23-
const inputChainId = CHAIN_IDS.MAINNET;
2422
await withFixtures(
2523
{
26-
fixtures: new FixtureBuilder({ inputChainId })
24+
fixtures: new FixtureBuilder()
2725
.withPermissionControllerConnectedToTestDapp()
2826
.withPreferencesControllerSmartTransactionsOptedIn()
2927
.withNetworkControllerOnMainnet()

0 commit comments

Comments
 (0)