Skip to main content

EntryPoint

This page documents the on-chain interface of the EntryPoint deployed on BOT Chain. When submitting UserOperations directly, the caller must assume the responsibilities of a Bundler.

EntryPoint validation and execution flow

1. PackedUserOperation​

EntryPoint accepts the following on-chain structure:

struct PackedUserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
bytes32 accountGasLimits;
uint256 preVerificationGas;
bytes32 gasFees;
bytes paymasterAndData;
bytes signature;
}

1.1 Fields and encoding​

FieldMeaningEncoding layout
senderSmart-account addresssmartAccount(160)
nonceTwo-dimensional nonce managed by EntryPointkey(192) ‖ sequence(64)
initCodeFactory address and calldata used for first deploymentUndeployed: factory(160) ‖ factoryData(N); deployed: 0x
callDataExecution data sent to the smart accountselector(32) ‖ encodedArguments(N)
accountGasLimitsGas limits for account validation and executionverificationGasLimit(128) ‖ callGasLimit(128)
preVerificationGasCalldata and bundle overhead outside on-chain validationpreVerificationGas(256)
gasFeesEIP-1559 priority fee and maximum total feemaxPriorityFeePerGas(128) ‖ maxFeePerGas(128)
paymasterAndDataOptional Paymaster address, Gas limits, and custom dataUsed: paymaster(160) ‖ paymasterVerificationGasLimit(128) ‖ paymasterPostOpGasLimit(128) ‖ paymasterData(N); unused: 0x
signatureAuthorization data validated by the smart accountaccountSignature(N)

Numbers in parentheses are bit lengths; N denotes a variable length.

2. Execution interfaces​

function handleOps(
PackedUserOperation[] calldata ops,
address payable beneficiary
) external;

function handleAggregatedOps(
UserOpsPerAggregator[] calldata opsPerAggregator,
address payable beneficiary
) external;

2.1 handleOps​

ParameterDescription
opsUserOperations that do not use a signature aggregator
beneficiaryAddress that receives the actual Gas fees for the batch

EntryPoint validates the entire batch before executing each account's callData. A validation error can revert the entire batch. A business-execution revert is recorded through an event and does not necessarily revert the outer transaction.

2.2 handleAggregatedOps​

Use this method when accounts return a non-zero signature aggregator. UserOperations are grouped by aggregator, and each group carries an aggregated signature. Use handleOps when signature aggregation is not required.

UserOpsPerAggregator contains:

FieldTypeDescription
userOpsPackedUserOperation[]Operations handled by the current aggregator
aggregatorIAggregatorAggregator for the group; only in handleAggregatedOps, a zero-address group means that no aggregation is needed
signaturebytesAggregated signature for the group

3. Hash, nonce, and address​

function getUserOpHash(
PackedUserOperation calldata userOp
) external view returns (bytes32);

function getNonce(
address sender,
uint192 key
) external view returns (uint256 nonce);

function incrementNonce(uint192 key) external;

function getSenderAddress(bytes memory initCode) external;

3.1 getUserOpHash​

Returns the UserOperation hash that the account must validate. The hash binds:

  • UserOperation content, excluding signature
  • Current EntryPoint address
  • Current chainId

Changing any participating field after signing invalidates the signature.

3.2 getNonce​

Returns the next complete nonce for an account and nonce key:

nonce = uint192 key || uint64 sequence

SimpleAccount uses key 0 by default. Do not substitute the Owner EOA transaction nonce or the smart account's eth_getTransactionCount.

3.3 incrementNonce​

Allows a caller to advance the sequence for one of its nonce keys. Standard accounts usually rely on EntryPoint to update the nonce after successful validation.

3.4 getSenderAddress​

Calculates a counterfactual account address from initCode. The method always reverts and returns the result through the custom error SenderAddressResult(address sender).

4. Deposit and stake​

function getDepositInfo(
address account
) external view returns (DepositInfo memory info);

function balanceOf(address account)
external view returns (uint256);

function depositTo(address account) external payable;

function withdrawTo(
address payable withdrawAddress,
uint256 withdrawAmount
) external;

function addStake(uint32 unstakeDelaySec) external payable;

function unlockStake() external;

function withdrawStake(
address payable withdrawAddress
) external;

4.1 Deposit​

A deposit is the balance that an account or Paymaster pre-funds in EntryPoint to pay UserOperation Gas.

MethodDescription
balanceOfQueries an entity's deposit
getDepositInfoQueries deposit, stake, and unlock state together
depositToAllows any address to fund the specified entity
withdrawToWithdraws the caller's own deposit

4.2 Stake​

A stake is locked by a Factory, Paymaster, or aggregator to satisfy validation and reputation rules. It is not used directly to pay UserOperation Gas.

MethodDescription
addStakeAdds stake and sets a minimum unlock delay
unlockStakeBegins the unlock waiting period
withdrawStakeWithdraws the stake after the waiting period

Deposit and stake are independent. A stake alone cannot pay Gas, and a deposit alone does not necessarily satisfy the Bundler's stake requirement for entities that access restricted storage.

5. Core events​

EventKey fieldsPurpose
UserOperationEventuserOpHash, sender, paymaster, nonce, success, actualGasCost, actualGasUsedDetermines the final result of each UserOperation
AccountDeployeduserOpHash, sender, factory, paymasterRecords counterfactual account deployment
UserOperationRevertReasonuserOpHash, sender, nonce, revertReasonRecords revert data from the account's business call
PostOpRevertReasonuserOpHash, sender, nonce, revertReasonRecords a Paymaster postOp revert
UserOperationPrefundTooLowuserOpHash, sender, nonceRecords insufficient prefund during execution
BeforeExecutionNoneSeparates validation-stage and execution-stage events
Deposited / Withdrawnaccount, amountRecords deposit changes
StakeLocked / StakeUnlocked / StakeWithdrawnaccount, stake, timeRecords the stake lifecycle

A successful outer handleOps transaction does not mean that every UserOperation succeeded. Use UserOperationEvent.success as the result.

6. Core errors​

ErrorDescription
FailedOp(opIndex, reason)The specified UserOperation failed during validation or prefunding
FailedOpWithRevert(opIndex, reason, inner)Failure with internal revert data from an account, Factory, or Paymaster
PostOpReverted(returnData)Paymaster postOp reverted
SignatureValidationFailed(aggregator)Aggregated signature validation failed
SenderAddressResult(sender)Expected result carrier for getSenderAddress