> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitflare.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Metis Swap API

> Низкоуровневый движок маршрутизации Jupiter для свопов — CPI, пользовательские инструкции и полный контроль над транзакциями

## Обзор

Metis — это низкоуровневый движок маршрутизации свопов Jupiter. Он предоставляет детальный контроль над каждым аспектом своп-транзакции: выбор маршрута, компоновка инструкций, комиссии за приоритет, лимиты вычислительных единиц, slippage и трансляция. В отличие от Jupiter Ultra, Metis требует управлять этим самостоятельно — но взамен даёт максимальную гибкость для интеграций, которым нужен CPI, пользовательские инструкции или специфическая стратегия трансляции транзакций.

**Используйте Metis, когда вам нужно:**

* CPI (Cross Program Invocation) с вашей собственной программой на блокчейне
* Компоновка пользовательских инструкций вокруг свопа
* Полный контроль над комиссиями за приоритет, вычислительными единицами и slippage
* Собственный RPC или трансляция через Jito

**Рассмотрите Ultra вместо Metis, если:**

* Вам нужно сквозное исполнение без управления slippage, комиссиями или трансляцией
* Вам нужен Real-Time Slippage Estimator (RTSE), доступный только через Ultra

<Note>
  Доступ к Metis Swap API через OrbitFlare доступен на **Dedicated Nodes** через путь `/jup` на эндпоинте вашего узла. Для размещённого Jupiter API используйте `https://api.jup.ag/swap/v1/...` с вашим `x-api-key`.
</Note>

## Как это работает

<Steps>
  <Step title="Получить котировку">
    Вызовите `GET /swap/v1/quote` с входным минтом, выходным минтом, суммой и slippage, чтобы получить лучший маршрут от движка маршрутизации Metis.
  </Step>

  <Step title="Создать своп-транзакцию">
    Отправьте ответ с котировкой на `POST /swap/v1/swap`. API возвращает сериализованную транзакцию, готовую к подписанию, с опциональной оценкой комиссии за приоритет, динамическими лимитами вычислительных единиц и динамическим slippage.
  </Step>

  <Step title="Подписать и отправить">
    Десериализуйте base64-транзакцию, подпишите её вашим кошельком и транслируйте через `connection.sendRawTransaction()` или через Jito.
  </Step>
</Steps>

***

## Шаг 1 — Получить котировку

**Эндпоинт:** `GET /swap/v1/quote`

### Обязательные параметры

| Параметр      | Описание                                                                                                     |
| ------------- | ------------------------------------------------------------------------------------------------------------ |
| `inputMint`   | Адрес минта входного токена (например, `So11111111111111111111111111111111111111112` для SOL)                |
| `outputMint`  | Адрес минта выходного токена (например, `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` для USDC)             |
| `amount`      | Целочисленная сумма входных токенов до десятичного знака (lamports для SOL, атомарные единицы для остальных) |
| `slippageBps` | Максимально допустимый slippage в basis points (например, `50` = 0,5%)                                       |

### Пример — Котировка 1 SOL в USDC

```javascript theme={null}
const quoteResponse = await (
  await fetch(
    "https://api.jup.ag/swap/v1/quote?" +
      "inputMint=So11111111111111111111111111111111111111112" +
      "&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" +
      "&amount=100000000" +
      "&slippageBps=50" +
      "&restrictIntermediateTokens=true",
    {
      headers: {
        "x-api-key": "YOUR_API_KEY",
      },
    }
  )
).json();

console.log(JSON.stringify(quoteResponse, null, 2));
```

### Пример ответа

```json theme={null}
{
  "inputMint": "So11111111111111111111111111111111111111112",
  "inAmount": "100000000",
  "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "outAmount": "16198753",
  "otherAmountThreshold": "16117760",
  "swapMode": "ExactIn",
  "slippageBps": 50,
  "platformFee": null,
  "priceImpactPct": "0",
  "routePlan": [
    {
      "swapInfo": {
        "ammKey": "5BKxfWMbmYBAEWvyPZS9esPducUba9GqyMjtLCfbaqyF",
        "label": "Meteora DLMM",
        "inputMint": "So11111111111111111111111111111111111111112",
        "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        "inAmount": "100000000",
        "outAmount": "16198753"
      },
      "percent": 100
    }
  ],
  "contextSlot": 299283763,
  "timeTaken": 0.015257836
}
```

<Tip>
  `outAmount` — лучший возможный результат на момент котировки. `slippageBps` не влияет на это значение — он управляет `otherAmountThreshold`, то есть минимумом, который вы готовы принять.
</Tip>

### Дополнительные параметры котировки

