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

# RPC-клиент

> JSON-RPC-клиент с повторными попытками, отказоустойчивостью и типизированными помощниками для распространённых методов Solana.

## Установка

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

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

## Сборка клиента

Клиент со всеми заданными опциями:

```go theme={null}
import (
    "time"

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

client, err := rpc.NewBuilder().
    URL("http://ny.rpc.orbitflare.com").
    FallbackURL("http://fra.rpc.orbitflare.com").
    FallbackURL("http://ams.rpc.orbitflare.com").
    APIKey("ORBIT-XXXXXX-NNNNNN-NNNNNN").
    Commitment("confirmed").
    Retry(orbitflare.RetryPolicy{
        InitialDelay: 100 * time.Millisecond,
        MaxDelay:     30 * time.Second,
        Multiplier:   2.0,
        MaxAttempts:  5,
    }).
    Timeout(30 * time.Second).
    Build()
```

У большинства из них есть разумные значения по умолчанию. Минимальная настройка:

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

Каждый метод принимает `context.Context`, поэтому передайте контекст с крайним сроком, чтобы ограничить вызов:

```go theme={null}
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
```

### Методы билдера

**`.URL(url)`** - Основной эндпоинт для отправки запросов. Если не задан, SDK читает переменную окружения `ORBITFLARE_RPC_URL`.

```go theme={null}
.URL("http://ny.rpc.orbitflare.com")
```

**`.URLs(urls...)`** - Задать основной и все резервные эндпоинты одним вызовом. Первый элемент - основной, остальные - резервные.

```go theme={null}
.URLs("http://ny.rpc.orbitflare.com", "http://fra.rpc.orbitflare.com", "http://ams.rpc.orbitflare.com")
```

**`.FallbackURL(url)`** - Добавить один резервный эндпоинт. Вызывайте несколько раз, чтобы добавить несколько. При сбое основного SDK перебирает резервные по порядку.

```go theme={null}
.FallbackURL("http://fra.rpc.orbitflare.com").
FallbackURL("http://ams.rpc.orbitflare.com")
```

**`.FallbackURLs(urls...)`** - То же, что `FallbackURL`, но принимает сразу несколько.

```go theme={null}
.FallbackURLs("http://fra.rpc.orbitflare.com", "http://ams.rpc.orbitflare.com")
```

**`.APIKey(key)`** - Ваш лицензионный ключ OrbitFlare. Если не задан, SDK читает `ORBITFLARE_LICENSE_KEY` из окружения. Ключ подставляется в URL во время запроса, никогда не хранится в эндпоинте и не попадает в логи или ошибки.

```go theme={null}
.APIKey("ORBIT-XXXXXX-NNNNNN-NNNNNN")
```

**`.Commitment(level)`** - Уровень commitment по умолчанию для всех типизированных помощников. Варианты: `"processed"`, `"confirmed"`, `"finalized"`. По умолчанию `"confirmed"`.

```go theme={null}
.Commitment("finalized")
```

**`.Retry(policy)`** - Управляет тем, как SDK повторяет неудавшиеся запросы. `InitialDelay` - ожидание перед первой повторной попыткой. `Multiplier` масштабирует задержку на каждой попытке. `MaxDelay` ограничивает backoff. `MaxAttempts` ограничивает общее число повторов (0 - бесконечно). По умолчанию: 100 мс начальная, 30 с максимум, множитель 2x, бесконечно.

```go theme={null}
.Retry(orbitflare.RetryPolicy{
    InitialDelay: 200 * time.Millisecond,
    MaxDelay:     15 * time.Second,
    Multiplier:   2.0,
    MaxAttempts:  5,
})
```

**`.Timeout(duration)`** - HTTP-таймаут для каждого отдельного запроса. По умолчанию 30 секунд.

```go theme={null}
.Timeout(10 * time.Second)
```

**`.Logger(logger)`** - `*slog.Logger` для повторов и отказоустойчивости запросов. Если не задан, логирование управляется переменной окружения `ORBITFLARE_LOG` (`trace|debug|info|warn|error|silent`, по умолчанию `silent`).

```go theme={null}
.Logger(slog.New(slog.NewTextHandler(os.Stderr, nil)))
```

## Доступные методы RPC

Типизированные помощники возвращают значения Go; всё остальное возвращает `json.RawMessage`, который вы можете разобрать в собственные типы.

### `GetSlot(ctx)`

Возвращает номер текущего слота.

```go theme={null}
slot, err := client.GetSlot(ctx) // uint64
```

### `GetBalance(ctx, address)`

Возвращает баланс аккаунта в lamports.

```go theme={null}
lamports, err := client.GetBalance(ctx, "So11111111111111111111111111111111111111112") // uint64
sol := float64(lamports) / 1_000_000_000
```

### `GetAccountInfo(ctx, address)`

Возвращает полные данные аккаунта в виде `json.RawMessage` или nil, если аккаунт не существует. Данные в base64.

```go theme={null}
raw, err := client.GetAccountInfo(ctx, "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")
if raw != nil {
    var info struct {
        Owner    string `json:"owner"`
        Lamports uint64 `json:"lamports"`
    }
    json.Unmarshal(raw, &info)
}
```

### `GetMultipleAccounts(ctx, addresses)`

Получает несколько аккаунтов за один вызов. Автоматически разбивает на пакеты по 100 (лимит Solana на запрос), поэтому можно передать любое количество адресов.

```go theme={null}
accounts, err := client.GetMultipleAccounts(ctx, []string{"addr1", "addr2", "addr3"}) // []json.RawMessage
```

### `GetLatestBlockhash(ctx)`

