Enable JupiterZ RFQ routing in JupiterSwapService #66

Open
opened 2026-08-10 13:47:52 +02:00 by minimons · 0 comments
Owner

Background

Issue #51 adds JupiterSwapService using Jupiter Swap V2.

The first implementation deliberately excludes the jupiterz router by sending:

excludeRouters=jupiterz

JupiterZ uses RFQ orders, which differ from ordinary aggregator routes in two important ways:

  • JupiterZ orders expire through expireAt instead of lastValidBlockHeight.
  • The transaction requires an additional market-maker signature, which Jupiter adds during /execute. The wallet must therefore partially sign the transaction without requiring every signature slot to be populated.

Excluding JupiterZ allows #51 to be implemented without introducing these additional transaction-signing requirements. However, JupiterZ may provide a better price than the aggregator routers, so it should be enabled in a separate follow-up.

Jupiter describes the RFQ signing and expiration flow here:

https://developers.jup.ag/docs/swap/order-and-execute

Dependency

This issue depends on #51.

The normal aggregator-based swap flow from #51 must remain functional.

Requirements

Enable JupiterZ routing

Remove the unconditional:

excludeRouters=jupiterz

parameter from Jupiter /order requests.

After this change, Jupiter must be allowed to select any supported router, including jupiterz.

The public JupiterSwapService API must remain unchanged.

Router-aware order validation

The order response must retain and validate the router selected by Jupiter.

For ordinary aggregator routers such as Metis, Dflow and OKX:

  • lastValidBlockHeight must be handled as the transaction expiration.
  • Missing or invalid block-height information must cause the order to be rejected before signing.

For the jupiterz router:

  • expireAt must be handled as the RFQ quote expiration.
  • A missing, malformed or already expired expireAt value must cause the order to be rejected before signing.
  • The transaction must be signed and submitted to /execute immediately after the order has been received.

Unknown router types must fail clearly rather than silently being treated as an aggregator route.

Partial transaction signing

Verify and, if necessary, extend the Solana wallet signing implementation so it can partially sign a versioned transaction.

Partial signing must:

  • Add the wallet’s signature to the correct required-signer position.
  • Preserve any signatures already present in the transaction.
  • Preserve unfilled signature positions required by other signers.
  • Not require the transaction to be fully signed after the wallet has signed it.
  • Return a serialized transaction that Jupiter can complete during /execute.

The partial-signing behavior belongs in the general Solana wallet or transaction-signing layer. Jupiter-specific signing logic must not be added to the wallet.

Existing fully signable transactions used by Jupiter Perps and ordinary Solana operations must continue to work unchanged.

Execute JupiterZ orders

The partially signed transaction and its requestId must be submitted through the existing Jupiter /execute flow.

For a JupiterZ order:

  • Do not require lastValidBlockHeight.
  • Allow Jupiter to add the market-maker signature during /execute.
  • Validate the returned execution status and transaction signature in the same way as other swaps.
  • Continue returning the normal JupiterSwapResult.

Error handling

Handle JupiterZ/RFQ execution failures clearly, including:

  • RFQ failed to land.
  • Unknown RFQ failure.
  • Invalid RFQ payload.
  • Expired quote.
  • Swap rejected by the market maker.

An /execute timeout or lost response must still be treated as an unknown execution result.

The service must never automatically repeat the swap. The caller must reload wallet balances before deciding whether another swap should be attempted.

Tests

Add tests covering at least:

  • A JupiterZ /order response containing expireAt.
  • Rejection of a missing, malformed or expired expireAt.
  • Partial signing where the wallet signature is added while the market-maker signature remains unfilled.
  • Preservation of signatures already present in the transaction.
  • Submission of the partially signed transaction to /execute.
  • Successful JupiterZ execution and construction of JupiterSwapResult.
  • JupiterZ-specific /order and /execute failures.
  • Continued support for aggregator orders using lastValidBlockHeight.
  • Continued support for transactions that only require the wallet’s signature.
  • Verification that /order no longer excludes jupiterz.

Acceptance criteria

  • JupiterZ is no longer excluded from Jupiter /order requests.
  • JupiterSwapService accepts both aggregator and JupiterZ orders.
  • Aggregator orders use lastValidBlockHeight.
  • JupiterZ orders use expireAt.
  • The wallet can add its signature without destroying or requiring other signatures.
  • Jupiter can add the market-maker signature during /execute.
  • The public JupiterSwapService API remains unchanged.
  • JupiterZ-specific failures produce clear exceptions.
  • No submitted swap is automatically retried.
  • Existing Jupiter Swap, Jupiter Perps and Solana wallet behavior remains functional.
  • All existing and new tests pass.

Out of scope

  • Calling JupiterZ directly without Jupiter Swap V2.
  • Selecting JupiterZ explicitly for individual swaps.
  • Changing the public JupiterSwapService API.
  • Automatic swap retries.
  • API-key configuration.
  • Changes to EvelynBurnerService.
