FAQs
userOperation
How can I track the status of a userOp?
To understand the status of a userOp you can use the eth_getUserOperationByHash
method as follows: loop over eth_getUserOperationByHash
for as long as you are willing to wait for the userOp to land. If it still returns null
after the timeout, there are two possibilities:
- The userOp is still pending: This is the most common scenario and typically means the fees are too low. In this case, you should drop and replace the userOp with higher fees.
- The userOp has been dropped: The most common (but rare) reason is that they paymaster signature has expired. However, this should rarely happen if you set a reasonable sponsorship expiry time, unless there is a significant delay in sending the userOp after the paymaster signs it.
How can I get push notifications for mined userOps?
Follow the guide on using custom webhooks to get real time alerts and receipts for mined userOperations
.
How do I get my userOp unstuck from the mempool?
For EIP-1559 fee markets, the base fee is fixed per block. To prioritize the inclusion of your userOp and get it unstuck from the mempool, you need to increase the maxPriorityFeePerGas
. This can be achieved by dropping and replacing the userOp with a new one that has a higher maxPriorityFeePerGas
.
Can a userOp be accepted by the bundler and then dropped while it’s in the mempool?
This is a possible but rare scenario and can occur due to several reasons:
- The userOp is replaced by another userOp from the same sender with the same nonce.
- The signature of the Gas Manager has expired, rendering the userOp ineligible for sponsorship.
- The validation function of the userOp fails when it is being bundled into a transaction for on-chain submission.
- The mempool runs out of memory, causing the bundler to drop userOps with the lowest fees.
Can I retrieve the hash of the bundle transaction right after calling eth_sendUserOperation
without waiting for the transaction to get mined?
The transaction hash is not included in the response of eth_sendUserOperation
for the following reasons:
- The hash of the bundle transaction that a userOp is included in can change before that userOp is mined. This can happen for multiple reasons, such as the pending bundle transaction being dropped and replaced by the bundler if it’s underpriced, or the bundle transaction being frontrun by another bundle that includes the userOp.
- Adding the transaction hash to the response of
eth_sendUserOperation
is incompatible with the future P2P mempool, since any bundler can bundle the userOp and land it on chain.
Common Errors
What are precheck failed
errors and how do I handle them?
precheck failed
errors are typically related to gas and/or fees. Our bundler follows the standard ERC 4337 implementation for gas and fee checks to 1) ensure your userOp lands on chain and to 2) protect the bundler from potential attacks in order to support scalability.
These errors are often related to market movement between the time gas and fees are estimated and the time when userOps are submitted to the bundler. This issue is especially prevalent on testnets. Our bundler currently rejects upon sending userOps if they are underpriced compared to the network rate to ensure inclusion in a block.
To handle these errors, you should:
- add buffers on top of our gas estimates to account for market fluctuations
- implement retry mechanisms.
What is a Replacement Underpriced
error and how can I resolve it?
You might get a "Replacement Underpriced Error"
when using eth_sendUserOperation
. This error occurs when a user already has an existing userOp in the mempool. userOps can become “stuck” in the mempool if their gas fee limits are too low to be included in a bundle.
To resolve this, you need to increase both maxFeePerGas
and maxPriorityFeePerGas
by at least 10%.
To do so, follow the next steps:
-
Re-estimate gas fees: This can be done in various ways which are mentioned below:
- Use the
eth_maxPriorityFeePerGas
method to obtainmaxPriorityFeePerGas
. - If using the Alchemy SDK, use the
getFeeData
method to obtain both the currentmaxPriorityFeePerGas
andmaxFeePerGas
. This method is also available on web3 libraries likeethers.js
and can be accessed through the provider asprovider.getFeeData()
.
- Use the
-
Choose the suitable increase values: Once you have the re-estimated gas fees, choose the maximum of a 10% increase or the re-estimated values. This ensures that your new gas fee is competitively priced to be included in a block.
-
Account for Rundler’s service tip: Rundler requires a small tip for its services via
maxPriorityFeePerGas
. Detailed information about this can be found below.
After calculating the new values, send your userOp
again with the updated fees and it should go through successfully.
Signatures
What is a dummy signature?
Our APIs are compatible with any type of smart account. This means regardless of the smart account you’re using, our endpoints will work with it. However, different smart accounts have unique ways of signing transactions, known as signature patterns. A dummy signature is essentially a template or example signature that aligns with the signature pattern of your specific account type.
For certain API endpoints (ex: eth_estimateUserOperationGas), particularly those involved in gas estimation, a dummy signature is required in the request. This is because these endpoints need to simulate or estimate the transaction without actually executing it, and the dummy signature helps in this process.
Fees
What are the bundler fees?
To provide its services, Alchemy’s Rundler requires fees when using eth_sendUserOperation
, and these fees differ based on the mainnet or testnet in use. Rundler’s requirements for priority fees are expressed via the rundler_maxPriorityFeePerGas
endpoint.
Each Bundler API endpoint has an associated compute unit cost.
The following table provides a detailed breakdown of the fee logic and recommendations for each network type:
Recommended Actions for Calculating maxFeePerGas
:
-
Fetch Current Base Fee: Use the method
eth_getBlockByNumber
with the'latest'
parameter to get the currentbaseFeePerGas
. -
Apply Buffer on Base Fee: To account for potential fee changes, apply a buffer on the current base fee based on the requirements and recommendations in the table shown above. (27% is the minimum for bundler acceptance, but we recommend at least 50%)
-
Fetch Current Priority Fee with Rundler: Use the
rundler_maxPriorityFeePerGas
method to query the current priority fee for the network. -
Apply Buffer on Priority Fee: Once you have the current priority fee using
rundler_maxPriorityFeePerGas
, increase it according to the fee requirement table shown above for any unexpected changes (No buffer for Arbitrum Mainnet and 25% buffer for all other mainnets). -
Determine
maxFeePerGas
: Add the buffered values from steps 2 and 4 together to obtain themaxFeePerGas
for your user operation.
The Alchemy bundler requires the simulated gas limit efficiency of both a UO’s pre-operation gas and call gas to be greater than or equal to 15%. (Note: the 15% efficiency value is subject to change and we will update docs if it does.)
Gas limit efficiency = gas used / gas limit
Pre-operation gas = preVerificationGas
+ verificationGasLimit
+ paymasterVerificationGasLimit
Note: for EP v0.6 paymasterVerificationGasLimit
== verificationGasLimit
This check is intended to prevent user operations from taking up gas limit space in a bundle, but then not using the gas on-chain. This could prevent other UO’s from being bundled that otherwise could have. It is recommended to use the results from the eth_estimateUserOperationGas
endpoint, with slight buffers if desired while keeping above 15% efficiency.
It’s recommended to use our Account Kit SDK to minimize the complexities of estimating userOp gas fees.
How do we determine fee values to give your userOp the best chance of landing on chain?
-
alchemy_requestGasAndPaymasterAndData is on opinionated endpoint that tries to set fee values that give your userOps a high chance of landing on-chain. It’s likely that we’re over-estimating here a bit, but this is intentional in order to land your UOs faster!
-
We encourage you to try out different fee percentages and determine what works best for you as a balance between cost and chance/time to mine.
-
For alchemy_requestGasAndPaymasterAndData we offer the ability to override our fee estimates with the
feeOverride
parameters.- We default to increasing baseFee by 50% and priorityFee by 5%.
- Note: The feeOverride parameters don’t include preVerificationGas (PVG). The method will always increase the estimated PVG by 5% to give the UO a better chance to mine if the L1 /L2 fee ratio changes. If you would like to modify this value, its recommended you use alchemy_requestPaymasterAndData instead.
EntryPoint
Which EntryPoint version should I use, v0.6 or v0.7?
The latest version of ERC-4337 is v0.7, which introduces optimizations aimed at improving the experience for both developers and end users. These include gas savings for users, optimized data structures, better gas estimation, simplified postOp logic, and structured errors during validation.
The appropriate version to use is determined by the smart contract account for which you are trying to send a userOp. Typically, a smart contract account will be written to be compatible with either v0.6 or v0.7. To determine which version is compatible, you should look at the smart contract account’s source code and check the first parameter of the validateUserOp
function. If it has type UserOperation
, the account uses v0.6. If the parameter type is PackedUserOperation
, the account uses v0.7.
For more information about the differences between the versions, refer to the specifications for ERC-4337 v0.6.0 and ERC-4337 v0.7.0, particularly the description of the user operation fields.
At which addresses are the EntryPoint contracts for v0.6 and v0.7 deployed?
The EntryPoint contracts for v0.6 and v0.7 are deployed at the following addresses across all chains supported by Alchemy:
EntryPoint v0.7: 0x0000000071727De22E5E9d8BAf0edAc6f37da032
EntryPoint v0.6: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
When will EntryPoint v0.6 be deprecated?
We plan to deprecate support for EntryPoint v0.6 in September 2025. Please ensure that you have migrated to EntryPoint v0.7 by that time. If you have any questions or need assistance with the migration process, please file a ticket via our Discord server.