{
  "openrpc": "1.4.1",
  "info": {
    "title": "Unlinked relay JSON-RPC API",
    "version": "0.1.0",
    "description": "The public JSON-RPC API of the Unlinked relay (apps/relay): the bundler front, co-signer and deposit ledger in front of the PowPaymaster, an ERC-4337 v0.9 paymaster that sponsors operations of fresh EIP-7702 accounts in exchange for proof of work. Derived from the relay's code (apps/relay/src/relay.ts, policy.ts, errors.ts, server.ts) and checked against it by tests.\n\n- Transport: JSON-RPC 2.0 over `POST /` or `POST /rpc`, single requests or batches of 1 to 10; bodies up to 16 KB, sends up to 16 KB each and other methods up to 8 KB (pow_checkRecipient 1 KB). `GET /health` answers `{status, chainId, epochId, block, drain}` (200 when ready, else 503). CORS headers only for the operator's web origins.\n- Quantities are 0x hex strings; epoch ids and timestamps are JSON numbers.\n- Rate limits, per client network (an IPv4 address or an IPv6 /64) and per minute, in memory only: `epoch` 60 (eth_chainId, eth_supportedEntryPoints, pow_getEpoch), `receipt` 60 (receipts, status, op by hash), `account` 10 (pow_getAccountState and pow_checkRecipient together), `estimate` 5. Sends are protected by the proof itself; a client whose sends fail at or before the PoW check runs out of an `invalidSend` budget of 60 per minute. `x-rate-limit-class` names each method's class.\n- Privacy: no IP address, request body, address or hash is logged; the only address-keyed reads are pow_getAccountState (of a sender) and pow_checkRecipient (of an ETH send's recipient). The relay still sees the IP address and the time of every request.\n- Every refusal is `{code, message, data: {reason, …}}`; messages are fixed texts (no bundler or provider text is forwarded).",
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "name": "mainnet",
      "url": "https://relay.useunlinked.app",
      "summary": "Robinhood Chain mainnet (chain 4663)"
    },
    {
      "name": "local",
      "url": "http://127.0.0.1:14338",
      "summary": "The local e2e stack (`pnpm dev:stack`, chain 31337)"
    }
  ],
  "methods": [
    {
      "name": "eth_chainId",
      "summary": "The relay's chain id.",
      "params": [],
      "result": {
        "name": "chainId",
        "schema": {
          "type": "string",
          "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
          "description": "A 0x hex quantity without leading zeros."
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "epoch",
      "x-max-request-bytes": 8192,
      "examples": [
        {
          "name": "mainnet",
          "params": [],
          "result": {
            "name": "chainId",
            "value": "0x1237"
          }
        }
      ]
    },
    {
      "name": "eth_supportedEntryPoints",
      "summary": "EntryPoint v0.9 only.",
      "params": [],
      "result": {
        "name": "entryPoints",
        "schema": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/Address"
          },
          "minItems": 1,
          "maxItems": 1
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "epoch",
      "x-max-request-bytes": 8192,
      "examples": [
        {
          "name": "v0.9",
          "params": [],
          "result": {
            "name": "entryPoints",
            "value": [
              "0x433709009B8330FDa32311DF1C2AFA402eD8D009"
            ]
          }
        }
      ]
    },
    {
      "name": "pow_getEpoch",
      "summary": "The current epoch: work price, fee caps, exact gas profiles, PVG quotes, acceptance window, headroom and budget.",
      "description": "Served from the relay's per-block snapshot. Poll it on a fixed interval (the SDK uses 60 s), not right before mining: a read tied to a send would let the relay time your mining. A plain read is not demand for an on-demand keeper; a client waiting to send (its current epoch is overdue or too short for its op) passes { \"wait\": true }, and a due epoch is then rolled at once.",
      "params": [
        {
          "name": "options",
          "required": false,
          "description": "Only while waiting to send: { \"wait\": true } asks an on-demand relay (KEEPER_ROLL=on-demand) to roll a due epoch. Omit it for the background poll.",
          "schema": {
            "type": "object",
            "properties": {
              "wait": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          }
        }
      ],
      "result": {
        "name": "epoch",
        "schema": {
          "$ref": "#/components/schemas/EpochInfo"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/PaymasterRejected"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "epoch",
      "x-max-request-bytes": 8192,
      "examples": [
        {
          "name": "mainnet",
          "description": "An illustrative mainnet epoch (900 s epochs, COSIGNED + DELEGATE_CHECK).",
          "params": [],
          "result": {
            "name": "epoch",
            "value": {
              "chainId": 4663,
              "entryPoint": "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
              "paymaster": "0x4E77B4AF15b55E4FB354e92078D46f39Ca659375",
              "epochId": 1234,
              "start": 1790000000,
              "validFor": 1200,
              "epochLength": 900,
              "validUntil": 1790001200,
              "workPerGwei": "0x1388",
              "minWork": "0x1000000",
              "flags": 3,
              "minFeePerGas": "0x989680",
              "maxFeePerGas": "0x5f5e100",
              "maxPriorityFeePerGas": "0xf4240",
              "refFeePerGas": "0x14fb180",
              "cosigner": "0x7B6909A356267b3A1FeaCFF4feB317587078d40e",
              "seed": "0x5ac2c81d5b7a5f0e2f1d9c44",
              "maxOpCost": "0x1b48eb57e000",
              "maxVerificationGasLimit": "0x3d090",
              "maxCallGasLimit": "0x493e0",
              "maxPreVerificationGas": "0x493e0",
              "pmVerificationGasLimit": "0x11170",
              "pmPostOpGasLimit": "0x61a8",
              "acceptUntil": 1790001020,
              "nextRollAt": 1790000900,
              "headroomWei": "0x10a741a462780",
              "budgetRemainingWei": "0xf2bcd1d8a4c0",
              "gasProfiles": {
                "approve": {
                  "first": {
                    "verificationGasLimit": "0xc350",
                    "callGasLimit": "0xea60"
                  },
                  "regular": {
                    "verificationGasLimit": "0x7530",
                    "callGasLimit": "0xea60"
                  }
                },
                "sendEth": {
                  "first": {
                    "verificationGasLimit": "0xc350",
                    "callGasLimit": "0xc350"
                  },
                  "regular": {
                    "verificationGasLimit": "0x7530",
                    "callGasLimit": "0xc350"
                  }
                },
                "transfer": {
                  "first": {
                    "verificationGasLimit": "0xc350",
                    "callGasLimit": "0x13880"
                  },
                  "regular": {
                    "verificationGasLimit": "0x7530",
                    "callGasLimit": "0x13880"
                  }
                }
              },
              "pvgQuotes": {
                "approve": {
                  "first": "0x1f9b8",
                  "regular": "0x1c2a0"
                },
                "sendEth": {
                  "first": "0x1fa1c",
                  "regular": "0x1c304"
                },
                "transfer": {
                  "first": "0x1fb48",
                  "regular": "0x1c430"
                }
              },
              "pvgQuotedAt": 1790000412,
              "serverTime": 1790000415
            }
          }
        },
        {
          "name": "local",
          "description": "The local stack (60 s epochs, tiny work).",
          "params": [],
          "result": {
            "name": "epoch",
            "value": {
              "chainId": 31337,
              "entryPoint": "0x433709009B8330FDa32311DF1C2AFA402eD8D009",
              "paymaster": "0x1e763f7171465B6bb3d89A303f05F926e8a51F4E",
              "epochId": 7,
              "start": 1789999995,
              "validFor": 120,
              "epochLength": 60,
              "validUntil": 1790000115,
              "workPerGwei": "0x1",
              "minWork": "0x100",
              "flags": 3,
              "minFeePerGas": "0x1",
              "maxFeePerGas": "0x3b9aca00",
              "maxPriorityFeePerGas": "0xf4240",
              "refFeePerGas": "0x1",
              "cosigner": "0x90F79bf6EB2c4f870365E785982E1f101E93b906",
              "seed": "0x3039",
              "maxOpCost": "0x38d7ea4c68000",
              "maxVerificationGasLimit": "0x3d090",
              "maxCallGasLimit": "0x493e0",
              "maxPreVerificationGas": "0x30d40",
              "pmVerificationGasLimit": "0x11170",
              "pmPostOpGasLimit": "0x61a8",
              "acceptUntil": 1790000055,
              "nextRollAt": 1790000055,
              "headroomWei": "0xb1a2bc2ec50000",
              "budgetRemainingWei": "0xb1a2bc2ec50000",
              "gasProfiles": {
                "approve": {
                  "first": {
                    "verificationGasLimit": "0xc350",
                    "callGasLimit": "0x9c40"
                  },
                  "regular": {
                    "verificationGasLimit": "0x7530",
                    "callGasLimit": "0x9c40"
                  }
                },
                "claim": {
                  "first": {
                    "verificationGasLimit": "0xc350",
                    "callGasLimit": "0x19a28"
                  },
                  "regular": {
                    "verificationGasLimit": "0x7530",
                    "callGasLimit": "0x19a28"
                  }
                },
                "sendEth": {
                  "first": {
                    "verificationGasLimit": "0xc350",
                    "callGasLimit": "0xc350"
                  },
                  "regular": {
                    "verificationGasLimit": "0x7530",
                    "callGasLimit": "0xc350"
                  }
                },
                "transfer": {
                  "first": {
                    "verificationGasLimit": "0xc350",
                    "callGasLimit": "0xafc8"
                  },
                  "regular": {
                    "verificationGasLimit": "0x7530",
                    "callGasLimit": "0xafc8"
                  }
                }
              },
              "pvgQuotes": {
                "approve": {
                  "first": "0x1adb0",
                  "regular": "0x186a0"
                },
                "claim": {
                  "first": "0x1adb0",
                  "regular": "0x186a0"
                },
                "sendEth": {
                  "first": "0x1adb0",
                  "regular": "0x186a0"
                },
                "transfer": {
                  "first": "0x1adb0",
                  "regular": "0x186a0"
                }
              },
              "pvgQuotedAt": 1790000000,
              "serverTime": 1790000000
            }
          }
        }
      ]
    },
    {
      "name": "pow_getAccountState",
      "summary": "Delegation, EOA nonce, EntryPoint nonce (key 0), ETH balance and the non-zero allowlisted token balances of one address.",
      "description": "The only read keyed to a sender. Read one address at a time, at import or after a failure, never right before mining. Not logged. Shares the `account` rate class with pow_checkRecipient.",
      "params": [
        {
          "name": "address",
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "required": true
        }
      ],
      "result": {
        "name": "state",
        "schema": {
          "$ref": "#/components/schemas/AccountState"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        },
        {
          "$ref": "#/components/errors/InternalError"
        }
      ],
      "x-rate-limit-class": "account",
      "x-max-request-bytes": 8192,
      "examples": [
        {
          "name": "mainnet account holding USDG",
          "params": [
            {
              "name": "address",
              "value": "0x7777777777777777777777777777777777777777"
            }
          ],
          "result": {
            "name": "state",
            "value": {
              "address": "0x7777777777777777777777777777777777777777",
              "delegate": "0xa46cc63eBF4Bd77888AA327837d20b23A63a56B5",
              "delegated": true,
              "eoaNonce": "0x1",
              "epNonce": "0x2",
              "ethBalance": "0x0",
              "balances": {
                "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168": "0x2faf080"
              }
            }
          }
        }
      ]
    },
    {
      "name": "pow_checkRecipient",
      "summary": "Whether a sponsored ETH send to this address would pass the recipient rules (no code, or an EOA delegated to Simple7702Account v0.9; not below 2^32).",
      "description": "Ask it before mining an ETH send, so a refused recipient costs no proof. One eth_getCode of the recipient (none for the reserved range); never the sender; not logged. The sender-specific rules (not the sender itself, its balance) are checked at send time.",
      "params": [
        {
          "name": "address",
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "required": true
        }
      ],
      "result": {
        "name": "check",
        "schema": {
          "$ref": "#/components/schemas/RecipientCheck"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        },
        {
          "$ref": "#/components/errors/InternalError"
        }
      ],
      "x-rate-limit-class": "account",
      "x-max-request-bytes": 1024,
      "examples": [
        {
          "name": "an EOA",
          "params": [
            {
              "name": "address",
              "value": "0x5555555555555555555555555555555555555555"
            }
          ],
          "result": {
            "name": "check",
            "value": {
              "address": "0x5555555555555555555555555555555555555555",
              "ok": true
            }
          }
        },
        {
          "name": "a contract",
          "params": [
            {
              "name": "address",
              "value": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"
            }
          ],
          "result": {
            "name": "check",
            "value": {
              "address": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
              "ok": false,
              "reason": "the recipient is a contract; sponsored ETH only goes to addresses without code or delegated to 0xa46cc63eBF4Bd77888AA327837d20b23A63a56B5"
            }
          }
        }
      ]
    },
    {
      "name": "eth_sendUserOperation",
      "summary": "Check, co-sign and forward a PoW-sponsored op to the relay's own bundler; returns the userOpHash the relay computed.",
      "description": "The relay checks, in order: EntryPoint v0.9 and the op's shape; the epoch (current, or the previous one within the grace period after a roll; at least 60 s before validUntil); nonce key 0; the EIP-7702 authorization and delegate rules; the userOpHash (recomputed, never trusted); the 8 PoW hashes and every on-chain soft check; the account signature; the template, allowlist, exact gas profile, PVG bounds and uniform fees; at most 4 pending ops per sender (for sendEth: the recipient's code and the sender's balance); then headroom, budget and pacing. It then co-signs and forwards to its own bundler only. No bundler or provider call happens before the proof is verified. Not rate-limited (the proof protects it), but refusals at or before the PoW check spend an `invalidSend` budget of 60 per minute.",
      "params": [
        {
          "name": "userOperation",
          "schema": {
            "$ref": "#/components/schemas/UserOperation"
          },
          "required": true
        },
        {
          "name": "entryPoint",
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "required": true,
          "description": "EntryPoint v0.9."
        }
      ],
      "result": {
        "name": "userOpHash",
        "schema": {
          "$ref": "#/components/schemas/Hash32"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/TimeRange"
        },
        {
          "$ref": "#/components/errors/PaymasterRejected"
        },
        {
          "$ref": "#/components/errors/BundlerRejected"
        },
        {
          "$ref": "#/components/errors/InternalError"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "none (PoW-gated; invalidSend budget)",
      "x-max-request-bytes": 16384,
      "examples": [
        {
          "name": "a first op (EIP-7702 delegation + transfer) on the local stack",
          "params": [
            {
              "name": "userOperation",
              "value": {
                "callData": "0xb61d27f6000000000000000000000000d0e613f1bd2a0a42e247e37c5d8300ca04d44d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044a9059cbb00000000000000000000000055555555555555555555555555555555555555550000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000",
                "callGasLimit": "0xafc8",
                "factory": "0x7702",
                "factoryData": "0x",
                "maxFeePerGas": "0x3b9aca00",
                "maxPriorityFeePerGas": "0xf4240",
                "nonce": "0x0",
                "paymaster": "0x1e763f7171465B6bb3d89A303f05F926e8a51F4E",
                "paymasterData": "0x0100000007",
                "paymasterPostOpGasLimit": "0x61a8",
                "paymasterSignature": "0x000000000000005c000000000000006100000000000000a000000000000000ed00000000000000fc000000000000012300000000000001490000000000000178fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c",
                "paymasterVerificationGasLimit": "0x11170",
                "preVerificationGas": "0x1adb0",
                "sender": "0x02199F05C7364C169A0b584D84Bf93f03310a7Fe",
                "signature": "0xb1a854ef884342cd99013d1797dae374649972ea2c04426491c12d922f4fa083590f2687408aec7ac88cd73f837d90e4a334604c778e20f1f6ea31bafcbe12961b",
                "verificationGasLimit": "0xc350",
                "eip7702Auth": {
                  "address": "0xa46cc63eBF4Bd77888AA327837d20b23A63a56B5",
                  "chainId": "0x7a69",
                  "nonce": "0x0",
                  "r": "0xf89c9022a0559d3b9cc615dd99db9c3180d49c7bd7878190ce7e37275e30537a",
                  "s": "0x2df0e1b5eb0c3e8f0830a16fc2e14bc5585952f23871473f647d77d07cd37251",
                  "yParity": "0x01"
                }
              }
            },
            {
              "name": "entryPoint",
              "value": "0x433709009B8330FDa32311DF1C2AFA402eD8D009"
            }
          ],
          "result": {
            "name": "userOpHash",
            "value": "0x979faa8c0c12525504e45d82c43ad34a1ce674ca2460c4925a4d007d308421df"
          }
        }
      ]
    },
    {
      "name": "pow_sendUserOperation",
      "summary": "Same checks and co-signature as eth_sendUserOperation; the relay holds the op for delaySec before forwarding it.",
      "description": "A relay-held delay decouples the op's time on chain from the time it was mined (SPEC §9.3). The op counts in the deposit ledger while held; held ops together may reserve at most a share of the epoch budget (HOLD_LIMIT). Without options, or with delaySec 0, it forwards at once and returns only the hash.",
      "params": [
        {
          "name": "userOperation",
          "schema": {
            "$ref": "#/components/schemas/UserOperation"
          },
          "required": true
        },
        {
          "name": "entryPoint",
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "required": true
        },
        {
          "name": "options",
          "schema": {
            "$ref": "#/components/schemas/SendOptions"
          },
          "required": false
        }
      ],
      "result": {
        "name": "held",
        "schema": {
          "$ref": "#/components/schemas/HeldResult"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/TimeRange"
        },
        {
          "$ref": "#/components/errors/PaymasterRejected"
        },
        {
          "$ref": "#/components/errors/BundlerRejected"
        },
        {
          "$ref": "#/components/errors/InternalError"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "none (PoW-gated; invalidSend budget)",
      "x-max-request-bytes": 16384,
      "examples": [
        {
          "name": "held 120 s",
          "params": [
            {
              "name": "userOperation",
              "value": {
                "callData": "0xb61d27f6000000000000000000000000d0e613f1bd2a0a42e247e37c5d8300ca04d44d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044a9059cbb00000000000000000000000055555555555555555555555555555555555555550000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000",
                "callGasLimit": "0xafc8",
                "factory": "0x7702",
                "factoryData": "0x",
                "maxFeePerGas": "0x3b9aca00",
                "maxPriorityFeePerGas": "0xf4240",
                "nonce": "0x0",
                "paymaster": "0x1e763f7171465B6bb3d89A303f05F926e8a51F4E",
                "paymasterData": "0x0100000007",
                "paymasterPostOpGasLimit": "0x61a8",
                "paymasterSignature": "0x000000000000005c000000000000006100000000000000a000000000000000ed00000000000000fc000000000000012300000000000001490000000000000178fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c",
                "paymasterVerificationGasLimit": "0x11170",
                "preVerificationGas": "0x1adb0",
                "sender": "0x02199F05C7364C169A0b584D84Bf93f03310a7Fe",
                "signature": "0xb1a854ef884342cd99013d1797dae374649972ea2c04426491c12d922f4fa083590f2687408aec7ac88cd73f837d90e4a334604c778e20f1f6ea31bafcbe12961b",
                "verificationGasLimit": "0xc350",
                "eip7702Auth": {
                  "address": "0xa46cc63eBF4Bd77888AA327837d20b23A63a56B5",
                  "chainId": "0x7a69",
                  "nonce": "0x0",
                  "r": "0xf89c9022a0559d3b9cc615dd99db9c3180d49c7bd7878190ce7e37275e30537a",
                  "s": "0x2df0e1b5eb0c3e8f0830a16fc2e14bc5585952f23871473f647d77d07cd37251",
                  "yParity": "0x01"
                }
              }
            },
            {
              "name": "entryPoint",
              "value": "0x433709009B8330FDa32311DF1C2AFA402eD8D009"
            },
            {
              "name": "options",
              "value": {
                "delaySec": 120
              }
            }
          ],
          "result": {
            "name": "held",
            "value": {
              "userOpHash": "0x979faa8c0c12525504e45d82c43ad34a1ce674ca2460c4925a4d007d308421df",
              "forwardAt": 1790000130
            }
          }
        }
      ]
    },
    {
      "name": "eth_getUserOperationReceipt",
      "summary": "The ERC-4337 receipt, built from chain logs; null while pending or unknown.",
      "params": [
        {
          "name": "userOpHash",
          "schema": {
            "$ref": "#/components/schemas/Hash32"
          },
          "required": true,
          "description": "The op's hash (as the relay computed it)."
        }
      ],
      "result": {
        "name": "receipt",
        "schema": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/components/schemas/UserOperationReceipt"
            }
          ]
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        },
        {
          "$ref": "#/components/errors/InternalError"
        }
      ],
      "x-rate-limit-class": "receipt",
      "x-max-request-bytes": 8192
    },
    {
      "name": "eth_getUserOperationByHash",
      "summary": "A pending op as sent (with the placeholder co-signature), or an included op decoded from its bundle; null if unknown.",
      "params": [
        {
          "name": "userOpHash",
          "schema": {
            "$ref": "#/components/schemas/Hash32"
          },
          "required": true,
          "description": "The op's hash (as the relay computed it)."
        }
      ],
      "result": {
        "name": "operation",
        "schema": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/components/schemas/UserOperationByHash"
            }
          ]
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        },
        {
          "$ref": "#/components/errors/InternalError"
        }
      ],
      "x-rate-limit-class": "receipt",
      "x-max-request-bytes": 8192
    },
    {
      "name": "pow_getUserOperationStatus",
      "summary": "held, submitted, included, rejected or expired; null for an unknown hash.",
      "params": [
        {
          "name": "userOpHash",
          "schema": {
            "$ref": "#/components/schemas/Hash32"
          },
          "required": true,
          "description": "The op's hash (as the relay computed it)."
        }
      ],
      "result": {
        "name": "status",
        "schema": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/components/schemas/UserOperationStatus"
            }
          ]
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        },
        {
          "$ref": "#/components/errors/InternalError"
        }
      ],
      "x-rate-limit-class": "receipt",
      "x-max-request-bytes": 8192,
      "examples": [
        {
          "name": "included",
          "params": [
            {
              "name": "userOpHash",
              "value": "0x979faa8c0c12525504e45d82c43ad34a1ce674ca2460c4925a4d007d308421df"
            }
          ],
          "result": {
            "name": "status",
            "value": {
              "status": "included",
              "transactionHash": "0xabababababababababababababababababababababababababababababababab"
            }
          }
        },
        {
          "name": "held",
          "params": [
            {
              "name": "userOpHash",
              "value": "0x979faa8c0c12525504e45d82c43ad34a1ce674ca2460c4925a4d007d308421df"
            }
          ],
          "result": {
            "name": "status",
            "value": {
              "status": "held",
              "forwardAt": 1790000130
            }
          }
        }
      ]
    },
    {
      "name": "eth_estimateUserOperationGas",
      "summary": "Debugging and third-party tooling only: the bundler's estimation for this paymaster. The SDK never calls it.",
      "description": "Limited to the relay's paymaster and EntryPoint v0.9, at most 4 at a time (busy: RateLimited without data). Unlike every other method, it may make the bundler call the chain.",
      "params": [
        {
          "name": "userOperation",
          "schema": {
            "$ref": "#/components/schemas/UserOperation"
          },
          "required": true
        },
        {
          "name": "entryPoint",
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "required": true
        },
        {
          "name": "stateOverrides",
          "schema": {
            "$ref": "#/components/schemas/StateOverrides"
          },
          "required": false
        }
      ],
      "result": {
        "name": "estimate",
        "schema": {
          "$ref": "#/components/schemas/GasEstimate"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/PaymasterRejected"
        },
        {
          "$ref": "#/components/errors/BundlerRejected"
        },
        {
          "$ref": "#/components/errors/InternalError"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "estimate",
      "x-max-request-bytes": 8192
    }
  ],
  "components": {
    "schemas": {
      "Address": {
        "type": "string",
        "pattern": "^0x[0-9a-fA-F]{40}$",
        "description": "A 20-byte address (any case; answers are checksummed)."
      },
      "Hash32": {
        "type": "string",
        "pattern": "^0x[0-9a-fA-F]{64}$"
      },
      "Quantity": {
        "type": "string",
        "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
        "description": "A 0x hex quantity without leading zeros."
      },
      "HexNumber": {
        "description": "A number as a 0x hex string (leading zeros allowed) or a non-negative integer.",
        "oneOf": [
          {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]+$"
          },
          {
            "type": "integer",
            "minimum": 0
          }
        ]
      },
      "Bytes": {
        "type": "string",
        "pattern": "^0x([0-9a-fA-F]{2})*$",
        "description": "0x hex data with an even number of digits."
      },
      "UnixSeconds": {
        "type": "integer",
        "minimum": 0
      },
      "Eip7702Authorization": {
        "type": "object",
        "description": "The EIP-7702 authorization of a first operation (viem's eip7702Auth). The relay requires address = Simple7702Account v0.9, chainId = the relay's chain (never 0), nonce = the sender's transaction count, a low-s signature by the sender; `contractAddress` and `v` are accepted as aliases of `address` and `yParity`.",
        "required": [
          "address",
          "chainId",
          "nonce",
          "r",
          "s",
          "yParity"
        ],
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "chainId": {
            "$ref": "#/components/schemas/HexNumber"
          },
          "nonce": {
            "$ref": "#/components/schemas/HexNumber"
          },
          "r": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{1,64}$"
          },
          "s": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{1,64}$"
          },
          "yParity": {
            "$ref": "#/components/schemas/HexNumber"
          }
        }
      },
      "UserOperation": {
        "type": "object",
        "description": "An ERC-4337 v0.9 UserOperation in its unpacked JSON-RPC form (ERC-7769, as viem's formatUserOperationRequest writes it), with the v0.9 `paymasterSignature` as its own field and the EIP-7702 authorization as `eip7702Auth`. Unknown fields and the packed v0.7 fields (`initCode`, `paymasterAndData`) are refused (INVALID_FIELDS). Gas and fee values are at most 2^120 − 1.",
        "required": [
          "sender",
          "nonce",
          "callData",
          "callGasLimit",
          "verificationGasLimit",
          "preVerificationGas",
          "maxFeePerGas",
          "maxPriorityFeePerGas",
          "paymaster",
          "paymasterVerificationGasLimit",
          "paymasterPostOpGasLimit",
          "paymasterData",
          "paymasterSignature",
          "signature"
        ],
        "additionalProperties": false,
        "properties": {
          "sender": {
            "$ref": "#/components/schemas/Address"
          },
          "nonce": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "EntryPoint nonce; its key (the high 192 bits) must be 0 (NONCE_KEY)."
          },
          "factory": {
            "$ref": "#/components/schemas/Bytes",
            "description": "First operation only: the 0x7702 marker (the relay sponsors no factory)."
          },
          "factoryData": {
            "type": "string",
            "pattern": "^0x([0-9a-fA-F]{2}){0,64}$",
            "description": "Empty (0x) with the 0x7702 marker."
          },
          "callData": {
            "type": "string",
            "pattern": "^0x([0-9a-fA-F]{2}){0,4096}$",
            "description": "One execute(target, value, data) of a sponsored template (claim, transfer, approve on an allowlisted target, or sendEth); at most 4096 bytes."
          },
          "callGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "verificationGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "preVerificationGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxFeePerGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxPriorityFeePerGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "paymaster": {
            "$ref": "#/components/schemas/Address",
            "description": "The relay's PowPaymaster (PAYMASTER otherwise)."
          },
          "paymasterVerificationGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "paymasterPostOpGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "paymasterData": {
            "type": "string",
            "pattern": "^0x01[0-9a-fA-F]{8}$",
            "description": "0x01 ‖ uint32 epochId (5 bytes, signed)."
          },
          "paymasterSignature": {
            "type": "string",
            "pattern": "^0x([0-9a-fA-F]{128}|[0-9a-fA-F]{258})$",
            "description": "The 8 PoW nonces (8 × uint64 BE, strictly increasing), followed in co-signed epochs by a 65-byte placeholder the relay replaces with its co-signature (129 bytes in all; 64 in permissionless epochs). Not covered by the userOpHash."
          },
          "signature": {
            "type": "string",
            "pattern": "^0x([0-9a-fA-F]{2}){0,128}$",
            "description": "The account's 65-byte ECDSA signature of the userOpHash (low s, v ∈ {27, 28})."
          },
          "eip7702Auth": {
            "$ref": "#/components/schemas/Eip7702Authorization"
          }
        }
      },
      "SendOptions": {
        "type": "object",
        "properties": {
          "delaySec": {
            "type": "integer",
            "minimum": 0,
            "description": "Seconds the relay holds the co-signed op before forwarding it; at most validUntil − now − 90 (DELAY_TOO_LONG)."
          }
        }
      },
      "HeldResult": {
        "type": "object",
        "required": [
          "userOpHash"
        ],
        "additionalProperties": false,
        "properties": {
          "userOpHash": {
            "$ref": "#/components/schemas/Hash32"
          },
          "forwardAt": {
            "$ref": "#/components/schemas/UnixSeconds",
            "description": "When the relay forwards a held op (absent without a delay)."
          }
        }
      },
      "GasProfile": {
        "type": "object",
        "required": [
          "verificationGasLimit",
          "callGasLimit"
        ],
        "additionalProperties": false,
        "properties": {
          "verificationGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "callGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          }
        }
      },
      "EpochInfo": {
        "type": "object",
        "description": "The current epoch (packages/sdk EpochInfoJson): the write-once on-chain epoch, plus the relay's acceptance window, deposit headroom, remaining budget, the exact gas profiles and the PVG quotes every client builds with.",
        "additionalProperties": false,
        "required": [
          "chainId",
          "entryPoint",
          "paymaster",
          "epochId",
          "start",
          "validFor",
          "epochLength",
          "validUntil",
          "workPerGwei",
          "minWork",
          "flags",
          "minFeePerGas",
          "maxFeePerGas",
          "maxPriorityFeePerGas",
          "refFeePerGas",
          "cosigner",
          "seed",
          "maxOpCost",
          "maxVerificationGasLimit",
          "maxCallGasLimit",
          "maxPreVerificationGas",
          "pmVerificationGasLimit",
          "pmPostOpGasLimit",
          "acceptUntil",
          "nextRollAt",
          "headroomWei",
          "budgetRemainingWei",
          "gasProfiles",
          "pvgQuotes",
          "pvgQuotedAt",
          "serverTime"
        ],
        "properties": {
          "chainId": {
            "type": "integer"
          },
          "entryPoint": {
            "$ref": "#/components/schemas/Address"
          },
          "paymaster": {
            "$ref": "#/components/schemas/Address"
          },
          "epochId": {
            "type": "integer",
            "minimum": 1
          },
          "start": {
            "$ref": "#/components/schemas/UnixSeconds"
          },
          "validFor": {
            "type": "integer"
          },
          "epochLength": {
            "type": "integer"
          },
          "validUntil": {
            "$ref": "#/components/schemas/UnixSeconds",
            "description": "start + validFor: ops of this epoch are invalid on chain after it."
          },
          "workPerGwei": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "minWork": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "flags": {
            "type": "integer",
            "description": "Bit 0 COSIGNED, bit 1 DELEGATE_CHECK."
          },
          "minFeePerGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxFeePerGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxPriorityFeePerGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "refFeePerGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "cosigner": {
            "$ref": "#/components/schemas/Address"
          },
          "seed": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxOpCost": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxVerificationGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxCallGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "maxPreVerificationGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "pmVerificationGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "pmPostOpGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "acceptUntil": {
            "$ref": "#/components/schemas/UnixSeconds",
            "description": "min(validUntil − 60, nextRollAt + STALE_GRACE): the last time the relay accepts ops of this epoch."
          },
          "nextRollAt": {
            "$ref": "#/components/schemas/UnixSeconds",
            "description": "start + epochLength."
          },
          "headroomWei": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "Paymaster deposit minus the maxCost of every op in flight (0 in drain mode)."
          },
          "budgetRemainingWei": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "What the epoch budget still allows after in-flight reservations (0 in drain mode)."
          },
          "gasProfiles": {
            "type": "object",
            "description": "Per sponsored template: the exact verificationGasLimit and callGasLimit of a first and a regular op.",
            "additionalProperties": {
              "type": "object",
              "required": [
                "first",
                "regular"
              ],
              "properties": {
                "first": {
                  "$ref": "#/components/schemas/GasProfile"
                },
                "regular": {
                  "$ref": "#/components/schemas/GasProfile"
                }
              }
            }
          },
          "pvgQuotes": {
            "type": "object",
            "description": "Per template: the relay's preVerificationGas quotes (relay-owned dummy accounts).",
            "additionalProperties": {
              "type": "object",
              "required": [
                "first",
                "regular"
              ],
              "properties": {
                "first": {
                  "type": "string",
                  "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
                  "description": "A 0x hex quantity without leading zeros."
                },
                "regular": {
                  "type": "string",
                  "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
                  "description": "A 0x hex quantity without leading zeros."
                }
              }
            }
          },
          "pvgQuotedAt": {
            "$ref": "#/components/schemas/UnixSeconds"
          },
          "serverTime": {
            "$ref": "#/components/schemas/UnixSeconds",
            "description": "The relay's clock (clients correct their own with it)."
          }
        }
      },
      "AccountState": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "address",
          "delegate",
          "delegated",
          "eoaNonce",
          "epNonce",
          "ethBalance",
          "balances"
        ],
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "delegate": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Address"
              }
            ]
          },
          "delegated": {
            "type": "boolean",
            "description": "Whether the code is exactly 0xef0100 ‖ Simple7702Account v0.9."
          },
          "eoaNonce": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "eth_getTransactionCount(address, 'pending')."
          },
          "epNonce": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "EntryPoint nonce of key 0."
          },
          "ethBalance": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "balances": {
            "type": "object",
            "description": "The NON-ZERO balances of the allowlisted tokens, by token address (a listed token missing here holds 0).",
            "propertyNames": {
              "pattern": "^0x[0-9a-fA-F]{40}$"
            },
            "additionalProperties": {
              "type": "string",
              "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
              "description": "A 0x hex quantity without leading zeros."
            }
          }
        }
      },
      "RecipientCheck": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "address",
          "ok"
        ],
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "ok": {
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "description": "Why not, when ok is false."
          }
        }
      },
      "UserOperationStatus": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "held",
              "submitted",
              "included",
              "rejected",
              "expired"
            ]
          },
          "forwardAt": {
            "$ref": "#/components/schemas/UnixSeconds",
            "description": "held: when the relay forwards it."
          },
          "transactionHash": {
            "$ref": "#/components/schemas/Hash32",
            "description": "included: the bundle transaction."
          },
          "reason": {
            "type": "string",
            "enum": [
              "COSIGNER_UNAVAILABLE",
              "PVG_TOO_LOW",
              "FEE_TOO_LOW",
              "BUNDLER_REJECTED",
              "BUNDLER_UNAVAILABLE",
              "BUNDLER_DROPPED",
              "BUNDLE_FAILED",
              "BUNDLER_LOST"
            ],
            "description": "rejected: why (the relay keeps resolved statuses about an hour)."
          }
        }
      },
      "Log": {
        "type": "object",
        "description": "A raw log of the bundle transaction.",
        "required": [
          "address",
          "topics",
          "data"
        ],
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "topics": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Hash32"
            }
          },
          "data": {
            "$ref": "#/components/schemas/Bytes"
          },
          "blockNumber": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "transactionHash": {
            "$ref": "#/components/schemas/Hash32"
          },
          "logIndex": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          }
        }
      },
      "TransactionReceipt": {
        "type": "object",
        "description": "The chain's raw eth_getTransactionReceipt of the bundle transaction.",
        "required": [
          "transactionHash",
          "blockNumber",
          "status"
        ],
        "properties": {
          "transactionHash": {
            "$ref": "#/components/schemas/Hash32"
          },
          "blockNumber": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "blockHash": {
            "$ref": "#/components/schemas/Hash32"
          },
          "from": {
            "$ref": "#/components/schemas/Address"
          },
          "to": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Address"
              }
            ]
          },
          "status": {
            "type": "string"
          },
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Log"
            }
          }
        }
      },
      "UserOperationReceipt": {
        "type": "object",
        "description": "The ERC-4337 receipt, rebuilt by the relay from the EntryPoint's UserOperationEvent (works while the bundler is down).",
        "required": [
          "userOpHash",
          "entryPoint",
          "sender",
          "nonce",
          "actualGasCost",
          "actualGasUsed",
          "success",
          "logs",
          "receipt"
        ],
        "properties": {
          "userOpHash": {
            "$ref": "#/components/schemas/Hash32"
          },
          "entryPoint": {
            "$ref": "#/components/schemas/Address"
          },
          "sender": {
            "$ref": "#/components/schemas/Address"
          },
          "nonce": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "paymaster": {
            "$ref": "#/components/schemas/Address"
          },
          "actualGasCost": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "Wei the paymaster paid."
          },
          "actualGasUsed": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "success": {
            "type": "boolean",
            "description": "Whether the call succeeded (false: included, but reverted)."
          },
          "reason": {
            "$ref": "#/components/schemas/Bytes",
            "description": "Revert data, when the call reverted."
          },
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Log"
            }
          },
          "receipt": {
            "$ref": "#/components/schemas/TransactionReceipt"
          }
        }
      },
      "UserOperationByHash": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "userOperation",
          "entryPoint",
          "transactionHash",
          "blockHash",
          "blockNumber"
        ],
        "properties": {
          "userOperation": {
            "$ref": "#/components/schemas/UserOperation",
            "description": "Pending: the op as the client sent it (the co-signature is never handed out). Included: decoded from the bundle's handleOps calldata."
          },
          "entryPoint": {
            "$ref": "#/components/schemas/Address"
          },
          "transactionHash": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Hash32"
              }
            ]
          },
          "blockHash": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Hash32"
              }
            ]
          },
          "blockNumber": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "string",
                "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
                "description": "A 0x hex quantity without leading zeros."
              }
            ]
          }
        }
      },
      "GasEstimate": {
        "type": "object",
        "description": "The bundler's (Alto's) v0.9 estimation, passed through.",
        "properties": {
          "preVerificationGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "verificationGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "callGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "paymasterVerificationGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          },
          "paymasterPostOpGasLimit": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "A 0x hex quantity without leading zeros."
          }
        }
      },
      "StateOverrides": {
        "type": "object",
        "description": "Optional eth_call-style state overrides, passed to the bundler."
      },
      "RelayReason": {
        "type": "string",
        "enum": [
          "ENTRYPOINT",
          "INVALID_FIELDS",
          "SIZE",
          "PAYMASTER",
          "PAYMASTER_DATA",
          "PAYMASTER_SIGNATURE",
          "EPOCH_UNKNOWN",
          "EPOCH_STALE",
          "EPOCH_EXPIRED",
          "DELAY_TOO_LONG",
          "NONCE_KEY",
          "AUTH_INVALID",
          "DELEGATE_MISMATCH",
          "POW_INVALID",
          "POLICY",
          "SIGNATURE_INVALID",
          "TEMPLATE",
          "GAS_PROFILE",
          "PVG_UNAVAILABLE",
          "PVG_TOO_HIGH",
          "FEE_MISMATCH",
          "FEE_TOO_LOW",
          "RECIPIENT",
          "INSUFFICIENT_BALANCE",
          "NONCE_SEQUENCE",
          "PENDING_LIMIT",
          "DRAINING",
          "BUDGET_EXHAUSTED",
          "PACING",
          "HOLD_LIMIT",
          "COSIGNER_UNAVAILABLE",
          "PVG_TOO_LOW",
          "BUNDLER_REJECTED",
          "BUNDLER_UNAVAILABLE",
          "NOT_READY"
        ],
        "description": "error.data.reason: the relay's machine-readable refusal reason (apps/relay/src/errors.ts RejectReason)."
      },
      "RelayErrorData": {
        "type": "object",
        "description": "error.data of a refusal. Messages are the relay's own fixed texts; bundler and provider text is never forwarded.",
        "required": [
          "reason"
        ],
        "additionalProperties": false,
        "properties": {
          "reason": {
            "$ref": "#/components/schemas/RelayReason"
          },
          "failMask": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "POW_INVALID, POLICY: the paymaster's soft-failure bits (checkUserOp)."
          },
          "failReasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The names of the failMask bits (FEE_LOW … DELEGATE)."
          },
          "retryAt": {
            "$ref": "#/components/schemas/UnixSeconds",
            "description": "BUDGET_EXHAUSTED, PACING, HOLD_LIMIT: when the same op may be sent again."
          },
          "limit": {
            "type": "string",
            "enum": [
              "headroom",
              "budget",
              "pacing",
              "hold"
            ],
            "description": "Which admission limit refused the op."
          },
          "currentEpochId": {
            "type": "integer",
            "description": "EPOCH_UNKNOWN, EPOCH_STALE."
          },
          "maxDelaySec": {
            "type": "integer",
            "description": "DELAY_TOO_LONG."
          },
          "template": {
            "type": "string",
            "description": "GAS_PROFILE."
          },
          "maxPreVerificationGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "PVG_TOO_HIGH: the ceiling."
          },
          "requiredPreVerificationGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "PVG_TOO_LOW: the floor (held op, or the bundler's)."
          },
          "minimumFeePerGas": {
            "type": "string",
            "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]*)$",
            "description": "FEE_TOO_LOW from the bundler."
          },
          "bundlerCode": {
            "type": "integer",
            "description": "A bundler refusal: the bundler's ERC-7769 code (also the error code)."
          },
          "aaCode": {
            "type": "string",
            "pattern": "^AA[1-9][0-9]$",
            "description": "The EntryPoint AAxx code the bundler named, if any."
          },
          "userOpHash": {
            "$ref": "#/components/schemas/Hash32",
            "description": "BUNDLER_UNAVAILABLE: the op whose forward was not confirmed (it may still land)."
          }
        }
      },
      "RateLimitData": {
        "type": "object",
        "required": [
          "retryAfter"
        ],
        "additionalProperties": false,
        "properties": {
          "retryAfter": {
            "type": "integer",
            "minimum": 1,
            "description": "Seconds to wait (also the Retry-After header of a single request's HTTP 429)."
          }
        }
      }
    },
    "errors": {
      "ParseError": {
        "code": -32700,
        "message": "parse error: the body is not JSON"
      },
      "InvalidRequest": {
        "code": -32600,
        "message": "invalid JSON-RPC request, a batch outside 1 to 10 requests, or a request above its size limit (HTTP 413)"
      },
      "MethodNotFound": {
        "code": -32601,
        "message": "method … is not supported"
      },
      "InvalidParams": {
        "code": -32602,
        "message": "malformed parameters; for an op, data.reason is ENTRYPOINT, INVALID_FIELDS, SIZE, PAYMASTER_DATA or PAYMASTER_SIGNATURE",
        "data": {
          "reason": "INVALID_FIELDS"
        }
      },
      "TimeRange": {
        "code": -32503,
        "message": "the op's epoch is unknown, no longer accepted or about to expire, or the hold is too long (data.reason EPOCH_UNKNOWN, EPOCH_STALE, EPOCH_EXPIRED, DELAY_TOO_LONG); re-mine against the current epoch",
        "data": {
          "reason": "EPOCH_STALE",
          "currentEpochId": 1235
        }
      },
      "PaymasterRejected": {
        "code": -32501,
        "message": "the relay's paymaster policy refused the op; data.reason says why (with failMask or retryAt where relevant)",
        "data": {
          "reason": "PACING",
          "retryAt": 1790000123,
          "limit": "pacing"
        }
      },
      "BundlerRejected": {
        "code": -32500,
        "message": "the bundler refused the co-signed op; the bundler's ERC-7769 code (-32500, -32501, -32502, -32503, -32504, -32505, -32506, -32507, -32508, -32521, -32601 or -32602) is passed through with data.reason PVG_TOO_LOW, FEE_TOO_LOW or BUNDLER_REJECTED and data.bundlerCode",
        "data": {
          "reason": "PVG_TOO_LOW",
          "bundlerCode": -32500,
          "requiredPreVerificationGas": "0x1b580"
        }
      },
      "InternalError": {
        "code": -32603,
        "message": "internal error, or data.reason BUNDLER_UNAVAILABLE: the bundler is unreachable or did not confirm the op (which may still land)",
        "data": {
          "reason": "BUNDLER_UNAVAILABLE"
        }
      },
      "RateLimited": {
        "code": -32005,
        "message": "rate limit exceeded (or too many invalid sends, or estimation busy); HTTP 429 with Retry-After",
        "data": {
          "retryAfter": 12
        }
      }
    }
  }
}
