GraphQL API

本节介绍 Sui 的 GraphQL RPC。GraphQL RPC 是官方新数据访问栈的一部分,适合对象、交易、事件、余额等复杂查询;交易构造和提交仍优先使用 TypeScript SDK 的 gRPC/Core API。

官方已要求生态从 JSON-RPC 迁移到 gRPC 或 GraphQL RPC。新项目不应把 JSON-RPC 作为长期依赖。

端点

网络GraphQL 端点
Mainnethttps://graphql.mainnet.sui.io/graphql
Testnethttps://graphql.testnet.sui.io/graphql
Devnethttps://graphql.devnet.sui.io/graphql

GraphQL IDE(交互式查询工具)可通过浏览器直接访问上述 URL。

基础查询

查询链信息

query {
  chainIdentifier
  epoch {
    epochId
    startTimestamp
    endTimestamp
    referenceGasPrice
  }
}

查询对象

query GetObject {
  object(address: "0x...") {
    objectId
    version
    digest
    owner {
      ... on AddressOwner {
        owner {
          address
        }
      }
      ... on Shared {
        initialSharedVersion
      }
    }
    asMoveObject {
      contents {
        type { repr }
        json
      }
    }
  }
}

查询地址拥有的对象

query OwnedObjects {
  address(address: "0x...") {
    objects(
      filter: { type: "0xPACKAGE::hero::Hero" }
      first: 10
    ) {
      nodes {
        objectId
        asMoveObject {
          contents {
            json
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

交易查询

查询交易详情

query GetTransaction {
  transactionBlock(digest: "...") {
    digest
    sender {
      address
    }
    effects {
      status
      gasEffects {
        gasSummary {
          computationCost
          storageCost
          storageRebate
        }
      }
      objectChanges {
        nodes {
          outputState {
            objectId
            asMoveObject {
              contents { json }
            }
          }
        }
      }
    }
  }
}

查询地址的交易历史

query TransactionHistory {
  address(address: "0x...") {
    transactionBlocks(
      first: 20
      scanLimit: 100
      filter: {}
    ) {
      nodes {
        digest
        effects {
          status
          timestamp
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

事件查询

query Events {
  events(
    filter: {
      eventType: "0xPACKAGE::hero::HeroCreated"
    }
    first: 20
  ) {
    nodes {
      sendingModule {
        name
        package { address }
      }
      type { repr }
      json
      timestamp
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

分页

GraphQL API 使用基于游标的分页:

# 第一页
query FirstPage {
  objects(
    filter: { type: "0xPACKAGE::hero::Hero" }
    first: 10
  ) {
    nodes {
      objectId
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

# 下一页:使用上一页的 endCursor
query NextPage {
  objects(
    filter: { type: "0xPACKAGE::hero::Hero" }
    first: 10
    after: "eyJj..."  # endCursor from previous page
  ) {
    nodes {
      objectId
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

TypeScript 客户端

使用 fetch 调用

const GRAPHQL_URL = 'https://graphql.testnet.sui.io/graphql';

async function queryGraphQL(query: string, variables?: Record<string, any>) {
  const response = await fetch(GRAPHQL_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, variables }),
  });

  const result = await response.json();
  if (result.errors) {
    throw new Error(result.errors[0].message);
  }
  return result.data;
}

// 使用示例
const data = await queryGraphQL(`
  query GetHeroes($owner: SuiAddress!) {
    address(address: $owner) {
      objects(filter: { type: "0xPACKAGE::hero::Hero" }, first: 10) {
        nodes {
          objectId
          asMoveObject {
            contents { json }
          }
        }
      }
    }
  }
`, { owner: '0x...' });

使用 graphql-request 库

import { GraphQLClient, gql } from 'graphql-request';

const client = new GraphQLClient(GRAPHQL_URL);

const query = gql`
  query GetObject($id: SuiAddress!) {
    object(address: $id) {
      objectId
      version
      asMoveObject {
        contents {
          type { repr }
          json
        }
      }
    }
  }
`;

const data = await client.request(query, { id: '0x...' });

动态字段查询

query DynamicFields {
  object(address: "0x...") {
    dynamicFields(first: 10) {
      nodes {
        name {
          json
        }
        value {
          ... on MoveValue {
            json
          }
          ... on MoveObject {
            contents {
              json
            }
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

GraphQL RPC、gRPC 与 JSON-RPC

方面GraphQL RPCgRPC/Core APIJSON-RPC
字段选择精确请求需要的字段按 Core/API 方法返回返回预定义字段集
适用场景复杂读取、分析、报表、索引dApp 读写、PTB 构造、交易执行旧脚本兼容
类型系统GraphQL schemaTypeScript 类型 + protobuf文档型
分页游标分页游标分页limit/offset
长期建议推荐推荐迁移期使用

小结

  • Sui GraphQL RPC 提供比 JSON-RPC 更灵活的查询能力
  • 使用精确的字段选择减少网络传输和解析开销
  • 游标分页适合处理大量数据
  • 嵌套查询可以在单次请求中获取关联数据
  • GraphQL IDE 是探索和调试查询的好工具
  • 适合构建需要复杂查询的应用前端和后端服务
  • 交易构造、提交和钱包交互优先使用 gRPC/Core API;JSON-RPC 仅用于旧项目迁移