<AccordionGroup>
  <Accordion title="restrictIntermediateTokens">
    Установите значение `true`, чтобы маршрутизация проходила только через высоколиквидные промежуточные токены. Это снижает сбои маршрутизации из-за неликвидных путей и повышает стабильность маршрута с незначительной потенциальной потерей в цене.
  </Accordion>

  <Accordion title="onlyDirectRoutes">
    Установите значение `true`, чтобы ограничить маршрутизацию одним рынком (без мультихопа). Возвращает пустую котировку, если прямого маршрута нет. Может давать невыгодные цены — используйте с осторожностью.
  </Accordion>

  <Accordion title="maxAccounts">
    Ограничивает общее количество аккаунтов во внутренних инструкциях свопа. Полезно, когда нужно оставить место для собственных инструкций. Рекомендуемый минимум — `64`. Слишком низкое значение исключает DEX, требующие большего числа аккаунтов (например, Meteora DLMM требует до 47).
  </Accordion>

  <Accordion title="platformFeeBps">
    Добавьте комиссию к свопу, которая зачисляется на ваш `feeAccount`. Комбинируйте с `feeAccount` в запросе свопа.
  </Accordion>
</AccordionGroup>

***

## Шаг 2 — Создать своп-транзакцию

**Эндпоинт:** `POST /swap/v1/swap`

Передайте ответ с котировкой из шага 1 вместе с публичным ключом пользователя. API возвращает сериализованную base64-транзакцию, готовую к подписанию и отправке.

### Создание транзакции с оптимизацией подтверждения

```javascript theme={null}
const swapResponse = await (
  await fetch("https://api.jup.ag/swap/v1/swap", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "YOUR_API_KEY",
    },
    body: JSON.stringify({
      quoteResponse,
      userPublicKey: wallet.publicKey.toString(),

      // Optimize for transaction landing
      dynamicComputeUnitLimit: true,
      dynamicSlippage: true,
      prioritizationFeeLamports: {
        priorityLevelWithMaxLamports: {
          maxLamports: 1000000,
          priorityLevel: "veryHigh",
        },
      },
    }),
  })
).json();
```

### Пример ответа

```json theme={null}
{
  "swapTransaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAGDkS+...",
  "lastValidBlockHeight": 279632475,
  "prioritizationFeeLamports": 9999,
  "computeUnitLimit": 388876,
  "prioritizationType": {
    "computeBudget": {
      "microLamports": 25715,
      "estimatedMicroLamports": 785154
    }
  },
  "dynamicSlippageReport": {
    "slippageBps": 50,
    "otherAmount": 20612318,
    "simulatedIncurredSlippageBps": -18,
    "amplificationRatio": "1.5",
    "categoryName": "lst",
    "heuristicMaxSlippageBps": 100
  },
  "simulationError": null
}
```

### Уровни комиссий за приоритет

| `priorityLevel` | Перцентиль | Случай использования                                       |
| --------------- | ---------- | ---------------------------------------------------------- |
| `medium`        | 25-й       | Низкая нагрузка, не чувствительные ко времени операции     |
| `high`          | 50-й       | Стандартные торговые условия                               |
| `veryHigh`      | 75-й       | Конкурентные условия, MEV, чувствительные ко времени свопы |

Установите `maxLamports` как предохранительный ограничитель для предотвращения переплаты во время скачков комиссий:

```javascript theme={null}
prioritizationFeeLamports: {
  priorityLevelWithMaxLamports: {
    maxLamports: 10000000,
    global: false,        // use local fee market (writable accounts), not global
    priorityLevel: "veryHigh",
  },
}
```

### Использование инструкций свопа вместо транзакции

Если вам нужно скомпоновать своп с вашими собственными инструкциями, используйте `/swap/v1/swap-instructions` вместо `/swap/v1/swap`. Принимает те же параметры, но возвращает отдельные объекты инструкций, а не сериализованную транзакцию:

```javascript theme={null}
const instructions = await (
  await fetch("https://api.jup.ag/swap/v1/swap-instructions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "YOUR_API_KEY",
    },
    body: JSON.stringify({
      quoteResponse,
      userPublicKey: wallet.publicKey.toString(),
    }),
  })
).json();

const {
  computeBudgetInstructions,
  setupInstructions,
  swapInstruction: swapInstructionPayload,
  cleanupInstruction,
  addressLookupTableAddresses,
} = instructions;
```

***

## Шаг 3 — Отправить своп-транзакцию

### Десериализация, подпись и сериализация

Поле `swapTransaction` в ответе закодировано в base64. Десериализуйте его в `VersionedTransaction`, подпишите, затем конвертируйте обратно в бинарный формат для отправки:

```javascript theme={null}
import { VersionedTransaction } from "@solana/web3.js";

const transactionBase64 = swapResponse.swapTransaction;
const transaction = VersionedTransaction.deserialize(
  Buffer.from(transactionBase64, "base64")
);

transaction.sign([wallet]);

const transactionBinary = transaction.serialize();
```

### Отправка транзакции

```javascript theme={null}
const signature = await connection.sendRawTransaction(transactionBinary, {
  maxRetries: 2,
  skipPreflight: true,
});
```

| Параметр        | Описание                                                                                                                              |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `maxRetries`    | Максимальное количество повторных попыток перед отказом. Если не указан, RPC повторяет попытки до истечения срока действия blockhash. |
| `skipPreflight` | Пропустить проверку подписи и симуляцию перед отправкой. Рекомендуется `true` для чувствительных ко времени свопов.                   |

### Подтверждение транзакции

