按月自动发放重置机会,余额用完可一键补回到 3,000 万 CU。了解详情 →

HyperEVM:公共 RPC 限速下,历史回填和轮询怎么做

了解 HyperEVM 公共 RPC 的速率与功能限制,使用 BlockVectra 进行分段日志回填、错误重试判断、Data API 替代查询以及新区块轮询。

在 HyperEVM 上构建应用或进行链上数据同步时,开发者通常需要处理两项基础任务:一是拉取历史事件日志与交易(历史回填,Backfill),二是持续监听新产生的区块与事件(实时轮询,Polling)。

官方公共 RPC 与第三方节点服务在调用速率、支持方法与历史状态保留机制上各有明确定义。本文基于官方公布的文档与接口规范,说明两者的事实参数,并提供分段回填、基于错误体判定重试、使用 Data API 替代海量扫描以及轮询新区块的具体实现。

现状与官方公共 RPC 限制

根据 Hyperliquid 官方开发文档,公共 RPC 的限制与运行特性如下:

  1. 调用速率限制: 官方文档限速与用户限额说明中明确规定,针对公共端点 rpc.hyperliquid.xyz/evm,每个 IP 地址每分钟最多允许 100 次 EVM JSON-RPC 请求(Maximum of 100 EVM JSON-RPC requests per minute for rpc.hyperliquid.xyz/evm)。
  2. WebSocket 支持情况: 官方文档 HyperEVM 概述中明确指出,公共 RPC 端点 rpc.hyperliquid.xyz/evm 当前不支持 WebSocket JSON-RPC(There is currently no websocket JSON-RPC support for the RPC at rpc.hyperliquid.xyz/evm but other RPC implementations may support it)。
  3. 网络标识与端点:
    • 主网(Mainnet):Chain ID 为 999,官方公共 JSON-RPC 端点为 https://rpc.hyperliquid.xyz/evm。
    • 测试网(Testnet):Chain ID 为 998,官方公共 JSON-RPC 端点为 https://rpc.hyperliquid-testnet.xyz/evm。
  4. 硬分叉与费用机制: HyperEVM 基于 Cancun 硬分叉(支持 MCOPY、TSTORE 与 TLOAD 操作码),但不支持 blob 交易(blob transactions)。支持 EIP-1559 规范,但没有优先费用(no priority fees,优先费用同样被销毁并转入零地址,因此交易的 maxFeePerGas 与 maxPriorityFeePerGas 必须相等)。

在公共端点每分钟 100 次调用且不支持 WebSocket 的约束下,单 IP 若直接全量扫描历史日志或高频拉取最新区块,容易触发限流。

BlockVectra 参数与服务规则

BlockVectra 为 HyperEVM 主网提供 JSON-RPC 与 REST 风格的 Data API。接口规则与速率限制均来自公开端点与套餐规范:

  1. 链参数与日志范围: 根据公开接口 GET /v1/chains 中 hyperevm_mainnet 的记录:
    • 链标识(Slug):hyperevm_mainnet,Chain ID 为 999。
    • max_logs_block_range:以 GET /v1/chains 的 max_logs_block_range 字段为准。单次 eth_getLogs 请求的区块跨度(toBlock − fromBlock + 1)不能超过该上限。若跨度超出上限,平台返回 HTTP 200 与 JSON-RPC 错误码 -32602(eth_getLogs block range too large: max <N> blocks),该错误不计费。
    • state_window_blocks:以 GET /v1/chains 的 state_window_blocks 字段为准。状态读取方法(如 eth_call、eth_getBalance)受该字段声明的保留窗口约束(为 null 时表示全量保留,不设短期滚动窗口限制)。
    • 方法策略:以 methods.allow 与 methods.deny 字段为准。常用读取方法(eth_blockNumber、eth_getLogs、eth_call、eth_getBalance、eth_getBlockByNumber、eth_getTransactionReceipt 等)均开放;过滤和订阅方法(eth_subscribe、eth_unsubscribe、eth_newFilter、eth_newBlockFilter)已禁用,调用禁用方法返回 -32601(不计费)。
  2. 免费套餐速率限制与升级: 根据 GET /v1/plans 的数据:
    • free.max_calls_per_sec:以接口返回的免费套餐每秒调用次数上限为准(注明:该数值是账户内所有 API key 合计的平均值)。
    • 单 key 默认限制:每个 API key 均有 CU 令牌桶(cu_per_sec 补充速率、burst_cu 突发容量——默认 400 CU/s、突发 1,600 CU)。方法按 CU 权重计费(例如 eth_getLogs 为 30 CU,eth_blockNumber 为 1 CU,地址交易与转账为 25 CU)。
    • 限额提升:首次付费充值后,解除账户级每秒调用上限;每个 key 仍有默认 CU 速率与突发上限。关于当前费率与计费规则,请参阅定价页。

回填历史数据:分段 eth_getLogs 与重试判断

回填历史事件日志时,需要将大跨度区间按目标链的 max_logs_block_range 上限分块请求。同时,当网络抖动或触发限流时,应依据错误响应中的 retryable 字段判断是否重试。

错误体中的 retryable 判定

