跳转至主要内容

Making Sui gRPC Requests with Go

更新于
Aug 07, 2026

概述

Go is a statically-typed, compiled language known for its simplicity, efficiency, and strong concurrency support. Follow the official installation guide to install Go. Verify the installation:

go version

Authentication Required for Sui gRPC

To ensure secure access to Sui gRPC, users are required to authenticate themselves. This authentication process is necessary before utilizing any method. Quicknode endpoints consist of two crucial components: the endpoint 以及相应的 token. 用户需要在调用任何方法之前,使用这两个组件配置一个带有身份验证凭据的gRPC 。

Authentication for the Sui gRPC can be handled in two ways:

  1. 基本身份验证
  2. x-token 身份验证

在本文档中,我们将把 getClientWithBasicAuthgetClientWithXToken 用于演示如何处理这些不同身份验证机制的函数。

基本身份验证

getClientWithBasicAuth 该函数演示了如何使用基本身份验证(Basic Authentication)来处理身份验证,该方法会将凭据编码为 base64。以下是该函数的代码实现: getClientWithBasicAuth 功能以及 basicAuth RPC 凭据的实现:

import (
"上下文"
"crypto/tls"
"encoding/base64"
"fmt"
"google.golang.grpc"
"google.golang.grpc"
)

func getClientWithBasicAuth(endpoint, token string) (client.GRPCClient, error) {
target := endpoint + ".sui-mainnet.quiknode.pro:9000" // for TLS connections
conn, err := grpc.Dial(target,
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
grpc.WithPerRPCCredentials(basicAuth{
username: endpoint,
password: token,
}),
)
if err != nil {
return nil, fmt.Errorf("Unable to dial endpoint %w", err)
}
return client.NewGRPCClient(conn), nil
}

// basicAuth implements the credentials.PerRPCCredentials interface to support basic authentication for grpc requests.
type basicAuth struct {
username string
password string
}

func (b basicAuth) GetRequestMetadata(ctx context.Context, in ...string) (map[string]string, error) {
auth := b.username + ":" + b.password
enc := base64.StdEncoding.EncodeToString([]byte(auth))
return map[string]string{"authorization": "Basic " + enc}, nil
}

func (basicAuth) RequireTransportSecurity() bool {
return false
}

getClientWithBasicAuth 该函数会使用必要的安全选项配置一个gRPC ,并连接到endpoint 9000. It takes the endpoint name and token as input parameters and returns an instance of the GRPCClient interface, which you can use to make authenticated API calls.

client, err := getClientWithBasicAuth("ENDPOINT_NAME", "TOKEN")
if err != nil {
log.Fatalf("err: %v", err)
}

x-token 身份验证

getClientWithXToken 该函数演示了如何使用 x-token 进行身份验证。此方法会将令牌附加到每个请求的 x-token 头中。


import (
"上下文"
"crypto/tls"
"fmt"
"github.com/fbsobreira/gosui-sdk/pkg/client"
"google.golang.grpc"
"google.golang.grpc"
)

func getClientWithXToken(endpoint, token string) (client.GRPCClient, error) {
target := endpoint + ".sui-mainnet.quiknode.pro:9000" // for TLS connections
conn, err := grpc.Dial(target,
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
grpc.WithPerRPCCredentials(auth{
token: token,
}),
)
if err != nil {
return nil, fmt.Errorf("Unable to dial endpoint %w", err)
}
return client.NewGRPCClient(conn), nil
}

// auth implements the credentials.PerRPCCredentials interface to support x-token authentication for grpc requests.
type auth struct {
token string
}

func (a *auth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"x-token": a.token,
}, nil
}

func (auth) RequireTransportSecurity() bool {
return false
}

该方法的配置gRPC 与基本身份验证示例类似,但会将身份验证令牌附加到 x-token 头中。以下是使用此函数进行 API 调用的方法:


client, err := getClientWithXToken("ENDPOINT_NAME", "TOKEN")
if err != nil {
log.Fatalf("err: %v", err)
}

The below section provides a step-by-step process to set up a Go environment for making gRPC requests. The instructions include setting up Go, configuring dependencies, and implementing authentication mechanisms.

Initiating the Go Project for Sui gRPC

Step 1: Create a New Project Directory

Create a dedicated directory for your Sui gRPC project and navigate into it:

mkdir sui-grpc
cd sui-grpc

Step 2: Initialize a Go Module

Create a Go module for your project. The module name can match your directory name or be a repository URL:

go mod init sui-grpc # directory name

Step 3: Install gRPC and Protobuf Dependencies

Ensure you have both protoc installed on your machine.

You can Install the core gRPC and Protobuf libraries by following commands:

go get google.golang.org/grpc
go get google.golang.org/protobuf

You can also define versions directly in your go.mod:

