Skip to main content

Sui gRPC API

High-Performance Blockchain Data Access#

Dwellir's Sui gRPC API provides a high-performance alternative to traditional JSON-RPC for accessing Sui blockchain data. Built on Protocol Buffers and HTTP/2, gRPC offers superior performance, type safety, and efficient binary serialization for demanding applications that require minimal latency and maximum throughput.

Why Use gRPC?#

Performance Advantages#

  • Binary Protocol: Protocol Buffers provide compact binary encoding, reducing payload sizes by up to 70% compared to JSON
  • HTTP/2 Multiplexing: Multiple concurrent requests over a single connection eliminate connection overhead
  • Streaming Support: Bidirectional streaming enables real-time data feeds with minimal latency
  • Efficient Serialization: Native binary format significantly reduces parsing overhead

Developer Benefits#

  • Strong Typing: Protocol Buffer definitions provide compile-time type checking
  • Code Generation: Automatic client generation from .proto files eliminates boilerplate
  • Language Support: Native implementations available for Go, Python, TypeScript, Rust, and more
  • Built-in Features: Deadlines, cancellation, and load balancing come standard

Use Cases for gRPC#

  • High-frequency trading: Microsecond-level latency requirements
  • Real-time monitoring: Live blockchain event streaming and monitoring dashboards
  • Analytics pipelines: Bulk data extraction and processing
  • Mobile applications: Reduced bandwidth consumption on limited connections
  • Microservices: Efficient inter-service communication in distributed architectures

gRPC vs JSON-RPC Comparison#

FeaturegRPCJSON-RPC
ProtocolHTTP/2 + Protocol BuffersHTTP/1.1 + JSON
Payload SizeCompact binary (~30% smaller)Text-based JSON
StreamingBidirectional streaming supportRequest/response only
Type SafetyStrong typing via .protoRuntime validation required
Performance5-10x faster serializationSlower text parsing
Browser SupportRequires gRPC-Web proxyNative browser support
ToolingCode generation requiredSimpler setup

Available Services#

The Sui gRPC API is organized into six specialized services:

1. Ledger Service#

Access historical blockchain data and core object information:

  • Retrieve objects by ID with field masking
  • Query transactions with execution details
  • Access checkpoint and epoch data
  • Batch operations for multiple objects or transactions

2. Live Data Service#

Query current blockchain state efficiently:

  • Check account balances for any coin type
  • List owned objects with pagination
  • Enumerate dynamic fields
  • Simulate transactions before execution
  • Retrieve coin metadata and information

3. Transaction Service#

Execute and broadcast transactions:

  • Submit signed transactions for on-chain execution
  • Monitor transaction status and finality
  • Dry-run transactions for gas estimation

4. Move Package Service#

Inspect Move smart contracts and modules:

  • Retrieve package information and metadata
  • Query function signatures and capabilities
  • Inspect data types and structures
  • List package version history

5. Subscription Service#

Real-time blockchain event streaming:

  • Subscribe to checkpoint updates as they finalize
  • Stream events matching specific filters
  • Monitor transaction confirmations in real-time

6. Signature Verification Service#

Cryptographic signature operations:

  • Verify transaction signatures off-chain
  • Validate multi-sig configurations
  • Check signature authenticity

Connection Configuration#

Endpoint Structure#

Dwellir's Sui gRPC endpoints follow this format:

[your-endpoint-name].sui-mainnet.dwellir.com:9000

Important Notes:

  • gRPC uses port 9000 (different from HTTP port 443)
  • Connections require TLS encryption
  • Authentication via metadata headers

Network Endpoints#

NetworkgRPC Endpoint
Mainnetapi-sui-mainnet-full.n.dwellir.com
Testnetyour-endpoint.sui-testnet.dwellir.com:9000

Quick Start Guide#

Prerequisites#

  1. Dwellir API Key: Obtain from dashboard.dwellir.com
  2. Protocol Buffers: Install protoc compiler for code generation
  3. gRPC Libraries: Language-specific gRPC implementation

Protocol Buffer Files#

Download the official Sui proto definitions from the MystenLabs sui-apis repository:

# Clone the Sui API definitions
git clone https://github.com/MystenLabs/sui-apis.git
cd sui-apis

Key proto files:

  • ledger.proto - Ledger service definitions
  • live_data.proto - Live data queries
  • transaction.proto - Transaction execution
  • move_package.proto - Move package inspection
  • subscription.proto - Real-time subscriptions
  • signature_verification.proto - Signature operations

Language-Specific Setup#

