Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Network & Protocol Guides14 min read

Reading HyperEVM State over JSON-RPC: EVM Methods and HyperCore Bridge

A practical guide to reading HyperEVM state with standard EVM JSON-RPC methods, including chain identity checks, contract calls, and the HyperCore bridge.

TL;DR

Hyperliquid operates two distinct systems: HyperCore, the native order-book and perpetuals engine with its own Info and Exchange APIs, and HyperEVM, an Ethereum-compatible chain that exposes the standard eth_ JSON-RPC namespace. Developers must know which system holds the data they need—market and account state live on HyperCore, while smart-contract state and EVM balances live on HyperEVM. This guide explains how to verify chain identity with eth_chainId, read contract state using eth_call, eth_getBalance, eth_getCode, and eth_getLogs, and interact with the HyperCore-to-HyperEVM bridge. It includes runnable Node.js examples, a reproducible results table, and troubleshooting steps for common JSON-RPC errors.

The Two-System Architecture of Hyperliquid

Hyperliquid is not a single monolithic blockchain. It runs two distinct interfaces that serve different purposes. HyperCore is the native order-book and perpetuals engine, exposing its own Info and Exchange REST and WebSocket APIs for market data, account state, and order management. HyperEVM is a separate Ethereum-compatible chain that hosts EVM smart contracts and exposes the standard eth_ JSON-RPC namespace. This separation is documented in the Hyperliquid HyperEVM documentation.

For developers, the critical question is: which system holds the data I need? Market prices, order books, account balances on the perpetuals engine, and order history live on HyperCore. Smart-contract state, EVM token balances, and contract events live on HyperEVM. Cross-referencing both systems is often necessary for a complete picture. The Hyperliquid RPC latency: HyperEVM vs native API guide covers endpoint selection at a high level, while this article focuses on the EVM read surface.

  • HyperCore: native order-book and perpetuals engine; Info and Exchange APIs; market and account state.
  • HyperEVM: Ethereum-compatible chain; standard eth_ JSON-RPC methods; smart-contract state and EVM balances.
  • Data location determines which interface to query—mixing them up leads to empty or incorrect results.

HyperEVM Chain Identity and Runtime Verification

HyperEVM mainnet uses chain ID 999, as published on ChainList and in the Hyperliquid documentation. However, chain IDs can be spoofed or misconfigured on custom endpoints. Always verify the chain ID at runtime using eth_chainId before sending any state-changing or read requests. The eth_chainId method returns the chain ID as a hexadecimal string, while net_version returns it as a decimal string. Both are part of the standard Ethereum JSON-RPC specification, documented on ethereum.org.

A mismatch between the expected chain ID and the returned value indicates you are connected to the wrong network or a misconfigured endpoint. This check is especially important when using third-party RPC providers, where endpoint behavior is documented but varies by provider. For a list of Hyperliquid RPC endpoints, see the Hyperliquid RPC endpoints (RPC Assistant) page.

  • eth_chainId returns the chain ID as a hex string (0x3e7 for 999).
  • net_version returns the chain ID as a decimal string ("999").
  • Always verify chain ID before reading state to avoid querying the wrong network.

Standard EVM Read Methods on HyperEVM

HyperEVM exposes the same eth_ namespace methods as any Ethereum-compatible chain. The read-only methods most relevant for state inspection are eth_blockNumber, eth_getBalance, eth_call, eth_getCode, eth_getStorageAt, eth_getLogs, eth_getTransactionReceipt, and eth_getTransactionByHash. These methods behave identically to their Ethereum counterparts, as defined in the Ethereum JSON-RPC specification.

eth_blockNumber returns the latest block number. eth_getBalance returns the native token balance for an address. eth_call executes a read-only contract function without creating a transaction. eth_getCode returns the bytecode at a contract address, which is useful for verifying that a contract is deployed. eth_getStorageAt reads a specific storage slot. eth_getLogs retrieves event logs within a block range. eth_getTransactionReceipt and eth_getTransactionByHash provide transaction details. All of these methods are available on a HyperEVM endpoint, though provider-specific rate limits and caching behavior may vary.

  • eth_blockNumber: latest block height.
  • eth_getBalance: native token balance for an address.
  • eth_call: read-only contract function execution.
  • eth_getCode: contract bytecode at an address.
  • eth_getStorageAt: raw storage slot value.
  • eth_getLogs: event logs within a block range.
  • eth_getTransactionReceipt: transaction receipt by hash.
  • eth_getTransactionByHash: transaction details by hash.

