Jito ve Kora ile Gassız İşlem Paketlerini Nasıl Uygularsınız

Son Güncelleme: 2025-01-09

Ne Oluşturacaksınız

Tam İşlem Akışı Kılavuzu'nda Kora kullanarak gassız işlemler oluşturmayı öğrendiniz. Ancak, tek bir işlemin yetersiz olduğu veya tek bir işlemde Kora ödeme talimatını içerecek yeterli alan bulunmadığı birçok senaryo vardır. Bu kılavuzda, Solana Mainnet üzerinde atomik yürütme için Jito'nun blok motoruna bir işlem paketi imzalamak ve göndermek için Kora'nın nasıl kullanılacağını gösteren bir demo oluşturacağız. Kora sunucusu Jito bahşişini ve tüm işlem ücretlerini ödeyecektir.

Nihai sonuç, çalışan bir Jito paket sistemi olacaktır:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
KORA JITO BUNDLE DEMO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[1/4] Initializing clients
Kora RPC: http://localhost:8080/
Solana RPC: https://api.mainnet-beta.solana.com
[2/4] Setting up keypairs
Sender: BYJVBqQ2xV9GECc84FeoPQy2DpgoonZQFQu97MMWTbBc
Kora signer address: 3Z1Ef7YaxK8oUMoi6exf7wYZjZKWJJsrzJXSt1c3qrDE
[3/4] Creating bundle transactions
Blockhash: 7HZUaMqV...
Tip account: 96gYZGLn...
Transaction 1: Kora Memo "Bundle tx #1"
Transaction 2: Kora Memo "Bundle tx #2"
Transaction 3: Kora Memo "Bundle tx #3"
Transaction 4: Kora Memo "Bundle tx #4" + Jito tip
4 transactions created for bundle
[4/4] Signing and sending bundle
Bundle submitted to Jito block engine
Bundle UUID: 8f4a3b2c-1d5e-6f7a-8b9c-0d1e2f3a4b5c
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SUCCESS: Bundle confirmed on Solana
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Bundle UUID:
8f4a3b2c-1d5e-6f7a-8b9c-0d1e2f3a4b5c

İşte bunu nasıl oluşturacağız.

Ön Koşullar

Bu öğreticiye başlamadan önce, aşağıdakilere sahip olduğunuzdan emin olun:

Kora v2.2.0 Beta

Önemli: Bu kılavuz Kora v2.2.0 beta sürümünü gerektirir. Sürümü buradan bulabilirsiniz. Bu bir ön sürümdür ve hatalar içerebilir.

cargo install kora-cli@2.2.0-beta.7

Jito Paketleri Temelleri

Solana'da, bir işlemdeki her talimat atomiktir—bir talimat başarısız olursa, tüm işlem başarısız olur. Paketler, 5 adede kadar işlemi atomik ve sıralı olarak yürütmenizi sağlayan bir araçtır. Paketler bir bahşişle teşvik edilir; bahşiş ne kadar yüksekse, öncelik o kadar yüksektir.

Bu kılavuz, Jito Paketleri hakkında temel bir anlayışa ve deneyime sahip olduğunuzu varsayar.

Proje Yapısı

Bu demo için örnek kod Kora örneklerinde bulunabilir:

jito-bundles/
├── client/
│ ├── src/
│ │ └── index.ts # Bundle demo implementation
│ └── package.json
├── server/
│ ├── kora.toml # Kora configuration with bundles enabled
│ └── signers.toml # Signer configuration
└── scripts/
└── start-kora.sh # Server startup script

Kora deposunu klonlayın ve jito-bundles dizinine gidin:

git clone https://github.com/solana-foundation/kora.git
cd kora/examples/jito-bundles

Kora Sunucu Yapılandırması

kora.toml

Bundle desteği için temel yapılandırma:

