Skip to content

refactor: unify submitTx and submitIntent#8257

Draft
micaelae wants to merge 3 commits intomainfrom
swaps4229-submitTx-strategy-refactor
Draft

refactor: unify submitTx and submitIntent#8257
micaelae wants to merge 3 commits intomainfrom
swaps4229-submitTx-strategy-refactor

Conversation

@micaelae
Copy link
Member

@micaelae micaelae commented Mar 19, 2026

Explanation

Before

Currently, submitTx and submitIntent are separate entry points that have overlapping logic. This obscures how the flows differ and some behaviors are inconsistent, although needed by both.

  • submitTx inlines long branching for non-EVM, batch/STX/7702, and default EVM paths, with history, rekeying, polling, and analytics mixed into each branch
  • submitIntent is a second large path: intent-specific steps (approval, signing, API submit, synthetic tx) with its own history and polling/intent-manager logic
%%{init: {"themeVariables": {"noteBkgColor": "#ffffff", "noteTextColor": "#333333", "noteBorderColor": "#cccccc"}}}%%
sequenceDiagram
  participant Ext as Client
  participant BSC as BridgeStatusController

  Ext->>BSC: submitTx
  Note left of BSC: pick one flow based on quote + client <br/>flags. each branch has its own step<br/> sequence and error handling
  alt non-EVM chains
    Note right of BSC: submitApproval if Tron
    Note right of BSC: submitTrade
    Note right of BSC: setTradeMeta
    Note right of BSC: publishFailedEvent
  else gasless, STX or 7702
    Note right of BSC: submitBatch
    Note right of BSC: setTradeMeta
  else EVM
    Note right of BSC: submitApproval
    Note right of BSC: addHistoryItem
    Note right of BSC: submitTrade
    Note right of BSC: rekeyHistoryItem
    Note right of BSC: setTradeMeta
  else shared
    Note right of BSC: startPolling if Tron or bridge tx
    Note right of BSC: addHistoryItem if non-EVM or gasless
    Note right of BSC: publishCompletedEvent if non-EVM swap
  end

  Ext->>BSC: submitIntent
  Note right of BSC: submitApproval
  Note right of BSC: sign EIP-712 intent payload
  Note right of BSC: submit intent order via IntentManager
  Note right of BSC: add a synthetic tx using <br/> orderId from order submission
  Note right of BSC: addHistoryItem
Loading

After

This PR reorganizes tx submission into strategies (reduces quote-specific if conditions in the controller) and an action stream (strategies yield step results, and the controller uses those to update history, poll, and publish metrics). Each strategy yields results in their own order.

%%{init: {"flowchart": {"useMaxWidth": true, "padding": 16, "nodeSpacing": 32, "rankSpacing": 48}}}%%
flowchart TB
  subgraph top[" "]
    direction LR
    SI["submitIntent entrypoint<br/>proxies to submitTx"] --> ST["submitTx orchestrates tracing,<br/>metrics, error handling,<br/>and strategy execution"]
  end
  REG["executeSubmitFlow picks <br/> a strategy based on  <br/> quote and params"]

  subgraph s_non[" "]
    direction TB
    nn0["submitApproval"] -->  nn1["submitTrade"] --> nn2["setTradeMeta"] --> nn3["addHistoryItem"] --> nn4["startPolling"] --> nn5["publishCompletedEvent"]
  end

  subgraph s_batch[" "]
    direction TB
    bb0["submitBatch"] --> bb1["setTradeMeta"] --> bb2["addHistoryItem"]
  end

  subgraph s_intent[" "]
    direction TB
    iia["submitApproval"] --> iic["signIntentPayload"] -->  ii0["postIntentOrder"] --> iib["submitSyntheticTrade"] --> ii1["setTradeMeta"] --> ii2["addHistoryItem"] --> ii3["startPolling"]
  end

  subgraph s_evm[" "]
    direction TB
    eea["submitResetApproval"]--> eeb["submitApproval"]--> eec["addHistoryItem"] -->  ee1["submitTrade"] -->  ee2["rekeyHistoryItem"] --> ee3["setTradeMeta"]
  end

  ST --> REG
  REG --> lblNon["non-evm-strategy"]
  lblNon --> nn0
  REG --> lblBatch["batch-strategy"]
  lblBatch --> bb0
  REG --> lblIntent["intent-strategy"]
  lblIntent --> iia
  REG --> lblEvm["evm-strategy default"]
  lblEvm --> eea

  classDef stratLabel fill:#ffffff,stroke:#57606a,color:#1f2328
  class lblNon,lblBatch,lblIntent,lblEvm stratLabel
Loading

