ZAN Bundler Guide

Users can effortlessly utilize our Bundler service with minimal learning curve, similar to how they use node services. Our bundler implementation is fully compliant with ERC-4337, which establishes rules and standards for bundler behavior and security. It has successfully passed the test suite to ensure a reliable and trustworthy service for users.

Our Advantages

  1. Reliable: ZAN bundler currently maintains 100% coverage of the test suite. While the specification is still being developed, our future iterations will aim to ensure complete compliance coverage remains intact.
  2. Low latency: ZAN bundler has been specifically optimized for minimizing userOperation latency. With our optimizations in place, userOperation are immediately packaged upon entering our mempool, eliminating the need for any waiting time (instant bundling policy). Additionally, we employ a parallel transaction sending architecture to prevent the aforementioned instant bundling policy from impacting the bundling of subsequent user userOperations, thereby enhancing overall throughput.
  3. Additional query API: ZAN bundler provides addition query API to improve user experience. For example, users can call zan_bundler_getUserOperationStatus API to query the status of their sent userOperations to determine whether they have been dropped, awaiting bundling, or already included in the blockchain.

Supported Network

The networks we support:

  • Ethereum
    • Sepolia
    • Goerli
  • Polygon
    • Mainnet
    • Mumbai

How to Use ZAN Bundler

Please refer to API Reference for API definitions. Here, we will introduce how to use these APIs.

πŸ“˜

Note:

the Bundler API is currently in beta stage, and the pricing for eth_sendUserOperation and eth_estimateUserOperationGas credits is set at 100. After the official release, the pricing for credits will be adjusted.

eth_supportedEntryPoints

The method eth_supportedEntryPoints returns the entrypoint address currently supported by the bundler.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_supportedEntryPoints",
  "params": []
}
{
  "jsonrpc": "2.0",
  "id": 1,

  // EntryPoint addresses
  "result": [
    "0x...",
    "0x..."
  ]
}

eth_estimateUserOperationGas

The method eth_estimateUserOperationGas returns estimates for PreVerificationGas, VerificationGas, and CallGasLimit given a UserOperation and EntryPoint address. Please note that the signature and gas price related fields in the parameters will not be verified. You can set these fields to empty values, but for accurate estimation, it is recommended to make the length of the field values consistent with the real situation.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_estimateUserOperationGas",
  "params": [
    // UserOperation object
    {
      sender,
      nonce,
      initCode,
      callData,
      callGasLimit,
      verificationGasLimit,
      preVerificationGas,
      maxFeePerGas,
      maxPriorityFeePerGas,
      paymasterAndData,
      signature
    },

    // Supported EntryPoint address
    entryPoint
  ]
}
{
  "jsonrpc": "2.0",
  "id": 1,

  // The return values are the hex strings for wei values.
  "result": {
		"preVerificationGas": "0x..",
		"verificationGasLimit": "0x..",
		"callGasLimit":       "0x..",
	}
}

eth_sendUserOperation

The method eth_sendUserOperation sends the UserOperation to the mempool of bundler and returns the userOpHash. The userOpHash is a hash over the userOp (except signature), entryPoint and chainId. The bundler will fetch the UserOperations from the mempool, and after passing validity checks, the UserOperations will be included in the transaction.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_sendUserOperation",
  "params": [
    // UserOperation object
    {
      sender,
      nonce,
      initCode,
      callData,
      callGasLimit,
      verificationGasLimit,
      preVerificationGas,
      maxFeePerGas,
      maxPriorityFeePerGas,
      paymasterAndData,
      signature
    },

    // Supported EntryPoint address
    entryPoint
  ]
}
{
  "jsonrpc": "2.0",
  "id": 1,

  // UserOpHash
  "result": "0x..."
}

eth_getUserOperationByHash

The method eth_getUserOperationByHash returns the UserOperation and transaction information of a given userOpHash.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getUserOperationByHash",
  "params": [userOpHash]
}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getUserOperationByHash",
  "params": [
    // UserOperation object
    {
      sender,
      nonce,
      initCode,
      callData,
      callGasLimit,
      verificationGasLimit,
      preVerificationGas,
      maxFeePerGas,
      maxPriorityFeePerGas,
      paymasterAndData,
      signature
    },
    // The EntryPoint address
    entryPoint,
    // The block number this UserOperation was included in
    blockNumber,
    // The block hash this UserOperation was included in
    blockHash,
    // The transaction hash this UserOperation was included in
    transactionHash,
  ]
}

eth_getUserOperationReceipt

The method eth_getUserOperationReceipt returns the receipt of a given userOpHash.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getUserOperationReceipt",
  "params": [userOpHash]
}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getUserOperationReceipt",
  "params": [
    // The hash of the UserOperation
    userOpHash,
    // The EntryPoint address
    entryPoint,
    // The contract account address
    sender,
    // nonce of the UserOperation
    nonce,
    // The paymaster address
    paymaster,
    // The actual amount paid for this UserOperation
    actualGasCost,
    // The total gas used by this UserOperation
    actualGasUsed,
    // Boolean value indicating if the execution completed without revert
    success,
    // If revert occurred, this is the reason
    reason,
    // logs generated by this UserOperation only
    logs,
    // The TransactionReceipt object for the entire bundle.
    receipt
  ]
}

zan_getUserOperationStatus

The method zan_getUserOperationStatus return the UserOperation status of a given userOpHash. The result is based on the perspective of the bundler. The value of status is one of the following values: not_found, accepted, dropped and included.

  • not_found: UserOperation not found in mempool based on given UserOpHash
  • accepted: UserOperation is in mempool, waitting to be bundled
  • dropped: UserOperation is dropped from mempool by some reasons
  • included: UserOperation is included in blockchain

If the returned status is "included", the result will include the transactionHash. Otherwise, the transactionHash will be null.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "zan_getUserOperationStatus",
  "params": [userOpHash]
}
{
  "jsonrpc": "2.0",
  "id": 1,

   "result": {
		"status": "included",
		"transactionHash": "0x..",
	}
}
{
  "jsonrpc": "2.0",
  "id": 1,

   "result": {
		"status": "not_found",
		"transactionHash": null,
	}
}