From 55121afceb45da84019ef565f84b2682cf6c5d44 Mon Sep 17 00:00:00 2001 From: Matt Rintoul Date: Fri, 29 May 2026 03:50:43 -0400 Subject: [PATCH 1/3] Surface relayer sponsorship signal end-to-end (additive, non-breaking) (#1007) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * 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 * 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 --------- Co-authored-by: Claude Opus 4.7 --- .changeset/dapp-client-is-sponsored.md | 19 +++++++ .changeset/relayer-sponsored-signal.md | 20 +++++++ .changeset/wdk-sponsored-signal.md | 23 ++++++++ .../services/relayer/src/relayer/relayer.ts | 9 ++- .../relayer/src/relayer/rpc-relayer/index.ts | 15 +++-- .../relayer/src/relayer/standard/eip6963.ts | 9 ++- .../relayer/src/relayer/standard/local.ts | 11 +++- .../src/relayer/standard/pk-relayer.ts | 9 ++- .../relayer/src/relayer/standard/sequence.ts | 12 +++- .../relayer/test/relayer/relayer.test.ts | 55 +++++++++++++++++++ .../dapp-client/src/ChainSessionManager.ts | 48 ++++++++++++++++ packages/wallet/dapp-client/src/DappClient.ts | 24 ++++++++ .../wallet/wdk/src/sequence/transactions.ts | 4 ++ .../wallet/wdk/src/sequence/types/index.ts | 1 + .../src/sequence/types/transaction-request.ts | 2 + packages/wallet/wdk/test/transactions.test.ts | 17 ++++++ 16 files changed, 261 insertions(+), 17 deletions(-) create mode 100644 .changeset/dapp-client-is-sponsored.md create mode 100644 .changeset/relayer-sponsored-signal.md create mode 100644 .changeset/wdk-sponsored-signal.md diff --git a/.changeset/dapp-client-is-sponsored.md b/.changeset/dapp-client-is-sponsored.md new file mode 100644 index 0000000000..731c28d3bd --- /dev/null +++ b/.changeset/dapp-client-is-sponsored.md @@ -0,0 +1,19 @@ +--- +'@0xsequence/dapp-client': minor +--- + +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`, so 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 also produces an empty array, so the inference +can misclassify a failed quote as a real subsidy. The new method uses the +positive `sponsored: boolean` signal from `@0xsequence/relayer`'s widened +`feeOptions` return. + +`getFeeOptions` is unchanged. diff --git a/.changeset/relayer-sponsored-signal.md b/.changeset/relayer-sponsored-signal.md new file mode 100644 index 0000000000..f922932ed4 --- /dev/null +++ b/.changeset/relayer-sponsored-signal.md @@ -0,0 +1,20 @@ +--- +'@0xsequence/relayer': minor +--- + +Surface explicit sponsorship signal on `feeOptions` and an error marker on +`feeOptions` / `feeTokens`. + +- `RpcRelayer.feeOptions` now returns `sponsored: boolean`, forwarded from the + server's `FeeOptionsReturn.sponsored`. The `Relayer` interface and all + bundled implementations (`RpcRelayer`, `SequenceRelayer`, `LocalRelayer`, + `EIP6963Relayer`, `PkRelayer`) carry the new field. +- When `feeOptions` swallows a transport / server error it now returns + `{ options: [], sponsored: false, failed: true }` (was `{ options: [] }`). +- When `feeTokens` swallows an error it now returns + `{ isFeeRequired: false, failed: true }` (was `{ isFeeRequired: false }`). + +These changes are additive — existing consumers that ignore the new fields are +unaffected. Consumers that classified sponsorship by "no fee option attached" +should migrate to `sponsored === true` to distinguish a real subsidy from a +swallowed `/FeeOptions` error. diff --git a/.changeset/wdk-sponsored-signal.md b/.changeset/wdk-sponsored-signal.md new file mode 100644 index 0000000000..14d94ddce8 --- /dev/null +++ b/.changeset/wdk-sponsored-signal.md @@ -0,0 +1,23 @@ +--- +'@0xsequence/wallet-wdk': minor +--- + +Carry `sponsored` / `failed` through `StandardRelayerOption`. + +`StandardRelayerOption` now exposes two optional fields: + +- `sponsored?: boolean` — populated from the relayer SDK's new `feeOptions` + return field. `true` means the server confirmed an active sponsorship policy + match; `false` means it did not (or the quote failed). +- `failed?: boolean` — `true` when the relayer's `feeOptions` call was swallowed + due to a transport or server error. + +Both fields are populated on the empty-options construction branch and the +per-option mapping branch in `transactions.ts`. The new `isStandardRelayerOption` +and `isERC4337RelayerOption` runtime helpers are now re-exported from the +package root for consumers that need to narrow `RelayerOption` before reading +the new fields. + +UI / wallet consumers that previously classified sponsorship by "no `feeOption` +attached" should switch to `sponsored === true` so a real subsidy is no longer +indistinguishable from a swallowed `/FeeOptions` error. diff --git a/packages/services/relayer/src/relayer/relayer.ts b/packages/services/relayer/src/relayer/relayer.ts index 9f648004af..d0c5580822 100644 --- a/packages/services/relayer/src/relayer/relayer.ts +++ b/packages/services/relayer/src/relayer/relayer.ts @@ -11,7 +11,12 @@ export interface Relayer { isAvailable(wallet: Address.Address, chainId: number): Promise - feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> + feeTokens(): Promise<{ + isFeeRequired: boolean + tokens?: FeeToken[] + paymentAddress?: Address.Address + failed?: boolean + }> feeOptions( wallet: Address.Address, @@ -19,7 +24,7 @@ export interface Relayer { to: Address.Address, calls: Payload.Call[], data?: Hex.Hex, - ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + ): Promise<{ options: FeeOption[]; quote?: FeeQuote; sponsored: boolean; failed?: boolean }> relay(to: Address.Address, data: Hex.Hex, chainId: number, quote?: FeeQuote): Promise<{ opHash: Hex.Hex }> diff --git a/packages/services/relayer/src/relayer/rpc-relayer/index.ts b/packages/services/relayer/src/relayer/rpc-relayer/index.ts index 814d25bbd3..05ba8be762 100644 --- a/packages/services/relayer/src/relayer/rpc-relayer/index.ts +++ b/packages/services/relayer/src/relayer/rpc-relayer/index.ts @@ -123,7 +123,12 @@ export class RpcRelayer implements Relayer { return Promise.resolve(this.chainId === chainId) } - async feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: RpcFeeToken[]; paymentAddress?: Address.Address }> { + async feeTokens(): Promise<{ + isFeeRequired: boolean + tokens?: RpcFeeToken[] + paymentAddress?: Address.Address + failed?: boolean + }> { try { const { isFeeRequired, tokens, paymentAddress } = await this.client.feeTokens() if (isFeeRequired) { @@ -140,7 +145,7 @@ export class RpcRelayer implements Relayer { } } catch (e) { console.warn('RpcRelayer.feeTokens failed:', e) - return { isFeeRequired: false } + return { isFeeRequired: false, failed: true } } } @@ -150,7 +155,7 @@ export class RpcRelayer implements Relayer { to: Address.Address, calls: Payload.Call[], data?: Hex.Hex, - ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + ): Promise<{ options: FeeOption[]; quote?: FeeQuote; sponsored: boolean; failed?: boolean }> { // IMPORTANT: // The relayer FeeOptions endpoint simulates `eth_call(to, data)`. // Callers that already built a wallet transaction should pass its `to` and `data`. @@ -182,10 +187,10 @@ export class RpcRelayer implements Relayer { gasLimit: option.gasLimit, })) - return { options, quote } + return { options, quote, sponsored: result.sponsored } } catch (e) { console.warn('RpcRelayer.feeOptions failed:', e) - return { options: [] } + return { options: [], sponsored: false, failed: true } } } diff --git a/packages/services/relayer/src/relayer/standard/eip6963.ts b/packages/services/relayer/src/relayer/standard/eip6963.ts index a290b2c6f9..957b13c443 100644 --- a/packages/services/relayer/src/relayer/standard/eip6963.ts +++ b/packages/services/relayer/src/relayer/standard/eip6963.ts @@ -23,7 +23,12 @@ export class EIP6963Relayer implements Relayer { return this.relayer.isAvailable(wallet, chainId) } - feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { + feeTokens(): Promise<{ + isFeeRequired: boolean + tokens?: FeeToken[] + paymentAddress?: Address.Address + failed?: boolean + }> { return this.relayer.feeTokens() } @@ -32,7 +37,7 @@ export class EIP6963Relayer implements Relayer { chainId: number, to: Address.Address, calls: Payload.Call[], - ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + ): Promise<{ options: FeeOption[]; quote?: FeeQuote; sponsored: boolean; failed?: boolean }> { return this.relayer.feeOptions(wallet, chainId, to, calls) } diff --git a/packages/services/relayer/src/relayer/standard/local.ts b/packages/services/relayer/src/relayer/standard/local.ts index 4135af3b30..e8066674c8 100644 --- a/packages/services/relayer/src/relayer/standard/local.ts +++ b/packages/services/relayer/src/relayer/standard/local.ts @@ -56,7 +56,12 @@ export class LocalRelayer implements Relayer { return new LocalRelayer(new EIP1193ProviderAdapter(provider)) } - feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { + feeTokens(): Promise<{ + isFeeRequired: boolean + tokens?: FeeToken[] + paymentAddress?: Address.Address + failed?: boolean + }> { return Promise.resolve({ isFeeRequired: false, }) @@ -67,8 +72,8 @@ export class LocalRelayer implements Relayer { _chainId: number, _to: Address.Address, _calls: Payload.Call[], - ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { - return Promise.resolve({ options: [] }) + ): Promise<{ options: FeeOption[]; quote?: FeeQuote; sponsored: boolean; failed?: boolean }> { + return Promise.resolve({ options: [], sponsored: false }) } async relay( diff --git a/packages/services/relayer/src/relayer/standard/pk-relayer.ts b/packages/services/relayer/src/relayer/standard/pk-relayer.ts index b1d420a586..28ea0850a4 100644 --- a/packages/services/relayer/src/relayer/standard/pk-relayer.ts +++ b/packages/services/relayer/src/relayer/standard/pk-relayer.ts @@ -107,7 +107,12 @@ export class PkRelayer implements Relayer { return providerChainId === chainId } - feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { + feeTokens(): Promise<{ + isFeeRequired: boolean + tokens?: FeeToken[] + paymentAddress?: Address.Address + failed?: boolean + }> { return this.relayer.feeTokens() } @@ -116,7 +121,7 @@ export class PkRelayer implements Relayer { chainId: number, to: Address.Address, calls: Payload.Call[], - ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + ): Promise<{ options: FeeOption[]; quote?: FeeQuote; sponsored: boolean; failed?: boolean }> { return this.relayer.feeOptions(wallet, chainId, to, calls) } diff --git a/packages/services/relayer/src/relayer/standard/sequence.ts b/packages/services/relayer/src/relayer/standard/sequence.ts index 1ae5ec69bd..8519c618a0 100644 --- a/packages/services/relayer/src/relayer/standard/sequence.ts +++ b/packages/services/relayer/src/relayer/standard/sequence.ts @@ -17,7 +17,12 @@ export class SequenceRelayer implements Relayer { return true } - async feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { + async feeTokens(): Promise<{ + isFeeRequired: boolean + tokens?: FeeToken[] + paymentAddress?: Address.Address + failed?: boolean + }> { const { isFeeRequired, tokens, paymentAddress } = await this.service.feeTokens() if (isFeeRequired) { Address.assert(paymentAddress) @@ -39,17 +44,18 @@ export class SequenceRelayer implements Relayer { to: Address.Address, calls: Payload.Call[], transactionData?: Hex.Hex, - ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + ): Promise<{ options: FeeOption[]; quote?: FeeQuote; sponsored: boolean; failed?: boolean }> { const execute = AbiFunction.from('function execute(bytes calldata _payload, bytes calldata _signature)') const payload = Payload.encode({ type: 'call', space: 0n, nonce: 0n, calls }, to) const signature = '0x0001' // TODO: use a stub signature const data = transactionData ?? AbiFunction.encodeData(execute, [Bytes.toHex(payload), signature]) - const { options, quote } = await this.service.feeOptions({ wallet, to, data }) + const { options, quote, sponsored } = await this.service.feeOptions({ wallet, to, data }) return { options, quote: quote ? { _tag: 'FeeQuote', _quote: quote } : undefined, + sponsored, } } diff --git a/packages/services/relayer/test/relayer/relayer.test.ts b/packages/services/relayer/test/relayer/relayer.test.ts index 028ccf32f0..cd8c096a3e 100644 --- a/packages/services/relayer/test/relayer/relayer.test.ts +++ b/packages/services/relayer/test/relayer/relayer.test.ts @@ -294,6 +294,7 @@ describe('Relayer', () => { vi.mocked(mockRelayer.feeOptions).mockResolvedValue({ options: [], quote: undefined, + sponsored: false, }) vi.mocked(mockRelayer.relay).mockResolvedValue({ opHash: TEST_OP_HASH, @@ -375,6 +376,60 @@ describe('Relayer', () => { data: expectedData, }) }) + + it('should propagate sponsored:true from the server', async () => { + const fetchImpl = vi.fn( + async () => new Response(JSON.stringify({ options: [], sponsored: true }), { status: 200 }), + ) + 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.sponsored).toBe(true) + expect(result.options).toEqual([]) + expect(result.failed).toBeUndefined() + }) + + it('should propagate sponsored:false from the server', async () => { + const fetchImpl = vi.fn( + async () => new Response(JSON.stringify({ options: [], sponsored: false }), { status: 200 }), + ) + 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.sponsored).toBe(false) + 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() + }) + }) + + describe('RpcRelayer.feeTokens', () => { + it('should return failed:true when the server errors', async () => { + const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + const fetchImpl = vi.fn(async () => new Response('boom', { status: 500 })) + const relayer = new Relayer.RpcRelayer('https://relayer.test', TEST_CHAIN_ID, 'https://rpc.test', fetchImpl) + + const result = await relayer.feeTokens() + + expect(result).toEqual({ isFeeRequired: false, failed: true }) + expect(warn).toHaveBeenCalled() + warn.mockRestore() + }) }) describe('Type compatibility', () => { diff --git a/packages/wallet/dapp-client/src/ChainSessionManager.ts b/packages/wallet/dapp-client/src/ChainSessionManager.ts index dc1f30e239..d2ebd1a8e5 100644 --- a/packages/wallet/dapp-client/src/ChainSessionManager.ts +++ b/packages/wallet/dapp-client/src/ChainSessionManager.ts @@ -878,6 +878,54 @@ export class ChainSessionManager { } } + /** + * Checks whether the given transactions would be sponsored by an active + * relayer policy on this chain. + * + * Returns `true` only when the relayer's `/FeeOptions` endpoint explicitly + * reports sponsorship. A failed quote, network error, or absence of + * sponsorship all return `false`, so a `true` result is always safe to + * surface as "free gas" in UI. + */ + async isSponsored(calls: Transaction[]): Promise { + const callsToSend = calls.map((tx) => ({ + to: tx.to, + value: tx.value, + data: tx.data, + gasLimit: tx.gasLimit ?? BigInt(0), + delegateCall: tx.delegateCall ?? false, + onlyFallback: tx.onlyFallback ?? false, + behaviorOnError: tx.behaviorOnError ?? ('revert' as const), + })) + try { + const signedCall = await this._buildAndSignCalls(callsToSend) + const fingerprint = this._fingerprintCalls(callsToSend) + if (fingerprint) { + this.lastSignedCallCache = { + fingerprint, + signedCall, + createdAtMs: Date.now(), + } + } + const walletAddress = this.walletAddress + if (!walletAddress) throw new InitializationError('Wallet is not initialized.') + const feeOptions = await this.relayer.feeOptions( + walletAddress, + this.chainId, + signedCall.to, + callsToSend, + signedCall.data, + ) + return feeOptions.sponsored === true && !feeOptions.failed + } catch (err) { + console.warn( + `isSponsored check failed for chain ${this.chainId}:`, + err instanceof Error ? err.message : String(err), + ) + return false + } + } + /** * Builds, signs, and sends a batch of transactions. * @param transactions The transactions to be sent. diff --git a/packages/wallet/dapp-client/src/DappClient.ts b/packages/wallet/dapp-client/src/DappClient.ts index e580bd9127..cc6bcba4df 100644 --- a/packages/wallet/dapp-client/src/DappClient.ts +++ b/packages/wallet/dapp-client/src/DappClient.ts @@ -806,6 +806,30 @@ export class DappClient { return await chainSessionManager.getFeeOptions(transactions) } + /** + * Checks whether the given transactions would be sponsored on `chainId`. + * + * Returns `true` only when the relayer's `/FeeOptions` endpoint explicitly + * reports sponsorship. A failed quote, network error, or absence of + * sponsorship all return `false`, so 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 also produces an empty array. + * + * @example + * if (await dappClient.isSponsored(1, transactions)) { + * // safe to show "Free gas, sponsored by app" + * } else { + * const feeOptions = await dappClient.getFeeOptions(1, transactions) + * // present feeOptions[0..n] to the user as payment choices + * } + */ + async isSponsored(chainId: number, transactions: Transaction[]): Promise { + const chainSessionManager = await this.getOrInitializeChainManager(chainId) + return await chainSessionManager.isSponsored(transactions) + } + /** * Fetches fee tokens for a chain. * @returns A promise that resolves with the fee tokens response. {@link GetFeeTokensResponse} diff --git a/packages/wallet/wdk/src/sequence/transactions.ts b/packages/wallet/wdk/src/sequence/transactions.ts index 146d669998..c5549f28d2 100644 --- a/packages/wallet/wdk/src/sequence/transactions.ts +++ b/packages/wallet/wdk/src/sequence/transactions.ts @@ -371,6 +371,8 @@ export class Transactions implements TransactionsInterface { id: uuidv7(), relayerType: relayer.type, relayerId: relayer.id, + sponsored: feeOptions.sponsored, + failed: feeOptions.failed, name, icon, } as StandardRelayerOption, @@ -383,6 +385,8 @@ export class Transactions implements TransactionsInterface { feeOption, relayerType: relayer.type, relayerId: relayer.id, + sponsored: feeOptions.sponsored, + failed: feeOptions.failed, quote: feeOptions.quote, })) }), diff --git a/packages/wallet/wdk/src/sequence/types/index.ts b/packages/wallet/wdk/src/sequence/types/index.ts index 066e8a071e..946ee9bf35 100644 --- a/packages/wallet/wdk/src/sequence/types/index.ts +++ b/packages/wallet/wdk/src/sequence/types/index.ts @@ -27,5 +27,6 @@ export type { TransactionRequest, TransactionRequested, } from './transaction-request.js' +export { isERC4337RelayerOption, isStandardRelayerOption } from './transaction-request.js' export type { Wallet } from './wallet.js' export type { Module } from './module.js' diff --git a/packages/wallet/wdk/src/sequence/types/transaction-request.ts b/packages/wallet/wdk/src/sequence/types/transaction-request.ts index 51160a0499..5511bc61bd 100644 --- a/packages/wallet/wdk/src/sequence/types/transaction-request.ts +++ b/packages/wallet/wdk/src/sequence/types/transaction-request.ts @@ -21,6 +21,8 @@ export type StandardRelayerOption = BaseRelayerOption & { kind: 'standard' feeOption?: Relayer.FeeOption quote?: Relayer.FeeQuote + sponsored?: boolean + failed?: boolean name?: string icon?: string } diff --git a/packages/wallet/wdk/test/transactions.test.ts b/packages/wallet/wdk/test/transactions.test.ts index 295d00d014..8d494347d7 100644 --- a/packages/wallet/wdk/test/transactions.test.ts +++ b/packages/wallet/wdk/test/transactions.test.ts @@ -1,5 +1,6 @@ import { afterEach, describe, expect, it } from 'vitest' import { + isStandardRelayerOption, Manager, SignerActionable, Transaction, @@ -56,6 +57,14 @@ describe('Transactions', () => { expect(tx.relayerOptions.length).toBe(1) expect(tx.relayerOptions[0]!.id).toBeDefined() + // PkRelayer/LocalRelayer never report sponsorship, so sponsored should be + // explicitly false (not undefined) and failed should remain undefined. + const firstOption = tx.relayerOptions[0]! + if (isStandardRelayerOption(firstOption)) { + expect(firstOption.sponsored).toBe(false) + expect(firstOption.failed).toBeUndefined() + } + const sigId = await manager.transactions.selectRelayer(txId!, tx.relayerOptions[0]!.id) expect(sigId).toBeDefined() @@ -169,6 +178,14 @@ describe('Transactions', () => { expect(tx.relayerOptions.length).toBe(1) expect(tx.relayerOptions[0]!.id).toBeDefined() + // PkRelayer/LocalRelayer never report sponsorship, so sponsored should be + // explicitly false (not undefined) and failed should remain undefined. + const firstOption = tx.relayerOptions[0]! + if (isStandardRelayerOption(firstOption)) { + expect(firstOption.sponsored).toBe(false) + expect(firstOption.failed).toBeUndefined() + } + const sigId = await manager.transactions.selectRelayer(txId!, tx.relayerOptions[0]!.id) expect(sigId).toBeDefined() From db978bd670bb759eb02169bdeee17a2d624e90c1 Mon Sep 17 00:00:00 2001 From: Taylan Pince Date: Fri, 29 May 2026 12:48:21 +0200 Subject: [PATCH 2/3] 3.0.11 --- .changeset/dapp-client-is-sponsored.md | 19 ----------- .changeset/relayer-sponsored-signal.md | 20 ----------- .changeset/wdk-sponsored-signal.md | 23 ------------- packages/services/api/CHANGELOG.md | 6 ++++ packages/services/api/package.json | 2 +- packages/services/builder/CHANGELOG.md | 6 ++++ packages/services/builder/package.json | 2 +- packages/services/guard/CHANGELOG.md | 6 ++++ packages/services/guard/package.json | 2 +- .../services/identity-instrument/CHANGELOG.md | 6 ++++ .../services/identity-instrument/package.json | 2 +- packages/services/indexer/CHANGELOG.md | 6 ++++ packages/services/indexer/package.json | 2 +- packages/services/marketplace/CHANGELOG.md | 6 ++++ packages/services/marketplace/package.json | 2 +- packages/services/metadata/CHANGELOG.md | 6 ++++ packages/services/metadata/package.json | 2 +- packages/services/relayer/CHANGELOG.md | 26 ++++++++++++++ packages/services/relayer/package.json | 2 +- packages/services/userdata/CHANGELOG.md | 6 ++++ packages/services/userdata/package.json | 2 +- packages/utils/abi/CHANGELOG.md | 6 ++++ packages/utils/abi/package.json | 2 +- packages/wallet/core/CHANGELOG.md | 11 ++++++ packages/wallet/core/package.json | 2 +- packages/wallet/dapp-client/CHANGELOG.md | 30 ++++++++++++++++ packages/wallet/dapp-client/package.json | 2 +- packages/wallet/primitives/CHANGELOG.md | 6 ++++ packages/wallet/primitives/package.json | 2 +- packages/wallet/wdk/CHANGELOG.md | 34 +++++++++++++++++++ packages/wallet/wdk/package.json | 2 +- 31 files changed, 175 insertions(+), 76 deletions(-) delete mode 100644 .changeset/dapp-client-is-sponsored.md delete mode 100644 .changeset/relayer-sponsored-signal.md delete mode 100644 .changeset/wdk-sponsored-signal.md diff --git a/.changeset/dapp-client-is-sponsored.md b/.changeset/dapp-client-is-sponsored.md deleted file mode 100644 index 731c28d3bd..0000000000 --- a/.changeset/dapp-client-is-sponsored.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -'@0xsequence/dapp-client': minor ---- - -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`, so 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 also produces an empty array, so the inference -can misclassify a failed quote as a real subsidy. The new method uses the -positive `sponsored: boolean` signal from `@0xsequence/relayer`'s widened -`feeOptions` return. - -`getFeeOptions` is unchanged. diff --git a/.changeset/relayer-sponsored-signal.md b/.changeset/relayer-sponsored-signal.md deleted file mode 100644 index f922932ed4..0000000000 --- a/.changeset/relayer-sponsored-signal.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -'@0xsequence/relayer': minor ---- - -Surface explicit sponsorship signal on `feeOptions` and an error marker on -`feeOptions` / `feeTokens`. - -- `RpcRelayer.feeOptions` now returns `sponsored: boolean`, forwarded from the - server's `FeeOptionsReturn.sponsored`. The `Relayer` interface and all - bundled implementations (`RpcRelayer`, `SequenceRelayer`, `LocalRelayer`, - `EIP6963Relayer`, `PkRelayer`) carry the new field. -- When `feeOptions` swallows a transport / server error it now returns - `{ options: [], sponsored: false, failed: true }` (was `{ options: [] }`). -- When `feeTokens` swallows an error it now returns - `{ isFeeRequired: false, failed: true }` (was `{ isFeeRequired: false }`). - -These changes are additive — existing consumers that ignore the new fields are -unaffected. Consumers that classified sponsorship by "no fee option attached" -should migrate to `sponsored === true` to distinguish a real subsidy from a -swallowed `/FeeOptions` error. diff --git a/.changeset/wdk-sponsored-signal.md b/.changeset/wdk-sponsored-signal.md deleted file mode 100644 index 14d94ddce8..0000000000 --- a/.changeset/wdk-sponsored-signal.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -'@0xsequence/wallet-wdk': minor ---- - -Carry `sponsored` / `failed` through `StandardRelayerOption`. - -`StandardRelayerOption` now exposes two optional fields: - -- `sponsored?: boolean` — populated from the relayer SDK's new `feeOptions` - return field. `true` means the server confirmed an active sponsorship policy - match; `false` means it did not (or the quote failed). -- `failed?: boolean` — `true` when the relayer's `feeOptions` call was swallowed - due to a transport or server error. - -Both fields are populated on the empty-options construction branch and the -per-option mapping branch in `transactions.ts`. The new `isStandardRelayerOption` -and `isERC4337RelayerOption` runtime helpers are now re-exported from the -package root for consumers that need to narrow `RelayerOption` before reading -the new fields. - -UI / wallet consumers that previously classified sponsorship by "no `feeOption` -attached" should switch to `sponsored === true` so a real subsidy is no longer -indistinguishable from a swallowed `/FeeOptions` error. diff --git a/packages/services/api/CHANGELOG.md b/packages/services/api/CHANGELOG.md index 37b4ea3326..abf1bac7ac 100644 --- a/packages/services/api/CHANGELOG.md +++ b/packages/services/api/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/api +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/api/package.json b/packages/services/api/package.json index d05f1ddbe4..f172925797 100644 --- a/packages/services/api/package.json +++ b/packages/services/api/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/api", - "version": "3.0.10", + "version": "3.0.11", "description": "api sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/api", "author": "Sequence Platforms ULC", diff --git a/packages/services/builder/CHANGELOG.md b/packages/services/builder/CHANGELOG.md index 1e76b7c904..5012884642 100644 --- a/packages/services/builder/CHANGELOG.md +++ b/packages/services/builder/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/builder +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/builder/package.json b/packages/services/builder/package.json index 56f014585a..84cf23976b 100644 --- a/packages/services/builder/package.json +++ b/packages/services/builder/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/builder", - "version": "3.0.10", + "version": "3.0.11", "description": "builder sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/builder", "author": "Sequence Platforms ULC", diff --git a/packages/services/guard/CHANGELOG.md b/packages/services/guard/CHANGELOG.md index d0d37458db..f9125f1bee 100644 --- a/packages/services/guard/CHANGELOG.md +++ b/packages/services/guard/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/guard +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/guard/package.json b/packages/services/guard/package.json index 3bc3e0f667..e4c7c1f053 100644 --- a/packages/services/guard/package.json +++ b/packages/services/guard/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/guard", - "version": "3.0.10", + "version": "3.0.11", "description": "guard sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/guard", "author": "Sequence Platforms ULC", diff --git a/packages/services/identity-instrument/CHANGELOG.md b/packages/services/identity-instrument/CHANGELOG.md index 845912fe80..7a3f203888 100644 --- a/packages/services/identity-instrument/CHANGELOG.md +++ b/packages/services/identity-instrument/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/identity-instrument +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/identity-instrument/package.json b/packages/services/identity-instrument/package.json index 7c37bbcc31..2dffdd4885 100644 --- a/packages/services/identity-instrument/package.json +++ b/packages/services/identity-instrument/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/identity-instrument", - "version": "3.0.10", + "version": "3.0.11", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/services/indexer/CHANGELOG.md b/packages/services/indexer/CHANGELOG.md index 693670b22c..34389ffed2 100644 --- a/packages/services/indexer/CHANGELOG.md +++ b/packages/services/indexer/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/indexer +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/indexer/package.json b/packages/services/indexer/package.json index 9833ffaa95..f8b17dac87 100644 --- a/packages/services/indexer/package.json +++ b/packages/services/indexer/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/indexer", - "version": "3.0.10", + "version": "3.0.11", "description": "indexer sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/indexer", "author": "Sequence Platforms ULC", diff --git a/packages/services/marketplace/CHANGELOG.md b/packages/services/marketplace/CHANGELOG.md index b99659fe6f..56b3ea4a64 100644 --- a/packages/services/marketplace/CHANGELOG.md +++ b/packages/services/marketplace/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/marketplace +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/marketplace/package.json b/packages/services/marketplace/package.json index 1ac1889a4e..23a7866f80 100644 --- a/packages/services/marketplace/package.json +++ b/packages/services/marketplace/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/marketplace", - "version": "3.0.10", + "version": "3.0.11", "description": "marketplace sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/marketplace", "author": "Sequence Platforms ULC", diff --git a/packages/services/metadata/CHANGELOG.md b/packages/services/metadata/CHANGELOG.md index c284615b66..74d47b401b 100644 --- a/packages/services/metadata/CHANGELOG.md +++ b/packages/services/metadata/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/metadata +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/metadata/package.json b/packages/services/metadata/package.json index db4ec068a1..234b7ea9c5 100644 --- a/packages/services/metadata/package.json +++ b/packages/services/metadata/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/metadata", - "version": "3.0.10", + "version": "3.0.11", "publishConfig": { "access": "public" }, diff --git a/packages/services/relayer/CHANGELOG.md b/packages/services/relayer/CHANGELOG.md index 507428d5bb..951a31f261 100644 --- a/packages/services/relayer/CHANGELOG.md +++ b/packages/services/relayer/CHANGELOG.md @@ -1,5 +1,31 @@ # @0xsequence/relayer +## 3.1.0 + +### Minor Changes + +- 55121af: Surface explicit sponsorship signal on `feeOptions` and an error marker on + `feeOptions` / `feeTokens`. + - `RpcRelayer.feeOptions` now returns `sponsored: boolean`, forwarded from the + server's `FeeOptionsReturn.sponsored`. The `Relayer` interface and all + bundled implementations (`RpcRelayer`, `SequenceRelayer`, `LocalRelayer`, + `EIP6963Relayer`, `PkRelayer`) carry the new field. + - When `feeOptions` swallows a transport / server error it now returns + `{ options: [], sponsored: false, failed: true }` (was `{ options: [] }`). + - When `feeTokens` swallows an error it now returns + `{ isFeeRequired: false, failed: true }` (was `{ isFeeRequired: false }`). + + These changes are additive — existing consumers that ignore the new fields are + unaffected. Consumers that classified sponsorship by "no fee option attached" + should migrate to `sponsored === true` to distinguish a real subsidy from a + swallowed `/FeeOptions` error. + +### Patch Changes + +- Fix for relayer sponsored fees +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.11 + ## 3.0.10 ### Patch Changes diff --git a/packages/services/relayer/package.json b/packages/services/relayer/package.json index ec2a8dcd9b..284ceae37e 100644 --- a/packages/services/relayer/package.json +++ b/packages/services/relayer/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/relayer", - "version": "3.0.10", + "version": "3.1.0", "type": "module", "publishConfig": { "access": "public" diff --git a/packages/services/userdata/CHANGELOG.md b/packages/services/userdata/CHANGELOG.md index 139297551a..ebf00e9ebe 100644 --- a/packages/services/userdata/CHANGELOG.md +++ b/packages/services/userdata/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/userdata +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/services/userdata/package.json b/packages/services/userdata/package.json index e546d8f223..0483c76a3d 100644 --- a/packages/services/userdata/package.json +++ b/packages/services/userdata/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/userdata", - "version": "3.0.10", + "version": "3.0.11", "description": "userdata sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/userdata", "author": "Sequence Platforms ULC", diff --git a/packages/utils/abi/CHANGELOG.md b/packages/utils/abi/CHANGELOG.md index 66866e4e33..fca1d35a4c 100644 --- a/packages/utils/abi/CHANGELOG.md +++ b/packages/utils/abi/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/abi +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/utils/abi/package.json b/packages/utils/abi/package.json index 34b211947d..6b6023abd8 100644 --- a/packages/utils/abi/package.json +++ b/packages/utils/abi/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/abi", - "version": "3.0.10", + "version": "3.0.11", "description": "abi sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/utils/abi", "author": "Sequence Platforms ULC", diff --git a/packages/wallet/core/CHANGELOG.md b/packages/wallet/core/CHANGELOG.md index 03d06db617..8c79704d74 100644 --- a/packages/wallet/core/CHANGELOG.md +++ b/packages/wallet/core/CHANGELOG.md @@ -1,5 +1,16 @@ # @0xsequence/wallet-core +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees +- Updated dependencies +- Updated dependencies [55121af] + - @0xsequence/guard@3.0.11 + - @0xsequence/relayer@3.1.0 + - @0xsequence/wallet-primitives@3.0.11 + ## 3.0.10 ### Patch Changes diff --git a/packages/wallet/core/package.json b/packages/wallet/core/package.json index 95457a5787..0c9ca7535b 100644 --- a/packages/wallet/core/package.json +++ b/packages/wallet/core/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-core", - "version": "3.0.10", + "version": "3.0.11", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/dapp-client/CHANGELOG.md b/packages/wallet/dapp-client/CHANGELOG.md index 492c1ec2e4..03750f575e 100644 --- a/packages/wallet/dapp-client/CHANGELOG.md +++ b/packages/wallet/dapp-client/CHANGELOG.md @@ -1,5 +1,35 @@ # @0xsequence/dapp-client +## 3.1.0 + +### Minor Changes + +- 55121af: 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`, so 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 also produces an empty array, so the inference + can misclassify a failed quote as a real subsidy. The new method uses the + positive `sponsored: boolean` signal from `@0xsequence/relayer`'s widened + `feeOptions` return. + + `getFeeOptions` is unchanged. + +### Patch Changes + +- Fix for relayer sponsored fees +- Updated dependencies +- Updated dependencies [55121af] + - @0xsequence/guard@3.0.11 + - @0xsequence/relayer@3.1.0 + - @0xsequence/wallet-core@3.0.11 + - @0xsequence/wallet-primitives@3.0.11 + ## 3.0.10 ### Patch Changes diff --git a/packages/wallet/dapp-client/package.json b/packages/wallet/dapp-client/package.json index 74b4beeabf..6d42b0a89e 100644 --- a/packages/wallet/dapp-client/package.json +++ b/packages/wallet/dapp-client/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/dapp-client", - "version": "3.0.10", + "version": "3.1.0", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/primitives/CHANGELOG.md b/packages/wallet/primitives/CHANGELOG.md index b2f04d8d59..c3ffa3d195 100644 --- a/packages/wallet/primitives/CHANGELOG.md +++ b/packages/wallet/primitives/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/wallet-primitives +## 3.0.11 + +### Patch Changes + +- Fix for relayer sponsored fees + ## 3.0.10 ### Patch Changes diff --git a/packages/wallet/primitives/package.json b/packages/wallet/primitives/package.json index a34f382e68..4bd610f9ed 100644 --- a/packages/wallet/primitives/package.json +++ b/packages/wallet/primitives/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-primitives", - "version": "3.0.10", + "version": "3.0.11", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/wdk/CHANGELOG.md b/packages/wallet/wdk/CHANGELOG.md index 47bc13af2c..8913970049 100644 --- a/packages/wallet/wdk/CHANGELOG.md +++ b/packages/wallet/wdk/CHANGELOG.md @@ -1,5 +1,39 @@ # @0xsequence/wallet-wdk +## 3.1.0 + +### Minor Changes + +- 55121af: Carry `sponsored` / `failed` through `StandardRelayerOption`. + + `StandardRelayerOption` now exposes two optional fields: + - `sponsored?: boolean` — populated from the relayer SDK's new `feeOptions` + return field. `true` means the server confirmed an active sponsorship policy + match; `false` means it did not (or the quote failed). + - `failed?: boolean` — `true` when the relayer's `feeOptions` call was swallowed + due to a transport or server error. + + Both fields are populated on the empty-options construction branch and the + per-option mapping branch in `transactions.ts`. The new `isStandardRelayerOption` + and `isERC4337RelayerOption` runtime helpers are now re-exported from the + package root for consumers that need to narrow `RelayerOption` before reading + the new fields. + + UI / wallet consumers that previously classified sponsorship by "no `feeOption` + attached" should switch to `sponsored === true` so a real subsidy is no longer + indistinguishable from a swallowed `/FeeOptions` error. + +### Patch Changes + +- Fix for relayer sponsored fees +- Updated dependencies +- Updated dependencies [55121af] + - @0xsequence/guard@3.0.11 + - @0xsequence/identity-instrument@3.0.11 + - @0xsequence/relayer@3.1.0 + - @0xsequence/wallet-core@3.0.11 + - @0xsequence/wallet-primitives@3.0.11 + ## 3.0.10 ### Patch Changes diff --git a/packages/wallet/wdk/package.json b/packages/wallet/wdk/package.json index 65a237c553..12e5d6dd83 100644 --- a/packages/wallet/wdk/package.json +++ b/packages/wallet/wdk/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-wdk", - "version": "3.0.10", + "version": "3.1.0", "license": "Apache-2.0", "type": "module", "publishConfig": { From fce05da60d54804b55b2dc7aeac8291ad4d7465e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 13:03:56 +0200 Subject: [PATCH 3/3] Bump turbo from 2.9.8 to 2.9.14 (#1008) 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](https://github.com/vercel/turborepo/compare/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] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 125 +++++++++++++------------------------------------ 2 files changed, 33 insertions(+), 94 deletions(-) diff --git a/package.json b/package.json index 38bc33117e..af9b64c380 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "prettier": "^3.8.3", "rimraf": "^6.1.3", "syncpack": "^14.3.1", - "turbo": "^2.9.8", + "turbo": "^2.9.14", "typescript": "^6.0.3" }, "pnpm": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a369a88a6..406d256af6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,8 +27,8 @@ importers: specifier: ^14.3.1 version: 14.3.1 turbo: - specifier: ^2.9.8 - version: 2.9.8 + specifier: ^2.9.14 + version: 2.9.14 typescript: specifier: ^6.0.3 version: 6.0.3 @@ -530,7 +530,7 @@ importers: version: 7.0.1(eslint@9.39.2) eslint-plugin-turbo: specifier: ^2.6.3 - version: 2.6.3(eslint@9.39.2)(turbo@2.9.9) + version: 2.6.3(eslint@9.39.2)(turbo@2.9.14) globals: specifier: ^16.5.0 version: 16.5.0 @@ -1357,23 +1357,13 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@turbo/darwin-64@2.9.8': - resolution: {integrity: sha512-zU1P95ygDpsQ+2QHh7CVTqvYwi9UBlhKWzoIyUnP3vUoge7H9SQEzrd8dj+XcTrslAp9Db3vIBcXtMVoTEYDnA==} + '@turbo/darwin-64@2.9.14': + resolution: {integrity: sha512-t7QiPflaEyBE4oayeZtSmu4mEfjgIrcNlNNl1z1dmIVPqEdtA7+CfTf8d7KXsOGPh6aNgWjKxyvQg9uGfDQF+A==} cpu: [x64] os: [darwin] - '@turbo/darwin-64@2.9.9': - resolution: {integrity: sha512-hTEiNu2ABZZOO1qbjnKASI8eF3BdOOzU6iKv5w5uGOK65DDMc10cS40N1kqM99YT0uSAGUwNu6GdFctRPeEeVA==} - cpu: [x64] - os: [darwin] - - '@turbo/darwin-arm64@2.9.8': - resolution: {integrity: sha512-nKRFI5ZhCGUi4eXNlrojzWcT/CehMj0raot1WE4lw5qf66ZxZHbRbBqcwNEy+ZLY7RkJJRY+TaU89fuj3BcgGg==} - cpu: [arm64] - os: [darwin] - - '@turbo/darwin-arm64@2.9.9': - resolution: {integrity: sha512-MinO40EEcP5mJiTVpfjtEulsEBhVeryfq21QhYtJZ8hQJLHGgy459rcmDVAY8/JERe4dkVU4KW+zoLF22o01EA==} + '@turbo/darwin-arm64@2.9.14': + resolution: {integrity: sha512-d23147mC9BsCPA9mJ0h/ubcpbRgcJBXbcG3+Vq7YLhjz3IXuvQsJ1UXH8f4MD76ZjJ4m/E4aRdJV+MW88CDfbw==} cpu: [arm64] os: [darwin] @@ -1381,43 +1371,23 @@ packages: resolution: {integrity: sha512-PK38N1fHhDUyjLi0mUjv0RbX0xXGwDLQeRSGsIlLcVpP1B5fwodSIwIYXc9vJok26Yne94BX5AGjueYsUT3uUw==} hasBin: true - '@turbo/linux-64@2.9.8': - resolution: {integrity: sha512-Wf/kQpVDCaWM3P5d6lKvJnqjYn/ofUBGbT4h4vRFrdC4N6B/nsun03S2kQNJJMXpXg39woeS4CI367RMU3/OAg==} - cpu: [x64] - os: [linux] - - '@turbo/linux-64@2.9.9': - resolution: {integrity: sha512-7JNLw88Isk+gMlbsC8pulLDkrqe2B827ZsKFEHilb17AC6Xn/62pzH7afjY7fEU6Ayp4XP/vGhlRWOzqBvBvIQ==} + '@turbo/linux-64@2.9.14': + resolution: {integrity: sha512-P3ZKB5tuUDdDQWuAsACGUR1qv9W7BNWxdxqVJ0kZNuNNPRaVYTPPikLcp79+GiEcW3npsR+KyP38lnQiBc5aSA==} cpu: [x64] os: [linux] - '@turbo/linux-arm64@2.9.8': - resolution: {integrity: sha512-v6S3HuKVoa9CEx16IxKj1i/+crxXx22A9O80zW1350zyUlcX0T/zLOxVf1k+ruK/7ssXnDJVg8uSYOxlYRedlA==} + '@turbo/linux-arm64@2.9.14': + resolution: {integrity: sha512-ZRTlzcUMrrPv9ZuDzRF9n60Ym13bKeG9jDB8WjxyLhWNzV+AJQN+zdpIk3NJYf2zQsGUm1mNar2P0elRzLw25g==} cpu: [arm64] os: [linux] - '@turbo/linux-arm64@2.9.9': - resolution: {integrity: sha512-0pnXDwPw1rHii98JZPRg7SvsjIzy7jrhkwGU9Jy5fVYoMdYd3P2vbtLfII+OJ0Mm4Ar5yykdHDTz3RWiRI1o9g==} - cpu: [arm64] - os: [linux] - - '@turbo/windows-64@2.9.8': - resolution: {integrity: sha512-JaefWOJNBazDylAn3f+lLB34XMNu8nEBbgPRP/Ewysg81cBubGfcyyyzpQOGVuMwfaqdNAE/kitG7w3AbJn9/g==} - cpu: [x64] - os: [win32] - - '@turbo/windows-64@2.9.9': - resolution: {integrity: sha512-vjDQycz4gQVvIq4n2rPtiiIESwJlAc406qtkiZlqyL+fHZEd9SxYNlBIFYtc5cuMuwrk+sIKrhN7XvwjmvS9YQ==} + '@turbo/windows-64@2.9.14': + resolution: {integrity: sha512-exanwN6sIduZwykYeiTQj8kCmOhazP5WOz3bvXMcYtjhL6Z3iRWLewKrXCBq0bqwSP3iBMb/AerRCnHI4lx46A==} cpu: [x64] os: [win32] - '@turbo/windows-arm64@2.9.8': - resolution: {integrity: sha512-Or6ljjB4TiiwCdVKDYWew0SokQ9kep5zruL8P3nbum9WdkH5XA41rQID4Ulc215Z+R3DrB+qXSHPsJjU3/n2ng==} - cpu: [arm64] - os: [win32] - - '@turbo/windows-arm64@2.9.9': - resolution: {integrity: sha512-V6NiH43oCctepbOdQFp7UjqLyK8p6Tt824QA+G4TE+B1BBHu80A0W8OCL+H7uBJ3XZjAj/hvPDw3k3l65DoDGw==} + '@turbo/windows-arm64@2.9.14': + resolution: {integrity: sha512-fVdCsnmYoKICsycbWuuGp6Jvi51/3G/UluFWuAUCvR8PIW5IJkAk5BM9UF8PSm0Q2IphWHFZjYEgjHsh3B9y/g==} cpu: [arm64] os: [win32] @@ -3611,12 +3581,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - turbo@2.9.8: - resolution: {integrity: sha512-REEB2rVTVDTf4hav1gJ5dIsGylWZrNonvjXFtk1dCi8gND3PhZtnYkyry1bra/Fo+iP6ctTEZbg6vWfdfHq/1A==} - hasBin: true - - turbo@2.9.9: - resolution: {integrity: sha512-3xfzXE/yTjhh0S5dIWlE+3E+J9A09REpLI1ZqVh2+HrNZoVzZn0pkvjiRgVK/Ev3PF9XnaTwCntTx+CADWXcyA==} + turbo@2.9.14: + resolution: {integrity: sha512-BQqXRr4UoWI3UPFrtznCLykYHxwxWh53iCB57x092jPMjIlW1wnm3N895g5irpiXmnxUhREBB0n6+y8BHhs4nw==} hasBin: true type-check@0.4.0: @@ -4607,16 +4573,10 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@turbo/darwin-64@2.9.8': - optional: true - - '@turbo/darwin-64@2.9.9': - optional: true - - '@turbo/darwin-arm64@2.9.8': + '@turbo/darwin-64@2.9.14': optional: true - '@turbo/darwin-arm64@2.9.9': + '@turbo/darwin-arm64@2.9.14': optional: true '@turbo/gen@1.13.4(@types/node@25.3.0)(typescript@6.0.3)': @@ -4639,28 +4599,16 @@ snapshots: - supports-color - typescript - '@turbo/linux-64@2.9.8': - optional: true - - '@turbo/linux-64@2.9.9': - optional: true - - '@turbo/linux-arm64@2.9.8': - optional: true - - '@turbo/linux-arm64@2.9.9': - optional: true - - '@turbo/windows-64@2.9.8': + '@turbo/linux-64@2.9.14': optional: true - '@turbo/windows-64@2.9.9': + '@turbo/linux-arm64@2.9.14': optional: true - '@turbo/windows-arm64@2.9.8': + '@turbo/windows-64@2.9.14': optional: true - '@turbo/windows-arm64@2.9.9': + '@turbo/windows-arm64@2.9.14': optional: true '@turbo/workspaces@1.13.4(@types/node@25.3.0)': @@ -5530,11 +5478,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.6.3(eslint@9.39.2)(turbo@2.9.9): + eslint-plugin-turbo@2.6.3(eslint@9.39.2)(turbo@2.9.14): dependencies: dotenv: 16.0.3 eslint: 9.39.2 - turbo: 2.9.9 + turbo: 2.9.14 eslint-scope@8.4.0: dependencies: @@ -7206,23 +7154,14 @@ snapshots: tslib@2.8.1: {} - turbo@2.9.8: - optionalDependencies: - '@turbo/darwin-64': 2.9.8 - '@turbo/darwin-arm64': 2.9.8 - '@turbo/linux-64': 2.9.8 - '@turbo/linux-arm64': 2.9.8 - '@turbo/windows-64': 2.9.8 - '@turbo/windows-arm64': 2.9.8 - - turbo@2.9.9: + turbo@2.9.14: optionalDependencies: - '@turbo/darwin-64': 2.9.9 - '@turbo/darwin-arm64': 2.9.9 - '@turbo/linux-64': 2.9.9 - '@turbo/linux-arm64': 2.9.9 - '@turbo/windows-64': 2.9.9 - '@turbo/windows-arm64': 2.9.9 + '@turbo/darwin-64': 2.9.14 + '@turbo/darwin-arm64': 2.9.14 + '@turbo/linux-64': 2.9.14 + '@turbo/linux-arm64': 2.9.14 + '@turbo/windows-64': 2.9.14 + '@turbo/windows-arm64': 2.9.14 type-check@0.4.0: dependencies: