Defines new JSON-RPC API methods which enable ERC-4337 wallets to communicate with UserOpeation mempool
nodes and bundlers, matching the functionality that exists for Ethereum transactions.
Additionally, a set of debug JSON-RPC API methods is defined in order to facilitate development, testing and
debugging issues with ERC-4337 implementations.
Motivation
In ERC-4337, user transactions as defined in Ethereum are replaced with UserOperation objects, which contain all the
information needed to perform the operations requested by the users.
However, existing Ethereum JSON-RPC API methods are not suited to working with UserOperation objects.
In order to facilitate the operation of the alternative UserOperation mempool it is important that all
implementations of the ERC-4337 protocol have a standardized set of APIs that can be used interchangeably.
Specification
Definitions
bundler: a node exposing the APIs, in order to submit them to the network.
A bundler collects one or more UserOperations into a bundle and submits them together to
the EntryPoint in a single handleOps call.
RPC methods (eth namespace)
eth_sendUserOperation
The eth_sendUserOperation method submits a UserOperation object to the UserOperation mempool.
The client MUST validate the UserOperation, and return a result accordingly.
The result SHOULD be set to the userOpHash if and only if the request passed simulation and was accepted
in the client’s UserOperation pool.
If the validation, simulation, or UserOperation pool inclusion fails,
userOpHash SHOULD NOT be returned. Rather, the client SHOULD return the failure reason.
Parameters:
UserOperation a full user-operation struct.
All fields MUST be set as hex values.
Empty bytes block (e.g. empty initCode) MUST be set to "0x"\
factory and factoryData
Must provide either both of these parameters, or none.
paymaster, paymasterData, paymasterValidationGasLimit, paymasterPostOpGasLimit
Must provide either all of these parameters, or none.
entryPoint the EntryPoint contract address the request should be sent through.
This MUST be one of the entry points returned by the supportedEntryPoints RPC call.
Return value:
If the UserOperation is valid, the client MUST return the calculated userOpHash for it
in case of failure, MUST return an error result object, with code and message.
The error code and message SHOULD be set as follows:
{"jsonrpc":"2.0","id":1,"error":{"message":"paymaster stake too low","data":{"paymaster":"0x123456789012345678901234567890123456790","minimumStake":"0xde0b6b3a7640000","minimumUnstakeDelay":"0x15180"},"code":-32504}}
* eth_estimateUserOperationGas
Estimate the gas values for a UserOperation.
Given UserOperation optionally without gas limits and gas prices, return the needed gas limits.
The signature field is ignored by the wallet, so that the operation will not require the user’s approval.
Still, it might require putting a “stub” signature value, e.g. a signature byte array of the right length.
Parameters:
Same as eth_sendUserOperation
All gas limits and fees parameters are optional, but are used if specified. maxFeePerGas and maxPriorityFeePerGas default to zero, so no payment is required by neither account nor paymaster.
Optionally accepts the State Override Set to allow users to modify the state during the gas estimation.
This field as well as its behavior is equivalent to the ones defined for eth_call RPC method.
Return Values:
preVerificationGas gas overhead of this UserOperation
verificationGasLimit estimation of gas limit required by the validation of this UserOperation
paymasterVerificationGasLimit estimation of gas limit required by the paymaster verification
Returned only if the UserOperation specifies a Paymaster address
callGasLimit estimation of gas limit required by the inner account execution
Note: actual postOpGasLimit cannot be reliably estimated.
Paymasters should provide this value to account, and require that specific value on-chain during validation.
Error Codes:
Same as eth_sendUserOperation
This operation may also return an error if either the inner call to the account contract reverts,
or paymaster’s postOp call reverts.
* eth_getUserOperationByHash
Return a UserOperationobject based on a userOpHash value returned by eth_sendUserOperation.
Parameters
hash a userOpHash value returned by eth_sendUserOperation
Return value:
If the UserOperation is included in a block:
Return a full UserOperation, with the addition of entryPoint, blockNumber, blockHash and transactionHash.
Else if the UserOperation is pending in the bundler’s mempool:
MAY return null, or a full UserOperation, with the addition of the entryPoint field and a null value for blockNumber, blockHash and transactionHash.
Else:
Return null
* eth_getUserOperationReceipt
Return a UserOperation receipt object based on a userOpHash value returned by eth_sendUserOperation.
Parameters
hash a userOpHash value returned by eth_sendUserOperation
Return value:
null in case the UserOperation is not yet included in a block, or:
userOpHash the request hash
entryPoint
sender
nonce
paymaster the paymaster used for this userOp (or empty)
actualGasCost - the actual amount paid (by account or paymaster) for this UserOperation
actualGasUsed - total gas used by this UserOperation, including pre-verification, creation, validation and execution
success boolean - whether this execution completed without a revert
reason - in case of reverted UserOperation, the returned revert reason byte array
logs - the logs generated by this particular UserOperation, not including logs of other UserOperations in the same bundle
receipt the TransactionReceipt object.
Note that the returned TransactionReceipt is for the entire bundle, not only for this UserOperation.
* eth_supportedEntryPoints
Returns an array of the EntryPoint contracts’ addresses supported by the client.
The first element of the array SHOULD be the EntryPoint contract addressed preferred by the client.
This api must only be available in testing mode and is required by the compatibility test suite.
In production, any debug_* rpc calls should be blocked.
* debug_bundler_clearState
Clears the bundler mempool and reputation data of paymasters/accounts/factories.
Returns the reputation data of all observed addresses.
Returns an array of reputation objects, each with the fields described above in debug_bundler_setReputation.
Parameters:
EntryPoint the entrypoint used by eth_sendUserOperation
Return value:
An array of reputation entries with the fields:
address - the address to set the reputation for
opsSeen - number of times a user operations with that entity was seen and added to the mempool
opsIncluded - number of times user operation that use this entity was included on-chain
status - (string) The status of the address in the bundler ('ok'
Inject UserOperation objects array into the mempool.
Assume the given UserOperation objects all pass validation without actually validating them,
and accept them directly into the mempool.
explicit debug functions: bundlers are required to provide a set of debug functions, so that the “bundler specification test suite” can be used to verify its adherance to the spec.
Backwards Compatibility
This proposal defines a new JSON-RPC API standard that does not pose any backwards compatibility challenges.
Security Considerations
Preventing DoS attacks on UserOperation mempool
Operating a public production ERC-4337 node is a computationally intensive task and may be a target of a DoS attack.
This is addressed by the ERC-7562 validation rules, which defines a way for the ERC-4337 node to track participants’
reputation as well as preventing nodes from accepting maliciously crafted UserOperations.
It is strictly recommended that all ERC-4337 nodes also implement ERC-7562 validation rules to minimize DoS risks.
Disabling debug API in production servers
The API defined in the debug namespace is not intended to ever be publicly available.
Production implementations of ERC-4337 must never make it available by default,
and in fact enabling it should result in a clear warning of the potential dangers of exposing this API.