Integrate MegaFuel with an ERC-4337 Wallet
Integrate MegaFuel with an ERC-4337 Wallet
This guide shows the wallet-side sequence for a MegaFuel-sponsored UserOperation. MegaFuel signs the paymaster authorization; the wallet still builds the UserOperation and creates the smart-account signature.
Endpoints
# Mainnet (chain ID 56 / 0x38)
PAYMASTER_URL=https://bsc-megafuel.nodereal.io/4337/paymaster
BUNDLER_URL=https://bsc-megafuel.nodereal.io/4337/bundler
# Testnet (chain ID 97 / 0x61)
PAYMASTER_URL=https://bsc-megafuel-testnet.nodereal.io/4337/paymaster
BUNDLER_URL=https://bsc-megafuel-testnet.nodereal.io/4337/bundlerAll requests are JSON-RPC 2.0 HTTPS POST requests with Content-Type: application/json.
Integration sequence
- Choose one EntryPoint returned by
eth_supportedEntryPoints. - Build the UserOperation with the sender, nonce, account call, fee fields, and factory information if the account is counterfactual.
- Call
pm_getPaymasterStubData. - Put the returned stub paymaster fields into the operation and attach a structurally valid dummy account signature for estimation.
- Call
eth_estimateUserOperationGason MegaFuel's Bundler and use its gas limits. - Call
pm_getPaymasterDatawith the final gas fields. It performs the policy check and returns short-lived, signed paymaster data. - Put the final paymaster fields into the operation, calculate the EntryPoint-specific UserOperation hash, and obtain the account signature according to your account's
validateUserOprules. - Submit the final operation with
eth_sendUserOperation. - Poll
eth_getUserOperationReceiptuntil it returns a receipt.
Do not alter fields covered by the account or paymaster authorization after the final paymaster response. If a field changes, restart at paymaster-data requesting and sign the new UserOperation hash.
1. Discover supported EntryPoints
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_supportedEntryPoints",
"params": []
}Send this request to BUNDLER_URL. The returned address determines the version and JSON encoding to use.
2. Build the v0.7 / v0.8 operation
For v0.7 and v0.8, use the packed-family JSON fields. All quantities are hex-encoded quantities and all byte arrays are 0x-prefixed hex.
{
"sender": "0x<SMART_ACCOUNT>",
"nonce": "0x0",
"factory": "0x<FACTORY>",
"factoryData": "0x<CREATE_ACCOUNT_CALLDATA>",
"callData": "0x<SMART_ACCOUNT_EXECUTE_OR_EXECUTE_BATCH_CALLDATA>",
"callGasLimit": "0x0",
"verificationGasLimit": "0x0",
"preVerificationGas": "0x0",
"maxFeePerGas": "0x<MAX_FEE_PER_GAS>",
"maxPriorityFeePerGas": "0x<MAX_PRIORITY_FEE_PER_GAS>",
"signature": "0x<DUMMY_OR_FINAL_ACCOUNT_SIGNATURE>"
}Omit factory and factoryData for an already deployed account. In an estimation request, omit the three account gas fields rather than treating 0x0 as a final gas limit.
v0.6: use a distinct unpacked operation
EntryPoint v0.6 does not use the v0.7/v0.8 packed-family fields. Its Bundler operation must use this classic, unpacked shape:
{
"sender": "0x<SMART_ACCOUNT>",
"nonce": "0x0",
"initCode": "0x<20_BYTE_FACTORY_ADDRESS><CREATE_ACCOUNT_CALLDATA>",
"callData": "0x<SMART_ACCOUNT_EXECUTE_CALLDATA>",
"callGasLimit": "0x0",
"verificationGasLimit": "0x0",
"preVerificationGas": "0x0",
"maxFeePerGas": "0x<MAX_FEE_PER_GAS>",
"maxPriorityFeePerGas": "0x<MAX_PRIORITY_FEE_PER_GAS>",
"paymasterAndData": "0x<20_BYTE_PAYMASTER_ADDRESS><PAYMASTER_DATA>",
"signature": "0x<DUMMY_OR_FINAL_ACCOUNT_SIGNATURE>"
}For an already deployed account, set initCode to 0x. initCode is the factory address followed immediately by the factory calldata; it is not the separate factory / factoryData representation used by v0.7/v0.8.
Use the normal MegaFuel paymaster RPC calls to obtain stub and final paymaster data. When a counterfactual v0.6 account needs deployment, provide the equivalent factory and factoryData values to those paymaster calls. For the v0.6 Bundler calls, convert them back to initCode as shown above.
For eth_estimateUserOperationGas and eth_sendUserOperation, build paymasterAndData exactly as:
paymasterAndData = paymaster (20 bytes) || paymasterDataUse stub paymasterData for estimation and final paymasterData for submission. Do not include v0.7/v0.8's two 16-byte paymaster gas-limit fields in v0.6 paymasterAndData; those fields do not exist in EntryPoint v0.6. Compute the UserOperation hash with the v0.6 EntryPoint over this unpacked tuple, then sign it using the signature scheme required by the selected account implementation.
3. Obtain stub paymaster data
Call the paymaster endpoint before estimating gas:
{
"jsonrpc": "2.0",
"id": 2,
"method": "pm_getPaymasterStubData",
"params": [
{
"sender": "0x<SMART_ACCOUNT>",
"nonce": "0x0",
"callData": "0x<ACCOUNT_CALLDATA>",
"maxFeePerGas": "0x<MAX_FEE_PER_GAS>",
"maxPriorityFeePerGas": "0x<MAX_PRIORITY_FEE_PER_GAS>",
"signature": "0x<DUMMY_ACCOUNT_SIGNATURE>"
},
"0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
"0x38",
{}
]
}For Testnet, use chain ID 0x61. Replace the EntryPoint with the selected v0.7 or v0.6 address as applicable.
The response has this shape:
{
"paymaster": "0x<MEGAFUEL_PAYMASTER>",
"paymasterData": "0x<STUB_DATA>",
"paymasterVerificationGasLimit": "0x...",
"paymasterPostOpGasLimit": "0x..."
}For v0.7/v0.8, copy the response to the matching separate operation fields. The stub is only for simulation/estimation; it is not a usable sponsorship authorization.
4. Estimate gas
Submit the stub-filled operation to the Bundler:
{
"jsonrpc": "2.0",
"id": 3,
"method": "eth_estimateUserOperationGas",
"params": [
{
"sender": "0x<SMART_ACCOUNT>",
"nonce": "0x0",
"callData": "0x<ACCOUNT_CALLDATA>",
"maxFeePerGas": "0x<MAX_FEE_PER_GAS>",
"maxPriorityFeePerGas": "0x<MAX_PRIORITY_FEE_PER_GAS>",
"paymaster": "0x<MEGAFUEL_PAYMASTER>",
"paymasterVerificationGasLimit": "0x<STUB_PM_VERIFICATION_GAS>",
"paymasterPostOpGasLimit": "0x<STUB_PM_POSTOP_GAS>",
"paymasterData": "0x<STUB_DATA>",
"signature": "0x<DUMMY_ACCOUNT_SIGNATURE>"
},
"0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
]
}Use the returned callGasLimit, verificationGasLimit, and preVerificationGas. Also use returned paymaster gas limits when present. The service signs the final paymaster authorization over the relevant operation fields, so do not substitute arbitrary larger limits after the final request.
5. Obtain final paymaster data
Call pm_getPaymasterData with the estimated gas fields and the same selected EntryPoint and chain ID.
{
"jsonrpc": "2.0",
"id": 4,
"method": "pm_getPaymasterData",
"params": [
{
"sender": "0x<SMART_ACCOUNT>",
"nonce": "0x0",
"callData": "0x<ACCOUNT_CALLDATA>",
"callGasLimit": "0x<ESTIMATED_CALL_GAS>",
"verificationGasLimit": "0x<ESTIMATED_VERIFICATION_GAS>",
"preVerificationGas": "0x<ESTIMATED_PREVERIFICATION_GAS>",
"maxFeePerGas": "0x<MAX_FEE_PER_GAS>",
"maxPriorityFeePerGas": "0x<MAX_PRIORITY_FEE_PER_GAS>",
"paymasterVerificationGasLimit": "0x<ESTIMATED_PM_VERIFICATION_GAS>",
"paymasterPostOpGasLimit": "0x<ESTIMATED_PM_POSTOP_GAS>",
"signature": "0x<DUMMY_ACCOUNT_SIGNATURE>"
},
"0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
"0x38",
{}
]
}Success returns paymaster, final paymasterData, and the two paymaster gas limits. An error means MegaFuel will not sponsor the operation; nothing has been sent to the chain. Show a useful error to the user or use an alternative, user-paid path when your product supports one.
6. Sign and send
Set the final paymaster fields, calculate getUserOpHash using the selected EntryPoint's exact version, and obtain the account signature. Do not use a generic signing method unless that is precisely what your smart account's validateUserOp expects.
Then call:
{
"jsonrpc": "2.0",
"id": 5,
"method": "eth_sendUserOperation",
"params": [
{ "...": "complete signed UserOperation" },
"0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
]
}The result is a userOpHash, not an Ethereum transaction hash. Store it with the user action so that the wallet can recover status later.
7. Track completion
Poll the Bundler endpoint:
{
"jsonrpc": "2.0",
"id": 6,
"method": "eth_getUserOperationReceipt",
"params": ["0x<USER_OP_HASH>"]
}null means the UserOperation is not yet included. A non-null result includes the transactionHash, blockNumber, success, actualGasCost, sender, and paymaster. Use eth_getUserOperationByHash when you need the full submitted operation and its current outer transaction reference.
Multi-operation nonce handling
Use the EntryPoint's UserOperation nonce—not the owner EOA's transaction nonce. For multiple pending operations from one smart account and nonce key, query MegaFuel's optional nr_getPendingUserOperationNonce extension, then submit promptly. The returned value is a point-in-time queue view, not a reservation; handle a conflict by re-querying and rebuilding the UserOperation. See the RPC reference.
Updated 42 minutes ago