[kora]
rate_limit = 100
[kora.auth]
api_key = "kora_facilitator_api_key_example"
[kora.enabled_methods]
sign_bundle = true
sign_and_send_bundle = true
estimate_bundle_fee = true
get_blockhash = true
get_config = true
get_payer_signer = true
[validation]
max_allowed_lamports = 1000000
max_signatures = 10
price_source = "Mock"
allowed_programs = [
"11111111111111111111111111111111", # System Program
"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", # Memo Program
]
[validation.fee_payer_policy.system]
allow_transfer = true # Required for Jito tip transfers
[validation.price]
type = "free" # No payment required for this demo
[kora.bundle]
enabled = true
[kora.bundle.jito]
block_engine_url = "https://mainnet.block-engine.jito.wtf"

Bundle desteği için Önemli ayarlar:

  • sign_bundle / sign_and_send_bundle — Bundle RPC metodlarını etkinleştirir
  • allow_transfer = true — Kora'nın imzalayıcısı Jito bahşişini öder, bu nedenle transfer iznine ihtiyacı vardır
  • bundle.enabled = true — Bundle işlevselliği için ana anahtar
  • Bu demo için genel mainnet blok motoru URL'sini kullanıyoruz. Üretim ortamında, özel blok motoru URL'sini kullanırsınız.

signers.toml

[signer_pool]
strategy = "round_robin"
[[signers]]
name = "main_signer"
type = "memory"
private_key_env = "KORA_PRIVATE_KEY"

.env.example dosyasını .env olarak yeniden adlandırdığınızdan ve KORA_PRIVATE_KEY ortham değişkenini mainnet özel anahtarınıza ayarladığınızdan emin olun. İmzalayıcı cüzdanının mainnet'te aşağıdakileri ödemek için SOL'ye ihtiyacı vardır:

  1. Tüm bundle işlemleri için işlem ücretleri
  2. Jito bahşişi (minimum 1.000 lamport)

Önemli: Bu rehber, Solana Mainnet'te Jito bahşişlerinin kullanımını göstermektedir. Bahşişler iade edilemez.

Sunucuyu Başlatma

server/ dizininden:

kora --config kora.toml --rpc-url https://api.mainnet-beta.solana.com rpc start --signers-config signers.toml

Veya sağlanan betiği kullanın. server/ dizininden:

../scripts/start-kora.sh

İstemci Uygulaması

İstemci uygulamasını adım adım, içe aktarmalarla başlayarak inceleyeceğiz.

İçe Aktarmalar ve Yapılandırma

import { KoraClient } from "@solana/kora";
import {
createNoopSigner,
address,
getBase64EncodedWireTransaction,
partiallySignTransactionMessageWithSigners,
Blockhash,
KeyPairSigner,
pipe,
createTransactionMessage,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
generateKeyPairSigner
} from "@solana/kit";
import { getAddMemoInstruction } from "@solana-program/memo";
import { getTransferSolInstruction } from "@solana-program/system";
const MINIMUM_JITO_TIP = 1_000n; // lamports
const CONFIG = {
solanaRpcUrl: "https://api.mainnet-beta.solana.com",
koraRpcUrl: "http://localhost:8080/",
jitoTipLamports: MINIMUM_JITO_TIP,
bundleSize: 4, // We'll create 4 transactions for this demo
pollIntervalMs: 6000,
pollTimeoutMs: 60000
};

Ayarladıklarımız:

  • İşlem oluşturmak için Solana Kit içe aktarmaları
  • Demo işlemlerimiz için Memo programı (gerçek işlemlerle değiştirirsiniz)
  • Jito bahşiş transferi için System Program
  • RPC uç noktaları ve paket parametreleri için Yapılandırma

Jito Bahşiş Hesapları

Jito'nun SOL gönderebileceğiniz 8 bahşiş hesabı vardır. Bu demo için rastgele birini seçiyoruz.

// Jito tip accounts - one is randomly selected by the block engine
const JITO_TIP_ACCOUNTS = [
"96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
"HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe",
"Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY",
"ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49",
"DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh",
"ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt",
"DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL",
"3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT"
];
function getRandomTipAccount(): string {
return JITO_TIP_ACCOUNTS[
Math.floor(Math.random() * JITO_TIP_ACCOUNTS.length)
];
}

Bahşiş hesapları Jito tarafından işletilen adreslerdir. Bunlardan herhangi birine SOL göndermek, validator'lara bahşiş miktarınızı bildirir.

Adım 1: İstemcileri Başlatma

Kora istemcisini API anahtarımızla başlatıyoruz; bu anahtar kora.toml içinde yapılandırılanla eşleşir. Üretim ortamında bunu bir ortam değişkeninden yüklersiniz.

async function initializeClients() {
console.log("\n[1/4] Initializing clients");
console.log(" → Kora RPC:", CONFIG.koraRpcUrl);
console.log(" → Solana RPC:", CONFIG.solanaRpcUrl);
const client = new KoraClient({
rpcUrl: CONFIG.koraRpcUrl,
apiKey: "kora_facilitator_api_key_example"
});
return { client };
}

Adım 2: Anahtarları Ayarlama

async function setupKeys(client: KoraClient) {
console.log("\n[2/4] Setting up keypairs");
const senderKeypair = await generateKeyPairSigner();
console.log(" → Sender:", senderKeypair.address);
const { signer_address } = await client.getPayerSigner();
console.log(" → Kora signer address:", signer_address);
return { senderKeypair, signer_address };
}

Demo için yeni bir keypair oluşturmak üzere generateKeyPairSigner() kullanıyoruz. keypair yalnızca memo talimatlarını imzaladığı ve herhangi bir Kora ücreti ödemek zorunda olmadığı için (yapılandırmamıza göre), hiçbir SOL veya başka token'a ihtiyaç yoktur. Kora'nın imzalayıcısı (getPayerSigner aracılığıyla alınır) tüm ücretleri ve Jito bahşişini öder.

Adım 3: Paket İşlemleri Oluşturma

Şimdi bir işlem paketi oluşturalım. Her biri kendi benzersiz talimatlarına sahip birden fazla işlem oluşturuyoruz. Burada, işlemlerimiz Solana Mainnet'e ulaştıktan sonra kolayca doğrulamak için benzersiz memo talimatları kullanıyoruz.

async function createBundleTransactions(
client: KoraClient,
senderKeypair: KeyPairSigner,
signer_address: string
) {
console.log("\n[3/4] Creating bundle transactions");
const noopSigner = createNoopSigner(address(signer_address));
const latestBlockhash = await client.getBlockhash();
const tipAccount = getRandomTipAccount();
console.log(" → Blockhash:", latestBlockhash.blockhash.slice(0, 8) + "...");
console.log(" → Tip account:", tipAccount.slice(0, 8) + "...");
const transactions: string[] = [];
for (let i = 0; i < CONFIG.bundleSize; i++) {
const isLastTransaction = i === CONFIG.bundleSize - 1;
console.log(
` → Transaction ${i + 1}: Kora Memo "Bundle tx #${i + 1}"${
isLastTransaction ? " + Jito tip" : ""
}`
);
// Build transaction with memo
let transactionMessage = pipe(
createTransactionMessage({
version: 0
}),
(tx) => setTransactionMessageFeePayerSigner(noopSigner, tx),
(tx) =>
setTransactionMessageLifetimeUsingBlockhash(
{
blockhash: latestBlockhash.blockhash as Blockhash,
lastValidBlockHeight: 0n
},
tx
),
(tx) =>
appendTransactionMessageInstruction(
getAddMemoInstruction({
memo: `Kora Bundle tx #${i + 1} of ${CONFIG.bundleSize}`,
signers: [senderKeypair]
}),
tx
),
// Add Jito tip to the LAST transaction only
(tx) =>
isLastTransaction
? appendTransactionMessageInstruction(
getTransferSolInstruction({
source: noopSigner,
destination: address(tipAccount),
amount: CONFIG.jitoTipLamports
}),
tx
)
: tx
);
// Sign with sender keypair (required for memo instruction)
const signedTransaction =
await partiallySignTransactionMessageWithSigners(transactionMessage);
const base64Transaction =
getBase64EncodedWireTransaction(signedTransaction);
transactions.push(base64Transaction);
}
console.log(` ✓ ${transactions.length} transactions created for bundle`);
return transactions;
}

