概述
SQL Explorer REST API允许您通过编程方式对已建立索引的区块链数据执行 SQL 查询。您可以使用标准 SQL 语法查询数十亿行链上数据,并以 JSON 格式获取结果。
您可以通过以下两种方式使用 SQL Explorer:
- 使用仪表盘:在用户界面中构建和测试查询,然后导出为 API 调用
- 使用 REST API:通过编程方式获取模式,并在代码中完全构建查询
身份验证
所有对 SQL Explorer REST API 的请求都必须通过 API 密钥进行身份验证。API 密钥必须包含在 x-api-key 每个请求都包含该标头。
要获取您的 API 密钥:
- 登录您的Quicknode 控制面板
- 点击左侧边栏右上角的“个人资料”图标
- 从下拉菜单中选择API 密钥
- 您可以点击“创建 API 密钥”为 SQL Explorer 创建一个新的 API 密钥,或者使用已启用 SQL Explorer 功能的现有 API 密钥
注意:这是所有 Quicknode 产品(RPC、Streams、IPFS 等)通用的 API 密钥系统。
快速入门
以下是通过编程方式使用 SQL Explorer 的完整工作流:
步骤 1:获取模式
获取目标链中可用的表和列。请将 {clusterId} 替换为所需的集群 ID(例如, hyperliquid-core-mainnet (用于 Hyperliquid)以及 YOUR_API_KEY 使用您从 身份验证 上文所述部分。参见 模式端点 对于所有受支持的集群 ID。
curl https://api.quicknode.com/sql/rest/v1/schema/{clusterId} \
-H "x-api-key: YOUR_API_KEY"
或者,您可以从“模式参考”页面下载静态模式文件。
步骤 2:编写 SQL 查询语句
根据该模式,编写您的查询:
SELECT toDateTime(block_time) AS time, 操作类型, 用户
FROM hyperliquid_system_actions
WHERE block_time >= now() - INTERVAL 1 天
排序 按 block_time DESC
限制 100
步骤 3:执行查询
将请求发送到查询端点,并附上目标集群 ID(详情请参阅“查询端点”):
curl -X POST 'https://api.quicknode.com/sql/rest/v1/query' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY' \
-d '{
"query": "SELECT toDateTime(block_time) AS time, action_type, user FROM hyperliquid_system_actions WHERE block_time >= now() - INTERVAL 1 DAY ORDER BY block_time DESC LIMIT 100",
"clusterId": "{clusterId}"
}'
可用端点
SQL Explorer 提供了两个 REST API 端点:
| 端点 | 目的 |
|---|---|
| POST /sql/rest/v1/query | 执行 SQL 查询并获取结果 |
| GET /sql/rest/v1/schema/{clusterId} | 获取数据库模式(表、列、数据类型、排序键) |
基础网址: https://api.quicknode.com
模式端点
获取完整的数据库模式,包括表名、列、数据类型、排序键和分区策略。
终点:
GET https://api.quicknode.com/sql/rest/v1/schema/{clusterId}
支持的集群 ID:
| 链 | 网络 | 集群 ID |
|---|---|---|
| 超流体 | 主网 | hyperliquid-core-mainnet |
请求示例:
curl https://api.quicknode.com/sql/rest/v1/schema/hyperliquid-core-mainnet \
-H "x-api-key: 您的API密钥"
示例回复:
[
{
"chain": "Hyperliquid (HyperCore)",
"clusterId": "hyperliquid-core-mainnet",
"tables": [
{
"name": "hyperliquid_agents",
"engine": "SharedReplacingMergeTree",
"total_rows": 81120375,
"partition_key": "toYYYYMM(snapshot_time)",
"sorting_key": ["block_number", "agent"],
"columns": [
{
"name": "agent",
"type": "FixedString(42)"
},
{
"name": "block_number",
"type": "UInt64"
},
{
"name": "snapshot_time",
"type": "DateTime64(6, 'UTC')"
}
// ... more columns
]
}
// ... more tables
]
}
]
另一种方法:从“模式参考”页面下载静态模式文件(无需 API 密钥),文件格式为 JSON 或纯文本。
查询端点
执行 SQL 查询并获取结果。
终点:
POST https://api.quicknode.com/sql/rest/v1/query
请求参数:
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| 查询 | 字符串 | 是 | 要执行的 SQL 查询 |
| clusterId | 字符串 | 是 | 区块链网络标识符(例如,“hyperliquid-core-mainnet”) |
请求示例:
- cURL
- JavaScript
Python
- Ruby
curl -X POST 'https://api.quicknode.com/sql/rest/v1/query' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY' \
-d '{
"query": "SELECT toDateTime(block_time) AS time, action_type, user FROM hyperliquid_system_actions WHERE block_time >= now() - INTERVAL 1 DAY ORDER BY block_time DESC LIMIT 100",
"clusterId": "{clusterId}"
}'
var myHeaders = new Headers();
myHeaders.append('accept', 'application/json');
myHeaders.append('Content-Type', 'application/json');
myHeaders.append('x-api-key', 'YOUR_API_KEY');
var requestOptions = {
method: 'POST',
headers: myHeaders,
redirect: 'follow',
body: JSON.stringify({
query: 'SELECT toDateTime(block_time) AS time, action_type, user FROM hyperliquid_system_actions WHERE block_time >= now() - INTERVAL 1 DAY ORDER BY block_time DESC LIMIT 100',
clusterId: '{clusterId}'
})
};
fetch('https://api.quicknode.com/sql/rest/v1/query', requestOptions)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error));
import requests
import json
url = "https://api.quicknode.com/sql/rest/v1/query"
payload = json.dumps({
"query": "SELECT toDateTime(block_time) AS time, action_type, user FROM hyperliquid_system_actions WHERE block_time >= now() - INTERVAL 1 DAY ORDER BY block_time DESC LIMIT 100",
"clusterId": "{clusterId}"
})
headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://api.quicknode.com/sql/rest/v1/query")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["accept"] = "application/json"
request["Content-Type"] = "application/json"
request["x-api-key"] = "YOUR_API_KEY"
request.body = JSON.dump({
"query": "SELECT toDateTime(block_time) AS time, action_type, user FROM hyperliquid_system_actions WHERE block_time >= now() - INTERVAL 1 DAY ORDER BY block_time DESC LIMIT 100",
"clusterId": "{clusterId}"
})
response = https.request(request)
puts response.read_body
回复格式:
该 API 会返回一个包含查询结果、元数据和执行统计信息的 JSON 响应。
响应字段:
元数据: 包含以下内容的列元数据数组:名称以及类型对于结果集中的每一列数据: 包含实际查询结果的对象数组,其中每个对象代表一行行: 此响应中返回的行数至少在限制值之前的行数: 应用 LIMIT 之前与查询条件匹配的行数总和(用于分页)统计数据: 查询优化的性能指标:已过去: 查询总执行时间(单位:秒)rows_read: 执行过程中扫描的行总数(由于过滤操作,该数值可能多于返回的行数)bytes_read: 扫描的数据总量(以字节为单位)(有助于理解查询成本和优化机会)
示例回复:
{
"meta": [
{
"name": "time",
"type": "DateTime('UTC')"
},
{
"name": "action_type",
"type": "LowCardinality(String)"
}
],
"data": [
{
"time": "2026-03-30 18:05:15",
"action_type": "SystemSpotSendAction",
"user": "0x2222222222222222222222222222222222222222"
},
{
"time": "2026-03-30 18:05:14",
"action_type": "SystemSpotSendAction",
"user": "0x2000000000000000000000000000000000000153"
}
],
"rows": 100,
"rows_before_limit_at_least": 14781,
"statistics": {
"elapsed": 0.004817085,
"rows_read": 33599,
"bytes_read": 1009864
}
}
分页
SQL Explorer 将查询结果限制为 每次请求1000行. 要检索更大的结果集,请使用分页功能,配合 LIMIT 以及 OFFSET SQL 查询中的子句。
分页原理
分页的工作原理如下:
- 使用
LIMIT用于指定每页返回的行数(最多 1000 行) - 使用
OFFSET跳过前几页的行 - 使用
至少在限制值之前的行数响应中的该字段,用于判断是否还有更多结果
分页的关键响应字段:
行: 当前响应中返回的行数至少在限制值之前的行数: 应用前与您的查询匹配的行总数LIMIT. 使用此方法计算总页数,并确定何时停止分页。
分页的基本示例
若要以每页100行的方式分页显示结果:
第 1 页(第 1-100 行):
- cURL
- JavaScript
Python
curl -X POST 'https://api.quicknode.com/sql/rest/v1/query' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY' \
-d '{
"query": "SELECT timestamp, coin, side, price, size, price * size AS notional_usd, buyer_address, seller_address, buyer_fee, seller_fee, fee_token FROM hyperliquid_trades WHERE block_time > now() - INTERVAL 1 HOUR ORDER BY block_number DESC, trade_id DESC LIMIT 100 OFFSET 0",
"clusterId": "hyperliquid-core-mainnet"
}'
const pageSize = 100;
const pageNumber = 1;
const offset = (pageNumber - 1) * pageSize;
var myHeaders = new Headers();
myHeaders.append('accept', 'application/json');
myHeaders.append('Content-Type', 'application/json');
myHeaders.append('x-api-key', 'YOUR_API_KEY');
var requestOptions = {
method: 'POST',
headers: myHeaders,
redirect: 'follow',
body: JSON.stringify({
query: `SELECT timestamp, coin, side, price, size, price * size AS notional_usd, buyer_address, seller_address, buyer_fee, seller_fee, fee_token FROM hyperliquid_trades WHERE block_time > now() - INTERVAL 1 HOUR ORDER BY block_number DESC, trade_id DESC LIMIT ${pageSize} OFFSET ${offset}`,
clusterId: 'hyperliquid-core-mainnet'
})
};
fetch('https://api.quicknode.com/sql/rest/v1/query', requestOptions)
.then(response => response.json())
.then(result => {
console.log(`Page ${pageNumber}: ${result.rows} rows`);
console.log(`Total matching rows: ${result.rows_before_limit_at_least}`);
})
.catch(error => console.log('error', error));
import requests
import json
page_size = 100
page_number = 1
offset = (page_number - 1) * page_size
url = "https://api.quicknode.com/sql/rest/v1/query"
payload = json.dumps({
"query": f"SELECT timestamp, coin, side, price, size, price * size AS notional_usd, buyer_address, seller_address, buyer_fee, seller_fee, fee_token FROM hyperliquid_trades WHERE block_time > now() - INTERVAL 1 HOUR ORDER BY block_number DESC, trade_id DESC LIMIT {page_size} OFFSET {offset}",
"clusterId": "hyperliquid-core-mainnet"
})
headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY'
}
response = requests.request("POST", url, headers=headers, data=payload)
result = response.json()
print(f"Page {page_number}: {result['rows']} rows")
print(f"Total matching rows: {result['rows_before_limit_at_least']}")
第 2 页(第 101-200 行):
curl -X POST 'https://api.quicknode.com/sql/rest/v1/query' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY' \
-d '{
"query": "SELECT timestamp, coin, side, price, size, price * size AS notional_usd, buyer_address, seller_address, buyer_fee, seller_fee, fee_token FROM hyperliquid_trades WHERE block_time > now() - INTERVAL 1 HOUR ORDER BY block_number DESC, trade_id DESC LIMIT 100 OFFSET 100",
"clusterId": "hyperliquid-core-mainnet"
}'
分页响应示例
使用分页时,请注意以下响应字段:
{
"meta": [...],
"data": [...],
"rows": 100,
"rows_before_limit_at_least": 4567,
"statistics": {
"elapsed": 0.042,
"rows_read": 15847,
"bytes_read": 2456789
}
}
行数:100- 该页面返回了 100 行rows_before_limit_at_least:4567- 共有至少 4,567 行符合您的查询条件- 如果
rows < LIMIT, 您已浏览到最后一页 - 如果
rows_before_limit_at_least > (OFFSET + rows),还有更多页面可供浏览
查询操作
预构建查询
SQL Explorer 包含针对 Hyperliquid 的预构建查询,涵盖交易、市场分析、持仓跟踪和基础设施监控等多个类别:交易、成交、订单、资金、基础设施、账本、市场、构建器和质押。
请在“Hyperliquid 查询”页面中查看所有预构建查询及其请求和响应示例。
自定义查询
除了预设的查询外,您还可以编写自定义的 SQL 查询。SQL Explorer 支持标准 SQL 语法,包括:
- 功能:
toDateTime(),base58Encode(),countIf(),round(),等等。 - 高级功能:子查询、CTE、窗口函数、
GROUP BY, 聚合,加入运营
两种方法:
- 以仪表盘为先:在SQL Explorer 仪表盘中测试查询,然后点击“API”按钮将其导出为代码
- 代码优先:按照上面的“快速入门”工作流,通过编程方式构建查询
构建自定义数据 API:
SQL Explorer 允许您通过编程方式执行任何 SQL 查询。您可以将查询封装到自己的后端服务中,以创建自定义端点、构建可重用的数据 API,或在仪表盘、移动应用和交易机器人中复用相同的查询。
我们 ❤️ 您的反馈!
如果您对本文档有任何反馈或疑问,请告诉我们。我们非常期待您的反馈!