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

Conversation

matthewwalsh0
Copy link
Member

@matthewwalsh0 matthewwalsh0 commented Feb 11, 2025

Explanation

Support atomic batch transactions via EIP-7702, and ERC-7821.

Specifically:

  • Add addTransactionBatch method with TransactionBatchRequest and TransactionBatchResult types.
  • Encode multiple transactions into single execute call using ERC-7821 ABI.
  • Automatically upgrade account via setCode transaction if needed.
  • Add isAtomicBatchSupported method to identify which chains support atomic batch for a given account.
  • Add new batch TransactionType.
  • Add batch utils to encapsulate all batch-related logic.
  • Add feature-flags utils to encapsulate retrieval and fallback of LaunchDarkly configuration.
    • Currently EIP-7702 chains and contract addresses.
  • Validate to of external transaction is not an internal account unless transactionType is batch.

References

Fixes #4096

Changelog

See CHANGELOG.md.

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

@matthewwalsh0
Copy link
Member Author

@metamaskbot publish-preview

@matthewwalsh0
Copy link
Member Author

@metamaskbot publish-preview

Copy link

socket-security bot commented Feb 11, 2025

New dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@metamask/remote-feature-flag-controller@1.4.0 None +1 2 MB metamaskbot

View full report↗︎

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "23.0.1-preview-1a21f764",
  "@metamask-previews/address-book-controller": "6.0.3-preview-1a21f764",
  "@metamask-previews/announcement-controller": "7.0.3-preview-1a21f764",
  "@metamask-previews/approval-controller": "7.1.3-preview-1a21f764",
  "@metamask-previews/assets-controllers": "49.0.0-preview-1a21f764",
  "@metamask-previews/base-controller": "8.0.0-preview-1a21f764",
  "@metamask-previews/build-utils": "3.0.3-preview-1a21f764",
  "@metamask-previews/composable-controller": "11.0.0-preview-1a21f764",
  "@metamask-previews/controller-utils": "11.5.0-preview-1a21f764",
  "@metamask-previews/earn-controller": "0.2.1-preview-1a21f764",
  "@metamask-previews/ens-controller": "15.0.2-preview-1a21f764",
  "@metamask-previews/eth-json-rpc-provider": "4.1.8-preview-1a21f764",
  "@metamask-previews/gas-fee-controller": "22.0.3-preview-1a21f764",
  "@metamask-previews/json-rpc-engine": "10.0.3-preview-1a21f764",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.7-preview-1a21f764",
  "@metamask-previews/keyring-controller": "19.0.7-preview-1a21f764",
  "@metamask-previews/logging-controller": "6.0.4-preview-1a21f764",
  "@metamask-previews/message-manager": "12.0.1-preview-1a21f764",
  "@metamask-previews/multichain": "2.1.1-preview-1a21f764",
  "@metamask-previews/multichain-transactions-controller": "0.3.0-preview-1a21f764",
  "@metamask-previews/name-controller": "8.0.3-preview-1a21f764",
  "@metamask-previews/network-controller": "22.2.1-preview-1a21f764",
  "@metamask-previews/notification-services-controller": "0.20.1-preview-1a21f764",
  "@metamask-previews/permission-controller": "11.0.6-preview-1a21f764",
  "@metamask-previews/permission-log-controller": "3.0.3-preview-1a21f764",
  "@metamask-previews/phishing-controller": "12.3.2-preview-1a21f764",
  "@metamask-previews/polling-controller": "12.0.3-preview-1a21f764",
  "@metamask-previews/preferences-controller": "15.0.2-preview-1a21f764",
  "@metamask-previews/profile-sync-controller": "7.0.1-preview-1a21f764",
  "@metamask-previews/queued-request-controller": "9.0.1-preview-1a21f764",
  "@metamask-previews/rate-limit-controller": "6.0.3-preview-1a21f764",
  "@metamask-previews/remote-feature-flag-controller": "1.4.0-preview-1a21f764",
  "@metamask-previews/selected-network-controller": "21.0.1-preview-1a21f764",
  "@metamask-previews/signature-controller": "23.2.1-preview-1a21f764",
  "@metamask-previews/token-search-discovery-controller": "2.1.0-preview-1a21f764",
  "@metamask-previews/transaction-controller": "45.1.0-preview-1a21f764",
  "@metamask-previews/user-operation-controller": "24.0.1-preview-1a21f764"
}

