Skip to content

gRPC Gateway

High-performance proxy to Inodra-managed Sui gRPC nodes with server reflection enabled.

What is gRPC?

gRPC is a high-performance RPC framework that uses Protocol Buffers for serialization and HTTP/2 for transport. Unlike JSON-RPC which sends human-readable text, gRPC sends compact binary data - making it faster and more bandwidth-efficient.

FeaturegRPCJSON-RPCREST
Data formatBinary (Protocol Buffers)JSON textJSON text
TransportHTTP/2HTTP/1.1HTTP/1.1
StreamingNative supportNot supportedNot supported
Type safetyCompile-timeRuntimeRuntime
Code generationBuilt-inManualManual
Typical latencyLowerHigherHigher

For a deeper dive, see the official gRPC documentation.

Why Sui is Moving to gRPC

📌 Important: JSON-RPC Deprecation

Sui has deprecated JSON-RPC in favor of gRPC, with full deprecation planned for April 2026. If you're currently using JSON-RPC, see our migration guide.

Sui chose gRPC for:

  • Performance: Binary serialization is faster than JSON
  • Streaming: Subscribe to real-time checkpoint updates
  • Type safety: Catch errors at compile time, not runtime
  • Modern tooling: Better developer experience with generated clients

Inodra makes gRPC easy - just add your API key and start making calls.

Overview

The gRPC gateway provides low-latency access to Sui blockchain data with full Sui gRPC compatibility.

Endpoint: grpc.inodra.com:443 (TLS required)

Key Features:

  • Full Sui gRPC compatibility
  • Server reflection enabled (explore without proto files)
  • HTTP/2 for optimal performance
  • TLS encryption

gRPC vs gRPC-Web

Inodra supports both native gRPC and gRPC-Web on the same endpoint:

ProtocolTransportUse CaseStreaming
gRPC-WebGrpcWebFetchTransportBrowsers, universalServer-side only
Native gRPCGrpcTransportNode.js, servers, CLIFull (bidirectional)

Why two protocols?

  • Browsers can't make native gRPC calls (HTTP/2 limitations)
  • gRPC-Web wraps gRPC in a browser-compatible format
  • Inodra's infrastructure automatically handles both

Which should you use?

  • Browser/Frontend: gRPC-Web (GrpcWebFetchTransport)
  • Node.js/Backend: Either works; native gRPC has full streaming support
  • Universal code: gRPC-Web (works everywhere)

Server Reflection: Explore Without Proto Files

One of the biggest barriers to getting started with gRPC is downloading and compiling proto files. With Inodra, you don't need to - server reflection lets you discover services, methods, and message types directly from the API.

Think of it as a self-documenting API. You can:

  • List all available services
  • See what methods each service offers
  • Inspect request/response message formats
  • Make calls without any local proto files

This is perfect for prototyping, debugging, or learning the API before setting up a full development environment.

Quick Start with grpcurl

grpcurl is the easiest way to explore gRPC APIs:

bash
# macOS
brew install grpcurl

# Linux
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

# Windows (via Scoop)
scoop install grpcurl

Discover Available Services

bash
# List all services (no proto files needed!)
grpcurl -H "x-api-key: YOUR_API_KEY" \
  grpc.inodra.com:443 list

# Example output:
# sui.rpc.v2.LedgerService
# sui.rpc.v2.LiveDataService
# sui.rpc.v2.TransactionExecutionService
# grpc.reflection.v1.ServerReflection

Explore a Service

bash
# See all methods in LedgerService
grpcurl -H "x-api-key: YOUR_API_KEY" \
  grpc.inodra.com:443 \
  describe sui.rpc.v2.LedgerService

# See the request format for a specific method
grpcurl -H "x-api-key: YOUR_API_KEY" \
  grpc.inodra.com:443 \
  describe sui.rpc.v2.GetCheckpointRequest

Make API Calls

bash
# Get latest checkpoint
grpcurl -H "x-api-key: YOUR_API_KEY" \
  -d '{}' \
  grpc.inodra.com:443 \
  sui.rpc.v2.LedgerService/GetLatestCheckpoint

# Get specific checkpoint
grpcurl -H "x-api-key: YOUR_API_KEY" \
  -d '{"sequence_number": 12345678}' \
  grpc.inodra.com:443 \
  sui.rpc.v2.LedgerService/GetCheckpoint

# Get transaction by digest
grpcurl -H "x-api-key: YOUR_API_KEY" \
  -d '{"digest": "TRANSACTION_DIGEST_HERE"}' \
  grpc.inodra.com:443 \
  sui.rpc.v2.LedgerService/GetTransaction

🚀 Ready to try it?

Get your free API key and start exploring with grpcurl in under 2 minutes.

Available Services

Sui's gRPC API is organized into specialized services. Here's what each one does:

ServicePurposeCommon Use Cases
LedgerServiceQuery historical blockchain dataIndexers, block explorers, archives
StateServiceQuery current on-chain stateWallets, DeFi apps, balance checks
TransactionExecutionServiceSubmit and simulate transactionsAny dApp that writes to Sui
SubscriptionServiceStream real-time checkpoint dataLive dashboards, monitoring
MovePackageServiceAccess Move package metadataDeveloper tools, contract analysis
SignatureVerificationServiceValidate signaturesAuthentication, zkLogin
NameServiceResolve SuiNS domain namesName resolution, reverse lookups

For detailed method documentation, see Sui's gRPC API reference.

TypeScript Quick Start

The official Sui SDK includes SuiGrpcClient with full type safety. This approach works in both browsers and Node.js:

typescript
import { SuiGrpcClient } from '@mysten/sui/grpc'
import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport'

// Create transport with Inodra endpoint and API key
const transport = new GrpcWebFetchTransport({
  baseUrl: 'https://grpc.inodra.com',
  meta: { 'x-api-key': 'YOUR_API_KEY' }
})

const client = new SuiGrpcClient({
  network: 'mainnet',
  transport
})

// Use the typed service clients
const checkpoint = await client.ledger.getLatestCheckpoint({})
console.log('Latest checkpoint:', checkpoint.checkpoint?.sequenceNumber)

// Get an object
const object = await client.ledger.getObject({
  objectId: '0x123...'
})

// Get account balance
const balance = await client.state.getBalance({
  address: '0xabc...',
  coinType: '0x2::sui::SUI'
})

Note: SuiGrpcClient is still in active development. Check the Sui SDK docs for the latest API.

Option 2: Native gRPC (Node.js only)

For server-side applications with full bidirectional streaming support:

typescript
import { SuiGrpcClient } from '@mysten/sui/grpc'
import { GrpcTransport } from '@protobuf-ts/grpc-transport'
import { ChannelCredentials } from '@grpc/grpc-js'

const transport = new GrpcTransport({
  host: 'grpc.inodra.com:443',
  channelCredentials: ChannelCredentials.createSsl(),
  meta: { 'x-api-key': 'YOUR_API_KEY' }
})

const client = new SuiGrpcClient({
  network: 'mainnet',
  transport
})

const { response } = await client.ledgerService.getLatestCheckpoint({})
console.log('Checkpoint:', response.checkpoint?.sequenceNumber)

Required packages:

bash
npm install @protobuf-ts/grpc-transport @grpc/grpc-js

Option 3: Dynamic Loading (No Proto Compilation)

For more control or when the SDK doesn't cover your use case:

typescript
import * as grpc from '@grpc/grpc-js'
import * as protoLoader from '@grpc/proto-loader'

// Download proto files from Sui's repository first
// https://github.com/MystenLabs/sui-apis/tree/main/proto
const packageDefinition = protoLoader.loadSync('./sui.proto', {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true
})

const sui = grpc.loadPackageDefinition(packageDefinition) as any

// Create client with TLS
const client = new sui.rpc.v2.LedgerService('grpc.inodra.com:443', grpc.credentials.createSsl())

// Add API key to metadata
const metadata = new grpc.Metadata()
metadata.add('x-api-key', 'YOUR_API_KEY')

// Get the latest checkpoint
client.GetLatestCheckpoint({}, metadata, (err: Error | null, response: any) => {
  if (err) {
    console.error('Error:', err.message)
    return
  }
  console.log('Latest checkpoint:', response.checkpoint.sequenceNumber)
})

Protocol Buffer Definitions

For code generation and type definitions, Sui provides official .proto files:

Since Inodra proxies to Sui's gRPC infrastructure, you can use Sui's official proto files directly for client generation.

Using Proto Files

bash
# Clone Sui's proto definitions
git clone https://github.com/MystenLabs/sui-apis.git
cd sui-apis/proto

# Node.js uses dynamic loading via @grpc/proto-loader, no code generation needed

Then use the generated types:

typescript
import * as grpc from '@grpc/grpc-js'
import { LedgerServiceClient } from './generated/sui/rpc/v2/ledger_grpc_pb'
import { GetLatestCheckpointRequest } from './generated/sui/rpc/v2/ledger_pb'

const client = new LedgerServiceClient('grpc.inodra.com:443', grpc.credentials.createSsl())

const metadata = new grpc.Metadata()
metadata.add('x-api-key', process.env.INODRA_API_KEY!)

const request = new GetLatestCheckpointRequest()

client.getLatestCheckpoint(request, metadata, (err, response) => {
  if (err) {
    console.error('Error:', err.message)
    return
  }
  console.log('Checkpoint:', response?.getCheckpoint()?.getSequenceNumber())
})

Streaming

gRPC's real power is streaming - subscribe to real-time updates without polling:

typescript
// Using SuiGrpcClient (recommended)
const stream = client.subscription.subscribeCheckpoints({
  startSequenceNumber: BigInt(0)
})

for await (const checkpoint of stream.responses) {
  console.log('New checkpoint:', checkpoint.sequenceNumber)
  // Process each checkpoint as it arrives - no polling delay
}

Why streaming matters:

  • Lower latency: Data arrives as soon as it's available
  • Less server load: One connection vs repeated polling
  • Cost efficient: Each streamed message costs only 2 CU

Error Handling

gRPC uses standard status codes for errors. With SuiGrpcClient, errors are thrown as exceptions:

typescript
import { RpcError } from '@protobuf-ts/runtime-rpc'

try {
  const { checkpoint } = await client.ledger.getCheckpoint({
    sequenceNumber: BigInt(999999999)
  })
} catch (err) {
  if (err instanceof RpcError) {
    switch (err.code) {
      case 'UNAUTHENTICATED':
        console.error('Invalid API key')
        break
      case 'NOT_FOUND':
        console.error('Checkpoint not found')
        break
      case 'UNAVAILABLE':
        console.error('Service unavailable, retrying...')
        // Implement exponential backoff
        break
      case 'RESOURCE_EXHAUSTED':
        console.error('Rate limited')
        break
      default:
        console.error('Error:', err.message)
    }
  }
}

When to Use gRPC

Perfect for:

  • High-frequency trading applications
  • Real-time monitoring dashboards
  • Microservices that need type safety
  • Mobile apps (bandwidth-sensitive)
  • Applications requiring sub-100ms latency
  • Any use case needing streaming

Consider alternatives if:

  • You have existing JSON-RPC code that works well
  • Your team isn't familiar with Protocol Buffers
  • You only need occasional API calls

Next Steps

Released under the MIT License.