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

# Custom paymaster

> Wire an SCS paymaster or a self-hosted ERC-7677 service into @startale/app-sdk.

`paymasterOptions` is the App SDK's hook into the ERC-4337 paymaster layer. Use it whenever you ship a standalone dApp that needs to sponsor gas, or when you need finer-grained control than the default flow gives you.

For the high-level model of who pays in which context, see [Gas sponsorship](/concepts/gasless). This page is the deep dive: what the paymaster service looks like on the wire, what `paymasterOptions` injects into requests, and how to choose between SCS-hosted and self-hosted services.

## Two valid backends

```mermaid theme={null}
flowchart LR
  App["@startale/app-sdk<br/>(your dApp)"]
  PM1[SCS Managed or<br/>Self-funded Paymaster]
  PM2[Your own<br/>ERC-7677 service]
  Bundler[SCS Bundler]
  EP[EntryPoint v0.7]

  App --> PM1
  App --> PM2
  PM1 --> Bundler
  PM2 --> Bundler
  Bundler --> EP
```

| Backend                          | When to pick it                                                                                                 | Setup time                                                                              |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| **SCS Managed paymaster**        | You want SCS to settle gas in fiat on a monthly cycle.                                                          | Minutes (provision in the [SCS Portal](/aa-sdk/tutorials/portal#2-create-a-paymaster)). |
| **SCS Self-funded paymaster**    | You want a hard ETH cap on sponsorship and prefer crypto settlement.                                            | Minutes plus an ETH top-up.                                                             |
| **Self-hosted ERC-7677 service** | You need custom logic the Portal cannot express (per-tenant rules, signed allowlists, off-platform settlement). | Hours to days, depending on your sponsorship rules.                                     |

The App SDK call site is identical for all three. The difference is in what you point `paymasterOptions[chainId].url` at.

## Configure

Pass `paymasterOptions` to either `createStartaleAccountSDK` or `startaleConnector`. The map is keyed by chain id.

<Tabs>
  <Tab title="Raw SDK">
    ```ts theme={null}
    import { createStartaleAccountSDK } from '@startale/app-sdk'

    const sdk = createStartaleAccountSDK({
      appName: 'My App',
      appChainIds: [1868],
      paymasterOptions: {
        1868: {
          url: 'https://paymaster.my-app.com/sponsor',
          id: 'pm_live_my_paymaster_id',
        },
      },
    })
    ```
  </Tab>

  <Tab title="wagmi connector">
    ```ts theme={null}
    import { startaleConnector } from '@startale/app-sdk'

    startaleConnector({
      appName: 'My App',
      paymasterOptions: {
        1868: {
          url: 'https://paymaster.my-app.com/sponsor',
          id: 'pm_live_my_paymaster_id',
        },
      },
    })
    ```

    The connector forwards every option to `createStartaleAccountSDK` internally; configuration is identical.
  </Tab>
</Tabs>

| Field | Type     | Notes                                                                                                                                       |
| ----- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `url` | `string` | The paymaster JSON-RPC endpoint. SCS-hosted: `https://paymaster.scs.startale.com/v1?apikey=YOUR_API_KEY`. Self-hosted: whatever you deploy. |
| `id`  | `string` | The value forwarded as `paymasterId` in the `paymasterContext` of every paymaster RPC call.                                                 |

Internally, the SDK uses `paymasterOptions` to populate the `paymasterService` field of the [EIP-5792 capabilities](https://eips.ethereum.org/EIPS/eip-5792) attached to `wallet_sendCalls`. From there the bundler routes paymaster requests to your URL with the `id` in context.

## ERC-7677 paymaster service surface

A custom paymaster service must implement the two methods defined by [ERC-7677](https://eips.ethereum.org/EIPS/eip-7677): `pm_getPaymasterStubData` and `pm_getPaymasterData`. Both run against the same JSON-RPC endpoint.

### `pm_getPaymasterStubData`

Called during gas estimation. Return a stub paymaster signature that lets the bundler estimate gas without committing to a real signature.

**Request**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "pm_getPaymasterStubData",
  "params": [
    {
      "sender": "0x...",
      "nonce": "0x0",
      "callData": "0x...",
      "callGasLimit": "0x...",
      "verificationGasLimit": "0x...",
      "preVerificationGas": "0x...",
      "maxFeePerGas": "0x...",
      "maxPriorityFeePerGas": "0x..."
    },
    "0x...EntryPoint",
    "0x...chainId",
    {
      "id": "pm_live_my_paymaster_id"
    }
  ]
}
```

**Response (EntryPoint v0.7)**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "paymaster": "0x...PaymasterAddress",
    "paymasterData": "0x...stubBytes",
    "paymasterVerificationGasLimit": "0x...",
    "paymasterPostOpGasLimit": "0x..."
  }
}
```

### `pm_getPaymasterData`

Called after gas estimation. Return the **real** paymaster signature for the now-finalised UserOperation. The request shape is identical; the response is the same as above but with a real `paymasterData` instead of a stub.

### What goes in the context object

`paymasterOptions[chainId].id` becomes `paymasterContext.id` in the request payload. SCS paymasters expect this to be the `paymasterId` issued by the Portal. Self-hosted services can interpret it however they like; many use it as a tenant key to look up a sponsorship policy.

## Picking the right path

<CardGroup cols={2}>
  <Card title="Use SCS Managed" icon="key" href="/aa-sdk/tutorials/portal">
    SCS pays gas, bills you in fiat. Fastest to ship; no infrastructure to operate.
  </Card>

  <Card title="Use SCS Self-funded" icon="wallet" href="/aa-sdk/tutorials/portal">
    You top up an ETH balance on the paymaster contract. Hard cap; crypto settlement.
  </Card>

  <Card title="Self-host ERC-7677" icon="server">
    Run your own service when you need policies the Portal cannot express. You implement `pm_getPaymasterStubData` and `pm_getPaymasterData`.
  </Card>

  <Card title="No paymaster" icon="user" href="/app-sdk/gasless">
    Skip `paymasterOptions` and let users pay gas from their smart account's ETH balance.
  </Card>
</CardGroup>

## Operational guidance

<Warning>
  **API keys.** SCS paymaster URLs include an `apikey` query parameter. If you embed the URL in client code, scope the key tightly with [SCS Portal gas policies](/aa-sdk/tutorials/portal#3-configure-gas-policies). For self-hosted services, terminate authentication on your own gateway.
</Warning>

| Concern         | Recommendation                                                                                                           |
| --------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Per-chain rules | Configure `paymasterOptions` per chain id; omit chains where users should pay.                                           |
| Per-user policy | Encode user identity into `id`, or run a self-hosted ERC-7677 service that resolves policy from the `sender` field.      |
| Spend caps      | Use SCS Portal gas policies for managed and self-funded; enforce caps yourself for self-hosted.                          |
| Auditing        | Log every `pm_getPaymasterData` call alongside the resulting UserOperation hash; reconcile against the bundler receipts. |

## Related

<CardGroup cols={2}>
  <Card title="App SDK gasless flows" icon="bolt" href="/app-sdk/gasless">
    The three runtime flows (Mini App, configured, user-pays) explained at the SDK call site.
  </Card>

  <Card title="AA SDK Portal setup" icon="key" href="/aa-sdk/tutorials/portal">
    Mint and tune SCS paymasters. Same Portal whether you consume them via the App SDK or the AA SDK.
  </Card>

  <Card title="Sponsored paymaster (AA)" icon="gas-pump" href="/aa-sdk/tutorials/sponsored-tx">
    The AA SDK call site. Useful for backend services or framework-free integrations.
  </Card>

  <Card title="ERC-20 paymaster" icon="coins" href="/aa-sdk/tutorials/erc20-payment">
    Charge gas in a token instead of ETH.
  </Card>
</CardGroup>
