Skip to main content
The App SDK is provider-neutral. It does not host a paymaster and it does not prefer one. When you set paymasterOptions, the Startale App forwards standard ERC-7677 requests to the URL you name, and any service that answers them correctly will work. This page is the contract that service has to satisfy.

How the request reaches your paymaster

The Startale App calls your paymaster from its own server rather than from the browser. Your endpoint therefore has to be reachable from the public internet over HTTPS, so it cannot be a localhost service or sit behind a private network address. It also never sees the browser’s headers: nothing you set on the client reaches it, and no Authorization header is forwarded.

Two required methods

Both methods are JSON-RPC calls against the same endpoint.

pm_getPaymasterStubData

Called before gas estimation. Return a stub that is representative in size so the bundler can estimate gas, without committing a real signature. The stub request does not carry the user’s operation. The Startale App requests it with a placeholder operation, with a zero-address sender, empty callData, and nonce and gas fields set to zero, then caches the result and reuses it across transactions. Do not validate stub requests or apply your sponsorship policy to them: a rule on sender or on the target contract rejects every stub, and sponsorship fails. Request
params[1] is the EntryPoint address, params[2] is the hex chain id, and params[3] is the context object described below. Startale accounts use EntryPoint v0.7 at the address shown. Response (EntryPoint v0.7)

pm_getPaymasterData

Called after gas estimation, with the user’s UserOperation. Return the real signature. The request shape is the same and the response is the same, with real paymasterData in place of the stub.
Do not return isFinal: true from pm_getPaymasterStubData. ERC-7677 lets a stub declare itself final. The Startale App then skips pm_getPaymasterData and submits paymaster data that was produced for the placeholder operation, not for the user’s.
This is the call that commits you to paying. Every sponsorship decision your service makes belongs here, evaluated against the sender and callData of the operation in front of it.

The context object

ERC-7677 allows a fourth parameter carrying a service-defined context object. The Startale App sends one, and its contents belong to the App rather than to your configuration:
The id field of paymasterOptions is not part of it and does not reach you. Treat the context as opaque, and ignore any field you do not recognise. If your service needs to distinguish a policy, a tenant, or an environment, put that distinction in the URL. A separate path or query parameter per policy works, and it is the only mechanism available through this integration. This also means a hosted provider that requires its own context, such as Alchemy’s policyId, cannot be used directly. Put it behind a proxy that adds the context before forwarding. See Secure your paymaster. calculateGasLimits tells you which of two attempts a request belongs to. The Startale App always makes the false attempt first, and makes the true attempt only if the first one fails: Return paymasterVerificationGasLimit and paymasterPostOpGasLimit from both methods and you satisfy either strategy without having to branch on the flag. pm_getPaymasterData can therefore be called more than once for a single transaction, for example when the Startale App retries, so it has to be safe to call repeatedly. Do not decrement a quota, consume a nonce, or write a billing record on the assumption of one call per transaction. Count spend from onchain settlement instead.

Deciding what to run

Whichever you choose, EntryPoint v0.7 is the version in use on Soneium, so return the v0.7 response fields shown above.

Constraints applied when forwarding

Keep responses small and fast. A paymaster that takes longer than 10 seconds to sign will fail the user’s transaction, and the failure will look to your user like the application is broken.

Before you go live

Serve both methods from one HTTPS endpoint on a public host, returning EntryPoint v0.7 fields from each. Answer stub requests without validating them, and never mark a stub final. Make the sponsorship decision in pm_getPaymasterData from sender and callData, decline with a JSON-RPC error rather than a malformed result, and ignore any context field you do not recognise instead of rejecting the request outright. Log every signature against the resulting UserOperation hash so spend can be reconciled later, and keep responses well inside the 10 second timeout.

Configure paymasterOptions

The call site, and the batched-call requirement that makes it take effect.

Secure your paymaster

Your URL is public. Scope what you sponsor before you fund it.

Who pays for gas

Mini App and standalone contexts, and the division of responsibility.

Batched calls

How wallet_sendCalls builds the UserOperation your paymaster signs.