Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/transaction-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
57 changes: 55 additions & 2 deletions packages/transaction-controller/src/TransactionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<TransactionMeta>;
};

/** Add a single transaction to be submitted after approval. */
Expand Down Expand Up @@ -420,6 +439,7 @@ export type TransactionControllerActions =
| TransactionControllerGetTransactionsAction
| TransactionControllerUpdateCustodialTransactionAction
| TransactionControllerUpdateTransactionAction
| TransactionControllerUpdateTransactionObjAction
| TransactionControllerEmulateNewTransaction
| TransactionControllerEmulateTransactionUpdate;

Expand Down Expand Up @@ -1861,15 +1881,43 @@ 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<TransactionMeta>;

updateTransaction(
transactionMetaOrRequest: TransactionMeta | UpdateTransactionRequest,
note?: string,
): void | Readonly<TransactionMeta> {
// 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 }, () => ({
...transactionMeta,
}));

log('Transaction updated', { transactionId, note });

return undefined;
}

/**
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions packages/transaction-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export type {
TransactionControllerUnapprovedTransactionAddedEvent,
TransactionControllerUpdateCustodialTransactionAction,
TransactionControllerUpdateTransactionAction,
TransactionControllerUpdateTransactionObjAction,
UpdateTransactionRequest,
TransactionControllerMessenger,
TransactionControllerOptions,
} from './TransactionController';
Expand Down
Loading