Skip to content

feat: rfq integration doc #641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 16, 2025
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_label: "DEX Integration"
sidebar_label: "Decentalized Exchanges"
description: "Integrate your DEX into Jupiter."
title: "DEX Integration"
---
Expand All @@ -9,8 +9,6 @@ title: "DEX Integration"
<meta name="twitter:card" content="summary" />
</head>

## Overview

Jupiter is one of the most widely integrated protocols, so a lot of work is involved in minimizing issues on new integrations and making each integration valuable to our users and partners.

Our top priority is securing the best prices and the best token selection for our users, so we will focus on DEXes that will bring the most benefits to them.
Expand Down
38 changes: 38 additions & 0 deletions docs/600-routing/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
sidebar_label: "About Routing"
description: "About Jupiter Routing"
title: "About Routing"
---

<head>
<title>About Routing</title>
<meta name="twitter:card" content="summary" />
</head>

Jupiter products utilizes the Swap infrastructure which is built on top of a robust and complex routing system that aggregates liquidity from multiple sources such as decentralized exchanges (DEXes) and market makers.

:::note
If you are an exchange or market maker and want to participate in Jupiter routing, please refer to our [DEX Integration](/docs/routing/dex-integration) and [RFQ Integration](/docs/routing/rfq-integration) guides.
:::

## DEX Routing

Jupiter's DEX routing system integrates with most AMMs and decentralized exchanges on Solana, accessible through our Swap API. You can find a complete list of supported AMMs and DEXes via the [/swap/v1/program-id-to-label](https://lite-api.jup.ag/swap/v1/program-id-to-label) endpoint.

Our routing infrastructure consists of several key components:

- A routing engine that finds the optimal price across all integrated venues
- A market indexer that automatically detects and integrates most new markets (with a 14-day grace period before the crawler takes over)
- A market crawler that runs periodically to categorize markets based on their liquidity

## Jupiter Z (RFQ) Routing

Jupiter Z is our Request for Quote (RFQ) system, it is intent based where the user express their desired price (intents) and market makers provide quotes to fulfill those intents.

Our RFQ system consists of:

- An order engine for RFQ processing
- To include RFQ into our routing, we utilize a quote proxy that compares quotes between market makers and DEX routing to ensure best quotes
- RFQ is accessible via the Ultra API

For more information about Jupiter Z, please refer to our [RFQ Integration](/docs/routing/rfq-integration) guide.
184 changes: 184 additions & 0 deletions docs/600-routing/rfq-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
sidebar_label: "Jupiter Z (RFQ)"
description: "Integrate your DEX into Jupiter."
title: "RFQ Integration"
---

<head>
<title>RFQ Integration</title>
<meta name="twitter:card" content="summary" />
</head>

This section will cover the integration of your RFQ service into Jupiter's routing system.

:::caution
The integration requirements are subjected to change and please provide suggestions or feedbacks on ways to improve the integration process.
:::

<img src="/dev/rfq-flow.png" alt="RFQ Flow" width="700" />

## Integration Prerequisites

- Host a service that adheres to our RFQ API schema
- Provide a webhook for Jupiter to send quotes and swap transactions
- Complete end-to-end integration tests
- When ready, you will be onboarded to Edge before going live on production

:::note
[Please reach out to us in Discord](https://discord.gg/jup)
- If you are interested to participate in Jupiter Z
- If you need any help or clarification regarding the integration.
- To begin onboarding to Edge.
:::

### Example Integration

To facilitate the integration, we provide an [integration SDK in this repository](https://github.com/jup-ag/rfq-webhook-toolkit).

- [**Sample server**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/server-example/): Implements the webhook API in Rust.
- [**API Schema**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/openapi): OpenAPI schema for the RFQ API.
- [**Integration tests**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/tests/): Verify the implementation of the webhook.
- [**Troubleshooting**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/tests/README.md#troubleshooting): Common issues that arise during integration.

---

### RFQ API Schema

To facilitate the integration into Jupiter's RFQ module, you will need to provide a webhook for us to register the quotation and swap endpoints with the corresponding request and response format.

| Endpoint | Method | URL | Description |
|----------|--------|-----|-------------|
| Base URL | - | `https://your-api-endpoint.com/jupiter/rfq` | Example URL that we will register into our API |
| Quote | POST | `https://your-api-endpoint.com/jupiter/rfq/quote` | Called to request quotes |
| Swap | POST | `https://your-api-endpoint.com/jupiter/rfq/swap` | Called to execute swaps |
| Tokens | GET | `https://your-api-endpoint.com/jupiter/rfq/tokens` | Called periodically to fetch supported tokens (see [below](#advertising-supported-tokens)) |

:::note API Key
If you require an API key to access your endpoints, please provide it to us during the registration process. The API Key will be passed to the webhook as a header `X-API-KEY`.
:::

---

### Response Codes

Market Makers should return appropriate HTTP status codes along with error messages.

| Status Code | Description |
|--------------|-------------|
| `200 OK` | The request was successful, and the webhook will return a quote |
| `404 Not Found` | The webhook will not return a quote for this request (e.g. the pair or the size are not supported) |
| `400 Bad Request` | The request sent to the webhook is malformed (e.g. missing an expected parameter) |
| `401 Unauthorized` | Authorization failed. For example the `X-API-KEY` is missing or incorrect |
| `50x Server Errors` | The webhook is offline or unable to respond. If the status persist, the webhook will be temporarily suspended and will not receive requests |

:::note Timeouts
A webhook must adhere to the [fullfillment and response time requirements](#fulfillment-requirements). When sending the quote request, the RFQ system includes the following headers:

| Header | Description |
|--------|-------------|
| `x-request-start` | The millisecond timestamp indicating when the request was sent |
| `x-request-timeout` | The millisecond timeout for the request (currently set to 250 ms) |
:::

## Integration Notes

### Order Engine

The RFQ functionality depends on the mainnet deployment of the [Order Engine Program](https://solscan.io/account/61DFfeTKM7trxYcPQCM78bJ794ddZprZpAwAnLiwTpYH) for order fulfillment.

- **Source Code**: The program's source is located in the [programs/order-engine](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/programs/order-engine) directory.
- **IDL**: The Interface Definition Language (IDL) file is available [here](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/idls).

---

### Non-standard payload
The transaction data includes, beside the instruction data for the order-engine, 3 additional bytes that are appended to the instruction data. These bytes are not processed by the program and are only information and to be consumed by an off-chain consumer. The first 2 bytes contains the fee amount in basis points (u16) and the third byte (u8) is a bit mask where the least significant bit indicates if the swap is exact-in (0) or exact-out (1).

---

### Fulfillment Requirements

To ensure market makers stay competitive and responsive, we enforce a minimum benchmark for fulfillment and response times.

- **Fulfillment**: Market makers are expected to comply and fulfill **95%** of the quotes provided within a 1-hour window. If this is not met, the market maker will be turned off.
- **Response Time**: A webhook must respond within **250 ms** of receiving a quote request. If it fails to do so, the RFQ system will proceed with the available quotes at the time.

:::caution
To resume operations, we will need to manually re-enable your webhook, please reach out to us if this happens.
:::

:::danger need clarification
are we penalizing the market maker if they consistently take more than 250ms to respond?
:::

---

### Expiry

We enforce a fixed expiry timing flow for all quotes and transactions. This simplifies the integration by removing the need for market makers to specify custom expiry times in quote requests, providing consistent behavior across all quotes and transactions, and establishing clear timeout boundaries at different stages of the flow.

**Breakdown of the expiry flow:**

- **Total of 50 seconds**: Transaction expiry time
- **1st 25 seconds**: Reserved for the webhook to verify, sign, and send the transaction on-chain
- **2nd 25 seconds**: Allocated for the user to accept the quote

:::note
The frontend automatically re-quotes every 5 seconds.
:::

:::caution
These expiry thresholds may be adjusted based on performance and feedback.
:::

---

### Fees

Jupiter RFQ allows MMs a way to provide liquidity, adjust their quotes without being subject to the volatility of on-chain gas prices or chain health. RFQ fills are also much less CU intensive (< 10x) compared to AMM swaps, and can save gas in the long run on fills. Today, RFQ, when operating in Ultra mode, charges a dynamic fee that is selected based on factors like tokens and size.

**Dynamic Fee**

The dynamic fee amount is forwarded to webhooks in the quote request parameters and it is contained in the message that both taker and maker sign ([see the payload section above](#non-standard-payload)). In manual mode, the fee is a flat 2pbs.

**Fee Calculation**

Webhooks do not need to account for fees when quoting, the fee is applied directly by the RFQ system during transaction building.

- For example, for a quote of 1 SOL to 1,000 USDC with a fee of 100 bps
- Only 990 USDC will be transferred out of the market maker account
- While 10 USDC will be collected as a fee

:::note
The fee is not automatically transferred and will be accounted for asynchronously on a regular basis.

This is subject to change in the future.
:::

---

## FAQ

**Does RFQ support native SOL?**

Yes, native SOL is fully supported in the order-engine program for both the taker (user) and the maker. However, for now, we assume the maker will use WSOL (Wrapped SOL).

**Do faster quotes receive priority?**

No, the RFQ system dispatches the quote request to all registered webhooks simultaneously. All quotes received within the quote timeout are compared to select the best one. The selection prioritizes the quote value first (In the unlikely scenario where two quotes have identical values, the quote from the webhook with the faster response time will be actually prioritized).

**Shall a webhook verify swap requests?**

Yes, the RFQ system will verify the swap requests before forwarding them to the webhooks. However, webhooks are encouraged to verify the swap requests as well to ensure the integrity of the system. The checks that the RFQ system performs can be found in the [validate_similar_fill_sanitized_message](https://github.com/jup-ag/rfq-webhook-toolkit/blob/de46a38c3cfbda730c026a9b4bea85591c83f9e5/order-engine-sdk/src/fill.rs#L151) function.

**Is there a penalty for not providing a quote (status code 404)?**

No, there is no penalty. It is up to the webhook to decide whether to respond with a quote (`200 OK`) or indicate that it cannot provide one (`404 Not Found`).

For example, suppose a webhook provides quotes for USDC/SOL only within a range of 100 to 1000 USDC. If it receives a quote request for 10 USDC → SOL, it will respond with `404 Not Found`, since the amount is outside its quoting range.

In another case, a webhook may only support one-way quotes (USDC → SOL) but not SOL → USDC. If it receives a request for SOL → USDC, it will also return `404 Not Found`.

**Is there a fee applied to stable-to-stable swaps?**

No. Stable to stable swaps are exempt from fees.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Refer to the [What's New?](#whats-new) section for the latest API updates and br

**For existing developers**: Please refer to the [What's New?](#whats-new) section for the latest API updates and breaking changes.

**For routing integrations**: Please refer to the [DEX Integration](/docs/dex-integration) guide to complete the prerequisites before we look into integrating.
**For routing integrations**: Please refer to the [DEX Integration](/docs/routing/dex-integration) and [RFQ Integration](/docs/routing/rfq-integration) guides to complete the prerequisites before we look into integrating.

**Quick Links** to APIs and Tool Kits:

Expand Down
4 changes: 0 additions & 4 deletions guides/11-jupiter-lock/1-jupiter-lock.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ description: "Jupiter Lock is an open-sourced, audited, and free ecosystem tool
<meta name="twitter:card" content="summary" />
</head>

import DownloadBox from '/src/components/DownloadBox';

Jupiter Lock (https://lock.jup.ag/) is an [open-sourced](https://github.com/jup-ag/jup-lock), audited and free way to lock and distribute tokens over-time. Lock will be free for all project teams to lock tokens, implement cliff, and vest non-circulating supply in a clear and transparent manner.

### Jupiter Lock Specifications
Expand All @@ -25,8 +23,6 @@ Mainnet Deployment: `LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn`

The **IDL** for the Jupiter Lock program can be found on [Solscan](https://solscan.io/account/LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn#anchorProgramIdl), or available here:

<DownloadBox fileName="locker.json" /> &nbsp;

:::info Jupiter Lock is in Beta
Feel free to submit PRs, suggestions, or reach out to us! If you need help with Jupiter Lock or have any feedback on how to improve, let us know on Discord or [Telegram](https://t.me/xianxlb).
:::
Expand Down
20 changes: 0 additions & 20 deletions guides/12-general/7-media-kit.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,8 @@ description: "Get the official Jupiter media kit, including logo, brand material
<meta name="twitter:card" content="summary" />
</head>

import DownloadBox from '/src/components/DownloadBox';

Please find official Jupiter information, imagery, infographics, and contacts below for your own use.

For additional info or media inquiries, please contact [email protected]

Or contact Jupiter through [Twitter](https://twitter.com/JupiterExchange) or [Discord](https://discord.gg/jup)

### Jupiter Logo

<DownloadBox fileName="jupiter-logo.zip" />

### Jupiter Integration

<DownloadBox fileName="powered-by-jupiter.zip" />

### Download Jupiter Brand Materials

<DownloadBox fileName="jupiter-brand-materials.zip" />

### Jupiter Token Logo

_(JUP Token, JLP Token, JupSOL Token Logos)_

<DownloadBox fileName="jupiter-token-logo.zip" />
2 changes: 2 additions & 0 deletions redirects.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[
{"to":"/docs/routing/dex-integration","from":"/docs/dex-integration"},

{"to":"/docs/misc/integrator-guidelines","from":"/docs/misc/support-guidelines"},

{"to":"/docs/","from":"/docs/get-started"},
Expand Down
26 changes: 26 additions & 0 deletions sidebars-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,32 @@ const sidebars = {
],
},
],
routing: [
{
type: 'doc',
id: 'routing/index',
},
{
type: 'html',
value: '<div class="sidebar-line-break"></div>',
},
{
type: 'category',
label: 'Routing Integrations',
collapsible: false,
collapsed: false,
items: [
{
type: 'doc',
id: 'routing/dex-integration',
},
{
type: 'doc',
id: 'routing/rfq-integration',
},
],
},
],
misc: [
{
type: 'category',
Expand Down
50 changes: 0 additions & 50 deletions src/components/DownloadBox/index.tsx

This file was deleted.

Loading