Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support atomic batch transactions #5306

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5fc40a1
Upgrade ethereumjs packages
matthewwalsh0 Feb 4, 2025
d7ba1a7
Add unit tests for prepare utils
matthewwalsh0 Feb 4, 2025
2e116ac
Update types
matthewwalsh0 Feb 4, 2025
495f1d6
Add validation
matthewwalsh0 Feb 4, 2025
e696ac0
Add signing
matthewwalsh0 Feb 5, 2025
d52b567
Update hardfork
matthewwalsh0 Feb 5, 2025
7407517
Add additional 7702 unit tests
matthewwalsh0 Feb 5, 2025
1676b5e
Add origin validation
matthewwalsh0 Feb 5, 2025
e85731b
Fix linting and unit test coverage
matthewwalsh0 Feb 5, 2025
8df08d5
Align upgrades
matthewwalsh0 Feb 5, 2025
f253296
Update yarn lock
matthewwalsh0 Feb 5, 2025
29e09cd
Update thresholds
matthewwalsh0 Feb 5, 2025
47cd630
Merge branch 'main' into feat/type-4-transactions
matthewwalsh0 Feb 6, 2025
d335bc4
Revert upgrades
matthewwalsh0 Feb 6, 2025
2a6578b
Use utils bytesToHex
matthewwalsh0 Feb 6, 2025
b6494b2
Add types
matthewwalsh0 Feb 6, 2025
cca282f
Add supported account and chain utils
matthewwalsh0 Feb 6, 2025
446e337
Add generate transaction function
matthewwalsh0 Feb 6, 2025
789bd71
Add batch method
matthewwalsh0 Feb 7, 2025
50bc5fc
Convert to type 4
matthewwalsh0 Feb 8, 2025
751ed20
Add feature flag unit tests
matthewwalsh0 Feb 8, 2025
62fd88b
Add batch unit tests
matthewwalsh0 Feb 9, 2025
84fd250
Add unit test
matthewwalsh0 Feb 9, 2025
f8819a4
Add nested transactions property
matthewwalsh0 Feb 9, 2025
202ea06
Add isAtomicBatchSupported method
matthewwalsh0 Feb 10, 2025
c3ac61a
Validate to is not internal
matthewwalsh0 Feb 10, 2025
7fabfc7
Merge branch 'main' into feat/transaction-batch
matthewwalsh0 Feb 11, 2025
5081e27
Fix linting
matthewwalsh0 Feb 11, 2025
efeb158
Merge branch 'main' into feat/transaction-batch
matthewwalsh0 Feb 11, 2025
5d2ca68
Fix dependencies
matthewwalsh0 Feb 11, 2025
4e3adee
Update Yarn lock
matthewwalsh0 Feb 11, 2025
7f833c8
Fix yParity validation
matthewwalsh0 Feb 11, 2025
1a21f76
Wait for publish
matthewwalsh0 Feb 11, 2025
febde9c
Use ERC-7821 contract
matthewwalsh0 Feb 12, 2025
0342acc
Skip to validation if type is batch
matthewwalsh0 Feb 12, 2025
923a875
Fix linting
matthewwalsh0 Feb 12, 2025
ee98fad
Update changelog
matthewwalsh0 Feb 12, 2025
862b5da
Move ABI
matthewwalsh0 Feb 12, 2025
538a67a
Fix linting
matthewwalsh0 Feb 12, 2025
f51ef7f
Update sign action
matthewwalsh0 Feb 12, 2025
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
6 changes: 0 additions & 6 deletions eslint-warning-thresholds.json
Original file line number Diff line number Diff line change
Expand Up @@ -570,18 +570,12 @@
"packages/transaction-controller/src/TransactionController.test.ts": {
"@typescript-eslint/no-unused-vars": 1,
"import-x/namespace": 1,
"import-x/order": 4,
"jsdoc/tag-lines": 1,
"promise/always-return": 2
},
"packages/transaction-controller/src/TransactionController.ts": {
"jsdoc/check-tag-names": 35,
"jsdoc/require-returns": 5
},
"packages/transaction-controller/src/TransactionControllerIntegration.test.ts": {
"import-x/order": 4,
"jsdoc/tag-lines": 1
},
"packages/transaction-controller/src/api/accounts-api.test.ts": {
"import-x/order": 1,
"jsdoc/tag-lines": 1
Expand Down
21 changes: 21 additions & 0 deletions packages/transaction-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Support atomic batch transactions ([#5306](https://github.com/MetaMask/core/pull/5306))
- Add methods:
- `addTransactionBatch`
- `isAtomicBatchSupported`
- Add `batch` to `TransactionType`.
- Add `nestedTransactions` to `TransactionMeta`.
- Add new types:
- `BatchTransactionParams`
- `TransactionBatchSingleRequest`
- `TransactionBatchRequest`
- `TransactionBatchResult`
- Add dependency on `@metamask/remote-feature-flag-controller:^1.4.0`.

### Changed

- **BREAKING:** Support atomic batch transactions ([#5306](https://github.com/MetaMask/core/pull/5306))
- Require `AccountsController:getState` action permission in messenger.
- Require `RemoteFeatureFlagController:getState` action permission in messenger.

## [45.1.0]

### Added
Expand Down
2 changes: 1 addition & 1 deletion packages/transaction-controller/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = merge(baseConfig, {
coverageThreshold: {
global: {
branches: 91.76,
functions: 94.62,
functions: 93.72,
lines: 96.83,
statements: 96.82,
},
Expand Down
4 changes: 3 additions & 1 deletion packages/transaction-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@metamask/eth-query": "^4.0.0",
"@metamask/metamask-eth-abis": "^3.1.1",
"@metamask/nonce-tracker": "^6.0.0",
"@metamask/remote-feature-flag-controller": "^1.4.0",
"@metamask/rpc-errors": "^7.0.2",
"@metamask/utils": "^11.1.0",
"async-mutex": "^0.5.0",
Expand Down Expand Up @@ -96,7 +97,8 @@
"@metamask/approval-controller": "^7.0.0",
"@metamask/eth-block-tracker": ">=9",
"@metamask/gas-fee-controller": "^22.0.0",
"@metamask/network-controller": "^22.0.0"
"@metamask/network-controller": "^22.0.0",
"@metamask/remote-feature-flag-controller": "^1.3.0"
},
"engines": {
"node": "^18.18 || >=20"
Expand Down
63 changes: 41 additions & 22 deletions packages/transaction-controller/src/TransactionController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ import { createDeferredPromise } from '@metamask/utils';
import assert from 'assert';
import * as uuidModule from 'uuid';

import { FakeBlockTracker } from '../../../tests/fake-block-tracker';
import { FakeProvider } from '../../../tests/fake-provider';
import { flushPromises } from '../../../tests/helpers';
import {
buildCustomNetworkClientConfiguration,
buildMockGetNetworkClientById,
} from '../../network-controller/tests/helpers';
import { getAccountAddressRelationship } from './api/accounts-api';
import { CHAIN_IDS } from './constants';
import { DefaultGasFeeFlow } from './gas-flows/DefaultGasFeeFlow';
Expand Down Expand Up @@ -79,6 +72,7 @@ import {
TransactionType,
WalletDevice,
} from './types';
import { addTransactionBatch } from './utils/batch';
import { addGasBuffer, estimateGas, updateGas } from './utils/gas';
import { updateGasFees } from './utils/gas-fees';
import { getGasFeeFlow } from './utils/gas-flow';
Expand All @@ -92,6 +86,13 @@ import {
updatePostTransactionBalance,
updateSwapsTransaction,
} from './utils/swaps';
import { FakeBlockTracker } from '../../../tests/fake-block-tracker';
import { FakeProvider } from '../../../tests/fake-provider';
import { flushPromises } from '../../../tests/helpers';
import {
buildCustomNetworkClientConfiguration,
buildMockGetNetworkClientById,
} from '../../network-controller/tests/helpers';

type UnrestrictedMessenger = Messenger<
TransactionControllerActions | AllowedActions,
Expand All @@ -111,6 +112,7 @@ jest.mock('./helpers/IncomingTransactionHelper');
jest.mock('./helpers/MethodDataHelper');
jest.mock('./helpers/MultichainTrackingHelper');
jest.mock('./helpers/PendingTransactionTracker');
jest.mock('./utils/batch');
jest.mock('./utils/gas');
jest.mock('./utils/gas-fees');
jest.mock('./utils/gas-flow');
Expand Down Expand Up @@ -273,6 +275,7 @@ function buildMockBlockTracker(

/**
* Builds a mock gas fee flow.
*
* @returns The mocked gas fee flow.
*/
function buildMockGasFeeFlow(): jest.Mocked<GasFeeFlow> {
Expand Down Expand Up @@ -485,6 +488,7 @@ describe('TransactionController', () => {
const getAccountAddressRelationshipMock = jest.mocked(
getAccountAddressRelationship,
);
const addTransactionBatchMock = jest.mocked(addTransactionBatch);
const methodDataHelperClassMock = jest.mocked(MethodDataHelper);

let mockEthQuery: EthQuery;
Expand Down Expand Up @@ -635,6 +639,7 @@ describe('TransactionController', () => {
'NetworkController:getNetworkClientById',
'NetworkController:findNetworkClientIdByChainId',
'AccountsController:getSelectedAccount',
'AccountsController:getState',
],
allowedEvents: [],
});
Expand All @@ -645,6 +650,11 @@ describe('TransactionController', () => {
mockGetSelectedAccount,
);

unrestrictedMessenger.registerActionHandler(
'AccountsController:getState',
() => ({}) as never,
);

const controller = new TransactionController({
...otherOptions,
messenger: restrictedMessenger,
Expand Down Expand Up @@ -1369,7 +1379,7 @@ describe('TransactionController', () => {
const mockOrigin = 'origin';
const mockSecurityAlertResponse = {
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention

result_type: 'Malicious',
reason: 'blur_farming',
description:
Expand Down Expand Up @@ -1568,6 +1578,7 @@ describe('TransactionController', () => {
deviceConfirmedOn: undefined,
id: expect.any(String),
isFirstTimeInteraction: undefined,
nestedTransactions: undefined,
networkClientId: NETWORK_CLIENT_ID_MOCK,
origin: undefined,
securityAlertResponse: undefined,
Expand Down Expand Up @@ -4163,8 +4174,6 @@ describe('TransactionController', () => {
const key = 'testKey';
const value = 123;

// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
incomingTransactionHelperClassMock.mock.calls[0][0].updateCache(
(cache) => {
cache[key] = value;
Expand Down Expand Up @@ -4464,24 +4473,18 @@ describe('TransactionController', () => {
txParams: { ...TRANSACTION_META_MOCK.txParams, nonce: '0x1' },
};

// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention
const duplicate_1 = {
...confirmed,
id: 'testId2',
status: TransactionStatus.submitted,
};

// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention
const duplicate_2 = {
...duplicate_1,
id: 'testId3',
status: TransactionStatus.approved,
};

// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention
const duplicate_3 = {
...duplicate_1,
id: 'testId4',
Expand Down Expand Up @@ -5103,8 +5106,6 @@ describe('TransactionController', () => {

controller.updateSecurityAlertResponse(transactionMeta.id, {
reason: 'NA',
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention
result_type: 'Benign',
});

Expand All @@ -5126,8 +5127,6 @@ describe('TransactionController', () => {
// @ts-expect-error Intentionally passing invalid input
controller.updateSecurityAlertResponse(undefined, {
reason: 'NA',
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention
result_type: 'Benign',
}),
).toThrow(
Expand Down Expand Up @@ -5194,8 +5193,6 @@ describe('TransactionController', () => {
expect(() =>
controller.updateSecurityAlertResponse('456', {
reason: 'NA',
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention
result_type: 'Benign',
}),
).toThrow(
Expand Down Expand Up @@ -6075,4 +6072,26 @@ describe('TransactionController', () => {
);
});
});

describe('addTransactionBatch', () => {
it('invokes util', async () => {
const { controller } = setupController();

await controller.addTransactionBatch({
from: ACCOUNT_MOCK,
networkClientId: NETWORK_CLIENT_ID_MOCK,
transactions: [
{
params: {
to: ACCOUNT_2_MOCK,
data: '0x123456',
value: '0x123',
},
},
],
});

expect(addTransactionBatchMock).toHaveBeenCalledTimes(1);
});
});
});
Loading
Loading