Skip to main content

Using gRPC

Before you begin, ensure you have access to a gRPC-enabled Sui full node. Refer to the list of RPC or data providers that have enabled gRPC on their full nodes. Contact a provider directly to request access. If your RPC or data provider doesn't yet support gRPC, ask them to enable support or contact the Sui Foundation team on Discord or Telegram for help.

Access using grpcurl

The simplest way to experiment with gRPC is by using grpcurl.

Your results might differ from the examples that follow, depending on the breadth, maturity, and data retention of the gRPC APIs available on the Sui full node you use.

List available gRPC services

$ grpcurl <full node URL:port> list

The port on Sui Foundation managed full nodes is 443.

Click to open
Output
grpc.health.v1.Health
grpc.reflection.v1.ServerReflection
sui.rpc.v2.LedgerService
sui.rpc.v2.MovePackageService
sui.rpc.v2.NameService
sui.rpc.v2.SignatureVerificationService
sui.rpc.v2.StateService
sui.rpc.v2.SubscriptionService
sui.rpc.v2.TransactionExecutionService

List available APIs in the LedgerService

$ grpcurl <full node URL:port> list sui.rpc.v2.LedgerService
Click to open
Output
sui.rpc.v2.LedgerService.BatchGetObjects
sui.rpc.v2.LedgerService.BatchGetTransactions
sui.rpc.v2.LedgerService.GetCheckpoint
sui.rpc.v2.LedgerService.GetEpoch
sui.rpc.v2.LedgerService.GetObject
sui.rpc.v2.LedgerService.GetServiceInfo
sui.rpc.v2.LedgerService.GetTransaction

Get the events and effects details of a particular transaction

$ grpcurl -d '{ "digest": "J4NvV5iQZQFm1xKPYv9ffDCCPW6cZ4yFKsCqFUiDX5L4" }' <full node URL:port> sui.rpc.v2.LedgerService/GetTransaction

Get the transactions in a particular checkpoint

$ grpcurl -d '{ "sequence_number": "164329987", "read_mask": { "paths": ["transactions"]} }' <full node URL:port> sui.rpc.v2.LedgerService/GetCheckpoint

Get the latest information for a coin type

$ grpcurl -d '{ "coin_type": "0x2::sui::SUI" }' <full node URL:port> sui.rpc.v2.StateService/GetCoinInfo

List the objects owned by a particular address

$ grpcurl -d '{ "owner": "0x94096a6a54129234237759c66e6ef1037224fb3102a0ae29d33b490281c8e4d5" }' <full node URL:port> sui.rpc.v2.StateService/ListOwnedObjects

List the dynamic fields in a particular object

$ grpcurl -d '{ "parent": "0xb57fba584a700a5bcb40991e1b2e6bf68b0f3896d767a0da92e69de73de226ac" }' <full node URL:port> sui.rpc.v2.StateService/ListDynamicFields

Access streaming data with Buf

grpcurl does not support server-side streaming RPCs. To test or experiment with SubscriptionService, use the Buf CLI instead.

$ buf curl --protocol grpc https://<full node URL>/sui.rpc.v2.SubscriptionService/SubscribeCheckpoints -d '{ "readMask": "sequenceNumber,digest,summary.timestamp" }'  --timeout 1m
Click to open
Output
{
"cursor": "164324277",
"checkpoint": {
"sequenceNumber": "164324277",
"digest": "AJsK688sDPbzWro1VSN3gVPxR1hfM9v3Bk1M9EhPBc3A",
"summary": {
"timestamp": "2025-07-05T16:49:09.788Z"
}
}
}
{
"cursor": "164324278",
"checkpoint": {
"sequenceNumber": "164324278",
"digest": "J35nDAwZm9YRZ4kHJH9oSqCMQ2ZrkbpmshCTi6N5TCpV",
"summary": {
"timestamp": "2025-07-05T16:49:10.032Z"
}
}
}
{
"cursor": "164324279",
"checkpoint": {
"sequenceNumber": "164324279",
"digest": "DgoaWNGtWojozP88AnmHskkDbdvyMApP1jVz2wRzPsC5",
"summary": {
"timestamp": "2025-07-05T16:49:10.292Z"
}
}
}
...
...
...

Build gRPC clients

info

For Rust, consider using the Sui Rust SDK.

This example shows how to build a TypeScript client for the Sui gRPC API.

Step 1: Install dependencies

npm init -y
npm install @grpc/grpc-js @grpc/proto-loader
npm i -D tsx

The default project has this structure:

.
├── protos/
│ └── sui/
│ └── node/
│ └── v2/
│ ├── ledger_service.proto
│ └── *.proto
├── client.ts
├── package.json

Download all of the sui/rpc/v2 proto files from Github in the same folder.

Step 2: Edit client.ts to get events and effects details of a particular transaction

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/sui/rpc/v2/ledger_service.proto');

// Load proto definitions
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs: [path.join(__dirname, 'protos')],
});

const suiProto = grpc.loadPackageDefinition(packageDefinition) as any;
const LedgerService = suiProto.sui.rpc.v2.LedgerService;

// Create gRPC client
const client = new LedgerService(
'<full node URL>:443',
grpc.credentials.createSsl()
);

// Sample transaction digest in Base58 format
const base58Digest = '3ByWphQ5sAVojiTrTrGXGM5FmCVzpzYmhsjbhYESJtxp';

// Construct the request
const request = {
digest: base58Digest,
read_mask: {
paths: ['events', 'effects'],
},
};

// Make gRPC call
client.GetTransaction(request, (err: any, response: any) => {
if (err) {
console.error('Error:', err);
} else {
console.log('Response:', JSON.stringify(response, null, 2));
}
});

Step 3: Run the sample client

npx tsx c
  • proto-loader handles any nested .proto files. Just make sure paths and imports are correct.

  • The example assumes that gRPC is available on port 443 which requires SSL.

  • Digest in the request is directly provided in the Base58 format, but check if you need to decode from your source format.