# Create project directory
mkdir sui-grpc-client && cd sui-grpc-client

# Initialize Node.js project
npm init -y

# Install dependencies
npm install @grpc/grpc-js @grpc/proto-loader
npm install -D @types/node tsx

# Download proto files
mkdir -p protos
# Copy proto files from sui-apis repository to protos/

Basic Client Example:

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import { ProtoGrpcType } from './generated/ledger';

// Configuration
const ENDPOINT = 'api-sui-mainnet-full.n.dwellir.com';
const API_TOKEN = 'your_api_token_here';

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

const protoDescriptor = grpc.loadPackageDefinition(
packageDefinition
) as unknown as ProtoGrpcType;

// Create secure channel with TLS
const credentials = grpc.credentials.createSsl();

// Setup authentication metadata
const metadata = new grpc.Metadata();
metadata.add('x-api-key', API_TOKEN);

// Create client
const client = new protoDescriptor.sui.rpc.v2beta2.LedgerService(
ENDPOINT,
credentials
);

// Example: Get object information
const objectId = '0x5';

const request = {
object_id: objectId,
read_mask: {
paths: ['object_id', 'version', 'digest', 'owner', 'object_type']
}
};

client.GetObject(request, metadata, (error, response) => {
if (error) {
console.error('Error:', error.message);
return;
}

console.log('Object data:', JSON.stringify(response, null, 2));
});

Authentication#

All gRPC requests to Dwellir's Sui endpoints require authentication via metadata headers:

x-api-key: YOUR_API_TOKEN

The API token is extracted from your Dwellir endpoint URL. For example, if your endpoint is:

https://api-sui-mainnet-full.n.dwellir.com/abc123xyz

Your gRPC token is: `abc123xyz`

### Security Best Practices

- **Never expose tokens in client-side code**: Use backend services to proxy gRPC requests
- **Rotate tokens periodically**: Generate new tokens through the Dwellir dashboard
- **Use environment variables**: Store tokens outside of source code
- **Monitor usage**: Track API consumption via the Dwellir dashboard

## Field Masking

gRPC requests support field masking to optimize response payloads and reduce bandwidth. Specify only the fields you need:

