Skip to content

fix(sdk): accept null for optional fields in swapApprovalResponseSchema#269

Merged
dohaki merged 4 commits into
masterfrom
droplet/T90K0AL22-C03HV8CFL80-1781066625-619939
Jun 10, 2026
Merged

fix(sdk): accept null for optional fields in swapApprovalResponseSchema#269
dohaki merged 4 commits into
masterfrom
droplet/T90K0AL22-C03HV8CFL80-1781066625-619939

Conversation

@droplet-rl

Copy link
Copy Markdown
Contributor

Summary

  • swapApprovalResponseSchema rejects valid /swap/approval responses on every bridgeable-to-bridgeable route — Zod's .optional() accepts undefined but not null, and the API now serializes approvalTxns, steps.originSwap, steps.destinationSwap, and swapTx as explicit null when they don't apply.
  • Switch the four affected fields to .nullish(). Consumers (executeSwapQuote) already coerce via truthiness, so runtime behavior is unchanged.

Context

Reported by Fun (Connor McEwen) in #fun on 2026-06-10. getSwapQuote throws Invalid swap approval response. Error: ... on quotes like Arbitrum USDC → Optimism USDC (no swap legs). Verified against live app.across.to/api/swap/approval:

crossSwapType: bridgeableToBridgeable
approvalTxns: null
steps.originSwap: null
steps.destinationSwap: null

Root cause on the server side: across-protocol/quote-api#2645 ("epic: hyperliquid withdrawals") flipped these fields from undefined to null in api/swap/_utils.ts:buildBaseSwapResponseJson. A surgical revert of those four lines is being pursued in quote-api; this SDK patch is the integrator-side defense so future server changes that null vs. omit don't break clients again.

Test plan

  • pnpm build (tsc) — clean
  • pnpm lint — only pre-existing warning unrelated to this change
  • Schema sanity-check against Connor's exact payload (null for the four fields) — swapApprovalResponseSchema.safeParse returns success: true
  • Reviewer to confirm consumer code paths (executeSwapQuote) still treat null the same as undefined (they do — if (!swapQuote.swapTx) and if (swapQuote.approvalTxns && ...))

🤖 Generated with Claude Code

`/swap/approval` now serializes `approvalTxns`, `steps.originSwap`,
`steps.destinationSwap`, and `swapTx` as explicit `null` (rather than
omitting them) for cases where they don't apply — e.g. bridgeable-to-
bridgeable routes return `null` for the swap legs. Zod's `.optional()`
accepts `undefined` but rejects `null`, so `getSwapQuote` was throwing
`Invalid swap approval response` on every same-token bridge quote.

Switch the four affected fields to `.nullish()`. Downstream consumers
(`executeSwapQuote`) already coerce these via truthiness checks, so
runtime behavior is unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 21c3029

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@across-protocol/app-sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
toolkit-example Ready Ready Preview, Comment Jun 10, 2026 5:06am

Request Review

@pxrl

pxrl commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Remember to bump the patch version of the package.

dohaki
dohaki previously approved these changes Jun 10, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@droplet-rl

Copy link
Copy Markdown
Contributor Author

Bumped @across-protocol/app-sdk from 0.6.00.6.1 in packages/sdk/package.json and committed. The changeset (patch) is already in place.

@dohaki

dohaki commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

@droplet-rl no need to bump the package version. it will be bumped by the changeset PR. also fix the failing test. Scroll is not supported by us anymore

droplet-rl and others added 2 commits June 10, 2026 05:04
Scroll is no longer a supported chain. Caused
"Could not find chainInfo for chain with id 534352" failures in
client.test.ts.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@droplet-rl

Copy link
Copy Markdown
Contributor Author

Done. Reverted the version bump (will let the changeset PR handle it) and dropped Scroll from MAINNET_SUPPORTED_CHAINS in packages/sdk/test/common/sdk.ts — that was the source of the Could not find chainInfo for chain with id 534352 failures in client.test.ts.

@dohaki dohaki self-requested a review June 10, 2026 05:06
@dohaki dohaki merged commit 0509ad3 into master Jun 10, 2026
3 checks passed
@dohaki dohaki deleted the droplet/T90K0AL22-C03HV8CFL80-1781066625-619939 branch June 10, 2026 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants