RIP-7560 Bundler

We provide a bundler compatible with Pioneer Devnet Alpha. The design philosophy behind this, is to keep changes from ERC-4337 as minimal as possible. Thus, in most cases, wallet providers will be able to rely on the same RPC method and UserOp format to send AA_TX_TYPE transactions. You will find a detailed demonstration about how it is implemented.

Note that the designed specification of this bundler is temporary and dedicated to Pioneer Devnet Alpha. It can be changed in the future with the design discussion.

Currently, the RIP-7560 bundler is implemented based on Stackup’s bundler. It internally converts the given ERC-4337 UserOp into AA_TX_TYPE format, collects them in a bundle and checks ERC-7562 rules, and calls eth_sendRip7560TransactionsBundle to make it included in the block.

There are 5 RPC endpoints that are supported by an ERC-4337 bundler:

  • eth_sendUserOperation

  • eth_estimateUserOperationGas

  • eth_getUserOperationByHash

  • eth_getUserOperationReceipt

  • eth_supportedEntryPoints

Pioneer Devnet Alpha bundler supports 3 methods among these:

  • eth_sendTransaction

  • eth_estimateGas

  • eth_getTransactionReceipt

  • eth_getTransactionHash

The format of request / response of each endpoints is as follows

eth_sendTransaction

Input

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_sendTransaction",
  "params": [
    {
      "from": "0x0000000000000000000000000000000000007560",
      "to": null,
      "gas": "0x1E8480",
      "gasPrice" : "0x3",
      "maxFeePerGas": "0x3B9ACA00", // 1Gwei,
      "maxPriorityFeePerGas" : "0x3B9ACA00", // 1Gwei,
      "executionData": "0xb61d27f60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000246057361d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000",
      "sender": "0x581dF454a2Db28c033D3A70738B97e824E67e229",
      "paymaster": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
      "paymasterData": "0x",
      "deployer": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
      "deployerData": "0x5fbfb9cf000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000000",
      "builderFee" : "0x186A0", //not used
      "verificationGasLimit" : "0xF4240",
      "paymasterVerificationGasLimit" : "0xF4240",
      "paymasterPostOpGasLimit" : "0xF4240",
      "authorizationData" : "0x",
      "nonceKey": "0x0",
      "nonce": "0x0" // Every contract has nonce starting from 1, not 0
    }
  ]
}

Output

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": "0x2d4497fff29c29006ae26b526afed17ced799eb3069e527e7eac2b312bb280d3"
}

This method returns the hash of the AA_TX_TYPE transaction, which is converted from the given userOp input. Note that it is NOT the hash of userOp itself.

eth_estimateGas

Input

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_estimateGas",
  "params": [
    {
      "from": "0x0000000000000000000000000000000000007560",
      "to": null,
      "gas": "0x1E8480",// 2,000,000 ,//AA_BASE_GAS_COST, 15,000
      "gasPrice" : "0x3",
      "maxFeePerGas": "0x3B9ACA00", // 1Gwei,
      "maxPriorityFeePerGas" : "0x3B9ACA00", // 1Gwei,
      "executionData": "0xb61d27f60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000246057361d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000",
      "sender": "0x9B66A37015f36Af242e0a3B7896306CEc5b3d5A1",
      "paymaster": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
      "paymasterData": "0x",
      "deployer": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
      "deployerData": "0x5fbfb9cf000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000000",
      "builderFee" : "0x186A0", //not used
      "verificationGasLimit" : "0xF4240", //1,000,000
      "paymasterVerificationGasLimit" : "0xF4240", //1,000,000
      "paymasterPostOpGasLimit" : "0xF4240", //1,000,000
      "authorizationData" : "0x",
      "nonceKey": "0x0",
      "nonce": "0x0" // Every contract has nonce starting from 1, not 0
    }
  ]
}

Output

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "verificationGasLimit": 181024,
    "callGasLimit": 28375
  }
}

verificationGasLimit and verificationGas have the same value, since they were introduced to maintain compatibility between Entrypoint v0.6 and v0.7. We decided to remain this as is in Pioneer Alpha.

eth_getTransactionReceipt

Input

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getTransactionReceipt",
  "params": [
    "0x2d4497fff29c29006ae26b526afed17ced799eb3069e527e7eac2b312bb280d3"
  ]
}

Output

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "type": "0x4",
    "root": "0x6cc6f1ba70121b4bf909f3a0d9dbbad40c8cff41de306f8a6451bf873a1fdfc3",
    "status": "0x0",
    "cumulativeGasUsed": "0x33af1",
    "logsBloom": "0x00000000000000000000000010000000400000000000000000000004000000000000000000000000000000000008000000000000000000000000000000000000000000004000000000000000000002000000000000000000000000000000000000081000000000000020000100000000000000000200000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000008000000000000000000000000000000000000000000000000000020002000280000000000000000000000002004000000000000000000000000000000000000000000000000000000040000000000000000000000000000",
    "logs": [
      {
        "address": "0x581df454a2db28c033d3a70738b97e824e67e229",
        "topics": [
          "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b",
          "0x000000000000000000000000a16e02e87b7454126e5e10d957a927a7f5b5d2be"
        ],
        "data": "0x",
        "blockNumber": "0x15b",
        "transactionHash": "0x2d4497fff29c29006ae26b526afed17ced799eb3069e527e7eac2b312bb280d3",
        "transactionIndex": "0x2",
        "blockHash": "0x17684dd173889fd53a8cde2be14af5e8f1c6f28db7dad9871eb460dd553ca554",
        "logIndex": "0x0",
        "removed": false
      },
      {
        "address": "0x581df454a2db28c033d3a70738b97e824e67e229",
        "topics": [
          "0xec0419c624b28198777e7294893fe091f48b45dad1fd486dc929cb8e15b2b260",
          "0x0000000000000000000000000000000000000000000000000000000000007560",
          "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266"
        ],
        "data": "0x",
        "blockNumber": "0x15b",
        "transactionHash": "0x2d4497fff29c29006ae26b526afed17ced799eb3069e527e7eac2b312bb280d3",
        "transactionIndex": "0x2",
        "blockHash": "0x17684dd173889fd53a8cde2be14af5e8f1c6f28db7dad9871eb460dd553ca554",
        "logIndex": "0x1",
        "removed": false
      },
      {
        "address": "0x581df454a2db28c033d3a70738b97e824e67e229",
        "topics": [
          "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2"
        ],
        "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
        "blockNumber": "0x15b",
        "transactionHash": "0x2d4497fff29c29006ae26b526afed17ced799eb3069e527e7eac2b312bb280d3",
        "transactionIndex": "0x2",
        "blockHash": "0x17684dd173889fd53a8cde2be14af5e8f1c6f28db7dad9871eb460dd553ca554",
        "logIndex": "0x2",
        "removed": false
      }
    ],
    "transactionHash": "0x2d4497fff29c29006ae26b526afed17ced799eb3069e527e7eac2b312bb280d3",
    "contractAddress": "0x0000000000000000000000000000000000000000",
    "gasUsed": "0x33af1",
    "effectiveGasPrice": "0x3b9aca00",
    "blockHash": "0x17684dd173889fd53a8cde2be14af5e8f1c6f28db7dad9871eb460dd553ca554",
    "blockNumber": "0x15b",
    "transactionIndex": "0x2",
    "l1GasPrice": "0x7",
    "l1BlobBaseFee": "0x1",
    "l1GasUsed": "0x7b0",
    "l1Fee": "0x35d4",
    "l1BaseFeeScalar": "0xf4240",
    "l1BlobBaseFeeScalar": "0x0"
  }
}

eth_getTransactionHash

Input

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getTransactionHash",
  "params": [
    {
      "from": "0x0000000000000000000000000000000000007560",
      "to": null,
      "gas": "0x1E8480",
      "gasPrice" : "0x3",
      "maxFeePerGas": "0x3B9ACA00", // 1Gwei,
      "maxPriorityFeePerGas" : "0x3B9ACA00", // 1Gwei,
      "executionData": "0xb61d27f60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000246057361d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000",
      "sender": "0x581dF454a2Db28c033D3A70738B97e824E67e229",
      "paymaster": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
      "paymasterData": "0x",
      "deployer": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
      "deployerData": "0x5fbfb9cf000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000000",
      "builderFee" : "0x186A0", //not used
      "verificationGasLimit" : "0xF4240",
      "paymasterVerificationGasLimit" : "0xF4240",
      "paymasterPostOpGasLimit" : "0xF4240",
      "authorizationData" : "0x",
      "nonceKey": "0x0",
      "nonce": "0x0" // Every contract has nonce starting from 1, not 0
    }
  ]
}

Output

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": "0x2d4497fff29c29006ae26b526afed17ced799eb3069e527e7eac2b312bb280d3"
}

Note that unlike eth_getUserOperationReceipt in the ERC-4337 bundler, eth_getTransactionReceipt does not return a value in the form of the previous userOp receipt. Instead, it returns the actual transaction receipt as computed by the executing client.

eth_getUserOperationByHash is not supported in Pioneer DevNet Alpha. If you want the same functionality, you can call eth_getTransactionByHash with the hash returned from eth_sendTransaction on the execution client. You can also use eth_getTransactionHash to double-check the hash of a transaction.

Also note that you can't send AA_TX_TYPE directly to the sequencer. All AA_TX_TYPE transactions must go through a bundler via the eth_sendTransaction API.

Last updated