Skip to content

Commit 2336981

Browse files
feat: performance improvement from rework on send transaction machine flows (#1794)
- Closes #1622 - Closes FE-808 ## Summary - Centralized provider logic, avoid recreating provider instances for the same network url - Sped up account balance calculation by making requests in parallel - Sped up gas calculation by using fee data recently generated by Send Machine in the Send Machine -> Tx Request Machine flow (i.e. Send screen). - Sped up gas calculation in SendMachine and TxRequestMachine by using already present information on account/balance from accountMachine instead of re-fetching - Sped up gas calculation in SendMachine and TxRequestMachine by merging calculations of default tip and gas limit into a single parallelized promise. - Decrease unnecessarily long delay in tx and send machines while waiting for a possible new user input --------- Co-authored-by: LuizAsFight <felipebolsonigomes@gmail.com>
1 parent d483ca6 commit 2336981

File tree

14 files changed

+207
-248
lines changed

14 files changed

+207
-248
lines changed

.changeset/lemon-maps-rest.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@fuels/playwright-utils": minor
3+
"fuels-wallet": minor
4+
---
5+
6+
feat: performance improvement from rework on send transaction machine flows

packages/app/playwright/crx/crx.test.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,11 @@ test.describe('FuelWallet Extension', () => {
9090
extensionId,
9191
}) => {
9292
const popupPage = await context.newPage();
93-
await popupPage.goto(`chrome-extension://${extensionId}/popup.html`);
94-
const page = await context.waitForEvent('page', {
93+
const pagePromise = context.waitForEvent('page', {
9594
predicate: (page) => page.url().includes('sign-up'),
9695
});
96+
await popupPage.goto(`chrome-extension://${extensionId}/popup.html`);
97+
const page = await pagePromise;
9798
expect(page.url()).toContain('sign-up');
9899
});
99100

packages/app/playwright/e2e/SendTransaction.test.ts

+33-27
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ test.describe('SendTransaction', () => {
5959

6060
const btnLocator = getButtonByText(page, 'Review');
6161

62-
await expectButtonToBeEnabled(btnLocator);
63-
await page.waitForTimeout(5000);
6462
await expectButtonToBeEnabled(btnLocator);
6563
await btnLocator.click();
6664

@@ -95,8 +93,6 @@ test.describe('SendTransaction', () => {
9593
// make sure the button is enabled
9694
const btnLocator = getButtonByText(page, 'Review');
9795

98-
await expectButtonToBeEnabled(btnLocator);
99-
await page.waitForTimeout(5000);
10096
await expectButtonToBeEnabled(btnLocator);
10197
await btnLocator.click();
10298

@@ -140,8 +136,6 @@ test.describe('SendTransaction', () => {
140136

141137
const btnLocator = getButtonByText(page, 'Review');
142138

143-
await expectButtonToBeEnabled(btnLocator);
144-
await page.waitForTimeout(5000);
145139
await expectButtonToBeEnabled(btnLocator);
146140
await btnLocator.click();
147141

@@ -173,12 +167,9 @@ test.describe('SendTransaction', () => {
173167

174168
// Waiting button change to Review in order to ensure that fee amount is updated
175169
await page.waitForSelector('button:has-text("Review")');
176-
await page.waitForTimeout(1000);
177170

178171
const btnLocator = getButtonByText(page, 'Review');
179172

180-
await expectButtonToBeEnabled(btnLocator);
181-
await page.waitForTimeout(5000);
182173
await expectButtonToBeEnabled(btnLocator);
183174
await btnLocator.click();
184175

@@ -215,12 +206,9 @@ test.describe('SendTransaction', () => {
215206

216207
// Waiting button change to Review in order to change fee amount
217208
await page.waitForSelector('button:has-text("Review")');
218-
await page.waitForTimeout(1000);
219209

220210
const btnLocator = getButtonByText(page, 'Review');
221211

222-
await expectButtonToBeEnabled(btnLocator);
223-
await page.waitForTimeout(5000);
224212
await expectButtonToBeEnabled(btnLocator);
225213
await btnLocator.click();
226214

@@ -253,27 +241,38 @@ test.describe('SendTransaction', () => {
253241

254242
// Waiting button change to Review in order to ensure that fee amount is updated
255243
await page.waitForSelector('button:has-text("Review")');
256-
await page.waitForTimeout(1000);
257244

258245
// Selecting and extracting regular fee amount
246+
await expect
247+
.poll(
248+
async () => {
249+
return await getByAriaLabel(page, 'fee value:Regular').isVisible();
250+
},
251+
{ timeout: 10000 }
252+
)
253+
.toBeTruthy();
259254
const regularFeeComponent = getByAriaLabel(page, 'fee value:Regular');
260255
await regularFeeComponent.click();
261256

262257
// Waiting button change to Review in order to ensure that fee amount is updated
263258
await page.waitForSelector('button:has-text("Review")');
264-
await page.waitForTimeout(1000);
265259

266260
const btnLocatorBeforeApprv = getButtonByText(page, 'Review');
267261

268-
await expectButtonToBeEnabled(btnLocatorBeforeApprv);
269-
await page.waitForTimeout(5000);
270262
await expectButtonToBeEnabled(btnLocatorBeforeApprv);
271263
await btnLocatorBeforeApprv.click();
272264

273265
// Waiting button change to Approve in order to get updated fee amount
274266
await page.waitForSelector('button:has-text("Submit")');
275-
await page.waitForTimeout(1000);
276267

268+
await expect
269+
.poll(
270+
async () => {
271+
return await getButtonByText(page, 'Back').isVisible();
272+
},
273+
{ timeout: 10000 }
274+
)
275+
.toBeTruthy();
277276
// Going back to select other fee value
278277
await getButtonByText(page, 'Back').click();
279278

@@ -283,27 +282,37 @@ test.describe('SendTransaction', () => {
283282

284283
// Waiting button change to Review in order to change fee amount
285284
await page.waitForSelector('button:has-text("Review")');
286-
await page.waitForTimeout(1000);
287285

288286
const btnLocator = getButtonByText(page, 'Review');
289287

290-
await expectButtonToBeEnabled(btnLocator);
291-
await page.waitForTimeout(5000);
292288
await expectButtonToBeEnabled(btnLocator);
293289
await btnLocator.click();
294290

295291
// Waiting button change to Approve in order to get updated fee amount
296292
await page.waitForSelector('button:has-text("Submit")');
297-
await page.waitForTimeout(1000);
298293

299294
await hasText(page, '0.001 ETH');
300295

301-
await page.waitForTimeout(1000);
296+
await expect
297+
.poll(
298+
async () => {
299+
return await getButtonByText(page, 'Submit').isEnabled();
300+
},
301+
{ timeout: 10000 }
302+
)
303+
.toBeTruthy();
302304
await getButtonByText(page, 'Submit').click();
303305
await hasText(page, '0.001 ETH');
304306

305307
// Wait for transaction to be confirmed
306-
await hasText(page, 'success');
308+
await expect
309+
.poll(
310+
async () => {
311+
return await hasText(page, 'success');
312+
},
313+
{ timeout: 10000 }
314+
)
315+
.toBeTruthy();
307316
});
308317

309318
test('Send max amount transaction', async () => {
@@ -337,15 +346,12 @@ test.describe('SendTransaction', () => {
337346
// Fee values change
338347
await new Promise((resolve) => setTimeout(resolve, 3000));
339348

340-
const maxAmountAfterFee = await getInputByName(page, 'amount').inputValue();
341-
342349
// Submit transaction
343350

344351
const btnLocator = getButtonByText(page, 'Review');
345352

346353
await expectButtonToBeEnabled(btnLocator);
347-
await page.waitForTimeout(5000);
348-
await expectButtonToBeEnabled(btnLocator);
354+
const maxAmountAfterFee = await getInputByName(page, 'amount').inputValue();
349355
await btnLocator.click();
350356

351357
// Approve transaction

packages/app/src/systems/DApp/hooks/useTransactionRequest.tsx

+14-21
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,26 @@ const selectors = {
2626
proposedTxRequest(state: TransactionRequestState) {
2727
return state.context.response?.proposedTxRequest;
2828
},
29-
isLoadingAccounts(state: TransactionRequestState) {
30-
return state.matches('fetchingAccount');
31-
},
3229
errors(state: TransactionRequestState) {
3330
if (!state.context.errors) return {};
3431
const simulateTxErrors = state.context.errors?.simulateTxErrors;
3532
const hasSimulateTxErrors = Boolean(simulateTxErrors);
3633
const txApproveError = state.context.errors?.txApproveError;
3734
return { txApproveError, simulateTxErrors, hasSimulateTxErrors };
3835
},
39-
status(externalLoading?: boolean) {
40-
return useCallback(
41-
(state: TransactionRequestState) => {
42-
const isLoading = state.hasTag('loading');
43-
const isClosed = state.matches('done') || state.matches('failed');
44-
45-
if (state.matches('idle')) return TxRequestStatus.idle;
46-
if (externalLoading || isLoading) return TxRequestStatus.loading;
47-
if (state.matches('txFailed')) return TxRequestStatus.failed;
48-
if (state.matches('txSuccess')) return TxRequestStatus.success;
49-
if (state.matches('sendingTx')) return TxRequestStatus.sending;
50-
if (isClosed) return TxRequestStatus.inactive;
51-
return TxRequestStatus.waitingApproval;
52-
},
53-
[externalLoading]
54-
);
36+
status() {
37+
return useCallback((state: TransactionRequestState) => {
38+
const isLoading = state.hasTag('loading');
39+
const isClosed = state.matches('done') || state.matches('failed');
40+
41+
if (state.matches('idle')) return TxRequestStatus.idle;
42+
if (isLoading) return TxRequestStatus.loading;
43+
if (state.matches('txFailed')) return TxRequestStatus.failed;
44+
if (state.matches('txSuccess')) return TxRequestStatus.success;
45+
if (state.matches('sendingTx')) return TxRequestStatus.sending;
46+
if (isClosed) return TxRequestStatus.inactive;
47+
return TxRequestStatus.waitingApproval;
48+
}, []);
5549
},
5650
title(state: TransactionRequestState) {
5751
if (state.matches('txSuccess')) return 'Transaction sent';
@@ -95,12 +89,11 @@ export function useTransactionRequest(opts: UseTransactionRequestOpts = {}) {
9589
},
9690
});
9791

98-
const isLoadingAccounts = useSelector(service, selectors.isLoadingAccounts);
9992
const account = useSelector(service, selectors.account);
10093
const ctx = useSelector(service, selectors.context);
10194
const errors = useSelector(service, selectors.errors);
10295
const providerUrl = ctx.input.providerUrl;
103-
const txStatusSelector = selectors.status(isLoadingAccounts);
96+
const txStatusSelector = selectors.status();
10497
const txStatus = useSelector(service, txStatusSelector);
10598
const title = useSelector(service, selectors.title);
10699
const txSummarySimulated = useSelector(service, selectors.txSummarySimulated);

0 commit comments

Comments
 (0)