Skip to content

refactor: extract more bridge-status-controller calls to utils#8215

Open
micaelae wants to merge 13 commits intomainfrom
swaps4229-extract-controller-calls
Open

refactor: extract more bridge-status-controller calls to utils#8215
micaelae wants to merge 13 commits intomainfrom
swaps4229-extract-controller-calls

Conversation

@micaelae
Copy link
Member

@micaelae micaelae commented Mar 17, 2026

Explanation

Changes

  • Move more code out of bridge-status-controller.ts
  • Replace IntentApi.submitOrder with a pure function postSubmitOrder
  • Update tests to serve as a baseline for the submitTx + submitIntent refactor

References

Fixes https://consensyssoftware.atlassian.net/browse/SWAPS-4229

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Refactors transaction submission, gas fee estimation, and intent-order handling into shared utils, which can subtly change bridging/swapping flows and metrics/event tracking behavior. Test updates reduce risk, but the changes touch core transaction lifecycle and status polling paths.

Overview
Refactors BridgeStatusController by moving more TransactionController/metrics/polling logic into dedicated utils. Core submission paths now use new helpers like submitEvmTransaction, addTransactionBatch, addSyntheticTransaction, and shared getters/updaters for transaction meta.

Intent order submission is decoupled from IntentApiImpl into a pure postSubmitOrder function, and intent-status translation/polling now treats missing txHash as undefined (not an empty string), updating both controller behavior and snapshots.

Gas fee estimation utilities are reorganized so getTxGasEstimates pulls estimates via messenger calls and getGasFeeEstimates, with corresponding test refactors.

History handling is tightened and rekeying is extracted/expanded, including support for choosing history keys from actionId, txMeta.id, or intent synthetic IDs, plus new unit tests and updated controller/tests to rely on bridgeTxMeta.hash rather than a separate statusRequest payload.

Written by Cursor Bugbot for commit ad7a598. This will update automatically on new commits. Configure here.

@micaelae micaelae force-pushed the swaps4229-extract-controller-calls branch 7 times, most recently from 8eca356 to 682da9c Compare March 18, 2026 19:36
Base automatically changed from swaps3560-submitTx-handlers to main March 19, 2026 17:16
@micaelae micaelae force-pushed the swaps4229-extract-controller-calls branch 3 times, most recently from 4f33f5d to 8cade9a Compare March 19, 2026 21:32
@micaelae micaelae force-pushed the swaps4229-extract-controller-calls branch 3 times, most recently from 71783df to 72a6c00 Compare March 19, 2026 23:32
@micaelae micaelae changed the title Swaps4229 extract controller calls refactor: extract more bridge-status-controller calls to utils Mar 19, 2026
Comment on lines +2057 to +2058
jest.spyOn(Date, 'now').mockReturnValueOnce(1234567890);
jest.spyOn(Date, 'now').mockReturnValueOnce(1234567891);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Date.now mocks for more accurate actionId snapshot tests, and to make sure actionId usage is preserved after submitTx and submiIntent are unified

StatusResponse,
} from '../types';

describe('History Utils', () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved these tests from transaction.test.ts


describe('getIntentFromQuote', () => {
it('returns intent when present in quote response', () => {
const mockIntent = { protocol: 'cowswap', order: { some: 'data' } };
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from transaction.test.ts

clientId: BridgeClientId,
): Promise<IntentStatusResponse> {
const endpoint = `${this.#baseUrl}/submitOrder`;
try {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced this with a pure function postSubmitOrder to decouple it from the IntentApi classes. This is in preparation for submitTx+submitIntent unification

bridgeTxMeta: txMeta, // Only the id field is used by the BridgeStatusController
statusRequest: {
...getStatusRequestParams(quoteResponse),
srcTxHash: txMeta.hash,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The statusRequest's data is also present in quoteResponse and bridgeTxMeta so this is ok to remove

@micaelae micaelae marked this pull request as ready for review March 20, 2026 00:22
@micaelae micaelae requested review from a team as code owners March 20, 2026 00:22
@micaelae micaelae enabled auto-merge March 20, 2026 00:25
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

} as TransactionMeta;

const startTime = Date.now();
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing originalTransactionId in intent #addTxToHistory call

High Severity

In the intent submission flow, originalTransactionId is set on bridgeTxMetaForHistory as an object property, but bridgeTxMeta is now typed as Pick<TransactionMeta, 'id' | 'hash' | 'batchId'> which doesn't include it. The StartPollingForBridgeTxStatusArgs type has a separate originalTransactionId field, but it's never passed in the #addTxToHistory call. In getInitialHistoryItem, the destructured originalTransactionId from args will be undefined, falling back to bridgeTxMeta?.id (the orderUid) instead of syntheticMeta.id (the TC transaction ID). This breaks syncTransactionFromIntentStatus, which uses originalTransactionId to find and update the correct transaction in the TransactionController.

Additional Locations (1)
Fix in Cursor Fix in Web

state: {
txHistory: options?.mockTxHistory ?? {},
},
addTransactionBatchFn: jest.fn(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate addTransactionBatchFn property in constructor

Low Severity

The BridgeStatusController constructor object literal has addTransactionBatchFn: jest.fn() specified twice — once at the newly added line and again a few lines later. The second value silently overrides the first. This is likely an accidental addition during the refactor.

Fix in Cursor Fix in Web

{
status: bridgeStatus?.transactionStatus,
hash: txHash,
...txReceiptUpdate,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unconditional hash assignment overwrites existing transaction hash

Medium Severity

The old code conditionally set hash only when txHash was truthy via ...(txHash ? { hash: txHash } : {}), preserving any existing hash on the transaction. The new code unconditionally sets hash: txHash, which when txHash is undefined will overwrite an existing valid hash on the TransactionMeta with undefined through the updateTransaction spread ({ ...txMeta, ...txMetaUpdates }).

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant