ZeroDev ECDSA Validator signature error with CDP toViemAccount

Resolved 💬 2 comments Opened Dec 30, 2025 by cmichaeltimmons Closed Dec 30, 2025

Description

When using toViemAccount from @coinbase/cdp-core as a signer for ZeroDev's ECDSA validator, user operations fail with an AA24 signature error.

Environment

  • @coinbase/cdp-core: 0.0.74
  • @coinbase/cdp-hooks: 0.0.74
  • @zerodev/sdk: latest
  • @zerodev/ecdsa-validator: latest
  • Chain: Base Mainnet (8453)
  • EntryPoint: 0.7
  • Kernel Version: KERNEL_V3_1

Steps to Reproduce

  1. Create a CDP account using @coinbase/cdp-hooks
  2. Get the EOA address from currentUser.evmAccounts[0]
  3. Create a viem account using toViemAccount(eoaAddress)
  4. Pass this account to ZeroDev's signerToEcdsaValidator
  5. Create a kernel account and client
  6. Send a user operation

Code

import { toViemAccount } from "@coinbase/cdp-core"
import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator"
import { createKernelAccount, createKernelAccountClient } from "@zerodev/sdk"
import { getEntryPoint, KERNEL_V3_1 } from "@zerodev/sdk/constants"

const eoaAddress = currentUser?.evmAccounts?.[0]
const cdpAccount = await toViemAccount(eoaAddress)

const validator = await signerToEcdsaValidator(publicClient, {
    signer: cdpAccount,
    entryPoint: getEntryPoint("0.7"),
    kernelVersion: KERNEL_V3_1,
})

const kernelAccount = await createKernelAccount(publicClient, {
    plugins: { sudo: validator },
    entryPoint,
    kernelVersion,
})

const kernelClient = await createKernelAccountClient({
    account: kernelAccount,
    chain: base,
    bundlerTransport: http(rpcUrl),
    client: publicClient,
    paymaster: { /* ... */ },
})

// This fails with AA24 signature error
const userOpHash = await kernelClient.sendUserOperation({ calls: [...] })

Error

UserOperationExecutionError: Signature provided for the User Operation is invalid.

This could arise when:
- the `signature` for the User Operation is incorrectly computed, and unable to be verified by the Smart Account

Details: UserOperation reverted with reason: AA24 signature error

Console Output

The toViemAccount returns a valid-looking LocalAccount:

{
    address: "0xEE975f934109002E2D4b3EaeBDed4126949Ca30f",
    nonceManager: undefined,
    sign: ƒ async sign(e28),
    signAuthorization: undefined,
    signMessage: ƒ async signMessage({ message: e28 }),
    signTransaction: ƒ async signTransaction(e28),
    signTypedData: ƒ async signTypedData(e28),
    source: "custom",
    type: "local"
}

Observations

  1. The EOA address (0xEE975...) is correctly embedded in the factory data
  2. The signature is being generated but fails verification on-chain
  3. This suggests a potential mismatch in signature format between what CDP produces and what ZeroDev/Kernel expects

Possible Causes

  1. EIP-191 vs EIP-712 signature format mismatch
  2. Missing signature prefix or encoding differences
  3. Hash computation differences between CDP signing and what ZeroDev expects for UserOp signing

Questions

  1. Does toViemAccount produce signatures compatible with ERC-4337 UserOperation signing?
  2. Is there a specific signature format or encoding that ZeroDev's ECDSA validator expects?
  3. Are there any known compatibility issues between CDP's signing and account abstraction validators?

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