fix(paymaster): CORS headers for ERC-7677 endpoint#9
Closed
PierreBesson wants to merge 5 commits into
Closed
Conversation
… data
Wallets that broker EIP-5792 paymasterService (e.g. Reown / WalletConnect via
secure.walletconnect.org) call the paymaster JSON-RPC endpoint cross-origin.
Without CORS, preflight failed and the wallet broadcast UserOps with
paymasterAndData = 0x, causing the bundler to reject them with AA21
("didn't pay prefund") because the smart account had no ETH to cover gas.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…text Reown's embedded smart wallets drop the `capabilities.paymasterService.context` field when bridging to ERC-7677, so the paymaster route was rejecting all sponsored UserOps with `Missing or invalid context.orgAddress`. Encode the org address in the paymaster URL itself so it survives regardless of the wallet's context handling; keep the context fallback for spec-compliant wallets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… flow Reown's smart-wallet stack reports "Sponsorship Available" but ships UserOps with paymasterAndData=0x. Add server-side logging so Vercel function logs show exactly which method is called, the URL/query, the entryPoint, and the response we returned. We can then reason about why the wallet isn't attaching the data instead of guessing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Vercel logs showed Reown's smart-wallet stack calls pm_getPaymasterStubData
twice (once for the modal estimate, once on confirm) and never calls
pm_getPaymasterData. Without `isFinal: true` on the stub response, the wallet
treats the data as non-final, expects a follow-up call that never happens,
and submits the UserOp with paymasterAndData=0x — triggering AA21.
Also branch the response shape on EntryPoint version: v0.7 wallets need
{paymaster, paymasterData, paymasterVerificationGasLimit,
paymasterPostOpGasLimit}; v0.6 keeps the existing {paymasterAndData}.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Server logs prove Reown calls our paymaster with valid responses (twice for stub, never for data, isFinal: true). Yet UserOps still ship with paymasterAndData=0x. Add browser-side logging of: - the capabilities Reown advertises (specifically paymasterService.supported) - the exact wallet_sendCalls payload we send This will tell us whether the wallet receives the URL we think it does and whether the capability claim matches the actual broadcast behavior. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wallets that broker EIP-5792
paymasterService(e.g. Reown / WalletConnect viasecure.walletconnect.org) call our paymaster JSON-RPC endpoint cross-origin. Without CORS the browser blocked the preflight, the wallet then broadcast UserOps withpaymasterAndData = 0x, and the bundler rejected them withAA21 didn't pay prefundbecause the smart account had no ETH for gas.This adds:
OPTIONShandler returning204with CORS headers (clears preflight).Access-Control-Allow-Origin: *,Allow-Methods: POST, OPTIONS,Allow-Headers: Content-Type,Max-Age: 86400on every JSON response (success + error).*is correct here: the route is a public ERC-7677 JSON-RPC endpoint with no cookies/auth state —context.orgAddressis the only client input and CGPaymaster enforces its own per-org budget on-chain.Test plan
204withAccess-Control-Allow-*headers.paymasterAndDataand succeed (no moreAA21 didn't pay prefund)./program/[address]) since they shareuseSponsoredWrite.🤖 Generated with Claude Code