Smart Account (ERC-4337) UserOp Builder
Build an ERC-4337 UserOperation for EntryPoint v0.6 or v0.7 and see its JSON, packed encoding, and UserOpHash.
How to use the Smart Account (ERC-4337) UserOp Builder
- Pick v0.6 or v0.7 from the EntryPoint Version selector — the tool defaults to v0.7.
- Fill in Sender, Nonce, Call Data, the three gas limit fields, and the two fee fields (in Gwei) — the tool is prefilled with a working example so all outputs render immediately.
- If a field is invalid, an alert names the offending field and the output panels are hidden until it's fixed.
- Open Factory (account deployment) (labeled Init Code (account deployment) in v0.6) only when this UserOperation deploys a new smart account; open Paymaster only when a paymaster sponsors gas. Leaving either closed/blank omits those fields from the built UserOperation.
- In the UserOpHash panel, set the Chain ID and EntryPoint Address (defaults to the canonical address for whichever version is selected, and updates automatically when you switch versions unless you've typed a custom address) to compute the exact hash that would need to be signed.
- Each panel has its own Copy button; the PackedUserOperation panel only appears for v0.7.
See it in action
This is exactly what the tool shows by default — EntryPoint v0.7, chain ID 1, and the built-in example values — so you can compare it directly against what your own browser renders with no fields changed:
Input (defaults, nothing edited): Nonce 0, Call Data 0xdeadbeef, Call Gas Limit 100000, Verification Gas Limit 70000, Pre-Verification Gas 50000, Max Fee Per Gas 2 Gwei, Max Priority Fee Per Gas 1 Gwei, Chain ID 1, plus the Sender and EntryPoint Address (v0.7's canonical address) below:
Sender:
0x1234567890AbcdEF1234567890aBcdef12345678
EntryPoint Address:
0x0000000071727De22E5E9d8BAf0edAc6f37da032
UserOperation JSON:
{
"sender": "0x1234567890AbcdEF1234567890aBcdef12345678",
"nonce": "0",
"callData": "0xdeadbeef",
"callGasLimit": "100000",
"verificationGasLimit": "70000",
"preVerificationGas": "50000",
"maxFeePerGas": "2000000000",
"maxPriorityFeePerGas": "1000000000",
"signature": "0xababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab"
}
UserOpHash:
0xeee1df9b42a4a16e9a1b39609365a044e56dfa3d3a9cc6e8cc6b602d3c95ae3d
With a factory and paymaster
The default above is the common case — an already-deployed account paying its own gas — so its Factory and Paymaster sections stay closed. Opening both and filling them in changes the built UserOperation, and is also the only way to see the PackedUserOperation panel populate fields beyond the defaults. Starting from the same input above, plus:
Factory Address:
0xfac700000000000000000000000000000000000f
Factory Data:
0xcafebabe
Paymaster Address:
0xed00000000000000000000000000000000000001
Paymaster Verification Gas Limit 50000, Paymaster Post-Op Gas Limit 20000, Paymaster Data:
0xfeedface
UserOperation JSON now carries both sets of fields:
{
"sender": "0x1234567890AbcdEF1234567890aBcdef12345678",
"nonce": "0",
"callData": "0xdeadbeef",
"callGasLimit": "100000",
"verificationGasLimit": "70000",
"preVerificationGas": "50000",
"maxFeePerGas": "2000000000",
"maxPriorityFeePerGas": "1000000000",
"signature": "0xababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab",
"factory": "0xfac700000000000000000000000000000000000f",
"factoryData": "0xcafebabe",
"paymaster": "0xed00000000000000000000000000000000000001",
"paymasterVerificationGasLimit": "50000",
"paymasterPostOpGasLimit": "20000",
"paymasterData": "0xfeedface"
}
PackedUserOperation shows exactly how those fields fold together — factory/factoryData concatenate into initCode, and paymaster/its two gas limits/paymasterData concatenate into paymasterAndData:
{
"accountGasLimits": "0x00000000000000000000000000011170000000000000000000000000000186a0",
"callData": "0xdeadbeef",
"initCode": "0xfac700000000000000000000000000000000000fcafebabe",
"gasFees": "0x0000000000000000000000003b9aca0000000000000000000000000077359400",
"nonce": "0",
"paymasterAndData": "0xed000000000000000000000000000000000000010000000000000000000000000000c35000000000000000000000000000004e20feedface",
"preVerificationGas": "50000",
"sender": "0x1234567890AbcdEF1234567890aBcdef12345678",
"signature": "0xababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab"
}
UserOpHash changes too, since it's computed over the packed data:
0x13391878b7ca848cde5ff7381b62647eb0c2556c036854581a23ffe707c5440e
How This Tool Works
Pick EntryPoint v0.6 or v0.7 from the version selector, then fill in the Sender, Nonce, Call Data, gas limit, and fee fields — the UserOperation JSON and UserOpHash panels update instantly as you type, with no debounce. A PackedUserOperation panel also appears for v0.7, which has a packed on-chain representation; v0.6 doesn't, so that panel is hidden in v0.6 mode.
Open the Factory/Init Code or Paymaster sections only if this UserOperation deploys a new account or uses a paymaster — leaving them blank omits those fields entirely, matching a normal already-deployed, self-paying account. Which fields appear there matches whichever EntryPoint version is selected.
Set the Chain ID and EntryPoint address in the UserOpHash panel to compute the exact hash a smart account would need to sign — switching versions updates the EntryPoint address to that version's canonical default automatically, unless you've typed a custom one.