@mysten/sui v2.0 and a new dApp Kit are here! Check out the migration guide
Mysten Labs SDKs
MigrationsMigrate to 2.0

Migrating from JSON-RPC

This guide covers migrating from SuiJsonRpcClient to the new client APIs. The JSON-RPC API is being deprecated in favor of SuiGrpcClient and SuiGraphQLClient.

We recommend using SuiGrpcClient for most operations and SuiGraphQLClient for complex queries like filtering transactions and events.

Choosing a Client

ClientBest For
SuiGrpcClientMost operations, SDK integrations, real-time data
SuiGraphQLClientComplex queries, filtering transactions/events, historical data

Quick Migration to gRPC

For most use cases, migrate to SuiGrpcClient:

- import { SuiJsonRpcClient, getJsonRpcFullnodeUrl } from '@mysten/sui/jsonRpc';
+ import { SuiGrpcClient } from '@mysten/sui/grpc';

- const client = new SuiJsonRpcClient({
-   url: getJsonRpcFullnodeUrl('mainnet'),
-   network: 'mainnet',
- });
+ const client = new SuiGrpcClient({
+   baseUrl: 'https://fullnode.mainnet.sui.io:443',
+   network: 'mainnet',
+ });

Both clients use the same full node URLs, so you can use the same endpoint when migrating.

Core API Methods

The gRPC client should work with almost all mysten SDKs as a drop in replacement for the JSON-RPC client. When using the client directly, the methods and data returned will not be exactly the same as what was available in JSON-RPC.

Methods Replaced by Core API

These JSON-RPC methods have direct replacements in the core API:

JSON-RPC MethodCore API Replacement
getCoinslistCoins
getAllCoinslistOwnedObjects with type: '0x2::coin::Coin'
getAllBalanceslistBalances
getOwnedObjectslistOwnedObjects
multiGetObjectsgetObjects
getDynamicFieldslistDynamicFields
getDynamicFieldObjectgetDynamicField
devInspectTransactionBlocksimulateTransaction
dryRunTransactionBlocksimulateTransaction
getNormalizedMoveFunctiongetMoveFunction
getMoveFunctionArgTypesgetMoveFunction

Example: Migrating getOwnedObjects

- const { data } = await jsonRpcClient.getOwnedObjects({
-   owner: '0xabc...',
-   options: { showContent: true },
- });
+ const { objects } = await grpcClient.listOwnedObjects({
+   owner: '0xabc...',
+   include: { content: true },
+ });

Methods Replaced by gRPC Services

These JSON-RPC methods can be replaced by calling gRPC service clients directly:

JSON-RPC MethodgRPC Service Replacement
getCheckpointledgerService.getCheckpoint
getCheckpointsledgerService.listCheckpoints
getLatestCheckpointSequenceNumberledgerService.getCheckpoint
getEpochsledgerService.listEpochs
getCurrentEpochledgerService.getEpoch
getLatestSuiSystemStateledgerService.getSystemState
getCommitteeInfoledgerService.getCommittee
getValidatorsApyledgerService.getValidators
getProtocolConfigledgerService.getProtocolConfig
getNormalizedMoveModulemovePackageService.getModule
getNormalizedMoveModulesByPackagemovePackageService.getPackage
getNormalizedMoveStructmovePackageService.getStruct
resolveNameServiceAddressnameService.lookupName
resolveNameServiceNamesnameService.reverseLookupName

Example: Using gRPC Service Clients

import { SuiGrpcClient } from '@mysten/sui/grpc';

const client = new SuiGrpcClient({
	baseUrl: 'https://fullnode.mainnet.sui.io:443',
	network: 'mainnet',
});

// Get checkpoint information
const { response } = await client.ledgerService.getCheckpoint({
	sequenceNumber: 12345n,
});

// Get current epoch
const { response: epoch } = await client.ledgerService.getEpoch({});

// Get Move module information
const { response: module } = await client.movePackageService.getModule({
	packageId: '0x2',
	moduleName: 'coin',
});

// Resolve SuiNS name
const { response: address } = await client.nameService.lookupName({
	name: 'example.sui',
});

Methods Requiring GraphQL

Some JSON-RPC methods don't have gRPC equivalents and require using SuiGraphQLClient instead:

JSON-RPC MethodGraphQL Alternative
queryTransactionBlockstransactions query
multiGetTransactionBlocksmultiGetTransactionEffects query
queryEventsevents query
getCoinMetadatacoinMetadata query
getTotalSupplycoinMetadata query
getStakesaddress.stakedSuis query
getStakesByIdsmultiGetObjects query
tryGetPastObjectHistorical object queries
getNetworkMetricsUse indexer
getAddressMetricsUse indexer
getMoveCallMetricsUse indexer

Setting Up GraphQL Client

