Skip to main content

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​

FeatureJSON-RPCgRPC
ProtocolHTTP/1.1 (Text)HTTP/2 (Binary)
Data FormatJSONProtocol Buffers (Protobuf)
Type SafetyLoose (Runtime validation)Strong (Compile-time validation)
PerformanceGoodExcellent (Lower latency, smaller payloads)
StreamingWebSockets (Subscription only)Native HTTP/2 Streaming
Field SelectionNot supportedSupported 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 MethodgRPC ServicegRPC MethodNotes
sui_getObjectStateServiceGetObjectUse read_mask to select specific fields like owner or bcs.
suix_getOwnedObjectsStateServiceListOwnedObjectsSupports filtering by object type directly.
suix_getDynamicFieldsStateServiceListDynamicFieldsPagination works similarly with cursors.
suix_getBalanceStateServiceGetBalanceOptimized for checking single coin balance.
suix_getAllBalancesStateServiceListBalancesReturns all coin balances for an address.

Ledger & History​

JSON-RPC MethodgRPC ServicegRPC MethodNotes
sui_getCheckpointLedgerServiceGetCheckpointCan fetch by sequence number or digest.
sui_getTransactionBlockLedgerServiceGetTransactionRetrieve full transaction details.
sui_getLatestCheckpointSequenceNumberLedgerServiceGetCheckpointRequest with no arguments to get the latest.

Transactions​

JSON-RPC MethodgRPC ServicegRPC MethodNotes
sui_executeTransactionBlockTransactionExecutionServiceExecuteTransactionSubmits a signed transaction.
sui_dryRunTransactionBlockTransactionExecutionServiceSimulateTransactionSimulates 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
Open gRPC Playground→