From d47cb4940f3d3c3e54cbaa30e365c582b36922a8 Mon Sep 17 00:00:00 2001 From: Florin Dzeladini Date: Mon, 19 Jan 2026 13:13:25 +0100 Subject: [PATCH 1/6] fix: not call get next nonce for 7702 path --- packages/transaction-controller/src/utils/nonce.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/transaction-controller/src/utils/nonce.ts b/packages/transaction-controller/src/utils/nonce.ts index 8c17ee5c12a..06e54406d74 100644 --- a/packages/transaction-controller/src/utils/nonce.ts +++ b/packages/transaction-controller/src/utils/nonce.ts @@ -23,6 +23,7 @@ export async function getNextNonce( const { customNonceValue, isExternalSign, + delegationAddress, txParams: { from, nonce: existingNonce }, } = txMeta; @@ -31,6 +32,13 @@ export async function getNextNonce( return [undefined, undefined]; } + // Skip nonce assignment for delegated transactions (EIP-7702) + // The delegation address manages its own nonce sequence externally + if (delegationAddress) { + log('Skipping nonce as transaction uses delegation address', delegationAddress); + return [undefined, undefined]; + } + const customNonce = customNonceValue ? toHex(customNonceValue) : undefined; if (customNonce) { From 3314e54f7962a9e7647ed6aea52aeee9f3b68c9e Mon Sep 17 00:00:00 2001 From: Florin Dzeladini Date: Mon, 19 Jan 2026 15:23:57 +0100 Subject: [PATCH 2/6] chore: add changelog --- packages/transaction-controller/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index 7ff51c30758..368682958cf 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Exclude transactions where `isTransfer` is defined when marking nonce duplicates as dropped ([#7637](https://github.com/MetaMask/core/pull/7637)) +- Skip nonce assignment for EIP-7702 delegated transactions to prevent marking transactions as dropped ([#7659](https://github.com/MetaMask/core/pull/7659)) + ## [62.9.1] From a56c32ca594aa935fc1c6160720406bc564ee34f Mon Sep 17 00:00:00 2001 From: Florin Dzeladini Date: Fri, 23 Jan 2026 09:27:41 +0100 Subject: [PATCH 3/6] fix: use externalSign when delegationAddress is set --- packages/transaction-controller/CHANGELOG.md | 2 +- .../transaction-controller/src/TransactionController.ts | 4 ++++ packages/transaction-controller/src/utils/nonce.ts | 8 -------- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index 368682958cf..ab9ffda870b 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Exclude transactions where `isTransfer` is defined when marking nonce duplicates as dropped ([#7637](https://github.com/MetaMask/core/pull/7637)) -- Skip nonce assignment for EIP-7702 delegated transactions to prevent marking transactions as dropped ([#7659](https://github.com/MetaMask/core/pull/7659)) +- Set `isExternalSign` for sponsored transactions to skip nonce assignment ([#7659](https://github.com/MetaMask/core/pull/7659)) ## [62.9.1] diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index 670a3fba393..3c804c83823 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -1463,6 +1463,10 @@ export class TransactionController extends BaseController< }, (tx) => { tx.delegationAddress = delegationAddress; + // EIP-7702 transactions are signed externally via delegation + if (delegationAddress) { + tx.isExternalSign = true; + } }, ); diff --git a/packages/transaction-controller/src/utils/nonce.ts b/packages/transaction-controller/src/utils/nonce.ts index 06e54406d74..8c17ee5c12a 100644 --- a/packages/transaction-controller/src/utils/nonce.ts +++ b/packages/transaction-controller/src/utils/nonce.ts @@ -23,7 +23,6 @@ export async function getNextNonce( const { customNonceValue, isExternalSign, - delegationAddress, txParams: { from, nonce: existingNonce }, } = txMeta; @@ -32,13 +31,6 @@ export async function getNextNonce( return [undefined, undefined]; } - // Skip nonce assignment for delegated transactions (EIP-7702) - // The delegation address manages its own nonce sequence externally - if (delegationAddress) { - log('Skipping nonce as transaction uses delegation address', delegationAddress); - return [undefined, undefined]; - } - const customNonce = customNonceValue ? toHex(customNonceValue) : undefined; if (customNonce) { From 0b8b218d89ea4f8c3a5b11f1a41ab1b3fa42155b Mon Sep 17 00:00:00 2001 From: Florin Dzeladini Date: Fri, 23 Jan 2026 09:57:14 +0100 Subject: [PATCH 4/6] chore: lint --- packages/transaction-controller/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index ab9ffda870b..b25fdc1399a 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -12,7 +12,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Exclude transactions where `isTransfer` is defined when marking nonce duplicates as dropped ([#7637](https://github.com/MetaMask/core/pull/7637)) - Set `isExternalSign` for sponsored transactions to skip nonce assignment ([#7659](https://github.com/MetaMask/core/pull/7659)) - ## [62.9.1] ### Changed From c1ba9c16c2bac7e984cfb1cf5f53868509d5b651 Mon Sep 17 00:00:00 2001 From: Florin Dzeladini Date: Fri, 23 Jan 2026 10:07:12 +0100 Subject: [PATCH 5/6] chore: changelog update --- packages/transaction-controller/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index d75bf5c5d4f..e8fd55c7a4d 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -20,6 +20,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use the `transactionHistoryLimit` feature flag in `RemoteFeatureFlagController` instead. - This option will be removed in a future version. +### Fixed + +- Set `isExternalSign` for sponsored transactions to skip nonce assignment ([#7659](https://github.com/MetaMask/core/pull/7659)) + ## [62.9.2] ### Changed @@ -31,7 +35,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Exclude transactions where `isTransfer` is defined when marking nonce duplicates as dropped ([#7637](https://github.com/MetaMask/core/pull/7637)) -- Set `isExternalSign` for sponsored transactions to skip nonce assignment ([#7659](https://github.com/MetaMask/core/pull/7659)) ## [62.9.1] From 1d3d23aded83ee621cb774311bd576147f3c6cb6 Mon Sep 17 00:00:00 2001 From: Florin Dzeladini Date: Fri, 23 Jan 2026 16:54:51 +0100 Subject: [PATCH 6/6] fix: comment --- .../transaction-controller/src/TransactionController.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index 5bc4f81d558..d2a4b4b1694 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -1351,6 +1351,8 @@ export class TransactionController extends BaseController< const existingTransactionMeta = this.#getTransactionWithActionId(actionId); // If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it. + // EIP-7702 batch transactions (with nestedTransactions) are signed externally via delegation + const isEIP7702Batch = Boolean(nestedTransactions?.length); let addedTransactionMeta: TransactionMeta = existingTransactionMeta ? cloneDeep(existingTransactionMeta) : { @@ -1363,6 +1365,7 @@ export class TransactionController extends BaseController< deviceConfirmedOn, disableGasBuffer, id: random(), + isExternalSign: isEIP7702Batch, isGasFeeTokenIgnoredIfBalance: Boolean(gasFeeToken), isGasFeeIncluded, isGasFeeSponsored, @@ -1457,6 +1460,8 @@ export class TransactionController extends BaseController< this.#addMetadata(addedTransactionMeta); + // Record delegationAddress for metrics, but do not use it to determine isExternalSign. + // Only EIP-7702 batch transactions (with nestedTransactions) should have isExternalSign = true. delegationAddressPromise .then((delegationAddress) => { this.#updateTransactionInternal( @@ -1467,10 +1472,6 @@ export class TransactionController extends BaseController< }, (tx) => { tx.delegationAddress = delegationAddress; - // EIP-7702 transactions are signed externally via delegation - if (delegationAddress) { - tx.isExternalSign = true; - } }, );