ERC-6900: Modular Smart Account Standard for the Next Generation of Wallets
A technical deep dive into ERC-6900, the modular plugin standard for smart accounts that makes wallet functionality composable and upgradeable.
The Problem with Monolithic Smart Accounts
ERC-4337 introduced smart contract wallets. But early smart account implementations were monolithic — the wallet logic was baked into a single contract. Want to add a new authentication method? Deploy a new account. Want to add a spending limit module? Deploy a new account. Each new feature required users to migrate to a new contract and a new address.
ERC-6900 solves this with a plugin architecture for smart accounts. Account functionality is split into modular plugins: validation plugins (who can authorize transactions), execution plugins (what new functions the account can perform), and hooks (custom logic before and after calls). Plugins can be installed and uninstalled without migrating the account.
This turns smart accounts into composable, upgradeable wallets where functionality can be added like apps on a smartphone. The account address is permanent — only the behavior changes as plugins are installed and removed.
ERC-6900 Architecture: Account, Validation, and Execution
ERC-6900 defines three types of interfaces:
IModularAccount: the base account interface. Defines installPlugin(), uninstallPlugin(), executeWithAuthorization(). The account maintains a list of installed plugins and routes calls to the appropriate plugin.
IValidationModule: implements validation logic. When the account receives a UserOperation or a direct call, it invokes the installed validation modules to check authorization. Common validation modules: single-owner ECDSA, multi-sig, passkey/WebAuthn, session keys with spend limits.
IExecutionModule: adds new function selectors to the account. When someone calls an unknown function on the account, it checks execution modules for a matching selector. This allows plugins to add new capabilities — a DCA (dollar cost averaging) plugin adds a executeScheduledDCA() function. A governance plugin adds executeVote().
Hook plugins: IPreUserOpValidationHook, IPostExecutionHook. These wrap calls before and after execution. Use cases: rate limiting, logging, fee collection, MEV protection.
Plugin manifest: every plugin declares what selectors it implements, what permissions it needs, and what dependencies it requires. The account checks the manifest before installation to ensure compatibility.
Building an ERC-6900 Plugin
A session key plugin as a practical example:
The plugin allows the account owner to grant a limited-permission key to a dApp for a set duration with a spending cap. The dApp can submit transactions on behalf of the user without full wallet access.
Plugin state (stored in the plugin contract):
mapping(address account => mapping(address sessionKey => SessionKeyData)) sessionKeys;
Where SessionKeyData includes: expiry timestamp, allowed contract addresses, allowed function selectors, remaining spend cap.
onInstall(bytes data): called when the account installs the plugin. Decode data to get initial session key parameters. Store in plugin state using account as the key.
validateUserOp: check if the UserOperation signer is an authorized session key for the account. Verify the session has not expired, the target is in the allowed list, and the spend cap has not been exceeded. Decrement the spend cap.
onUninstall(): clean up all session keys for this account.
Plugin manifest: declare that this plugin handles validation for UserOperations signed by session keys. Declare it requires no execution permissions (it only validates).
ERC-6900 vs ERC-7579: The Standards Landscape
ERC-6900 is not the only modular account standard. ERC-7579 (Minimal Modular Smart Accounts) emerged as a competing — or complementary — standard with a simpler interface aimed at maximum implementation compatibility.
Key differences:
ERC-6900 is more opinionated: it defines a specific plugin manifest format, specific hook types, and specific routing rules. This enables richer composability but requires more implementation work.
ERC-7579 is minimal: it defines just enough interface for modules to be interoperable across different account implementations. A 7579 executor module works with any 7579-compliant account regardless of how the account is implemented internally.
The consensus in 2026: ERC-7579 for basic module interoperability; ERC-6900 for rich plugin ecosystems with complex dependency and hook systems. Alchemy's Modular Account implements ERC-6900. Biconomy's Nexus and ZeroDev's Kernel implement ERC-7579.
For plugin developers: implement ERC-7579 as a baseline and add ERC-6900 compatibility on top. This maximizes the number of accounts your plugin can be installed on.
Deploying and Auditing Modular Accounts
Modular accounts introduce new security considerations that monolithic accounts do not have.
Plugin installation security: the onInstall function runs with the account's execution context. A malicious plugin installed by a compromised key could drain the account. Implement allowlists for trusted plugins, or require multi-sig approval for plugin installation.
Plugin interaction attacks: two legitimate plugins can have unexpected interactions when combined. A spending limit plugin and a DEX trading plugin might conflict — the DEX plugin spends tokens in a way the spending limit plugin does not track. Audit plugin combinations, not just individual plugins.
Reentrancy through hooks: postExecutionHooks run after the main call. If the main call sends ETH and a hook then makes another external call, reentrancy is possible. Apply reentrancyGuard at the account level for all hooks.
Plugin upgrade paths: if a plugin needs to be updated, the flow is: install new plugin version, migrate state, uninstall old plugin. Design plugins with state migration in mind from the beginning.
Testing modular accounts: use the Reference Implementation from the ERC-6900 repository as a base. Write integration tests that install combinations of plugins and verify they behave correctly together. Fuzz with random plugin installation/uninstallation sequences and verify the account remains functional.