Surface relayer sponsorship signal end-to-end (additive, non-breaking)#1007
Merged
Conversation
`RpcRelayer.feeOptions` now forwards the server's `sponsored: boolean` to callers, and both `feeOptions` and `feeTokens` mark their swallowed-error returns with `failed: true`. The `Relayer` interface and all bundled implementations (Rpc, Sequence, Local, EIP6963, Pk) are widened to match. Additive change: existing consumers ignoring the new fields are unaffected. Downstream sponsorship classifiers should switch from `!feeOption` inference to `sponsored === true` so a real subsidy is no longer indistinguishable from a swallowed `/FeeOptions` error. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`StandardRelayerOption` gains optional `sponsored` and `failed` fields, populated on both construction branches in `transactions.ts` from the relayer SDK's new `feeOptions` return. `isStandardRelayerOption` / `isERC4337RelayerOption` are re-exported so consumers can narrow before reading the new fields. UI consumers that classified sponsorship by "no fee option attached" should switch to `sponsored === true` to distinguish a real subsidy from a swallowed `/FeeOptions` error. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`DappClient.isSponsored(chainId, transactions)` and `ChainSessionManager.isSponsored(calls)` return true only when the relayer's `/FeeOptions` endpoint explicitly reports sponsorship; any error, network failure, or absence of sponsorship returns false. A true result is always safe to surface as "free gas" in UI. Prefer this over inferring sponsorship from an empty `getFeeOptions` array — a swallowed `/FeeOptions` error produces the same empty shape as a real subsidy. `getFeeOptions` is unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e34cf7d09
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
taylanpince
approved these changes
May 29, 2026
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
Fixes the
/FeeOptionsmisclassification described in our internal bug report: a real subsidy and a swallowed/FeeOptionserror currently produce byte-identical option shapes, so any consumer using!feeOptionas the sponsorship discriminator labels failed quotes as "free gas". This PR makes the two cases distinguishable end-to-end without breaking any existing consumer.@0xsequence/relayer—feeOptionsnow forwards the server'ssponsored: boolean; bothfeeOptionsandfeeTokensmark swallowed errors withfailed: true. TheRelayerinterface and all impls (Rpc, Sequence, Local, EIP6963, Pk) are widened to match.@0xsequence/wallet-wdk—StandardRelayerOptiongains optionalsponsored/failed, populated on both construction branches intransactions.ts;isStandardRelayerOption/isERC4337RelayerOptionare now re-exported.@0xsequence/dapp-client— addsDappClient.isSponsored(chainId, txs)(andChainSessionManager.isSponsored(calls)), which returnstrueonly when the relayer explicitly reports sponsorship.Downstream consumers should switch sponsorship classification from
!feeOptioninference tosponsored === true(orisSponsored()) so a real subsidy is no longer indistinguishable from a swallowed error. All three packages getminorchangesets — additive types, no behavior change for unchanged code paths.(Supersedes #1006, which was closed when the branch was renamed.)
Test plan
feeOptionsandfeeTokenserror paths (124/124 vitest passing)sponsored === falseandfailed === undefinedon the LocalRelayer/PkRelayer pathpnpm test:anvil)option.sponsored === truefor a genuinely sponsored tx andoption.failed === truefor a forced/FeeOptions400 (e.g. Polygon Morpho capped vault, Aave insufficient-balance deposit)🤖 Generated with Claude Code