The HyperCore to HyperEVM Bridge and Asset Movement

Assets such as HYPE can move between HyperCore and HyperEVM through a bridge mechanism. The bridge uses a system address on the EVM side to represent assets that originate from HyperCore. When reading balances, it is essential to query the correct side: a balance on HyperCore is not the same as a balance on HyperEVM, even for the same asset. The Hyperliquid HyperEVM documentation describes the bridge and the system address.

For integrators, this means that a user's HYPE balance on HyperCore (used for trading) is separate from their HYPE balance on HyperEVM (used in smart contracts). To display a unified balance, you must query both systems and combine the results. The bridge address itself is a contract on HyperEVM, and its state can be read using eth_call or eth_getBalance. Always confirm the bridge address for the specific network (mainnet vs testnet) from official documentation, as contract addresses differ per network.

  • HyperCore balance and HyperEVM balance are distinct; query both for a complete view.
  • The bridge system address on HyperEVM holds assets moved from HyperCore.
  • Contract addresses differ between mainnet and testnet—verify from official sources.

JSON-RPC Envelope and Error Shapes

All HyperEVM JSON-RPC requests follow the JSON-RPC 2.0 specification. A request object must include jsonrpc: "2.0", a unique id, a method string, and a params array (or object). The response contains either a result field or an error object with code, message, and optional data. Common error codes include -32601 (method not found), -32602 (invalid params), and -32000 (server error). Provider-specific errors may use custom codes.

When debugging, always check the error object first. A -32601 error usually means the method is not supported by the endpoint. A -32602 error indicates malformed parameters, such as an invalid address or block tag. A -32000 error can indicate rate limiting or an internal server issue. For rate limit specifics, see the Hyperliquid API rate limits guide.

  • Request: { jsonrpc: "2.0", id: 1, method: "eth_chainId", params: [] }
  • Success response: { jsonrpc: "2.0", id: 1, result: "0x3e7" }
  • Error response: { jsonrpc: "2.0", id: 1, error: { code: -32601, message: "Method not found" } }

Runnable Node.js Example: Chain ID, Block Number, Balance, and Code

The following Node.js script uses the native fetch API to send raw JSON-RPC requests to a HyperEVM endpoint. It first verifies the chain ID, then fetches the latest block number, the native balance of an address, and the bytecode at a contract address. Replace the endpoint URL with your provider's HyperEVM endpoint. This example assumes Node.js 18 or later, which includes fetch by default.

The script prints each result in a readable format. If you are using a provider that requires an API key, include it in the URL or headers as documented by that provider. The same pattern applies to any EVM-compatible chain, but the chain ID check ensures you are on HyperEVM.

const endpoint = 'https://your-hyperevm-endpoint.example';

async function rpc(method, params = []) {
  const response = await fetch(endpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params })
  });
  const data = await response.json();
  if (data.error) throw new Error(`${method}: ${data.error.message}`);
  return data.result;
}

async function main() {
  const chainId = await rpc('eth_chainId');
  console.log('Chain ID:', chainId, '(', parseInt(chainId, 16), ')');

  const blockNumber = await rpc('eth_blockNumber');
  console.log('Latest block:', parseInt(blockNumber, 16));

  const address = '0x0000000000000000000000000000000000000000';
  const balance = await rpc('eth_getBalance', [address, 'latest']);
  console.log('Balance:', parseInt(balance, 16) / 1e18, 'HYPE');

  const contract = '0xYourContractAddress';
  const code = await rpc('eth_getCode', [contract, 'latest']);
  console.log('Code length:', code.length);
}

main().catch(console.error);

Runnable Node.js Example: eth_call for a View Function

The eth_call method executes a read-only function on a smart contract. It requires a transaction object with to, data, and optionally from and gas. The data field is the ABI-encoded function selector and arguments. For a simple view function like balanceOf(address), the selector is 0x70a08231 followed by the 32-byte padded address. The following example calls balanceOf on a hypothetical ERC-20 contract and decodes the returned uint256.

This pattern works for any view or pure function. For complex return types, use a library like ethers.js or viem to encode and decode automatically. The raw JSON-RPC approach is useful for understanding the underlying mechanics and for lightweight scripts.

const endpoint = 'https://your-hyperevm-endpoint.example';

