> ## 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 TypeScript İstemcisi

> @orbitflare/sdk içindeki ApexClient ile TypeScript'ten OrbitFlare Apex üzerinden işlemler, toplu gönderimler ve paketler gönderin. Yalnızca HTTP JSON-RPC; bölge yedeklemesi ve bahşiş yardımcılarıyla.

> [!NOTE]
>
> TypeScript Apex istemcisi ayrı bir paket değil, [`@orbitflare/sdk`](/tr/sdk/overview) paketinin bir parçasıdır. Apex ile **yalnızca HTTP JSON-RPC** üzerinden konuşur. TypeScript için henüz bir QUIC taşıma yöntemi yoktur, çünkü Node'da gönderim yapmaya yetecek kadar güvenilir bir QUIC uygulaması bulunmuyor. QUIC üzerinden en düşük gecikmeli yol için [Rust istemcisini](/tr/apex/rust-client) veya [Go istemcisini](/tr/apex/go-client) kullanın.

## Kurulum

```bash theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
npm install @orbitflare/sdk @solana/kit @solana-program/system @solana-program/compute-budget
```

`@solana/kit` ve iki program paketi işlemi oluşturur ve imzalar. Apex istemcisinin kendisi yalnızca `@orbitflare/sdk` paketine ihtiyaç duyar.

Apex API anahtarınızı, bakiyesi olan bir anahtar çiftini ve blockhash ile onay için bir Solana RPC uç noktasını ayarlayın. Örnek, lisans anahtarınızla OrbitFlare RPC kullanır:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
export ORBITFLARE_APEX_API_KEY=apex_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export ORBITFLARE_LICENSE_KEY=ORBIT-XXXXXX-NNNNNN-NNNNNN
export KEYPAIR_PATH=payer.json
export SOLANA_RPC_URL="https://fra.rpc.orbitflare.com?api_key=$ORBITFLARE_LICENSE_KEY"
```

## Hızlı Başlangıç

Bu program, minimum bahşişle seçtiğiniz bir adrese (varsayılan olarak kendisine) 1.000 lamport gönderir ve ardından işlemin bloğa girmesini bekler. `send.ts` olarak kaydedin ve `npx tsx send.ts` ile çalıştırın.

```ts theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
import { readFileSync } from 'node:fs';

import {
  address,
  appendTransactionMessageInstructions,
  createKeyPairSignerFromBytes,
  createTransactionMessage,
  getSignatureFromTransaction,
  getTransactionEncoder,
  lamports,
  pipe,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  signTransactionMessageWithSigners,
  type Blockhash,
} from '@solana/kit';
import {
  getSetComputeUnitLimitInstruction,
  getSetComputeUnitPriceInstruction,
} from '@solana-program/compute-budget';
import { getTransferSolInstruction } from '@solana-program/system';

import {
  APEX_DEFAULT_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS,
  APEX_MIN_TIP_LAMPORTS,
  ApexClientBuilder,
  RpcClientBuilder,
  pickApexTipAccount,
  waitForConfirmation,
} from '@orbitflare/sdk';

async function main() {
  // Reads ORBITFLARE_APEX_API_KEY; sends over HTTP to Frankfurt.
  const apex = new ApexClientBuilder().region('fra').build();
  const solana = new RpcClientBuilder()
    .url(process.env.SOLANA_RPC_URL ?? 'https://api.mainnet-beta.solana.com')
    .build();

  const keypair = JSON.parse(readFileSync(process.env.KEYPAIR_PATH ?? 'payer.json', 'utf8'));
  const payer = await createKeyPairSignerFromBytes(Uint8Array.from(keypair));
  const to = address(process.env.TO ?? payer.address);

  // A tip to any other account is rejected, so pick from the published list.
  const tipAccount = pickApexTipAccount(await apex.getTipAccounts());
  const { blockhash, lastValidBlockHeight } = await solana.getLatestBlockhash();

  const message = pipe(
    createTransactionMessage({ version: 'legacy' }),
    (m) => setTransactionMessageFeePayerSigner(payer, m),
    (m) =>
      setTransactionMessageLifetimeUsingBlockhash(
        { blockhash: blockhash as Blockhash, lastValidBlockHeight: BigInt(lastValidBlockHeight) },
        m,
      ),
    (m) =>
      appendTransactionMessageInstructions(
        [
          getSetComputeUnitLimitInstruction({ units: 50_000 }),
          getSetComputeUnitPriceInstruction({
            microLamports: APEX_DEFAULT_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS,
          }),
          getTransferSolInstruction({ source: payer, destination: to, amount: lamports(1_000n) }),
          // Exactly one top-level tip of at least 0.001 SOL.
          getTransferSolInstruction({
            source: payer,
            destination: address(tipAccount),
            amount: lamports(BigInt(APEX_MIN_TIP_LAMPORTS)),
          }),
        ],
        m,
      ),
  );
  const tx = await signTransactionMessageWithSigners(message);
  const wire = getTransactionEncoder().encode(tx);

  const sentAt = Date.now();
  const signature = await apex.sendTransactionBinary(wire);
  console.log(`accepted in ${Date.now() - sentAt} ms: ${signature}`);
  console.log(`matches the signed transaction: ${signature === getSignatureFromTransaction(tx)}`);

  // Accepted is not landed: confirm on a Solana RPC.
  const slot = await waitForConfirmation(solana, signature);
  console.log(
    slot === null
      ? 'not confirmed within 30 s'
      : `landed in slot ${slot} after ${Date.now() - sentAt} ms`,
  );
}

