Skip to content

Commit 32fe773

Browse files
authored
Expose TransactionController methods needed by SmartTransactionsController through messenger (#6615)
Currently, the `confirmExternalTransaction`, `getNonceLock`, `getTransactions`, and `updateTransaction` methods in `TransactionController` are accessed by the `SmartTransactionsController` constructor, but in a non-standard way: `SmartTransactionsController` takes function references, when we would like it to call these methods via the messenger instead. This commit exposes these methods through TransactionController's messenger so we can do this.
1 parent d82c88b commit 32fe773

File tree

4 files changed

+248
-1
lines changed

4 files changed

+248
-1
lines changed

packages/transaction-controller/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Expose `confirmExternalTransaction`, `getNonceLock`, `getTransactions`, and `updateTransaction` actions through the messenger ([#6615](https://github.com/MetaMask/core/pull/6615))
13+
- Like other action methods, they are callable as `TransactionController:*`
14+
- Also add associated types:
15+
- `TransactionControllerConfirmExternalTransactionAction`
16+
- `TransactionControllerGetNonceLockAction`
17+
- `TransactionControllerGetTransactionsAction`
18+
- `TransactionControllerUpdateTransactionAction`
19+
1020
### Changed
1121

1222
- Bump `@metamask/controller-utils` from `^11.12.0` to `^11.13.0` ([#6620](https://github.com/MetaMask/core/pull/6620))

packages/transaction-controller/src/TransactionController.test.ts

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8044,4 +8044,171 @@ describe('TransactionController', () => {
80448044
`);
80458045
});
80468046
});
8047+
8048+
describe('messenger actions', () => {
8049+
describe('TransactionController:confirmExternalTransaction', () => {
8050+
it('calls confirmExternalTransaction method via messenger', async () => {
8051+
const { controller, messenger } = setupController();
8052+
const externalTransactionToConfirm = {
8053+
id: '1',
8054+
chainId: toHex(1),
8055+
networkClientId: NETWORK_CLIENT_ID_MOCK,
8056+
time: 123456789,
8057+
status: TransactionStatus.confirmed as const,
8058+
txParams: {
8059+
gasUsed: undefined,
8060+
from: ACCOUNT_MOCK,
8061+
to: ACCOUNT_2_MOCK,
8062+
},
8063+
};
8064+
const externalTransactionReceipt = {
8065+
gasUsed: '0x5208',
8066+
};
8067+
const externalBaseFeePerGas = '0x14';
8068+
8069+
await messenger.call(
8070+
'TransactionController:confirmExternalTransaction',
8071+
externalTransactionToConfirm,
8072+
externalTransactionReceipt,
8073+
externalBaseFeePerGas,
8074+
);
8075+
8076+
expect(controller.state.transactions).toHaveLength(1);
8077+
expect(controller.state.transactions[0]).toMatchObject({
8078+
id: '1',
8079+
status: TransactionStatus.confirmed,
8080+
txParams: {
8081+
from: ACCOUNT_MOCK,
8082+
to: ACCOUNT_2_MOCK,
8083+
},
8084+
});
8085+
});
8086+
});
8087+
8088+
describe('TransactionController:getNonceLock', () => {
8089+
it('calls getNonceLock method via messenger', async () => {
8090+
const { messenger } = setupController();
8091+
8092+
const result = await messenger.call(
8093+
'TransactionController:getNonceLock',
8094+
ACCOUNT_MOCK,
8095+
NETWORK_CLIENT_ID_MOCK,
8096+
);
8097+
8098+
expect(result).toMatchObject({
8099+
nextNonce: NONCE_MOCK,
8100+
releaseLock: expect.any(Function),
8101+
});
8102+
expect(getNonceLockSpy).toHaveBeenCalledWith(
8103+
ACCOUNT_MOCK,
8104+
NETWORK_CLIENT_ID_MOCK,
8105+
);
8106+
});
8107+
});
8108+
8109+
describe('TransactionController:getTransactions', () => {
8110+
it('calls getTransactions method via messenger with no parameters', async () => {
8111+
const { messenger } = setupController({
8112+
options: {
8113+
state: {
8114+
transactions: [
8115+
{
8116+
...TRANSACTION_META_MOCK,
8117+
txParams: {
8118+
from: ACCOUNT_MOCK,
8119+
to: ACCOUNT_2_MOCK,
8120+
},
8121+
},
8122+
],
8123+
},
8124+
},
8125+
});
8126+
8127+
const result = await messenger.call(
8128+
'TransactionController:getTransactions',
8129+
);
8130+
8131+
expect(result).toHaveLength(1);
8132+
expect(result[0]).toMatchObject({
8133+
txParams: {
8134+
from: ACCOUNT_MOCK,
8135+
to: ACCOUNT_2_MOCK,
8136+
},
8137+
});
8138+
});
8139+
8140+
it('calls getTransactions method via messenger with search criteria', async () => {
8141+
const { messenger } = setupController({
8142+
options: {
8143+
state: {
8144+
transactions: [
8145+
{
8146+
...TRANSACTION_META_MOCK,
8147+
id: '1',
8148+
txParams: {
8149+
from: ACCOUNT_MOCK,
8150+
to: ACCOUNT_2_MOCK,
8151+
},
8152+
},
8153+
{
8154+
...TRANSACTION_META_2_MOCK,
8155+
id: '2',
8156+
txParams: {
8157+
from: ACCOUNT_2_MOCK,
8158+
to: ACCOUNT_MOCK,
8159+
},
8160+
},
8161+
],
8162+
},
8163+
},
8164+
});
8165+
8166+
const result = await messenger.call(
8167+
'TransactionController:getTransactions',
8168+
{
8169+
searchCriteria: {
8170+
from: ACCOUNT_MOCK,
8171+
},
8172+
},
8173+
);
8174+
8175+
expect(result).toHaveLength(1);
8176+
expect(result[0].txParams.from).toBe(ACCOUNT_MOCK);
8177+
});
8178+
});
8179+
8180+
describe('TransactionController:updateTransaction', () => {
8181+
it('calls updateTransaction method via messenger', async () => {
8182+
const transaction = {
8183+
...TRANSACTION_META_MOCK,
8184+
txParams: {
8185+
from: ACCOUNT_MOCK,
8186+
to: ACCOUNT_2_MOCK,
8187+
},
8188+
};
8189+
const { controller, messenger } = setupController({
8190+
options: {
8191+
state: {
8192+
transactions: [transaction],
8193+
},
8194+
},
8195+
});
8196+
const updatedTransaction = {
8197+
...transaction,
8198+
txParams: {
8199+
...transaction.txParams,
8200+
value: '0x1',
8201+
},
8202+
};
8203+
8204+
await messenger.call(
8205+
'TransactionController:updateTransaction',
8206+
updatedTransaction,
8207+
'Test update note',
8208+
);
8209+
8210+
expect(controller.state.transactions[0].txParams.value).toBe('0x1');
8211+
});
8212+
});
8213+
});
80478214
});

packages/transaction-controller/src/TransactionController.ts

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,59 @@ export type TransactionControllerEstimateGasAction = {
308308
handler: TransactionController['estimateGas'];
309309
};
310310

311+
/**
312+
* Adds external provided transaction to state as confirmed transaction.
313+
*
314+
* @param transactionMeta - TransactionMeta to add transactions.
315+
* @param transactionReceipt - TransactionReceipt of the external transaction.
316+
* @param baseFeePerGas - Base fee per gas of the external transaction.
317+
*/
318+
export type TransactionControllerConfirmExternalTransactionAction = {
319+
type: `${typeof controllerName}:confirmExternalTransaction`;
320+
handler: TransactionController['confirmExternalTransaction'];
321+
};
322+
323+
export type TransactionControllerGetNonceLockAction = {
324+
type: `${typeof controllerName}:getNonceLock`;
325+
handler: TransactionController['getNonceLock'];
326+
};
327+
328+
/**
329+
* Search transaction metadata for matching entries.
330+
*
331+
* @param opts - Options bag.
332+
* @param opts.initialList - The transactions to search. Defaults to the current state.
333+
* @param opts.limit - The maximum number of transactions to return. No limit by default.
334+
* @param opts.searchCriteria - An object containing values or functions for transaction properties to filter transactions with.
335+
* @returns An array of transactions matching the provided options.
336+
*/
337+
export type TransactionControllerGetTransactionsAction = {
338+
type: `${typeof controllerName}:getTransactions`;
339+
handler: TransactionController['getTransactions'];
340+
};
341+
342+
/**
343+
* Updates an existing transaction in state.
344+
*
345+
* @param transactionMeta - The new transaction to store in state.
346+
* @param note - A note or update reason to include in the transaction history.
347+
*/
348+
export type TransactionControllerUpdateTransactionAction = {
349+
type: `${typeof controllerName}:updateTransaction`;
350+
handler: TransactionController['updateTransaction'];
351+
};
352+
311353
/**
312354
* The internal actions available to the TransactionController.
313355
*/
314356
export type TransactionControllerActions =
357+
| TransactionControllerConfirmExternalTransactionAction
315358
| TransactionControllerEstimateGasAction
359+
| TransactionControllerGetNonceLockAction
316360
| TransactionControllerGetStateAction
317-
| TransactionControllerUpdateCustodialTransactionAction;
361+
| TransactionControllerGetTransactionsAction
362+
| TransactionControllerUpdateCustodialTransactionAction
363+
| TransactionControllerUpdateTransactionAction;
318364

319365
/**
320366
* Configuration options for the PendingTransactionTracker
@@ -4416,15 +4462,35 @@ export class TransactionController extends BaseController<
44164462
}
44174463

44184464
#registerActionHandlers(): void {
4465+
this.messagingSystem.registerActionHandler(
4466+
`${controllerName}:confirmExternalTransaction`,
4467+
this.confirmExternalTransaction.bind(this),
4468+
);
4469+
44194470
this.messagingSystem.registerActionHandler(
44204471
`${controllerName}:estimateGas`,
44214472
this.estimateGas.bind(this),
44224473
);
44234474

4475+
this.messagingSystem.registerActionHandler(
4476+
`${controllerName}:getNonceLock`,
4477+
this.getNonceLock.bind(this),
4478+
);
4479+
4480+
this.messagingSystem.registerActionHandler(
4481+
`${controllerName}:getTransactions`,
4482+
this.getTransactions.bind(this),
4483+
);
4484+
44244485
this.messagingSystem.registerActionHandler(
44254486
`${controllerName}:updateCustodialTransaction`,
44264487
this.updateCustodialTransaction.bind(this),
44274488
);
4489+
4490+
this.messagingSystem.registerActionHandler(
4491+
`${controllerName}:updateTransaction`,
4492+
this.updateTransaction.bind(this),
4493+
);
44284494
}
44294495

44304496
#deleteTransaction(transactionId: string) {

packages/transaction-controller/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ export type {
22
MethodData,
33
Result,
44
TransactionControllerActions,
5+
TransactionControllerConfirmExternalTransactionAction,
56
TransactionControllerEvents,
67
TransactionControllerEstimateGasAction,
8+
TransactionControllerGetNonceLockAction,
79
TransactionControllerGetStateAction,
10+
TransactionControllerGetTransactionsAction,
811
TransactionControllerIncomingTransactionsReceivedEvent,
912
TransactionControllerPostTransactionBalanceUpdatedEvent,
1013
TransactionControllerSpeedupTransactionAddedEvent,
@@ -23,6 +26,7 @@ export type {
2326
TransactionControllerTransactionSubmittedEvent,
2427
TransactionControllerUnapprovedTransactionAddedEvent,
2528
TransactionControllerUpdateCustodialTransactionAction,
29+
TransactionControllerUpdateTransactionAction,
2630
TransactionControllerMessenger,
2731
TransactionControllerOptions,
2832
} from './TransactionController';

0 commit comments

Comments
 (0)