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

# Sponsored paymaster

> Send UserOperations with gas paid by a managed or self-funded SCS paymaster.

The sponsored flow is the simplest paymaster mode: your dapp pays gas on the user's behalf. The same call site works for both managed and self-funded paymasters; the only difference is how the paymaster is funded in the [Portal](/aa-sdk/tutorials/portal).

<Note>
  Source: [`StartaleGroup/scs-aa-sdk`](https://github.com/StartaleGroup/scs-aa-sdk).
</Note>

## End-to-end flow

```mermaid theme={null}
sequenceDiagram
  participant App
  participant Client as StartaleAccountClient
  participant PM as SCS Paymaster
  participant Bundler as SCS Bundler
  participant EP as EntryPoint v0.7

  App->>Client: sendUserOperation(calls)
  Client->>PM: pm_getPaymasterStubData (paymasterId)
  PM-->>Client: stub paymasterAndData
  Client->>Bundler: eth_estimateUserOperationGas
  Bundler-->>Client: gas limits
  Client->>PM: pm_getPaymasterData (paymasterId)
  PM-->>Client: paymasterAndData
  Note over Client: sign populated UserOp
  Client->>Bundler: eth_sendUserOperation
  Bundler->>EP: handleOps
  EP-->>App: success
```

The SDK handles every step; the only thing you need to plug in is the `paymasterId`.

## Wire the client

```ts theme={null}
import { http, createPublicClient } from "viem"
import { soneiumMinato } from "viem/chains"
import {
  createSCSPaymasterClient,
  createSmartAccountClient,
  toStartaleSmartAccount,
} from "@startale-scs/aa-sdk"

const publicClient = createPublicClient({ chain: soneiumMinato, transport: http() })

const paymasterClient = createSCSPaymasterClient({
  transport: http(process.env.PAYMASTER_URL!),
})

const account = await toStartaleSmartAccount({
  signer,
  chain: soneiumMinato,
  transport: http(),
  index: 0n,
})

const smartAccountClient = createSmartAccountClient({
  account,
  transport: http(process.env.BUNDLER_URL!),
  client: publicClient,
  paymaster: paymasterClient,
  paymasterContext: {
    paymasterId: process.env.PAYMASTER_ID!,
  },
})
```

| Symbol                         | Source                 | Role                                                                                             |
| ------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------ |
| `createSCSPaymasterClient`     | `@startale-scs/aa-sdk` | Connects to the SCS Paymaster RPC.                                                               |
| `paymasterContext.paymasterId` | SCS Portal             | The id of the paymaster you provisioned. **Both managed and self-funded paymasters return one.** |

## Send a sponsored UserOperation

```ts theme={null}
import { type Address, encodeFunctionData } from "viem"

const callData = encodeFunctionData({
  abi: counterAbi,
  functionName: "count",
})

const hash = await smartAccountClient.sendUserOperation({
  calls: [
    {
      to: counterAddress as Address,
      data: callData,
      value: 0n,
    },
  ],
})

const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash })
```

If the paymaster declines, the call throws before the UserOperation reaches the bundler. The most common causes are:

| Reason                      | What to check                                                                                   |
| --------------------------- | ----------------------------------------------------------------------------------------------- |
| Policy exceeded             | Open the paymaster's policies in the SCS Portal and look at the current 7-day window.           |
| Self-funded paymaster empty | Top up the sponsor balance.                                                                     |
| Wrong `paymasterId`         | Confirm you copied the id from the Portal exactly, including any prefix.                        |
| Wrong network               | Soneium Minato uses chain id `1946`; mainnet uses `1868`. The bundler URL and chain must match. |

## Choosing between managed and self-funded

Both modes use the same SDK call site. Pick whichever matches how you want to settle gas. See the [Portal setup guide](/aa-sdk/tutorials/portal#2-create-a-paymaster) for a side-by-side comparison.

|               | Managed                                | Self-funded                                  |
| ------------- | -------------------------------------- | -------------------------------------------- |
| **Funding**   | SCS fronts gas, bills you in fiat      | You top up ETH on the paymaster              |
| **Best for**  | Production apps, predictable invoicing | Hard treasury caps, crypto-native settlement |
| **Call site** | `paymasterId: "pm_..."`                | `paymasterId: "pm_..."`                      |

<Warning>
  A managed paymaster does not have unlimited funds. SCS still applies the gas policies you configure in the Portal; tighten them before launch.
</Warning>

## Next steps

<CardGroup cols={2}>
  <Card title="ERC-20 paymaster" icon="coins" href="/aa-sdk/tutorials/erc20-payment">
    Charge users in ASTR, USDC, or other supported tokens.
  </Card>

  <Card title="Parallel transactions" icon="bolt" href="/aa-sdk/advanced/parallel-tx">
    Run multiple sponsored UserOperations in parallel via nonce lanes.
  </Card>

  <Card title="Smart sessions" icon="key-skeleton" href="/aa-sdk/tutorials/smart-sessions">
    Combine sponsorship with scoped session keys for the smoothest UX.
  </Card>

  <Card title="Portal setup" icon="key" href="/aa-sdk/tutorials/portal">
    Tune your gas policies and rotate API keys.
  </Card>
</CardGroup>
