diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index c849a4287ea..7c6473e911e 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 ([#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 ([#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 ([#7784](https://github.com/MetaMask/core/pull/7784)) + - 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..624de35b79b 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -359,10 +359,29 @@ 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 +439,7 @@ export type TransactionControllerActions = | TransactionControllerGetTransactionsAction | TransactionControllerUpdateCustodialTransactionAction | TransactionControllerUpdateTransactionAction + | TransactionControllerUpdateTransactionObjAction | TransactionControllerEmulateNewTransaction | TransactionControllerEmulateTransactionUpdate; @@ -1861,8 +1881,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; + + /** + * 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(transactionMeta: TransactionMeta, note: string): void { + 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 }, () => ({ @@ -1870,6 +1916,8 @@ export class TransactionController extends BaseController< })); log('Transaction updated', { transactionId, note }); + + return undefined; } /** @@ -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';