> ## 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.

# Чаевые в Apex

> Каждая транзакция Apex содержит один перевод SystemProgram на опубликованный аккаунт для чаевых. Правило чаевых, стандартный минимум 0.001 SOL и использование чаевых.

## Правило чаевых

Каждая транзакция, которую вы отправляете через Apex, должна содержать **ровно одни** чаевые, которые отвечают всем этим условиям:

<Steps>
  <Step title="Перевод SystemProgram">
    Чаевые представляют собой обычную инструкцию `SystemProgram::Transfer` на один из опубликованных аккаунтов для чаевых Apex.
  </Step>

  <Step title="Верхний уровень">
    Перевод является инструкцией верхнего уровня в транзакции. Перевод, сделанный изнутри вашей программы через CPI, не считается.
  </Step>

  <Step title="Оплачены подписантом">
    Аккаунт, который платит чаевые, подписывает транзакцию. Он не обязан быть плательщиком комиссии.
  </Step>

  <Step title="Аккаунт для чаевых в статических ключах">
    Аккаунт для чаевых присутствует в статических ключах аккаунтов транзакции. Не загружайте его через address lookup table.
  </Step>

  <Step title="Не ниже минимума вашего тарифа">
    Минимум стандартного тарифа составляет **0.001 SOL (1,000,000 lamports)**. Тариф вашего ключа может задавать другой минимум.
  </Step>
</Steps>

Транзакция без чаевых, с несколькими чаевыми или с чаевыми ниже вашего минимума отклоняется до того, как будет куда-либо отправлена. Отклонение сообщает, какое правило нарушено, а сообщение о чаевых ниже минимума указывает ваш минимум. См. [Ошибки и лимиты запросов](/ru/apex/errors-and-rate-limits).

## Вы платите, только когда транзакция попала в блок

Чаевые находятся внутри вашей транзакции. Если транзакция не попала в блок, перевод не исполняется, и вы ничего не платите. Отклонённая, просроченная или отброшенная транзакция не стоит вам чаевых.

## Получите аккаунты для чаевых

Вызовите JSON-RPC `getTipAccounts` на любом эндпоинте Apex. API-ключ для этого не нужен.

<CodeGroup>
  ```bash cURL theme={null}
  curl -s http://fra.apex.orbitflare.com \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","id":1,"method":"getTipAccounts","params":[]}'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("http://fra.apex.orbitflare.com", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getTipAccounts", params: [] }),
  });
  const { result: tipAccounts } = await res.json();
  const tipAccount = tipAccounts[Math.floor(Math.random() * tipAccounts.length)];
  console.log(tipAccount);
  ```

  ```python Python theme={null}
  import random
  import requests

  res = requests.post(
      "http://fra.apex.orbitflare.com",
      json={"jsonrpc": "2.0", "id": 1, "method": "getTipAccounts", "params": []},
      timeout=5,
  )
  tip_accounts = res.json()["result"]
  tip_account = random.choice(tip_accounts)
  print(tip_account)
  ```

  ```rust Rust theme={null}
  use apex_sender_client::rpc::RpcClient;
  use apex_sender_client::{tip, Region};

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let api_key = std::env::var("APEX_API_KEY")?;
      let tip_accounts = RpcClient::new(Region::Frankfurt, &api_key)
          .get_tip_accounts()
          .await?;
      let tip_account = tip::pick_tip_account(&tip_accounts).ok_or("no tip accounts")?;
      println!("{tip_account}");
      Ok(())
  }
  ```
</CodeGroup>

