> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sumvin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sponsored UserOperations

> How Sumvin sponsors gas for ERC-4337 UserOperations and the lifecycle states you can observe.

# Sponsored UserOperations

Every on-chain action a Sumvin user takes — deploying a Safe, sending a token, executing a Purchase Intent — happens as an **ERC-4337 UserOperation**, not as a regular Ethereum transaction. Sumvin acts as the paymaster: we sign for gas and forward the operation to a bundler so users never need to hold native gas tokens.

This page explains the moving parts and, importantly, the **status vocabulary** you will see when polling `GET /v0/safe/rpc/{user_op_hash}/status`.

## What is an ERC-4337 UserOperation?

[ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) is the account-abstraction standard. Instead of submitting a signed transaction directly to a node, an account-abstracted application submits a **UserOperation** — a signed payload describing what the user's smart account should do — to a **bundler**. The bundler aggregates UserOperations from many users into a single bundle transaction and sends it to the on-chain **EntryPoint** contract, which validates each signature and dispatches each call.

Two consequences matter for integrators:

* The user's smart account (a Safe, in Sumvin's case) is the `sender`. The user's signing key signs the UserOperation; no externally owned account ever needs to hold a balance.
* A **paymaster** can volunteer to cover gas. Sumvin runs the paymaster — partners do not need to fund a relayer wallet.

## Why Sumvin sponsors gas

Partner integrations want a frictionless first session. Asking a user to acquire native ETH on Optimism, or SEI on Sei mainnet, before they can do anything is a non-starter for partner experiences. Sumvin sponsors all UserOperations originated through the Platform API. The user signs, Sumvin pays, the bundler delivers.

## Status vocabulary

A UserOperation passes through a small state machine. The `status` field on the polling endpoint takes one of seven values:

| Status          | Meaning                                                                                                                                                   |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `not_found`     | The bundler has not seen this UserOperation hash. Either the hash is wrong, or the operation has not yet propagated.                                      |
| `not_submitted` | Sumvin accepted and persisted the operation but has not yet pushed it to the bundler. Transient.                                                          |
| `queued`        | The bundler accepted the UserOperation and queued it for the next bundle.                                                                                 |
| `submitted`     | The bundler has broadcast a bundle transaction containing this UserOperation to the network mempool.                                                      |
| `included`      | The bundle landed in a block **and** this UserOperation succeeded on-chain. Terminal.                                                                     |
| `rejected`      | The bundler refused the UserOperation pre-submission (e.g., signature invalid, paymaster denied, simulation reverted). **No transaction hash.** Terminal. |
| `failed`        | The bundle landed in a block but this UserOperation reverted on-chain. **Has a transaction hash.** Terminal.                                              |

`included` and `failed` are the only on-chain terminal states. `rejected` is a pre-submission terminal state.

## `rejected` vs `failed` — failure-mode taxonomy

The most common confusion: the difference between `rejected` and `failed`.

<Warning>
  **`rejected` means the UserOperation never reached the chain.** No bundle was broadcast. There is no transaction hash, no block number, no gas was burned. Typical causes: invalid signature, malformed callData that fails simulation, paymaster declined sponsorship.

  **`failed` means the UserOperation reached the chain but reverted.** A bundle transaction was mined and gas was paid. The transaction hash is populated and a `receipt` link is included in the response. Typical causes: a sub-call inside the operation reverted, an insufficient-balance check failed at execution time, a downstream contract enforced a constraint.
</Warning>

When you handle errors in your UI, treat the two cases differently:

* For `rejected`: show the user that the request was not submitted and prompt them to retry or amend the signed payload.
* For `failed`: show the on-chain failure with a link to the receipt, since gas was already burned and the user may have observable side effects from any sub-calls that succeeded before the revert.

## Lifecycle flow

```
client                  Sumvin Platform API                bundler / chain
  │                              │                              │
  │  GET /v0/safe/config         │                              │
  │  ──────────────────────────▶ │                              │
  │  ◀── factory, factoryData ── │                              │
  │       predicted address      │                              │
  │                              │                              │
  │  sign UserOperation          │                              │
  │  (off-chain, client-side)    │                              │
  │                              │                              │
  │  POST /v0/safe/rpc           │                              │
  │  ──────────────────────────▶ │  paymaster sign + forward    │
  │                              │  ──────────────────────────▶ │
  │  ◀── 202 Accepted ─────────  │                              │
  │      user_op_hash            │                              │
  │                              │                              │
  │  GET /v0/safe/rpc/{hash}/    │                              │
  │      status                  │                              │
  │  ──────────────────────────▶ │  poll bundler for receipt    │
  │                              │  ──────────────────────────▶ │
  │  ◀── status: queued ──────── │  ◀── pending ──────────────  │
  │                              │                              │
  │  GET ... (poll again)        │                              │
  │  ──────────────────────────▶ │  ──────────────────────────▶ │
  │  ◀── status: included ────── │  ◀── receipt: success ─────  │
  │      txn_hash, block_number  │                              │
  │      _links.receipt          │                              │
  │                              │                              │
  │  GET _links.receipt.href     │                              │
  │  ──────────────────────────▶ │                              │
  │  ◀── full transaction ─────  │                              │
```

When the terminal status is `included` or `failed`, the response carries `txn_hash` and a `_links.receipt` href pointing at `/v0/transactions/receipts/{txn_hash}` so you can fetch the full on-chain transaction details. For `rejected`, neither field is present.

## See also

* [Safes and identity](/concepts/safes-and-identity) — how the Safe address that signs UserOperations is bound to the user.
* [Submitting UserOperations end-to-end](/guides/safe-user-operations) — worked example with concrete request and response payloads.
* [HAL, RFC 7807, idempotency, and pagination](/concepts/hal-rfc7807-idempotency-pagination) — the conventions every Platform API response follows.
