feat: using websockets events for transaction polling#7822
feat: using websockets events for transaction polling#7822
Conversation
70ae62d to
41a0567
Compare
e9cf4eb to
45493b2
Compare
| this.#chainId = chainId; | ||
| this.#messenger = messenger; | ||
|
|
||
| const featureFlags = messenger.call('RemoteFeatureFlagController:getState') |
There was a problem hiding this comment.
We create small util wrappers for all the feature flags to encapsulate their layout in feature-flags.ts, so could we make a isPollingWebSocketsEnabled?
| const featureFlags = messenger.call('RemoteFeatureFlagController:getState') | ||
| .remoteFeatureFlags as TransactionControllerFeatureFlags; | ||
|
|
||
| this.#useWebsockets = |
There was a problem hiding this comment.
Is there any risk here that would warrant a feature flag? Since even if it fires, we still check the receipt?
There was a problem hiding this comment.
Not really, I agree feature flag here is not required. I added it to be double safe. But yep let me remove this.
There was a problem hiding this comment.
PR is updated to remove the flag
| return; | ||
| } | ||
|
|
||
| if (transaction.status !== 'confirmed') { |
There was a problem hiding this comment.
Do we also want to continue if failed so we can check the receipt and update the status to failed?
There was a problem hiding this comment.
Good point, let me add that.
There was a problem hiding this comment.
PR is updated to check for both dropped and failed statuses also.
| return; | ||
| } | ||
|
|
||
| this.#interval(false, undefined, true).catch(() => { |
There was a problem hiding this comment.
Is the block number on the transaction object so we can skip the block request?
There was a problem hiding this comment.
Unfortunately no, the only data we get is:
export type Transaction = {
/** Transaction ID/hash */
id: string;
/** Chain identifier in CAIP-2 format (e.g., "eip155:1") */
chain: string;
/** Transaction status */
status: string;
/** Timestamp when the transaction was processed */
timestamp: number;
/** Address that initiated the transaction */
from: string;
/** Address that received the transaction */
to: string;
};
| async #interval( | ||
| isAccelerated: boolean, | ||
| latestBlockNumber?: string, | ||
| transactionUpdateReceived: boolean = false, |
There was a problem hiding this comment.
Rather than adding a second boolean argument, could we define a local enum such as PollingTrigger and replace isAccelerated with trigger?
| return; | ||
| } | ||
|
|
||
| if (transaction.status !== 'confirmed') { |
There was a problem hiding this comment.
Should we also check the from of the transaction to confirm it's an outgoing transaction?
There was a problem hiding this comment.
I reverted this change as it is failing for some transactions.
| return; | ||
| } | ||
|
|
||
| this.#interval(false, undefined, true).catch(() => { |
There was a problem hiding this comment.
We're technically triggering the polling of all pending transactions for the chain, rather than the specific one from the event.
But I think it will be incredibly rare that a user has two simultaneously submitted meaning it's not worth the code complexity to only query specific transactions.
…/MetaMask/core into transaction_polling_improvements
…ion_polling_improvements
Explanation
Using event AccountActivityService:transactionUpdated to improve transaction polling.
References
Fixes https://github.com/MetaMask/MetaMask-planning/issues/6948
Checklist
Note
Medium Risk
Changes core transaction polling behavior by adding an event-driven trigger path, which could affect polling frequency and missed/extra updates if event filtering or subscriptions are incorrect. Scope is contained to the poller/helper layer with thorough unit coverage.
Overview
Adds event-driven polling:
TransactionPollernow subscribes toAccountActivityService:transactionUpdatedonstart()and unsubscribes onstop(), triggering an immediate poll when a confirmed transaction arrives for the selected account on the same chain.Refactors chain-id conversion: Introduces shared
caip2ToHexinutils.ts(with tests) and replaces the inline CAIP-2 conversion logic inIncomingTransactionHelperto use the shared helper.Updates
CHANGELOG.mdto document the new event-driven polling behavior.Written by Cursor Bugbot for commit 7db2f62. This will update automatically on new commits. Configure here.