Skip to content

fix: set is_smart_transaction=true for cancelled/dropped smart transactions#26479

Merged
cloudonshore merged 4 commits into
mainfrom
fix/smart-transaction-metrics-property
Mar 30, 2026
Merged

fix: set is_smart_transaction=true for cancelled/dropped smart transactions#26479
cloudonshore merged 4 commits into
mainfrom
fix/smart-transaction-metrics-property

Conversation

@cloudonshore

@cloudonshore cloudonshore commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Description

Cancelled or dropped smart transactions never get mined, so getSmartTransactionByMinedTxHash() returns nothing and is_smart_transaction was never set. This caused "Smart transaction failed" errors to appear under is_smart_transaction=false in metrics.

Since getSmartTransactionMetricsProperties() is only called when smart transactions are enabled for the chain (gated by selectShouldUseSmartTransaction in stx.ts), we can safely return { is_smart_transaction: true } even when the mined hash lookup fails — the transaction still went through the smart transaction flow.

Context

In PR #21027, return {} was intentionally introduced for the !smartTransaction case to fix a bug where undefined smart transactions were being misclassified as is_smart_transaction: true (due to !smartTransaction?.statusMetadata evaluating to true for undefined).

That fix was correct for the general case, but it didn't account for cancelled/dropped smart transactions — these go through the STX flow but never produce a mined hash, so getSmartTransactionByMinedTxHash() returns nothing. Since this function is only reachable when STX is enabled for the chain, returning { is_smart_transaction: true } here is safe and gives us accurate metrics for failed STX.

Changelog

CHANGELOG entry: null

Related issues

N/A

Manual testing steps

This is a metrics-only change. is_smart_transaction is not used in any business logic, UI rendering, or transaction routing — it is purely an analytics property on the "Transaction Finalized" event.

Verification:

  1. Confirm unit tests pass for app/util/smart-transactions/index.test.ts
  2. Confirm that cancelled/dropped smart transactions now report is_smart_transaction: true in the "Transaction Finalized" event in Mixpanel

Screenshots/Recordings

N/A — no UI changes.

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Low Risk
Low risk metrics-only change: adjusts analytics properties when a smart transaction record can’t be found, with a unit test update to lock in the new behavior.

Overview
getSmartTransactionMetricsProperties now returns { is_smart_transaction: true } (instead of {}) when no smart transaction is found by mined hash, ensuring cancelled/dropped smart transactions are still classified as smart transactions in analytics.

Updates the corresponding unit test to expect is_smart_transaction: true in this no-record/no-wait scenario.

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

…ctions

Cancelled or dropped smart transactions never get mined, so
getSmartTransactionByMinedTxHash() returns nothing and
is_smart_transaction was never set. This caused "Smart transaction
failed" errors to appear under is_smart_transaction=false in metrics.

Since this function is only called when smart transactions are enabled
for the chain, return is_smart_transaction: true even when the mined
hash lookup fails.
@github-actions

github-actions Bot commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-swaps-and-bridge Swaps and Bridge team label Feb 24, 2026
Comment thread app/util/smart-transactions/index.ts
@cloudonshore

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@cursor cursor Bot left a comment

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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

// smart transactions are enabled for the chain. Cancelled/dropped smart
// transactions won't have a mined tx hash, so the lookup above returns
// nothing, but the transaction still went through the smart transaction flow.
return { is_smart_transaction: true };

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.

Non-smart txs may be misclassified

Medium Severity

getSmartTransactionMetricsProperties() now returns { is_smart_transaction: true } when getSmartTransactionByMinedTxHash() returns nothing. If this function is called for any finalized transaction while smart transactions are merely enabled/opted-in (but the specific transactionMeta did not actually go through the smart transaction flow, or controller state was lost), metrics will incorrectly label it as a smart transaction.

Fix in Cursor Fix in Web

@cloudonshore cloudonshore Feb 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Bugbot's concern doesn't hold up. Looking at stx.ts:26-31, getSmartTransactionMetricsProperties is only called when selectShouldUseSmartTransaction returns true for the transaction's chain.

The gate is chain-level, not per-transaction, but if STX is enabled for a chain, all transactions on that chain go through the smart transaction publish hook in transaction-controller-init.ts:247-259. There's no per-transaction opt-out.

The only exception would be relay deposit child transactions (created with requireApproval: false in the relay-submit strategy), but those get their own "Transaction Finalized" events with their own types.

So the scenario described -- a transaction on an STX-enabled chain that somehow skips the STX flow -- doesn't happen in practice.

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.

Renaming smartTransaction to may be successfulSmartTransaction so it is more clear.

@cloudonshore cloudonshore Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

but isn't success/failed handled by status and error fields? I feel like is_smart_transaction should indicate whether or not it was broadcasted to the STX system, not whether or not the STX system succeeded

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: None (no tests recommended)
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
The change is a small, isolated fix to the getSmartTransactionMetricsProperties function in app/util/smart-transactions/index.ts. Previously, when a smart transaction was not found (e.g., cancelled/dropped transactions that don't have a mined tx hash), the function returned an empty object {}. Now it returns { is_smart_transaction: true } to properly track that the transaction still went through the smart transaction flow.

This is purely a metrics/analytics tracking fix that:

  1. Only affects the return value of a metrics helper function
  2. Has comprehensive unit test coverage (the test file was also updated)
  3. Does not change any user-facing behavior or transaction execution flow
  4. Does not affect the actual smart transaction processing logic
  5. Is used only for analytics properties in transaction metrics

The change is well-contained and the unit tests adequately validate the fix. No E2E tests are needed as this doesn't affect any user-visible functionality or transaction flows.

Performance Test Selection:
This change only affects the return value of a metrics helper function, changing from an empty object to { is_smart_transaction: true }. It has no impact on UI rendering, data loading, state management, or any performance-critical paths. The change is purely for analytics tracking purposes and doesn't affect app performance in any way.

View GitHub Actions results

// smart transactions are enabled for the chain. Cancelled/dropped smart
// transactions won't have a mined tx hash, so the lookup above returns
// nothing, but the transaction still went through the smart transaction flow.
return { is_smart_transaction: true };

@matthewwalsh0 matthewwalsh0 Mar 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agreed, I'd go even further and align with extension which just sets it to true if the preference is enabled, the chain is supported, and the flags are enabled.

There is no additional checks based on the individual transaction itself and the resulting hash etc.

We have dedicated properties in extension for the other states such as smart_transaction_timed_out.

I'm also concerned why we're awaiting transaction events while just generating metrics, that could risk delaying or omitting portions of the metrics.

Ideally we'd have a single function that generates all the STX properties for a given transaction that encapsulates the preference and chain ID and feature flag checks, so we don't have to assume the caller has done any checks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes agreed I think that makes sense for a future refactor.

@cloudonshore cloudonshore added this pull request to the merge queue Mar 26, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Mar 26, 2026
@cloudonshore cloudonshore added this pull request to the merge queue Mar 30, 2026
Merged via the queue into main with commit 65ebbe1 Mar 30, 2026
64 of 66 checks passed
@cloudonshore cloudonshore deleted the fix/smart-transaction-metrics-property branch March 30, 2026 21:04
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 30, 2026
@metamaskbot metamaskbot added the release-7.73.0 Issue or pull request that will be included in release 7.73.0 label Mar 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.73.0 Issue or pull request that will be included in release 7.73.0 size-XS team-swaps-and-bridge Swaps and Bridge team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants