diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index 4bed644e8d..979a313dff 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Include Mantle operator fee in the displayed L1 gas estimate when simulated `gasUsed` is unavailable, by falling back to the transaction's gas limit ([#8837](https://github.com/MetaMask/core/pull/8837)) - Adds a `protected getOperatorFeeGas` hook on `OracleLayer1GasFeeFlow` that subclasses can override to supply a fallback value. The default behaviour is unchanged (returns `transactionMeta.gasUsed`). - `MantleLayer1GasFeeFlow` overrides the hook with `gasUsed ?? txParams.gas ?? txParams.gasLimit`, so the operator-fee oracle is called with the gas limit when `gasUsed` is missing. Gas limit is an upper bound on actual gas used, so the operator fee is over-estimated rather than under-reported. +- Fix `ExtraTransactionsPublishHook` not passing `isInternal: true` when calling `addTransactionBatch`, causing the duplicate-batch-ID guard to incorrectly throw `DuplicateBundleId` (error 5720) for nested ERC-20 gas-fee-token transfers that share a `batchId` with their parent batch ([#8884](https://github.com/MetaMask/core/pull/8884)) ## [66.0.0] diff --git a/packages/transaction-controller/src/TransactionController.test.ts b/packages/transaction-controller/src/TransactionController.test.ts index 1c53dc6808..12d4f2b8a2 100644 --- a/packages/transaction-controller/src/TransactionController.test.ts +++ b/packages/transaction-controller/src/TransactionController.test.ts @@ -3739,6 +3739,36 @@ describe('TransactionController', () => { networkClientId: NETWORK_CLIENT_ID_MOCK, }); }); + + it('does not throw if duplicate and isInternal is true', async () => { + const { controller } = setupController({ + options: { + state: { + transactions: [ + { + batchId: BATCH_ID_MOCK, + } as unknown as TransactionMeta, + ], + }, + }, + updateToInitialState: true, + }); + + const txParams = { + from: ACCOUNT_MOCK, + to: ACCOUNT_MOCK, + }; + + const { result } = await controller.addTransaction(txParams, { + batchId: BATCH_ID_MOCK, + isInternal: true, + networkClientId: NETWORK_CLIENT_ID_MOCK, + origin: ORIGIN_MOCK, + requireApproval: false, + }); + + await result.catch(() => undefined); + }); }); }); diff --git a/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.test.ts b/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.test.ts index 86652d382e..e950de03df 100644 --- a/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.test.ts +++ b/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.test.ts @@ -121,6 +121,7 @@ describe('ExtraTransactionsPublishHook', () => { disable7702: true, disableHook: false, disableSequential: true, + isInternal: true, requireApproval: false, }); }); diff --git a/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.ts b/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.ts index 6aaf6c5e95..3c1e240634 100644 --- a/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.ts +++ b/packages/transaction-controller/src/hooks/ExtraTransactionsPublishHook.ts @@ -164,6 +164,7 @@ export class ExtraTransactionsPublishHook { await this.#addTransactionBatch({ from, + isInternal: true, networkClientId, requireApproval: false, transactions,