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

> JSON-RPC client with retry, failover, and typed helpers for common Solana methods.

## Install

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

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

## Building the client

Here's a client with every option set:

```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()
```

Most of these have sensible defaults. A minimal setup:

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

Every method takes a `context.Context`, so pass a context with a deadline to bound a call:

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

### Builder methods

**`.URL(url)`** - The primary endpoint to send requests to. If not set, the SDK checks the `ORBITFLARE_RPC_URL` environment variable.

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

**`.URLs(urls...)`** - Set the primary and all fallbacks in one call. The first element is the primary, the rest are fallbacks.

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

**`.FallbackURL(url)`** - Add a single fallback endpoint. Call multiple times to add several. When the primary fails, the SDK tries fallbacks in order.

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

**`.FallbackURLs(urls...)`** - Same as `FallbackURL` but takes several at once.

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

**`.APIKey(key)`** - Your OrbitFlare license key. If not set, the SDK checks `ORBITFLARE_LICENSE_KEY` from the environment. The key is injected into the URL at request time, never stored in the endpoint, and never printed in logs or errors.

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

**`.Commitment(level)`** - Default commitment level used for all typed helpers. Options: `"processed"`, `"confirmed"`, `"finalized"`. Defaults to `"confirmed"`.

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

**`.Retry(policy)`** - Controls how the SDK retries failed requests. `InitialDelay` is the wait before the first retry. `Multiplier` scales the delay on each attempt. `MaxDelay` caps the backoff. `MaxAttempts` limits total retries (0 means infinite). Defaults: 100ms initial, 30s max, 2x multiplier, infinite attempts.

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

**`.Timeout(duration)`** - HTTP timeout for each individual request. Defaults to 30 seconds.

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

**`.Logger(logger)`** - A `*slog.Logger` for request retries and failovers. When unset, logging is controlled by the `ORBITFLARE_LOG` environment variable (`trace|debug|info|warn|error|silent`, default `silent`).

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

## Available RPC methods

Typed helpers return Go values; everything else returns `json.RawMessage` you can unmarshal into your own types.

### `GetSlot(ctx)`

Returns the current slot number.

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

### `GetBalance(ctx, address)`

Returns the balance in lamports for an account.

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

### `GetAccountInfo(ctx, address)`

Returns the full account data as `json.RawMessage`, or nil if the account doesn't exist. Data is base64-encoded.

```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)`

Fetches multiple accounts in one call. Automatically chunks into batches of 100 (Solana's per-request limit), so you can pass any number of addresses.

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

### `GetLatestBlockhash(ctx)`

Returns the most recent blockhash and the last block height it's valid for.

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

### `GetTransaction(ctx, signature)`

Fetches a confirmed transaction by its signature. Returns the full transaction with metadata as `json.RawMessage`.

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

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

Returns recent transaction signatures for an address, newest first.

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

### `GetProgramAccounts(ctx, programID)`

Returns all accounts owned by a program. Can return a lot of data.

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

### `GetRecentPrioritizationFees(ctx, addresses)`

Returns recent priority fees for a set of accounts. Useful for estimating compute unit pricing.

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

### `SendTransaction(ctx, txBase64)`

Sends a signed transaction to the network. Takes a base64-encoded serialized transaction. Returns the transaction signature.

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

### `SimulateTransaction(ctx, txBase64)`

Simulates a transaction without submitting it. Returns logs, compute units consumed, and any errors as `json.RawMessage`.

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

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

Returns token accounts for a wallet. Pass either a specific mint or a token program ID. If both are empty strings, defaults to the SPL Token program.

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

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

OrbitFlare-specific method that combines `getSignaturesForAddress` and `getTransaction` into one call. Returns a `GetTransactionsResult` with the `Data` slice and an optional `PaginationToken` for fetching the next page.

Supports four detail levels (`signatures`, `none`, `accounts`, `full`), bidirectional sorting, time/slot filtering, status filtering, and token account inclusion. `options` may be nil for defaults.

```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 {
    // fetch next page by setting PaginationToken on the next call
}
```

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

Call any RPC method by name. The SDK builds the JSON-RPC envelope, handles retry and failover, and returns the `result` field as `json.RawMessage`.

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

### `RequestRaw(ctx, body)`

Send a raw JSON-RPC body string. Same retry and failover as everything else.

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

## Full example

A program that checks the state of the network, fetches a wallet's SOL balance, and looks up recent transactions.

```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])
    }
}
```