Each strategy is an async generator that yields step results for the BridgeStatusController to apply

%%{init: {"themeVariables": {"noteBkgColor": "#ffffff", "noteTextColor": "#333333", "noteBorderColor": "#cccccc"}}}%%
sequenceDiagram
  participant BSC as submitTx
  participant IDX as executeSubmitFlow
  participant STR as strategy

  BSC->>IDX: starts executing submit strategy
  IDX->>STR: selects and executes strategy (async generator)

  Note over STR,IDX: Each strategy yields a subset of these steps in different orders

  STR-->>BSC: setTradeMeta
  Note right of BSC: set the tradeMeta to be returned to the client

  STR-->>BSC: addHistoryItem
  Note right of BSC: include metadata in action payload and update state

  STR-->>BSC: rekeyHistoryItem
  Note right of BSC: update state historyItem with trade metadata

  STR-->>BSC: startPolling
  Note right of BSC: starts polling by the provided key (actionId, orderId, tradeMetaId)

  STR-->>BSC: publishCompletedEvent
  Note right of BSC: call trackUnifiedSwapBridgeEvent with txHistory key

  STR-->>IDX: generator is done
  IDX-->>BSC: return

  Note right of BSC: return tradeMeta

Loading

Example dev workflows

Add a step to some flows

  1. Extend the SubmitStepResult with a new variant describing the step
  2. Add any new controller calls to utils (avoid bridge-status-controller.ts)
  3. Handle the new type in submitTx's generator processing loop
  4. For each strategy generator that needs the step, yield the new SubmitStepResult when it should run (order matters)

Add a step that applies to all flows

  1. Add any new controller calls to utils (avoid bridge-status-controller.ts)
  2. Implement the step in submitTx, outside of the generator processing loop

Add logic that does not need BridgeStatusController state updates or events

These can stay within the relevant strategy as plain async code. No new SubmitStepResult type is needed if it doesn't touch bridge history, polling, or metrics publishing

References

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

@micaelae micaelae changed the title Swaps4229 submit tx strategy refactor refactor: submitTx Mar 19, 2026
@micaelae micaelae changed the title refactor: submitTx refactor: unify submitTx and submitIntent Mar 20, 2026
@micaelae micaelae force-pushed the swaps4229-submitTx-strategy-refactor branch from 7da4e79 to f9fcc48 Compare March 23, 2026 18:02
github-merge-queue bot pushed a commit that referenced this pull request Mar 24, 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](#8257)

<!--
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

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

<!--
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

- [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
- [ ] 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]
> **Medium Risk**
> Medium risk because it refactors transaction submission, history
keying, and intent-order submission/polling paths; behavior changes
around `txHash`/action IDs and batching could affect bridge/swap
tracking if edge cases are missed.
> 
> **Overview**
> Refactors `bridge-status-controller` by moving more
transaction-handling logic into `utils/transaction` (e.g.,
`submitEvmTransaction`, `addTransactionBatch`, tx lookup/update helpers,
delegated-account check) and shifting gas-fee estimation helpers out of
`utils/gas`.
> 
> Intent order submission is changed from `IntentApiImpl.submitIntent`
to a pure `postSubmitOrder` function, and intent polling/translation now
treats missing hashes as `undefined` (not empty string) while updating
transactions via shared transaction helpers.
> 
> History handling is tightened: `StartPollingForBridgeTxStatusArgs` no
longer requires a `statusRequest`, history keys can fall back to
`originalTransactionId`, and new `utils/history` tests cover rekeying
and key selection; snapshots/tests are updated accordingly (including
added coverage for `handleNonEvmTx` response shapes and updated metrics
tracking expectations).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3ab2f3b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Base automatically changed from swaps4229-extract-controller-calls to main March 24, 2026 14:23
@micaelae micaelae force-pushed the swaps4229-submitTx-strategy-refactor branch 2 times, most recently from 9da49db to 3afcc23 Compare March 24, 2026 17:48
@micaelae micaelae changed the base branch from main to swaps4273-failed-event March 24, 2026 17:49
@micaelae micaelae force-pushed the swaps4229-submitTx-strategy-refactor branch 2 times, most recently from c3dee22 to 016db52 Compare March 24, 2026 18:16
Base automatically changed from swaps4273-failed-event to main March 24, 2026 18:22
@micaelae micaelae force-pushed the swaps4229-submitTx-strategy-refactor branch from 016db52 to 7152655 Compare March 24, 2026 18:33
rename

rename

wip

fix: merge conflict
@micaelae micaelae force-pushed the swaps4229-submitTx-strategy-refactor branch from 38c104d to 479a9ac Compare March 24, 2026 21:21
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