@matthewwalsh0
Copy link
Member Author

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "23.0.1-preview-ee98fad1",
  "@metamask-previews/address-book-controller": "6.0.3-preview-ee98fad1",
  "@metamask-previews/announcement-controller": "7.0.3-preview-ee98fad1",
  "@metamask-previews/approval-controller": "7.1.3-preview-ee98fad1",
  "@metamask-previews/assets-controllers": "49.0.0-preview-ee98fad1",
  "@metamask-previews/base-controller": "8.0.0-preview-ee98fad1",
  "@metamask-previews/build-utils": "3.0.3-preview-ee98fad1",
  "@metamask-previews/composable-controller": "11.0.0-preview-ee98fad1",
  "@metamask-previews/controller-utils": "11.5.0-preview-ee98fad1",
  "@metamask-previews/earn-controller": "0.2.1-preview-ee98fad1",
  "@metamask-previews/ens-controller": "15.0.2-preview-ee98fad1",
  "@metamask-previews/eth-json-rpc-provider": "4.1.8-preview-ee98fad1",
  "@metamask-previews/gas-fee-controller": "22.0.3-preview-ee98fad1",
  "@metamask-previews/json-rpc-engine": "10.0.3-preview-ee98fad1",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.7-preview-ee98fad1",
  "@metamask-previews/keyring-controller": "19.0.7-preview-ee98fad1",
  "@metamask-previews/logging-controller": "6.0.4-preview-ee98fad1",
  "@metamask-previews/message-manager": "12.0.1-preview-ee98fad1",
  "@metamask-previews/multichain": "2.1.1-preview-ee98fad1",
  "@metamask-previews/multichain-transactions-controller": "0.3.0-preview-ee98fad1",
  "@metamask-previews/name-controller": "8.0.3-preview-ee98fad1",
  "@metamask-previews/network-controller": "22.2.1-preview-ee98fad1",
  "@metamask-previews/notification-services-controller": "0.20.1-preview-ee98fad1",
  "@metamask-previews/permission-controller": "11.0.6-preview-ee98fad1",
  "@metamask-previews/permission-log-controller": "3.0.3-preview-ee98fad1",
  "@metamask-previews/phishing-controller": "12.3.2-preview-ee98fad1",
  "@metamask-previews/polling-controller": "12.0.3-preview-ee98fad1",
  "@metamask-previews/preferences-controller": "15.0.2-preview-ee98fad1",
  "@metamask-previews/profile-sync-controller": "7.0.1-preview-ee98fad1",
  "@metamask-previews/queued-request-controller": "9.0.1-preview-ee98fad1",
  "@metamask-previews/rate-limit-controller": "6.0.3-preview-ee98fad1",
  "@metamask-previews/remote-feature-flag-controller": "1.4.0-preview-ee98fad1",
  "@metamask-previews/selected-network-controller": "21.0.1-preview-ee98fad1",
  "@metamask-previews/signature-controller": "23.2.1-preview-ee98fad1",
  "@metamask-previews/token-search-discovery-controller": "2.1.0-preview-ee98fad1",
  "@metamask-previews/transaction-controller": "45.1.0-preview-ee98fad1",
  "@metamask-previews/user-operation-controller": "24.0.1-preview-ee98fad1"
}

