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

# Как отправлять транзакции Solana

> Пошаговое руководство по созданию надежных производственных процессов отправки транзакций Solana. Узнайте об оптимизации вычислений, приоритетных комиссиях и стратегиях подтверждения.

<Tip>
  Это **базовый** способ отправки транзакций — плата взимается за каждую отправку, и он лучше всего подходит для случаев, когда
  надежность важнее предельно высокой скорости (платежи, кошельки, приложения). Если вы
  торгуете и вам нужна минимальная задержка, используйте вместо него [Helius
  Sender](/docs/ru/sending-transactions/sender).
</Tip>

Собственная логика отправки транзакций — лучший способ обеспечить максимальную производительность, управляемость и надежность вашего приложения. Хотя [Helius SDK](/docs/ru/sdks) предоставляет удобную обертку для начала работы, для производственных систем настоятельно рекомендуется разобраться в этом ручном процессе и реализовать его самостоятельно.

В этом руководстве описаны необходимые шаги для создания собственного решения.

### Ручной процесс

Отправка транзакции вручную включает следующие шаги:

<Steps>
  <Step title="Build the Initial Transaction">
    Соберите инструкции и подпишите транзакцию, чтобы ее можно было симулировать.
  </Step>

  <Step title="Optimize Compute Units">
    Симулируйте транзакцию, чтобы определить точное необходимое количество CU, и добавьте небольшой запас.
  </Step>

  <Step title="Add Priority Fees">
    Получите оценку комиссии через Helius Priority Fee API и добавьте ее в транзакцию.
  </Step>

  <Step title="Send and Re-broadcast">
    Отправьте итоговую транзакцию и реализуйте надежную стратегию опроса для обработки подтверждения.
  </Step>
</Steps>

