{
  "openrpc": "1.4.1",
  "info": {
    "title": "Stamp relay JSON-RPC API",
    "version": "0.1.0",
    "description": "The public JSON-RPC API of the Stamp relay (apps/relay): the bundler front, co-signer and deposit ledger in front of the StampPaymaster, 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-production-fb81.up.railway.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": "0xB264A4A36bC65A1d2E91D23880192cfFAa5bE893",
              "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": "0x90F79bf6EB2c4f870365E785982E1f101E93b906",
              "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
    },
    {
      "name": "stamp_getIssuer",
      "summary": "The stamp issuer key, metadata, window and price booklets are bought under now.",
      "description": "Address-free. Booklets are blinded against this key and metadata, so a client compares them with the published pins first (checkStampIssuer in the SDK).",
      "params": [],
      "result": {
        "name": "issuer",
        "schema": {
          "$ref": "#/components/schemas/StampIssuer"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/PaymasterRejected"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "epoch",
      "x-max-request-bytes": 8192
    },
    {
      "name": "stamp_issue",
      "summary": "Blind-signs the booklet a mined PostOffice purchase paid for.",
      "description": "The purchase must be mined (STAMP_CONFIRMATIONS), name the PostOffice, and commit to keccak256(keccak256(info) ‖ blinded…); its block time must fall in the window info names. Deterministic: asking again returns the same signatures. The relay learns the buyer and the blinded messages, never the serials.",
      "params": [
        {
          "name": "request",
          "schema": {
            "$ref": "#/components/schemas/StampIssueRequest"
          },
          "required": true
        }
      ],
      "result": {
        "name": "issued",
        "schema": {
          "$ref": "#/components/schemas/StampIssueResult"
        }
      },
      "errors": [
        {
          "$ref": "#/components/errors/InvalidParams"
        },
        {
          "$ref": "#/components/errors/PaymasterRejected"
        },
        {
          "$ref": "#/components/errors/RateLimited"
        }
      ],
      "x-rate-limit-class": "issue",
      "x-max-request-bytes": 65536
    },
    {
      "name": "stamp_sendUserOperation",
      "summary": "Sends a prepaid-stamp op (paymasterData version 2): the relay verifies the stamp and co-signs userOpHash and nullifier.",
      "description": "Same checks as pow_sendUserOperation without proof of work: the stamp must verify under its window key, its nullifier must match the op and be neither cancelled on chain nor in flight. The paymaster records the nullifier in postOp, so a double spend is public.",
      "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/StampSendOptions"
          },
          "required": true
        }
      ],
      "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 (stamp-gated; invalidSend budget)",
      "x-max-request-bytes": 16384
    }
  ],
  "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 StampPaymaster (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)."
          },
          "stampPostOpGasLimit": {
            "$ref": "#/components/schemas/Quantity",
            "description": "Exact paymasterPostOpGasLimit of a prepaid-stamp op (paymasterData version 2); 0 or absent when the stamp lane is closed"
          }
        }
      },
      "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",
          "STAMP_INVALID",
          "STAMP_SPENT",
          "STAMP_IN_FLIGHT",
          "STAMP_EXPIRED",
          "STAMP_LANE_CLOSED",
          "ISSUER_UNAVAILABLE",
          "ORDER_UNKNOWN",
          "ORDER_PENDING",
          "ORDER_MISMATCH"
        ],
        "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)."
          }
        }
      },
      "StampIssuer": {
        "type": "object",
        "description": "The key and metadata booklets bought now are issued under (SPEC §12.4). Clients check key and window against the pins published in the deployment record before blinding anything: a relay that tagged buyers with a key or window of their own would be caught there.",
        "required": [
          "chainId",
          "paymaster",
          "postOffice",
          "key",
          "modulusBits",
          "info",
          "window",
          "priceWei",
          "markupBps",
          "maxBooklet",
          "suite"
        ],
        "properties": {
          "chainId": {
            "type": "integer"
          },
          "paymaster": {
            "$ref": "#/components/schemas/Address"
          },
          "postOffice": {
            "$ref": "#/components/schemas/Address",
            "description": "Where booklets are bought (PostOffice.buy)"
          },
          "key": {
            "type": "object",
            "required": [
              "keyId",
              "n",
              "e"
            ],
            "properties": {
              "keyId": {
                "type": "string"
              },
              "n": {
                "type": "string",
                "description": "base64url RSA modulus"
              },
              "e": {
                "type": "string",
                "description": "base64url public exponent"
              }
            }
          },
          "modulusBits": {
            "type": "integer",
            "description": "Blinded messages and signatures are modulusBits / 8 bytes"
          },
          "info": {
            "type": "string",
            "description": "Canonical public metadata: paravion:v1;chain=…;paymaster=…;key=…;face=1op;from=…;until=…"
          },
          "window": {
            "type": "object",
            "required": [
              "from",
              "issueUntil",
              "until"
            ],
            "properties": {
              "from": {
                "$ref": "#/components/schemas/UnixSeconds"
              },
              "issueUntil": {
                "$ref": "#/components/schemas/UnixSeconds"
              },
              "until": {
                "$ref": "#/components/schemas/UnixSeconds",
                "description": "End of validity of the stamps"
              }
            }
          },
          "priceWei": {
            "$ref": "#/components/schemas/Quantity",
            "description": "PostOffice.price(): wei per stamp (gas share plus markup)"
          },
          "markupBps": {
            "type": "integer"
          },
          "maxBooklet": {
            "type": "integer"
          },
          "suite": {
            "type": "string",
            "description": "RSAPBSSA-SHA384-PSS-Deterministic (partially blind RSA)"
          },
          "serverTime": {
            "$ref": "#/components/schemas/UnixSeconds"
          }
        }
      },
      "StampIssueRequest": {
        "type": "object",
        "required": [
          "orderTx",
          "info",
          "blinded"
        ],
        "properties": {
          "orderTx": {
            "$ref": "#/components/schemas/Hash32",
            "description": "The PostOffice.buy transaction"
          },
          "info": {
            "type": "string",
            "maxLength": 256
          },
          "blinded": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/Bytes"
            },
            "description": "The blinded serials, in the order the purchase committed to"
          }
        }
      },
      "StampIssueResult": {
        "type": "object",
        "required": [
          "orderId",
          "blindSignatures"
        ],
        "properties": {
          "orderId": {
            "type": "integer"
          },
          "blindSignatures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Bytes"
            }
          }
        }
      },
      "StampToken": {
        "type": "object",
        "description": "An unblinded stamp: the serial and the issuer signature over it under the key derived from info",
        "required": [
          "info",
          "serial",
          "signature"
        ],
        "properties": {
          "info": {
            "type": "string"
          },
          "serial": {
            "$ref": "#/components/schemas/Hash32"
          },
          "signature": {
            "$ref": "#/components/schemas/Bytes"
          }
        }
      },
      "StampSendOptions": {
        "type": "object",
        "required": [
          "stamp"
        ],
        "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)."
          },
          "stamp": {
            "$ref": "#/components/schemas/StampToken"
          }
        }
      }
    },
    "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; for a booklet, ORDER_MISMATCH",
        "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
        }
      }
    }
  }
}