@matthewwalsh0 matthewwalsh0 marked this pull request as ready for review February 12, 2025 10:47
@matthewwalsh0 matthewwalsh0 requested review from a team as code owners February 12, 2025 10:47
@matthewwalsh0
Copy link
Member Author

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "23.0.1-preview-862b5dac",
  "@metamask-previews/address-book-controller": "6.0.3-preview-862b5dac",
  "@metamask-previews/announcement-controller": "7.0.3-preview-862b5dac",
  "@metamask-previews/approval-controller": "7.1.3-preview-862b5dac",
  "@metamask-previews/assets-controllers": "49.0.0-preview-862b5dac",
  "@metamask-previews/base-controller": "8.0.0-preview-862b5dac",
  "@metamask-previews/build-utils": "3.0.3-preview-862b5dac",
  "@metamask-previews/composable-controller": "11.0.0-preview-862b5dac",
  "@metamask-previews/controller-utils": "11.5.0-preview-862b5dac",
  "@metamask-previews/earn-controller": "0.2.1-preview-862b5dac",
  "@metamask-previews/ens-controller": "15.0.2-preview-862b5dac",
  "@metamask-previews/eth-json-rpc-provider": "4.1.8-preview-862b5dac",
  "@metamask-previews/gas-fee-controller": "22.0.3-preview-862b5dac",
  "@metamask-previews/json-rpc-engine": "10.0.3-preview-862b5dac",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.7-preview-862b5dac",
  "@metamask-previews/keyring-controller": "19.0.7-preview-862b5dac",
  "@metamask-previews/logging-controller": "6.0.4-preview-862b5dac",
  "@metamask-previews/message-manager": "12.0.1-preview-862b5dac",
  "@metamask-previews/multichain": "2.1.1-preview-862b5dac",
  "@metamask-previews/multichain-transactions-controller": "0.3.0-preview-862b5dac",
  "@metamask-previews/name-controller": "8.0.3-preview-862b5dac",
  "@metamask-previews/network-controller": "22.2.1-preview-862b5dac",
  "@metamask-previews/notification-services-controller": "0.20.1-preview-862b5dac",
  "@metamask-previews/permission-controller": "11.0.6-preview-862b5dac",
  "@metamask-previews/permission-log-controller": "3.0.3-preview-862b5dac",
  "@metamask-previews/phishing-controller": "12.3.2-preview-862b5dac",
  "@metamask-previews/polling-controller": "12.0.3-preview-862b5dac",
  "@metamask-previews/preferences-controller": "15.0.2-preview-862b5dac",
  "@metamask-previews/profile-sync-controller": "7.0.1-preview-862b5dac",
  "@metamask-previews/queued-request-controller": "9.0.1-preview-862b5dac",
  "@metamask-previews/rate-limit-controller": "6.0.3-preview-862b5dac",
  "@metamask-previews/remote-feature-flag-controller": "1.4.0-preview-862b5dac",
  "@metamask-previews/selected-network-controller": "21.0.1-preview-862b5dac",
  "@metamask-previews/signature-controller": "23.2.1-preview-862b5dac",
  "@metamask-previews/token-search-discovery-controller": "2.1.0-preview-862b5dac",
  "@metamask-previews/transaction-controller": "45.1.0-preview-862b5dac",
  "@metamask-previews/user-operation-controller": "24.0.1-preview-862b5dac"
}