<Info>
  SDK Helius имеют открытый исходный код. Вы можете посмотреть исходный код метода `sendSmartTransaction` в наших [TypeScript SDK](https://github.com/helius-labs/helius-sdk) и [Rust SDK](https://github.com/helius-labs/helius-rust-sdk), чтобы ознакомиться с реализацией этого процесса промышленного уровня.
</Info>

### 1. Создайте исходную транзакцию

Сначала соберите все инструкции, которые нужно включить в транзакцию. Затем создайте объект `Transaction` или `VersionedTransaction`. Также потребуется получить недавний хеш блока.

В этом примере подготавливается версионированная транзакция. На этом этапе ее также необходимо подписать, чтобы на следующем шаге можно было выполнить симуляцию.

```typescript theme={"system"}
import {
  Connection,
  Keypair,
  TransactionMessage,
  VersionedTransaction,
  SystemProgram,
  LAMPORTS_PER_SOL,
} from "@solana/web3.js";

const connection = new Connection("YOUR_RPC_URL");
const fromKeypair = Keypair.generate(); // Assume this is funded
const toPubkey = Keypair.generate().publicKey;

// 1. Build your instructions
const instructions = [
  SystemProgram.transfer({
    fromPubkey: fromKeypair.publicKey,
    toPubkey: toPubkey,
    lamports: 0.001 * LAMPORTS_PER_SOL,
  }),
];

// 2. Get a recent blockhash
const { blockhash } = await connection.getLatestBlockhash();

// 3. Compile the transaction message
const messageV0 = new TransactionMessage({
  payerKey: fromKeypair.publicKey,
  recentBlockhash: blockhash,
  instructions,
}).compileToV0Message();

// 4. Create and sign the transaction
const transaction = new VersionedTransaction(messageV0);
transaction.sign([fromKeypair]);
```

### 2. Оптимизируйте использование вычислительных единиц (CU)

Чтобы не переплачивать комиссию и избежать сбоя транзакции, задайте лимит вычислительных единиц (CU) как можно точнее. Для этого симулируйте транзакцию с помощью метода RPC [`simulateTransaction`](/docs/ru/api-reference/rpc/http/simulatetransaction).

Рекомендуется сначала выполнить симуляцию с высоким лимитом CU, чтобы она гарантированно завершилась успешно, а затем использовать значение `unitsConsumed` из ответа в качестве фактического лимита.

```typescript theme={"system"}
import { ComputeBudgetProgram } from "@solana/web3.js";

// Create a test transaction with a high compute limit to ensure simulation succeeds
const testInstructions = [
    ComputeBudgetProgram.setComputeUnitLimit({ units: 1_400_000 }),
    ...instructions, // Your original instructions
];
const testMessage = new TransactionMessage({
    payerKey: fromKeypair.publicKey,
    recentBlockhash: blockhash,
    instructions: testInstructions,
}).compileToV0Message();
const testTransaction = new VersionedTransaction(testMessage);
testTransaction.sign([fromKeypair]);

// Simulate the transaction to get the exact CUs consumed
const { value: simulationResult } = await connection.simulateTransaction(testTransaction);

if (!simulationResult.unitsConsumed) {
  throw new Error("Simulation failed to return unitsConsumed");
}

// Add a 10% buffer to the CU estimate
const computeUnitLimit = Math.ceil(simulationResult.unitsConsumed * 1.1);

// Create the instruction to set the CU limit
const setCuLimitInstruction = ComputeBudgetProgram.setComputeUnitLimit({
    units: computeUnitLimit,
});
```

Теперь у вас есть инструкция, которая точно задает лимит вычислений. Добавьте ее в итоговую транзакцию.

### 3. Задайте подходящую приоритетную комиссию

Затем определите оптимальную приоритетную комиссию для добавления в транзакцию. Helius [Priority Fee API](/docs/ru/priority-fee-api) — лучший способ получить оценку в реальном времени с учетом текущего состояния сети.

Вам потребуется вызвать метод RPC `getPriorityFeeEstimate`. Чтобы максимально повысить вероятность включения через стейкинговые подключения Helius, используйте параметр `recommended: true`.

```typescript theme={"system"}
// The transaction needs to be serialized and base58 encoded
const serializedTransaction = bs58.encode(transaction.serialize());

const response = await fetch("YOUR_RPC_URL", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getPriorityFeeEstimate",
        params: [
            {
                // Pass the serialized transaction
                transaction: serializedTransaction, 
                // Use 'recommended' for Helius's staked connections
                options: { recommended: true },
            },
        ],   
    }),
});
const data = await response.json();

if (!data.result || !data.result.priorityFeeEstimate) {
    throw new Error("Failed to get priority fee estimate");
}

const priorityFeeEstimate = data.result.priorityFeeEstimate;

// Create the instruction to set the priority fee
const setPriorityFeeInstruction = ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFeeEstimate,
});
```

### 4. Создайте, отправьте и подтвердите транзакцию

Теперь соберите итоговую транзакцию с новыми инструкциями бюджета вычислений, отправьте ее и реализуйте надежный механизм опроса для подтверждения ее включения в блок.

<Warning>
  Не полагайтесь на стандартную логику повторных попыток поставщика RPC (`maxRetries` в [`sendTransaction`](/docs/ru/api-reference/rpc/http/sendtransaction)). Хотя стейкинговые подключения Helius передают вашу транзакцию непосредственно лидеру, она все равно может быть отброшена. Для надежного подтверждения необходимо реализовать собственную логику повторной отправки.
</Warning>

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

```typescript theme={"system"}
// 1. Add the new instructions to your original set
const finalInstructions = [
  setCuLimitInstruction,
  setPriorityFeeInstruction,
  ...instructions,
];

// 2. Re-build and re-sign the transaction with the final instructions
const { blockhash: latestBlockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();

const finalMessage = new TransactionMessage({
  payerKey: fromKeypair.publicKey,
  recentBlockhash: latestBlockhash,
  instructions: finalInstructions,
}).compileToV0Message();

const finalTransaction = new VersionedTransaction(finalMessage);
finalTransaction.sign([fromKeypair]);

// 3. Send the transaction
const signature = await connection.sendTransaction(finalTransaction, {
  skipPreflight: true, // Optional: useful for bypassing client-side checks
});

// 4. Implement a polling loop to confirm the transaction
let confirmed = false;
while (!confirmed) {
    const statuses = await connection.getSignatureStatuses([signature]);
    const status = statuses && statuses.value && statuses.value[0];

    if (status && (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized')) {
        console.log('Transaction confirmed!');
        confirmed = true;
    }

    // Check if the blockhash has expired
    const currentBlockHeight = await connection.getBlockHeight();
    if (currentBlockHeight > lastValidBlockHeight) {
        console.log('Blockhash expired, transaction failed.');
        break;
    }
    
    // Wait for a short period before polling again
    await new Promise(resolve => setTimeout(resolve, 2000)); 
}
```

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

## Защита от сэндвич-атак

Чтобы направлять транзакцию в обход валидаторов, статистически связанных с сэндвич-атаками, добавьте параметр запроса `mev-protect=true` в URL RPC — изменять логику транзакции не нужно:

```
https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY&mev-protect=true
```

<Card title="MEV Protect" icon="shield-halved" href="/docs/ru/sending-transactions/mev-protect">
  Узнайте, как работает MEV Protect, какие методы он поддерживает и какие у него есть компромиссы.
</Card>

## Получайте вознаграждения за транзакции

Вы можете подключиться к программе и получать долю от MEV, создаваемой вашими транзакциями. Выплаты в SOL выполняются автоматически, а изменять логику транзакций не требуется.

<Card title="Transaction Rebates" icon="coins" href="/docs/ru/sending-transactions/backrun-rebates">
  Добавьте один параметр в вызовы `sendTransaction`, чтобы начать получать вознаграждения в SOL.
</Card>

## Связанные методы

<CardGroup cols={2}>
  <Card title="sendTransaction" href="/docs/ru/api-reference/rpc/http/sendtransaction">
    Отправка подписанной транзакции в сеть
  </Card>

  <Card title="simulateTransaction" href="/docs/ru/api-reference/rpc/http/simulatetransaction">
    Симуляция транзакции для оценки количества вычислительных единиц
  </Card>

  <Card title="getSignatureStatuses" href="/docs/ru/api-reference/rpc/http/getsignaturestatuses">
    Проверка статуса подтверждения транзакций
  </Card>

  <Card title="getLatestBlockhash" href="/docs/ru/api-reference/rpc/http/getlatestblockhash">
    Получение недавнего хеша блока для подписания транзакции
  </Card>

  <Card title="getBlockHeight" href="/docs/ru/api-reference/rpc/http/getblockheight">
    Получение текущей высоты блока для проверки срока действия
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.