> ## 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.

# Gas sponsorship in the App SDK

> How gas is paid for transactions sent through @startale/app-sdk, and how to configure your own paymaster.

The App SDK does not pay for gas itself. It builds an ERC-4337 UserOperation, attaches a paymaster signature if one is configured, and submits the operation through the bundler. The result is one of three flows depending on context.

<Note>
  For the conceptual overview of who pays gas and why, see [Gas sponsorship](/concepts/gasless). This page covers the App SDK call sites.
</Note>

## Three flows, one SDK

```mermaid theme={null}
flowchart LR
  Tx[App calls send / wallet_sendCalls] --> Q{Where is this running?}
  Q -->|Mini App in Startale App| Host[Host paymaster sponsors]
  Q -->|Standalone dApp| Cfg{paymasterOptions configured?}
  Cfg -->|yes| Custom[Your paymaster sponsors]
  Cfg -->|no| User[User pays from smart account]
```

| Flow                                  | Who pays                                      | What you configure                                                      |
| ------------------------------------- | --------------------------------------------- | ----------------------------------------------------------------------- |
| **Mini App**                          | Startale host                                 | nothing                                                                 |
| **Standalone dApp with paymaster**    | You (or your sponsor wallet)                  | `paymasterOptions` on `createStartaleAccountSDK` or `startaleConnector` |
| **Standalone dApp without paymaster** | The end user, in ETH from their smart account | nothing, but the user must hold ETH                                     |

## Mini Apps: nothing to do

Inside the Startale App, gas is sponsored by the host paymaster. Your code calls `eth_sendTransaction`, `wallet_sendCalls`, `useSendTransaction`, or `useWriteContract` exactly as it would against any wagmi-compatible wallet. The host attaches the paymaster signature before the UserOperation reaches the bundler.

| Method                 | Sponsored by host      |
| ---------------------- | ---------------------- |
| `eth_sendTransaction`  | yes                    |
| `wallet_sendCalls`     | yes                    |
| `personal_sign`        | no gas, signature only |
| `eth_signTypedData_v4` | no gas, signature only |

If the user has just enough ETH to cover gas, that does not change anything either; the host paymaster pays first.

## Standalone dApps: configure a paymaster

Standalone dApps do not get free gas. Pass `paymasterOptions` to either `createStartaleAccountSDK` or `startaleConnector`. The map is keyed by chain id.

```ts theme={null}
import { createStartaleAccountSDK } from '@startale/app-sdk'

const sdk = createStartaleAccountSDK({
  appName: 'My App',
  appChainIds: [1868],
  paymasterOptions: {
    1868: {
      url: 'https://paymaster.scs.startale.com/v1?apikey=YOUR_API_KEY',
      id: 'pm_live_my_paymaster_id',
    },
  },
})
```

```ts theme={null}
import { startaleConnector } from '@startale/app-sdk'

startaleConnector({
  appName: 'My App',
  paymasterOptions: {
    1868: {
      url: 'https://paymaster.scs.startale.com/v1?apikey=YOUR_API_KEY',
      id: 'pm_live_my_paymaster_id',
    },
  },
})
```

| Field                           | Type     | Notes                                                                                                                                                                |
| ------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `paymasterOptions[chainId].url` | `string` | The paymaster RPC URL. SCS-hosted paymasters live at `https://paymaster.scs.startale.com/v1`; self-hosted services use whatever URL you deploy.                      |
| `paymasterOptions[chainId].id`  | `string` | The `paymasterId` injected into the paymaster request context. SCS-issued for managed and self-funded paymasters; service-defined for self-hosted ERC-7677 services. |

The SDK packs `{ url, id }` into the [EIP-5792 capabilities](https://eips.ethereum.org/EIPS/eip-5792) sent with `wallet_sendCalls`, so every batched call on that chain is routed through your paymaster.

<Tip>
  The fastest way to get a working `(url, id)` pair is to provision an SCS paymaster from the [SCS Portal](/aa-sdk/tutorials/portal). You get the same managed or self-funded modes the AA SDK uses, with no extra service to deploy.
</Tip>

## Standalone dApps without `paymasterOptions`

If you do not configure a paymaster, UserOperations are still built and submitted, but **the user pays gas from their smart account's ETH balance**. The user therefore needs:

* An ETH balance on the smart account address (not the EOA).
* A way to top up that balance (bridge, faucet on testnet, in-app purchase).

This flow is appropriate for testing, internal tooling, or apps where users are expected to fund their own activity. Document the funding requirement in your UX, otherwise users hit "insufficient funds for gas" failures with no recourse.

## Per-chain configuration

`paymasterOptions` is a map per chain id. You can sponsor on one chain and ask the user to pay on another:

```ts theme={null}
paymasterOptions: {
  1868: { // Soneium Mainnet, sponsored
    url: 'https://paymaster.scs.startale.com/v1?apikey=YOUR_API_KEY',
    id: 'pm_live_my_paymaster_id',
  },
  // No entry for 1946 means users pay gas on Soneium Minato.
}
```

## Failure modes

| Symptom                             | Likely cause                                           | Fix                                                                         |
| ----------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------- |
| `paymaster declined to sponsor`     | Policy hit (rate limit, allowlist) on your paymaster.  | Inspect the paymaster's policies in the SCS Portal or your service logs.    |
| `insufficient funds for gas`        | User-pays flow with an empty smart account.            | Top up the smart account, or configure `paymasterOptions`.                  |
| `paymaster context invalid`         | `paymasterOptions[chainId].id` is wrong or missing.    | Re-copy the `paymasterId` from the SCS Portal or check your service config. |
| Sponsorship works on one chain only | `paymasterOptions` is missing the other chain's entry. | Add the chain id to the map.                                                |

## Related

<CardGroup cols={2}>
  <Card title="Custom paymaster reference" icon="gas-pump" href="/app-sdk/custom-paymaster">
    Full ERC-7677 paymaster service shape and integration patterns.
  </Card>

  <Card title="Provision an SCS paymaster" icon="key" href="/aa-sdk/tutorials/portal">
    Mint a paymaster URL and `paymasterId` in the Portal.
  </Card>

  <Card title="Concept: gas sponsorship" icon="bolt" href="/concepts/gasless">
    The two-tier model and where it is going.
  </Card>

  <Card title="Batched calls" icon="layer-group" href="/app-sdk/batched-calls">
    Atomic multi-call UserOperations work the same way regardless of who pays.
  </Card>
</CardGroup>
