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

# JetStream İstemcisi

> OrbitFlare'ın çözümlenmiş shred'leri, işlem filtreleriyle gRPC akışları olarak sunulur.

## Kurulum

```bash theme={null}
go get github.com/orbitflare/orbitflare-sdk-go
```

```go theme={null}
import "github.com/orbitflare/orbitflare-sdk-go/jetstream"
```

## İstemciyi oluşturma

```go theme={null}
client, err := jetstream.NewBuilder().
    URL("http://ny.jetstream.orbitflare.com").
    FallbackURL("http://fra.jetstream.orbitflare.com").
    Build()
```

URL, `ORBITFLARE_JETSTREAM_URL` ortam değişkenine düşer. Tüm builder yöntemleri [gRPC istemcisi](/tr/sdk/go-grpc) ile aynıdır - aynı varsayılanlar, aynı davranış (`Retry`, `Timeout`, `Keepalive`, `PingInterval`, `MaxMissedPongs`, `ChannelCapacity`, `Logger`).

## Abonelik oluşturma

JetStream, işlem filtrelerini destekler (slot, blok veya commitment yoktur - bunlar Yellowstone'a özgüdür). Her `TransactionFilter`; `AccountInclude`, `AccountExclude` ve `AccountRequired` sunar.

```go theme={null}
request := jetstream.NewSubscribeRequestBuilder().
    Transactions("raydium", jetstream.NewTransactionFilter().
        AccountInclude("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8")).
    Transactions("pumpfun", jetstream.NewTransactionFilter().
        AccountInclude("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")).
    Build()
```

## Akışı okuma

`Subscribe`, bir `*jetstream.Stream` döndürür. `Next(ctx)` çağırın:

```go theme={null}
stream := client.Subscribe(request)
defer stream.Close()

for {
    update, err := stream.Next(ctx)
    if errors.Is(err, io.EOF) {
        break
    }
    if err != nil {
        break
    }

    if tx := update.GetTransaction(); tx != nil {
        // tx.GetSlot() - slot numarası
        // tx.GetTransaction() - signature, account_keys, instructions içeren işlem bilgisi
    }
}
```

Kapatma, birden çok akış, yeniden bağlanma ve ping/pong, [gRPC istemcisi](/tr/sdk/go-grpc) ile birebir aynı çalışır.

## Tam örnek

Raydium AMM takaslarını izleyip her işlemin slotunu yazdıran bir akış.

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "io"
    "log"

    "github.com/orbitflare/orbitflare-sdk-go/jetstream"
)

func main() {
    client, err := jetstream.NewBuilder().
        URL("http://ny.jetstream.orbitflare.com").
        Build()
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    request := jetstream.NewSubscribeRequestBuilder().
        Transactions("raydium", jetstream.NewTransactionFilter().
            AccountInclude("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8")).
        Build()

    stream := client.Subscribe(request)
    defer stream.Close()

    ctx := context.Background()
    var count int
    fmt.Println("streaming raydium txs...")

    for {
        update, err := stream.Next(ctx)
        if errors.Is(err, io.EOF) {
            return
        }
        if err != nil {
            log.Fatal(err)
        }
        if tx := update.GetTransaction(); tx != nil {
            count++
            fmt.Printf("#%d slot=%d\n", count, tx.GetSlot())
        }
    }
}
```

## JetStream v2

JetStream v2 (`github.com/orbitflare/orbitflare-sdk-go/jetstream/v2`), v1 ile **aynı uç noktalarda ve kimlik doğrulamada** çalışır ve tamamen eklemelidir: v1 değişmeden çalışmaya devam eder. v2'nin eklediği:

* **Çalışma zamanında yönetilen filtreler** - canlı bir akışta yeniden bağlanmadan filtre ekleyip kaldırma.
* **Mesaj başına sıra numaraları** - her yanıt monoton bir `Sequence` taşır; böylece atlanan mesajları tespit edebilirsiniz.
* **İsteğe bağlı zenginleştirme** - işlem başına ücret ödeyeni, program id'lerini, compute unit fiyatını, hesaplama sınırını, çözümlenmiş adres tablosu adreslerini ve daha fazlasını isteyin.
* **Slot yaşam döngüsü olayları** - slot alive/complete/dead olaylarının ayrı bir sunucu akışı.

v2 istemcisi `jetstream/v2` altındadır. Builder, v1 ile aynıdır (aynı yöntemler, varsayılanlar, `ORBITFLARE_JETSTREAM_URL` ortam değişkeni ve yedek uç nokta geçişi):

```go theme={null}
import jetstreamv2 "github.com/orbitflare/orbitflare-sdk-go/jetstream/v2"