```typescript
const request = {
object_id: '0x5',
read_mask: {
paths: ['object_id', 'version', 'owner'] // Only return these fields
}
};

Benefits:

  • Reduced response sizes (up to 80% smaller)
  • Faster serialization and network transfer
  • Lower bandwidth costs
  • Improved application performance

Error Handling#

gRPC provides standardized error codes for consistent error handling:

CodeDescriptionAction
OK (0)SuccessContinue processing
CANCELLED (1)Client cancelledRetry if needed
INVALID_ARGUMENT (3)Invalid request parametersFix request and retry
NOT_FOUND (5)Resource not foundVerify object IDs
ALREADY_EXISTS (6)Resource existsHandle duplicate
PERMISSION_DENIED (7)Authentication failedCheck API token
RESOURCE_EXHAUSTED (8)Rate limit exceededImplement backoff
FAILED_PRECONDITION (9)System state invalidRetry later
UNAVAILABLE (14)Service unavailableRetry with backoff
DEADLINE_EXCEEDED (4)Request timeoutIncrease timeout

Example Error Handling#

client.GetObject(request, metadata, (error, response) => {
if (error) {
switch (error.code) {
case grpc.status.NOT_FOUND:
console.error('Object not found:', error.message);
break;
case grpc.status.PERMISSION_DENIED:
console.error('Authentication failed. Check API token.');
break;
case grpc.status.RESOURCE_EXHAUSTED:
console.error('Rate limit exceeded. Retrying after backoff...');
// Implement exponential backoff
break;
case grpc.status.UNAVAILABLE:
console.error('Service temporarily unavailable. Retrying...');
// Retry with backoff
break;
default:
console.error('Unexpected error:', error.message);
}
return;
}

// Process successful response
console.log('Success:', response);
});

Performance Optimization#

Connection Pooling#

Reuse gRPC channels across requests to avoid connection overhead:

// Create a single channel for the application lifecycle
const channel = new grpc.Client(
ENDPOINT,
credentials,
{ 'grpc.keepalive_time_ms': 10000 }
);

// Reuse channel for all services
const ledgerClient = new protoDescriptor.sui.rpc.v2beta2.LedgerService(channel);
const liveDataClient = new protoDescriptor.sui.rpc.v2beta2.LiveDataService(channel);

Batch Requests#

Use batch methods when querying multiple items:

// Efficient: Single batch request
const batchResponse = await client.BatchGetObjects({
object_ids: ['0x1', '0x2', '0x3', '0x4', '0x5']
});

// Inefficient: Multiple individual requests
for (const id of objectIds) {
await client.GetObject({ object_id: id }); // Avoid this pattern
}

Field Masking#

Request only necessary fields to minimize payload size:

// Efficient: Only request needed fields
const request = {
object_id: '0x5',
read_mask: { paths: ['object_id', 'owner'] }
};

// Inefficient: Requesting all fields
const request = { object_id: '0x5' }; // Returns everything

Compression#

Enable gRPC compression for large payloads:

const options = {
'grpc.default_compression_algorithm': grpc.compressionAlgorithms.gzip,
'grpc.default_compression_level': grpc.compressionLevels.high
};

const client = new protoDescriptor.sui.rpc.v2beta2.LedgerService(
ENDPOINT,
credentials,
options
);

Real-Time Streaming#

gRPC's streaming capabilities enable real-time blockchain monitoring:

Checkpoint Subscription Example#

const subscribeRequest = {
read_mask: {
paths: [
'sequence_number',
'digest',
'timestamp_ms',
'network_total_transactions'
]
}
};

const stream = client.SubscribeCheckpoints(subscribeRequest, metadata);

stream.on('data', (checkpoint) => {
console.log('New checkpoint:', {
sequence: checkpoint.sequence_number,
digest: checkpoint.digest,
timestamp: new Date(parseInt(checkpoint.timestamp_ms)),
txCount: checkpoint.network_total_transactions
});
});

stream.on('error', (error) => {
console.error('Stream error:', error.message);
// Implement reconnection logic
});

stream.on('end', () => {
console.log('Stream ended');
});

Stream Management Best Practices#

  1. Implement reconnection logic: Automatically reconnect on stream failures
  2. Handle backpressure: Process data faster than it arrives or implement buffering
  3. Monitor connection health: Use keepalive pings and heartbeats
  4. Graceful shutdown: Close streams properly to avoid resource leaks

Best Practices#

1. Use Appropriate Timeouts#

Set reasonable timeouts to prevent hanging requests:

const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 10);

client.GetObject(request, { deadline }, (error, response) => {
// Handle response
});

2. Implement Exponential Backoff#

Handle rate limits and transient failures gracefully:

async function retryWithBackoff(fn, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;

const waitTime = Math.min(1000 * Math.pow(2, i), 30000);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
}
}

3. Monitor and Log#

Track gRPC performance metrics:

const call = client.GetObject(request, metadata, callback);

call.on('status', (status) => {
console.log('RPC Status:', status.code, status.details);
});

call.on('metadata', (metadata) => {
console.log('Server metadata:', metadata.getMap());
});

4. Validate Inputs#

Validate request parameters before sending:

function isValidObjectId(id: string): boolean {
return /^0x[a-f0-9]+$/i.test(id);
}

if (!isValidObjectId(objectId)) {
throw new Error('Invalid object ID format');
}

Migration from JSON-RPC#

Transitioning from JSON-RPC to gRPC requires minimal code changes:

JSON-RPCgRPC Equivalent
sui_getObjectLedgerService.GetObject
suix_getBalanceLiveDataService.GetBalance
sui_executeTransactionBlockTransactionService.ExecuteTransaction
suix_subscribeEventSubscriptionService.SubscribeCheckpoints

Example Migration#

Before (JSON-RPC):

const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'sui_getObject',
params: [objectId],
id: 1
})
});
const data = await response.json();

After (gRPC):

const response = await new Promise((resolve, reject) => {
client.GetObject(
{ object_id: objectId },
metadata,
(error, response) => {
if (error) reject(error);
else resolve(response);
}
);
});

Troubleshooting#

Common Issues#

Connection Refused

  • Verify port 9000 is used for gRPC
  • Check firewall settings allow outbound connections on port 9000
  • Ensure TLS credentials are properly configured

Authentication Errors

  • Verify API token is correct and active
  • Check token is passed in x-api-key metadata header
  • Confirm endpoint URL matches your Dwellir account

Timeout Errors

  • Increase request timeout/deadline
  • Check network connectivity and latency
  • Verify endpoint availability via Dwellir dashboard

Protocol Buffer Errors

  • Ensure proto files match server version
  • Regenerate client code after proto updates
  • Check import paths and dependencies

Support and Resources#

Documentation#

Getting Help#

Additional Resources#


Ready to build with gRPC? Get your API key and experience the performance difference with Dwellir's enterprise-grade Sui infrastructure.