async function rpc(method, params = []) {
  const response = await fetch(endpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params })
  });
  const data = await response.json();
  if (data.error) throw new Error(`${method}: ${data.error.message}`);
  return data.result;
}

async function main() {
  const token = '0xYourTokenAddress';
  const holder = '0xYourHolderAddress';
  const selector = '0x70a08231';
  const paddedHolder = holder.slice(2).padStart(64, '0');
  const data = selector + paddedHolder;

  const result = await rpc('eth_call', [{ to: token, data }, 'latest']);
  const balance = BigInt(result);
  console.log('Token balance:', balance.toString());
}

main().catch(console.error);

Reproducible Results Table for Your Endpoint

To compare endpoints or verify provider behavior, fill in the following table with measurements from your own environment. Run each method multiple times and record the median latency. The table is intentionally blank so you can populate it with your own data. Do not rely on third-party benchmark numbers; measure against your specific endpoint and network conditions.

Use a consistent method for timing, such as performance.now() in Node.js or curl's time_total. Record the chain ID returned by eth_chainId to confirm you are on HyperEVM mainnet (0x3e7) or testnet. The latest block number will change over time, so note the timestamp of your measurement.

  • Endpoint URL: ________________
  • eth_chainId returned: ________________
  • Latest block (eth_blockNumber): ________________
  • Gas price (eth_gasPrice): ________________
  • eth_call latency (ms): ________________
  • eth_getBalance latency (ms): ________________
  • Timestamp of measurement: ________________

Limitations and Tradeoffs of HyperEVM JSON-RPC Reads

HyperEVM is a separate chain from the native HyperCore API. Cross-referencing market data with EVM state requires querying both interfaces, which introduces complexity and potential inconsistency if the two systems are not synchronized. There is no single JSON-RPC method that returns both HyperCore order-book data and HyperEVM contract state. Developers must design their data layer to handle both sources.

Contract addresses differ per network. An address on HyperEVM mainnet is not the same as on testnet, and the bridge system address may also differ. Always verify addresses from official documentation or on-chain sources. Endpoint behavior is documented but varies by provider: some providers may cache eth_call results, limit eth_getLogs block ranges, or impose rate limits. These variations can affect consistency and latency. For historical market data, the native APIs are more appropriate; see the Hyperliquid historical market data APIs guide.

  • Two systems: HyperCore for market/account state, HyperEVM for contract state.
  • No unified RPC method—cross-referencing requires both interfaces.
  • Contract addresses differ per network; verify from official sources.
  • Provider-specific caching, rate limits, and block range restrictions apply.

Troubleshooting Common HyperEVM JSON-RPC Issues

If eth_chainId returns an unexpected value, you are likely connected to the wrong network or a misconfigured endpoint. Double-check the endpoint URL and any API key. If eth_call returns an empty result or an error, verify the contract address, function selector, and argument encoding. A common mistake is using the wrong number of decimals or not padding addresses to 32 bytes. For eth_getLogs, if you receive an error about block range, reduce the range or use a provider that supports larger queries.

Rate limiting often manifests as HTTP 429 or JSON-RPC error -32000. Implement exponential backoff and consider using multiple endpoints. If a method is not found (-32601), the endpoint may not support that method; check the provider's documentation. For persistent issues, consult the Hyperliquid RPC endpoints (RPC Assistant) page or the OnFinality Learn hub for related guides.

  • Unexpected chain ID: check endpoint URL and network.
  • eth_call errors: verify address, selector, and argument padding.
  • eth_getLogs range errors: reduce block range or switch provider.
  • Rate limits: implement backoff and use multiple endpoints.
  • Method not found: confirm provider supports the method.

Next Steps and Further Resources

Now that you can read HyperEVM state, explore the native HyperCore APIs for market and account data. The Hyperliquid oracle prices and the builder auction guide explains how oracle prices are exposed via the Info API. For a complete list of supported networks, see the Hyperliquid network page. If you need reliable RPC access, consider OnFinality RPC pricing or the API service for managed endpoints.

To go deeper into performance and endpoint selection, read the Hyperliquid RPC latency: HyperEVM vs native API article. For rate limit specifics, the Hyperliquid API rate limits guide provides detailed thresholds. Always test against your own use case and measure with the results table above.

  • Explore HyperCore Info and Exchange APIs for market data.
  • Review the Hyperliquid network page for supported chains.
  • Consider managed RPC providers for production workloads.
  • Measure your own endpoint performance with the results table.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started