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

Monad JSON-RPC Methods: Ethereum-Compatible Surface

A practical reference for mapping Monad's Ethereum-compatible JSON-RPC method surface, probing endpoint capabilities, and reconciling EVM parity assumptions.

TL;DR

Monad exposes an Ethereum-compatible JSON-RPC interface, so the method vocabulary is the familiar eth_*, net_*, web3_* namespaces, and where enabled debug_*/trace_* namespaces, wrapped in the standard JSON-RPC 2.0 request envelope. However, EVM compatibility does not guarantee identical method availability or semantics across providers and node releases. Developers should probe a given Monad endpoint for a small, safe set of methods and record which return results versus method-not-found (-32601) or unsupported errors. Monad-specific wrinkles include asynchronous execution affecting receipt status intuition and dual gas pricing making eth_gasPrice alone potentially misleading. Always reconcile observed behavior against current Monad documentation rather than assuming Ethereum parity.

Monad's Ethereum-Compatible JSON-RPC Interface

Monad is designed as an EVM-compatible blockchain, meaning it exposes a JSON-RPC interface that mirrors the method namespaces defined in the Ethereum JSON-RPC specification. For developers, this is the starting point: the method vocabulary you already know from Ethereum tooling—eth_, net_, web3_, and where enabled debug_/trace_*—is the same vocabulary you will use against a Monad endpoint. The request envelope is the standard JSON-RPC 2.0 object containing jsonrpc, method, params, and id, as defined by the JSON-RPC 2.0 specification.

This compatibility lowers the barrier to entry: existing Ethereum libraries, wallet integrations, and indexers can often point at a Monad RPC endpoint with minimal changes. OnFinality provides Monad RPC endpoints that follow this compatible surface, and the Monad RPC endpoints and guide covers endpoint discovery and connection basics. However, compatibility is a starting point, not a guarantee of identical behavior across every method and every provider.

  • Standard namespaces: eth_, net_, web3_* are the baseline for EVM-compatible chains.
  • Optional namespaces: debug_* and trace_* are typically disabled on shared or public endpoints due to resource intensity.
  • Request envelope: { "jsonrpc": "2.0", "method": "...", "params": [...], "id": 1 }.
  • Response envelope: { "jsonrpc": "2.0", "result": ..., "id": 1 } or { "jsonrpc": "2.0", "error": { "code": ..., "message": ... }, "id": 1 }.

Enumerating Supported Methods on a Monad Endpoint

Do not assume every Ethereum method is enabled on a given Monad endpoint. Providers and node releases vary in which namespaces they expose, and some methods may be disabled for performance, security, or operational reasons. The only reliable way to know what a specific endpoint supports is to probe it with a small, safe set of methods and record the responses. A method that is not supported will typically return a JSON-RPC error with code -32601 (method not found) or a provider-specific 'unsupported' message.

When probing, start with read-only methods that have no side effects: eth_chainId, eth_blockNumber, web3_clientVersion, and a small-range eth_getLogs call. Avoid sending transactions or calling debug/trace methods during initial capability discovery. Record both the result and the raw error for each method so you can distinguish between a method that is absent, a method that is present but temporarily failing, and a method that requires parameters you did not supply correctly.

  • Probe with read-only methods first: eth_chainId, eth_blockNumber, web3_clientVersion.
  • Record the exact error code and message for unsupported methods.
  • Distinguish -32601 (method not found) from -32602 (invalid params) and -32603 (internal error).
  • Re-probe after provider or node upgrades; capability sets can change.

Core Method Groups for Monad Developers

The methods you will use most often on Monad fall into five functional groups. Chain and node identity methods—eth_chainId, net_version, web3_clientVersion—tell you which network you are connected to and what client software is serving the endpoint. Block and transaction read methods—eth_blockNumber, eth_getBlockByNumber, eth_getTransactionByHash, eth_getTransactionReceipt—let you inspect chain state and transaction outcomes. State and simulation methods—eth_call, eth_estimateGas, eth_getBalance, eth_getCode, eth_getStorageAt—support contract interaction and preflight checks.

Logs methods, primarily eth_getLogs, are essential for event indexing but come with block-range limits that vary by provider; see the dedicated guide on Monad eth_getLogs block-range limits for handling invalid-range errors. Fee and priority data methods—eth_gasPrice, eth_feeHistory, eth_maxPriorityFeePerGas—help you construct transactions, but on Monad you must account for dual gas pricing, which is covered in the Monad dual gas pricing estimation article.

  • Chain/node identity: eth_chainId, net_version, web3_clientVersion.
  • Block and transaction reads: eth_blockNumber, eth_getBlockByNumber, eth_getTransactionByHash, eth_getTransactionReceipt.
  • State and simulation: eth_call, eth_estimateGas, eth_getBalance, eth_getCode, eth_getStorageAt.
  • Logs: eth_getLogs (watch block-range caps).
  • Fee and priority: eth_gasPrice, eth_feeHistory, eth_maxPriorityFeePerGas.

