Genel Bakış
Yellowstone gRPC, ağ ilerlemesini takip etmek için iki ilgili ancak birbirinden farklı abonelik türü sunar:
- Slotlar — bir slot’un
processed, confirmed veya finalized taahhüdüne ulaştığını gösteren hafif güncellemeler. Düşük bant genişliği, konsensüs izleme için kullanışlı.
- Bloklar — işlemler, hesap güncellemeleri ve girişler dahil tam blok verisi. Daha yüksek bant genişliği, indeksleyiciler ve analitik için kullanışlı.
Slot Abonelikleri
Filtre Parametreleri
| Parametre | Tür | Açıklama |
|---|
filterByCommitment | boolean | true olduğunda, yalnızca aboneliğin taahhüt düzeyiyle eşleşen slot güncellemelerini yayınlar. false (varsayılan) olduğunda, tüm taahhüt düzeyleri için güncellemeler yayınlar. |
interslotUpdates | boolean | true olduğunda, yalnızca slot sınırlarında değil, slot içi durum değişikliklerini de yayınlar. Ayrıntılı gerçek zamanlı izleme için kullanışlı. |
Örnek: Onaylanmış Slotları Takip Etme
import Client, { CommitmentLevel, SubscribeRequest } from "@triton-one/yellowstone-grpc";
const GRPC_URL = "https://your-endpoint.grpc.orbitflare.com";
const X_TOKEN = "YOUR_GRPC_TOKEN";
const client = new Client(GRPC_URL, X_TOKEN, {
"grpc.max_receive_message_length": 64 * 1024 * 1024,
});
async function main() {
const stream = await client.subscribe();
const streamClosed = new Promise<void>((resolve, reject) => {
stream.on("error", (error) => { reject(error); stream.end(); });
stream.on("end", () => resolve());
stream.on("close", () => resolve());
});
stream.on("data", (data) => {
if (data.slot) {
const { slot, parent, status } = data.slot;
console.log(`Slot ${slot} (parent: ${parent}) — status: ${status}`);
} else if (data.pong) {
console.log("Pong received");
}
});
const request: SubscribeRequest = {
slots: {
slotUpdates: {
filterByCommitment: true,
},
},
commitment: CommitmentLevel.CONFIRMED,
accounts: {},
accountsDataSlice: [],
transactions: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
entry: {},
ping: { id: 1 },
};
await new Promise<void>((resolve, reject) => {
stream.write(request, (err) => {
if (err == null) resolve(); else reject(err);
});
});
setInterval(() => {
stream.write({ ping: { id: 1 }, accounts: {}, accountsDataSlice: [], transactions: {}, transactionsStatus: {}, slots: {}, blocks: {}, blocksMeta: {}, entry: {} }, () => {});
}, 30_000);
await streamClosed;
}
main();
Blok Abonelikleri
Filtre Parametreleri
| Parametre | Tür | Açıklama |
|---|
accountInclude | string[] | Bloklar içindeki işlemleri ve hesap güncellemelerini yalnızca bu hesapları içerecek şekilde filtrele. |
includeTransactions | boolean | Her blok güncellemesine tam işlem verisi dahil et. |
includeAccounts | boolean | Her blok güncellemesine hesap durumu güncellemeleri dahil et. |
includeEntries | boolean | Her blok güncellemesine girişler (yürütme birimleri) dahil et. |
includeTransactions: true ve hesap filtresi olmayan blok abonelikleri çok yüksek veri hacimleri üretir. Akışı önem verdiğiniz hesaplarla daraltmak için accountInclude kullanın veya sürekli verim için özel bir düğümle birleştirin.
Örnek: İşlemlerle Blok Akışı
import Client, { CommitmentLevel, SubscribeRequest } from "@triton-one/yellowstone-grpc";
const client = new Client(
"https://your-endpoint.grpc.orbitflare.com",
"YOUR_GRPC_TOKEN",
{ "grpc.max_receive_message_length": 1024 * 1024 * 1024 }
);
async function main() {
const stream = await client.subscribe();
const streamClosed = new Promise<void>((resolve, reject) => {
stream.on("error", (error) => { reject(error); stream.end(); });
stream.on("end", () => resolve());
stream.on("close", () => resolve());
});
stream.on("data", (data) => {
if (data.block) {
const { block } = data;
console.log(`Block slot: ${block.slot}`);
console.log(` Blockhash: ${block.blockhash}`);
console.log(` Transactions: ${block.transactions?.length ?? 0}`);
}
});
const request: SubscribeRequest = {
blocks: {
blockStream: {
accountInclude: [
"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8", // Raydium AMM
],
includeTransactions: true,
includeAccounts: false,
includeEntries: false,
},
},
commitment: CommitmentLevel.CONFIRMED,
accounts: {},
accountsDataSlice: [],
transactions: {},
transactionsStatus: {},
slots: {},
blocksMeta: {},
entry: {},
ping: { id: 1 },
};
await new Promise<void>((resolve, reject) => {
stream.write(request, (err) => {
if (err == null) resolve(); else reject(err);
});
});
setInterval(() => {
stream.write({ ping: { id: 1 }, accounts: {}, accountsDataSlice: [], transactions: {}, transactionsStatus: {}, slots: {}, blocks: {}, blocksMeta: {}, entry: {} }, () => {});
}, 30_000);
await streamClosed;
}
main();
İşlem yükü olmadan hafif blok başlıkları (slot, blockhash, blok zamanı) almak için blocksMeta kullanın:
const request: SubscribeRequest = {
blocksMeta: {
blockMeta: {},
},
commitment: CommitmentLevel.FINALIZED,
accounts: {},
accountsDataSlice: [],
transactions: {},
transactionsStatus: {},
slots: {},
blocks: {},
entry: {},
};
Slotlar ve Bloklar Arasında Seçim
| İhtiyaç | Kullanım |
|---|
| Bir slot’un ne zaman kesinleştiğini tespit etme | Slot aboneliği (filterByCommitment: true) |
| Blok yüksekliği ilerlemesini takip etme | Slot aboneliği |
| Bir bloktaki tüm işlemleri indeksleme | Blok aboneliği (includeTransactions: true) |
| Blok başına hesap durum değişikliklerini izleme | Blok aboneliği (includeAccounts: true) |
| Minimum gecikme konsensüs sinyali | processed durumunda slot aboneliği |
| Tam arşiv kalitesinde blok verisi | finalized durumunda blok aboneliği |