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.
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.
EntryPoint
in a single handleOps
call.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.
bytes
block (e.g. empty initCode
) MUST be set to "0x"
\EntryPoint
contract address the request should be sent through.\
This MUST be one of the entry points returned by the supportedEntryPoints
RPC call.userOpHash
for iterror
result object, with code
and message
.\
The error code and message SHOULD be set as follows:UserOperation
struct/fieldsEntryPoint
contract's simulateValidation
function
during wallet creation or validationmessage
field MUST be set to the emitted FailedOp
event's "AAxx
" error message from the EntryPoint
paymaster
contract's validatePaymasterUserOp
functionmessage
field SHOULD be set to the revert message from the paymaster
contractdata
field MUST contain a paymaster
valuedata
field SHOULD contain the validUntil
and validAfter
valuesdata
field SHOULD contain a paymaster
address if this error was triggered by the paymaster
contractpaymaster
is throttled or banned due to ERC-7562 reputation rulesdata
field SHOULD contain a paymaster
addresspaymaster
contract's ERC-7562 stake or unstake-delay is too lowdata
field SHOULD contain a paymaster
addressdata
field SHOULD contain a minimumStake
and minimumUnstakeDelay
UserOperations
.Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_sendUserOperation",
"params": [
{
eip7702Auth, // an EIP-7702 authorization tuple
sender, // address
nonce, // uint256
factory, // address
factoryData, // bytes
callData, // bytes
callGasLimit, // uint256
verificationGasLimit, // uint256
preVerificationGas, // uint256
maxFeePerGas, // uint256
maxPriorityFeePerGas, // uint256
paymaster, // address
paymasterVerificationGasLimit, // uint256
paymasterPostOpGasLimit, // uint256
paymasterData, // bytes
signature // bytes
},
entryPoint // address
]
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x123456789012345678901234567890123456789012345678901234567890abcd"
}
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"message": "AA21 didn't pay prefund",
"code": -32500
}
}
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"message": "paymaster stake too low",
"data": {
"paymaster": "0x123456789012345678901234567890123456790",
"minimumStake": "0xde0b6b3a7640000",
"minimumUnstakeDelay": "0x15180"
},
"code": -32504
}
}
On networks with EIP-7702 activated, the UserOperation
object may also contain an eip7702Auth
tuple.
Notice that according to EIP-7702 an eip7702Auth
tuple must be provided only to perform a change of the authorization address.
Once the necessary eip7702Auth
tuple was stored on-chain,
users are not required to provide the same eip7702Auth
tuple for any consequent
UserOperation
.
Separately, the fields factory
and factoryData
have a modified behaviour when using an EIP-7702 authorized sender
.
The factory
field SHOULD be set to exactly the INITCODE_EIP7702_MARKER = 0x7702
flag when using an EIP-7702 authorized sender
.
Passing his flag instructs the EntryPoint
contract to verify the sender
address contains a valid EIP-7702 authorization.
When INITCODE_EIP7702_MARKER
is specified, the factoryData
value is passed directly to the sender
contract,
instead of the factory
contract.
This is done as a separate call before the validateUserOp
is called,
meaning the sender
contract will be called two times during validation.
The factoryData
value can be left empty. In this case, the call will not be performed.
The purpose of this factoryData
call is to provide the EIP-7702 sender
contract an ability to initialize its
storage before accepting the UserOperation
via the validateUserOp
function.
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.
If the UserOperation contains an eip7702Auth
tuple, for the purpose of estimation the signature should be ignored, and the tuple should be evaluated as if it was signed by the sender
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:
UserOperation
UserOperation
UserOperation
specifies a Paymaster
addressNote: actual postOpGasLimit
cannot be reliably estimated.\
Paymasters should provide this value to account, and require that specific value on-chain during validation.
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.
Return a UserOperation
object based on a userOpHash
value returned by eth_sendUserOperation
.
Parameters
userOpHash
value returned by eth_sendUserOperation
Return value:
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:
null
Return a UserOperation
receipt object based on a userOpHash
value returned by eth_sendUserOperation
.
Parameters
userOpHash
value returned by eth_sendUserOperation
Return value:
null
in case the UserOperation
is not yet included in a block, or:
UserOperation
UserOperation
, including pre-verification, creation, validation and executionUserOperation
, the returned revert reason byte arrayUserOperation
, not including logs of other UserOperations
in the same bundleTransactionReceipt
object.
Note that the returned TransactionReceipt
is for the entire bundle, not only for this UserOperation
.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.
```json=
{ "jsonrpc": "2.0", "id": 1, "method": "eth_supportedEntryPoints", "params": [] }
{ "jsonrpc": "2.0", "id": 1, "result": [ "0xcd01C8aa8995A59eB7B2627E69b40e0524B5ecf8", "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6" ] }
#### eth_chainId
Returns [EIP-155](/eips/eip-155.html) Chain ID.
```json=
# Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_chainId",
"params": []
}
# Response
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x1"
}
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.
Clears the bundler mempool and reputation data of paymasters/accounts/factories.
# Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "debug_bundler_clearState",
"params": []
}
# Response
{
"jsonrpc": "2.0",
"id": 1,
"result": "ok"
}
Dumps the current UserOperation
mempool
Parameters:
eth_sendUserOperation
Returns:
array
- Array of UserOperation
objects currently in the mempool.
```json=
{ "jsonrpc": "2.0", "id": 1, "method": "debug_bundler_dumpMempool", "params": ["0x1306b01bC3e4AD202612D3843387e94737673F53"] }
{ "jsonrpc": "2.0", "id": 1, "result": [ { sender, // address nonce, // uint256 factory, // address factoryData, // bytes callData, // bytes callGasLimit, // uint256 verificationGasLimit, // uint256 preVerificationGas, // uint256 maxFeePerGas, // uint256 maxPriorityFeePerGas, // uint256 signature // bytes } ] }
#### debug_bundler_sendBundleNow
Forces the bundler to build and execute a bundle from the mempool as `handleOps()` transaction.
Returns: `transactionHash`
```json
# Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "debug_bundler_sendBundleNow",
"params": []
}
# Response
{
"jsonrpc": "2.0",
"id": 1,
"result": "0xdead9e43632ac70c46b4003434058b18db0ad809617bd29f3448d46ca9085576"
}
Sets bundling mode.
After setting mode to "manual", an explicit call to debug_bundler_sendBundleNow
is required to send a bundle.
mode
- 'manual' | 'auto'
```json=
{ "jsonrpc": "2.0", "id": 1, "method": "debug_bundler_setBundlingMode", "params": ["manual"] }
{ "jsonrpc": "2.0", "id": 1, "result": "ok" }
#### debug_bundler_setReputation
Sets the reputation of given addresses.
**Parameters:**
* An array of reputation entries to add/replace, 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 operations that use this entity was included on-chain
* **EntryPoint** the entrypoint used by `eth_sendUserOperation`
```json=
# Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "debug_bundler_setReputation",
"params": [
[
{
"address": "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6",
"opsSeen": "0x14",
"opsIncluded": "0x0D"
}
],
"0x1306b01bC3e4AD202612D3843387e94737673F53"
]
}
# Response
{
"jsonrpc": "2.0",
"id": 1,
"result": "ok"
}
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:
eth_sendUserOperation
Return value:
An array of reputation entries with the fields:
address
- the address to set the reputation foropsSeen
- number of times a user operations with that entity was seen and added to the mempoolopsIncluded
- number of times user operation that use this entity was included on-chainstatus
- (string) The status of the address in the bundler ('ok'
| 'throttled'
| 'banned'
)```json=
{ "jsonrpc": "2.0", "id": 1, "method": "debug_bundler_dumpReputation", "params": ["0x1306b01bC3e4AD202612D3843387e94737673F53"] }
{ "jsonrpc": "2.0", "id": 1, "result": [ { "address": "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6", "opsSeen": "0x14", "opsIncluded": "0x13", "status": "ok" } ] }
#### debug_bundler_addUserOps
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.
**Parameters:**
* An array of `UserOperation` objects
```json=
# Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "debug_bundler_addUserOps",
"params": [
[
{ sender: "0xa...", ... },
{ sender: "0xb...", ... }
]
]
}
# Response
{
"jsonrpc": "2.0",
"id": 1,
"result": "ok"
}
This proposal defines a new JSON-RPC API standard that does not pose any backwards compatibility challenges.
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.
debug
API in production serversThe 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.
Copyright and related rights waived via CC0.