Bump turbo from 2.9.8 to 2.9.14 (0xsequence#1008) #641
Conversation
#1007) * feat(relayer): propagate sponsored signal and mark swallowed errors `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> * feat(wallet-wdk): carry sponsored/failed on StandardRelayerOption `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> * feat(dapp-client): add isSponsored for explicit sponsorship checks `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> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Bumps [turbo](https://github.com/vercel/turborepo) from 2.9.8 to 2.9.14. - [Release notes](https://github.com/vercel/turborepo/releases) - [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md) - [Commits](vercel/turborepo@v2.9.8...v2.9.14) --- updated-dependencies: - dependency-name: turbo dependency-version: 2.9.14 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
|
|
Reviewer's GuidePropagates explicit sponsorship and error signals from relayer fee endpoints through the relayer interface, wallet WDK, and dapp client, and adds a high-level isSponsored API, while bumping turbo and publishing patch/minor releases of affected packages. Sequence diagram for DappClient.isSponsored flow using relayer.feeOptionssequenceDiagram
participant DappClient
participant ChainSessionManager
participant Relayer
DappClient->>DappClient: getOrInitializeChainManager(chainId)
DappClient->>ChainSessionManager: isSponsored(transactions)
ChainSessionManager->>ChainSessionManager: _buildAndSignCalls(callsToSend)
ChainSessionManager->>ChainSessionManager: _fingerprintCalls(callsToSend)
ChainSessionManager->>Relayer: feeOptions(walletAddress, chainId, signedCall.to, callsToSend, signedCall.data)
Relayer-->>ChainSessionManager: { options, quote, sponsored, failed }
alt [feeOptions.sponsored === true && !feeOptions.failed]
ChainSessionManager-->>DappClient: true
else [otherwise or on error]
ChainSessionManager-->>DappClient: false
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="packages/services/relayer/src/relayer/standard/sequence.ts" line_range="20-24" />
<code_context>
}
- async feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: RpcFeeToken[]; paymentAddress?: Address.Address }> {
+ async feeTokens(): Promise<{
+ isFeeRequired: boolean
+ tokens?: RpcFeeToken[]
+ paymentAddress?: Address.Address
+ failed?: boolean
+ }> {
try {
</code_context>
<issue_to_address>
**issue (bug_risk):** SequenceRelayer’s `feeTokens` does not surface the new `failed` signal, which may lead to inconsistent error-handling compared to RpcRelayer.
`RpcRelayer.feeTokens` now maps transport errors to `{ isFeeRequired: false, failed: true }`, but `SequenceRelayer.feeTokens` still awaits `this.service.feeTokens()` directly and will throw on network errors without setting `failed`. This means callers relying on the `failed` flag will see different behaviour between relayers.
Consider either wrapping `this.service.feeTokens()` in a try/catch and returning `{ isFeeRequired: false, failed: true }` on failure (to match `RpcRelayer`), or explicitly standardizing/documenting that some relayers throw while others use the flag, and updating callers accordingly, to avoid subtle relayer-specific error-handling paths.
</issue_to_address>
### Comment 2
<location path="packages/services/relayer/test/relayer/relayer.test.ts" line_range="405-418" />
<code_context>
+ expect(result.failed).toBeUndefined()
+ })
+
+ it('should return sponsored:false and failed:true when the server errors', async () => {
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
+ const fetchImpl = vi.fn(
+ async () =>
+ new Response(JSON.stringify({ error: 'Aborted', code: 1005, msg: 'simulation failed' }), { status: 400 }),
+ )
+ const relayer = new Relayer.RpcRelayer('https://relayer.test', TEST_CHAIN_ID, 'https://rpc.test', fetchImpl)
+
+ const result = await relayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, TEST_TO_ADDRESS, [mockCall])
+
+ expect(result).toEqual({ options: [], sponsored: false, failed: true })
+ expect(warn).toHaveBeenCalled()
+ warn.mockRestore()
+ })
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test for network/transport errors in `RpcRelayer.feeOptions` to cover the catch branch when `fetch` rejects, not just when it returns an error HTTP response.
This test covers the 4xx + error-payload path. There’s also a separate failure mode where `fetchImpl` rejects (e.g. network error/timeout) instead of returning a `Response`. Please add a test that uses `vi.fn().mockRejectedValue(new Error('network failure'))` for `fetchImpl` and asserts that `feeOptions` still returns `{ options: [], sponsored: false, failed: true }` and logs a warning, to cover that branch of the `catch` block.
```suggestion
it('should return sponsored:false and failed:true when the server errors', async () => {
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
const fetchImpl = vi.fn(
async () =>
new Response(JSON.stringify({ error: 'Aborted', code: 1005, msg: 'simulation failed' }), { status: 400 }),
)
const relayer = new Relayer.RpcRelayer('https://relayer.test', TEST_CHAIN_ID, 'https://rpc.test', fetchImpl)
const result = await relayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, TEST_TO_ADDRESS, [mockCall])
expect(result).toEqual({ options: [], sponsored: false, failed: true })
expect(warn).toHaveBeenCalled()
warn.mockRestore()
})
it('should return sponsored:false and failed:true when the network request fails', async () => {
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
const fetchImpl = vi.fn().mockRejectedValue(new Error('network failure'))
const relayer = new Relayer.RpcRelayer('https://relayer.test', TEST_CHAIN_ID, 'https://rpc.test', fetchImpl)
const result = await relayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, TEST_TO_ADDRESS, [mockCall])
expect(result).toEqual({ options: [], sponsored: false, failed: true })
expect(warn).toHaveBeenCalled()
warn.mockRestore()
})
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request introduces explicit sponsorship signals and error tracking across the relayer services, dapp-client, and WDK packages. Specifically, the Relayer interface's feeOptions now returns a sponsored boolean and a failed flag, while feeTokens includes a failed flag to distinguish swallowed errors from actual zero-fee scenarios. A new isSponsored helper has been added to DappClient and ChainSessionManager to safely check for active sponsorship. Feedback on these changes suggests defaulting the sponsored field to false if it is missing from server or service responses to guarantee type safety, and providing a default value of BigInt(0) for tx.value in ChainSessionManager to prevent potential serialization issues.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary by Sourcery
Expose explicit sponsorship and error signals from relayer fee endpoints and wire them through wallet clients, while adding a safe isSponsored helper for UIs and updating related packages and tooling.
New Features:
Bug Fixes:
Enhancements:
Build:
Documentation:
Tests:
Chores: