Solana gRPC

Yellowstone gRPC enables real-time Solana blockchain data streaming through gRPC interfaces. Stream accounts, transactions, blocks, and slots with low latency and efficient bidirectional communication.

Getting Started

Endpoint

  • api.1inch.com:443

Authentication

All requests must include an API key in the authorization header:

Bash
1
Authorization: Bearer YOUR_API_KEY

Get your API key here.

Protocol Reference

The protocol uses Protocol Buffers. View the geyser.proto definition for complete specifications.

Key Methods:

  • Subscribe - Bidirectional stream for real-time updates
  • GetLatestBlockhash, GetBlockHeight, GetSlot
  • IsBlockhashValid, Ping, GetVersion

Setup

Download geyser.proto and solana-storage.proto to your project.

Typescript Usage Examples

Install dependencies

Bash
1
npm install @grpc/grpc-js @grpc/proto-loader

Example 1: Simple GetSlot call

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import * as grpc from "@grpc/grpc-js";
import * as protoLoader from "@grpc/proto-loader";

// Load proto file
const packageDefinition = protoLoader.loadSync("path/to/geyser.proto", {
  longs: String // Convert uint64 to strings for easier handling
});
const geyserProto = grpc.loadPackageDefinition(packageDefinition).geyser;

// Create client with TLS
const client = new geyserProto.Geyser("api.1inch.com:443", grpc.credentials.createSsl());

// Set authorization metadata
const metadata = new grpc.Metadata();
metadata.add("authorization", "Bearer YOUR_API_KEY");

// Call GetSlot
client.getSlot({}, metadata, (err, response) => {
  if (err) {
    console.error("Error:", err);
    return;
  }
  console.log("Current slot:", response.slot);
});

Example 2: Subscribe to account updates

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import * as grpc from "@grpc/grpc-js";
import * as protoLoader from "@grpc/proto-loader";

const packageDefinition = protoLoader.loadSync("path/to/geyser.proto", {
  longs: String
});
const geyserProto = grpc.loadPackageDefinition(packageDefinition).geyser;

const client = new geyserProto.Geyser("api.1inch.com:443", grpc.credentials.createSsl());

const metadata = new grpc.Metadata();
metadata.add("authorization", "Bearer YOUR_API_KEY");

// Create bidirectional stream
const stream = client.subscribe(metadata);

// Send subscription request
stream.write({
  accounts: {
    client: {
      account: ["ACCOUNT_PUBKEY_HERE"],
      owner: [],
      filters: []
    }
  }
});

// Handle updates
stream.on("data", (data) => {
  if (data.account) {
    console.log("Account update:", {
      slot: data.account.slot,
      lamports: data.account.account.lamports
    });
  }
});

stream.on("error", (err) => console.error("Error:", err));
stream.on("end", () => console.log("Stream ended"));

Go Usage Examples

Install dependencies

Bash
1
2
3
4
go get google.golang.org/grpc google.golang.org/grpc/credentials

# generate bindings
protoc --go_out=. --go-grpc_out=. geyser.proto

Example 1: Simple GetSlot call

GO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package main

import (
    "context"
    "crypto/tls"
    "log"

    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "google.golang.org/grpc/metadata"

    pb "your/proto/package" // Generated from geyser.proto
)

func main() {
    // Connect with TLS
    creds := credentials.NewTLS(&tls.Config{
        ServerName: "api.1inch.com",
    })
    conn, err := grpc.Dial("api.1inch.com:443", grpc.WithTransportCredentials(creds))
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    client := pb.NewGeyserClient(conn)

    // Add authorization
    ctx := metadata.AppendToOutgoingContext(
        context.Background(),
        "authorization", "Bearer YOUR_API_KEY",
    )

    // Call GetSlot
    resp, err := client.GetSlot(ctx, &pb.GetSlotRequest{})
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Current slot: %d", resp.Slot)
}

Example 2: Subscribe to account updates

GO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main

import (
    "context"
    "crypto/tls"
    "fmt"
    "io"
    "log"

    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "google.golang.org/grpc/metadata"

    pb "your/proto/package"
)

func main() {
    creds := credentials.NewTLS(&tls.Config{
        ServerName: "api.1inch.com",
    })
    conn, err := grpc.Dial("api.1inch.com:443", grpc.WithTransportCredentials(creds))
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    client := pb.NewGeyserClient(conn)

    ctx := metadata.AppendToOutgoingContext(
        context.Background(),
        "authorization", "Bearer YOUR_API_KEY",
    )

    stream, err := client.Subscribe(ctx)
    if err != nil {
        log.Fatal(err)
    }

    // Send subscription request
    err = stream.Send(&pb.SubscribeRequest{
        Accounts: map[string]*pb.SubscribeRequestFilterAccounts{
            "client": {
                Account: []string{"ACCOUNT_PUBKEY_HERE"},
                Owner:   []string{},
                Filters: []*pb.SubscribeRequestFilterAccountsFilter{},
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // Receive updates
    for {
        update, err := stream.Recv()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }

        if account := update.GetAccount(); account != nil {
            fmt.Printf("Account update: slot=%d, lamports=%d\n",
                account.Slot, account.Account.Lamports)
        }
    }
}

Additional Resources

Did you find what you need?