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 noAuthorization 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.
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: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 inpm_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.
Related
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.