{"openapi":"3.0.0","paths":{"/health":{"get":{"operationId":"HealthController_check","summary":"Liveness probe","description":"Returns 200 with { status: \"ok\", revision: \"<short commit sha>\" }.","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponseDto"}}}}},"tags":["Health"]}},"/v1/sessions/{id}":{"get":{"operationId":"SessionController_getSession","summary":"Get a payment session","description":"Public — returns the session with payment options and line items.","parameters":[{"name":"id","required":true,"in":"path","description":"Session id (UUID)","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionDto"}}}},"404":{"description":"Session not found"}},"tags":["Sessions"]}},"/v1/sessions/{id}/status":{"get":{"operationId":"SessionController_getSessionStatus","summary":"Poll session status","description":"Public — lightweight status + webhookDelivered flag for redirect gating.","parameters":[{"name":"id","required":true,"in":"path","description":"Session id (UUID)","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStatusResponseDto"}}}},"404":{"description":"Session not found"}},"tags":["Sessions"]}},"/v1/sessions":{"post":{"operationId":"SessionController_create","summary":"Create a payment session","description":"Server-to-server — requires an `sk_*` secret key in the Authorization header.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequestDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionResponseDto"}}}},"401":{"description":"Missing or unknown `Authorization: Bearer sk_*` secret key","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number"},"message":{"type":"string"},"error":{"type":"string"}},"required":["statusCode","message"]}}}}},"tags":["Sessions"],"security":[{"sk-api-key":[]}]}},"/v1/paymaster/rpc":{"post":{"operationId":"PaymasterRpcController_handle","summary":"ERC-4337 paymaster JSON-RPC proxy","description":"ERC-4337 paymaster JSON-RPC for the publishable `pmc_*` client id in `X-Client-Id`.\n\n**Methods.** Every method takes `params = [userOp, entryPoint, chainId, context?]`: `entryPoint` is EntryPoint v0.8 or v0.7; `chainId` is a `0x` hex string, a decimal string or a number; `context` is optional `{\"token\": \"0x…\"}`.\n\n- `pm_getPaymasterStubData` (ERC-7677) — paymaster data with a recoverable, non-authorizing 65-byte ECDSA placeholder for gas estimation; does not call the real signer or authorize payment, and reads the limits without consuming them.\n- `pm_getPaymasterData` (ERC-7677) — signed paymaster data to submit; needs `callGasLimit`, `verificationGasLimit`, `preVerificationGas` and `maxFeePerGas`, and consumes one unit of the per-sender limits.\n- `pm_sponsorUserOperation` — the same signed result for merchant-sponsored gas; a `context.token` is refused.\n\nThe result of every method is `{paymaster, paymasterData, paymasterVerificationGasLimit, paymasterPostOpGasLimit}`.\n\n**What gets sponsored.**\n- A `pmc_live_*` key covers mainnets only and a `pmc_test_*` key testnets only; the chain must also be in the client's `allowedChainIds`.\n- No `context.token` is merchant-sponsored gas; a `context.token` is user-paid gas in that ERC-20. The client's `gasMode` (`sponsored`, `user_paid`, `both`) decides which are allowed.\n- Direct calls support `execute(address,uint256,bytes)` and MetaMask's single `execute((address,uint256,bytes))`. The target must be on the merchant contract allowlist and not blocked by a deny rule.\n- Direct batches support `executeBatch(address[],uint256[],bytes[])` (SimpleAccount v0.7 and thirdweb Account, both on EntryPoint v0.7) and ERC-7579 `execute(bytes32,bytes)` with exactly the BatchDefault mode (`0x01` then 31 zero bytes) and an `abi.encode((address,uint256,bytes)[])` payload (MetaMask smart accounts). A batch holds 1 to 16 calls in at most 32 KiB of `callData`, every call has zero native value, the three `executeBatch` arrays have equal length (an empty value array is refused), and the encoding must be canonical. Try, delegatecall and every other mode, SimpleAccount v0.8 `executeBatch((address,uint256,bytes)[])` and a call targeting DelegationManager are refused.\n- Every call target of a batch must be on the merchant contract allowlist and none may be blocked by a deny rule; one refused call refuses the whole operation before it is signed or counted against limits, and the error names the call by its zero-based index. The allowlist matches contract addresses only; call arguments such as an `approve` spender are not checked.\n- A batch executes in the account in order and atomically: a reverting call reverts every call of the operation, while the included operation still consumes gas and is billed like any other operation. A batch is one operation for limits, billing and usage; `targets` on usage and activity rows lists every call target in order.\n- On all supported networks (Ethereum, Base, Arbitrum and their Sepolia testnets), MetaMask v1.3.0 Advanced Permissions (ERC-7715) support one ERC-20 allowance transfer through DelegationManager, wrapped in a supported single execute call or ERC-7579 `execute(bytes32,bytes)` with an all-zero SingleDefault mode. One root delegation must bind the sender and chain-specific EOA signature, token allowance, expiry, redeemer, payee, zero native value and nonce. Delegated batches, redelegation, other modes and unrecognised caveats are refused.\n- Delegated transfers check deny rules and per-account limits for both the session sender and original owner; the global budget is charged once. Usage keeps the actual UserOperation sender and records the owner in `reason`. Bundler execution simulation checks on-chain revocation and remaining allowance.\n- Sponsored ops on mainnets need a positive prepaid gas balance.\n- Per-sender limits are the lower of the platform and merchant values, see `GET /v1/paymaster/limits`.\n\n**Errors.**\n\n| Response | `message` starts with | Cause |\n| --- | --- | --- |\n| HTTP 401 (`/v1/paymaster/rpc`, `/v1/paymaster/bundler/{chainId}`) | `paymaster_unauthorized` | Client id missing (`X-Client-Id` header or `?clientId=`), unknown or revoked |\n| HTTP 403 (`/v1/paymaster/rpc`, `/v1/paymaster/bundler/{chainId}`) | `paymaster_origin_not_allowed` | The client has `allowedOrigins` and the `Origin` header is missing or not on the list |\n| JSON-RPC `-32700` | `Parse error` | The JSON body is not a JSON-RPC 2.0 request: `jsonrpc` is not `\"2.0\"`, `method` is not a string, `params` is not an array, or `id` is not a string or number |\n| JSON-RPC `-32601` | `Unknown method` | `method` is not `pm_sponsorUserOperation`, `pm_getPaymasterStubData` or `pm_getPaymasterData` |\n| JSON-RPC `-32602` | `Invalid params` | `params[0]` is not an object, `params[1]` is not a string starting with `0x`, `params[2]` is not a chainId (`0x` hex, decimal string or number), or `nonce` or a gas field cannot be read as an integer |\n| JSON-RPC `-32602` | `paymaster_token_invalid` | `params[3].token` is present but not an address |\n| JSON-RPC `-32602` | `paymaster_token_unsupported_method` | `context.token` sent with `pm_sponsorUserOperation`; user-paid gas uses the stub + data methods |\n| JSON-RPC `-32602` | `paymaster_gas_fields_missing` | `pm_getPaymasterData` / `pm_sponsorUserOperation` without `callGasLimit`, `verificationGasLimit`, `preVerificationGas` or `maxFeePerGas` |\n| HTTP 403 (`/v1/paymaster/rpc`, `/v1/paymaster/bundler/{chainId}`); JSON-RPC `-32602` | `Policy denied: paymaster_chain_not_allowed` (`paymaster_chain_not_allowed` on the bundler route) | chainId is not in the client's `allowedChainIds`; on `/v1/paymaster/rpc` the client-id check answers HTTP 403 first, the JSON-RPC code is the service's re-check |\n| HTTP 403 (`/v1/paymaster/bundler/{chainId}`); JSON-RPC `-32602` | `Policy denied: paymaster_key_network_class_mismatch` (`paymaster_key_network_class_mismatch` on the bundler route) | A `pmc_live_*` key on a testnet or a `pmc_test_*` key on a mainnet |\n| JSON-RPC `-32602` | `Policy denied: paymaster_entrypoint_not_supported` | `params[1]` is neither EntryPoint v0.8 nor v0.7 |\n| JSON-RPC `-32602` | `Policy denied: paymaster_target_not_allowed` | Unsupported execution, batch or bounded MetaMask delegation transfer, a batch call with native value or targeting DelegationManager, invalid delegation permission, or a call target is not in the merchant's contract allowlist for that chain |\n| HTTP 403 (`/v1/paymaster/bundler/{chainId}`); JSON-RPC `-32600` | `Policy denied: paymaster_gas_mode_not_allowed` (`paymaster_gas_mode_not_allowed` on the bundler route) | The client's `gasMode` does not allow this op (a `token` on a `sponsored` key, no token on a `user_paid` key) |\n| JSON-RPC `-32600` | `Policy denied: paymaster_blocked_by_merchant_rule` | A merchant deny rule matches the sender, the delegated owner or any call target on that chain; checked before the allowlist |\n| HTTP 402 (`/v1/paymaster/bundler/{chainId}`); JSON-RPC `-32600` | `Policy denied: paymaster_billing_balance_exhausted` (`paymaster_billing_balance_exhausted` on the bundler route) | Sponsored op on a mainnet while the merchant's prepaid gas balance is exhausted |\n| JSON-RPC `-32600` | `Policy denied: paymaster_merchant_tx_cap_unpriceable` | A merchant per-transaction cap is set and the op cannot be priced (no ETH/USD rate) |\n| JSON-RPC `-32600` | `Policy denied: paymaster_merchant_tx_cap_exceeded` | Estimated cost plus markup exceeds the merchant per-transaction cap |\n| JSON-RPC `-32600` | `Policy denied: paymaster_global_cap_exceeded` | Platform daily sponsorship budget reached; resets at 00:00 UTC |\n| JSON-RPC `-32600` | `Policy denied: paymaster_spend_cap_exceeded` | Per-sender daily USD cap reached; `(merchant-configured cap)` suffix when the merchant cap is the binding one |\n| JSON-RPC `-32600` | `Policy denied: paymaster_rate_limit_exceeded` | Per-sender hourly op limit reached; `(merchant-configured cap)` suffix when the merchant limit is the binding one |\n| JSON-RPC `-32600` | `Policy denied: paymaster_price_unavailable` | A dollar cap applies and no ETH/USD price is available; retry |\n| JSON-RPC `-32603` | `paymaster_upstream_error` | The signing service is unreachable, timed out, or answered with a non-2xx status or a non-JSON body |\n| JSON-RPC `-32603` | `paymaster_mode_mismatch` | A `token` was requested and the signing service did not return ERC-20 mode paymaster data |\n| HTTP 502 (`/v1/paymaster/bundler/{chainId}`) | `bundler upstream` | The platform bundler answered with a non-2xx status or a non-JSON body; a transport failure returns 502 with the transport error text instead |\n\n- HTTP 401 and 403 from the client-id check carry `{\"statusCode\":<status>,\"message\":\"...\",\"error\":\"...\"}`; the other HTTP errors of the bundler route carry `{\"error\":{\"message\":\"...\",\"type\":\"error\"}}`.\n- A `{chainId}` path segment that is not an integer is rejected with HTTP 400 `Validation failed (numeric string is expected)` right after the client-id check.\n- JSON-RPC errors arrive with HTTP 200 as `{\"jsonrpc\":\"2.0\",\"id\":<id>,\"error\":{\"code\":<code>,\"message\":\"...\"}}`; `id` is `null` only for `Parse error`.\n- A `Policy denied: ` prefix marks a policy decision: never fall back to another paymaster for that operation. The bundler route never adds the prefix.\n- Once every check passes, errors from the internal signing service (for example `Unsupported chain`, `Token … not whitelisted`, `Paymaster deposit too low`) are returned unchanged with code `-32602` or `-32000`.","parameters":[{"name":"Origin","in":"header","description":"Validated against the client's allowedOrigins when configured","required":false,"schema":{"type":"string"}},{"name":"X-Client-Id","in":"header","description":"Publishable paymaster client id (`pmc_live_*` / `pmc_test_*`)","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponseDto"}}}},"401":{"description":"`paymaster_unauthorized` — Client id missing (`X-Client-Id` header or `?clientId=`), unknown or revoked","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number"},"message":{"type":"string"},"error":{"type":"string"}},"required":["statusCode","message"]}}}},"403":{"description":"`paymaster_origin_not_allowed` — The client has `allowedOrigins` and the `Origin` header is missing or not on the list\n\n`paymaster_chain_not_allowed` — chainId is not in the client's `allowedChainIds`; on `/v1/paymaster/rpc` the client-id check answers HTTP 403 first, the JSON-RPC code is the service's re-check","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number"},"message":{"type":"string"},"error":{"type":"string"}},"required":["statusCode","message"]}}}}},"tags":["Paymaster RPC"],"security":[{"paymaster-client-id":[]}]}},"/v1/paymaster/bundler/{chainId}":{"post":{"operationId":"PaymasterBundlerController_proxy","summary":"Authenticated ERC-4337 bundler proxy","description":"Relays ERC-4337 bundler JSON-RPC (e.g. `eth_sendUserOperation`) to the platform bundler so the Pimlico key never reaches the browser. Authenticates via the publishable `pmc_*` client id in `X-Client-Id` (Origin validated against the client's allowlist); the `:chainId` path param is validated against the client's allowedChainIds.","parameters":[{"name":"chainId","required":true,"in":"path","schema":{"type":"number"}},{"name":"Origin","in":"header","description":"Validated against the client's allowedOrigins when configured","required":false,"schema":{"type":"string"}},{"name":"clientId","required":false,"in":"query","description":"Publishable client id, alternative to the `X-Client-Id` header (header wins).","schema":{}},{"name":"X-Client-Id","in":"header","description":"Publishable paymaster client id (`pmc_live_*` / `pmc_test_*`). May be supplied as the `clientId` query param instead — thirdweb's `bundlerUrl` can't send a header, so the bundler route accepts it in the URL.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"description":"ERC-4337 bundler JSON-RPC request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Object"}}}},"responses":{"200":{"description":"Raw bundler JSON-RPC response"},"400":{"description":"`Validation failed (numeric string is expected)` — the `{chainId}` path segment is not an integer","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number"},"message":{"type":"string"},"error":{"type":"string"}},"required":["statusCode","message"]}}}},"401":{"description":"`paymaster_unauthorized` — Client id missing (`X-Client-Id` header or `?clientId=`), unknown or revoked","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number"},"message":{"type":"string"},"error":{"type":"string"}},"required":["statusCode","message"]}}}},"402":{"description":"`paymaster_billing_balance_exhausted` — Sponsored op on a mainnet while the merchant's prepaid gas balance is exhausted","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["error"]}},"required":["message","type"]}},"required":["error"]}}}},"403":{"description":"`paymaster_origin_not_allowed` — The client has `allowedOrigins` and the `Origin` header is missing or not on the list\n\n`paymaster_chain_not_allowed` — chainId is not in the client's `allowedChainIds`; on `/v1/paymaster/rpc` the client-id check answers HTTP 403 first, the JSON-RPC code is the service's re-check\n\n`paymaster_key_network_class_mismatch` — A `pmc_live_*` key on a testnet or a `pmc_test_*` key on a mainnet\n\n`paymaster_gas_mode_not_allowed` — The client's `gasMode` does not allow this op (a `token` on a `sponsored` key, no token on a `user_paid` key)","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["error"]}},"required":["message","type"]}},"required":["error"]},{"type":"object","properties":{"statusCode":{"type":"number"},"message":{"type":"string"},"error":{"type":"string"}},"required":["statusCode","message"]}]}}}},"502":{"description":"`bundler upstream` — The platform bundler answered with a non-2xx status or a non-JSON body; a transport failure returns 502 with the transport error text instead","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["error"]}},"required":["message","type"]}},"required":["error"]}}}}},"tags":["Paymaster Bundler"],"security":[{"paymaster-client-id":[]}]}}},"info":{"title":"StablecoinX Public API","description":"Integrator-facing endpoints for StablecoinX — create and read payment sessions, poll session status, and proxy ERC-4337 paymaster JSON-RPC calls. Session creation uses an `sk_*` secret key; the paymaster RPC proxy uses a publishable `pmc_*` client id in the `X-Client-Id` header. For the full merchant + integrator spec see /docs/openapi.yaml.\n\n## floYsh / Yield as a Service\n\nfloYsh is StablecoinX's Yield as a Service (YaaS): a branded stablecoin-yield site built around Ethena USDe/sUSDe vaults. Merchants manage the site's deployment, branding and domains in Business UI; customers use the public site to connect a wallet and access the vault.\n\n- [Business UI](https://business.harness.stablecoinx.com/) — sign in, open **Deployments → Yield** (`/deployments/yield`), and choose **New deployment** (or **Create deployment** for the first one). Open a deployment to edit its branding, manage **Domains**, and inspect **Contracts**.\n- [Business UI guide](https://business.harness.stablecoinx.com/llms-full.txt) — product overview and navigation, including how to find a deployment's public site.\n- [Merchant OpenAPI](https://api.harness.stablecoinx.com/docs#/yield-deployments) ([JSON](https://api.harness.stablecoinx.com/docs/openapi.json)) — configuration routes under `/v1/merchants/me/yield-deployments`, authenticated with a merchant JWT. These routes are in the full merchant spec, not the integrator spec at `/openapi`.\n\nThe MCP server currently has no yield-deployment tools; guide users to Business UI for floYsh management.\n","version":"1.0","contact":{}},"tags":[{"name":"Health","description":"Liveness probe"},{"name":"Sessions","description":"Payment sessions — create (sk_*), read + poll status (public)"},{"name":"Paymaster RPC","description":"ERC-4337 paymaster JSON-RPC proxy (X-Client-Id)"},{"name":"Paymaster Bundler","description":"ERC-4337 bundler JSON-RPC proxy per chain (X-Client-Id or ?clientId=)"}],"servers":[{"url":"https://api.harness.stablecoinx.com","description":"Production"}],"components":{"securitySchemes":{"sk-api-key":{"type":"http","scheme":"bearer","description":"Server-to-server secret key as `Bearer sk_*`"},"paymaster-client-id":{"type":"apiKey","in":"header","name":"X-Client-Id","description":"Publishable paymaster client id (`pmc_live_*` / `pmc_test_*`)"}},"schemas":{"HealthResponseDto":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"revision":{"type":"string","example":"9f8e7d6c5b4a","description":"Short sha of the commit this build was made from, or \"unknown\"."}},"required":["status","revision"]},"NetworkDto":{"type":"object","properties":{"name":{"type":"string","example":"Base Sepolia"},"chainId":{"type":"number","example":84532},"standard":{"type":"string","example":"ERC-20"}},"required":["name","chainId","standard"]},"PaymentOptionDto":{"type":"object","properties":{"id":{"type":"string"},"symbol":{"type":"string","enum":["USDe","USDT","USDC"]},"tokenAddress":{"type":"string"},"decimals":{"type":"number","example":6},"network":{"$ref":"#/components/schemas/NetworkDto"},"depositAddress":{"type":"string","description":"CREATE2-predicted Forwarder address the payer sends funds to"}},"required":["id","symbol","tokenAddress","decimals","network","depositAddress"]},"LineItemDto":{"type":"object","properties":{"name":{"type":"string","example":"Pro plan (annual)"},"quantity":{"type":"number","example":1},"unitPrice":{"type":"string","example":"100.00","description":"Decimal string"},"total":{"type":"string","example":"100.00","description":"Decimal string"}},"required":["name","quantity","unitPrice","total"]},"SessionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"merchantName":{"type":"string"},"amount":{"type":"string","description":"Decimal string"},"currency":{"type":"string","example":"usd"},"status":{"type":"string","enum":["pending","awaiting_payment","partial","confirming","bridging","completed","failed","expired"]},"paymentOptions":{"type":"array","items":{"$ref":"#/components/schemas/PaymentOptionDto"}},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/LineItemDto"}},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"paidAt":{"type":"string","format":"date-time"},"txHash":{"type":"string","nullable":true},"sandboxMode":{"type":"boolean"},"successUrl":{"type":"string"}},"required":["id","merchantName","amount","currency","status","paymentOptions","lineItems","expiresAt","createdAt","sandboxMode"]},"ChainAmountReceivedDto":{"type":"object","properties":{"chainId":{"type":"number"},"amountReceived":{"type":"string","description":"Decimal string"},"currency":{"type":"string","example":"usd"}},"required":["chainId","amountReceived","currency"]},"SessionStatusResponseDto":{"type":"object","properties":{"status":{"type":"string","enum":["pending","awaiting_payment","partial","confirming","bridging","completed","failed","expired"]},"webhookDelivered":{"type":"boolean","description":"True when the user-ui is clear to redirect the payer to successUrl"},"currency":{"type":"string","example":"usd","description":"Lowercase ISO 4217 currency code for the session amount fields"},"amountReceived":{"type":"object","nullable":true,"description":"Amount received on the leading payment chain as a decimal string. Null until a deposit lands."},"amountRemaining":{"type":"object","nullable":true,"description":"Amount still owed on the leading payment chain, clamped at \"0\". Always \"0\" once the session settled as paid (a tolerance-accepted shortfall is not owed). Null until a deposit lands."},"amountReceivedChainId":{"type":"object","nullable":true},"amountReceivedByChain":{"type":"array","items":{"$ref":"#/components/schemas/ChainAmountReceivedDto"}}},"required":["status","webhookDelivered","currency","amountReceived","amountRemaining","amountReceivedByChain"]},"CreateSessionRequestDto":{"type":"object","properties":{"amount":{"type":"string","example":"100.00","description":"Total amount as a positive decimal string"},"merchantName":{"type":"string","example":"Acme Inc."},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/LineItemDto"}},"paymentOptionSymbols":{"type":"array","description":"Restrict offered payment currencies; defaults to all supported","items":{"type":"string","enum":["USDe","USDT","USDC"]}},"expiresInSec":{"type":"number","example":3600,"description":"Session lifetime in seconds (60..604800)"},"successUrl":{"type":"string","example":"https://shop.example.com/order/123/success","description":"Absolute https URL the payer is redirected to after settlement"},"sandboxMode":{"type":"boolean","description":"When true, only testnet payment options are attached; when false, only mainnet. Omit to use the API default."},"payoutChainId":{"type":"object","nullable":true,"description":"SCX-276: per-session normalize payout chain override (supported chain id)"},"payoutAddress":{"type":"object","nullable":true,"description":"SCX-276: per-session normalize payout address override (EVM address)"}},"required":["amount"]},"CreateSessionResponseDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"paymentUrl":{"type":"string","example":"https://pay.stablecoinx.com/session/<id>"},"status":{"type":"string","enum":["pending","awaiting_payment","partial","confirming","bridging","completed","failed","expired"]},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","paymentUrl","status","expiresAt","createdAt"]},"JsonRpcRequestDto":{"type":"object","properties":{"jsonrpc":{"type":"string","example":"2.0","enum":["2.0"]},"id":{"description":"Request id echoed back in the response; null or missing is rejected with -32700","oneOf":[{"type":"number"},{"type":"string"}],"example":1},"method":{"type":"string","enum":["pm_sponsorUserOperation","pm_getPaymasterStubData","pm_getPaymasterData"],"example":"pm_sponsorUserOperation"},"params":{"type":"array","items":{},"description":"[userOp, entryPoint, chainId, context?] for every method — chainId as `0x` hex, decimal string or number; context is optional `{token}` for user-paid gas.","example":[{"sender":"0x…","nonce":"0x0","callData":"0xb61d27f6…"},"0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108","0x14a34"]}},"required":["jsonrpc","id","method","params"]},"JsonRpcResponseDto":{"type":"object","properties":{"jsonrpc":{"type":"string","example":"2.0"},"id":{"type":"object","nullable":true,"example":1},"result":{"type":"object","description":"Present on success — method-specific result object"},"error":{"type":"object","description":"Present on error","properties":{"code":{"type":"number","example":-32601},"message":{"type":"string","example":"Unknown method: eth_chainId"}}}},"required":["jsonrpc","id"]},"Object":{"type":"object","properties":{}}}}}