Skip to main content

Making Injective Indexer gRPC Requests with Go

Updated on
Sep 17, 2026

Overview

Go is a statically typed, compiled language designed for simple and efficient concurrent applications. Its concurrency model and strong gRPC support make it well suited for blockchain clients and streaming services. Follow the official installation guide to install Go. Verify the installation:

go version

This guide builds a Go client for the Injective Indexer gRPC API, authenticates with x-token, and calls the Explorer service's GetBlocksV2 method. The completed example requests the latest indexed Mainnet block and prints the protobuf response as JSON.

You will:

  1. Install the gRPC and Protocol Buffer tooling.
  2. Download the official Explorer and Exchange proto definitions.
  3. Generate Go client code.
  4. Configure your Quicknode endpoint and token.
  5. Run an authenticated request and verify the response.

Prerequisites

Install protoc and the Go protobuf plugins:

brew install protobuf
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
export PATH="$(go env GOPATH)/bin:$PATH"

The PATH update makes the installed protobuf generators available to protoc in the current shell.

Step 1: Create the project

Create a project and install the Go dependencies:

mkdir injective-indexer-grpc-go
cd injective-indexer-grpc-go
go mod init injective-indexer-grpc
go get google.golang.org/grpc
go get google.golang.org/protobuf
mkdir -p proto/explorer proto/exchange

Step 2: Download the proto definitions

Download the official injective_explorer_rpc.proto and injective_exchange_rpc.proto files:

curl -L \
https://raw.githubusercontent.com/InjectiveLabs/injective-proto/master/all_protos/exchange/injective_explorer_rpc.proto \
-o proto/explorer/injective_explorer_rpc.proto

curl -L \
https://raw.githubusercontent.com/InjectiveLabs/injective-proto/master/all_protos/exchange/injective_exchange_rpc.proto \
-o proto/exchange/injective_exchange_rpc.proto

The upstream files use absolute go_package values. Replace them with module-local package paths before generating code:

sed -i.bak \
's|option go_package = "/injective_explorer_rpcpb";|option go_package = "injective-indexer-grpc/pb/explorer;explorer";|' \
proto/explorer/injective_explorer_rpc.proto

sed -i.bak \
's|option go_package = "/injective_exchange_rpcpb";|option go_package = "injective-indexer-grpc/pb/exchange;exchange";|' \
proto/exchange/injective_exchange_rpc.proto

Step 3: Generate the clients

Generate both clients:

protoc -I proto \
--go_out=. --go_opt=module=injective-indexer-grpc \
--go-grpc_out=. --go-grpc_opt=module=injective-indexer-grpc \
proto/explorer/injective_explorer_rpc.proto \
proto/exchange/injective_exchange_rpc.proto

Step 4: Configure the endpoint and token

Given an HTTP Provider URL in this format:

https://YOUR_ENDPOINT_NAME.injective-mainnet.quiknode.pro/YOUR_TOKEN/

set the gRPC endpoint and token as environment variables. Injective Indexer gRPC uses TLS on port 443:

export QN_GRPC_ENDPOINT="YOUR_ENDPOINT_NAME.injective-mainnet.quiknode.pro:443"
export QN_TOKEN="YOUR_TOKEN"

Injective Indexer gRPC requires x-token authentication.

x-token authentication

Attach the token to the outgoing RPC context:

ctx = metadata.AppendToOutgoingContext(ctx, "x-token", token)

Step 5: Create the application

Create main.go. This runnable example uses x-token authentication:

package main

import (
"context"
"crypto/tls"
"fmt"
"log"
"os"
"time"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/encoding/protojson"

pb "injective-indexer-grpc/pb/explorer"
)

func main() {
endpoint := os.Getenv("QN_GRPC_ENDPOINT")
token := os.Getenv("QN_TOKEN")
if endpoint == "" || token == "" {
log.Fatal("set QN_GRPC_ENDPOINT and QN_TOKEN")
}

creds := credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12})
conn, err := grpc.Dial(endpoint, grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatal(err)
}
defer conn.Close()

ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
ctx = metadata.AppendToOutgoingContext(ctx, "x-token", token)

client := pb.NewInjectiveExplorerRPCClient(conn)
response, err := client.GetBlocksV2(ctx, &pb.GetBlocksV2Request{PerPage: 1})
if err != nil {
log.Fatal(err)
}

data, err := protojson.MarshalOptions{
UseProtoNames: true,
Indent: " ",
}.Marshal(response)
if err != nil {
log.Fatal(err)
}

fmt.Println(string(data))
}

Step 6: Run the application

Download any remaining module dependencies and run the request:

go mod tidy
go run .

Step 7: Verify the response

The request returns the most recently indexed block. Block values change as Injective Mainnet advances, but the response should have this structure. This shortened example is from a live Quicknode response:

{
"paging": {
"next": ["MTgxMDIxMTAw"]
},
"data": [
{
"height": "181021101",
"moniker": "SCV-Security",
"block_hash": "0xd39c44f30e2e45fe5313d9b450e1421f25b88219bc611f493e885dbc58cf07ca",
"num_txs": "3",
"block_unix_timestamp": "1788186602675"
}
]
}

A successful response confirms that TLS, x-token authentication, generated protobuf types, and the Explorer client are configured correctly.

Next steps

Your Go client is now ready to make authenticated requests to the Injective Indexer gRPC API. Explore the Explorer API methods and Exchange API methods to find more methods, request parameters, response fields, and runnable examples.