Skip to content

permissionless.js FAQs

Getting WaitForUserOperationReceiptTimeoutError?

This error is thrown when the bundler takes too long to bundle your user operation or the default timeout configured in permissionless.js is not enough. This could be due to the block time of the chain you are using is more than the default timeout.

The easiest way to fix this is to increase the timeout in permissionless.js. You can do this by changing timeout value in bundlerTransport like so:

const smartAccountClient = createSmartAccountClient({
  account: simpleSmartAccount,
  chain: sepolia, // or whatever chain you are using
  bundlerTransport: http("<bundler_endpoint>", {
    timeout: 30_000 // Custom timeout
  })
})

Can I use social logins (Google, Facebook, etc.) with permissionless.js?

Yes! While permissionless.js doesn't directly implement social logins, you can integrate third-party providers that offer social login capabilities. Popular options include:

These providers can be integrated with permissionless.js to enable social login experiences while leveraging smart accounts for features like gas sponsorship and transaction batching. Check out our Signers documentation for integration guides with these providers.

Getting out of gas errors?

Such errors are thrown when the provided gas limits are not enough to execute the user operation. Usually the gas limits are calculated by the bundler. If you are getting such error, you can try setting up gas limits manually.

const userOp = await smartAccountClient.prepareUserOperation({
    calls,
    callGasLimit: 100_000n,
    verificationGasLimit: 100_000n,
    preVerificationGas: 100_000n,
})

Do I need the same saltNonce to re-initialize my Safe?

When initializing a Safe account with toSafeSmartAccount, if you want to get the same account address when re-initializing the Safe wallet, you must use the same saltNonce value that was used during the initial creation. If no saltNonce is specified, toSafeSmartAccount defaults to 0n.

Using a different saltNonce will result in a different account address being generated. Here's an example of how to specify the saltNonce:

const safeAccount = await toSafeSmartAccount({
    client: publicClient,
    entryPoint: {
        address: entryPoint07Address,
        version: "0.7",
    },
    owners: [someSigner],
    saltNonce: 100n, // must match the original saltNonce to get the same address
    version: "1.4.1",
});

For more details about the saltNonce parameter and other configuration options, see the reference documentation for toSafeSmartAccount.

Getting preVerificationGas is not enough errors?

This error occurs when a userOperation is submitted with a preVerificationGas that is insufficient to cover the offchain overhead. You might see an error message like:

{
    "message": "preVerificationGas is not enough, required: 60676, got: 48550",
    "code": -32500
}

The preVerificationGas accounts for:

  • Gas overhead that can't be calculated onchain
  • L1 data costs when operating on L2 networks

This error typically occurs in two scenarios:

  1. When calling eth_estimateUserOperationGas with a userOperation signature that is not the same length as the real signature.
  2. When submitting a UserOperation after the bundler's preVerificationGas commitment has expired.

To resolve this issue:

  1. Ensure proper dummy signature is used during estimation to ensure proper L1DataCost calculations:

    • Provide a semi-valid dummy signature that matches your final signature's length
    • The signature should be semi valid such that the validation doesn't revert
  2. Account for gas estimation timing:

    • The bundler commits to the estimated preVerificationGas for 30 seconds
    • You should submit your UserOperation within this window to avoid insufficient preVerificationGas errors
    • If you are submitting after the window, you can add a fixed overhead to your preVerificationGas to increase the chances it gets included