> ## 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.

# gRPC İstemcisi (Yellowstone)

> Otomatik yeniden bağlanma, ping/pong canlılık denetimi ve YAML yapılandırması ile Yellowstone Geyser akışı.

## Kurulum

```bash theme={null}
npm install @orbitflare/sdk @grpc/grpc-js yaml
```

`@grpc/grpc-js` ve `yaml` isteğe bağlı peer bağımlılıklardır. Yalnızca gRPC istemcisini (veya YAML yapılandırmasını) kullanıyorsanız kurun.

## İstemciyi oluşturma

Tüm seçeneklerin ayarlı olduğu bir istemci:

```ts theme={null}
import { GeyserClientBuilder } from '@orbitflare/sdk/grpc';
import type { RetryPolicy } from '@orbitflare/sdk';

const client = new GeyserClientBuilder()
  .url('http://ny.rpc.orbitflare.com:10000')
  .fallbackUrl('http://fra.rpc.orbitflare.com:10000')
  .retry({
    initialDelayMs: 100,
    maxDelayMs: 30_000,
    multiplier: 2.0,
    maxAttempts: 0,
  })
  .timeoutSecs(30)
  .keepaliveSecs(60)
  .pingIntervalSecs(10)
  .maxMissedPongs(3)
  .channelCapacity(4096)
  .build();
```

Minimal kurulum:

```ts theme={null}
const client = new GeyserClientBuilder()
  .url('http://ny.rpc.orbitflare.com:10000')
  .build();
```

### Builder yöntemleri

**`.url(url)`** - Birincil gRPC uç noktası. `ORBITFLARE_GRPC_URL` ortam değişkenine düşer.

```ts theme={null}
.url('http://ny.rpc.orbitflare.com:10000')
```

**`.urls([...])`** - Tek çağrıda birincil + yedekler. İlk eleman birincildir.

```ts theme={null}
.urls(['http://ny.rpc.orbitflare.com:10000', 'http://fra.rpc.orbitflare.com:10000'])
```

**`.fallbackUrl(url)` / `.fallbackUrls([...])`** - Yedek uç noktalar ekler. Bağlantı hatasında SDK aralarında döner.

```ts theme={null}
.fallbackUrl('http://fra.rpc.orbitflare.com:10000')
```

**`.retry(policy)`** - Yeniden bağlanma geri çekilmesini denetler. Bağlantı koptuğunda SDK önce `initialDelayMs` bekler, sonra her denemede gecikmeyi iki katına çıkarır (`maxDelayMs` ile sınırlı). `maxAttempts` değerini 0 yaparak sonsuz yeniden deneme ayarlayın. Varsayılan: 100 ms başlangıç, 30 sn üst sınır, 2x çarpan, sonsuz.

```ts theme={null}
.retry({
  initialDelayMs: 200,
  maxDelayMs: 15_000,
  multiplier: 2.0,
  maxAttempts: 0,
})
```

**`.timeoutSecs(n)`** - İstek başına gRPC zaman aşımı. Varsayılan: 30.

```ts theme={null}
.timeoutSecs(15)
```

**`.keepaliveSecs(n)`** - TCP keepalive aralığı. İşletim sistemi bu aralıkta ölü bağlantıları TCP düzeyinde tespit etmek için probe gönderir. Varsayılan: 60.

```ts theme={null}
.keepaliveSecs(30)
```

**`.pingIntervalSecs(n)`** - SDK'nın sunucuya proto düzeyinde `Ping` gönderme sıklığı. Sunucunun `Pong` ile yanıt vermesi beklenir. Varsayılan: 10.

```ts theme={null}
.pingIntervalSecs(15)
```

**`.maxMissedPongs(n)`** - SDK'nın bağlantıyı ölü sayıp yeniden bağlanmadan önce ardışık kaç ping'in yanıtsız kalabileceği. Varsayılan: 3. Varsayılanlarla ölü bağlantı yaklaşık 30 saniye içinde tespit edilir.

```ts theme={null}
.maxMissedPongs(5)
```

**`.channelCapacity(n)`** - Arka plan görevi ile kodunuz arasındaki sınırlı tampon. Olayları tüketmek yavaşsa ve bu dolarsa arka plan görevi sınırsız bellek yemek yerine duraklar. Varsayılan: 4096.

```ts theme={null}
.channelCapacity(8192)
```

## YAML yapılandırması yazma

İstediğiniz filtrelerle bir YAML dosyası oluşturun:

```yaml theme={null}
# grpc.yml
transactions:
  pumpfun:
    vote: false
    failed: false
    account_include:
      - "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
  jupiter:
    vote: false
    failed: false
    account_include:
      - "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"

accounts:
  usdc_mint:
    account:
      - "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
  token_program:
    owner:
      - "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"

slots:
  all:
    filter_by_commitment: true

commitment: confirmed
```

### YAML filtre referansı