Возвращает самый свежий blockhash и последнюю высоту блока, до которой он действителен.

```go theme={null}
blockhash, lastValid, err := client.GetLatestBlockhash(ctx) // (string, uint64)
```

### `GetTransaction(ctx, signature)`

Получает подтверждённую транзакцию по её подписи. Возвращает полную транзакцию с метаданными в виде `json.RawMessage`.

```go theme={null}
raw, err := client.GetTransaction(ctx, "5K8F2j...")
```

### `GetSignaturesForAddress(ctx, address, limit)`

Возвращает недавние подписи транзакций для адреса, начиная с новых.

```go theme={null}
sigs, err := client.GetSignaturesForAddress(ctx, "So111...", 10) // []json.RawMessage
```

### `GetProgramAccounts(ctx, programID)`

Возвращает все аккаунты, принадлежащие программе. Может вернуть много данных.

```go theme={null}
accounts, err := client.GetProgramAccounts(ctx, "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
```

### `GetRecentPrioritizationFees(ctx, addresses)`

Возвращает недавние приоритетные комиссии для набора аккаунтов. Полезно для оценки цены compute unit.

```go theme={null}
fees, err := client.GetRecentPrioritizationFees(ctx, []string{"6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"})
```

### `SendTransaction(ctx, txBase64)`

Отправляет подписанную транзакцию в сеть. Принимает сериализованную транзакцию в base64. Возвращает подпись транзакции.

```go theme={null}
signature, err := client.SendTransaction(ctx, txBase64) // string
```

### `SimulateTransaction(ctx, txBase64)`

Симулирует транзакцию без отправки. Возвращает логи, потреблённые compute units и любые ошибки в виде `json.RawMessage`.

```go theme={null}
raw, err := client.SimulateTransaction(ctx, txBase64)
```

### `GetTokenAccountsByOwner(ctx, owner, mint, programID)`

Возвращает токен-аккаунты кошелька. Передайте конкретный mint или ID токен-программы. Если обе строки пустые, используется программа SPL Token.

```go theme={null}
tokens, err := client.GetTokenAccountsByOwner(ctx, "wallet_address", "", "")
```

### `GetTransactionsForAddress(ctx, address, options)`

Метод, специфичный для OrbitFlare, объединяющий `getSignaturesForAddress` и `getTransaction` в один вызов. Возвращает `GetTransactionsResult` со срезом `Data` и опциональным `PaginationToken` для получения следующей страницы.

Поддерживает четыре уровня детализации (`signatures`, `none`, `accounts`, `full`), двунаправленную сортировку, фильтрацию по времени/слоту, фильтрацию по статусу и включение токен-аккаунтов. `options` может быть nil для значений по умолчанию.

```go theme={null}
details, order, status := "full", "asc", "succeeded"
var limit uint32 = 100
gte, lte := int64(1704067200), int64(1706745600)

result, err := client.GetTransactionsForAddress(ctx, "address", &rpc.GetTransactionsOptions{
    TransactionDetails: &details,
    Limit:              &limit,
    SortOrder:          &order,
    Filters: &rpc.GetTransactionsFilters{
        Status:    &status,
        BlockTime: &rpc.RangeFilter[int64]{Gte: &gte, Lte: &lte},
    },
})

for _, tx := range result.Data {
    _ = tx // json.RawMessage
}
if result.PaginationToken != nil {
    // получить следующую страницу, задав PaginationToken в следующем вызове
}
```

### `Request(ctx, method, params)`

Вызвать любой RPC-метод по имени. SDK строит конверт JSON-RPC, выполняет повторы и отказоустойчивость и возвращает поле `result` в виде `json.RawMessage`.

```go theme={null}
epoch, err := client.Request(ctx, "getEpochInfo", []any{})
inflation, err := client.Request(ctx, "getInflationRate", []any{})
```

### `RequestRaw(ctx, body)`

Отправить сырую строку тела JSON-RPC. Те же повторы и отказоустойчивость, что и у всего остального.

```go theme={null}
result, err := client.RequestRaw(ctx, `{"jsonrpc":"2.0","id":1,"method":"getHealth","params":[]}`)
```

## Полный пример

Программа, которая проверяет состояние сети, получает баланс SOL кошелька и ищет недавние транзакции.

```go theme={null}
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

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

func main() {
    client, err := rpc.NewBuilder().
        URL("http://ny.rpc.orbitflare.com").
        FallbackURL("http://fra.rpc.orbitflare.com").
        Commitment("confirmed").
        Build()
    if err != nil {
        log.Fatal(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
    defer cancel()

    wallet := "CKs1E69a2e9TmH4mKKLrXFF8kD3ZnwKjoEuXa6sz9WqX"

    slot, _ := client.GetSlot(ctx)
    blockhash, _, _ := client.GetLatestBlockhash(ctx)
    fmt.Printf("network slot: %d\nblockhash: %s\n", slot, blockhash)

    balance, _ := client.GetBalance(ctx, wallet)
    fmt.Printf("\n%s\n  SOL: %.4f\n", wallet, float64(balance)/1_000_000_000)

    sigs, _ := client.GetSignaturesForAddress(ctx, wallet, 5)
    fmt.Println("\nrecent transactions:")
    for _, raw := range sigs {
        var sig struct {
            Signature string `json:"signature"`
            Slot      uint64 `json:"slot"`
            Err       any    `json:"err"`
        }
        json.Unmarshal(raw, &sig)
        status := "ok"
        if sig.Err != nil {
            status = "failed"
        }
        fmt.Printf("  %d %s %s\n", sig.Slot, status, sig.Signature[:20])
    }
}
```
