diff --git a/src/SmartTransactionsController.test.ts b/src/SmartTransactionsController.test.ts index 53025fa0..53c5ffcc 100644 --- a/src/SmartTransactionsController.test.ts +++ b/src/SmartTransactionsController.test.ts @@ -1578,6 +1578,76 @@ describe('SmartTransactionsController', () => { ); }); + it('iterates over transactions from all networks when updating statuses', async () => { + // Setup: Create controller with pending transactions on two different networks + const mainnetPendingTx = { + uuid: 'mainnet-tx', + status: SmartTransactionStatuses.PENDING, + chainId: ChainId.mainnet, + networkClientId: NetworkType.mainnet, + }; + + const sepoliaPendingTx = { + uuid: 'sepolia-tx', + status: SmartTransactionStatuses.PENDING, + chainId: ChainId.sepolia, + networkClientId: NetworkType.sepolia, + }; + + await withController( + { + options: { + supportedChainIds: [ChainId.mainnet, ChainId.sepolia], + state: { + smartTransactionsState: { + ...getDefaultSmartTransactionsControllerState() + .smartTransactionsState, + smartTransactions: { + [ChainId.mainnet]: [mainnetPendingTx] as SmartTransaction[], + [ChainId.sepolia]: [sepoliaPendingTx] as SmartTransaction[], + }, + }, + }, + }, + }, + async ({ controller }) => { + // Mock the API responses for both networks + nock(API_BASE_URL) + .get(`/networks/1/batchStatus?uuids=mainnet-tx`) + .reply(200, { 'mainnet-tx': {} }); + + nock(API_BASE_URL) + .get(`/networks/11155111/batchStatus?uuids=sepolia-tx`) + .reply(200, { 'sepolia-tx': {} }); + + const fetchStatusSpy = jest.spyOn( + controller, + 'fetchSmartTransactionsStatus', + ); + + // Call updateSmartTransactions + await controller.updateSmartTransactions(); + + // Verify both calls were made with correct parameters + expect(fetchStatusSpy).toHaveBeenCalledTimes(2); + expect(fetchStatusSpy).toHaveBeenNthCalledWith(1, [ + expect.objectContaining({ + uuid: 'mainnet-tx', + chainId: ChainId.mainnet, + networkClientId: NetworkType.mainnet, + }), + ]); + expect(fetchStatusSpy).toHaveBeenNthCalledWith(2, [ + expect.objectContaining({ + uuid: 'sepolia-tx', + chainId: ChainId.sepolia, + networkClientId: NetworkType.sepolia, + }), + ]); + }, + ); + }); + it('does not call updateTransaction when smart transaction is cancelled but returnTxHashAsap is false', async () => { const mockUpdateTransaction = jest.fn(); await withController( diff --git a/src/SmartTransactionsController.ts b/src/SmartTransactionsController.ts index 3615978e..ef19f480 100644 --- a/src/SmartTransactionsController.ts +++ b/src/SmartTransactionsController.ts @@ -622,23 +622,24 @@ export default class SmartTransactionsController extends StaticIntervalPollingCo if (chainIds && !chainIds.includes(chainId as Hex)) { continue; } - // Filter pending transactions and map them to the desired shape + + // Filter pending transactions for this chainId const pendingTransactions = transactions .filter(isSmartTransactionPending) .map((pendingSmartTransaction) => { - // Use the transaction's chainId (from the key) to derive a networkClientId + // Use the transaction's chainId to derive a networkClientId const networkClientIdToUse = this.#getNetworkClientId({ chainId: chainId as Hex, }); return { uuid: pendingSmartTransaction.uuid, networkClientId: networkClientIdToUse, - chainId: pendingSmartTransaction.chainId as Hex, // same as the key, but explicit on the transaction + chainId: chainId as Hex, }; }); if (pendingTransactions.length > 0) { - // Since each group is per chain, all transactions share the same chainId. + // Fetch status updates for all pending transactions on this chain await this.fetchSmartTransactionsStatus(pendingTransactions); } }