require (
google.golang.org/grpc v1.60.0
google.golang.org/protobuf v1.33.0
)

Next, install the protoc plugins for Go:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

Make sure $GOPATH/bin is in your system’s PATH. You can follow below steps to set the system PATH for GO.


提示

To use Go-installed tools globally (e.g., protoc-gen-go, grpcurl), add $GOPATH/bin to your system PATH.

For macOS / Linux
  1. Add to your shell config file:
echo 'export PATH="$PATH:$(go env GOPATH)/bin"' >> ~/.bashrc
source ~/.bashrc

Use .zshrc instead of .bashrc if you're using Zsh.


  1. Verify:
which protoc-gen-go
For Windows
  1. Open Start Menu → search for Environment Variables

  2. Under System Variables, select Path → click Edit

  3. Click New and add:

%USERPROFILE%\go\bin
  1. Open a new Command Prompt or PowerShell and verify:
where protoc-gen-go

Step 4: Organize Your Project Directory

Create a protos folder to store the original Protocol Buffer definition files:

mkdir protos

Download the official Sui proto files from the MystenLabs/sui repository. Extract and place the entire sui directory structure into your newly created protos folder. Alternatively, you can run the following commands:

# Clone the repository with minimal depth
git clone https://github.com/MystenLabs/sui-apis.git --depth=1

# Copy the proto files to your working directory
cp -r sui-apis/proto protos

# Remove the cloned repository (optional)
rm -rf sui-apis

Your project structure should look like this:

sui-grpc/
├── protos/
│ └── sui/
│ └── rpc/
│ └── v2/
│ ├── ledger_service.proto
│ ├── object.proto
│ ├── transaction.proto
│ └── ... (other proto files)
├── go.mod

Step 5: Generate Go Code from Proto Files

First, we need to add go_package to each .proto File. For that we need to modify each .proto file (e.g. argument.proto, checkpoint.proto, etc.) to include a go_package option near the top:

syntax = "proto3";

package sui.rpc.v2;

option go_package = "sui/rpc/v2";

Once the go_package is added and your folder structure matches the above layout, generate the .pb.go files by running the following command:

protoc \
--proto_path=protos/proto \
--go_out=. \
--go-grpc_out=. \
protos/proto/sui/rpc/v2/*.proto

Step 6: Create a Main Go File

Set up a main Go file for implementing client or server logic:

touch main.go

You can copy and paste the following sample code into your main.go file to get started. The example demonstrates how to interact with the Sui gRPC service to fetch object information.

package main

import (
"上下文"
"crypto/tls"
"encoding/json"
"fmt"
“日志”
“时间”

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

pb "sui-grpc/sui/rpc/v2" // Your Generated .pb.go files path
)

// Quicknode endpoints consist of two crucial components: the endpoint name and the corresponding token
// For eg: QN Endpoint: https://docs-demo.sui-mainnet.quiknode.pro/abcde123456789
// endpoint will be: docs-demo.sui-mainnet.quiknode.pro:9000 {9000 is the port number for Sui gRPC}
// token will be : abcde123456789

var (
token = "YOUR_TOKEN_NUMBER"
endpoint = "YOUR_QN_ENDPOINT:9000"
)

type auth struct {
token string
}

func (a *auth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{"x-token": a.token}, nil
}
func (a *auth) RequireTransportSecurity() bool {
return true
}

func main() {
creds := credentials.NewTLS(&tls.Config{})
opts := []grpc.DialOption{
grpc.WithTransportCredentials(creds),
grpc.WithPerRPCCredentials(&auth{token}),
}

conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer conn.Close()

client := pb.NewLedgerServiceClient(conn)

// Object ID to fetch
objectID := "0x27c4fdb3b846aa3ae4a65ef5127a309aa3c1f466671471a806d8912a18b253e8"

// Build request with field mask
req := &pb.BatchGetObjectsRequest{
Requests: []*pb.GetObjectRequest{
{
ObjectId: &objectID,
},
},
}

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

resp, err := client.BatchGetObjects(ctx, req)
if err != nil {
log.Fatalf("BatchGetObjects failed: %v", err)
}

// Pretty print the response
marshaler := protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: true,
Indent: " ",
}

jsonBytes, err := marshaler.Marshal(resp)
if err != nil {
log.Fatalf("Failed to marshal: %v", err)
}

var pretty map[string]interface{}
if err := json.Unmarshal(jsonBytes, &pretty); err != nil {
log.Fatalf("Failed to parse JSON: %v", err)
}

out, _ := json.MarshalIndent(pretty, "", " ")
fmt.Println(string(out))
}

Step 7: Run Your Code

Before running your code, clean up and ensure all dependencies are correctly resolved:

go mod tidy

Build and run the project using:

运行 main.go