在 BlockVectra 平台上,JSON-RPC 错误响应的 error.data 包含 reason、docs_url 以及 retryable(布尔值):

  • retryable: true(可重试):例如瞬时过载(overloaded)、免费档每秒频次超限(free_plan_call_limit)、节点同步中(node_syncing)或底层暂时不可用(upstream_unavailable)。若 HTTP 响应头带有 Retry-After,应按指定秒数休眠;或采用带抖动的指数退避重试。
  • retryable: false(不可重试):例如区块跨度超限(-32602 / logs_range_too_large)、请求参数错误(invalid_params)、缺少 API key(missing_api_key)或突发容量超限(-32022 / request_exceeds_burst)。此类错误盲目重试无法成功,必须修正参数后再发起请求。

未带 API key 时的真实 401 响应体结构如下:

{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32024,
    "message": "missing API key: send it in the request path (/v1/{chain}/<api_key>) or in the x-api-key header",
    "data": {
      "reason": "missing_api_key",
      "docs_url": "https://docs.blockvectra.com/en/errors/#missing_api_key",
      "retryable": false
    }
  }
}

代码示例:分段拉取与重试

export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# 1. 验证目标链 max_logs_block_range(公开接口,免认证)
curl -s "https://api.blockvectra.com/v1/chains"

# 2. 单次分段请求(区间不超过 max_logs_block_range,如 0x1 到 0x3e8)
curl -s "https://api.blockvectra.com/v1/hyperevm_mainnet" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_getLogs",
    "params": [{
      "address": "0x2222222222222222222222222222222222222222",
      "fromBlock": "0x1",
      "toBlock": "0x3e8"
    }]
  }'

使用 Data API 替代大量 getLogs 扫描

当业务需求是追踪某个具体地址的交互历史,或者特定地址的代币划转时,通过 eth_getLogs 扫描需要按目标链的 max_logs_block_range 逐段发起请求,并手动过滤 Transfer 事件与解码数据。

BlockVectra 的 Data API 针对 hyperevm_mainnet 提供了按地址索引的专用端点(路径见 openapi/data.yaml),单次查询可覆盖最宽 100,000 个区块并支持游标分页:

  1. 地址交易列表:GET /v1/data/hyperevm_mainnet/addresses/{address}/transactions
    • 查询参数:from_block(必填)、to_block(必填)、direction(可选:from, to, any,默认 any)、clamp(可选,设为 true 可在区间超出 100,000 块或超出最新最终确认区块时自动截断,避免返回 409 错误)、limit(可选,最大 500)、cursor(分页游标)。
  2. 地址代币转账列表:GET /v1/data/hyperevm_mainnet/addresses/{address}/transfers
    • 查询参数:standard(必填:erc20 或 erc721;OpenAPI 明确声明 erc1155 不支持按地址查询并返回 422 no_coverage)、token(可选合约地址)、from_block(必填)、to_block(必填)、direction(可选:in, out, any)、clamp(可选)、limit、cursor。

响应结构说明(依据 OpenAPI 规范)

两个端点均返回标准信封:

  • data:数据对象数组。地址交易包含 hash、block_number、block_timestamp、from、to、value、tx_index、gas_limit、gas_used、status 等;代币转账包含 token、standard、from、to、block_number、block_timestamp、tx_hash、tx_index、log_index(ERC-20 包含 amount,ERC-721 包含 token_id)。
  • next_cursor:存在下一页数据时返回的不透明游标字符串;若为最后一页则该字段不存在(非 null)。
  • meta:包含 chain、chain_slug、chain_external_id、as_of_block、finalized_block、coverage(full 或 partial)以及 refreshed_at。

代码示例:调用 Data API

export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# 1. 查询地址历史交易(支持 clamp=true 避免 409)
curl -s "https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/0x2222222222222222222222222222222222222222/transactions?from_block=0&to_block=50000&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

# 2. 查询地址 ERC-20 转账记录
curl -s "https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/0x2222222222222222222222222222222222222222/transfers?standard=erc20&from_block=0&to_block=50000&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

实时追踪:轮询新区块

由于 HyperEVM 官方公共 RPC 不提供 WebSocket JSON-RPC 支持,且 BlockVectra 的方法策略中亦禁用了 eth_subscribe(methods.deny 中声明),实时监听新区块与新事件需要采用轮询机制。

轮询实现逻辑

  1. 定时调用轻量读取方法 eth_blockNumber(权重为 1 CU)获取链上最新高度。
  2. 比较当前高度与已处理高度 lastSeenBlock。
  3. 若 currentBlock > lastSeenBlock,则按区间 [lastSeenBlock + 1, currentBlock] 读取新产生的日志或区块数据,并更新 lastSeenBlock。
  4. viem 的 watchBlockNumber 或 watchBlocks 在 HTTP transport 下原生使用轮询机制,可通过 pollingInterval 参数自定义轮询周期(例如 1000 毫秒)。

代码示例:轮询最新区块

export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# 单次轮询最新区块高度(消耗 1 CU)
curl -s "https://api.blockvectra.com/v1/hyperevm_mainnet" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

相关文档与规则参考

下一步

最后更新:

本页目录