Skip to content

feat: support atomic batch transactions #30271

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

Merged
merged 4 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from 3 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
130 changes: 130 additions & 0 deletions .yarn/patches/@ethereumjs-tx-npm-5.4.0-0c4a0f973e.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
diff --git a/dist/cjs/util.js b/dist/cjs/util.js
index d60cf924ee8144ee49dd07e8e910d87a2c4bfb6a..ea5494530c05f4c831e301b88fef7855c89f2885 100644
--- a/dist/cjs/util.js
+++ b/dist/cjs/util.js
@@ -119,14 +119,11 @@ class AuthorizationLists {
}
const chainId = (0, util_1.hexToBytes)(item.chainId);
const addressBytes = (0, util_1.hexToBytes)(item.address);
- const nonceList = [];
- for (let j = 0; j < item.nonce.length; j++) {
- nonceList.push((0, util_1.hexToBytes)(item.nonce[j]));
- }
+ const nonce = (0, util_1.hexToBytes)(item.nonce);
const yParity = (0, util_1.hexToBytes)(item.yParity);
const r = (0, util_1.hexToBytes)(item.r);
const s = (0, util_1.hexToBytes)(item.s);
- newAuthorizationList.push([chainId, addressBytes, nonceList, yParity, r, s]);
+ newAuthorizationList.push([chainId, addressBytes, nonce, yParity, r, s]);
}
bufferAuthorizationList = newAuthorizationList;
}
@@ -138,18 +135,14 @@ class AuthorizationLists {
const data = bufferAuthorizationList[i];
const chainId = (0, util_1.bytesToHex)(data[0]);
const address = (0, util_1.bytesToHex)(data[1]);
- const nonces = data[2];
- const nonceList = [];
- for (let j = 0; j < nonces.length; j++) {
- nonceList.push((0, util_1.bytesToHex)(nonces[j]));
- }
+ const nonce = (0, util_1.bytesToHex)(data[2]);
const yParity = (0, util_1.bytesToHex)(data[3]);
const r = (0, util_1.bytesToHex)(data[4]);
const s = (0, util_1.bytesToHex)(data[5]);
const jsonItem = {
chainId,
address,
- nonce: nonceList,
+ nonce,
yParity,
r,
s,
@@ -167,20 +160,14 @@ class AuthorizationLists {
for (let key = 0; key < authorizationList.length; key++) {
const authorizationListItem = authorizationList[key];
const address = authorizationListItem[1];
- const nonceList = authorizationListItem[2];
+ const nonce = authorizationListItem[2];
const yParity = authorizationListItem[3];
const r = authorizationListItem[4];
const s = authorizationListItem[5];
- (0, util_1.validateNoLeadingZeroes)({ yParity, r, s });
+ (0, util_1.validateNoLeadingZeroes)({ yParity, r, s, nonce });
if (address.length !== 20) {
throw new Error('Invalid EIP-7702 transaction: address length should be 20 bytes');
}
- if (nonceList.length > 1) {
- throw new Error('Invalid EIP-7702 transaction: nonce list should consist of at most 1 item');
- }
- else if (nonceList.length === 1) {
- (0, util_1.validateNoLeadingZeroes)({ nonce: nonceList[0] });
- }
}
}
static getDataFeeEIP7702(authorityList, common) {
diff --git a/dist/esm/util.js b/dist/esm/util.js
index 36fa7e9917f72b042efc753ba5d1c9cd0d5572db..de454fa2f09a98b2a8716e173d1cd1f87101a490 100644
--- a/dist/esm/util.js
+++ b/dist/esm/util.js
@@ -114,14 +114,11 @@ export class AuthorizationLists {
}
const chainId = hexToBytes(item.chainId);
const addressBytes = hexToBytes(item.address);
- const nonceList = [];
- for (let j = 0; j < item.nonce.length; j++) {
- nonceList.push(hexToBytes(item.nonce[j]));
- }
+ const nonce = hexToBytes(item.nonce);
const yParity = hexToBytes(item.yParity);
const r = hexToBytes(item.r);
const s = hexToBytes(item.s);
- newAuthorizationList.push([chainId, addressBytes, nonceList, yParity, r, s]);
+ newAuthorizationList.push([chainId, addressBytes, nonce, yParity, r, s]);
}
bufferAuthorizationList = newAuthorizationList;
}
@@ -133,18 +130,14 @@ export class AuthorizationLists {
const data = bufferAuthorizationList[i];
const chainId = bytesToHex(data[0]);
const address = bytesToHex(data[1]);
- const nonces = data[2];
- const nonceList = [];
- for (let j = 0; j < nonces.length; j++) {
- nonceList.push(bytesToHex(nonces[j]));
- }
+ const nonce = bytesToHex(data[2]);
const yParity = bytesToHex(data[3]);
const r = bytesToHex(data[4]);
const s = bytesToHex(data[5]);
const jsonItem = {
chainId,
address,
- nonce: nonceList,
+ nonce,
yParity,
r,
s,
@@ -162,20 +155,14 @@ export class AuthorizationLists {
for (let key = 0; key < authorizationList.length; key++) {
const authorizationListItem = authorizationList[key];
const address = authorizationListItem[1];
- const nonceList = authorizationListItem[2];
+ const nonce = authorizationListItem[2];
const yParity = authorizationListItem[3];
const r = authorizationListItem[4];
const s = authorizationListItem[5];
- validateNoLeadingZeroes({ yParity, r, s });
+ validateNoLeadingZeroes({ yParity, r, s, nonce });
if (address.length !== 20) {
throw new Error('Invalid EIP-7702 transaction: address length should be 20 bytes');
}
- if (nonceList.length > 1) {
- throw new Error('Invalid EIP-7702 transaction: nonce list should consist of at most 1 item');
- }
- else if (nonceList.length === 1) {
- validateNoLeadingZeroes({ nonce: nonceList[0] });
- }
}
}
static getDataFeeEIP7702(authorityList, common) {

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller';
import {
AccountsControllerGetSelectedAccountAction,
AccountsControllerGetStateAction,
} from '@metamask/accounts-controller';
import { ApprovalControllerActions } from '@metamask/approval-controller';
import { Messenger } from '@metamask/base-controller';
import {
Expand All @@ -21,6 +24,8 @@ import {
TransactionControllerUnapprovedTransactionAddedEvent,
} from '@metamask/transaction-controller';
import { SmartTransactionsControllerSmartTransactionEvent } from '@metamask/smart-transactions-controller';
import { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller';
import { KeyringControllerSignEip7702AuthorizationAction } from '@metamask/keyring-controller';
import {
SwapsControllerSetApproveTxIdAction,
SwapsControllerSetTradeTxIdAction,
Expand All @@ -29,9 +34,12 @@ import {
type MessengerActions =
| ApprovalControllerActions
| AccountsControllerGetSelectedAccountAction
| AccountsControllerGetStateAction
| KeyringControllerSignEip7702AuthorizationAction
| NetworkControllerFindNetworkClientIdByChainIdAction
| NetworkControllerGetEIP1559CompatibilityAction
| NetworkControllerGetNetworkClientByIdAction
| RemoteFeatureFlagControllerGetStateAction
| SwapsControllerSetApproveTxIdAction
| SwapsControllerSetTradeTxIdAction;

Expand Down Expand Up @@ -60,9 +68,12 @@ export function getTransactionControllerMessenger(
name: 'TransactionController',
allowedActions: [
'AccountsController:getSelectedAccount',
'AccountsController:getState',
`ApprovalController:addRequest`,
'KeyringController:signEip7702Authorization',
'NetworkController:findNetworkClientIdByChainId',
'NetworkController:getNetworkClientById',
'RemoteFeatureFlagController:getState',
],
allowedEvents: [`NetworkController:stateChange`],
});
Expand Down Expand Up @@ -92,6 +103,7 @@ export function getTransactionControllerInitMessenger(
'ApprovalController:startFlow',
'ApprovalController:updateRequestState',
'NetworkController:getEIP1559Compatibility',
'RemoteFeatureFlagController:getState',
'SwapsController:setApproveTxId',
'SwapsController:setTradeTxId',
],
Expand Down
3 changes: 3 additions & 0 deletions app/scripts/controllers/permissions/specifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,13 @@ export const unrestrictedMethods = Object.freeze([
'personal_ecRecover',
'personal_sign',
'wallet_addEthereumChain',
'wallet_getCallsStatus',
'wallet_getCapabilities',
'wallet_getPermissions',
'wallet_requestPermissions',
'wallet_revokePermissions',
'wallet_registerOnboarding',
'wallet_sendCalls',
'wallet_switchEthereumChain',
'wallet_watchAsset',
'web3_clientVersion',
Expand Down
6 changes: 6 additions & 0 deletions app/scripts/lib/createMetamaskMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ import {
export default function createMetamaskMiddleware({
version,
getAccounts,
getCapabilities,
getTransactionReceiptsByBatchId,
processTransaction,
processTypedMessage,
processTypedMessageV3,
processTypedMessageV4,
processPersonalMessage,
processDecryptMessage,
processEncryptionPublicKey,
processSendCalls,
getPendingNonce,
getPendingTransactionByHash,
}) {
Expand All @@ -28,13 +31,16 @@ export default function createMetamaskMiddleware({
}),
createWalletMiddleware({
getAccounts,
getCapabilities,
getTransactionReceiptsByBatchId,
processTransaction,
processTypedMessage,
processTypedMessageV3,
processTypedMessageV4,
processPersonalMessage,
processDecryptMessage,
processEncryptionPublicKey,
processSendCalls,
}),
createPendingNonceMiddleware({ getPendingNonce }),
createPendingTxMiddleware({ getPendingTransactionByHash }),
Expand Down
Loading
Loading