client, err := jetstreamv2.NewBuilder().
    URL("http://ny.jetstream.orbitflare.com").
    FallbackURL("http://fra.jetstream.orbitflare.com").
    Build()
```

### Tiplenmiş filtreler oluşturma

Her filtre, istemcinin seçtiği bir id'ye (`.WithID()` ile) sahip bir `TransactionFilter`'dır. Bu id, eşleşen her işlemde ve filtre doğrulama onayında geri döner; böylece eşleşmeleri ilişkilendirebilir ve filtreyi sonradan kaldırabilirsiniz.

```go theme={null}
filter := jetstreamv2.NewTransactionFilter().
    AccountInclude("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P").
    IncludeEnrichment(true).
    WithID("pumpfun")
```

Bir filtre, `AccountInclude`, `AccountExclude` veya `AccountRequired`'dan en az birini ayarlamalıdır; boş (her şeyle eşleşen) filtreler reddedilir. `IncludeEnrichment` isteğe bağlıdır (varsayılan kapalı) ve tüm aboneliğe uygulanır: etkin herhangi bir filtre onu etkinleştirirse, aldığınız her işlem zenginleştirilir.

### İşlemlere abone olma

```go theme={null}
stream := client.SubscribeTransactions(filter)
defer stream.Close()

for {
    resp, err := stream.Next(ctx)
    if errors.Is(err, io.EOF) {
        break
    }
    if err != nil {
        break
    }

    switch {
    case resp.GetTransaction() != nil:
        ft := resp.GetTransaction()
        // resp.GetSequence() - akış başına monoton sıra numarası
        // ft.GetFilterIds() - bu işlemin hangi filtrelerinizle eşleştiği
        if tx := ft.GetTransaction(); tx != nil {
            // tx.GetSlot(), tx.GetSignature(), tx.GetAccountKeys(), tx.GetInstructions()
            // zenginleştirme (yalnızca IncludeEnrichment ayarlıysa): tx.GetFeePayer(),
            //   tx.GetProgramIds(), tx.GetComputeUnitPrice(), tx.GetComputeLimit(),
            //   tx.GetLoadedWritableAddresses(), tx.GetLoadedReadonlyAddresses()
            fmt.Printf("seq=%d slot=%d\n", resp.GetSequence(), tx.GetSlot())
        }
    case resp.GetFilterValidation() != nil:
        r := resp.GetFilterValidation() // her ekleme/kaldırmadan sonra filtre başına bir tane
        fmt.Printf("filter %s accepted=%v %s\n", r.GetFilterId(), r.GetAccepted(), r.GetRejectionReason())
    case resp.GetHeartbeat() != nil:
        // resp.GetHeartbeat().GetServerTsMs() - sunucu duvar saati, epoch'tan bu yana ms
    case resp.GetPong() != nil:
        // resp.GetPong().GetPingId()
    }
}
```

### Canlı bir akışta filtreleri yönetme

Akıştan bir tutamaç alın ve yeniden bağlanmadan filtre ekleyip kaldırın. Kaldırma, `.WithID()` ile atadığınız filtre id'sine başvurur.

```go theme={null}
handle := stream.Handle()

handle.AddFilters([]*jetstreamv2.TxFilter{
    jetstreamv2.NewTransactionFilter().
        AccountInclude("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8").
        WithID("raydium"),
})

handle.RemoveFilters([]string{"pumpfun"})
```

`stream.AddFilters(...)` ve `stream.RemoveFilters(...)`, aynı işlemin kısayollarıdır. Akış kapatılmışsa her biri bir hata döndürür.

### Slot yaşam döngüsü olayları

`SubscribeSlots()`, ayrı bir sunucu akışıdır ve filtre almaz.

```go theme={null}
slots := client.SubscribeSlots()
defer slots.Close()

for {
    event, err := slots.Next(ctx)
    if errors.Is(err, io.EOF) {
        break
    }
    if err != nil {
        break
    }
    // event.GetSlot(), event.GetStatus() (bir SlotStatus enum'u: alive / complete / dead),
    // event.GetParentSlot(), event.GetCurrentLeader(), event.GetSequence()
    fmt.Printf("slot=%d status=%s\n", event.GetSlot(), event.GetStatus())
}
```

### Sağlık probları

`GetVersion(ctx)` ve `Ping(ctx, count)`, akışlarla aynı yedek uç nokta geçişine sahip birer unary çağrıdır.

```go theme={null}
version, err := client.GetVersion(ctx)
count, err := client.Ping(ctx, 7)
```

Tam protobuf spesifikasyonu, mesaj biçimleri, zenginleştirme alanları ve slot durumları için [JetStream v2 Protokol Referansı](/tr/data-streaming/jetstream-v2-reference)'na bakın.
