diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index a7a5fb27ac0..46e2fc579e2 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 + +- Ensure provided `batchId` is used in `addTransactionBatch` when going through the publish batch hook route ([#7705](https://github.com/MetaMask/core/pull/7705)) + ## [62.9.2] ### Changed diff --git a/packages/transaction-controller/src/utils/batch.test.ts b/packages/transaction-controller/src/utils/batch.test.ts index 358297c8e95..e6f2c39ec65 100644 --- a/packages/transaction-controller/src/utils/batch.test.ts +++ b/packages/transaction-controller/src/utils/batch.test.ts @@ -1112,6 +1112,79 @@ describe('Batch Utils', () => { doesChainSupportEIP7702Mock.mockReturnValueOnce(false); }); + it('returns provided batch ID', async () => { + const publishBatchHook: jest.MockedFn = jest.fn(); + + addTransactionMock + .mockResolvedValueOnce({ + transactionMeta: { + ...TRANSACTION_META_MOCK, + id: TRANSACTION_ID_MOCK, + }, + result: Promise.resolve(''), + }) + .mockResolvedValueOnce({ + transactionMeta: { + ...TRANSACTION_META_MOCK, + id: TRANSACTION_ID_2_MOCK, + }, + result: Promise.resolve(''), + }); + + publishBatchHook.mockResolvedValue({ + results: [ + { + transactionHash: TRANSACTION_HASH_MOCK, + }, + { + transactionHash: TRANSACTION_HASH_2_MOCK, + }, + ], + }); + + const resultPromise = addTransactionBatch({ + ...request, + publishBatchHook, + request: { + ...request.request, + batchId: BATCH_ID_CUSTOM_MOCK, + disable7702: true, + }, + }); + + await flushPromises(); + + const publishHooks = addTransactionMock.mock.calls.map( + ([, options]) => options.publishHook, + ); + + publishHooks[0]?.( + TRANSACTION_META_MOCK, + TRANSACTION_SIGNATURE_MOCK, + ).catch(() => { + // Intentionally empty + }); + + publishHooks[1]?.( + TRANSACTION_META_MOCK, + TRANSACTION_SIGNATURE_2_MOCK, + ).catch(() => { + // Intentionally empty + }); + + await flushPromises(); + + const result = await resultPromise; + + expect(result.batchId).toBe(BATCH_ID_CUSTOM_MOCK); + expect(addTransactionMock.mock.calls[0][1].batchId).toBe( + BATCH_ID_CUSTOM_MOCK, + ); + expect(addTransactionMock.mock.calls[1][1].batchId).toBe( + BATCH_ID_CUSTOM_MOCK, + ); + }); + it('adds each nested transaction', async () => { const publishBatchHook = jest.fn(); diff --git a/packages/transaction-controller/src/utils/batch.ts b/packages/transaction-controller/src/utils/batch.ts index 6b4ec92f272..8171bcda8e6 100644 --- a/packages/transaction-controller/src/utils/batch.ts +++ b/packages/transaction-controller/src/utils/batch.ts @@ -467,6 +467,7 @@ async function addTransactionBatchWithHook( } = request; const { + batchId: batchIdOverride, from, networkClientId, origin, @@ -514,7 +515,7 @@ async function addTransactionBatchWithHook( } let txBatchMeta: TransactionBatchMeta | undefined; - const batchId = generateBatchId(); + const batchId = batchIdOverride ?? generateBatchId(); const nestedTransactions = requestedTransactions.map((tx) => ({ ...tx,