JSON-RPC to gRPC Migration Guide
This guide helps you migrate your existing Sui applications from the JSON-RPC API to the new gRPC API.
Key Differences
| Feature | JSON-RPC | gRPC |
|---|---|---|
| Protocol | HTTP/1.1 (Text) | HTTP/2 (Binary) |
| Data Format | JSON | Protocol Buffers (Protobuf) |
| Type Safety | Loose (Runtime validation) | Strong (Compile-time validation) |
| Performance | Good | Excellent (Lower latency, smaller payloads) |
| Streaming | WebSockets (Subscription only) | Native HTTP/2 Streaming |
| Field Selection | Not supported | Supported via Field Masks |
Method Mapping
The gRPC API is organized into domain-specific services, whereas JSON-RPC uses a flat namespace.
State & Objects
| JSON-RPC Method | gRPC Service | gRPC Method | Notes |
|---|---|---|---|
sui_getObject | StateService | GetObject | Use read_mask to select specific fields like owner or bcs. |
suix_getOwnedObjects | StateService | ListOwnedObjects | Supports filtering by object type directly. |
suix_getDynamicFields | StateService | ListDynamicFields | Pagination works similarly with cursors. |
suix_getBalance | StateService | GetBalance | Optimized for checking single coin balance. |
suix_getAllBalances | StateService | ListBalances | Returns all coin balances for an address. |
Ledger & History
| JSON-RPC Method | gRPC Service | gRPC Method | Notes |
|---|---|---|---|
sui_getCheckpoint | LedgerService | GetCheckpoint | Can fetch by sequence number or digest. |
sui_getTransactionBlock | LedgerService | GetTransaction | Retrieve full transaction details. |
sui_getLatestCheckpointSequenceNumber | LedgerService | GetCheckpoint | Request with no arguments to get the latest. |
Transactions
| JSON-RPC Method | gRPC Service | gRPC Method | Notes |
|---|---|---|---|
sui_executeTransactionBlock | TransactionExecutionService | ExecuteTransaction | Submits a signed transaction. |
sui_dryRunTransactionBlock | TransactionExecutionService | SimulateTransaction | Simulates execution without committing. |
Code Migration Example
Before: JSON-RPC (TypeScript)
import { SuiClient } from '@mysten/sui/client';
const client = new SuiClient({ url: 'https://fullnode.mainnet.sui.io' });
// Get object
const obj = await client.getObject({
id: '0x123...',
options: { showContent: true }
});
console.log(obj.data?.content);
After: gRPC (TypeScript)
import { SuiGrpcClient } from '@mysten/sui/grpc';
import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport';
const API_KEY = 'YOUR_API_KEY';
// Custom fetch to inject API key
const fetchWithApiKey = (url, init) => {
const headers = new Headers(init?.headers);
headers.set('x-api-key', API_KEY);
return fetch(url, { ...init, headers });
};
const client = new SuiGrpcClient({
network: 'mainnet',
transport: new GrpcWebFetchTransport({
baseUrl: 'https://grpc.surflux.dev',
fetch: fetchWithApiKey,
}),
});
// Get object
const { response } = await client.stateService.getObject({
object_id: '0x123...'
});
console.log(response.object);
Field Masks
One of the biggest changes is the ability to request only the data you need using Field Masks. This replaces the options object in JSON-RPC.
JSON-RPC:
options: {
showContent: true,
showOwner: true,
showType: true
}
gRPC:
read_mask: {
paths: ['object.content', 'object.owner', 'object.type']
}
Error Handling
gRPC uses standard status codes instead of JSON-RPC error objects.
- INVALID_ARGUMENT (3): Malformed request or invalid parameters.
- NOT_FOUND (5): Object or resource not found.
- UNAUTHENTICATED (16): Missing or invalid API key.
- RESOURCE_EXHAUSTED (8): Rate limit exceeded.
Ensure your error handling logic catches RpcError and checks the code property.
Try it in the Playground
The best way to understand the new gRPC methods is to try them out interactively. Our Playground allows you to:
- Browse available services and methods
- See the equivalent JSON-RPC method for each gRPC endpoint
- Execute requests against the mainnet
- Inspect the full response structure