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