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

# Sponsor gas with Paymasters

> Deploy a paymaster contract you own, fund it, set budgets and SDK-key rules in the Client Dashboard, and let eligible deposit routes execute with gas sponsored.

Trustware Paymasters are a new ownership standard for gas sponsorship. You deploy a paymaster contract, you own it, and you fund it. Trustware decides which of your eligible operations get sponsored against the budget and rules you configure, and it never holds the funds.

The result for your users is a deposit that goes through without them holding native gas to pay for it on the source chain. One exception remains: a user's first sponsored deposit of a given ERC-20 needs a one-time approval transaction they pay for themselves, which [use sponsored routes](#use-sponsored-routes) explains. The result for you is a sponsorship balance you can audit on chain at any time.

<Note>
  Paymaster deployment is rolling out chain by chain. The **Paymasters** tab in
  the [Client Dashboard](https://dashboard.trustware.io) shows which chains you
  can deploy on, and marks the rest **Pending**.
</Note>

## How ownership works

When you deploy a paymaster from the Client Dashboard, the connected wallet becomes the **client owner** of a paymaster contract that belongs to your project. Every project and chain combination gets its own contract, so budgets and balances never mix across projects.

Sponsorship funds sit in that paymaster's on-chain EntryPoint deposit.

| Who                                                  | Controls                                                                                                        |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| You, through the owner wallet                        | Withdrawing the EntryPoint deposit, and administering the contract                                              |
| Trustware, through its off-chain authorization layer | Deciding which eligible operations are authorized for sponsorship, against your active budget and SDK-key rules |

Keep those two apart when you reason about risk. Trustware authorizes sponsorship, and your paymaster verifies that authorization before it pays. Trustware cannot move, withdraw, or redirect client sponsorship funds.

Anyone can top up the deposit, since funding is an open payment into the contract. Only the owner wallet can withdraw it.

One operational caveat goes with that. Paymaster operations can be paused in an emergency, which temporarily stops sponsorship and withdrawals on the affected paymaster. A pause is a stop, not a transfer of authority. It gives Trustware no ability to withdraw or redirect your funds, and withdrawal stays with the owner wallet once operations resume.

## When sponsorship applies

Sponsorship is additive to routing. It changes how an eligible route executes, and it never changes whether a route resolves.

Gas is sponsored on the **source chain**, where the route executes and gas is charged. That chain needs a paymaster of yours with active coverage on it. The destination chain is unconstrained, so if your coverage is on Base, a Base to Arbitrum deposit can be sponsored while an Ethereum to Base deposit cannot.

| Route                                                                                    | Sponsorship                                                               |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| An EVM route executing from a smart account on a chain where you have paymaster coverage | Eligible. The route can carry a `sponsorship` object.                     |
| An EVM route executing from any other source chain                                       | Not sponsored. Coverage is per chain, and the source chain needs its own. |
| A plain EOA transaction                                                                  | Not sponsored. An EOA send does not carry an ERC-4337 paymaster payload.  |
| A non-EVM route, such as Solana or Bitcoin                                               | Not sponsored. ERC-4337 paymasters are EVM only.                          |
| A deposit-address flow                                                                   | Not sponsored. `Trustware.buildDepositAddress()` returns no sponsorship.  |

Not every route is gasless. A route outside those boundaries, or one with no active deployment, budget, or matching rule, still resolves and executes normally. It just pays its own gas.

## Set up a paymaster

<Steps>
  <Step title="Select your project">
    Sponsorship configuration is scoped to a project, because rules attach to that project's SDK keys. Switch to the project you want before you start.
  </Step>

  <Step title="Open Paymasters">
    Go to the **Paymasters** tab in the Client Dashboard sidebar.
  </Step>

  <Step title="Deploy on a chain">
    Click **New Deployment**, connect the wallet you want as the owner, choose a chain you can deploy on, and deploy. The connected wallet becomes the client owner of the contract.

    <Warning>
      Use a wallet you can keep long term. The owner wallet is the only wallet
      that can withdraw the sponsorship balance later.
    </Warning>
  </Step>

  <Step title="Top up the balance">
    Open the deployment and click **Top Up** to deposit ETH into the paymaster's EntryPoint balance. The dashboard shows that balance in ETH and its approximate USD value.
  </Step>

  <Step title="Create a chain budget">
    Under **Chain Budget**, add a monthly cap for the project on that chain. A budget is active as soon as you create it. The budget is the ceiling for everything below it, the dashboard tracks spend against it, and editing it later changes that monthly amount.
  </Step>

  <Step title="Add an SDK-key rule">
    Under **SDK Rules**, create at least one active rule for an SDK key. A deployment and a budget on their own sponsor nothing, because rules are what make a given key eligible.
  </Step>
</Steps>

A chain is only ready when all three exist: a deployment, an active budget, and active rule coverage. The dashboard shows that readiness per chain.

## Configure sponsorship rules

A rule attaches to one SDK key on one chain and sets how much you are willing to sponsor for a user of that key.

| Rule type                | What it limits                                                                                              |
| ------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Onboarding transaction   | A number of sponsored transactions per sender, so you can cover a user's first deposit and nothing after it |
| Per-user lifetime budget | A total sponsored spend per sender, in USD, that never resets                                               |
| Per-user monthly budget  | A sponsored spend per sender, in USD, that resets monthly                                                   |

Every rule also takes two optional controls:

* **Priority.** Rules are evaluated from the lowest priority number upward, and the first eligible rule wins. New rules default to `100`, so leave room above and below it.
* **Max cost per transaction.** A USD ceiling per operation. Anything above it is not sponsored under that rule.

The project-chain monthly budget sits above all of them. Once monthly spend reaches that cap, no rule sponsors anything more on that chain until the next month, regardless of per-user headroom.

To hold a rule back without deleting it, set its status to disabled and it drops out of evaluation.

## Use sponsored routes

Nothing changes in how you request a route. When a route is fully eligible and authorized, `Trustware.buildRoute()` returns an optional `sponsorship` object alongside the usual result.

```ts theme={null}
const route = await Trustware.buildRoute({
  fromChain: "8453", // Base, the source chain in this example
  toChain: "42161",
  fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
  toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
  fromAmount: "1000000", // 1 USDC, source base units
  fromAddress: await Trustware.getAddress(),
  toAddress: "0xDestination...",
});

if (route.sponsorship) {
  // This route is authorized for gas sponsorship from your paymaster.
}
```

See [`RouteSponsorship`](/api-reference/types#routesponsorship) for the full field list.

**With the widget**, there is nothing to wire up. When a sponsored route resolves for an ERC-20 source asset on an EVM chain, the widget executes it as a smart-account user operation so your paymaster can pay the gas. If that path fails, the widget falls back to the ordinary route on the next confirm.

**With the headless core**, which function you send the route through decides whether the paymaster is reached.

* `sendRouteAsUserOperation()`, exported from the `@trustware/sdk/smart-account` entry point, is the supported way to execute a sponsored route yourself. It runs the route as a smart-account user operation against your paymaster, signed by the wallet you already have. This is the same path the widget takes.
* `Trustware.sendRouteTransaction()` attaches the sponsorship payload only on the custom `sendTransaction` wallet interface. Given a standard EIP-1193 wallet it sends a plain transaction, not a user operation. Do not pass a sponsored route to it with a standard EIP-1193 wallet. Use `sendRouteAsUserOperation()` instead.

Both paths run the route from a smart account, which adds one step for an ERC-20 source asset.

<Note>
  A sponsored ERC-20 deposit pulls the source tokens through Permit2, so on the
  first one the SDK asks the connected wallet for a plain approval transaction and
  waits for it to confirm. That approval is unlimited and lives per token per
  chain, so it is requested once and later sponsored deposits of the same token
  skip it. It is
  an ordinary transaction rather than a user operation, so the user pays its gas
  and needs a small native balance for that first deposit. Native source assets
  skip Permit2 entirely.
</Note>

Call `sendRouteAsUserOperation()` with the sponsored route itself, so keep it inside the `route.sponsorship` check. Every other argument describes the source side the sponsorship was issued against:

```ts theme={null}
import { sendRouteAsUserOperation } from "@trustware/sdk/smart-account";
import { base } from "viem/chains";

// `provider` is the EIP-1193 provider of the wallet you already connected.
if (route.sponsorship) {
  const sent = await sendRouteAsUserOperation({
    route,
    fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
    fromAmountWei: 1_000_000n, // 1 USDC, source base units
    fromDecimals: 6,
    eoaAddress: (await Trustware.getAddress()) as `0x${string}`,
    chainId: 8453, // Base, the chain the route executes on
    viemChain: base,
    eip1193Request: (args) => provider.request(args),
  });

  // The receipt is submitted for you, so poll for the destination result.
  const result = await Trustware.pollStatus(sent.intentId);

  if (result.status === "success") {
    console.log("Deposit complete:", result.destTxHash);
  }
}
```

The call returns the `userOpHash`, the route's `intentId`, and the source `txHash` once the operation lands in a block. If the wait for inclusion times out, `txHash` comes back undefined while the operation can still land, which is another reason to poll on the `intentId`. Give it a route with no sponsorship and it throws, because there is no paymaster payload to execute against.

<Note>
  Every sponsorship is issued for one exact route. `Trustware.sendRouteTransaction()`
  checks the route calldata against the sponsorship's `callDataHash` first, and if they
  do not match it ignores the sponsorship and falls back to the ordinary path, including
  the source token approval. That check keeps a sponsorship bound to the route it was
  issued for. It does not make `sendRouteTransaction()` a sponsored path.
</Note>

## Operate the paymaster

Everything below lives on the **Paymasters** tab, per chain.

* **Watch the balance.** Expand the deployment to see the EntryPoint deposit. Treat it as an operational metric rather than a set-and-forget deposit, because sponsorship stops silently when it runs dry.
* **Watch the budget.** The chain budget row shows spend against your monthly cap, and the summary cards show live chains, total monthly budget, remaining budget, and active rule count.
* **Top up.** Click **Top Up** and deposit ETH. This does not need the owner wallet.
* **Withdraw.** Click **Withdraw** and connect the owner wallet. The dashboard warns you when the connected wallet is not the owner, because the transaction reverts in that case.
* **Review activity.** The [Transactions](/quickstart#client-dashboard) tab flags each transaction as sponsored or unsponsored, and Analytics reports gas sponsored in USD per chain and per key.

## Why sponsorship may be absent

An absent `sponsorship` object is not a route failure. Work down this list when you expected one and did not get it.

<AccordionGroup>
  <Accordion title="The route is outside the sponsorship boundary">
    Check the route against [when sponsorship applies](#when-sponsorship-applies). Non-EVM routes, deposit-address flows, and plain EOA execution never carry a paymaster.
  </Accordion>

  <Accordion title="The source chain has no paymaster coverage">
    Gas is sponsored on the chain the route executes from, so that is the chain that needs a supported paymaster configuration. A route that starts on a chain without one resolves normally but carries no sponsorship. A route that starts on a covered chain can be sponsored whatever its destination chain is.
  </Accordion>

  <Accordion title="Setup is incomplete">
    Confirm the chain shows a deployment, an active budget, and at least one active rule. Any one of the three missing means no sponsorship.
  </Accordion>

  <Accordion title="The rule does not match the key">
    Rules attach to a specific SDK key on a specific chain. A request made with a different key from the same project matches nothing.
  </Accordion>

  <Accordion title="A limit is already spent">
    The sender may have used their onboarding allowance or per-user budget, the operation may cost more than the rule's max cost per transaction, or the project-chain monthly cap may be reached.
  </Accordion>

  <Accordion title="The deposit is empty">
    Check the EntryPoint balance on the deployment and top it up.
  </Accordion>
</AccordionGroup>

If none of those explain it, send the route's `sponsorship.requestId`, or the `intentId` when there is no sponsorship, to [support@trustware.io](mailto:support@trustware.io).

## Related reference

<CardGroup cols={2}>
  <Card title="TypeScript types" icon="brackets-curly" href="/api-reference/types#routesponsorship">
    The `RouteSponsorship` field list, including `callDataHash`, `maxCost`, and `paymasterAndData`.
  </Card>

  <Card title="Headless core" icon="terminal" href="/integration/headless-core">
    The full `Trustware` namespace API, including `buildRoute`, `sendRouteTransaction`, and `pollStatus`.
  </Card>

  <Card title="Client Dashboard" icon="gauge" href="/quickstart#client-dashboard">
    The Paymasters, Transactions, and Analytics tabs, and where SDK keys come from.
  </Card>
</CardGroup>
