Querying Sui RPC with GraphQL
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.
Both Mainnet and Testnet services are rate-limited to keep network throughput optimized.
- Mainnet: https://graphql.mainnet.sui.io/graphql
- Testnet: https://graphql.testnet.sui.io/graphql
- Devnet: https://graphql.devnet.sui.io/graphql
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 withTransaction
Owner
has been merged withAddress
dryRunTransactionBlock
is being replaced withsimulateTransaction
bcs
fields are qualified with the type of BCS data they hold, to avoid confusion.changedObject
andinputObject
filters intransactions
query are being replaced withaffectedObject
.address.coins
andaddress.stakedSuis
are being deprecated in favor ofaddress.objects
with the correspondingtype
filter.MoveValue.data
has been deprecated because it does not add value overMoveValue.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
- Beta
- Alpha (deprecated)
query {
epoch {
referenceGasPrice
}
}
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.
- Beta
- Alpha (deprecated)
query {
epoch(epochId: 100)
{
epochId
totalStakeRewards
referenceGasPrice
totalCheckpoints
totalGasFees
totalStakeSubsidies
storageFund {
totalObjectStorageRebates
nonRefundableBalance
}
}
}
query {
epoch(id: 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.
- Beta
- Alpha (deprecated)
query {
transaction(digest: "FdK...qK2") {
gasInput {
gasSponsor {
address
}
gasPrice
gasBudget
}
effects {
status
timestamp
checkpoint {
sequenceNumber
}
epoch {
epochId
referenceGasPrice
}
}
}
}
query {
transactionBlock(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
- Beta
- Alpha (deprecated)
This example demonstrates future functionality.
query {
transactions(last: 10, filter: {kind: PROGRAMMABLE_TX}) {
nodes {
digest
kind {
__typename
}
}
}
}
query {
transactionBlocks(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.
This example uses GraphQL variables and pagination.
- Beta
- Alpha (deprecated)
query ($objectID: SuiAddress!) {
transactions(filter: {affectedObject: $objectID}) {
nodes {
sender {
address
}
digest
effects {
objectChanges {
nodes {
address
}
}
}
}
}
}
This example demonstrates future functionality.
query ($objectID: SuiAddress!) {
transactionBlocks(filter: {changedObject: $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.
This example makes use of the last
filter. In this case, returns only the last 10
transactions known to the service.
- Beta
- Alpha (deprecated)
This example demonstrates future functionality.
{
transactions(
last: 10,
filter: {
function: "0x2::transfer::public_transfer"
}
) {
nodes { digest }
}
}
{
transactionBlocks(
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.
- Beta
- Alpha (deprecated)
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
}
}
}
}
}
}
query ($address: SuiAddress!) {
transactionBlocks(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
This example uses aliases and fragments.
- Beta
- Alpha (deprecated)
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
}
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
}
data
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.
- Beta
- Alpha (deprecated)
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
}
query ($id: SuiAddress!) {
owner(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
.
This example uses GraphQL variables and pagination.
- Beta
- Alpha (deprecated)
query ($after: String) {
checkpoints(first: 5, after: $after) {
pageInfo {
hasNextPage
endCursor
}
nodes {
digest
timestamp
}
}
}
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
.
This example uses GraphQL variables and pagination.
- Beta
- Alpha (deprecated)
query ($before: String) {
checkpoints(last: 5, before: $before) {
pageInfo {
hasPreviousPage
startCursor
}
nodes {
digest
timestamp
}
}
}
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
.
- Beta
- Alpha (deprecated)
mutation ($tx: String!, $sigs: [String!]!) {
executeTransaction(transactionDataBcs: $tx, signatures: $sigs) {
errors
effects {
status
epoch {
startTimestamp
}
gasEffects {
gasSummary {
computationCost
}
}
}
}
}
mutation ($tx: String!, $sigs: [String!]!) {
executeTransactionBlock(txBytes: $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.
- JSON-RPC
- GraphQL
{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_getTotalTransactionBlocks",
"params": []
}
query {
checkpoint {
networkTotalTransactions
}
}
Example 2: Get a specific transaction
Get the transaction by its digest.
- JSON-RPC
- GraphQL
{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_getTransactionBlock",
"params": [
"Hay2tj3GcDYcE3AMHrej5WDsHGPVAYsegcubixLUvXUF",
{
"showInput": true,
"showRawInput": false,
"showEffects": true,
"showEvents": true,
"showObjectChanges": false,
"showBalanceChanges": false
}
]
}
query {
transaction(digest: "Hay2tj3GcDYcE3AMHrej5WDsHGPVAYsegcubixLUvXUF") {
gasInput {
gasSponsor {
address
}
gasPrice
gasBudget
}
effects {
status
timestamp
checkpoint {
sequenceNumber
}
epoch {
epochId
referenceGasPrice
}
}
}
}
Example 3: Get coin objects owned by an address
Return all Coin<0x2::sui::SUI>
objects that an address owns.
- JSON-RPC
- GraphQL
query {
"jsonrpc": "2.0",
"id": 1,
"method": "suix_getCoins",
"params": [
"0x5094652429957619e6efa79a404a6714d1126e63f551f4b6c7fb76440f8118c9", //owner
"0x2::sui::SUI", //coin type
"0xe5c651321915b06c81838c2e370109b554a448a78d3a56220f798398dde66eab", //cursor
3 //limit
]
}
query {
address(address: "0x5094652429957619e6efa79a404a6714d1126e63f551f4b6c7fb76440f8118c9") {
objects(
first: 3,
after: "vBIzCwAAAADMAQBQlGUkKZV2Gebvp5pASmcU0RJuY/VR9LbH+3ZED4EYyQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAARjb2luAAAAAAAAAARDb2luAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAA3N1aQAAAAAAAAADU1VJAAAAAAAAAAAB/////XBZUf9feyhb9cW+AOBraL10O9t0D9JAr+tIq2wXDJdl5/zP5w==",
filter: { type: "0x2::coin::Coin<0x2::sui::SUI>" }
) {
nodes {
address
}
}
}
}
The cursor is now passed in the after
(or before
) fields on the connection, and the limit in the first
or last
fields.
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
}
}
}
}
}
Related links
Use GraphQL to make Sui RPC calls. This feature is currently in Beta.
GraphQL is a public service for the Sui RPC that enables you to efficiently interact with the Sui network.
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 GraphiQL IDE for the Testnet network.
Sui GraphiQL IDE for the Mainnet network.