Skip to content
Merged
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
10 changes: 10 additions & 0 deletions packages/transaction-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Expose `confirmExternalTransaction`, `getNonceLock`, `getTransactions`, and `updateTransaction` actions through the messenger ([#6615](https://github.com/MetaMask/core/pull/6615))
- Like other action methods, they are callable as `TransactionController:*`
- Also add associated types:
- `TransactionControllerConfirmExternalTransactionAction`
- `TransactionControllerGetNonceLockAction`
- `TransactionControllerGetTransactionsAction`
- `TransactionControllerUpdateTransactionAction`

### Changed

- Bump `@metamask/controller-utils` from `^11.12.0` to `^11.13.0` ([#6620](https://github.com/MetaMask/core/pull/6620))
Expand Down
167 changes: 167 additions & 0 deletions packages/transaction-controller/src/TransactionController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8044,4 +8044,171 @@ describe('TransactionController', () => {
`);
});
});

describe('messenger actions', () => {
describe('TransactionController:confirmExternalTransaction', () => {
it('calls confirmExternalTransaction method via messenger', async () => {
const { controller, messenger } = setupController();
const externalTransactionToConfirm = {
id: '1',
chainId: toHex(1),
networkClientId: NETWORK_CLIENT_ID_MOCK,
time: 123456789,
status: TransactionStatus.confirmed as const,
txParams: {
gasUsed: undefined,
from: ACCOUNT_MOCK,
to: ACCOUNT_2_MOCK,
},
};
const externalTransactionReceipt = {
gasUsed: '0x5208',
};
const externalBaseFeePerGas = '0x14';

await messenger.call(
'TransactionController:confirmExternalTransaction',
externalTransactionToConfirm,
externalTransactionReceipt,
externalBaseFeePerGas,
);

expect(controller.state.transactions).toHaveLength(1);
expect(controller.state.transactions[0]).toMatchObject({
id: '1',
status: TransactionStatus.confirmed,
txParams: {
from: ACCOUNT_MOCK,
to: ACCOUNT_2_MOCK,
},
});
});
});

describe('TransactionController:getNonceLock', () => {
it('calls getNonceLock method via messenger', async () => {
const { messenger } = setupController();

const result = await messenger.call(
'TransactionController:getNonceLock',
ACCOUNT_MOCK,
NETWORK_CLIENT_ID_MOCK,
);

expect(result).toMatchObject({
nextNonce: NONCE_MOCK,
releaseLock: expect.any(Function),
});
expect(getNonceLockSpy).toHaveBeenCalledWith(
ACCOUNT_MOCK,
NETWORK_CLIENT_ID_MOCK,
);
});
});

describe('TransactionController:getTransactions', () => {
it('calls getTransactions method via messenger with no parameters', async () => {
const { messenger } = setupController({
options: {
state: {
transactions: [
{
...TRANSACTION_META_MOCK,
txParams: {
from: ACCOUNT_MOCK,
to: ACCOUNT_2_MOCK,
},
},
],
},
},
});

const result = await messenger.call(
'TransactionController:getTransactions',
);

expect(result).toHaveLength(1);
expect(result[0]).toMatchObject({
txParams: {
from: ACCOUNT_MOCK,
to: ACCOUNT_2_MOCK,
},
});
});

it('calls getTransactions method via messenger with search criteria', async () => {
const { messenger } = setupController({
options: {
state: {
transactions: [
{
...TRANSACTION_META_MOCK,
id: '1',
txParams: {
from: ACCOUNT_MOCK,
to: ACCOUNT_2_MOCK,
},
},
{
...TRANSACTION_META_2_MOCK,
id: '2',
txParams: {
from: ACCOUNT_2_MOCK,
to: ACCOUNT_MOCK,
},
},
],
},
},
});

const result = await messenger.call(
'TransactionController:getTransactions',
{
searchCriteria: {
from: ACCOUNT_MOCK,
},
},
);

expect(result).toHaveLength(1);
expect(result[0].txParams.from).toBe(ACCOUNT_MOCK);
});
});

describe('TransactionController:updateTransaction', () => {
it('calls updateTransaction method via messenger', async () => {
const transaction = {
...TRANSACTION_META_MOCK,
txParams: {
from: ACCOUNT_MOCK,
to: ACCOUNT_2_MOCK,
},
};
const { controller, messenger } = setupController({
options: {
state: {
transactions: [transaction],
},
},
});
const updatedTransaction = {
...transaction,
txParams: {
...transaction.txParams,
value: '0x1',
},
};

await messenger.call(
'TransactionController:updateTransaction',
updatedTransaction,
'Test update note',
);

expect(controller.state.transactions[0].txParams.value).toBe('0x1');
});
});
});
});
68 changes: 67 additions & 1 deletion packages/transaction-controller/src/TransactionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,59 @@ export type TransactionControllerEstimateGasAction = {
handler: TransactionController['estimateGas'];
};

/**
* Adds external provided transaction to state as confirmed transaction.
*
* @param transactionMeta - TransactionMeta to add transactions.
* @param transactionReceipt - TransactionReceipt of the external transaction.
* @param baseFeePerGas - Base fee per gas of the external transaction.
*/
export type TransactionControllerConfirmExternalTransactionAction = {
type: `${typeof controllerName}:confirmExternalTransaction`;
handler: TransactionController['confirmExternalTransaction'];
};

export type TransactionControllerGetNonceLockAction = {
type: `${typeof controllerName}:getNonceLock`;
handler: TransactionController['getNonceLock'];
};

/**
* Search transaction metadata for matching entries.
*
* @param opts - Options bag.
* @param opts.initialList - The transactions to search. Defaults to the current state.
* @param opts.limit - The maximum number of transactions to return. No limit by default.
* @param opts.searchCriteria - An object containing values or functions for transaction properties to filter transactions with.
* @returns An array of transactions matching the provided options.
*/
export type TransactionControllerGetTransactionsAction = {
type: `${typeof controllerName}:getTransactions`;
handler: TransactionController['getTransactions'];
};

/**
* Updates an existing transaction in state.
*
* @param transactionMeta - The new transaction to store in state.
* @param note - A note or update reason to include in the transaction history.
*/
export type TransactionControllerUpdateTransactionAction = {
type: `${typeof controllerName}:updateTransaction`;
handler: TransactionController['updateTransaction'];
};

/**
* The internal actions available to the TransactionController.
*/
export type TransactionControllerActions =
| TransactionControllerConfirmExternalTransactionAction
| TransactionControllerEstimateGasAction
| TransactionControllerGetNonceLockAction
| TransactionControllerGetStateAction
| TransactionControllerUpdateCustodialTransactionAction;
| TransactionControllerGetTransactionsAction
| TransactionControllerUpdateCustodialTransactionAction
| TransactionControllerUpdateTransactionAction;

/**
* Configuration options for the PendingTransactionTracker
Expand Down Expand Up @@ -4416,15 +4462,35 @@ export class TransactionController extends BaseController<
}

#registerActionHandlers(): void {
this.messagingSystem.registerActionHandler(
`${controllerName}:confirmExternalTransaction`,
this.confirmExternalTransaction.bind(this),
);

this.messagingSystem.registerActionHandler(
`${controllerName}:estimateGas`,
this.estimateGas.bind(this),
);

this.messagingSystem.registerActionHandler(
`${controllerName}:getNonceLock`,
this.getNonceLock.bind(this),
);

this.messagingSystem.registerActionHandler(
`${controllerName}:getTransactions`,
this.getTransactions.bind(this),
);

this.messagingSystem.registerActionHandler(
`${controllerName}:updateCustodialTransaction`,
this.updateCustodialTransaction.bind(this),
);

this.messagingSystem.registerActionHandler(
`${controllerName}:updateTransaction`,
this.updateTransaction.bind(this),
);
}

#deleteTransaction(transactionId: string) {
Expand Down
4 changes: 4 additions & 0 deletions packages/transaction-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ export type {
MethodData,
Result,
TransactionControllerActions,
TransactionControllerConfirmExternalTransactionAction,
TransactionControllerEvents,
TransactionControllerEstimateGasAction,
TransactionControllerGetNonceLockAction,
TransactionControllerGetStateAction,
TransactionControllerGetTransactionsAction,
TransactionControllerIncomingTransactionsReceivedEvent,
TransactionControllerPostTransactionBalanceUpdatedEvent,
TransactionControllerSpeedupTransactionAddedEvent,
Expand All @@ -23,6 +26,7 @@ export type {
TransactionControllerTransactionSubmittedEvent,
TransactionControllerUnapprovedTransactionAddedEvent,
TransactionControllerUpdateCustodialTransactionAction,
TransactionControllerUpdateTransactionAction,
TransactionControllerMessenger,
TransactionControllerOptions,
} from './TransactionController';
Expand Down
Loading