Skip to content

Frequently asked questions

Smart Accounts - Light Account

Do accounts have the same address across all chains?


In almost all cases, yes, you will get the same address on all chains as long as the connecting signer address is the same! The deployment address is a function of the address of owner/signer address, the account implementation (e.g. latest version of Light Account), and the salt (you can optionally specify this). If all three of those remain the same, then you deploy the smart account at the same contract address.

There are two scenarios where you would get a different contract address:

  1. If you deploy one smart account, then change the signer, then deploy the second account.
  2. If you upgrade the smart account (e.g. to a new version of Light Account). It is unlikely that we will make many updates to this contract so the address will not change frequently.

How does a smart account get deployed?


Your smart account will be deployed when the first UserOperation (UO) is sent from the account. The first UO must be sent with a non-zero initCode. aa-sdk will handle generation of this initCode for you using getAccountInitCode.

How can I upgrade a Light Account?


It is unlikely you will need to frequently update the Light Account contract itself, however it is possible if needed. Light Account has UUPSUpgradeable which adds upgrade methods on the account itself. To upgrade an account you will need to send a UserOperation using the method upgradeTo or upgradeToAndCall, depending on whether or not you need to initialize the new implementation.

Can I have multiple accounts for the same signer address? / How do I set the value of the salt for Light Account?


Yes! The optional salt value on Light Account enables the ability to have multiple accounts under a single signer. This value defaults to 0. You can set it when you create light account.

How can I upgrade from Simple Account to Light Account?


Simple Account's support upgradeToAndCall implemented by openzeppelin UUPSUpgradeable contract. This allows you to upgrade from Simple Account to Light Account without changing the smart contract account address. Using upgradeToAndCall will update the underlying implementation contract on the account while the account address and assets will stay the same.

You can call upgradeToAndCall on the Simple Account with these params:

  • newImplementation: Latest LightAccount implementation address (found here - make sure to use the implementation address, not the factory address)
    • For example LightAccount v1.1.0 - 0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba
  • data: encoded version of the initialize function with anOwner parameter set to the owner on the account, usually the same owner as what the account used as Simple Account.
    • In solidity (foundry) you can use abi.encodeCall and in viem you can use encodeFunctionData

It is very important that the initialize step is encoded correctly to ensure the account does not get into a risky state where someone else could call initialize on it with one's signer and take control of your account. You can call owner() on the account after the upgrade to ensure it is assigned correctly.

This can be called on the existing smart contract account by sending a user operation that calls execute (or executeBatch) and has that call upgradeToAndCall (the same way you would make the account send calls to other addresses).

Submitting UserOperations

How does the speed of UserOperations compare to normal transactions?


If the UserOperation (meta-transaction for 4337 accounts) is correctly priced and submitted a few hundred milliseconds prior to a new block getting created, it will typically get placed in the next block. This is because the Bundler needs time to create/propagate its transaction. You can think of it as 1 extra block time worth of latency, but we are working towards improving this latency.

Why am I seeing a delay in landing UserOperations on-chain?


This can happen when UserOperations (UOs) become underpriced, frequently due to fee market movement between when gas and fees are estimations and when the UO is actually submitted.

You may experience this when calling the waitForUserOperationTransaction method. It may throw an error if it does not find the UO in a mined Transaction within its retry limits.

You can mitigate this by defining a more flexible retry period when constructing a Client (i.e. txMaxRetries, txRetryIntervalMs, txRetryMultiplier in opts). If your UO continues to be delayed beyond a limit you are willing to wait, you can resubmit it using dropAndReplaceUserOperation.

Are UserOperations protected from MEV bots?


Right now, UserOperations are sent to a private mempool for all networks other than Polygon, where there is no way to do this. We are actively involved in proposals for a peer-to-peer mempool standard.

Can I simulate UserOperations the same way I simulate transactions?


Yes! Check out this guide.

Gas Estimation

How does gas estimation for 4337 smart contract accounts work?


Our bundler estimates gas and submits UserOperations (UOs) under the hood of the aa-sdk. Our gas estimations are just that, estimations that optimize for UOs landing on chain, and you may need to adjust gas limits based on your needs using overrides.

Learn more about gas estimation and how it is implemented in our Bundler.

There are many nuances and edge cases that our bundler considers especially for L2’s. Learn more here.

We recommend adding error handling when sending a UO to handle potential gas and fee changes due to market movement. Learn more about frequent errors.

Gas Manager

What tiers support gas sponsorship?


Gas sponsorship is available on testnet for all tiers. For support on mainnet, you must be on a paying tier (i.e. Growth tier and above). Learn more about our different pricing tiers here.

How is gas sponsored? Do I need to fund the Gas Manager?


We front the gas for your application and put the USD equivalent on your bill at the end of the month. No need to worry about pre-funding the Gas Manager or conversions, we’ve got you covered! You can follow this guide for more details on how to sponsor UserOperations.

What are my gas sponsorship limits?


You can find details of Gas Manager limits depending on your tier here.

Do you support ERC-20 or stablecoin paymasters?


Currently, we don’t support this, but we are actively exploring. Please reach out if you are interested as we would love your input in our spec.

How is the Gas Manager protected from DDOS attacks?


In your Gas Manager policy, you can configure spending rules per address, per app, and/or policy wide limits. See how to set up these policies here.

Common Errors {#common-errors}

Invalid policy ID: { code: -32602, message: 'Invalid Policy ID' }


Gas Manager policies can only be tied to one app. Make sure you are using the API Key that is associated with the app the Gas Manager policy is configured for, or create a new policy for the app you are using.

Precheck failed: { code: -3200, message: 'precheck failed: ...' }


Precheck failed errors are often related to gas and/or fees. Our Bundler follows standard ERC 4337 implementation for gas and fee checks in order to 1) ensure your UserOperations (UOs) land 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 when gas and fees are estimated and the time when UOs are submitted to the bundler. This fluctuation in the market is especially variant on testnet. To ensure your UO is included in a block, we currently reject sending any UOs that are underpriced compared to the network rate .

To handle these errors, we recommend you use our override fields to increase buffers on top of our estimates and implement retry mechanisms as needed.

Our gas and fee estimations are just that, estimations, but we are always working to improve these estimates!

Total execution gas limit exceeded: { code: -3202, message: 'precheck failed: total execution gas is X but must be at most 10000000}


Currently our Bundler allows max 10M gas in aggregate between preVerificationGas, verificationGasLimit, and callGasLimit. To reduce the gas needed, try reducing the size of your call data and/or sending your call data in multiple UserOperations rather than one.

waitForUserOperationTransaction timeout


waitForUserOperationTransaction may throw this error if it does not find the mined User Operation within its retry limits.

You can mitigate this by defining a more flexible retry period when constructing a Client (i.e. txMaxRetries, txRetryIntervalMs, txRetryMultiplier in opts).

If your UserOperation continues to be delayed beyond a limit you are willing to wait, you can resubmit the user operation using dropAndReplaceUserOperation.

Other Support

Does the aa-sdk repo support React Native?

No, the aa-sdk repo does not offically support React Native. It is on our radar!

Currently we have a strong dependency on Viem, which requires several global features, such as TextEncoder and crypto, that are absent in React Native's environment. See more about Viem's capability here.

However, we have created a small PoC using Expo that you can find here. For more information on how to use Account Kit within a React Native application see the guide.