OpenChainGraph Suite · ART-613 · ERC-4337 Account Abstraction

ERC-4337 UserOperation Math

Three deterministic legs over bytes you already hold. First, the userOpHash recompute: keccak256(abi.encode(keccak256(packedUserOp), entryPoint, chainId)). Second, the EntryPoint's required prefund, computed from the gas limits you supply. Third, a reconciliation of a paymaster charge you declare against one recomputed from your own declared inputs. Nothing here is fetched: no RPC, no indexer, no receipt lookup, no contract state.

ERC-4337 v0.6 and v0.7keccak256 (vendored, no hand-rolled crypto)Recompute and reconcile only, no settlement claim
๐Ÿ”’ All inputs are processed locally in your browser. No data is transmitted. Do not enter real personal data โ€” use synthetic or anonymised inputs only.
What This Does and Does Not Prove

This node recomputes the exact 32 bytes an ERC-4337 account signs, from the UserOperation fields you supply. It does not verify a signature or recover a signer address, and the ERC-4337 specification itself excludes the signature from the hashed struct, so supplying one changes nothing. A recomputed hash is not an inclusion, and a reconciled charge is not a settlement. This node never reads chain state: it cannot tell you whether the account exists, whether the EntryPoint holds a deposit, whether the nonce is still valid, or whether the operation was ever mined.

The EntryPoint version is yours to declare, and it changes what gets hashed. v0.6 hashes a ten-word UserOperation pack. v0.7 hashes an eight-word PackedUserOperation, in which verificationGasLimit and callGasLimit pack into a single accountGasLimits word and maxPriorityFeePerGas and maxFeePerGas pack into gasFees. The prefund formulas differ as well. Guessing the version would silently produce a wrong hash that still looks perfectly well formed, so this node refuses to guess: an unrecognised version returns INDETERMINATE rather than falling back to either layout.

What This Node Never Fetches

L1 data and blob fees are never derived. On rollups the total charge includes an L1 data-fee component that, after EIP-4844, depends on the inclusion-time L1 basefee and blob basefee. Neither is derivable offline from a UserOperation, so this node does not compute them. An L1 data fee enters the reconciliation only when you declare it, and when you do not, its absence is reported as a named gap rather than quietly absorbed into a residual.

The value block.basefee is never fetched either. The effective gas price is min(maxFeePerGas, maxPriorityFeePerGas + block.basefee). When your two fee caps are equal, the EntryPoint's own legacy shortcut returns maxFeePerGas directly and the basefee drops out, so the price is fully derivable offline. When they differ, the price is reported as null with the reason unless you declare a basefee. It is never guessed.

EntryPoint (declared, never inferred)
Both are hashed into the userOpHash, so neither is defaulted. The address you enter is what gets hashed; this node only flags whether it matches the widely published canonical deployment for the version you declared, and never substitutes it.
UserOperation Fields
Use 0x for an empty field. Under v0.7 the first 52 bytes of paymasterAndData carry the paymaster address, its verification gas limit, and its postOp gas limit; a shorter value is reported as not carrying them rather than back-filled with zeros.
Caller-Supplied Gas Limits and Fee Caps
Every value here is yours. This node applies each version's own prefund formula to them and never checks them against a deployed EntryPoint.
Paymaster Reconciliation (all inputs declared, all optional)
Leave any field blank to declare nothing. A blank field is treated as undeclared and named in the output, never as a zero.
userOpHash (the bytes the account signs)
Packed Struct Hash
Pack Layout
EntryPoint version
Words hashed
accountGasLimits
gasFees
EntryPoint matches canonical
Gas Accounting
Paymaster Reconciliation
Never Fetched
Execution Hash (SHA-256)