Skip to content
Alchemy Logo

Frequently asked questions

Check out GitHub discussions for more commonly asked questions and support.

Answer

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

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

  1. If you deploy one smart wallet, then change the owner, then deploy the second account.
  2. If you upgrade the smart wallet (e.g. to a new version of Light Account). Updates to this contract are infrequent, so the address will not change often.

Answer

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

Answer

You are unlikely to 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, send a UserOperation using the method upgradeTo or upgradeToAndCall, depending on whether or not you need to initialize the new implementation.

Answer

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

Answer

Simple Account's support upgradeToAndCall implemented by OpenZeppelin UUPSUpgradeable contract. This allows you to upgrade from Simple Account to Light Account without changing the wallet address. Using upgradeToAndCall updates the underlying implementation contract on the account while the account address and assets 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

Encode the initialize step correctly to ensure the account does not get into a risky state where someone else could call initialize on it with their own key and take control of your account. Call owner() on the account after the upgrade to verify it is assigned correctly.

This can be called on the existing smart wallet 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).

Answer

If the UserOperation (meta-transaction for 4337 accounts) is correctly priced and submitted a few hundred milliseconds before a new block gets created, it will typically land in the next block. The transaction sender needs time to create/propagate its transaction. You can think of it as 1 extra block time worth of latency.

Answer

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.

Answer

Right now, UserOperations are sent to a private mempool for all networks other than Polygon, where there is no way to do this.

Answer

The transaction sender estimates gas and submits UserOperations (UOs) under the hood of the aa-sdk. Gas estimations optimize for UOs landing onchain, 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 the transaction sender blog post.

There are many nuances and edge cases that the transaction sender considers especially for L2s. Learn more in the L2 gas and signature aggregators blog post.

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

Answer

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 the different pricing tiers here.

Answer

Gas is fronted for your application and the USD equivalent appears on your bill at the end of the month. No need to worry about pre-funding the Gas Manager or conversions. Follow the gas sponsorship guide for more details on how to sponsor UserOperations.

Answer

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

Answer

Yes. Gas Manager includes an ERC-20 paymaster contract so your users can pay fees with tokens like USDC. See How to pay gas with any token for details.

Answer

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.

Answer

After a user logs in with Smart Wallets on the frontend, you might want to verify their identity on your backend to authorize actions or access.

You can do this using one of two approaches:


Use this flow to verify user sessions created by EOAs and smart wallets via Smart Wallets.

For EOAs, Smart Wallets doesn’t create a session on the client side and stampWhoAmI isn’t available, so use SIWE instead. This works for verifying both EOA and SCA flows. Create a SIWE message with all the necessary info to get server side (address, chainId, etc).

  1. The backend provides a nonce to the frontend.
  2. The user signs a SIWE message with their wallet (EOA or SCA).
  3. The frontend sends the signed message back to the backend.
  4. The backend verifies the signature:
  • EOAs: Standard signature recovery
  • SCAs: Use EIP-1271 or EIP-6492 to verify the contract signature
  1. The backend issues a session token.

Note:

  • SIWE requires an explicit signature from the user, which costs more than calling whoami
  • For verifying both EOA and SCA user sessions

Use this flow when you need to verify user sessions created by SCAs via Smart Wallets.

  1. The frontend generates a stamped request using signer.inner.stampWhoAmI.
  2. It sends the stamp to your backend.
  3. The backend calls the /signer/v1/whoami endpoint to verify the identity.
  4. If you need to make subsequent requests, you can avoid calling the whoami endpoint on every request. After verifying the whoami, the backend can issue its own session token (e.g. an HTTP-only cookie or access token). If the token is present, you can safely skip the whoami check.

Why this approach?

  • No user signature required
  • Cheaper than flows requiring a signed message
  • Retrieve user's login info, such as email and address if available

Answer

Replacement underpriced errors occur when you attempt to send another user operation (UO) from the same sender before the pending user operation has been confirmed onchain. Please follow recommendations here.

Answer

Please follow this guide for best practices on implementing waiting and retries.

This error indicates that your User Operation has not yet landed onchain (assuming it was accepted by the transaction sender). 1) Continue waiting or 2) drop and replace and 3) add a multiplier to gas estimates to increase the priority of your transaction.