void main();
```

Aşağıdaki kod parçaları bu programdaki `apex`, `solana` ve imzalı işlem baytlarını (`wire`) yeniden kullanır.

## Gönderme

Tek bir işlemi iki yöntem gönderir. İkisi de uç nokta işlemi kabul eder etmez imzayı döndürür.

| Yöntem | Rota | Gövde |
| - | - | - |
| `sendTransactionBinary(bytes)` | `POST /send-bin` | Ham işlem baytları. Kodlanacak hiçbir şey olmadan en hızlı HTTP yolu |
| `sendTransaction(bytesOrBase64)` | JSON-RPC `sendTransaction` | Bir JSON-RPC isteği içinde base64. Bayt veya base64 dizesi kabul eder |

```ts theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
const signature = await apex.sendTransaction(wire, { mevProtect: true, maxRetries: 10 });
```

İkisi de isteğe bağlı `mevProtect` (Shield engelleme listesindeki liderleri atlar, [MEV koruması](/tr/apex/mev-protection) sayfasına bakın) ve `maxRetries` (Apex'in kaç kez yeniden göndereceğini sınırlar) seçeneklerini alır ve o çağrı için oluşturucu varsayılanlarını geçersiz kılar. Bir işlem 1 ile 4.096 bayt (`APEX_MAX_TRANSACTION_SIZE`) arasında olmalıdır.

## Toplu Gönderimler

`sendBatch`, tek bir istekte en fazla 16 işlem (`APEX_MAX_BATCH`) gönderir. Her işlem ayrı ayrı kontrol edilir ve yarıştırılır, dolayısıyla hatalı bir işlem diğerlerini durdurmaz.

```ts theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
const batch = await apex.sendBatch([wire1, wire2, wire3]);
console.log(`${batch.accepted} of ${batch.attempted} accepted`);
for (const item of batch.results) {
  console.log(item.accepted ? item.signature : `${item.error}: ${item.message}`);
}
```

## Paketler

`sendBundle`, yalnızca Jito liderleri üzerinden, birlikte bloğa giren ya da hiç girmeyen 1 ila 4 işlem (`APEX_MAX_BUNDLE`) gönderir. Paketteki işlemlerden tam olarak biri bahşişi taşır.

```ts theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
const { bundleId, signatures } = await apex.sendBundle([wire1, wire2]);
const [status] = await apex.getBundleStatuses([bundleId]);
console.log(status?.state, status?.landedSlot);
```

`state` değeri `Pending`, `Landed`, `Failed` veya `Invalid` olur. Paket durumları zincirin gerisinde kalabilir, bu yüzden yalnızca durumu beklemek yerine paketin `signatures` değerlerini `waitForConfirmation` ile onaylayın. Kurallar ve hız sınırları için [Paketler](/tr/apex/bundles) sayfasına bakın.

## Bahşişler ve Onay

| Yardımcı | Ne yapar |
| - | - |
| `apex.getTipAccounts()` | Uç noktanın kabul ettiği bahşiş hesapları |
| `pickApexTipAccount(accounts)` | Yazma kilitlerini dağıtmak için bunlardan rastgele biri |
| `APEX_MIN_TIP_LAMPORTS` | Standart katmanın bahşiş tabanı: 1.000.000 lamport (0,001 SOL) |
| `APEX_DEFAULT_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS` | Makul bir varsayılan öncelik ücreti: hesaplama birimi başına 10.000 mikro-lamport |
| `fetchApexVaults(rpc)` | Bahşiş programının vault hesaplarını zincirden okur. Bu, bahşiş listesi değildir: uç noktanın reddettiği yayınlanmamış vault'ları da içerir. Bahşiş verilecek hesaplar için `getTipAccounts()` kullanın; bunu ise yalnızca belirli bir hesabın gerçek bir vault olup olmadığını kontrol etmek için kullanın |
| `waitForConfirmation(rpc, signature, { timeoutMs, pollMs })` | İşlem onaylanana kadar sorgular. Slotu döndürür, zaman aşımında `null` döndürür (varsayılan 30 sn) ve işlem bloğa girip başarısız olduysa hata fırlatır |

Bahşiş kuralları [Bahşişler](/tr/apex/tips) sayfasındadır.

## Bölgeler ve Yedekleme

```ts theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
const apex = new ApexClientBuilder()
  .region('fra')
  .fallbackRegion('ams')
  .fallbackRegion('lon')
  .build();