## Background Issue #51 adds `JupiterSwapService` using Jupiter Swap V2. The first implementation deliberately excludes the `jupiterz` router by sending: ```text excludeRouters=jupiterz ``` JupiterZ uses RFQ orders, which differ from ordinary aggregator routes in two important ways: * JupiterZ orders expire through `expireAt` instead of `lastValidBlockHeight`. * The transaction requires an additional market-maker signature, which Jupiter adds during `/execute`. The wallet must therefore partially sign the transaction without requiring every signature slot to be populated. Excluding JupiterZ allows #51 to be implemented without introducing these additional transaction-signing requirements. However, JupiterZ may provide a better price than the aggregator routers, so it should be enabled in a separate follow-up. Jupiter describes the RFQ signing and expiration flow here: https://developers.jup.ag/docs/swap/order-and-execute ## Dependency This issue depends on #51. The normal aggregator-based swap flow from #51 must remain functional. ## Requirements ### Enable JupiterZ routing Remove the unconditional: ```text excludeRouters=jupiterz ``` parameter from Jupiter `/order` requests. After this change, Jupiter must be allowed to select any supported router, including `jupiterz`. The public `JupiterSwapService` API must remain unchanged. ### Router-aware order validation The order response must retain and validate the router selected by Jupiter. For ordinary aggregator routers such as Metis, Dflow and OKX: * `lastValidBlockHeight` must be handled as the transaction expiration. * Missing or invalid block-height information must cause the order to be rejected before signing. For the `jupiterz` router: * `expireAt` must be handled as the RFQ quote expiration. * A missing, malformed or already expired `expireAt` value must cause the order to be rejected before signing. * The transaction must be signed and submitted to `/execute` immediately after the order has been received. Unknown router types must fail clearly rather than silently being treated as an aggregator route. ### Partial transaction signing Verify and, if necessary, extend the Solana wallet signing implementation so it can partially sign a versioned transaction. Partial signing must: * Add the wallet’s signature to the correct required-signer position. * Preserve any signatures already present in the transaction. * Preserve unfilled signature positions required by other signers. * Not require the transaction to be fully signed after the wallet has signed it. * Return a serialized transaction that Jupiter can complete during `/execute`. The partial-signing behavior belongs in the general Solana wallet or transaction-signing layer. Jupiter-specific signing logic must not be added to the wallet. Existing fully signable transactions used by Jupiter Perps and ordinary Solana operations must continue to work unchanged. ### Execute JupiterZ orders The partially signed transaction and its `requestId` must be submitted through the existing Jupiter `/execute` flow. For a JupiterZ order: * Do not require `lastValidBlockHeight`. * Allow Jupiter to add the market-maker signature during `/execute`. * Validate the returned execution status and transaction signature in the same way as other swaps. * Continue returning the normal `JupiterSwapResult`. ### Error handling Handle JupiterZ/RFQ execution failures clearly, including: * RFQ failed to land. * Unknown RFQ failure. * Invalid RFQ payload. * Expired quote. * Swap rejected by the market maker. An `/execute` timeout or lost response must still be treated as an unknown execution result. The service must never automatically repeat the swap. The caller must reload wallet balances before deciding whether another swap should be attempted. ## Tests Add tests covering at least: * A JupiterZ `/order` response containing `expireAt`. * Rejection of a missing, malformed or expired `expireAt`. * Partial signing where the wallet signature is added while the market-maker signature remains unfilled. * Preservation of signatures already present in the transaction. * Submission of the partially signed transaction to `/execute`. * Successful JupiterZ execution and construction of `JupiterSwapResult`. * JupiterZ-specific `/order` and `/execute` failures. * Continued support for aggregator orders using `lastValidBlockHeight`. * Continued support for transactions that only require the wallet’s signature. * Verification that `/order` no longer excludes `jupiterz`. ## Acceptance criteria * JupiterZ is no longer excluded from Jupiter `/order` requests. * `JupiterSwapService` accepts both aggregator and JupiterZ orders. * Aggregator orders use `lastValidBlockHeight`. * JupiterZ orders use `expireAt`. * The wallet can add its signature without destroying or requiring other signatures. * Jupiter can add the market-maker signature during `/execute`. * The public `JupiterSwapService` API remains unchanged. * JupiterZ-specific failures produce clear exceptions. * No submitted swap is automatically retried. * Existing Jupiter Swap, Jupiter Perps and Solana wallet behavior remains functional. * All existing and new tests pass. ## Out of scope * Calling JupiterZ directly without Jupiter Swap V2. * Selecting JupiterZ explicitly for individual swaps. * Changing the public `JupiterSwapService` API. * Automatic swap retries. * API-key configuration. * Changes to `EvelynBurnerService`.
minimons added the enhancement label 2026-08-10 13:47:52 +02:00
minimons self-assigned this 2026-08-10 13:47:52 +02:00
minimons added this to the AssetAZ project 2026-08-10 13:47:52 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: r35157/com_r35157_nenjim-hubd-impl_ref#66