```javascript theme={null}
const confirmation = await connection.confirmTransaction(
  { signature },
  "finalized"
);

if (confirmation.value.err) {
  throw new Error(
    `Transaction failed: ${JSON.stringify(confirmation.value.err)}\nhttps://solscan.io/tx/${signature}/`
  );
} else {
  console.log(`Transaction successful: https://solscan.io/tx/${signature}/`);
}
```

### Трансляция через Jito

Чтобы использовать Jito для более быстрого включения и защиты от MEV, замените `prioritizationFeeLamports` чаевыми Jito и отправьте на эндпоинт Jito RPC:

```javascript theme={null}
body: JSON.stringify({
  quoteResponse,
  userPublicKey: wallet.publicKey.toString(),
  prioritizationFeeLamports: {
    jitoTipLamports: 1000000, // fixed lamports, not a cap
  },
}),
```

<Warning>
  Чаевые Jito должны быть отправлены на эндпоинт Jito RPC, чтобы вступить в силу. Отправка на стандартный RPC не будет маршрутизирована через блок-движок Jito.
</Warning>

***

## Расширенные возможности

<AccordionGroup>
  <Accordion title="Динамический Slippage">
    Включите `dynamicSlippage: true` в запросе свопа. Бэкенд симулирует транзакцию и применяет эвристику на основе категории токена для оценки подходящего значения slippage.

    Примечание: Разработка Dynamic Slippage прекращена. Для использования в продакшене Jupiter рекомендует Ultra Swap API, включающий Real-Time Slippage Estimator (RTSE) — значительно более точную и реактивную систему.
  </Accordion>

  <Accordion title="CPI (Cross Program Invocation)">
    Начиная с января 2025 года, Jupiter Swap через CPI является рекомендуемым методом интеграции с программами на блокчейне. Добавьте крейт `jupiter-cpi` в вашу программу:

    ```toml theme={null}
    [dependencies]
    jupiter-cpi = { git = "https://github.com/jup-ag/jupiter-cpi", rev = "5eb8977" }
    ```

    Затем вызовите маршрут общих аккаунтов из обработчика инструкции. Полный пример реализации смотрите в [примере Jupiter CPI](https://github.com/jup-ag/jupiter-cpi-swap-example).
  </Accordion>

  <Accordion title="Flash Fill (устаревший)">
    Flash Fill был более ранним обходным решением для ограничений размера аккаунтов CPI с использованием Versioned Transactions и Address Lookup Tables. Больше не рекомендуется, поскольку ослабление ограничений CPI активно на мейннете Solana. Смотрите [sol-swap-flash-fill](https://github.com/jup-ag/sol-swap-flash-fill) для исторической справки.
  </Accordion>

  <Accordion title="Требования к аккаунтам DEX">
    При использовании `maxAccounts`, вот приблизительное количество аккаунтов для каждого DEX (минимум применяется при наличии ALT, максимум — без них):

    | DEX                   | Макс. аккаунтов | Мин. аккаунтов |
    | --------------------- | :-------------: | :------------: |
    | Meteora DLMM          |        47       |       19       |
    | Meteora               |        45       |       18       |
    | Raydium               |        45       |       18       |
    | Raydium CLMM          |        45       |       19       |
    | Moonshot              |        37       |       15       |
    | Raydium CPMM          |        37       |       14       |
    | Pumpfun AMM           |        42       |       17       |
    | Pumpfun Bonding Curve |        40       |       16       |
    | Orca Whirlpool        |        30       |       12       |
    | Obric                 |        30       |       12       |
    | Solfi                 |        22       |        9       |
    | Sanctum               |        80       |       80       |
    | Sanctum Infinity      |        80       |       80       |

    Слишком низкое значение `maxAccounts` молча исключит DEX из маршрутизации. Держите его как можно выше и снижайте только если транзакция превышает ограничение в 1232 байта.
  </Accordion>
</AccordionGroup>

***

## Требования и ресурсы

Доступ к Metis Swap API через OrbitFlare доступен только на **Dedicated Nodes**. API доступен через путь `/jup` на эндпоинте вашего выделенного узла или напрямую по адресу `https://api.jup.ag/swap/v1/...` с ключом Jupiter API.

<CardGroup cols={2}>
  <Card title="Официальная документация Metis" icon="book" href="https://dev.jup.ag/docs/swap">
    Полный справочник API для всех эндпоинтов, параметров и схем ответов Metis.
  </Card>

  <Card title="Бинарный файл Metis (GitHub)" icon="code" href="https://github.com/jup-ag/metis-binary">
    Саморазмещаемый бинарный файл Metis от Jupiter для запуска движка маршрутизации на вашей собственной инфраструктуре.
  </Card>

  <Card title="Симуляция Jito Bundle" icon="bolt" href="/trading-apis/jito-bundle-simulation">
    Симулируйте и проверяйте MEV-бандлы Jito на вашем выделенном узле перед отправкой.
  </Card>

  <Card title="Dedicated Nodes" icon="server" href="/dedicated-nodes">
    Разверните изолированную инфраструктуру Solana с неограниченным RPS и включённым доступом к Metis Swap API.
  </Card>
</CardGroup>
