GetEpoch gRPC Method
Parameters
epoch
string
The identifier of the epoch to retrieve. If omitted, the latest epoch will be returned.
read_mask
object
Field mask specifying which fields to include in the response.
paths
array
List of field names to return (e.g., 'epoch', 'committee', 'start', 'end', etc.).
Returns
epoch
string
The numerical identifier of the epoch.
committee
object
Details about the validator committee for the epoch.
epoch
string
The epoch this committee is assigned to.
members
array
List of committee members and their associated stake.
publicKey
string
The BLS public key of the committee member.
stake
string
The amount of stake delegated to this validator for the epoch.
Request
grpcurl -proto ./sui/rpc/v2beta/ledger_service.proto -H "x-token: YOUR_TOKEN_VALUE" -d '{ "epoch": "10", "read_mask": { "paths": [ "epoch", "committee" ] } }' docs-demo.sui-mainnet.quiknode.pro:9000 sui.rpc.v2beta.LedgerService/GetEpoch
package main import ( "context" "crypto/tls" "encoding/json" "fmt" "log" "time" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/fieldmaskpb" pb "sui-grpc/sui/proto/generated/sui/rpc/v2beta" // 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" ) // Token-based auth via PerRPCCredentials 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) // Request epoch #10 epochNum := uint64(10) fieldMask := &fieldmaskpb.FieldMask{ Paths: []string{ "epoch", "committee" }, } req := &pb.GetEpochRequest{ Epoch: &epochNum, ReadMask: fieldMask, } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() resp, err := client.GetEpoch(ctx, req) if err != nil { log.Fatalf("GetEpoch failed: %v", err) } // Convert protobuf response to readable JSON marshaler := protojson.MarshalOptions{ UseProtoNames: true, EmitUnpopulated: true, Indent: " ", } jsonBytes, err := marshaler.Marshal(resp) if err != nil { log.Fatalf("Failed to marshal response: %v", err) } var pretty map[string]interface{} if err := json.Unmarshal(jsonBytes, &pretty); err != nil { log.Fatalf("Failed to parse JSON: %v", err) } formatted, _ := json.MarshalIndent(pretty, "", " ") fmt.Println(string(formatted)) }
import * as grpc from '@grpc/grpc-js'; import * as protoLoader from '@grpc/proto-loader'; import * as path from 'path'; // Configuration const PROTO_PATH = path.join(__dirname, 'protos/sui/rpc/v2beta/ledger_service.proto'); // 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 const endpoint = 'docs-demo.sui-mainnet.quiknode.pro:9000'; const token = 'abcde123456789'; // Load protobuf definitions const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true, includeDirs: [path.join(__dirname, 'protos')], }); const proto = grpc.loadPackageDefinition(packageDefinition) as any; const LedgerService = proto.sui.rpc.v2beta.LedgerService; // Create secure client const client = new LedgerService(endpoint, grpc.credentials.createSsl()); // Metadata for authentication const metadata = new grpc.Metadata(); metadata.add('x-token', token); // Convert byte arrays to hex function toHex(bytes: number[] | Buffer): string { return Buffer.from(bytes).toString('hex'); } // Recursively convert byte arrays to hex strings function convertBytesToHex(obj: any): any { if (Array.isArray(obj)) { return obj.map(convertBytesToHex); } else if (typeof obj === 'object' && obj !== null) { const result: any = {}; for (const key in obj) { if ( Buffer.isBuffer(obj[key]) || (Array.isArray(obj[key]) && typeof obj[key][0] === 'number') ) { result[key] = toHex(obj[key]); } else { result[key] = convertBytesToHex(obj[key]); } } return result; } else { return obj; } } // Request payload const request = { epoch: 10, read_mask: { paths: [ 'epoch', 'committee' ], }, }; // gRPC call client.GetEpoch(request, metadata, (err: grpc.ServiceError | null, response: any) => { if (err) { console.error('gRPC Error:', { code: err.code, message: err.message, details: err.details, }); } else { const clean = convertBytesToHex(response); console.log('Epoch Response:'); console.log(JSON.stringify(clean, null, 2)); } });
import grpc import json from google.protobuf.field_mask_pb2 import FieldMask from google.protobuf.json_format import MessageToDict from sui.rpc.v2beta import ledger_service_pb2, ledger_service_pb2_grpc def get_epoch(): # 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 endpoint = 'docs-demo.sui-mainnet.quiknode.pro:9000'; token = 'YOUR_TOKEN_HERE'; channel = grpc.secure_channel(endpoint, grpc.ssl_channel_credentials()) stub = ledger_service_pb2_grpc.LedgerServiceStub(channel) # Specify which epoch you want to retrieve # For example, epoch 10 - replace with the actual epoch number you want epoch_number = 10 # Create a field mask to specify which fields to include in the response read_mask = FieldMask(paths=[ "epoch", "committee" ]) # Prepare the GetEpochRequest request = ledger_service_pb2.GetEpochRequest( epoch=epoch_number, read_mask=read_mask ) metadata = [("x-token", token)] return stub.GetEpoch(request, metadata=metadata) def parse_response_to_json(response): return json.dumps( MessageToDict(response, preserving_proto_field_name=True), indent=2 ) def main(): try: response = get_epoch() print(parse_response_to_json(response)) except grpc.RpcError as e: print(f"{e.code().name}: {e.details()}") if __name__ == "__main__": main()
Don't have an account yet?
Create your QuickNode endpoint in seconds and start building
Get started for free