Monad-Specific Behavioral Wrinkles

Two Monad-specific behaviors deserve attention when mapping the JSON-RPC surface. First, Monad uses asynchronous execution, which means a submitted transaction may not have a receipt immediately available in the same way Ethereum's synchronous intuition suggests. A transaction hash can be known before the receipt status is final; developers should poll eth_getTransactionReceipt and handle null results gracefully. The Monad transaction lifecycle and receipt status article explains this in detail.

Second, Monad employs dual gas pricing, which means eth_gasPrice alone can mislead you about the actual cost of a transaction. If your application relies solely on eth_gasPrice for fee estimation, you may under- or over-estimate fees. Use eth_feeHistory and eth_maxPriorityFeePerGas where available, and consult the dual gas pricing guide for a more accurate approach. These wrinkles are not method availability issues—the methods exist—but they affect how you interpret the results.

  • Asynchronous execution: receipt may be null immediately after submission; poll with backoff.
  • Dual gas pricing: eth_gasPrice is a single data point; combine with eth_feeHistory and eth_maxPriorityFeePerGas.
  • Receipt status semantics may differ from synchronous EVM chains; verify against Monad documentation.
  • Always reconcile observed behavior with the current Monad documentation.

Runnable Node.js Capability Probe Script

The following Node.js script probes a Monad endpoint for a small set of methods and prints OK or NOT-SUPPORTED for each, along with the raw error when applicable. It uses only the built-in fetch API (Node.js 18+) and requires no external dependencies. Replace the RPC_URL constant with your Monad endpoint URL. The script calls eth_chainId, eth_blockNumber, eth_getBlockByNumber, eth_getBalance, eth_getLogs with a small block range, and web3_clientVersion.

Run this script against your own endpoint to build a capability matrix. The output will show which methods return results and which return errors. For eth_getLogs, use a recent block range of a few blocks to avoid hitting range limits; if the endpoint rejects the range, that itself is useful information about the provider's constraints.

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