Ответ представляет собой массив адресов в base58:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": ["APeX2oLtjYehgTMUCA971L8htM7tGNqsXHDz5NrivhhX", "APeXAKT6spXSmU3uRv2MoEgQ7ckhAS4nexTgaxwLEfJ9", "..."]
}
```

Получите список при запуске и закэшируйте его. Выбирайте аккаунт **случайным образом для каждой транзакции**. Распределение чаевых по аккаунтам избавляет ваши транзакции от конкуренции за блокировку записи на одном и том же аккаунте.

### Опубликованные аккаунты

Аккаунты для чаевых в mainnet, все они хранилища программы чаевых `9ig7pd4gqe2m16ACGPbPo4HfMGD3ba38poDhXEayx7EF`. Авторитетный список даёт `getTipAccounts`: только его эндпоинт принимает, и изменения появляются там первыми. Каждый адрес начинается с `APeX`, так что подменённый аккаунт заметен сразу.

```
APeX2oLtjYehgTMUCA971L8htM7tGNqsXHDz5NrivhhX
APeXAKT6spXSmU3uRv2MoEgQ7ckhAS4nexTgaxwLEfJ9
APeXB4mu1X7BSjwyPtiNUnKyhvc4wrq5SKEdmnPKWR95
APeXJTSGoxLWmwb9o1tiiEL5RXVUakazYgjLmZdDc2Ef
APeXUUaKFfPXjPxKHEdwCsJ4BfTuGg4qnVQyJE9K37PU
APeXVWXKDRAAujckMjmMsV61a4DQiXa98MPUAkL46sim
APeXW6PKFZRDz7WXBBybBMcoJaQo97UtLa5TAQnchNBY
APeXZuKaKuqouyfU8fFL1woeWvSEVFkY4EMrmkvbfhhD
APeXbYdbmrYWsastf6GurexGe3dwnuWKLD2mcsDoEuBU
APeXn29deoxpsZz6r7n63Ymmv2skBr3WhKYLB1mB2fR7
```

## Добавьте инструкцию чаевых

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { PublicKey, SystemProgram } from "@solana/web3.js";

  const tipInstruction = SystemProgram.transfer({
    fromPubkey: payer.publicKey,
    toPubkey: new PublicKey(tipAccount),
    lamports: 1_000_000, // 0.001 SOL, the standard tier floor
  });
  ```

  ```python Python theme={null}
  from solders.pubkey import Pubkey
  from solders.system_program import TransferParams, transfer

  tip_instruction = transfer(TransferParams(
      from_pubkey=payer.pubkey(),
      to_pubkey=Pubkey.from_string(tip_account),
      lamports=1_000_000,  # 0.001 SOL, the standard tier floor
  ))
  ```

  ```rust Rust theme={null}
  use apex_sender_client::{tip_instruction, MIN_TIP_LAMPORTS};

  let tip_ix = tip_instruction(&payer.pubkey(), &tip_account, MIN_TIP_LAMPORTS);
  ```
</CodeGroup>

Добавьте её в список инструкций транзакции рядом с вашими собственными инструкциями. В разделе [Быстрый старт](/ru/apex/quickstart) приведены полные программы.

## Куда идут чаевые

Аккаунты для чаевых являются хранилищами ончейн-программы чаевых OrbitFlare. Списывать с них средства может только программа.

Когда вашу транзакцию доставляет в блок именно **путь Jito**, чаевые за вычетом базовой комиссии 5,000 lamports идут ставкой в Jito в том же бандле, что и ваша транзакция. Отдельные чаевые Jito добавлять не нужно. Одни чаевые Apex покрывают все три пути.

| Ваши чаевые        | Базовая комиссия | Ставка Jito, когда побеждает путь Jito |
| ------------------ | ---------------- | -------------------------------------- |
| 1,000,000 lamports | 5,000 lamports   | 995,000 lamports                       |
| 5,000,000 lamports | 5,000 lamports   | 4,995,000 lamports                     |

Поэтому более крупные чаевые означают более крупную ставку на аукционе Jito. Вы платите одну и ту же сумму, какой бы путь ни доставил транзакцию в блок, потому что чаевые и есть перевод, который вы подписали.

## Чем чаевые отличаются от приоритетной комиссии

Apex доставляет вашу транзакцию лидеру. Планировщик лидера по-прежнему упорядочивает транзакции по **приоритетной комиссии**, то есть по цене вычислительной единицы, умноженной на лимит вычислительных единиц. Задавайте оба значения в каждой транзакции:

* **Лимит вычислительных единиц**, близкий к тому, что транзакция реально использует. Завышенный лимит снижает ваш эффективный приоритет на единицу и впустую занимает место в блоке.
* **Цена вычислительной единицы**, которая соответствует текущему рынку для аккаунтов, которые вы затрагиваете.

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { ComputeBudgetProgram } from "@solana/web3.js";

  const computeBudget = [
    ComputeBudgetProgram.setComputeUnitLimit({ units: 100_000 }),
    ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000 }),
  ];
  ```

  ```python Python theme={null}
  from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price

  compute_budget = [
      set_compute_unit_limit(100_000),
      set_compute_unit_price(10_000),  # micro-lamports per compute unit
  ]
  ```

  ```rust Rust theme={null}
  use solana_compute_budget_interface::ComputeBudgetInstruction;

  let compute_budget = [
      ComputeBudgetInstruction::set_compute_unit_limit(100_000),
      ComputeBudgetInstruction::set_compute_unit_price(10_000), // micro-lamports per compute unit
  ];
  ```
</CodeGroup>

Эти инструкции предназначены для транзакций legacy и v0. [Транзакция v1](/ru/apex/transaction-v1) задаёт вычислительный бюджет в `TransactionConfig` сообщения.

Рекомендации по выбору обоих значений см. в разделе [Лучшие практики](/ru/apex/best-practices#соизмеряйте-чаевые-со-сделкой).
