> ## 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 Hızlı Başlangıç

> İlk bahşişli Solana işleminizi OrbitFlare Apex üzerinden dakikalar içinde gönderin. Olduğu gibi çalıştırabileceğiniz eksiksiz cURL, JavaScript, Python ve Rust örnekleriyle.

## Ön Koşullar

İhtiyacınız olanlar:

* [OrbitFlare gösterge panelinde](https://orbitflare.com/dashboard) **Dashboard > Apex** altından alınmış bir Apex API anahtarı. Apex beta aşamasındadır ve yalnızca davetle kullanılabilir.
* Bahşiş ve ücretler için en az 0,002 SOL içeren, bakiyesi olan bir Solana anahtar çifti dosyası (`solana-keygen` tarafından yazılan JSON dizisi biçiminde).
* Blockhash almak ve onaylamak için herhangi bir Solana RPC URL'si, örneğin [OrbitFlare RPC](/tr/quickstart) uç noktanız.

Her örnek aynı ortam değişkenlerini okur:

```bash theme={null}
export APEX_API_KEY="YOUR_API_KEY"
export APEX_RPC="http://fra.apex.orbitflare.com"   # nearest Apex endpoint, see Endpoints and regions
export SOLANA_RPC_URL="https://api.mainnet-beta.solana.com"
export KEYPAIR_PATH="payer.json"
```

<Warning>
  Bu örnekler mainnet üzerinde gerçek bir işlem gönderir. İşlem bloğa girerse 0,001 SOL bahşiş ve ağ ücretini öder. Bloğa girmezse hiçbir maliyeti olmaz.
</Warning>

## İlk İşleminizi Gönderin

<Steps>
  <Step title="Apex uç noktasının erişilebilir olduğunu kontrol edin">
    `GET /ping` anahtar gerektirmez ve `pong` döndürür:

    ```bash theme={null}
    curl -s "$APEX_RPC/ping"
    ```
  </Step>

  <Step title="Bahşiş hesaplarını alın">
    ```bash theme={null}
    curl -s "$APEX_RPC" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":1,"method":"getTipAccounts","params":[]}'
    ```

    İşleminiz, bu hesaplardan birine en az katmanınızın tabanı kadar (standart katmanda 0,001 SOL) transfer yapmalıdır. [Bahşişler](/tr/apex/tips) sayfasına bakın.
  </Step>

  <Step title="Oluşturun, imzalayın, gönderin ve onaylayın">
    Her sekme eksiksiz bir programdır. Hesaplama bütçesi ve bahşiş içeren bir memo işlemi oluşturur, onu JSON-RPC `sendTransaction` ile gönderir ve onayı bekler.

    cURL bir işlemi imzalayamaz, bu yüzden cURL sekmesi bir işlem oluşturup imzalamak ve base64 olarak yazdırmak için küçük bir Node.js betiği kullanır. Bundan sonraki her şey düz cURL'dür.

    <CodeGroup>
      ```bash cURL theme={null}
      # 1. Save this as sign.mjs, then: npm install @solana/web3.js
      cat > sign.mjs <<'SCRIPT'
      import {
        ComputeBudgetProgram, Connection, Keypair, PublicKey, SystemProgram,
        TransactionInstruction, TransactionMessage, VersionedTransaction,
      } from "@solana/web3.js";
      import { readFileSync } from "node:fs";

      const payer = Keypair.fromSecretKey(
        Uint8Array.from(JSON.parse(readFileSync(process.env.KEYPAIR_PATH ?? "payer.json", "utf8"))),
      );
      const connection = new Connection(process.env.SOLANA_RPC_URL, "confirmed");
      const { blockhash } = await connection.getLatestBlockhash("confirmed");
      const message = new TransactionMessage({
        payerKey: payer.publicKey,
        recentBlockhash: blockhash,
        instructions: [
          ComputeBudgetProgram.setComputeUnitLimit({ units: 100_000 }),
          ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000 }),
          new TransactionInstruction({
            programId: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),
            keys: [{ pubkey: payer.publicKey, isSigner: true, isWritable: true }],
            data: Buffer.from(`apex curl ${Date.now()}`),
          }),
          SystemProgram.transfer({
            fromPubkey: payer.publicKey,
            toPubkey: new PublicKey(process.argv[2]),
            lamports: 1_000_000,
          }),
        ],
      }).compileToV0Message();
      const tx = new VersionedTransaction(message);
      tx.sign([payer]);
      console.log(Buffer.from(tx.serialize()).toString("base64"));
      SCRIPT

      # 2. Pick a tip account and sign a transaction that tips it.
      TIP_ACCOUNT=$(curl -s "$APEX_RPC" -H "Content-Type: application/json" \
        -d '{"jsonrpc":"2.0","id":1,"method":"getTipAccounts","params":[]}' | jq -r '.result[0]')
      TX_BASE64=$(node sign.mjs "$TIP_ACCOUNT")

      # 3. Send it. params: [base64 transaction, config, mevProtect]
      SIGNATURE=$(curl -s "$APEX_RPC" \
        -H "Content-Type: application/json" \
        -H "x-api-key: $APEX_API_KEY" \
        -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"sendTransaction\",\"params\":[\"$TX_BASE64\",{\"encoding\":\"base64\"},false]}" \
        | jq -r '.result // .error')
      echo "accepted: $SIGNATURE"

      # 4. Confirm on any Solana RPC. Repeat until confirmationStatus is "confirmed".
      curl -s "$SOLANA_RPC_URL" -H "Content-Type: application/json" \
        -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getSignatureStatuses\",\"params\":[[\"$SIGNATURE\"]]}" | jq '.result.value[0]'
      ```

      ```javascript JavaScript theme={null}
      // send.mjs
      //   npm install @solana/web3.js
      //   node send.mjs
      import {
        ComputeBudgetProgram, Connection, Keypair, PublicKey, SystemProgram,
        TransactionInstruction, TransactionMessage, VersionedTransaction,
      } from "@solana/web3.js";
      import { readFileSync } from "node:fs";

      const APEX_RPC = process.env.APEX_RPC ?? "http://fra.apex.orbitflare.com";
      const API_KEY = process.env.APEX_API_KEY;
      const SOLANA_RPC = process.env.SOLANA_RPC_URL ?? "https://api.mainnet-beta.solana.com";
      const TIP_LAMPORTS = Number(process.env.TIP_LAMPORTS ?? 1_000_000);
      const MEMO_PROGRAM = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");

      async function apexRpc(method, params) {
        const res = await fetch(APEX_RPC, {
          method: "POST",
          headers: { "Content-Type": "application/json", "x-api-key": API_KEY },
          body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
        });
        const body = await res.json();
        if (body.error) throw new Error(`${method} failed ${body.error.code}: ${body.error.message}`);
        return body.result;
      }

      if (!API_KEY) throw new Error("APEX_API_KEY is required");
      const payer = Keypair.fromSecretKey(
        Uint8Array.from(JSON.parse(readFileSync(process.env.KEYPAIR_PATH ?? "payer.json", "utf8"))),
      );
      const connection = new Connection(SOLANA_RPC, "confirmed");

      const tipAccounts = await apexRpc("getTipAccounts", []);
      const tipAccount = new PublicKey(tipAccounts[Math.floor(Math.random() * tipAccounts.length)]);

      const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
      const message = new TransactionMessage({
        payerKey: payer.publicKey,
        recentBlockhash: blockhash,
        instructions: [
          ComputeBudgetProgram.setComputeUnitLimit({ units: 100_000 }),
          ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000 }),
          new TransactionInstruction({
            programId: MEMO_PROGRAM,
            keys: [{ pubkey: payer.publicKey, isSigner: true, isWritable: true }],
            data: Buffer.from(`apex javascript ${Date.now()}`),
          }),
          SystemProgram.transfer({ fromPubkey: payer.publicKey, toPubkey: tipAccount, lamports: TIP_LAMPORTS }),
        ],
      }).compileToV0Message();
      const tx = new VersionedTransaction(message);
      tx.sign([payer]);

      const started = Date.now();
      // params: [base64 transaction, { encoding, maxRetries? }, mevProtect]
      const signature = await apexRpc("sendTransaction", [
        Buffer.from(tx.serialize()).toString("base64"),
        { encoding: "base64" },
        false,
      ]);
      console.log(`accepted in ${Date.now() - started} ms: ${signature}`);

      const result = await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight }, "confirmed");
      if (result.value.err) throw new Error(`failed on chain: ${JSON.stringify(result.value.err)}`);
      console.log(`confirmed after ${Date.now() - started} ms`);
      ```

      ```python Python theme={null}
      # send.py
      #   pip install solders requests
      #   python send.py
      import base64
      import json
      import os
      import random
      import time

      import requests
      from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price
      from solders.hash import Hash
      from solders.instruction import AccountMeta, Instruction
      from solders.keypair import Keypair
      from solders.message import Message
      from solders.pubkey import Pubkey
      from solders.system_program import TransferParams, transfer
      from solders.transaction import Transaction

      APEX_RPC = os.environ.get("APEX_RPC", "http://fra.apex.orbitflare.com")
      API_KEY = os.environ["APEX_API_KEY"]
      SOLANA_RPC = os.environ.get("SOLANA_RPC_URL", "https://api.mainnet-beta.solana.com")
      TIP_LAMPORTS = int(os.environ.get("TIP_LAMPORTS", "1000000"))
      MEMO_PROGRAM = Pubkey.from_string("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr")


      def apex_rpc(method, params):
          r = requests.post(APEX_RPC, headers={"x-api-key": API_KEY},
                            json={"jsonrpc": "2.0", "id": 1, "method": method, "params": params}, timeout=5)
          body = r.json()
          if "error" in body:
              raise RuntimeError(f"{method} failed {body['error']['code']}: {body['error']['message']}")
          return body["result"]


      def solana_rpc(method, params):
          r = requests.post(SOLANA_RPC, json={"jsonrpc": "2.0", "id": 1, "method": method, "params": params}, timeout=10)
          return r.json()["result"]


      def confirm(signature, timeout_s=30.0):
          deadline = time.time() + timeout_s
          while time.time() < deadline:
              status = solana_rpc("getSignatureStatuses", [[signature]])["value"][0]
              if status and status.get("err"):
                  raise RuntimeError(f"failed on chain: {status['err']}")
              if status and status.get("confirmationStatus") in ("confirmed", "finalized"):
                  return status["slot"]
              time.sleep(0.5)
          return None


      with open(os.environ.get("KEYPAIR_PATH", "payer.json")) as f:
          payer = Keypair.from_bytes(bytes(json.load(f)))

      tip_account = Pubkey.from_string(random.choice(apex_rpc("getTipAccounts", [])))
      blockhash = Hash.from_string(
          solana_rpc("getLatestBlockhash", [{"commitment": "confirmed"}])["value"]["blockhash"])

      instructions = [
          set_compute_unit_limit(100_000),
          set_compute_unit_price(10_000),
          Instruction(MEMO_PROGRAM, f"apex python {time.time_ns()}".encode(),
                      [AccountMeta(payer.pubkey(), is_signer=True, is_writable=True)]),
          transfer(TransferParams(from_pubkey=payer.pubkey(), to_pubkey=tip_account, lamports=TIP_LAMPORTS)),
      ]
      tx = Transaction([payer], Message.new_with_blockhash(instructions, payer.pubkey(), blockhash), blockhash)

      started = time.perf_counter()
      # params: [base64 transaction, {encoding, maxRetries?}, mevProtect]
      signature = apex_rpc("sendTransaction", [base64.b64encode(bytes(tx)).decode(), {"encoding": "base64"}, False])
      print(f"accepted in {(time.perf_counter() - started) * 1000:.1f} ms: {signature}")
      print("landed in slot", confirm(signature))
      ```

      ```rust Rust theme={null}
      // src/main.rs. Cargo.toml dependencies are listed under "Rust dependencies" below.
      //   cargo run --release
      use std::str::FromStr;
      use std::time::{Duration, Instant};

      use apex_sender_client::rpc::{RpcClient, SolanaRpc};
      use apex_sender_client::{tip, tip_instruction, ApexSenderClient, Region, MIN_TIP_LAMPORTS};
      use solana_compute_budget_interface::ComputeBudgetInstruction;
      use solana_instruction::{AccountMeta, Instruction};
      use solana_keypair::read_keypair_file;
      use solana_pubkey::Pubkey;
      use solana_signer::Signer;
      use solana_transaction::versioned::VersionedTransaction;
      use solana_transaction::Transaction;

      #[tokio::main]
      async fn main() -> Result<(), Box<dyn std::error::Error>> {
          let api_key = std::env::var("APEX_API_KEY")?;
          let solana_rpc_url = std::env::var("SOLANA_RPC_URL")
              .unwrap_or_else(|_| "https://api.mainnet-beta.solana.com".into());
          let keypair_path = std::env::var("KEYPAIR_PATH").unwrap_or_else(|_| "payer.json".into());
          let payer = read_keypair_file(keypair_path)?;
          let region = Region::Frankfurt;

          // One persistent QUIC connection, authenticated by a certificate derived from the key.
          let client = ApexSenderClient::connect(region, &api_key).await?;
          let tip_accounts = RpcClient::new(region, &api_key).get_tip_accounts().await?;
          let tip_account = tip::pick_tip_account(&tip_accounts).ok_or("no tip accounts")?;

          let nonce = std::time::SystemTime::now()
              .duration_since(std::time::UNIX_EPOCH)?
              .as_nanos();
          let memo = Instruction::new_with_bytes(
              Pubkey::from_str("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr")?,
              format!("apex rust {nonce}").as_bytes(),
              vec![AccountMeta::new(payer.pubkey(), true)],
          );
          let instructions = [
              ComputeBudgetInstruction::set_compute_unit_limit(100_000),
              ComputeBudgetInstruction::set_compute_unit_price(10_000),
              memo,
              tip_instruction(&payer.pubkey(), &tip_account, MIN_TIP_LAMPORTS),
          ];

          let solana = SolanaRpc::new(solana_rpc_url);
          let blockhash = solana.latest_blockhash().await?;
          let tx = VersionedTransaction::from(Transaction::new_signed_with_payer(
              &instructions,
              Some(&payer.pubkey()),
              &[&payer],
              blockhash,
          ));

          let sent_at = Instant::now();
          let signature = client.send_transaction(&tx).await?; // unidirectional stream, no acknowledgement
          println!("sent in {} us", sent_at.elapsed().as_micros());

          match solana.confirm(&signature.to_string(), Duration::from_secs(30)).await? {
              Some(slot) => println!("landed in slot {slot} after {} ms: {signature}", sent_at.elapsed().as_millis()),
              None => println!("not confirmed within 30 s: {signature}"),
          }
          Ok(())
      }
      ```
    </CodeGroup>
  </Step>
</Steps>

Başarılı bir `sendTransaction` işlemin imzasını döndürür:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "5gwAmfVM..."
}
```

<Note>
  **Kabul edilmiş olması bloğa girdiği anlamına gelmez.** İmza, Apex uç noktası işlemi alıp yarıştırmaya başlar başlamaz geri döner. Her örnekte yapıldığı gibi, her zaman bir Solana RPC üzerinde `getSignatureStatuses` ile onaylayın.
</Note>

## Rust Bağımlılıkları

Rust sekmesi, en hızlı yol olan QUIC istemcisini kullanır. Crate, `apex-sender-client` adıyla crates.io'ya geliyor. O zamana kadar OrbitFlare GitHub deposundan kurun:

```toml theme={null}
[dependencies]
apex-sender-client = { git = "https://github.com/orbitflare/apex-sender-client", features = ["rpc"] }
tokio = { version = "1", features = ["full"] }
solana-compute-budget-interface = "3"
solana-instruction = "3.4"
solana-keypair = "3.1"
solana-pubkey = "4.2"
solana-signer = "3"
solana-transaction = { version = "=4.1.6", features = ["wincode"] }
```

API'nin tamamı için [Rust istemcisi](/tr/apex/rust-client) sayfasına bakın.

## Zaten sendTransaction Çağırıyor musunuz?

Apex, standart Solana `sendTransaction` biçimini konuşur, dolayısıyla mevcut kodu taşımak bir URL değişimi ve iki değişiklikten ibarettir:

1. **Gönderim** çağrılarınızı `http://<code>.apex.orbitflare.com` adresine yönlendirin ve `x-api-key` başlığını (veya `?api-key=`) ekleyin.
2. Her işleme [bahşiş talimatını](/tr/apex/tips) ekleyin.

Geri kalan her şey için normal Solana RPC'nizi kullanmaya devam edin: blockhash'ler, hesap okumaları, simülasyon ve onay. Apex uç noktaları yalnızca gönderimleri kabul eder.

## Sırada Ne Var?

<CardGroup cols={2}>
  <Card title="İşlem gönderme" icon="paper-plane" href="/tr/apex/sending-transactions">
    İkili HTTP, toplu gönderimler ve QUIC akışları.
  </Card>

  <Card title="Bahşişler" icon="coins" href="/tr/apex/tips">
    Bahşiş kuralının tamamı ve bahşişin nasıl kullanıldığı.
  </Card>

  <Card title="Hatalar ve hız sınırları" icon="triangle-exclamation" href="/tr/apex/errors-and-rate-limits">
    Her ret kodu ve bu durumda ne yapılacağı.
  </Card>

  <Card title="En iyi uygulamalar" icon="list-check" href="/tr/apex/best-practices">
    Sıcak bağlantılar, bahşiş boyutlandırma, onaylama ve yeniden denemeler.
  </Card>
</CardGroup>