```

Birincil uç noktaya yapılan bir istek başarısız olduğunda istemci yedekleri sırayla dener. Bölge kodları `fra`, `ams`, `dub`, `lon`, `nyc`, `slc`, `sgp`, `tyo`, `sqq` ve `global` (en yakın sağlıklı uç nokta) şeklindedir. Hiçbir bölge ayarlanmamışsa istemci önce `ORBITFLARE_APEX_URL`, ardından `ORBITFLARE_APEX_REGION`, ardından Frankfurt'u kullanır. [Uç noktalar](/tr/apex/endpoints) sayfasına bakın.

## Seçenekler

| Oluşturucu yöntemi | Varsayılan | Ne yapar |
| - | - | - |
| `.apiKey(key)` | `ORBITFLARE_APEX_API_KEY` | `x-api-key` başlığı olarak gönderilen Apex API anahtarınız |
| `.region(code)` / `.url(url)` | Frankfurt | Birincil uç nokta |
| `.fallbackRegion(code)` / `.fallbackUrl(url)` | Yok | Birincil uç nokta başarısız olduğunda denenecek uç noktalar |
| `.mevProtect(enabled)` | `false` | Her gönderimde Shield engelleme listesindeki liderleri atlar. [MEV koruması](/tr/apex/mev-protection) sayfasına bakın |
| `.maxRetries(n)` | Apex varsayılanı | Apex'in her işlemi kaç kez yeniden göndereceği |
| `.retry(policy)` | Uç nokta başına 1 deneme | Başarısız bir isteğin aynı uç noktada, geri çekilmeyle birlikte istemci tarafında yeniden denenmesi |
| `.timeoutMs(ms)` | `5000` | İstek başına zaman aşımı |

Varsayılan olarak istemci uç nokta başına bir deneme yapar ve yeniden denemek yerine doğrudan bir sonraki yedeğe geçer. Bu bilinçli bir tercihtir: Apex'in zaten kabul ettiği bir işlemi yeniden göndermek hız sınırınızı boşa harcar ve Apex kabul edilen işlemleri kendisi yeniden göndermeye devam eder.

## Bağlantıyı Sıcak Tutun

`apex.ping()`, `GET /ping` çağrısını yapar ve uç nokta `pong` yanıtını verdiğinde çözümlenir. Bunu birkaç saniyede bir çağırmak HTTP bağlantısını açık tutar, böylece bir sonraki gönderim TCP el sıkışmasını atlar.

```ts theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
setInterval(() => apex.ping().catch(() => {}), 5_000);
```

## Hatalar

Her hata, bir `kind` alanına sahip bir `OrbitflareError` değeridir:

| `kind` | Anlamı |
| - | - |
| `config` | Eksik API anahtarı, bilinmeyen bölge veya boyut sınırlarının dışında kalan bir işlem, toplu gönderim ya da paket. Hiçbir şey gönderilmedi |
| `rpc` | Apex bir JSON-RPC çağrısına, yetersiz bir bahşiş veya geçersiz bir işlem gibi bir hatayla yanıt verdi. Kod ve mesaj hatanın üzerindedir |
| `apex` | İkili rotalardan biri (`/send-bin`, `/send-batch`, `/send-bundle`) isteği reddetti. HTTP durumu, etiket ve mesaj hatanın üzerindedir |
| `rateLimited` | Anahtarınızın saniye başına sınırı aşıldı (HTTP 429). Apex sağladığında `retryAfterMs` ne kadar bekleneceğini söyler |
| `timeout` | `timeoutMs` içinde yanıt gelmedi |
| `transport` | İstek denenen her uç noktada başarısız oldu veya uç nokta bir sunucu hatası döndürdü |

Apex hata kodları ve hız sınırları [Hatalar ve hız sınırları](/tr/apex/errors-and-rate-limits) sayfasında listelenmiştir.


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