diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index 1bff4d745e..58772de962 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/accounts-controller` from `^39.0.7` to `^39.1.0` ([#9807](https://github.com/MetaMask/core/pull/9807)) +### Fixed + +- Skip resimulation check when failing incomplete transactions at startup, preventing a crash when `isSimulationEnabled` depends on controllers not yet registered ([#9821](https://github.com/MetaMask/core/pull/9821)) + ## [69.5.1] ### Changed diff --git a/packages/transaction-controller/src/TransactionController.test.ts b/packages/transaction-controller/src/TransactionController.test.ts index 97a14a14ea..dbbc422a42 100644 --- a/packages/transaction-controller/src/TransactionController.test.ts +++ b/packages/transaction-controller/src/TransactionController.test.ts @@ -1275,6 +1275,55 @@ describe('TransactionController', () => { ); }); + it('fails signed transactions even when isSimulationEnabled throws', async () => { + const mockTransactionMeta = { + from: ACCOUNT_MOCK, + txParams: { + from: ACCOUNT_MOCK, + to: ACCOUNT_2_MOCK, + }, + }; + + const mockedTransactions = [ + { + id: '111', + chainId: toHex(5), + status: TransactionStatus.signed, + ...mockTransactionMeta, + }, + { + id: '222', + chainId: toHex(1), + status: TransactionStatus.approved, + ...mockTransactionMeta, + }, + ]; + + const mockedControllerState = { + transactions: mockedTransactions, + methodData: {}, + lastFetchedBlockNumbers: {}, + }; + + const { controller } = setupController({ + options: { + isSimulationEnabled: () => { + throw new Error('Handler not registered'); + }, + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + state: mockedControllerState as any, + }, + }); + + await flushPromises(); + + const { transactions } = controller.state; + + expect(transactions[0].status).toBe(TransactionStatus.failed); + expect(transactions[1].status).toBe(TransactionStatus.failed); + }); + it('removes unapproved transactions', async () => { const mockTransactionMeta = { from: ACCOUNT_MOCK, diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index 244a0318ee..f6aa336639 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -4388,6 +4388,7 @@ export class TransactionController extends BaseController< { transactionId: transactionMeta.id, skipValidation: true, + skipResimulateCheck: true, }, (draftTransactionMeta) => { draftTransactionMeta.status = TransactionStatus.failed;