async function call(method, params = []) {
  const body = { jsonrpc: '2.0', method, params, id: 1 };
  const res = await fetch(RPC_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  const json = await res.json();
  if (json.error) {
    return { ok: false, error: json.error };
  }
  return { ok: true, result: json.result };
}

async function probe() {
  const latestHex = (await call('eth_blockNumber')).result;
  const latest = parseInt(latestHex, 16);
  const fromBlock = '0x' + Math.max(0, latest - 5).toString(16);
  const toBlock = '0x' + latest.toString(16);

  const probes = [
    ['eth_chainId', []],
    ['eth_blockNumber', []],
    ['eth_getBlockByNumber', [latestHex, false]],
    ['eth_getBalance', ['0x0000000000000000000000000000000000000000', 'latest']],
    ['eth_getLogs', [{ fromBlock, toBlock }]],
    ['web3_clientVersion', []],
  ];

  for (const [method, params] of probes) {
    const out = await call(method, params);
    if (out.ok) {
      console.log(`OK  ${method} ->`, JSON.stringify(out.result).slice(0, 120));
    } else {
      console.log(`NOT-SUPPORTED  ${method} ->`, JSON.stringify(out.error));
    }
  }
}

probe().catch(console.error);

Reproducible Results Table for Your Endpoint

Use the table below to record your probe results. Fill in one row per method you test against your Monad endpoint. The 'Supported?' column should be Yes, No, or Error. The 'Sample response field' column should capture a representative field from the result (for example, the chainId value or the block number). The 'Notes' column is for provider-specific observations, such as rate limits or required parameters.

This table is intentionally blank so you can measure against your own endpoint rather than relying on third-party claims. Re-run the probe after changing providers or after a node upgrade, and keep the table with your integration tests. If a method is not supported, document the exact error code and message so you can handle it gracefully in your application.

  • Method: the JSON-RPC method name, e.g., eth_chainId.
  • Namespace: eth, net, web3, debug, trace.
  • Supported?: Yes / No / Error.
  • Sample response field: a key field from the result, e.g., result.chainId.
  • Notes: provider-specific behavior, rate limits, required params.

Interpreting Method-Not-Found and Unsupported Errors

When a Monad endpoint does not support a method, the JSON-RPC response will contain an error object. The standard error code for a method that does not exist is -32601 (method not found), as defined in the JSON-RPC 2.0 specification. Some providers may return a different code or a custom message such as 'unsupported method' or 'method disabled'. You should treat any error response as a signal that the method is not available on that endpoint, but distinguish between a method that is truly absent and one that is temporarily unavailable due to rate limiting or internal errors.

If you receive -32601, do not retry the same method repeatedly; instead, fall back to an alternative method or endpoint. If you receive -32602 (invalid params), check your parameter formatting—for example, block numbers must be hex strings or the tags 'latest', 'earliest', 'pending'. If you receive -32603 (internal error), the method may exist but the node encountered a problem; retry with backoff and consider switching endpoints.

  • -32601: method not found or disabled; do not retry, use fallback.
  • -32602: invalid params; verify hex encoding and parameter count.
  • -32603: internal error; retry with backoff, consider endpoint switch.
  • Provider-specific codes: consult provider documentation for custom error codes.

Debug and Trace Namespace Availability

The debug_* and trace_* namespaces provide powerful introspection methods such as debug_traceTransaction and trace_block. On shared or public Monad endpoints, these namespaces are usually disabled because they are resource-intensive and can degrade performance for other users. If your application requires tracing, you may need a dedicated node or a provider that explicitly offers these namespaces. Do not assume that because a method exists in the Ethereum JSON-RPC specification, it is enabled on your Monad endpoint.

To check availability, probe with a safe debug method such as debug_traceTransaction on a known transaction hash, or simply attempt a trace_ call and inspect the error. If the endpoint returns -32601, the namespace is not exposed. For production tracing needs, consider running your own Monad node or using a provider that documents trace support. OnFinality's API service and RPC pricing pages describe the available service tiers, but always verify namespace support with a direct probe.

  • debug_* and trace_* are typically disabled on shared endpoints.
  • Probe with a known transaction hash to test debug_traceTransaction.
  • For tracing, consider a dedicated node or a provider with documented trace support.
  • Verify namespace support directly; do not rely on assumptions.

Limitations and Tradeoffs of EVM Compatibility

EVM compatibility does not guarantee identical method availability or semantics. Monad may implement the same method names but with different performance characteristics, block-range limits, or error behaviors. For example, eth_getLogs on Monad may have a lower block-range cap than you expect from Ethereum mainnet, and eth_gasPrice may not reflect dual gas pricing accurately. These differences are not bugs; they are properties of the network and its providers.

Another tradeoff is that some Ethereum methods may be deprecated or replaced on Monad, or new methods may be introduced that are not part of the standard Ethereum surface. Always reconcile your assumptions against the current Monad documentation and your provider's documentation. If you are migrating an existing Ethereum application, run the capability probe script against your Monad endpoint and compare the results with your Ethereum endpoint to identify gaps early.

  • Method availability varies by provider and node release.
  • Block-range limits for eth_getLogs may differ from Ethereum.
  • Dual gas pricing affects fee-related methods.
  • New or deprecated methods may exist outside the standard Ethereum surface.
  • Always verify against current Monad documentation.

Troubleshooting Common Monad JSON-RPC Issues

If your application fails to connect or receives unexpected errors, start by verifying the endpoint URL and network. Use eth_chainId to confirm you are on the intended Monad network. If eth_chainId returns a value you do not recognize, you may be pointing at a testnet or a different chain. Next, check that your request envelope is valid JSON-RPC 2.0: the jsonrpc field must be exactly '2.0', and the id should be a number or string. A malformed envelope can produce a parse error (-32700) or invalid request (-32600).

If a specific method fails, isolate it with a minimal curl command. For example, curl -X POST -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' YOUR_RPC_URL. If this works but your application fails, the issue is likely in your client library or parameter formatting. If it fails, the method may not be supported or the endpoint may be temporarily unavailable. For log-related errors, see the Monad eth_getLogs block-range limits guide.

  • Verify endpoint URL and network with eth_chainId.
  • Validate JSON-RPC 2.0 envelope: jsonrpc, method, params, id.
  • Isolate failing methods with a minimal curl command.
  • Check block-range limits for eth_getLogs.
  • Consult provider documentation for custom error codes.

Next Steps for Monad JSON-RPC Integration

After probing your endpoint and filling in the results table, you have a capability matrix you can use to design your integration. For endpoint discovery and provider selection, see the Monad RPC endpoints (RPC Assistant) page. For a broader overview of Monad RPC usage, the Monad RPC endpoints and guide covers connection setup and common patterns. If you need to estimate fees accurately, review the Monad dual gas pricing estimation article.

For production deployments, consider using a provider that offers the namespaces you need and documents its block-range limits. OnFinality's Monad RPC endpoints are designed for EVM-compatible workloads, and the OnFinality Learn hub contains additional guides on Monad-specific behaviors. Always re-run your capability probe after provider changes or node upgrades, and keep your results table up to date as part of your integration test suite.

  • Use the capability matrix to choose fallback methods and endpoints.
  • Document block-range limits and error handling for eth_getLogs.
  • Re-probe after provider or node upgrades.
  • Review Monad-specific guides for gas, receipts, and logs.
  • Consider dedicated nodes for debug/trace namespaces.

Never Worry about Infrastructure Again

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

Get Started