Önemli: Kora imzalayıcısı tarafından ödenen bahşiş: Kora düğümünün Jito bahşişimizi ödemesini istediğimiz için, bahşiş transferinin kaynağının Kora'nın adresi olduğu bir "no-op" imzalayıcı (noopSigner) kullanıyoruz. Kora, paketi işlerken bunu imzalayacaktır.

Adım 4: Paketi İmzalama ve Gönderme

Artık her şeyi bir araya getirebilir ve paketi Kora'ya imzalama ve Jito'nun blok motoruna gönderilmek üzere iletebiliriz.

async function main() {
console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
console.log("KORA JITO BUNDLE DEMO");
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
try {
// Step 1: Initialize clients
const { client } = await initializeClients();
// Step 2: Setup keys
const { senderKeypair, signer_address } = await setupKeys(client);
// Step 3: Create bundle transactions
const transactions = await createBundleTransactions(
client,
senderKeypair,
signer_address
);
// Step 4: Sign and send bundle
console.log("\n[4/4] Signing and sending bundle");
const { bundle_uuid } = await client.signAndSendBundle({
transactions,
signer_key: signer_address
});
console.log("\nBundle UUID:");
console.log(bundle_uuid);
} catch (error) {
console.error("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
console.error("ERROR: Demo failed");
console.error("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
console.error("\nDetails:", error);
process.exit(1);
}
}
main().catch((e) => console.error("Error:", e));

Demo'yu Çalıştırma

1. Kora Sunucusunu Başlatın

cd examples/jito-bundles/server
kora --config kora.toml --rpc-url https://api.mainnet-beta.solana.com rpc start --signers-config signers.toml

2. İstemciyi Çalıştırın

Yeni bir terminalde client/ dizinine gidin ve demoyu çalıştırın:

cd examples/jito-bundles/client
# Install dependencies
pnpm install
# Run the demo
pnpm start

Beklenen Çıktı

Sonunda başarılı bir paketle birlikte adım adım yürütmeyi görmelisiniz. Paket şunları yapacaktır:

  • 4 memo işlemi oluştur
  • Son işleme bir Jito bahşişi ekle (1.000 lamport)
  • Tüm işlemlerin ücret ödeyici olarak Kora tarafından imzalanmasını sağla
  • Jito'nun blok motoruna atomik olarak gönder

Not:

  • Jito'nun varsayılan yönlendiricisi hız limitine takılabilir. 429 hatası alırsanız, daha sonra tekrar deneyebilir veya daha yüksek limitler talep edebilirsiniz. Daha fazla bilgi için Jito'nun hız sınırlama dokümantasyonuna göz atın.
  • Demomuz çok küçük bir bahşiş kullandığı için, paket Solana Mainnet'e ulaşmayabilir. Paketi Jito'nun paket gezgininde göremezseniz, daha yüksek bir bahşişle daha sonra tekrar deneyebilirsiniz.

Ne Olduğunu Anlamak

Tek işlemlerden farklı olarak şunlar gerçekleşti:

  1. Çoklu İşlemler — Bir işlem yerine, birlikte yürütülmesi gereken 4 işlem oluşturduk
  2. Jito Bahşişi — Validator'leri teşvik etmek için bir bahşiş transferi ekledik (Kora'nın imzalayıcısı tarafından ödendi)
  3. Paket Doğrulama — Kora, kora.toml içinde belirtilen gereksinimleri karşılayan tüm işlemleri doğruladı
  4. Atomik Gönderim — Tüm işlemler, Kora sunucumuz tarafından tüm ücretler ve bahşişler Kora'nın imzalayıcısı tarafından ödenerek Jito'ya tek bir birim olarak gönderildi

Sonuç: ya 4 işlem de sırayla yürütülür ya da hiçbiri yürütülmez. Kısmi durumlar söz konusu değildir.

Ek Kaynaklar

Is this page helpful?

Yönetici

© 2026 Solana Vakfı.
Tüm hakları saklıdır.
Bağlanın