Skip to content

Commit 96c8582

Browse files
feat: skip transaction receipt check if intent complete (#6950)
## Explanation Do not wait for a transaction receipt if the intent of the transaction is marked as complete via the new `isIntentComplete` property on `TransactionMeta`. ## References ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs), highlighting breaking changes as necessary - [x] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces `isIntentComplete` on `TransactionMeta` and updates `PendingTransactionTracker` to mark such transactions confirmed without fetching a receipt, with corresponding tests and changelog entry. > > - **Types**: > - Add optional `isIntentComplete` to `TransactionMeta` in `src/types.ts`. > - **PendingTransactionTracker** (`src/helpers/PendingTransactionTracker.ts`): > - `#checkTransaction` confirms transaction immediately when `txMeta.isIntentComplete` is true. > - `#onTransactionConfirmed` now accepts an optional `receipt`; only fetches block data and sets `baseFeePerGas`, `blockTimestamp`, `txParams.gasUsed`, `txReceipt`, and `verifiedOnBlockchain` when a receipt is present. > - **Tests** (`src/helpers/PendingTransactionTracker.test.ts`): > - Add test to assert confirmation when `isIntentComplete` is true. > - **Changelog**: > - Document new `isIntentComplete` property and behavior in `CHANGELOG.md`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6741a3b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent a9f7269 commit 96c8582

File tree

4 files changed

+65
-14
lines changed

4 files changed

+65
-14
lines changed

packages/transaction-controller/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Add optional `isIntentComplete` property to `TransactionMeta` to indicate transaction outcome was achieved via an alternate chain or mechanism ([#6950](https://github.com/MetaMask/core/pull/6950))
13+
1014
## [61.0.0]
1115

1216
### Changed

packages/transaction-controller/src/helpers/PendingTransactionTracker.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,41 @@ describe('PendingTransactionTracker', () => {
605605
}),
606606
);
607607
});
608+
609+
it('if isIntentComplete is true', async () => {
610+
const transaction = {
611+
...TRANSACTION_SUBMITTED_MOCK,
612+
isIntentComplete: true,
613+
};
614+
615+
const getTransactions = jest
616+
.fn()
617+
.mockReturnValue(freeze([transaction], true));
618+
619+
pendingTransactionTracker = new PendingTransactionTracker({
620+
...options,
621+
getTransactions,
622+
});
623+
624+
const listener = jest.fn();
625+
pendingTransactionTracker.hub.addListener(
626+
'transaction-confirmed',
627+
listener,
628+
);
629+
630+
await onPoll();
631+
632+
expect(listener).toHaveBeenCalledTimes(1);
633+
expect(listener).toHaveBeenCalledWith(
634+
expect.objectContaining({
635+
...TRANSACTION_SUBMITTED_MOCK,
636+
txParams: expect.objectContaining(
637+
TRANSACTION_SUBMITTED_MOCK.txParams,
638+
),
639+
status: TransactionStatus.confirmed,
640+
}),
641+
);
642+
});
608643
});
609644

610645
describe('fires updated event', () => {

packages/transaction-controller/src/helpers/PendingTransactionTracker.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,12 @@ export class PendingTransactionTracker {
382382
}
383383

384384
async #checkTransaction(txMeta: TransactionMeta) {
385-
const { hash, id } = txMeta;
385+
const { hash, id, isIntentComplete } = txMeta;
386+
387+
if (isIntentComplete) {
388+
await this.#onTransactionConfirmed(txMeta);
389+
return;
390+
}
386391

387392
if (!hash && (await this.#beforeCheckPendingTransaction(txMeta))) {
388393
const error = new Error(
@@ -450,10 +455,10 @@ export class PendingTransactionTracker {
450455

451456
async #onTransactionConfirmed(
452457
txMeta: TransactionMeta,
453-
receipt: SuccessfulTransactionReceipt,
458+
receipt?: SuccessfulTransactionReceipt,
454459
) {
455460
const { id } = txMeta;
456-
const { blockHash } = receipt;
461+
const { blockHash } = receipt ?? {};
457462

458463
this.#log('Transaction confirmed', id);
459464

@@ -463,19 +468,23 @@ export class PendingTransactionTracker {
463468
return;
464469
}
465470

466-
const { baseFeePerGas, timestamp: blockTimestamp } =
467-
await this.#getBlockByHash(blockHash, false);
468-
469471
const updatedTxMeta = cloneDeep(txMeta);
470-
updatedTxMeta.baseFeePerGas = baseFeePerGas;
471-
updatedTxMeta.blockTimestamp = blockTimestamp;
472+
473+
if (receipt && blockHash) {
474+
const { baseFeePerGas, timestamp: blockTimestamp } =
475+
await this.#getBlockByHash(blockHash, false);
476+
477+
updatedTxMeta.baseFeePerGas = baseFeePerGas;
478+
updatedTxMeta.blockTimestamp = blockTimestamp;
479+
updatedTxMeta.txParams = {
480+
...updatedTxMeta.txParams,
481+
gasUsed: receipt.gasUsed,
482+
};
483+
updatedTxMeta.txReceipt = receipt;
484+
updatedTxMeta.verifiedOnBlockchain = true;
485+
}
486+
472487
updatedTxMeta.status = TransactionStatus.confirmed;
473-
updatedTxMeta.txParams = {
474-
...updatedTxMeta.txParams,
475-
gasUsed: receipt.gasUsed,
476-
};
477-
updatedTxMeta.txReceipt = receipt;
478-
updatedTxMeta.verifiedOnBlockchain = true;
479488

480489
this.#updateTransaction(
481490
updatedTxMeta,

packages/transaction-controller/src/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ export type TransactionMeta = {
268268
/** Whether MetaMask will be compensated for the gas fee by the transaction. */
269269
isGasFeeIncluded?: boolean;
270270

271+
/** Whether the intent of the transaction was achieved via an alternate route or chain. */
272+
isIntentComplete?: boolean;
273+
271274
/**
272275
* Whether the transaction is an incoming token transfer.
273276
*/

0 commit comments

Comments
 (0)