Skip to main content
Version: SDK V3

ECDSA Ownership Module

What is it? 🤔

The ECDSA Ownership Registry Module or ECDSA Validation Module is integral to Biconomy's Modular Smart Account, enhancing transaction security and user authentication. This document outlines its functionality, benefits, and use cases.

What is the ECDSA Ownership Module? 🤔

This module allows Externally Owned Accounts (EOAs) to authorize and sign user operations (UserOps) for Smart Account. It operates similarly to non-modular Smart Account ownership but is reconstructed as a Validation Module within the Account Abstraction + Modular Smart Accounts ecosystem.


The ECDSA Validation Module is the standard choice for Biconomy Modular Smart Accounts unless another module is chosen during setup. It makes things easier for users and helps manage ownership smoothly.

Key Functions 🔐

  • Single Signer Simplicity: Offers 1/1 multisig, single-signature control, ideal for both Web2 users and crypto-native users who already possess an EOA wallet.
  • ECDSA Signature Scheme: Utilizes the ECDSA secp256k1 curve for secure signing.
  • Flexible Owner Authentication: Supports various signer solutions like Privy, Fireblocks, Arcana Auth, Web3Auth, Magic, Capsule, Turnkey or Particle.
  • EIP-1271 Compliance: Allowing Smart Accounts to sign Ethereum messages for logging into dApps.

One of the most popular modules, it bridges the ease of traditional web logins with the security of blockchain technology.

Use Cases 🌟

  1. Secure Transaction Signing: EOAs can securely authorize transactions for Smart Accounts.
  2. dApp Interaction: Simplifies the process of logging into dApps using Ethereum messages thanks to EIP-1271 support.
  3. Ownership Management: Mirrors traditional ownership systems, providing a familiar framework within a more advanced blockchain setting.

Smart Contract Deep Dive 🛠️

This section dives into the EcdsaOwnershipRegistryModule for Biconomy Smart Accounts, focusing on key functionalities and security aspects.

Core Functionalities

User Operation Validation (validateUserOp) 🛡️

// Validates user operations signed by an EOA
function validateUserOp(
UserOperation calldata userOp,
bytes32 userOpHash
) external view virtual override returns (uint256) {
if (
) {

Objective: The function safeguards the authenticity of user operations on Smart Accounts.

Method: It specifically decodes and verifies a segment of the userOp.signature. This segmentation is crucial because userOp.signature contains both the signature and the validation module's address. By extracting only the signature part, the function accurately validates the operation against the intended owner's signature, ensuring that the operation is legitimately authorized.

Signature Verification (_verifySignature) 🔐

// Internal function to verify the signature of a smart account
function _verifySignature(bytes32 dataHash, bytes memory signature, address smartAccount)
internal view returns (bool) {
address expectedSigner = _smartAccountOwners[smartAccount];
// Reverts if no owner is registered
if (expectedSigner == address(0)) {
revert NoOwnerRegisteredForSmartAccount(smartAccount);
// Checks for signature length and recovers the signer
if (signature.length < 65) revert WrongSignatureLength();
address recovered = (dataHash.toEthSignedMessageHash()).recover(signature);
if (expectedSigner == recovered) {
return true;
recovered = dataHash.recover(signature);
return expectedSigner == recovered;

Validates a signature against a data hash and registered owner, supporting EIP-1271 standard.

function isValidSignature(
bytes32 dataHash,
bytes memory signature
) public view returns (bytes4);

isValidSignature serves as a key function for external smart contracts to verify signature authenticity.


Proper handling and verification of signatures are crucial for maintaining the integrity of the Smart Account. The isValidSignature function is essential for EIP-1271 support, validating that the signature matches the expected signer as per the EIP-1271 standard.

Security Considerations

  • Strict Ownership Rules: Only Externally Owned Accounts (EOAs) can authorize transactions, ensuring secure control over Smart Account operations.
  • Signature Verification: Implements robust methods for signature validation, crucial for preventing unauthorized access.

The initForSmartAccount method doesn't include isSmartContract checks due to operational constraints. However, this doesn't compromise security as operations require valid EOA signatures. This ensures Smart Accounts remain secure within their operational framework.

Interaction with Smart Accounts 🤝

The EcdsaOwnershipRegistryModule interacts with Smart Accounts primarily through its core functionalities:

  • Initialization and Ownership: During deployment, Smart Accounts use init method to invoke initForSmartAccount on modules, setting initial ownership and configurations.
  • User Operation Validation: When a Smart Account attempts to perform an operation, validateUserOp is invoked to ensure the action is authorized by the registered owner.
  • Signature Verification: The module uses _verifySignature to verify any signatures associated with transactions initiated by the Smart Account.

SDK Guide 📘

Integrate the ECDSA Validation Module into Biconomy Smart Accounts using the SDK.

Setup and Installation 🛠️

npm install @biconomy/modules ethers

Creating a Signer 🗝️

import { ethers } from "ethers";

const provider = new ethers.providers.JsonRpcProvider("[RPC_Endpoint]");
const signer = new ethers.Wallet("[Private_Key]", provider);

Importing and Initializing ECDSA Module 🌟

import {
} from "@biconomy/modules";

const ecdsaModule = await ECDSAOwnershipValidationModule.create({
signer: signer,

Creating a Smart Account 🚀

import { BiconomySmartAccountV2 } from "@biconomy/account";

const smartAccount = await BiconomySmartAccountV2.create({
paymaster: //basePaymaster,
bundler: //baseBundler,
rpcUrl: // Base Goerli Rpc
defaultValidationModule: ecdsaModule,
activeValidationModule: ecdsaModule, // If not provided, it will be same as provided defaultValidationModule
// Additional configurations

The Smart Account's address is counterfactually generated based on the signer's public key, which is the owner's address used in the ECDSA Module. This feature allows for the pre-calculation of the account address before deployment.


To deploy the same Smart Account (with the same address) on different chains, it's crucial to use the same module address, the same initialization data (here, the owner's EOA address) for the ECDSA Module here and the index. This ensures consistency in the account's address across various blockchains.