BatchGetObjects gRPC Method
Parameters
requests
array
REQUIRED
Loading...
read_mask
object
Loading...
paths
array
Loading...
Returns
objects
array
Loading...
object
object
Loading...
bcs
object
Loading...
name
string
Loading...
value
string
Loading...
objectId
string
Loading...
version
string
Loading...
digest
string
Loading...
owner
object
Loading...
kind
string
Loading...
version
string
Loading...
objectType
string
Loading...
hasPublicTransfer
boolean
Loading...
contents
object
Loading...
name
string
Loading...
value
string
Loading...
previousTransaction
string
Loading...
storageRebate
string
Loading...
Request
grpcurl \
-import-path . \
-proto sui/rpc/v2beta2/ledger_service.proto \
-H "x-token: YOUR_TOKEN_VALUE" \
-d '{
"requests": [
{ "object_id": "0x27c4fdb3b846aa3ae4a65ef5127a309aa3c1f466671471a806d8912a18b253e8" }
],
"read_mask": {
"paths": [
"bcs",
"object_id",
"version",
"digest",
"owner",
"object_type",
"has_public_transfer",
"contents",
"previous_transaction",
"storage_rebate"
]
}
}' \
docs-demo.sui-mainnet.quiknode.pro:9000 \
sui.rpc.v2beta2.LedgerService/BatchGetObjectspackage 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/rpc/v2beta2" // 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,
},
},
ReadMask: &fieldmaskpb.FieldMask{
Paths: []string{
"object_id",
"version",
"digest",
"owner",
"object_type",
"has_public_transfer",
"contents",
"previous_transaction",
"storage_rebate",
"bcs",
},
},
}
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))
}
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import * as path from 'path';
const PROTO_PATH = path.join(__dirname, 'protos/proto/sui/rpc/v2beta2/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/proto')],
});
const proto = grpc.loadPackageDefinition(packageDefinition) as any;
const LedgerService = proto.sui.rpc.v2beta2.LedgerService;
// Create secure client
const client = new LedgerService(endpoint, grpc.credentials.createSsl());
// Add token metadata
const metadata = new grpc.Metadata();
metadata.add('x-token', token);
// Request payload
const request = {
requests: [
{
object_id: '0x27c4fdb3b846aa3ae4a65ef5127a309aa3c1f466671471a806d8912a18b253e8',
},
],
read_mask: {
paths: [
'bcs',
'object_id',
'version',
'digest',
'owner',
'object_type',
'has_public_transfer',
'contents',
'previous_transaction',
'storage_rebate',
],
},
};
// Recursively decode Uint8Array or Buffer fields to hex
function decodeBytesFields(obj: any): any {
if (Array.isArray(obj)) {
return obj.map(decodeBytesFields);
} else if (obj && typeof obj === 'object') {
const result: any = {};
for (const key of Object.keys(obj)) {
const val = obj[key];
if (val instanceof Uint8Array) {
result[key] = Buffer.from(val).toString('hex');
} else if (val && val.type === 'Buffer' && Array.isArray(val.data)) {
result[key] = Buffer.from(val.data).toString('hex');
} else {
result[key] = decodeBytesFields(val);
}
}
return result;
} else {
return obj;
}
}
// Perform gRPC call
client.BatchGetObjects(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 decoded = decodeBytesFields(response);
console.log('BatchGetObjects Response:');
console.log(JSON.stringify(decoded, null, 2));
}
});
import grpc
import json
from google.protobuf.field_mask_pb2 import FieldMask
from google.protobuf.json_format import MessageToDict
from sui.rpc.v2beta2 import ledger_service_pb2, ledger_service_pb2_grpc
def batch_get_objects():
# 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 = 'abcde123456789';
channel = grpc.secure_channel(endpoint, grpc.ssl_channel_credentials())
stub = ledger_service_pb2_grpc.LedgerServiceStub(channel)
object_id = "0x27c4fdb3b846aa3ae4a65ef5127a309aa3c1f466671471a806d8912a18b253e8"
# Define valid read_mask field paths from Object message
read_mask = FieldMask(paths=[
"bcs",
"object_id",
"version",
"digest",
"owner",
"object_type",
"has_public_transfer",
"contents",
"previous_transaction",
"storage_rebate"
])
request = ledger_service_pb2.BatchGetObjectsRequest(
requests=[ledger_service_pb2.GetObjectRequest(object_id=object_id)],
read_mask=read_mask
)
metadata = [("x-token", token)]
return stub.BatchGetObjects(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 = batch_get_objects()
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