Skip to main content
On EVM, a sponsored send lets the user pay the fee in an ERC-20 token instead of native gas. You bring your own bundler and paymaster. For the model, see Sponsorship.

Configure the infrastructure

Set both bundlerUrl and paymasterUrl on the client config. They are required together. With only one, there is no sponsored rail, and a send that asks for sponsorship fails.
Many providers (Pimlico, Alchemy) serve both from one endpoint; pass the same URL twice.

Ask for sponsorship

Sponsorship is a per-send choice, and there are two ways to ask for it:
Omit both and the send is native-gas. Sponsorship is never inferred from your configuration: a client with a paymaster wired up still pays native gas unless a send asks. If the sponsored rail is not reachable, either call throws SponsorshipUnavailableError before anything is signed, naming which side is missing. It does not degrade to native-gas. That default exists because degrading spends the user’s own gas on a transaction you meant to sponsor, and because the users this rail serves hold no native gas at all, so the send fails anyway on an error that names a balance rather than your missing endpoint. There is no degrade and no flag that enables one. A request is served or it errors. A misconfigured or unreachable rail surfaces the same way: SponsorshipUnavailableError, before signing. There is no ahead-of-time “which tokens does this paymaster take” list to check first: ERC-7677 makes that answer transaction-scoped and provider-specific, so the paymaster accepts or rejects the actual send at pm_getPaymasterStubData. For gas-free sponsorship there is no token to pick at all.

Send with a fee token

Trigger the send through the provider with an EIP-5792 wallet_sendCalls request. The per-send fee token rides in the paymasterService capability’s context:
A single-token paymaster (for example, Circle USDC) can omit context.token; the provider then falls back to the chain’s default registry fee token. If you use wagmi, its useSendCalls produces the same request.

Confirm which rail ran

The returned id is the intent id. Check the rail rather than assuming your configuration took effect: use wallet_getCallsStatus, or on the core send path inspect receipt.rail. A sponsored EVM receipt has rail: "sponsored", an id that is a userOpHash, and status: "pending" until the bundler reports a receipt. See Receipts.