@matthewwalsh0
Copy link
Member Author

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "23.0.1-preview-f51ef7f8",
  "@metamask-previews/address-book-controller": "6.0.3-preview-f51ef7f8",
  "@metamask-previews/announcement-controller": "7.0.3-preview-f51ef7f8",
  "@metamask-previews/approval-controller": "7.1.3-preview-f51ef7f8",
  "@metamask-previews/assets-controllers": "49.0.0-preview-f51ef7f8",
  "@metamask-previews/base-controller": "8.0.0-preview-f51ef7f8",
  "@metamask-previews/build-utils": "3.0.3-preview-f51ef7f8",
  "@metamask-previews/composable-controller": "11.0.0-preview-f51ef7f8",
  "@metamask-previews/controller-utils": "11.5.0-preview-f51ef7f8",
  "@metamask-previews/earn-controller": "0.2.1-preview-f51ef7f8",
  "@metamask-previews/ens-controller": "15.0.2-preview-f51ef7f8",
  "@metamask-previews/eth-json-rpc-provider": "4.1.8-preview-f51ef7f8",
  "@metamask-previews/gas-fee-controller": "22.0.3-preview-f51ef7f8",
  "@metamask-previews/json-rpc-engine": "10.0.3-preview-f51ef7f8",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.7-preview-f51ef7f8",
  "@metamask-previews/keyring-controller": "19.0.7-preview-f51ef7f8",
  "@metamask-previews/logging-controller": "6.0.4-preview-f51ef7f8",
  "@metamask-previews/message-manager": "12.0.1-preview-f51ef7f8",
  "@metamask-previews/multichain": "2.1.1-preview-f51ef7f8",
  "@metamask-previews/multichain-transactions-controller": "0.3.0-preview-f51ef7f8",
  "@metamask-previews/name-controller": "8.0.3-preview-f51ef7f8",
  "@metamask-previews/network-controller": "22.2.1-preview-f51ef7f8",
  "@metamask-previews/notification-services-controller": "0.20.1-preview-f51ef7f8",
  "@metamask-previews/permission-controller": "11.0.6-preview-f51ef7f8",
  "@metamask-previews/permission-log-controller": "3.0.3-preview-f51ef7f8",
  "@metamask-previews/phishing-controller": "12.3.2-preview-f51ef7f8",
  "@metamask-previews/polling-controller": "12.0.3-preview-f51ef7f8",
  "@metamask-previews/preferences-controller": "15.0.2-preview-f51ef7f8",
  "@metamask-previews/profile-sync-controller": "7.0.1-preview-f51ef7f8",
  "@metamask-previews/queued-request-controller": "9.0.1-preview-f51ef7f8",
  "@metamask-previews/rate-limit-controller": "6.0.3-preview-f51ef7f8",
  "@metamask-previews/remote-feature-flag-controller": "1.4.0-preview-f51ef7f8",
  "@metamask-previews/selected-network-controller": "21.0.1-preview-f51ef7f8",
  "@metamask-previews/signature-controller": "23.2.1-preview-f51ef7f8",
  "@metamask-previews/token-search-discovery-controller": "2.1.0-preview-f51ef7f8",
  "@metamask-previews/transaction-controller": "45.1.0-preview-f51ef7f8",
  "@metamask-previews/user-operation-controller": "24.0.1-preview-f51ef7f8"
}

log('Retrieved feature flags', featureFlags);

return featureFlags as TransactionControllerFeatureFlags;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking for this PR, but I have a doubt if it is ok to use launchdarkly to dynamically get data like this. May be we make our own api for the purpose.

Also, is there a plan at what stage we get rid of using feature flags for this functionality.

Copy link
Member Author

@matthewwalsh0 matthewwalsh0 Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not dynamically getting data, it's still reliant on the polling that is controlled by the client, so it won't fire a request for each usage.

Both of these usages are also still conceptually "feature flags" as the supported chains are a means to enable the feature progressively as each chain adds support.

Similarly, the contract addresses are a means to "release" new contracts for the user to upgrade to.

Even if they were purely for remote configuration, I think we've been doing this for even longer than feature flags through swaps and smart transactions. Why would we create our own service and infrastructure, and client logic, to achieve what is already possible with one platform?

There is no plans to remove this functionality in future since it's a key part of the management, and security model.

import {
getEIP7702ContractAddresses,
getEIP7702SupportedChains,
} from './feature-flags';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: sorting imports

return {
batchId,
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look like utility function, may be it should have been part of controller itself. Also, does not look a good practice to pass functions, messenger to utility function like above.

Copy link
Member Author

@matthewwalsh0 matthewwalsh0 Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main TransactionController file is almost 4000 lines long so this is a fundamental part of our controller architecture to modularise functionality in order to keep it readable, maintainable, and testable.

The practice of passing callbacks and the messenger itself is well established as it's the same as what we do with the controllers themselves in the client, it provides a clean abstraction to provide logic in a decoupled way without duplication or unnecessarily coupling distinct pieces of logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants