Skip to main content

Querying Sui RPC with GraphQL

info

Refer to Access Sui Data for an overview of options to access Sui network data.

The GraphQL RPC release stage is currently in beta. Refer to the high-level timeline for releases in Access Sui Data.

The quickest way to access the GraphQL service for Sui RPC is through the online IDE that provides a complete toolbox for fetching data and executing transactions on the network. The online IDE provides features such as auto-completion (use Ctrl+Space or just start typing), built-in documentation (Book icon, top-left), multi-tabs, and more.

The online IDE is available for Mainnet, Testnet, and Devnet. You can try the various queries on this page directly in the IDE.

info

Both Mainnet and Testnet services are rate-limited to keep network throughput optimized.

caution

Switch any apps that still use the GraphQL Alpha endpoints (https://sui-mainnet.mystenlabs.com/graphql, https://sui-testnet.mystenlabs.com/graphql, and https://sui-devnet.mystenlabs.com/graphql) as soon as possible. Migrate your apps to the GraphQL Beta endpoints to avoid disruption of service.

For more details about some concepts used in the following examples, see the GraphQL concepts page. Consult the GraphQL reference for full documentation on the supported schema.

Discovering the schema

GraphQL introspection exposes the schema supported by the RPC service. The IDE's Docs pane (Book icon, top-left) and Search dialog (Cmd + K on macOS or Ctrl + K on Windows and Linux) offer a way to browse introspection output interactively.

The official GraphQL introspection documentation provides an overview on introspection and how to interact with it programmatically.

Beta schema changes

Some of the schema updates for the beta version include:

Renames and deprecations

  • TransactionBlock is being replaced with Transaction
  • Owner has been merged with Address
  • dryRunTransactionBlock is being replaced with simulateTransaction
  • bcs fields are qualified with the type of BCS data they hold, to avoid confusion.
  • changedObject and inputObject filters in transactions query are being replaced with affectedObject.
  • address.coins and address.stakedSuis are being deprecated in favor of address.objects with the corresponding type filter.
  • MoveValue.data has been deprecated because it does not add value over MoveValue.json, which provides a more clear representation of the data.

Consistency

GraphQL Beta offers the ability to run a query at a fixed checkpoint (retention permitting). This allows clients to query the chain state at a particular snapshot in time over multiple arbitrary requests (GraphQL Alpha offered consistency across multiple requests as long as they were for pages of a paginated query).

Versioning

APIs for traversing different versions of packages and objects have been added. You can now list a package or object's versions, or go from one version of a package or object to another version by number, or the latest version.

Splitting up query APIs

Paginated query APIs were previously responsible for three kinds of query pattern, which will be broken up into two separate APIs:

  • A dedicated multi-get API that accepts a list of keys and returns a list of results.
  • A query API that offers the original core functionality: Efficient paginated results without having to supply a checkpoint range, but for limited combinations of filters.

Relaxed consistency cursors

Cursors in GraphQL Alpha indicated the checkpoint that pagination started at. Future pages would be fetched as if from this checkpoint. This is helpful for paginating owned objects of an address, but cannot express queries that update over time (like tracking a stream of events in real time). Cursors in GraphQL Beta have relaxed this constraint — only cursors for pages whose results do not flow in the same direction as time (such as owned object queries) remember their checkpoint.

The old behavior is reproducible by explicitly setting the checkpoint to query from (see the Consistency section).

Preserving Entity IDs

The service retains the ability to identify entities that have been pruned when they are referred to be other entities. For example, even if an object's previous transaction has been pruned, the service is still able to return the transaction digest.

Unpruned point lookups

Point look-ups (accessing an object by its ID and version, a transaction by its digest, a checkpoint by its sequence number, and so on) are generally unpruned, if GraphQL has access to an Archival Service.

More detailed retention API

The service provides more details about the retention of its underlying data through the ServiceConfig.retention field.

Governance

APIs related to governance and staking are removed in favor of using view functions to access the data at its source of truth on-chain.

Owned Coin Pagination

As there is no longer a dedicated API for fetching the coins owned by an address, whenever coins are returned by an owned object API (such as Query.objects with an owner filter or IAddressable.objects), they are grouped by coin type and sorted in descending balance order.

Example queries

The following queries show some common tasks you can perform with GraphQL.

Find the reference gas price for latest epoch

query {
epoch {
referenceGasPrice
}
}

Find a specific historical epoch

Find the total stake rewards, the reference gas price, the number of checkpoints and the total gas fees for epoch 100. In the query, the epochId argument is optional and defaults to the latest epoch.

query {
epoch(epochId: 100)
{
epochId
totalStakeRewards
referenceGasPrice
totalCheckpoints
totalGasFees
totalStakeSubsidies
storageFund {
totalObjectStorageRebates
nonRefundableBalance
}
}
}

Find a transaction by its digest

Get a transaction by its digest and show information such as the gas sponsor address, the gas price, the gas budget, and effects from executing that transaction.

query {
transaction(digest: "FdK...qK2") {
gasInput {
gasSponsor {
address
}
gasPrice
gasBudget
}
effects {
status
timestamp
checkpoint {
sequenceNumber
}
epoch {
epochId
referenceGasPrice
}
}
}
}

Find the last ten transactions that are not a system transaction

caution

This example demonstrates future functionality.

query {
transactions(last: 10, filter: {kind: PROGRAMMABLE_TX}) {
nodes {
digest
kind {
__typename
}
}
}
}

Find all transactions that touched a given object

Find all the transactions that touched (modified/transferred/deleted) a given object. Useful when you want to trace the flow of a Coin, StakeSui, NFT, or similar object.

info

This example uses GraphQL variables and pagination.

query ($objectID: SuiAddress!) {
transactions(filter: {affectedObject: $objectID}) {
nodes {
sender {
address
}
digest
effects {
objectChanges {
nodes {
address
}
}
}
}
}
}

Variables

When using the online IDE, copy the following JSON to the Variables window, below the main editor.

{
"objectID": "0x11c6ae8432156527fc2e12e05ac7db79f2e972510a823a4ef2e670f27ad7b52f"
}

Filter transactions by a function

Find the last ten transactions that called the public_transfer function as a Move call transaction command.

info

This example makes use of the last filter. In this case, returns only the last 10 transactions known to the service.

caution

This example demonstrates future functionality.

{
transactions(
last: 10,
filter: {
function: "0x2::transfer::public_transfer"
}
) {
nodes { digest }
}
}

Find transaction balance changes

Find the balance changes of all the transactions where a given address called a staking-related function. Useful when you want to get your staking or unstaking history.

caution

This example demonstrates future functionality.

query ($address: SuiAddress!) {
transactions(filter: {
function: "0x3::sui_system::request_add_stake"
sentAddress: $address
}) {
nodes {
digest
effects {
balanceChanges {
nodes {
owner {
address
}
amount
}
}
}
}
}
}

Variables

When using the online IDE, copy the following JSON to the Variables window, below the main editor.

{
"address": "0xa9ad44383140a07cc9ea62d185c12c4d9ef9c6a8fd2f47e16316229815862d23"
}

Fetch a dynamic field on an object

info

This example uses aliases and fragments.

query DynamicField {
object(
address: "0xb57fba584a700a5bcb40991e1b2e6bf68b0f3896d767a0da92e69de73de226ac"
) {
dynamicField(
name: {
type: "0x2::kiosk::Lock",
bcs: "NLArx1UJguOUYmXgNG8Pv8KbKXLjWtCi6i0Yeq1Vhfw=",
}
) {
...DynamicFieldSelect
}
}
}

fragment DynamicFieldSelect on DynamicField {
name {
...MoveValueFields
}
value {
...DynamicFieldValueSelection
}
}

fragment DynamicFieldValueSelection on DynamicFieldValue {
__typename
... on MoveValue {
...MoveValueFields
}
... on MoveObject {
hasPublicTransfer
contents {
...MoveValueFields
}
}
}

fragment MoveValueFields on MoveValue {
type {
repr
}
json
bcs
}

Fetch all dynamic fields on an object

Paginate over the dynamic fields of an object. This works even when the object in question is wrapped by using the owner query. Can be used for iterating over the elements of on-chain data structures, like tables and bags. See The Move Book to learn more about dynamic collections available in Move.

info

This example uses fragments and variables.

query ($id: SuiAddress!) {
address(address: $id) {
dynamicFields {
nodes {
name { ...Value }
value {
__typename
... on MoveValue {
...Value
}
... on MoveObject {
contents {
...Value
}
}
}
}
}
}
}

fragment Value on MoveValue {
type {
repr
}
json
}

Paginate checkpoints forward five at a time

Set up a paginated query starting at the genesis checkpoint, reading five checkpoints at a time in increasing order of sequence number. The value of pageInfo.hasNextPage determines whether there is another page to read. The value of pageInfo.endCursor is used as the cursor to read $after.

info

This example uses GraphQL variables and pagination.

query ($after: String) {
checkpoints(first: 5, after: $after) {
pageInfo {
hasNextPage
endCursor
}
nodes {
digest
timestamp
}
}
}

Paginate checkpoints backwards five at a time

Set up a paginated query starting at the latest indexed checkpoint, reading five checkpoints at a time in decreasing order of sequence number. The value of pageInfo.hasPreviousPage determines whether there is another page to read. The value of pageInfo.startCursor is used as the cursor to read $before.

info

This example uses GraphQL variables and pagination.

query ($before: String) {
checkpoints(last: 5, before: $before) {
pageInfo {
hasPreviousPage
startCursor
}
nodes {
digest
timestamp
}
}
}

Execute a transaction

Transaction execution takes two arguments, transactionDataBcs and signatures. transactionDataBcs is the serialized unsigned transaction data, which the Sui Client CLI client call command can generate. Pass the --serialize-unsigned-transaction flag to the command to call a Move function. The Sui Keytool CLI command sui keytool sign can generate the signatures.

mutation ($tx: String!, $sigs: [String!]!) {
executeTransaction(transactionDataBcs: $tx, signatures: $sigs) {
errors
effects {
status
epoch {
startTimestamp
}
gasEffects {
gasSummary {
computationCost
}
}
}
}
}

Variables

When using the online IDE, copy the following JSON to the Variables window, below the main editor.

{
"tx": "AAACACAZXApmrHgzTs3FGDyXWka+wmMCy2IwOdKLmTWHb5PnFQEASlCnLAw4qfzLF3unH9or5/L7YpOlReaSEWfoEwhTqpavSxAAAAAAACCUFUCOn8ljIxcG9O+CA1bzqjunqr4DLDSzSoNCkUvu2AEBAQEBAAEAALNQHmLi4jgC5MuwwmiMvZEeV5kuyh+waCS60voE7fpzAa3v/tOFuqDvQ+bjBpKTfjyL+6yIg+5eC3dKReVwghH/rksQAAAAAAAgxtZtKhXTr1zeFAo1JzEqVKn9J1H74ddbCJNVZGo2I1izUB5i4uI4AuTLsMJojL2RHleZLsofsGgkutL6BO36c+gDAAAAAAAAQEIPAAAAAAAA",
"sigs": [
"AB4ZihXxUMSs9Ju5Cstuuf/hvbTvvycuRk2TMuagLYNJgQuAeXmKyJF9DAXUtL8spIsHrDQgemn4NmojcNl8HQ3JFqhnaTC8gMX4fy/rGgqgL6CDcbikawUUjC4zlkflwg=="
]
}

Migrating to GraphQL from JSON-RPC

The examples in the following sections demonstrate the typical API calls. The calls are tabbed to show both the JSON-RPC call and the equivalent GraphQL structure. For a comprehensive list of all available GraphQL features, consult the reference.

Example 1: Get total transactions

Get the total number of transactions in the network.

{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_getTotalTransactionBlocks",
"params": []
}

Example 2: Get a specific transaction

Get the transaction by its digest.

{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_getTransactionBlock",
"params": [
"Hay2tj3GcDYcE3AMHrej5WDsHGPVAYsegcubixLUvXUF",
{
"showInput": true,
"showRawInput": false,
"showEffects": true,
"showEvents": true,
"showObjectChanges": false,
"showBalanceChanges": false
}
]
}

Example 3: Get coin objects owned by an address

Return all Coin<0x2::sui::SUI> objects that an address owns.

query {
"jsonrpc": "2.0",
"id": 1,
"method": "suix_getCoins",
"params": [
"0x5094652429957619e6efa79a404a6714d1126e63f551f4b6c7fb76440f8118c9", //owner
"0x2::sui::SUI", //coin type
"0xe5c651321915b06c81838c2e370109b554a448a78d3a56220f798398dde66eab", //cursor
3 //limit
]
}

New features

The previous examples show GraphQL calls that perform the same function as their JSON-RPC equivalent. There is functionality available to GraphQL that can't be replicated with JSON-RPC, such as:

  • Time travel queries with checkpoint { query { ... } }.
  • Nested dynamic field look-ups (and paginating dynamic fields with their contents in one request).
  • Fetching live objects by owner kind and type (such as all shared objects of a certain type).
  • Fetching deserialized input and output object contents from a transaction that has just executed.

The following examples demonstrate some of the functions not available with JSON-RPC.

Example 4: Getting objects by type

Fetch the latest versions of objects of type 0x2::package::Publisher that are currently live on-chain.

query {
objects(filter: { type: "0x2::package::Publisher" }) {
nodes {
address
digest
asMoveObject {
contents { json }
}
}
}
}

Example 5: Paging through package versions

Find all versions of the Sui framework and list their modules:

query {
packageVersions(address: "0x2") {
nodes {
version
modules {
nodes {
name
}
}
}
}
}
GraphQL for Sui RPC (Beta)

Use GraphQL to make Sui RPC calls. This feature is currently in Beta.

GraphQL for Sui RPC (Alpha)

GraphQL is a public service for the Sui RPC that enables you to efficiently interact with the Sui network.

GraphQL and General-Purpose Indexer (Beta)

The GraphQL RPC Beta service offers a structured way for your clients to interact with data on the Sui blockchain. It accesses data processed by a general-purpose indexer and can connect to an archival store for historical network state.

Sui Testnet GraphiQL

Sui GraphiQL IDE for the Testnet network.

Sui Mainnet GraphiQL

Sui GraphiQL IDE for the Mainnet network.