Draft ERC defining a standardized JSON-RPC capability (`pm_getPaymasterStubData`, `pm_getPaymasterData`) that wallets call against an app-provided paymaster web service to fetch sponsorship data for an ERC-4337 UserOperation, enabling sponsored gas without locking apps into a specific bundler/paymaster vendor. Status: Draft.
- 01vendor-neutral gas sponsorship
- 02ERC-4337 paymaster sponsorship UX
- 03Coinbase Smart Wallet / 5792 capability sponsorship
- 04decoupling app paymaster logic from wallet UX
- pnpm add viem permissionless
- # providers: Pimlico, Alchemy, ZeroDev, Coinbase Developer Platform all expose 7677 endpoints
Expose an ERC-7677 paymaster web service at a URL the wallet trusts (passed via ERC-5792 `wallet_sendCalls` capabilities). Two RPC methods: `pm_getPaymasterStubData(userOp, entryPoint, chainId, context) -> { paymaster, paymasterData, paymasterVerificationGasLimit, paymasterPostOpGasLimit, sponsor?, isFinal? }` (cheap, returns dummy data so the wallet can estimate gas) and `pm_getPaymasterData(...)` (returns the real signed paymaster data after gas estimation). EntryPoint v0.7 returns split fields; v0.6 returns a packed `paymasterAndData`. The wallet calls stub first, runs `eth_estimateUserOperationGas` against the bundler with stub data, then calls real `pm_getPaymasterData` and submits via `eth_sendUserOperation`. Validate sponsorship policy (allowlisted contracts, per-user spend cap, abuse heuristics) on the service — never sign blindly.
- ⚑Status is Draft — RPC namespace `pm_*` is stable in major implementations (Coinbase, Pimlico) but field names differ between EntryPoint v0.6 and v0.7. Branch on `entryPoint` argument before signing.
- ⚑`getPaymasterStubData` MUST return realistic gas-limit dummies (not zeros) or the wallet's `eth_estimateUserOperationGas` will under-estimate and the final UserOp will run out of gas at execution.
- ⚑The paymaster signs over `(userOp, validUntil, validAfter, chainId)` — the SAME hash must be reproduced when the wallet calls back for real data, so stub and final paymasterData must use IDENTICAL nonces and timestamps or signatures invalidate.
- ⚑CORS: wallets call `pm_*` from the user's browser/extension — your service must allowlist wallet origins. Coinbase Smart Wallet, MetaMask Smart Account, Safe all have distinct origins.
- ⚑Stake & deposit live on-chain at the EntryPoint — your service issues sponsorships but the actual ETH is the paymaster contract's deposit. Top up via `EntryPoint.depositTo(paymaster)` and monitor `getDepositInfo` or sponsorships start failing silently.
- ⚑Sponsoring untrusted call data is a DoS vector — an attacker bursts UserOps to drain your deposit. Always validate `userOp.callData` decode (function selector allowlist, target allowlist) before returning sponsorship.