llms.txt
@mysten/sui v2.0 and a new dApp Kit are here! Check out the migration guide
Mysten Labs SDKs
Clients

Sui Clients

Choose between SuiGrpcClient and SuiGraphQLClient and understand their shared API

A client is how your code reads from and writes to the Sui network. There are two to choose from, and they implement the same API (the same method names, options, and response shapes), so the choice is about which transport suits your application, not about which features you get.

ClientChoose it for
SuiGrpcClientThe default. Reads from a full node, and the only client with real-time subscriptions
SuiGraphQLClientReads from the indexer, and custom queries written against the GraphQL schema

Both are fully supported primary choices. Pick SuiGrpcClient if you have no particular reason to prefer one, and SuiGraphQLClient when your application wants to query the GraphQL schema directly. Because they share an API, moving between them is mostly a matter of changing the constructor.

JSON-RPC is deprecated. See the migration guide if you maintain existing JSON-RPC code.

Quick start

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

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

const { balance } = await client.getBalance({ owner: '0x...' });

const { object } = await client.getObject({
	objectId: '0x...',
	include: { content: true },
});

The same code against GraphQL differs only in how the client is created:

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

const client = new SuiGraphQLClient({
	network: 'mainnet',
	url: 'https://graphql.mainnet.sui.io/graphql',
});

Three ways to call a client

Each client exposes the same functionality through three surfaces, aimed at different callers.

Top-level methods

The main API for application code. Read data, execute transactions, and query history by calling methods directly on the client:

const { objects } = await client.listOwnedObjects({
	owner: '0x...',
	include: { display: true },
});

const result = await client.signAndExecuteTransaction({
	transaction,
	signer,
	include: { effects: true, balanceChanges: true },
});

These are documented in Querying data and Signing and execution. Where a transport can return more than the shared shape carries, it adds options here, such as include: { protoJson: true } on gRPC.

client.core

The transport-agnostic contract, for libraries that must work with whichever client their caller supplies:

import type { ClientWithCoreApi } from '@mysten/sui/client';

export async function fetchResource(client: ClientWithCoreApi, objectId: string) {
	return client.core.getObject({
		objectId,
		include: { content: true },
	});
}

See the Core API for the contract and the cross-transport differences to account for. Application code does not need this. Call the top-level methods instead.

Native APIs

Each client also exposes its transport in full, for the cases the shared API does not cover:

// gRPC: generated service clients, read masks, and streams
const { response } = await grpcClient.ledgerService.getServiceInfo({});

// GraphQL: type-safe custom queries
const result = await graphqlClient.query({
	query: graphql(`
		query {
			chainIdentifier
		}
	`),
});

gRPC adds raw list RPCs and subscriptions; GraphQL adds custom queries against the schema.

Client extensions

Both clients support extensions through $extend, which lets SDKs such as @mysten/walrus add functionality to a client your application already configured:

import { walrus } from '@mysten/walrus';

const client = new SuiGrpcClient({ network: 'mainnet', baseUrl: '...' }).$extend(walrus());

const { blobId } = await client.walrus.writeBlob({
	blob: file,
	deletable: false,
	epochs: 3,
	signer: keypair,
});

See Building SDKs for creating your own.

On this page