import { SuiGraphQLClient } from '@mysten/sui/graphql';

const graphqlClient = new SuiGraphQLClient({
	url: 'https://sui-mainnet.mystenlabs.com/graphql',
	network: 'mainnet',
});

Querying Transactions

Replace queryTransactionBlocks with a GraphQL query:

const result = await graphqlClient.query({
	query: `
    query QueryTransactions($sender: SuiAddress, $first: Int, $after: String) {
      transactions(
        first: $first
        after: $after
        filter: { sentAddress: $sender }
      ) {
        pageInfo {
          hasNextPage
          endCursor
        }
        nodes {
          digest
          effects {
            status
            epoch { epochId }
          }
        }
      }
    }
  `,
	variables: {
		sender: '0xabc...',
		first: 10,
	},
});

Available transaction filters:

  • sentAddress - Filter by sender address
  • affectedAddress - Filter by any address involved in the transaction
  • affectedObject - Filter by object ID that was affected
  • function - Filter by Move function called (e.g., 0x2::coin::transfer)
  • kind - Filter by transaction kind (SYSTEM or PROGRAMMABLE)
  • atCheckpoint / beforeCheckpoint / afterCheckpoint - Filter by checkpoint

Querying Events

Replace queryEvents with a GraphQL query:

const result = await graphqlClient.query({
	query: `
    query QueryEvents($type: String, $first: Int, $after: String) {
      events(
        first: $first
        after: $after
        filter: { type: $type }
      ) {
        pageInfo {
          hasNextPage
          endCursor
        }
        nodes {
          transactionModule {
            package { address }
            name
          }
          sender { address }
          contents {
            type { repr }
            bcs
          }
        }
      }
    }
  `,
	variables: {
		type: '0x2::coin::CoinCreated',
		first: 10,
	},
});

Available event filters:

  • type - Filter by event type (package, package::module, or full type)
  • module - Filter by emitting module
  • sender - Filter by transaction sender
  • atCheckpoint / beforeCheckpoint / afterCheckpoint - Filter by checkpoint

Fetching Multiple Transactions

Replace multiGetTransactionBlocks with a GraphQL query:

const result = await graphqlClient.query({
	query: `
    query MultiGetTransactions($digests: [String!]!) {
      multiGetTransactionEffects(keys: $digests) {
        transaction {
          digest
          transactionBcs
        }
        status
        epoch { epochId }
      }
    }
  `,
	variables: {
		digests: ['digest1', 'digest2', 'digest3'],
	},
});

Querying Historical Objects

Replace tryGetPastObject with a GraphQL query specifying a version:

const result = await graphqlClient.query({
	query: `
    query GetObjectAtVersion($id: SuiAddress!, $version: UInt53!) {
      object(address: $id, version: $version) {
        address
        version
        digest
        asMoveObject {
          contents {
            type { repr }
            bcs
          }
        }
      }
    }
  `,
	variables: {
		id: '0x123...',
		version: 42,
	},
});

Querying Coin Metadata

Replace getCoinMetadata and getTotalSupply with a GraphQL query:

const result = await graphqlClient.query({
	query: `
    query GetCoinMetadata($coinType: String!) {
      coinMetadata(coinType: $coinType) {
        name
        symbol
        description
        decimals
        iconUrl
        supply
      }
    }
  `,
	variables: {
		coinType: '0x2::sui::SUI',
	},
});

Querying Staked SUI

Replace getStakes with a GraphQL query:

const result = await graphqlClient.query({
	query: `
    query GetStakes($owner: SuiAddress!) {
      address(address: $owner) {
        stakedSuis {
          nodes {
            principal
            stakeActivationEpoch
            estimatedReward
            contents {
              bcs
            }
          }
        }
      }
    }
  `,
	variables: {
		owner: '0xabc...',
	},
});

Response Format Differences

The gRPC client uses the core API response format, which differs from JSON-RPC responses. See the @mysten/sui migration guide for details on the new response format.

Key differences:

// Transaction result access
- const status = result.effects?.status?.status;
+ const tx = result.Transaction ?? result.FailedTransaction;
+ const status = tx.effects.status.success;

// Include options
- { showEffects: true, showEvents: true }
+ { effects: true, events: true }

Client Extensions

Client extensions work the same way with both clients:

import { SuiGrpcClient } from '@mysten/sui/grpc';
import { deepbook } from '@mysten/deepbook-v3';
import { suins } from '@mysten/suins';

const client = new SuiGrpcClient({
	baseUrl: 'https://fullnode.mainnet.sui.io:443',
	network: 'mainnet',
}).$extend(deepbook({ address: myAddress }), suins());

// Use extended functionality
await client.deepbook.checkManagerBalance(manager, asset);
await client.suins.getName('0xabc...');

See Also

On this page