NERO
Account Abstraction

Smart Accounts

SimpleAccount deployment, address derivation, and UserOperation construction

Smart Accounts

The SimpleAccount class implements ERC-4337 compliant smart contract accounts. The MPC-derived EOA serves as the owner of the smart account, and addresses are determined before deployment through counterfactual derivation.

EOA Address Derivation

The wallet's primary identity begins as an EOA derived from the distributedly generated public key using standard Ethereum protocol.

The derivation logic (src/wallet/address-derivation.ts):

  1. Strip existing 0x or 04 prefixes from the public key string
  2. Validate the resulting hex string represents a valid 64-byte uncompressed key
  3. Apply Keccak-256 hashing to raw key bytes
  4. Take the last 20 bytes (40 hex characters) of the hash
  5. Apply EIP-55 checksum encoding to the resulting address

Key Functions

FunctionDescription
deriveEOAAddress(publicKey)Converts MPC public key to EVM address
checksumAddress(address)Implements EIP-55 for mixed-case checksums
isValidAddress(address)Validates 20-byte Ethereum address format

Smart Account Address Derivation

Smart account addresses are counterfactual (determined before deployment) and depend on:

  • factoryAddress -- The SimpleAccountFactory contract address
  • ownerAddress -- The MPC-derived EOA
  • salt -- A deterministic constant (typically 0)

The SDK retrieves this address by calling the getAddress function on the factory contract via RPC call:

address = factory.getAddress(owner, salt)

The account contract does not need to be deployed on-chain until the first transaction. The deployment cost is included automatically in the first UserOperation via initCode.

UserOperation Construction

The buildUserOperation Method

Building a UserOperation involves six stages:

  1. Encoding CallData -- Converts TransactionRequest objects into execute or executeBatch calldata
  2. Deployment Check -- Checks if the contract is deployed; generates initCode if not
  3. Nonce Management -- Retrieves current nonce from EntryPoint contract
  4. Gas Estimation -- Communicates with the bundler to estimate gas limits
  5. Paymaster Integration -- If configured, requests paymasterAndData to sponsor fees
  6. Dummy Signature -- Initially populates the signature field with a dummy value for accurate gas estimation

UserOperation Hash

The computeUserOpHash method packs operation fields and hashes them with the entryPointAddress and chainId. This hash is what gets signed by the MPC protocol.

Function Selectors

ConstantValuePurpose
EXECUTE_SELECTORb61d27f6Standard execute(address, uint256, bytes)
EXECUTE_BATCH_SELECTOR18dfb3c7Standard executeBatch(address[], uint256[], bytes[])
CREATE_ACCOUNT_SELECTOR5fbfb9cfFactory method createAccount(address, uint256)
GET_ADDRESS_SELECTOR8cb84e18Factory method getAddress(address, uint256)

Source Files

  • src/__tests__/address-derivation.test.ts -- Test vectors and usage examples
  • src/aa/simple-account.ts -- SimpleAccount implementation with selector definitions
  • src/wallet/address-derivation.ts -- Address derivation logic

On this page