Skip to content

feat: add support for batch sell in quote status manager - #9514

Merged
GeorgeGkas merged 7 commits into
mainfrom
swaps-4705
Jul 15, 2026
Merged

feat: add support for batch sell in quote status manager#9514
GeorgeGkas merged 7 commits into
mainfrom
swaps-4705

Conversation

@GeorgeGkas

@GeorgeGkas GeorgeGkas commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Explanation

What is the current state of things and why does it need to change?

The QuoteStatusManager reports each quote's on-chain status (SUBMITTEDFinalizedSuccess/FinalizedFailed) to the backend keyed by a single source transaction hash and txMetaId. This worked for the existing single-transaction submission paths, but batch sell flows (EIP-7702 delegated accounts and nested/atomic batch transactions, handled by submitBatchSellHandler in strategy/batch-sell-strategy.ts) can submit multiple quotes under a single batch transaction. Previously there was no way to correlate all of the quotes in a batch to the one transaction hash that actually executes them, so their status reporting and finalization couldn't be tracked correctly as a group.

What is the solution your changes offer and how does it work?

reportSubmitted/reportFinalised on QuoteStatusManager (quote-status-manager/quotes-status-manager.ts) now correlate entries by shared txMetaId rather than assuming a 1:1 quote-to-transaction relationship:

  • When a batch sell is submitted, submitBatchSellHandler determines whether the batch produced a single transaction (atomic 7702/nested batch) or multiple independent transactions (e.g. STX/sendBundle), since that determines how the quotes should be tracked (isSingleBatchTx check against unique txMeta.id values).
  • For a single-tx batch, every quote sharing that batch is reported as SUBMITTED under the same source transaction hash and txMetaId, and a parent history item plus per-quote nested history items are recorded.
  • QuoteStatusEntryStore.getAllByTxMetaId allows reportFinalised to look up all entries sharing a txMetaId and transition/finalize them together once that shared transaction confirms or fails, instead of only handling a single entry.
  • For multi-tx batches, each quote keeps its own transaction hash/history item, preserving existing single-quote behavior.

Are there any changes whose purpose might not be obvious to those unfamiliar with the domain?

  • The distinction between "atomic 7702/nested batch" (one tx) vs. "STX/sendBundle batch" (many txs) is why submitBatchSellHandler counts unique txMeta.ids rather than trusting is7702Tx alone, a delegated (7702) account can still produce multiple transactions via STX, so is7702Tx being true doesn't guarantee a single shared hash.
  • reportSubmitted intentionally no-ops (drops) a submission if the quote has already moved past Submitted for that quote id, this guards against late/duplicate SUBMITTED calls racing with finalization in the batch scenario, since the backend would reject a SUBMITTED call for an entry already in a terminal state.

References

https://consensyssoftware.atlassian.net/browse/SWAPS-4705


Note

Medium Risk
Changes backend quote-status lifecycle for batch sells and multi-entry finalization by txMetaId; behavior is heavily tested but incorrect grouping could mis-report quote states.

Overview
Extends quote-status reporting so batch sell flows (atomic EIP-7702 / nested batch with one on-chain transaction) can send SUBMITTED and finalization for every quote under the same source tx hash and txMetaId.

#reportSubmittedOnce now resolves quotes from a batch parent’s quoteIds (child history keys → real quote ids) and calls reportSubmitted for each, with the existing reportedSubmittedTxHash guard still applying once per parent. Startup backfill treats parents with quoteIds as eligible even when the parent has no single quoteId.

QuoteStatusEntryStore.getAllByTxMetaId and QuoteStatusManager.reportFinalised finalize all store entries that share a txMetaId, skipping entries already in a terminal state so duplicate finalization stays safe.

submitBatchSellHandler only builds the parent + nested history shape when the batch produced one distinct txMeta.id (isSingleBatchTx); multi-tx batches (e.g. STX/sendBundle) keep per-quote tracking. BridgeHistoryItem docs clarify quoteIds vs quoteId.

Tests cover batch submit/confirm/fail, startup seeding, rekey edge cases, and store/manager batch finalization.

Reviewed by Cursor Bugbot for commit b4cd9f4. Bugbot is set up for automated code reviews on this repo. Configure here.

@GeorgeGkas
GeorgeGkas requested review from a team as code owners July 15, 2026 07:12
@GeorgeGkas GeorgeGkas changed the title Swaps 4705 feat: add support for batch sell in quote status manager Jul 15, 2026
Comment on lines +498 to +500
// For a 7702/nested batch the parent item lists every quote in `quoteIds`
// (keys into `txHistory`); resolve each to its real quote id. Otherwise fall
// back to the item's own single quote id.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we get a comment on the types that explain more about quoteId? I think quoteIds is sufficiently explained but quoteId is a little sparse.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I.e. here packages/bridge-status-controller/src/types.ts

@GeorgeGkas
GeorgeGkas added this pull request to the merge queue Jul 15, 2026
Merged via the queue into main with commit afb989c Jul 15, 2026
426 checks passed
@GeorgeGkas
GeorgeGkas deleted the swaps-4705 branch July 15, 2026 18:09
@cursor cursor Bot mentioned this pull request Jul 15, 2026
4 tasks
pull Bot pushed a commit to Reality2byte/core that referenced this pull request Jul 15, 2026
## Explanation

Update `bridge-status-controller` package from `74.2.0` to `74.3.0`.

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?

For example:

* Fixes #12345
* Related to #67890
-->

## 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](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Version and changelog-only release with no code diff; consumers should
note 74.3.0’s batch quote-status behavior when upgrading.
> 
> **Overview**
> **Monorepo release `1126.0.0`** bumps the root
`@metamask/core-monorepo` version from `1125.0.0` and publishes
**`@metamask/bridge-status-controller` `74.3.0`** (from `74.2.0`) with
an updated package version and changelog.
> 
> The new **`74.3.0`** changelog section documents behavior that ships
with this release tag: **batch sell (EIP-7702 / nested batch)** support
in the quote-status flow so every quote in one batch is reported to the
backend as `SUBMITTED` under a shared source tx hash and `txMetaId`,
with shared finalization on confirm/fail ([MetaMask#9514]). A **Changed** entry
notes tsconfig project-reference sync with internal deps ([MetaMask#8384]).
Compare links for `[Unreleased]` and `[74.3.0]` are updated accordingly.
> 
> There are **no application source changes** in this diff—only
`package.json` version fields and `CHANGELOG.md` release bookkeeping.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
24b0fa0. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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.

2 participants