Simple 7702 Account (EntryPoint v0.9)
The Simple7702AccountV09 is a minimalist smart contract account for EIP-7702, targeting EntryPoint v0.9 (0x433709009B8330FDa32311DF1C2AFA402eD8D009). It shares the same audited contract implementation and API surface as Simple7702Account, with type specialization for UserOperationV9.
EntryPoint v0.9 maintains ABI compatibility with v0.8 while adding:
- Parallelizable Paymaster Signing: New
paymasterSignature field allows passing data to Paymasters after UserOperation signing.
- Block Number-Based Validity Ranges:
validAfter and validUntil can now specify block numbers instead of timestamps.
- Flexible InitCode Handling:
initCode is silently ignored if the Account already exists, enabling two-dimensional nonce usage.
- UserOp Hash Query: New
getCurrentUserOpHash function exposes the current UserOperation hash during execution.
The following ERCs are supported:
- ERC-165
- ERC-721
- ERC-1155
- ERC-1271
- ERC-4337 v0.9
Smart Contracts and Audits
The contracts were developed by the Ethereum Foundation Account Abstraction Team and audited by Cantina.
How to Use
Prerequisites
Before using Simple7702AccountV09, you must have:
- Node.js: Version 18.0 or higher.
- EIP-7702 Compatible Network: Ethereum mainnet, Sepolia, or other EIP-7702 enabled chains with EP v0.9 support.
- Private Key Access: Required for signing authorizations and user operations.
Installation
npm install abstractionkit
Usage
import { Simple7702AccountV09 } from "abstractionkit";
const delegatorPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const smartAccount = new Simple7702AccountV09(delegatorPublicAddress);
Constructor defaults:
entrypointAddress: 0x433709009B8330FDa32311DF1C2AFA402eD8D009 (EntryPoint v0.9)
delegateeAddress: 0xa46cc63eBF4Bd77888AA327837d20b23A63a56B5
Both can be overridden by passing an overrides object as the second constructor argument.
Essential Methods
createUserOperation
Creates a UserOperation for EIP-7702 accounts that can be sent to bundlers for execution.
- example.ts
- Param Types
- Return Type
example.ts
import { Simple7702AccountV09 } from "abstractionkit";
const delegatorPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
const smartAccount = new Simple7702AccountV09(delegatorPublicAddress);
const transactions = [
{
to: "0x...",
value: 0n,
data: "0x...",
},
];
const userOperation = await smartAccount.createUserOperation(
transactions,
"https://ethereum-sepolia-rpc.publicnode.com",
"https://your-ep-v09-bundler-rpc",
{
eip7702Auth: {
chainId,
},
maxFeePerGas: 20000000000n,
maxPriorityFeePerGas: 2000000000n,
}
);
| key | type | description |
|---|
transactions | SimpleMetaTransaction[] | Array of transactions to include in the user operation |
providerRpc? | string | Optional JSON-RPC provider URL for blockchain queries |
bundlerRpc? | string | Optional bundler RPC URL for gas estimation |
overrides? | | key | type | description |
|---|
eip7702Auth? | | key | type | description |
|---|
chainId | string | Chain ID in hexadecimal format where the authorization is valid | address | string | Address to authorize for the EOA delegation | nonce | string | Authorization nonce in hexadecimal format | yParity | string | Y parity of the authorization signature | r | string | R component of the authorization signature | s | string | S component of the authorization signature |
| EIP-7702 authorization parameters for EOA delegation | nonce? | string | Anti-replay parameter (see Semi-abstracted Nonce Support) | callData? | string | The data to pass to the sender during the main execution call | callGasLimit? | bigint | The amount of gas to allocate the main execution call | verificationGasLimit? | bigint | The amount of gas to allocate for the verification step | preVerificationGas? | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata | maxFeePerGas? | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) | maxPriorityFeePerGas? | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) | callGasLimitPercentageMultiplier? | number | Set the callGasLimitPercentageMultiplier instead of estimating gas using the bundler | verificationGasLimitPercentageMultiplier? | number | Set the verificationGasLimitPercentageMultiplier instead of estimating gas using the bundler | preVerificationGasPercentageMultiplier? | number | Set the preVerificationGasPercentageMultiplier instead of estimating gas using the bundler | maxFeePerGasPercentageMultiplier? | number | Set the maxFeePerGasPercentageMultiplier instead of querying the current gas price from the RPC node | maxPriorityFeePerGasPercentageMultiplier? | number | Set the maxPriorityFeePerGasPercentageMultiplier instead of querying the current gas price from the RPC node | state_override_set? | StateOverrideSet | Pass state override set for simulation | dummySignature? | string | Dummy signature for gas estimation |
| Optional overrides for user operation creation |
SimpleMetaTransaction
| key | type | description |
|---|
SimpleMetaTransaction | | key | type | description |
|---|
to | string | Target contract address for the transaction | value | bigint | Value transferred in the transaction (usually 0n for contract interactions) | data | string | The call data for the transaction |
| SimpleMetaTransaction is the type of transaction used with Simple7702Account. |
| key | type | description |
|---|
userOperation | | key | type | description |
|---|
sender | string | The account making the operation | nonce | bigint | Anti-replay parameter (see Semi-abstracted Nonce Support) | factory | string | null | Account factory address, only for new accounts (null if account already exists) | factoryData | string | null | Data for account factory (null if account already exists) | callData | string | The data to pass to the sender during the main execution call | callGasLimit | bigint | The amount of gas to allocate the main execution call | verificationGasLimit | bigint | The amount of gas to allocate for the verification step | preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata | maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) | maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) | paymaster | string | null | Address of paymaster contract (null if account pays for itself) | paymasterVerificationGasLimit | bigint | null | The amount of gas to allocate for the paymaster verification step (null if no paymaster) | paymasterPostOpGasLimit | bigint | null | The amount of gas to allocate for the paymaster post-operation code (null if no paymaster) | paymasterData | string | null | Data for paymaster (null if no paymaster) | eip7702Auth | Authorization7702Hex | null | EIP-7702 authorization data for EOA delegation (null if not using EIP-7702) | signature | string | Data passed into the account to verify authorization. Resolves to '0x' when the user did not provide their signature yet |
| The constructed user operation for EIP-7702 |
signUserOperation
Signs a UserOperation with the provided private key for the EIP-7702 account.
- example.ts
- Param Types
- Return Type
example.ts
const signature = smartAccount.signUserOperation(
userOperation,
"0x...private-key",
11155111n
);
userOperation.signature = signature;
| key | type | description |
|---|
userOperation | | key | type | description |
|---|
sender | string | The account making the operation | nonce | bigint | Anti-replay parameter (see Semi-abstracted Nonce Support) | factory | string | null | Account factory address, only for new accounts (null if account already exists) | factoryData | string | null | Data for account factory (null if account already exists) | callData | string | The data to pass to the sender during the main execution call | callGasLimit | bigint | The amount of gas to allocate the main execution call | verificationGasLimit | bigint | The amount of gas to allocate for the verification step | preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata | maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) | maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) | paymaster | string | null | Address of paymaster contract (null if account pays for itself) | paymasterVerificationGasLimit | bigint | null | The amount of gas to allocate for the paymaster verification step (null if no paymaster) | paymasterPostOpGasLimit | bigint | null | The amount of gas to allocate for the paymaster post-operation code (null if no paymaster) | paymasterData | string | null | Data for paymaster (null if no paymaster) | eip7702Auth | Authorization7702Hex | null | EIP-7702 authorization data for EOA delegation (null if not using EIP-7702) | signature | string | Data passed into the account to verify authorization. Resolves to '0x' when the user did not provide their signature yet |
| The user operation to sign |
privateKey | string | Private key to sign the user operation with |
chainId | bigint | Chain ID for the target blockchain |
| key | type | description |
|---|
signature | string | The signature for the user operation |
sendUserOperation
Sends a signed UserOperation to the bundler for execution on-chain.
- example.ts
- Param Types
- Return Type
example.ts
const response = await smartAccount.sendUserOperation(
userOperation,
"https://your-ep-v09-bundler-rpc"
);
console.log("UserOperation hash:", response.userOperationHash);
const receipt = await response.included();
console.log("Transaction receipt:", receipt);
| key | type | description |
|---|
userOperation | | key | type | description |
|---|
sender | string | The account making the operation | nonce | bigint | Anti-replay parameter (see Semi-abstracted Nonce Support) | factory | string | null | Account factory address, only for new accounts (null if account already exists) | factoryData | string | null | Data for account factory (null if account already exists) | callData | string | The data to pass to the sender during the main execution call | callGasLimit | bigint | The amount of gas to allocate the main execution call | verificationGasLimit | bigint | The amount of gas to allocate for the verification step | preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata | maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) | maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) | paymaster | string | null | Address of paymaster contract (null if account pays for itself) | paymasterVerificationGasLimit | bigint | null | The amount of gas to allocate for the paymaster verification step (null if no paymaster) | paymasterPostOpGasLimit | bigint | null | The amount of gas to allocate for the paymaster post-operation code (null if no paymaster) | paymasterData | string | null | Data for paymaster (null if no paymaster) | eip7702Auth | Authorization7702Hex | null | EIP-7702 authorization data for EOA delegation (null if not using EIP-7702) | signature | string | Data passed into the account to verify authorization. Resolves to '0x' when the user did not provide their signature yet |
| The signed user operation to send |
bundlerRpc | string | Bundler RPC URL to send the user operation to |
| key | type | description |
|---|
response | | key | type | description |
|---|
userOperationHash | string | The hash over the userOp (except signature), entryPoint and chainId | bundler | Bundler | The Bundler class | entrypointAddress | string | The entrypoint address where the useroperation got executed | included() | Promise<UserOperationReceiptResult | BundlerJsonRpcError> | Waits for the user operation to be included onchain and returns the user operation receipt on success, or the bundler error on failture |
| Response containing user operation hash and bundler details |
SendUseroperationResponse
| key | type | description |
|---|
userOperationHash | string | The hash over the userOp (except signature), entryPoint and chainId |
bundler | Bundler | The Bundler class |
entrypointAddress | string | The entrypoint address where the useroperation got executed |
included() | Promise<UserOperationReceiptResult | BundlerJsonRpcError> | Waits for the user operation to be included onchain and returns the user operation receipt on success, or the bundler error on failture |
BundlerJsonRpcError
| key | type | description |
|---|
code | number | Bundler RPC error code |
message | string | Bundler RPC error message description |
UserOperationReceiptResult
| key | type | description |
|---|
userOpHash | string | The hash of the user operation. |
entryPoint | string | The address of the entry point contract that processed the operation. |
sender | string | The address of the sender of the user operation. |
nonce | bigint | The nonce of the user operation. |
paymaster | string | The address of the paymaster that paid for the gas of the user operation. |
actualGasCost | bigint | The actual gas cost incurred for executing the user operation. |
actualGasUsed | bigint | The actual amount of gas used for the user operation. |
success | boolean | Indicates whether the user operation was successful. |
logs | string | The logs produced during the execution of the user operation. |
receipt | | key | type | description |
|---|
blockHash | string | The hash of the block in which the transaction was included. | blockNumber | bigint | The number of the block in which the transaction was included. | from | string | The address that initiated the transaction. | cumulativeGasUsed | bigint | The total amount of gas used in the block up to and including this transaction. | gasUsed | bigint | The amount of gas used by this transaction. | logs | string | Logs generated by the transaction. | logsBloom | string | The bloom filter for the logs generated by the transaction. | transactionHash | string | The unique hash of the transaction. | transactionIndex | bigint | The index of the transaction within the block. | effectiveGasPrice | bigint | The effective gas price for the transaction. This field is optional and may not be present in all receipts. |
| The detailed receipt of the user operation. |
prependTokenPaymasterApproveToCallDataStatic
Prepends a token approval transaction to existing call data for use with token paymasters.
- example.ts
- Param Types
- Return Type
example.ts
const callDataWithApproval = Simple7702AccountV09.prependTokenPaymasterApproveToCallDataStatic(
"0x...",
"0xa0b86a33e6b3e96bb24b8e4b28e80e0fb3a4f4b6",
"0x...",
1000000n
);
| key | type | description |
|---|
callData | string | Existing call data to prepend the approval to |
tokenAddress | string | Address of the ERC-20 token to approve |
paymasterAddress | string | Address of the paymaster contract |
approveAmount | bigint | Amount of tokens to approve for the paymaster |
| key | type | description |
|---|
callData | string | Call data with token approval prepended |
prependTokenPaymasterApproveToCallData
Instance method to prepend token approval to call data for paymaster usage.
- example.ts
- Param Types
- Return Type
example.ts
const callDataWithApproval = smartAccount.prependTokenPaymasterApproveToCallData(
"0x...",
"0xa0b86a33e6b3e96bb24b8e4b28e80e0fb3a4f4b6",
"0x...",
1000000n
);
| key | type | description |
|---|
callData | string | Existing call data to prepend the approval to |
tokenAddress | string | Address of the ERC-20 token to approve |
paymasterAddress | string | Address of the paymaster contract |
approveAmount | bigint | Amount of tokens to approve for the paymaster |
| key | type | description |
|---|
callData | string | Call data with token approval prepended |
Advanced Methods
createAccountCallData
Creates call data for a basic transaction with specified target, value, and data.
- example.ts
- Param Types
- Return Type
example.ts
const callData = Simple7702AccountV09.createAccountCallData(
"0x...",
1000000000000000000n,
"0x..."
);
| key | type | description |
|---|
to | string | Target address for the transaction |
value | bigint | Value to transfer in the transaction |
data | string | Call data for the transaction |
| key | type | description |
|---|
callData | string | Encoded call data for the account transaction |
createAccountCallDataSingleTransaction
Creates call data for a single SimpleMetaTransaction.
- example.ts
- Param Types
- Return Type
example.ts
const metaTransaction = {
to: "0x...",
value: 0n,
data: "0x...",
};
const callData = Simple7702AccountV09.createAccountCallDataSingleTransaction(metaTransaction);
| key | type | description |
|---|
metaTransaction | | key | type | description |
|---|
SimpleMetaTransaction | | key | type | description |
|---|
to | string | Target contract address for the transaction | value | bigint | Value transferred in the transaction (usually 0n for contract interactions) | data | string | The call data for the transaction |
| SimpleMetaTransaction is the type of transaction used with Simple7702Account. |
| The SimpleMetaTransaction to create call data for |
| key | type | description |
|---|
callData | string | Encoded call data for the account transaction |
createAccountCallDataBatchTransactions
Creates call data for batching multiple SimpleMetaTransactions together.
- example.ts
- Param Types
- Return Type
example.ts
const transactions = [
{ to: "0x...", value: 0n, data: "0x..." },
{ to: "0x...", value: 0n, data: "0x..." },
];
const callData = Simple7702AccountV09.createAccountCallDataBatchTransactions(transactions);
| key | type | description |
|---|
transactions | SimpleMetaTransaction[] | Array of SimpleMetaTransactions to batch together |
| key | type | description |
|---|
callData | string | Encoded call data for the account transaction |
estimateUserOperationGas
Estimates gas limits for a UserOperation using the bundler.
- example.ts
- Param Types
- Return Type
example.ts
const [preVerificationGas, verificationGasLimit, callGasLimit] =
await smartAccount.estimateUserOperationGas(
userOperation,
"https://your-ep-v09-bundler-rpc",
{
stateOverrideSet: {...},
dummySignature: "0x...",
}
);
| key | type | description |
|---|
userOperation | | key | type | description |
|---|
sender | string | The account making the operation | nonce | bigint | Anti-replay parameter (see Semi-abstracted Nonce Support) | factory | string | null | Account factory address, only for new accounts (null if account already exists) | factoryData | string | null | Data for account factory (null if account already exists) | callData | string | The data to pass to the sender during the main execution call | callGasLimit | bigint | The amount of gas to allocate the main execution call | verificationGasLimit | bigint | The amount of gas to allocate for the verification step | preVerificationGas | bigint | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata | maxFeePerGas | bigint | Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) | maxPriorityFeePerGas | bigint | Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) | paymaster | string | null | Address of paymaster contract (null if account pays for itself) | paymasterVerificationGasLimit | bigint | null | The amount of gas to allocate for the paymaster verification step (null if no paymaster) | paymasterPostOpGasLimit | bigint | null | The amount of gas to allocate for the paymaster post-operation code (null if no paymaster) | paymasterData | string | null | Data for paymaster (null if no paymaster) | eip7702Auth | Authorization7702Hex | null | EIP-7702 authorization data for EOA delegation (null if not using EIP-7702) | signature | string | Data passed into the account to verify authorization. Resolves to '0x' when the user did not provide their signature yet |
| The user operation to estimate gas for |
bundlerRpc | string | Bundler RPC URL for gas estimation |
overrides? | | key | type | description |
|---|
state_override_set? | StateOverrideSet | State override set for simulation | dummySignature? | string | Dummy signature for gas estimation |
| Optional overrides for gas estimation |
| key | type | description |
|---|
gasLimits | [bigint, bigint, bigint] | Tuple of [preVerificationGas, verificationGasLimit, callGasLimit] |
Delegation Methods
isDelegatedToThisAccount
Checks if the EOA is currently delegated to the expected smart account address via EIP-7702. Returns true only when delegated to the account's delegateeAddress.
- example.ts
- Param Types
- Return Type
example.ts
const isDelegated = await smartAccount.isDelegatedToThisAccount(
"https://ethereum-sepolia-rpc.publicnode.com"
);
if (isDelegated) {
console.log("EOA is delegated to this smart account");
} else {
console.log("EOA is not delegated");
}
| key | type | description |
|---|
providerRpc | string | Ethereum JSON-RPC node URL |
| key | type | description |
|---|
isDelegated | boolean | true if the EOA is delegated to the expected address, false otherwise |
createRevokeDelegationTransaction
Creates a signed EIP-7702 transaction that revokes the delegation, restoring the EOA to a regular account. The transaction delegates to address(0), removing the smart account code from the EOA.
This is a regular Ethereum transaction (type 0x04), not a UserOperation. The EOA needs native tokens to pay for gas.
Revocation cannot be done via a UserOperation because the authorization list is processed before execution, which would remove the account's code mid-transaction.
- example.ts
- Param Types
- Return Type
example.ts
const signedTransaction = await smartAccount.createRevokeDelegationTransaction(
"0x...private-key",
"https://ethereum-sepolia-rpc.publicnode.com",
);
| key | type | description |
|---|
eoaPrivateKey | string | The EOA's private key (signs both the authorization and the transaction) |
providerRpc | string | JSON-RPC endpoint for nonce, gas price, and chain ID queries |
overrides? | | key | type | description |
|---|
nonce? | bigint | Transaction nonce override | authorizationNonce? | bigint | EIP-7702 authorization nonce override | maxFeePerGas? | bigint | Maximum fee per gas (EIP-1559) | maxPriorityFeePerGas? | bigint | Maximum priority fee per gas (EIP-1559) | gasLimit? | bigint | Gas limit for the transaction | chainId? | bigint | Chain ID override |
| Optional overrides for transaction fields |
| key | type | description |
|---|
signedTransaction | string | Signed raw transaction hex, ready for eth_sendRawTransaction |
Error Handling & Common Issues
- Authorization Errors
- Gas Estimation Issues
- Network Mismatches
const userOperation = await smartAccount.createUserOperation(
transactions,
providerRpc,
bundlerRpc,
{
eip7702Auth: { chainId: 11155111n },
}
);
const userOperation = await smartAccount.createUserOperation(
transactions,
providerRpc,
bundlerRpc,
{
eip7702Auth: { chainId: 11155111n },
maxFeePerGasPercentageMultiplier: 120,
maxPriorityFeePerGasPercentageMultiplier: 150,
}
);
const userOperation = await smartAccount.createUserOperation(
transactions,
"https://ethereum-sepolia-rpc.publicnode.com",
"https://your-ep-v09-bundler-rpc",
{
eip7702Auth: { chainId: 11155111n },
}
);