From 8628b881982cc931b2a928823b0e2cb23c547aac Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Fri, 30 Jan 2026 11:37:00 +0000 Subject: [PATCH 1/3] feat(transaction-controller): add updateTransaction overload with callback Add a new public updateTransaction overload that accepts an object with transactionId and callback properties, allowing transactions to be updated using a callback function. Changes: - Add UpdateTransactionRequest type for the new overload parameters - Add updateTransaction overload that takes { transactionId, callback } - Mark the original updateTransaction(transactionMeta, note) as deprecated - Add new TransactionController:updateTransactionObj messenger action - Add TransactionControllerUpdateTransactionObjAction type - Add tests for the new updateTransactionObj messenger action - Export new types from index.ts Co-authored-by: matthew.walsh --- packages/transaction-controller/CHANGELOG.md | 16 +++++ .../src/TransactionController.test.ts | 62 +++++++++++++++++++ .../src/TransactionController.ts | 57 ++++++++++++++++- packages/transaction-controller/src/index.ts | 2 + 4 files changed, 135 insertions(+), 2 deletions(-) diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index c849a4287ea..dc647bdf014 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add new `updateTransaction` overload that accepts an object with `transactionId` and `callback` properties +- Add new `UpdateTransactionRequest` type for the new `updateTransaction` overload parameters +- Add new `TransactionController:updateTransactionObj` messenger action for the new `updateTransaction` overload +- Add new `TransactionControllerUpdateTransactionObjAction` type for the new messenger action + +### Changed + +- **DEPRECATED**: The `updateTransaction(transactionMeta, note)` signature is now deprecated + - Use `updateTransaction({ transactionId, callback })` instead. + - This signature will be removed in a future version. +- **DEPRECATED**: The `TransactionControllerUpdateTransactionAction` type is now deprecated + - Use `TransactionControllerUpdateTransactionObjAction` instead. + - This type will be removed in a future version. + ## [62.12.0] ### Added diff --git a/packages/transaction-controller/src/TransactionController.test.ts b/packages/transaction-controller/src/TransactionController.test.ts index 4b7f34ff0c5..1b4e954d48f 100644 --- a/packages/transaction-controller/src/TransactionController.test.ts +++ b/packages/transaction-controller/src/TransactionController.test.ts @@ -8368,6 +8368,68 @@ describe('TransactionController', () => { }); }); + describe('TransactionController:updateTransactionObj', () => { + it('calls updateTransaction with callback via messenger', () => { + const transaction = { + ...TRANSACTION_META_MOCK, + txParams: { + from: ACCOUNT_MOCK, + to: ACCOUNT_2_MOCK, + }, + }; + const { controller, messenger } = setupController({ + options: { + state: { + transactions: [transaction], + }, + }, + }); + + const result = messenger.call( + 'TransactionController:updateTransactionObj', + { + transactionId: transaction.id, + callback: (txMeta: TransactionMeta) => { + txMeta.txParams.value = '0x3'; + }, + }, + ); + + expect(controller.state.transactions[0].txParams.value).toBe('0x3'); + expect(result).toBeDefined(); + expect(result.id).toBe(transaction.id); + }); + + it('returns updated transaction metadata', () => { + const transaction = { + ...TRANSACTION_META_MOCK, + txParams: { + from: ACCOUNT_MOCK, + to: ACCOUNT_2_MOCK, + }, + }; + const { messenger } = setupController({ + options: { + state: { + transactions: [transaction], + }, + }, + }); + + const result = messenger.call( + 'TransactionController:updateTransactionObj', + { + transactionId: transaction.id, + callback: (txMeta: TransactionMeta) => { + txMeta.txParams.value = '0x4'; + }, + }, + ); + + expect(result.txParams.value).toBe('0x4'); + }); + }); + describe('TransactionController:getGasFeeTokens', () => { it('returns gas fee tokens', async () => { const { messenger } = setupController(); diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index 09b42639521..b4de6d8f55b 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -359,10 +359,31 @@ export type TransactionControllerGetTransactionsAction = { * * @param transactionMeta - The new transaction to store in state. * @param note - A note or update reason to be logged. + * @deprecated Use TransactionControllerUpdateTransactionObjAction instead. */ export type TransactionControllerUpdateTransactionAction = { type: `${typeof controllerName}:updateTransaction`; - handler: TransactionController['updateTransaction']; + handler: (transactionMeta: TransactionMeta, note: string) => void; +}; + +/** + * Request object for updating a transaction using a callback. + */ +export type UpdateTransactionRequest = { + /** The ID of the transaction to update. */ + transactionId: string; + /** A callback that receives the current transaction and returns the updated transaction or void. */ + callback: (transactionMeta: TransactionMeta) => TransactionMeta | void; +}; + +/** + * Updates an existing transaction in state using a callback function. + */ +export type TransactionControllerUpdateTransactionObjAction = { + type: `${typeof controllerName}:updateTransactionObj`; + handler: ( + request: UpdateTransactionRequest, + ) => Readonly; }; /** Add a single transaction to be submitted after approval. */ @@ -420,6 +441,7 @@ export type TransactionControllerActions = | TransactionControllerGetTransactionsAction | TransactionControllerUpdateCustodialTransactionAction | TransactionControllerUpdateTransactionAction + | TransactionControllerUpdateTransactionObjAction | TransactionControllerEmulateNewTransaction | TransactionControllerEmulateTransactionUpdate; @@ -1861,8 +1883,34 @@ export class TransactionController extends BaseController< * * @param transactionMeta - The new transaction to store in state. * @param note - A note or update reason to be logged. + * @deprecated Use the object form `updateTransaction({ transactionId, callback })` instead. */ - updateTransaction(transactionMeta: TransactionMeta, note: string): void { + updateTransaction(transactionMeta: TransactionMeta, note: string): void; + + /** + * Updates an existing transaction in state using a callback function. + * + * @param request - The update request containing transactionId and callback. + * @param request.transactionId - The ID of the transaction to update. + * @param request.callback - A callback that receives the current transaction and returns the updated transaction or void. + * @returns The updated transaction metadata. + */ + updateTransaction( + request: UpdateTransactionRequest, + ): Readonly; + + updateTransaction( + transactionMetaOrRequest: TransactionMeta | UpdateTransactionRequest, + note?: string, + ): void | Readonly { + // New form: object with transactionId and callback + if ('callback' in transactionMetaOrRequest) { + const { transactionId, callback } = transactionMetaOrRequest; + return this.#updateTransactionInternal({ transactionId }, callback); + } + + // Old form (deprecated): transactionMeta and note + const transactionMeta = transactionMetaOrRequest; const { id: transactionId } = transactionMeta; this.#updateTransactionInternal({ transactionId }, () => ({ @@ -4649,6 +4697,11 @@ export class TransactionController extends BaseController< `${controllerName}:updateTransaction`, this.updateTransaction.bind(this), ); + + this.messenger.registerActionHandler( + `${controllerName}:updateTransactionObj`, + (request: UpdateTransactionRequest) => this.updateTransaction(request), + ); } #deleteTransaction(transactionId: string): void { diff --git a/packages/transaction-controller/src/index.ts b/packages/transaction-controller/src/index.ts index eb635910979..1f853120f0b 100644 --- a/packages/transaction-controller/src/index.ts +++ b/packages/transaction-controller/src/index.ts @@ -33,6 +33,8 @@ export type { TransactionControllerUnapprovedTransactionAddedEvent, TransactionControllerUpdateCustodialTransactionAction, TransactionControllerUpdateTransactionAction, + TransactionControllerUpdateTransactionObjAction, + UpdateTransactionRequest, TransactionControllerMessenger, TransactionControllerOptions, } from './TransactionController'; From 9cf90c685f82cadfea6ebccf3ab3c4bc6d6d16bf Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Fri, 30 Jan 2026 11:41:22 +0000 Subject: [PATCH 2/3] docs: add PR links to changelog entries Co-authored-by: matthew.walsh --- packages/transaction-controller/CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index dc647bdf014..7c6473e911e 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -9,17 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add new `updateTransaction` overload that accepts an object with `transactionId` and `callback` properties -- Add new `UpdateTransactionRequest` type for the new `updateTransaction` overload parameters -- Add new `TransactionController:updateTransactionObj` messenger action for the new `updateTransaction` overload -- Add new `TransactionControllerUpdateTransactionObjAction` type for the new messenger action +- Add new `updateTransaction` overload that accepts an object with `transactionId` and `callback` properties ([#7784](https://github.com/MetaMask/core/pull/7784)) +- Add new `UpdateTransactionRequest` type for the new `updateTransaction` overload parameters ([#7784](https://github.com/MetaMask/core/pull/7784)) +- Add new `TransactionController:updateTransactionObj` messenger action for the new `updateTransaction` overload ([#7784](https://github.com/MetaMask/core/pull/7784)) +- Add new `TransactionControllerUpdateTransactionObjAction` type for the new messenger action ([#7784](https://github.com/MetaMask/core/pull/7784)) ### Changed -- **DEPRECATED**: The `updateTransaction(transactionMeta, note)` signature is now deprecated +- **DEPRECATED**: The `updateTransaction(transactionMeta, note)` signature is now deprecated ([#7784](https://github.com/MetaMask/core/pull/7784)) - Use `updateTransaction({ transactionId, callback })` instead. - This signature will be removed in a future version. -- **DEPRECATED**: The `TransactionControllerUpdateTransactionAction` type is now deprecated +- **DEPRECATED**: The `TransactionControllerUpdateTransactionAction` type is now deprecated ([#7784](https://github.com/MetaMask/core/pull/7784)) - Use `TransactionControllerUpdateTransactionObjAction` instead. - This type will be removed in a future version. From 67c097e3d56c75bf8af240cb1fca58dd079fc262 Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Fri, 30 Jan 2026 11:47:49 +0000 Subject: [PATCH 3/3] fix: lint issues in updateTransaction overload - Fix Prettier formatting for handler type definition - Add explicit return undefined for consistent-return rule Co-authored-by: matthew.walsh --- .../transaction-controller/src/TransactionController.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index b4de6d8f55b..624de35b79b 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -381,9 +381,7 @@ export type UpdateTransactionRequest = { */ export type TransactionControllerUpdateTransactionObjAction = { type: `${typeof controllerName}:updateTransactionObj`; - handler: ( - request: UpdateTransactionRequest, - ) => Readonly; + handler: (request: UpdateTransactionRequest) => Readonly; }; /** Add a single transaction to be submitted after approval. */ @@ -1918,6 +1916,8 @@ export class TransactionController extends BaseController< })); log('Transaction updated', { transactionId, note }); + + return undefined; } /**