**`transactions`** - her giriş adlı bir filtredir. Bir işlem `account_include` adreslerinden herhangi birini içeriyorsa eşleşir. `account_exclude` eşleşmeleri çıkarır. `account_required` listelenen tüm adreslerin bulunmasını gerektirir. `vote` ve `failed` işlem tipine göre filtreler.

**`accounts`** - adresle belirli hesapları izleyin veya `owner` ile bir programa ait tüm hesapları izleyin.

**`slots`** - slot güncellemelerine abone olun. `filter_by_commitment` yalnızca taahhüt düzeyinizdeki güncellemeleri gönderir.

**`commitment`** - `'processed'`, `'confirmed'` veya `'finalized'`. Varsayılan: `'confirmed'`.

YAML `${ENV_VAR}` genişletmesini destekler:

```yaml theme={null}
transactions:
  target:
    account_include:
      - "${TARGET_PROGRAM}"
```

## Olaylara abone olma ve okuma

### YAML'dan

```ts theme={null}
const stream = client.subscribeYaml('grpc.yml');
```

### Programatik olarak

Çalışma zamanında oluşturulan dinamik filtreler için:

```ts theme={null}
import { proto } from '@orbitflare/sdk/proto';

const request: proto.geyser.SubscribeRequest = {
  transactions: {
    target: {
      vote: false,
      failed: false,
      signature: undefined,
      accountInclude: [someAddress],
      accountExclude: [],
      accountRequired: [],
    },
  },
  accounts: {},
  slots: {},
  transactionsStatus: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  accountsDataSlice: [],
  commitment: 1,
  ping: { id: 1 },
};

const stream = client.subscribe(request);
```

### Akışı okuma

Hem `subscribeYaml` hem `subscribe` bir `GeyserStream` döndürür. Bu bir async iterable'dır - `for await` kullanın:

```ts theme={null}
for await (const update of stream) {
  if (update.transaction) {
    // update.transaction.slot - the slot this transaction was in
    // update.transaction.transaction - the transaction info (signature, accounts, instructions, meta)
  } else if (update.account) {
    // update.account.slot - the slot
    // update.account.account - account info (pubkey, lamports, owner, data)
    // update.account.isStartup - true during initial account snapshot
  } else if (update.slot) {
    // update.slot.slot - the slot number
    // update.slot.status - processed, confirmed, finalized, etc.
  } else if (update.blockMeta) {
    // update.blockMeta.slot, update.blockMeta.blockhash, update.blockMeta.parentSlot
    // update.blockMeta.executedTransactionCount
  }
}
```

Veya tek seferde bir olay çekmek için doğrudan `await stream.next()` çağırın. Akış kapalıysa `undefined` döner. Yeniden denemeler tükendiyse bir sonraki iterasyon hata fırlatır.

Pong iletileri dahili tüketilir ve akışınızda asla görünmez.

### Kapatma

```ts theme={null}
stream.close();
```

Arka plan görevini anında durdurur.

## Birden çok akış

Tek istemci aynı anda birçok akış çalıştırabilir. Her biri kendi arka plan bağlantısını alır:

```ts theme={null}
const pumpfun = client.subscribeYaml('config/pumpfun.yml');
const raydium = client.subscribeYaml('config/raydium.yml');
const slots = client.subscribeYaml('config/slots.yml');
```

Uç nokta sağlık durumunu paylaşırlar - bir akış başarısız bir uç noktayı karantinaya alırsa diğerleri bir sonraki yeniden bağlanmada onu atlar. Ancak bağlantıları ve yaşam döngüleri tamamen bağımsızdır.

Mevcut bir akıştan gelen veriye dayalı olarak da dahil olmak üzere istediğiniz zaman yeni akışlar başlatabilirsiniz.

## Tam örnek

pump.fun işlemlerini izleyen, imzayı çözen ve her biri için bir özet yazdıran bir akış.

```ts theme={null}
import bs58 from 'bs58';
import { GeyserClientBuilder } from '@orbitflare/sdk/grpc';

async function main() {
  const client = new GeyserClientBuilder()
    .url('http://ny.rpc.orbitflare.com:10000')
    .fallbackUrl('http://fra.rpc.orbitflare.com:10000')
    .build();

  const stream = client.subscribeYaml('grpc.yml');
  let txCount = 0;

  console.log('streaming...');

  for await (const update of stream) {
    if (update.transaction) {
      txCount += 1;
      const info = update.transaction.transaction;
      if (info?.signature) {
        const sig = bs58.encode(info.signature);
        const fee = info.meta?.fee ?? 0n;
        const ixCount = info.transaction?.message?.instructions.length ?? 0;
        console.log(
          `#${txCount} slot=${update.transaction.slot} sig=${sig.slice(0, 16)}... fee=${fee} instructions=${ixCount}`,
        );
      }
    } else if (update.slot) {
      console.log(`slot ${update.slot.slot} (${update.slot.status})`);
    }
  }
}

void main();
```

Bu `grpc.yml` ile:

```yaml theme={null}
transactions:
  pumpfun:
    vote: false
    failed: false
    account_include:
      - "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"

slots:
  all:
    filter_by_commitment: true

commitment: confirmed
```