Answer

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.

Answer

Precheck failed errors are often related to gas and/or fees. The transaction sender follows the standard ERC-4337 implementation for gas and fee checks to 1) ensure your UserOperations (UOs) land onchain and 2) protect the transaction sender from potential attacks 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 transaction sender. This fluctuation in the market is especially variant on testnet. To ensure your UO is included in a block, any UOs that are underpriced compared to the network rate are rejected.

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

Answer

Currently the transaction sender 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.

Answer

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.

Answer

This revert warning message is expected when using Modular Account v1. In MAv1, a checker enforces that calls made using the account (from execute or executeBatch) don't target plugin contracts. When the contract being called to isn't a plugin (which is usually the case), the checker reverts, and it shows this message in explorers.

Answer

This message is usually triggered by browser ad-blocking tools that stop analytics scripts from running. Analytics collection will be blocked, but the Smart Wallet functionality continues to work normally.

Answer

These errors show up when you submit UserOperations on Polygon PoS using the transaction sender without a paymaster contract, or with a non-compatible paymaster contract address. Polygon PoS now requires sponsored operations through a compatible paymaster contract. Double-check that your request includes the correct paymaster contract address and that your config points to the right paymaster contract.

You can confirm the requirement and see the latest details in the Polygon PoS chain reference: https://www.alchemy.com/docs/wallets/resources/chain-reference/polygon-pos#transactions.

If you need help getting set up, contact [email protected].

No, the aa-sdk repo does not officially support React Native.

Currently there is 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.

However, a small PoC using Expo is available here. For more information on how to use Smart Wallets within a React Native application see the guide.

Why is it important to protect your API key and Policy ID?

To prevent unauthorized use or abuse of your API key and Policy ID, avoid exposing them on the frontend. If these credentials are exposed, they could be misused, leading to unintended usage or sponsorship.

Gas sponsorship requests only succeed if both the Policy ID and the corresponding API key are used together. While protecting your API key alone renders the Policy ID useless to malicious actors, the best security practice is to protect both.

How to protect your API key

Move your API key to the backend by routing to a proxy. See an example of setting up a transport to a backend rpcUrl in the demo app.

For more information on how to secure your API key, refer to the key security and management guide.

If you have logic in your proxy that restricts certain paths, ensure that the relative paths for network-agnostic RPC requests and signer API requests (see example here), and network-specific RPC requests (see example here) are preserved when forwarding.

How to protect your Policy ID

Protecting your Policy ID requires some custom work, but it’s similar to safeguarding any key on the backend. One solution is to use a proxy server that holds both the API key and Policy ID. In the frontend, when creating a client, pass the proxy server URL as the RPC URL instead of a public URL.

Additionally, implement custom code on your proxy server to limit gas sponsorship requests. This could include rules that make sense for your app, such as limiting gas fees, restricting certain contract or method calls, or implementing limits based on IP addresses or CAPTCHA verification.

Issue:
You or your users might notice that the session ends sooner than expected, requiring re-authentication.

Default behavior:
By default, authenticated sessions using AlchemyWebSigner are stored in localStorage and expire after 15 minutes of inactivity.


Solution: extend or configure session duration

You can customize the session timeout by passing a sessionConfig object to the createConfig method:

createConfig({
  ...,
  sessionConfig: {
    expirationTimeMs: 1000 * 60 * 60, // 1 hour session duration (defaults to 15 min)
  },
})

Reference: createConfig


Other common causes of session ending

  • Server-Side Rendering (SSR) misconfigured If you're using SSR and haven't configured the provider correctly, session state can reset on the client. Enable SSR and pass initial params

  • Ad blockers Some ad blockers (especially those with aggressive cookie or storage policies) can interfere with localStorage or SDK requests, causing unexpected logouts.

  • Private/incognito mode Browsers often restrict or wipe localStorage between tabs or after a short time in incognito mode. Consider warning users or designing for short session lengths in those environments.


Debugging checklist

If you're seeing repeated or sporadic logouts in production, test the behavior across:

  • Browsers (Chrome, Firefox, Safari)
  • Devices (desktop vs mobile)
  • Browsing modes (incognito vs standard)
  • With and without ad blockers
Was this page helpful?