<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: OnFinality</title>
    <description>The latest articles on DEV Community by OnFinality (@onfinality).</description>
    <link>https://dev.to/onfinality</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3813781%2Fb863954f-6836-4b28-a128-248450616fc8.png</url>
      <title>DEV Community: OnFinality</title>
      <link>https://dev.to/onfinality</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/onfinality"/>
    <language>en</language>
    <item>
      <title>Staking KLAY on Klaytn: RPC Methods and Integration Checks</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:22:01 +0000</pubDate>
      <link>https://dev.to/onfinality/staking-klay-on-klaytn-rpc-methods-and-integration-checks-3nbi</link>
      <guid>https://dev.to/onfinality/staking-klay-on-klaytn-rpc-methods-and-integration-checks-3nbi</guid>
      <description>&lt;p&gt;Klaytn rebranded to Kaia, but the staking mechanics developers ask about are the same: KLAY (now KAIA) holders delegate stake to governance councils or node operators, and applications need reliable RPC access to read stake state, track rewards, and submit staking transactions. This page is aimed at developers building staking dashboards, wallets, or reward trackers, and at teams deciding what RPC infrastructure to run behind them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you actually need before you stake
&lt;/h2&gt;

&lt;p&gt;Before writing any code, confirm three things. First, the staking path you are targeting: governance council delegation, a public node operator, or a liquid staking service. Each has a different contract surface and different data you need to read. Second, the unstaking delay, because it determines how you present withdrawal timelines in your UI. Third, whether your RPC endpoint can handle the read-heavy pattern staking apps produce, since reward tracking means frequent &lt;code&gt;eth_call&lt;/code&gt; and log queries rather than occasional transfers.&lt;/p&gt;

&lt;p&gt;If you are building on Klaytn and want a managed endpoint instead of running your own node, &lt;a href="https://onfinality.io/networks/klaytn" rel="noopener noreferrer"&gt;OnFinality's Klaytn (Kaia) RPC&lt;/a&gt; exposes a public endpoint you can test against immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://klaytn.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A correct response returns &lt;code&gt;0x2019&lt;/code&gt;, which is chain ID 8217 for Kaia Mainnet. If you get a different chain ID, you are pointed at the wrong network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Klaytn staking model in plain terms
&lt;/h2&gt;

&lt;p&gt;Klaytn runs a delegated proof-of-stake consensus. A limited set of governance council nodes produce blocks, and KLAY holders can stake toward those nodes. Staking is not a free-for-all validator set like some networks; the council structure means the set of entities you can delegate to is constrained, and governance decisions affect who participates.&lt;/p&gt;

&lt;p&gt;For developers, the practical consequences are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Staking operations often route through specific staking contracts rather than a generic precompile.&lt;/li&gt;
&lt;li&gt;Reward accrual is tied to block production, so you read rewards by scanning blocks or querying contract state, not by calling a single "get rewards" method.&lt;/li&gt;
&lt;li&gt;Unstaking is not instant. You need to model a delay in your UI and in any accounting logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the network is now branded Kaia, some documentation and block explorers use Kaia naming while older contracts and tooling still say Klaytn. Expect both terms in the wild and do not assume a contract is deprecated just because it uses the older name.&lt;/p&gt;

&lt;h2&gt;
  
  
  RPC methods that matter for staking apps
&lt;/h2&gt;

&lt;p&gt;Staking front-ends and backends lean on a small set of JSON-RPC methods. The table below maps the job to the method you will call most often.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Job in your staking app&lt;/th&gt;
&lt;th&gt;Primary method&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Confirm you are on Kaia Mainnet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_chainId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Expect &lt;code&gt;0x2019&lt;/code&gt; (8217)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read a staking contract's state&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_call&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Encode function selectors for the staking contract&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Track reward or staking events&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_getLogs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bound block ranges; wide ranges are expensive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check a user's KLAY balance&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_getBalance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns wei; format to 18 decimals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Submit a stake or unstake transaction&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_sendRawTransaction&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sign locally, then broadcast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estimate gas before submitting&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_estimateGas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Do this before every staking write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confirm a transaction landed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_getTransactionReceipt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Poll until status is &lt;code&gt;0x1&lt;/code&gt; or &lt;code&gt;0x0&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read current block for reward windows&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth_blockNumber&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use as the upper bound for log queries&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A minimal reward-tracking loop in JavaScript looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parseAbi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;viem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://klaytn.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stakingAbi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseAbi&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function getReward(address account) view returns (uint256)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;readReward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contractAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reward&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readContract&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contractAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;stakingAbi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;functionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getReward&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reward&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;latest&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the ABI and contract address with the actual staking contract you integrate. The point is the pattern: read state with &lt;code&gt;eth_call&lt;/code&gt;, anchor it to a block number, and store that block number so you can reconcile later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing RPC infrastructure for a staking product
&lt;/h2&gt;

&lt;p&gt;Staking apps have a read-heavy, latency-sensitive profile. Users expect reward numbers to update quickly, and they expect stake and unstake transactions to land without retries. That makes endpoint choice a product decision, not just an infrastructure detail.&lt;/p&gt;

&lt;p&gt;When you evaluate providers for a Klaytn staking app, compare on the dimensions that actually affect staking UX:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evaluation area&lt;/th&gt;
&lt;th&gt;What to look for&lt;/th&gt;
&lt;th&gt;Why it affects staking&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read throughput&lt;/td&gt;
&lt;td&gt;Ability to serve frequent &lt;code&gt;eth_call&lt;/code&gt; and &lt;code&gt;eth_getLogs&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Reward dashboards poll constantly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log query limits&lt;/td&gt;
&lt;td&gt;Clear guidance on block-range caps&lt;/td&gt;
&lt;td&gt;Wide ranges silently fail or time out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write path reliability&lt;/td&gt;
&lt;td&gt;Stable &lt;code&gt;eth_sendRawTransaction&lt;/code&gt; behavior&lt;/td&gt;
&lt;td&gt;Failed broadcasts strand user funds in pending state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failover&lt;/td&gt;
&lt;td&gt;Multiple endpoints or automatic routing&lt;/td&gt;
&lt;td&gt;A single endpoint outage freezes staking UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archive access&lt;/td&gt;
&lt;td&gt;Historical state if you reconcile old rewards&lt;/td&gt;
&lt;td&gt;Without it, backfills are impossible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support model&lt;/td&gt;
&lt;td&gt;Who you contact when a staking tx misbehaves&lt;/td&gt;
&lt;td&gt;Staking bugs are time-sensitive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;OnFinality provides managed Klaytn (Kaia) RPC through its &lt;a href="https://onfinality.io/api-service" rel="noopener noreferrer"&gt;API service&lt;/a&gt;, and teams that need isolated capacity, custom rate limits, or private networking can move to a &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated node&lt;/a&gt;. For most staking dashboards, a managed endpoint with a failover plan is enough to start; dedicated infrastructure becomes worthwhile when your read volume or compliance needs outgrow shared capacity. You can compare tiers on the &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing page&lt;/a&gt; and see the full set of &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are still deciding between providers, the &lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;RPC provider selection guide&lt;/a&gt; walks through the same criteria in more depth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes and how to debug them
&lt;/h2&gt;

&lt;p&gt;Staking integrations fail in predictable ways. Here is a symptom-to-fix table you can keep next to your logs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reward numbers jump or reset&lt;/td&gt;
&lt;td&gt;Reading from a different block each poll&lt;/td&gt;
&lt;td&gt;Pin reads to a block number and store it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;eth_getLogs&lt;/code&gt; returns nothing&lt;/td&gt;
&lt;td&gt;Block range too wide or wrong address&lt;/td&gt;
&lt;td&gt;Narrow the range; verify the contract address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stake transaction stuck pending&lt;/td&gt;
&lt;td&gt;Gas price too low or nonce gap&lt;/td&gt;
&lt;td&gt;Re-estimate gas; check nonce sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong chain data&lt;/td&gt;
&lt;td&gt;Endpoint pointed at a testnet&lt;/td&gt;
&lt;td&gt;Re-check &lt;code&gt;eth_chainId&lt;/code&gt; returns &lt;code&gt;0x2019&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intermittent timeouts&lt;/td&gt;
&lt;td&gt;Single endpoint under load&lt;/td&gt;
&lt;td&gt;Add a second endpoint and retry logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unstake never completes&lt;/td&gt;
&lt;td&gt;UI ignores the unstaking delay&lt;/td&gt;
&lt;td&gt;Model the delay explicitly in your state machine&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The nonce gap problem is the one that bites hardest. If a staking transaction fails silently and you submit another without resyncing the nonce, every subsequent transaction queues behind the stuck one. Always read &lt;code&gt;eth_getTransactionCount&lt;/code&gt; with the &lt;code&gt;pending&lt;/code&gt; tag before broadcasting a new staking write.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical integration checklist
&lt;/h2&gt;

&lt;p&gt;Work through this list before you ship a staking feature:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm chain ID 8217 and the correct staking contract addresses for your target path.&lt;/li&gt;
&lt;li&gt;Decide how you will read rewards: contract &lt;code&gt;eth_call&lt;/code&gt;, event logs, or both.&lt;/li&gt;
&lt;li&gt;Pin every read to a block number and persist it for reconciliation.&lt;/li&gt;
&lt;li&gt;Implement gas estimation and nonce management for stake and unstake writes.&lt;/li&gt;
&lt;li&gt;Model the unstaking delay in your UI and in any accounting.&lt;/li&gt;
&lt;li&gt;Add a second RPC endpoint and retry logic for read failures.&lt;/li&gt;
&lt;li&gt;Log the endpoint and block number with every staking error so you can reproduce it.&lt;/li&gt;
&lt;li&gt;Test the full stake, reward, and unstake cycle on a testnet before mainnet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your team would rather not operate nodes at all, a managed endpoint removes steps 6 and 7 from your plate because failover and endpoint health become the provider's responsibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Klaytn is now branded Kaia, but staking mechanics and contract addresses still use both names.&lt;/li&gt;
&lt;li&gt;Staking apps are read-heavy: &lt;code&gt;eth_call&lt;/code&gt; and &lt;code&gt;eth_getLogs&lt;/code&gt; dominate, not transfers.&lt;/li&gt;
&lt;li&gt;Pin reward reads to a block number or your numbers will drift.&lt;/li&gt;
&lt;li&gt;Nonce and gas management are the most common sources of stuck staking transactions.&lt;/li&gt;
&lt;li&gt;Endpoint choice directly affects staking UX; compare read throughput, log limits, and failover.&lt;/li&gt;
&lt;li&gt;OnFinality offers managed Klaytn (Kaia) RPC and dedicated nodes when shared capacity is not enough.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I run my own Klaytn validator to stake?&lt;/strong&gt;&lt;br&gt;
Governance council participation is limited and not open to arbitrary operators. Most KLAY holders stake through delegation or a liquid staking service rather than running a validator directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long does unstaking take on Klaytn?&lt;/strong&gt;&lt;br&gt;
There is a delay between requesting an unstake and receiving funds. Check the current staking contract documentation for the exact period, and model it in your UI rather than assuming instant withdrawal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which RPC method do I use to read staking rewards?&lt;/strong&gt;&lt;br&gt;
Usually &lt;code&gt;eth_call&lt;/code&gt; against the staking contract, or &lt;code&gt;eth_getLogs&lt;/code&gt; if rewards are emitted as events. There is no single global "get staking rewards" method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need an archive node for staking?&lt;/strong&gt;&lt;br&gt;
Only if you reconcile historical rewards or backfill data from old blocks. For live dashboards, a standard full node is typically sufficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use the public OnFinality endpoint in production?&lt;/strong&gt;&lt;br&gt;
Public endpoints are useful for testing and low-volume reads. For production staking apps, evaluate a managed plan or dedicated node so you have predictable capacity and failover.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What chain ID should I expect?&lt;/strong&gt;&lt;br&gt;
Kaia Mainnet returns &lt;code&gt;0x2019&lt;/code&gt;, which is 8217 in decimal. If you see anything else, you are on the wrong network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/klaytn" rel="noopener noreferrer"&gt;Klaytn (Kaia) RPC network&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated node infrastructure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/staking-klaytn" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Ethereum RPC Node Provider: How to Evaluate One</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:21:28 +0000</pubDate>
      <link>https://dev.to/onfinality/ethereum-rpc-node-provider-how-to-evaluate-one-4fj5</link>
      <guid>https://dev.to/onfinality/ethereum-rpc-node-provider-how-to-evaluate-one-4fj5</guid>
      <description>&lt;p&gt;Choosing an Ethereum RPC node provider is really a question about how your application reads and writes chain state under load. Ethereum mainnet produces a block roughly every 12 seconds, and every wallet balance check, log query, and transaction broadcast goes through a JSON-RPC endpoint. If that endpoint is slow, rate-limited, or missing the methods you need, your users feel it before your dashboards do.&lt;/p&gt;

&lt;p&gt;This page is for developers and infrastructure buyers comparing Ethereum RPC options. It covers what a node provider actually does, which capabilities separate a shared endpoint from a dedicated node, and how to test a provider before you commit production traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with your workload, not the provider list
&lt;/h2&gt;

&lt;p&gt;Before you compare vendors, write down what your app actually sends. Most Ethereum RPC traffic falls into a few patterns, and each one stresses a different part of the node.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload pattern&lt;/th&gt;
&lt;th&gt;Typical methods&lt;/th&gt;
&lt;th&gt;What it stresses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wallet / dapp reads&lt;/td&gt;
&lt;td&gt;eth_call, eth_getBalance, eth_getTransactionCount&lt;/td&gt;
&lt;td&gt;Low-latency head state, high request volume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indexer / analytics&lt;/td&gt;
&lt;td&gt;eth_getLogs, eth_getBlockByNumber&lt;/td&gt;
&lt;td&gt;Archive state, large result sets, long queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trading / bots&lt;/td&gt;
&lt;td&gt;eth_sendRawTransaction, eth_getTransactionReceipt&lt;/td&gt;
&lt;td&gt;Broadcast speed, mempool visibility, WebSocket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bridges / relayers&lt;/td&gt;
&lt;td&gt;eth_getProof, trace_*&lt;/td&gt;
&lt;td&gt;Trace and proof support, deep historical state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring / alerting&lt;/td&gt;
&lt;td&gt;eth_subscribe, eth_blockNumber&lt;/td&gt;
&lt;td&gt;Persistent WebSocket, stable connection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you only send eth_call and eth_getBalance, a well-run shared endpoint is usually enough. If you run eth_getLogs across wide block ranges, replay history, or need trace_* and debug_* methods, you are in archive and dedicated-node territory. That distinction drives cost far more than raw request count.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an Ethereum RPC node provider actually runs
&lt;/h2&gt;

&lt;p&gt;A provider operates Ethereum execution and consensus clients, keeps them synced to the network, and exposes them through a load-balanced JSON-RPC layer. Good providers also handle client upgrades, reorg handling, peer management, and monitoring so you do not have to.&lt;/p&gt;

&lt;p&gt;There are three common delivery models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public endpoints.&lt;/strong&gt; Free, shared, and rate-limited. Fine for prototyping and low-volume reads, but not something to point a production wallet at.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed RPC API.&lt;/strong&gt; A paid shared endpoint with higher limits, API keys, and usually archive access. This is the default choice for most production dapps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedicated nodes.&lt;/strong&gt; Isolated node capacity for one team. You get predictable throughput, your own archive or trace configuration, and no noisy neighbors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OnFinality offers Ethereum through a managed &lt;a href="https://onfinality.io/api-service" rel="noopener noreferrer"&gt;RPC API service&lt;/a&gt; and through &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; when you need isolated capacity. You can start on the shared endpoint and move up without changing your application code, because the JSON-RPC interface stays the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ethereum chain settings at a glance
&lt;/h2&gt;

&lt;p&gt;If you are wiring Ethereum into a wallet, a Hardhat config, or a backend service, you need the canonical network parameters. Use these values so your tooling connects to mainnet rather than a testnet.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Network name&lt;/td&gt;
&lt;td&gt;Ethereum Mainnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;ETH (18 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://etherscan.io" rel="noopener noreferrer"&gt;https://etherscan.io&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public RPC URL&lt;/td&gt;
&lt;td&gt;&lt;a href="https://eth.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://eth.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transports&lt;/td&gt;
&lt;td&gt;HTTP and WebSocket&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A quick way to confirm an endpoint is live and on the right chain is to ask it for the chain ID and latest block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://eth.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'&lt;/span&gt;

&lt;span class="c"&gt;# {"jsonrpc":"2.0","id":1,"result":"0x1"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that returns &lt;code&gt;0x1&lt;/code&gt;, you are on Ethereum mainnet. If it returns anything else, you are pointed at a different chain or a testnet. For testnet work, use the &lt;a href="https://onfinality.io/networks/eth-sepolia" rel="noopener noreferrer"&gt;Ethereum Sepolia network page&lt;/a&gt; instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provider evaluation matrix
&lt;/h2&gt;

&lt;p&gt;Once you know your workload, compare providers against the capabilities that matter for it. The table below is a practical checklist rather than a ranking.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;th&gt;What to ask&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Transport support&lt;/td&gt;
&lt;td&gt;Wallets and bots often need WebSocket for subscriptions&lt;/td&gt;
&lt;td&gt;Is HTTP and WS both available?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archive access&lt;/td&gt;
&lt;td&gt;Historical eth_getLogs and state reads need archive nodes&lt;/td&gt;
&lt;td&gt;Is archive included or a separate tier?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trace / debug methods&lt;/td&gt;
&lt;td&gt;Bridges and analytics rely on trace_* and debug_*&lt;/td&gt;
&lt;td&gt;Which trace methods are exposed?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate limits&lt;/td&gt;
&lt;td&gt;Bursty workloads hit shared caps&lt;/td&gt;
&lt;td&gt;What are the request and compute-unit limits?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failover&lt;/td&gt;
&lt;td&gt;A single endpoint is a single point of failure&lt;/td&gt;
&lt;td&gt;Are there multiple regions or endpoints?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;You need to see errors before users do&lt;/td&gt;
&lt;td&gt;Are usage and error metrics exposed?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support model&lt;/td&gt;
&lt;td&gt;Incidents need a human, not a ticket queue&lt;/td&gt;
&lt;td&gt;What is the response path during an outage?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;OnFinality appears first here because it is the provider this site operates: it offers Ethereum over HTTP and WebSocket, supports archive and trace workloads on appropriate plans, and lets teams move from shared RPC to dedicated nodes. Compare every provider on the same criteria before deciding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing a provider before you commit
&lt;/h2&gt;

&lt;p&gt;Do not migrate production traffic on a provider's marketing page. Run a short evaluation against your real methods. A simple script that measures latency and correctness across a few endpoints will tell you more than any benchmark table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// probe.mjs — compare Ethereum RPC endpoints on the methods you actually use&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endpoints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://eth.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// add other provider endpoints you are evaluating&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;probe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eth_blockNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eth_getLogs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fromBlock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;latest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;toBlock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;latest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logs&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;probe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this at different times of day. Watch for endpoints that are fast on eth_blockNumber but slow or erroring on eth_getLogs, since log queries are where shared capacity usually shows its limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where shared endpoints stop being enough
&lt;/h2&gt;

&lt;p&gt;A managed shared endpoint is the right default for most teams. It stops being enough when one of these becomes true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You regularly hit rate limits during peak traffic and cannot smooth the load.&lt;/li&gt;
&lt;li&gt;You need eth_getLogs across large block ranges on a schedule.&lt;/li&gt;
&lt;li&gt;You depend on trace_* or debug_* methods that shared tiers restrict.&lt;/li&gt;
&lt;li&gt;You need a WebSocket connection that stays open for subscriptions without reconnects.&lt;/li&gt;
&lt;li&gt;You need predictable throughput for a launch, a mint, or a trading window.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point, a dedicated Ethereum node gives you isolated CPU, memory, and disk, plus your own archive and trace configuration. It also removes the noisy-neighbor problem, where another tenant's traffic spike becomes your latency spike. See &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; for how that model works, and &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; to compare tiers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failover and multi-provider strategy
&lt;/h2&gt;

&lt;p&gt;Even a well-run provider can have a bad hour. Production apps should assume any single endpoint will occasionally fail and design for it.&lt;/p&gt;

&lt;p&gt;A common pattern is a primary endpoint with one or two fallbacks, selected by health checks rather than hardcoded order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// rpc-router.mjs — simple health-checked failover across endpoints&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://eth.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// fallback endpoints&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;healthy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eth_blockNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AbortSignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;healthy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;all Ethereum RPC endpoints failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the fallback list short and tested. An untested fallback is worse than none, because it fails exactly when you need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes and what they usually mean
&lt;/h2&gt;

&lt;p&gt;When an Ethereum RPC call misbehaves, the error often points at configuration rather than the provider.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;method not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Endpoint does not expose that method (often trace_*)&lt;/td&gt;
&lt;td&gt;Confirm method support with the provider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;429&lt;/code&gt; or rate-limit errors&lt;/td&gt;
&lt;td&gt;Shared tier request cap exceeded&lt;/td&gt;
&lt;td&gt;Reduce burst size or move to a higher tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;missing trie node&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Query hit non-archive state&lt;/td&gt;
&lt;td&gt;Use an archive endpoint for historical reads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nonce too low&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Local nonce tracking out of sync&lt;/td&gt;
&lt;td&gt;Re-read eth_getTransactionCount with pending&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket drops&lt;/td&gt;
&lt;td&gt;Idle timeout or unstable connection&lt;/td&gt;
&lt;td&gt;Add reconnect logic and heartbeat pings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slow eth_getLogs&lt;/td&gt;
&lt;td&gt;Wide block range on shared capacity&lt;/td&gt;
&lt;td&gt;Narrow ranges or use a dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are debugging transaction-level issues like nonce errors, the &lt;a href="https://onfinality.io/rpc-assistant/what-is-a-blockchain-nonce" rel="noopener noreferrer"&gt;nonce explainer&lt;/a&gt; walks through the mechanics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An Ethereum RPC node provider runs the nodes; you consume JSON-RPC over HTTP or WebSocket. The delivery model (public, managed, dedicated) matters more than the brand.&lt;/li&gt;
&lt;li&gt;Match the provider to your workload. Reads, log queries, transaction broadcasts, and trace calls stress different parts of a node.&lt;/li&gt;
&lt;li&gt;Ethereum mainnet uses chain ID 1, ETH as the native currency, and supports both HTTP and WebSocket transports.&lt;/li&gt;
&lt;li&gt;Test providers against your real methods, especially eth_getLogs and any trace_* calls, before migrating production traffic.&lt;/li&gt;
&lt;li&gt;Plan for failover. A primary endpoint plus tested fallbacks is standard practice for production apps.&lt;/li&gt;
&lt;li&gt;Move to a dedicated node when you hit rate limits, need archive or trace access, or require predictable throughput. See &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; and &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; for options.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between an Ethereum RPC provider and a node provider?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In practice they overlap. A node provider runs the Ethereum clients; an RPC provider exposes them over JSON-RPC. Most managed services do both, so the terms are often used interchangeably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need an archive node for Ethereum?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only if you query historical state or logs beyond the recent window. Wallets and simple dapps usually do not. Indexers, analytics tools, and bridges often do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use a public Ethereum RPC endpoint in production?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Public endpoints are shared and rate-limited, so they are best for testing. Production apps generally use a managed RPC API or a dedicated node for predictable behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does OnFinality support Ethereum WebSocket subscriptions?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ethereum on OnFinality supports HTTP and WebSocket transports. Check the &lt;a href="https://onfinality.io/networks/eth" rel="noopener noreferrer"&gt;Ethereum network page&lt;/a&gt; for current endpoint details and plan options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I switch providers without rewriting my app?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because Ethereum JSON-RPC is standardized, you usually only change the endpoint URL and API key. Keep your RPC URL in configuration, not hardcoded, so migration is a config change rather than a code change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should I move from shared RPC to a dedicated node?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you consistently hit rate limits, need archive or trace methods, or require stable throughput for launches and trading windows. &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt; isolate your capacity from other tenants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/eth" rel="noopener noreferrer"&gt;Ethereum RPC on OnFinality&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/ethereum-rpc-node-provider" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Binance Beacon Chain Explorer: What It Was and What to Use Now</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:20:54 +0000</pubDate>
      <link>https://dev.to/onfinality/binance-beacon-chain-explorer-what-it-was-and-what-to-use-now-2p1o</link>
      <guid>https://dev.to/onfinality/binance-beacon-chain-explorer-what-it-was-and-what-to-use-now-2p1o</guid>
      <description>&lt;h2&gt;
  
  
  What the Binance Beacon Chain explorer actually showed
&lt;/h2&gt;

&lt;p&gt;The Binance Beacon Chain was the proof-of-stake consensus layer that ran alongside BNB Smart Chain (BSC). It handled staking, validator registration, delegation, and governance for the BNB Chain ecosystem. Its explorer was the web interface where you could look up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Validators and their voting power&lt;/strong&gt; — who was producing blocks and how much BNB was bonded to each validator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delegations&lt;/strong&gt; — which addresses delegated stake to which validators, and the reward history that followed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-chain events&lt;/strong&gt; — transfers and messages between the Beacon Chain and BNB Smart Chain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance proposals&lt;/strong&gt; — on-chain votes and their outcomes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you searched for a "Binance Beacon Chain explorer," you were probably trying to answer one of three questions: &lt;em&gt;where did my staking rewards go&lt;/em&gt;, &lt;em&gt;which validator should I delegate to&lt;/em&gt;, or &lt;em&gt;how do I pull this data programmatically&lt;/em&gt;. The first two are historical lookups. The third is where RPC infrastructure comes in, and it is the part that still matters for developers today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision guide: explorer lookup vs. RPC query
&lt;/h2&gt;

&lt;p&gt;Before you spend time wiring up an endpoint, decide what you actually need. Explorers are for humans reading a page; RPC is for software that needs to read state on demand.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you need&lt;/th&gt;
&lt;th&gt;Best tool&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read a validator's delegation history&lt;/td&gt;
&lt;td&gt;Historical explorer / archive data&lt;/td&gt;
&lt;td&gt;Explorers index and format this for reading&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confirm a transaction status by hash&lt;/td&gt;
&lt;td&gt;BNB Smart Chain explorer or RPC&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;eth_getTransactionReceipt&lt;/code&gt; returns the raw result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build a staking dashboard&lt;/td&gt;
&lt;td&gt;RPC + indexer&lt;/td&gt;
&lt;td&gt;You need programmatic, repeatable queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitor validator uptime&lt;/td&gt;
&lt;td&gt;RPC + monitoring&lt;/td&gt;
&lt;td&gt;Polling endpoints beats refreshing a web page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debug a failed contract call&lt;/td&gt;
&lt;td&gt;RPC with trace support&lt;/td&gt;
&lt;td&gt;Explorers rarely expose full traces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One-off balance check&lt;/td&gt;
&lt;td&gt;Public RPC endpoint&lt;/td&gt;
&lt;td&gt;Fastest path, no setup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your answer lands in the bottom half of that table, keep reading — the rest of this page is about querying BNB Chain data through RPC instead of clicking through an explorer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Beacon Chain explorer is no longer the main entry point
&lt;/h2&gt;

&lt;p&gt;The BNB Chain ecosystem consolidated its architecture, and the Beacon Chain's role was folded into the broader BNB Chain stack. That means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;New development happens on BNB Smart Chain.&lt;/strong&gt; Contracts, tokens, and most dApps live there, and that is where RPC traffic goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staking data still exists, but it is accessed differently.&lt;/strong&gt; Historical staking records may still be available through archives and indexers, but they are not the primary workflow for most builders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explorers and RPC serve different audiences.&lt;/strong&gt; An explorer is a read-only UI. An RPC endpoint is a programmable interface that your backend, wallet, or bot calls directly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So the practical question is no longer "which Beacon Chain explorer should I open" — it is "which BNB Smart Chain endpoint should my app talk to."&lt;/p&gt;

&lt;h2&gt;
  
  
  BNB Smart Chain RPC settings at a glance
&lt;/h2&gt;

&lt;p&gt;If you are moving from explorer lookups to programmatic queries, these are the values you need. They match the BNB Smart Chain mainnet configuration used by OnFinality.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain name&lt;/td&gt;
&lt;td&gt;BNB Smart Chain Mainnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;BNB (18 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bscscan.com" rel="noopener noreferrer"&gt;https://bscscan.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public RPC endpoint&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bnb.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://bnb.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;td&gt;HTTP and WebSocket&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For testnet work, BNB Chain Testnet uses chain ID 97, the tBNB native token, the explorer at &lt;a href="https://testnet.bscscan.com" rel="noopener noreferrer"&gt;https://testnet.bscscan.com&lt;/a&gt;, and the public endpoint &lt;a href="https://bnb-testnet.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://bnb-testnet.api.onfinality.io/public&lt;/a&gt;. You can find both on the &lt;a href="https://onfinality.io/networks/bnb" rel="noopener noreferrer"&gt;BNB Chain network page&lt;/a&gt; and the &lt;a href="https://onfinality.io/networks/bnb-testnet" rel="noopener noreferrer"&gt;BNB Chain Testnet page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying BNB Chain data with JSON-RPC
&lt;/h2&gt;

&lt;p&gt;Once you have an endpoint, the explorer's job becomes a set of method calls. Here is a quick curl example that fetches the latest block number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://bnb.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check a transaction that you previously found in an explorer, use the hash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://bnb.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "method": "eth_getTransactionReceipt",
    "params": ["0xYOUR_TX_HASH"],
    "id": 1
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In JavaScript with ethers, the same lookup looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;JsonRpcProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JsonRpcProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://bnb.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkTx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTransactionReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pending or unknown transaction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Status:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reverted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Block:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;checkTx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xYOUR_TX_HASH&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For live updates — useful if you are replacing a manual explorer refresh with a dashboard — subscribe over WebSocket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://bnb.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eth_subscribe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newHeads&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New block:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebSocket support depends on the endpoint and plan you use. Confirm transport availability on the &lt;a href="https://onfinality.io/networks/bnb" rel="noopener noreferrer"&gt;BNB Chain network page&lt;/a&gt; before you build around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a public endpoint is enough — and when it is not
&lt;/h2&gt;

&lt;p&gt;A public RPC endpoint is the fastest way to replace an explorer lookup with a script. It works well for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prototyping and one-off queries.&lt;/li&gt;
&lt;li&gt;Low-volume wallets or internal tools.&lt;/li&gt;
&lt;li&gt;Reading balances, blocks, and receipts at a modest rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It becomes a bottleneck when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High request volume&lt;/strong&gt; from a backend or bot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archive data&lt;/strong&gt; for historical state, such as balances at an old block.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trace and debug methods&lt;/strong&gt; for failed transactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent WebSocket subscriptions&lt;/strong&gt; for real-time features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point, the choice is between managing your own BNB node or using managed infrastructure. Running your own node means handling sync, disk growth, upgrades, and monitoring. A managed RPC API or &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated node&lt;/a&gt; removes that operational load and gives you a stable endpoint your team can rely on. OnFinality provides both RPC API access and dedicated node options for BNB Chain, so you can start on a shared endpoint and move to dedicated capacity as traffic grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common pitfalls when moving off explorer lookups
&lt;/h2&gt;

&lt;p&gt;Explorers hide a lot of complexity. When you switch to RPC, a few things trip people up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Assuming every endpoint is an archive node.&lt;/strong&gt; Historical &lt;code&gt;eth_getBalance&lt;/code&gt; calls at an old block fail on non-archive nodes. Check archive support before you depend on it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring rate limits on public endpoints.&lt;/strong&gt; A script that hammers a shared endpoint will get throttled. Plan for a paid tier or dedicated node if your volume is real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting chain ID checks.&lt;/strong&gt; Wallets and tools need chain ID 56 for mainnet and 97 for testnet. Mixing them up sends transactions to the wrong network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating a receipt as final too early.&lt;/strong&gt; A transaction can be included and later reorged. Wait for a few confirmations before you mark something settled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardcoding one endpoint.&lt;/strong&gt; If your only endpoint goes down, your app goes down. Keep a fallback and monitor both.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Production readiness checklist
&lt;/h2&gt;

&lt;p&gt;If you are replacing explorer-driven workflows with RPC in a live product, run through this before launch:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;What to confirm&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Endpoint redundancy&lt;/td&gt;
&lt;td&gt;At least one fallback endpoint configured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archive access&lt;/td&gt;
&lt;td&gt;Confirmed if you query historical state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket plan&lt;/td&gt;
&lt;td&gt;Subscriptions tested under load, not just locally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID guard&lt;/td&gt;
&lt;td&gt;Mainnet (56) vs. testnet (97) enforced in config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;Alerts on error rate and block lag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate strategy&lt;/td&gt;
&lt;td&gt;Volume mapped to a plan that fits, not a public endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key management&lt;/td&gt;
&lt;td&gt;API keys stored in secrets, not in client code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A simple monitoring probe can catch most issues early:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Poll block height and alert if it stalls&lt;/span&gt;
&lt;span class="nv"&gt;HEIGHT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://bnb.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'"result":"[^"]*"'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'"'&lt;/span&gt; &lt;span class="nt"&gt;-f4&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Current block: &lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;HEIGHT&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Compare against a previous value and alert on stagnation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where OnFinality fits
&lt;/h2&gt;

&lt;p&gt;OnFinality runs RPC API endpoints and dedicated nodes for BNB Chain and many other networks. For teams moving away from explorer-based workflows, that means you get a stable endpoint, archive and trace options where supported, and the ability to scale from a shared API to dedicated infrastructure without changing your application code. You can review &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; to match a plan to your workload, and browse &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; if you also build on chains beyond BNB. If you are still deciding between providers, the &lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;RPC provider selection guide&lt;/a&gt; walks through the evaluation criteria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Binance Beacon Chain explorer was a UI for staking, validators, and governance data on the BNB Chain consensus layer.&lt;/li&gt;
&lt;li&gt;BNB Chain development now centers on BNB Smart Chain, where RPC endpoints are the primary programmatic interface.&lt;/li&gt;
&lt;li&gt;Chain ID 56 (mainnet) and 97 (testnet) are the values you need for wallet and app configuration.&lt;/li&gt;
&lt;li&gt;Public endpoints are fine for prototyping; production workloads usually need archive access, WebSocket support, and redundancy.&lt;/li&gt;
&lt;li&gt;OnFinality offers RPC API and dedicated node infrastructure for BNB Chain, with plans you can match to your traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the Binance Beacon Chain explorer still available?
&lt;/h3&gt;

&lt;p&gt;The Beacon Chain's role changed as BNB Chain consolidated its architecture. Historical staking data may still be reachable through archives and indexers, but new development targets BNB Smart Chain. For current data, use a BNB Smart Chain explorer or an RPC endpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between an explorer and an RPC endpoint?
&lt;/h3&gt;

&lt;p&gt;An explorer is a read-only website for humans. An RPC endpoint is a programmable interface that your code calls to read state, send transactions, and subscribe to events. Explorers are good for one-off lookups; RPC is what you build on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which chain ID should I use for BNB Smart Chain?
&lt;/h3&gt;

&lt;p&gt;Use chain ID 56 for BNB Smart Chain mainnet and chain ID 97 for BNB Chain Testnet. The native currency is BNB on mainnet and tBNB on testnet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I query historical staking data over RPC?
&lt;/h3&gt;

&lt;p&gt;Some historical state is available if the endpoint supports archive queries, but staking-specific data may require an indexer rather than a standard JSON-RPC call. Confirm archive support with your provider before relying on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a dedicated node for a small project?
&lt;/h3&gt;

&lt;p&gt;Not always. A public or shared RPC endpoint is often enough for low-volume apps. Move to a dedicated node when you need consistent throughput, archive access, or isolation from other users' traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I avoid downtime if my RPC endpoint fails?
&lt;/h3&gt;

&lt;p&gt;Configure at least one fallback endpoint, monitor error rates and block lag, and keep your provider's status information handy. Redundancy at the application layer is the simplest protection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/bnb" rel="noopener noreferrer"&gt;BNB Chain RPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/bnb-testnet" rel="noopener noreferrer"&gt;BNB Chain Testnet RPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/binance-beacon-chain-explorer" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Solana RPC Providers With Dedicated Nodes: How to Evaluate</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:20:21 +0000</pubDate>
      <link>https://dev.to/onfinality/solana-rpc-providers-with-dedicated-nodes-how-to-evaluate-235g</link>
      <guid>https://dev.to/onfinality/solana-rpc-providers-with-dedicated-nodes-how-to-evaluate-235g</guid>
      <description>&lt;p&gt;Solana RPC is not a generic EVM endpoint. The chain produces blocks continuously, account state changes constantly, and many applications depend on WebSocket subscriptions rather than one-off reads. That combination means a shared public endpoint can work for a prototype but often stops being the right fit once you have real users, background indexers, or trading logic. A dedicated Solana node changes the economics: you get isolated resources for your own traffic instead of sharing a pool with other tenants.&lt;/p&gt;

&lt;p&gt;This article focuses on how to evaluate providers that offer dedicated Solana nodes, not on listing a single winner. The right provider depends on your workload shape, your tolerance for operational work, and how much control you need over the node itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a dedicated Solana node is the right fit
&lt;/h2&gt;

&lt;p&gt;Before comparing providers, decide whether you actually need a dedicated node. A dedicated node is usually justified when one or more of these is true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your application sends a high and predictable volume of requests, and shared rate limits are the bottleneck.&lt;/li&gt;
&lt;li&gt;You rely on WebSocket subscriptions such as &lt;code&gt;accountSubscribe&lt;/code&gt;, &lt;code&gt;logsSubscribe&lt;/code&gt;, or &lt;code&gt;programSubscribe&lt;/code&gt; and need stable connection behavior.&lt;/li&gt;
&lt;li&gt;You run indexers, backfill jobs, or analytics that scan large ranges of history.&lt;/li&gt;
&lt;li&gt;You need consistent behavior during network congestion, when shared endpoints may throttle or degrade.&lt;/li&gt;
&lt;li&gt;You want a private endpoint that is not exposed to the public internet and can be allowlisted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A dedicated node is usually not the first step if you are still validating an idea, running a low-traffic dApp, or only reading occasional account balances. In those cases a managed shared RPC API is cheaper and simpler. OnFinality offers both models, so you can start on a shared RPC API and move to a &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated node&lt;/a&gt; when the workload justifies it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "dedicated" actually means across providers
&lt;/h2&gt;

&lt;p&gt;The word "dedicated" is used loosely. Two providers can both advertise dedicated Solana nodes and deliver very different things. Ask what is actually isolated:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Shared RPC API&lt;/th&gt;
&lt;th&gt;Dedicated node&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compute and memory&lt;/td&gt;
&lt;td&gt;Shared across tenants&lt;/td&gt;
&lt;td&gt;Reserved for your workload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request throughput&lt;/td&gt;
&lt;td&gt;Pooled limits&lt;/td&gt;
&lt;td&gt;Sized to your plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket connections&lt;/td&gt;
&lt;td&gt;Shared gateway&lt;/td&gt;
&lt;td&gt;Direct to your node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Endpoint visibility&lt;/td&gt;
&lt;td&gt;Public or keyed URL&lt;/td&gt;
&lt;td&gt;Private, often allowlisted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node version control&lt;/td&gt;
&lt;td&gt;Provider-managed&lt;/td&gt;
&lt;td&gt;Provider-managed, sometimes configurable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure blast radius&lt;/td&gt;
&lt;td&gt;Affects all tenants&lt;/td&gt;
&lt;td&gt;Limited to your node&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A genuinely dedicated Solana node should give you your own process and your own connection budget. If a provider only gives you a private URL that still routes through a shared backend, you are buying a private label, not isolation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provider evaluation matrix for Solana dedicated nodes
&lt;/h2&gt;

&lt;p&gt;Use this matrix to compare providers on the dimensions that matter for Solana specifically. Fill it in per provider rather than relying on marketing pages.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evaluation area&lt;/th&gt;
&lt;th&gt;What to verify&lt;/th&gt;
&lt;th&gt;Why it matters on Solana&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Node type&lt;/td&gt;
&lt;td&gt;Full vs archive, and whether historical state is available&lt;/td&gt;
&lt;td&gt;Backfills and analytics need older slots&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method coverage&lt;/td&gt;
&lt;td&gt;Support for &lt;code&gt;getProgramAccounts&lt;/code&gt;, &lt;code&gt;getSignaturesForAddress&lt;/code&gt;, &lt;code&gt;getTransaction&lt;/code&gt; with full encoding&lt;/td&gt;
&lt;td&gt;Many apps depend on these for indexing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket support&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;accountSubscribe&lt;/code&gt;, &lt;code&gt;logsSubscribe&lt;/code&gt;, &lt;code&gt;programSubscribe&lt;/code&gt;, &lt;code&gt;slotSubscribe&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Real-time features break without stable subscriptions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;td&gt;HTTP and WebSocket endpoints, TLS, private networking options&lt;/td&gt;
&lt;td&gt;Different clients need different transports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate and connection limits&lt;/td&gt;
&lt;td&gt;Requests per second, concurrent connections, subscription caps&lt;/td&gt;
&lt;td&gt;Determines whether the plan fits your traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failover&lt;/td&gt;
&lt;td&gt;Whether you can run a second node or endpoint for redundancy&lt;/td&gt;
&lt;td&gt;Single points of failure are a production risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;Metrics, logs, and alerting exposed to you&lt;/td&gt;
&lt;td&gt;You cannot operate what you cannot see&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support model&lt;/td&gt;
&lt;td&gt;Response channels and escalation path&lt;/td&gt;
&lt;td&gt;Node issues need fast human response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Migration path&lt;/td&gt;
&lt;td&gt;How endpoint changes are rolled out&lt;/td&gt;
&lt;td&gt;Avoids downtime during cutover&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;OnFinality appears first here because it offers both a managed Solana RPC API and dedicated node infrastructure, so you can evaluate the same vendor across both models. Compare other providers against the same rows rather than against a feature list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solana-specific methods and limits to test
&lt;/h2&gt;

&lt;p&gt;Solana's JSON-RPC surface is broad, and some methods are far more expensive than others. Before you commit to a provider, test the methods your application actually uses. A minimal connectivity check looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://solana.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getLatestBlockhash",
    "params": [{"commitment": "confirmed"}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a dedicated node, repeat the same call against your private endpoint and then test the heavier methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SOLANA_DEDICATED_ENDPOINT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "getSignaturesForAddress",
    "params": ["&amp;lt;ACCOUNT_PUBKEY&amp;gt;", {"limit": 100}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pay attention to how the provider handles &lt;code&gt;getProgramAccounts&lt;/code&gt; with filters, since this method can be expensive and is often rate-limited differently from simple reads. Also confirm whether transaction responses include full metadata or only signatures, because indexers usually need the full form.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSocket behavior is where many providers differ
&lt;/h2&gt;

&lt;p&gt;Real-time Solana applications often depend on subscriptions more than on HTTP calls. Test WebSocket behavior explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;WebSocket&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ws&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://solana.api.onfinality.io/public-ws&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logsSubscribe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;mentions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;PROGRAM_ID&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logsNotification&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slot&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things to check with any provider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the connection stay open under load, or does it drop and require reconnection logic?&lt;/li&gt;
&lt;li&gt;Are subscription limits per connection or per account?&lt;/li&gt;
&lt;li&gt;Is there a documented reconnection and replay strategy?&lt;/li&gt;
&lt;li&gt;How are missed slots or gaps surfaced to the client?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a provider cannot answer these clearly, treat that as a risk for any real-time feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration checkpoints before you cut over
&lt;/h2&gt;

&lt;p&gt;Moving from a shared endpoint to a dedicated Solana node is a configuration change, but it touches every client. Plan the cutover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inventory every place an RPC URL is configured, including frontend wallets, backend services, cron jobs, and CI.&lt;/li&gt;
&lt;li&gt;Add the new endpoint alongside the old one so both are reachable during the transition.&lt;/li&gt;
&lt;li&gt;Run a shadow period where a non-critical service reads from the dedicated node and you compare responses.&lt;/li&gt;
&lt;li&gt;Verify commitment levels match between environments, since &lt;code&gt;processed&lt;/code&gt;, &lt;code&gt;confirmed&lt;/code&gt;, and &lt;code&gt;finalized&lt;/code&gt; behave differently.&lt;/li&gt;
&lt;li&gt;Update WebSocket clients and confirm reconnection logic works against the new endpoint.&lt;/li&gt;
&lt;li&gt;Keep the old endpoint available as a fallback until you are confident in the new one.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A simple environment-based configuration keeps this manageable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SOLANA_RPC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOLANA_RPC_URL&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://solana.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SOLANA_WS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOLANA_WS_URL&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://solana.api.onfinality.io/public-ws&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For wallet or app network configuration, keep the chain identity consistent with Solana mainnet: native currency SOL with 9 decimals, and the explorer at &lt;code&gt;https://explorer.solana.com&lt;/code&gt;. If you are testing first, use &lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet&lt;/a&gt; and keep devnet and mainnet configuration separate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost and operations tradeoffs
&lt;/h2&gt;

&lt;p&gt;Dedicated nodes shift cost from per-request pricing toward reserved capacity. That is usually favorable when your traffic is steady and high, and less favorable when it is spiky or low. Consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reserved capacity is predictable but you pay for it even during quiet periods.&lt;/li&gt;
&lt;li&gt;Shared RPC APIs scale down to zero cost when idle, which suits early-stage projects.&lt;/li&gt;
&lt;li&gt;Running your own Solana node gives maximum control but adds significant operational work: hardware, upgrades, monitoring, and incident response.&lt;/li&gt;
&lt;li&gt;A managed dedicated node sits between those extremes: you get isolation without owning the full operations burden.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most teams, the practical sequence is shared RPC API first, then a dedicated node once traffic and reliability requirements are clear. Review &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; to compare models, and check &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; if you also need other chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operational checklist after go-live
&lt;/h2&gt;

&lt;p&gt;Once the dedicated node is serving production traffic, keep these in place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor request latency, error rates, and WebSocket connection counts.&lt;/li&gt;
&lt;li&gt;Alert on slot lag so you notice when the node falls behind the cluster.&lt;/li&gt;
&lt;li&gt;Track subscription churn to catch clients that reconnect too often.&lt;/li&gt;
&lt;li&gt;Keep a documented fallback endpoint and test it periodically.&lt;/li&gt;
&lt;li&gt;Review node version and upgrade windows with your provider.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A lightweight monitoring probe can catch regressions early:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nv"&gt;RESPONSE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SOLANA_DEDICATED_ENDPOINT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"getHealth"}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"solana rpc http status: &lt;/span&gt;&lt;span class="nv"&gt;$RESPONSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A dedicated Solana node is justified by steady high traffic, WebSocket dependence, indexing workloads, or a need for private endpoints.&lt;/li&gt;
&lt;li&gt;"Dedicated" varies by provider; verify what is actually isolated before comparing prices.&lt;/li&gt;
&lt;li&gt;Test Solana-specific methods such as &lt;code&gt;getProgramAccounts&lt;/code&gt; and &lt;code&gt;getSignaturesForAddress&lt;/code&gt;, not just simple reads.&lt;/li&gt;
&lt;li&gt;WebSocket subscription behavior is often the deciding factor for real-time apps.&lt;/li&gt;
&lt;li&gt;Plan migration with a shadow period and a fallback endpoint rather than a hard cutover.&lt;/li&gt;
&lt;li&gt;OnFinality offers both a Solana RPC API and dedicated node infrastructure, so you can match the model to your workload.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do I need a dedicated Solana node for a small dApp?
&lt;/h3&gt;

&lt;p&gt;Usually not. A managed shared RPC API is a better starting point until traffic, WebSocket usage, or reliability requirements justify reserved capacity.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between a dedicated node and a private RPC endpoint?
&lt;/h3&gt;

&lt;p&gt;A private endpoint can still route through shared backend infrastructure. A dedicated node gives your workload its own compute and connection budget, which is what actually reduces contention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which Solana methods should I benchmark before choosing a provider?
&lt;/h3&gt;

&lt;p&gt;Test the methods your app depends on, especially &lt;code&gt;getProgramAccounts&lt;/code&gt;, &lt;code&gt;getSignaturesForAddress&lt;/code&gt;, &lt;code&gt;getTransaction&lt;/code&gt;, and any subscription methods used by your real-time features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use the same endpoint for HTTP and WebSocket?
&lt;/h3&gt;

&lt;p&gt;No. Solana uses separate HTTP and WebSocket URLs. OnFinality exposes both, and you should configure each transport explicitly in your clients.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I avoid downtime when migrating to a dedicated node?
&lt;/h3&gt;

&lt;p&gt;Run the new endpoint alongside the old one, shadow traffic from a non-critical service, verify commitment levels and WebSocket behavior, then cut over with a fallback still in place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where can I see which networks OnFinality supports?
&lt;/h3&gt;

&lt;p&gt;See &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; for the current list, and &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; for plan details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC network&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/best-rpc-providers-for-solana-with-dedicated-nodes" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>solana</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Base Node RPC: Endpoint, Chain ID &amp; Debugging</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:19:48 +0000</pubDate>
      <link>https://dev.to/onfinality/base-node-rpc-endpoint-chain-id-debugging-511m</link>
      <guid>https://dev.to/onfinality/base-node-rpc-endpoint-chain-id-debugging-511m</guid>
      <description>&lt;p&gt;Base is an Ethereum Layer 2 built on the OP Stack, which means its node RPC interface is deliberately familiar: standard JSON-RPC over HTTP, the same &lt;code&gt;eth_*&lt;/code&gt; method names you already use on Ethereum, and a small set of OP-Stack-specific methods on top. If you are wiring up a wallet, a backend indexer, or a test suite, you mostly need the right chain settings, a working endpoint, and a clear debugging path when a request fails.&lt;/p&gt;

&lt;p&gt;This page is a working reference for Base node RPC. It covers the settings you paste into a wallet, how to send a request with curl and with viem, what to check when a call fails, and how to decide between a public endpoint and a dedicated Base node.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chain settings at a glance
&lt;/h2&gt;

&lt;p&gt;Before you write any code, confirm the network parameters. Base mainnet and Base Sepolia are separate networks with different chain IDs, so a wallet or SDK pointed at the wrong one will look like it is working while returning the wrong data.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Base mainnet&lt;/th&gt;
&lt;th&gt;Base Sepolia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID&lt;/td&gt;
&lt;td&gt;8453&lt;/td&gt;
&lt;td&gt;84532&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;ETH (18 decimals)&lt;/td&gt;
&lt;td&gt;ETH (18 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://basescan.org" rel="noopener noreferrer"&gt;https://basescan.org&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://sepolia.basescan.org" rel="noopener noreferrer"&gt;https://sepolia.basescan.org&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPC transport&lt;/td&gt;
&lt;td&gt;HTTP (JSON-RPC)&lt;/td&gt;
&lt;td&gt;HTTP (JSON-RPC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical use&lt;/td&gt;
&lt;td&gt;Production apps, real value&lt;/td&gt;
&lt;td&gt;Development, testing, faucets&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A quick sanity check: call &lt;code&gt;eth_chainId&lt;/code&gt; and confirm it returns &lt;code&gt;0x2105&lt;/code&gt; for mainnet (8453 in decimal) or &lt;code&gt;0x14a34&lt;/code&gt; for Sepolia (84532). If the value does not match the network you intended, stop and fix the configuration before debugging anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Base to a wallet
&lt;/h2&gt;

&lt;p&gt;Most wallets accept a custom network. The fields map directly to the table above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network name: Base&lt;/li&gt;
&lt;li&gt;RPC URL: your Base endpoint&lt;/li&gt;
&lt;li&gt;Chain ID: 8453&lt;/li&gt;
&lt;li&gt;Currency symbol: ETH&lt;/li&gt;
&lt;li&gt;Block explorer: &lt;a href="https://basescan.org" rel="noopener noreferrer"&gt;https://basescan.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Base Sepolia, use chain ID 84532 and the Sepolia explorer. If you are building a wallet connection flow, you can request the network programmatically instead of asking users to type it in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethereum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wallet_addEthereumChain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="na"&gt;chainId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x2105&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;chainName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Base&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;nativeCurrency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ether&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ETH&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;rpcUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://base.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;blockExplorerUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://basescan.org&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using OnFinality for Base, the public endpoint is &lt;code&gt;https://base.api.onfinality.io/public&lt;/code&gt; and the Base Sepolia equivalent is &lt;code&gt;https://base-sepolia.api.onfinality.io/public&lt;/code&gt;. For production traffic, a dedicated Base node gives you a private endpoint you can rotate without touching user configuration. See the &lt;a href="https://onfinality.io/networks/base" rel="noopener noreferrer"&gt;Base network page&lt;/a&gt; and &lt;a href="https://onfinality.io/networks/base-sepolia" rel="noopener noreferrer"&gt;Base Sepolia network page&lt;/a&gt; for current details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending your first Base RPC request
&lt;/h2&gt;

&lt;p&gt;The fastest way to confirm an endpoint works is a single curl call. This checks connectivity, chain ID, and the latest block in one shot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://base.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://base.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A healthy response returns a JSON object with a &lt;code&gt;result&lt;/code&gt; field. If you get an error object instead, the &lt;code&gt;error.code&lt;/code&gt; and &lt;code&gt;error.message&lt;/code&gt; tell you whether the problem is the request, the endpoint, or the network.&lt;/p&gt;

&lt;p&gt;In application code, the same call looks like this with viem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viem/chains&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://base.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blockNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chainId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getChainId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;chainId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blockNumber&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because Base follows Ethereum conventions, most Ethereum tooling works without a Base-specific adapter. The main differences are chain ID, explorer URLs, and a handful of OP-Stack methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Base RPC methods matter in practice
&lt;/h2&gt;

&lt;p&gt;You do not need every method. Most applications lean on a small set, and knowing which ones are heavier helps you plan capacity.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Notes for Base&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_chainId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the chain ID&lt;/td&gt;
&lt;td&gt;Use to verify you are on 8453 or 84532&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_blockNumber&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Latest block height&lt;/td&gt;
&lt;td&gt;Cheap, good for health checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_getBalance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Account balance&lt;/td&gt;
&lt;td&gt;Common in wallet flows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_call&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read-only contract call&lt;/td&gt;
&lt;td&gt;Core of most dapp reads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_getLogs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Query event logs&lt;/td&gt;
&lt;td&gt;Heaviest common method; scope by block range&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_getTransactionReceipt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Transaction status&lt;/td&gt;
&lt;td&gt;Poll after sending a tx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_estimateGas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gas estimate&lt;/td&gt;
&lt;td&gt;Run before sending&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth_sendRawTransaction&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Broadcast a signed tx&lt;/td&gt;
&lt;td&gt;Returns a tx hash, not a receipt&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;eth_getLogs&lt;/code&gt; deserves special attention. Wide block ranges and broad topic filters can return large payloads and are a frequent cause of timeouts. Narrow the range, filter by address, and paginate where possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debug path for common Base RPC failures
&lt;/h2&gt;

&lt;p&gt;When something breaks, the error message usually points at the layer. Work through this table before assuming the endpoint is down.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;First check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;chainId&lt;/code&gt; mismatch&lt;/td&gt;
&lt;td&gt;Wrong network configured&lt;/td&gt;
&lt;td&gt;Call &lt;code&gt;eth_chainId&lt;/code&gt;, compare to 8453/84532&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;method not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Typo or unsupported method&lt;/td&gt;
&lt;td&gt;Confirm method name and endpoint transport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timeout on &lt;code&gt;eth_getLogs&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Block range too wide&lt;/td&gt;
&lt;td&gt;Reduce range, add address filter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nonce too low&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stale nonce after a stuck tx&lt;/td&gt;
&lt;td&gt;Re-read &lt;code&gt;eth_getTransactionCount&lt;/code&gt; with &lt;code&gt;pending&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;insufficient funds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gas or value exceeds balance&lt;/td&gt;
&lt;td&gt;Check balance and gas estimate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empty &lt;code&gt;result&lt;/code&gt; on a read&lt;/td&gt;
&lt;td&gt;Contract not deployed on this network&lt;/td&gt;
&lt;td&gt;Verify address on the correct explorer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intermittent 429&lt;/td&gt;
&lt;td&gt;Shared endpoint rate limits&lt;/td&gt;
&lt;td&gt;Move heavy reads to a dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two patterns cause most confusion. First, mixing mainnet and testnet data: a contract address that exists on Base mainnet will not exist on Base Sepolia, and vice versa. Second, treating &lt;code&gt;eth_sendRawTransaction&lt;/code&gt; as final: it returns a hash immediately, but you must poll &lt;code&gt;eth_getTransactionReceipt&lt;/code&gt; to know whether the transaction succeeded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Public endpoint or dedicated Base node?
&lt;/h2&gt;

&lt;p&gt;This is the decision most teams face once an app moves past prototyping. The right answer depends on your workload shape, not on a single benchmark.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Public endpoint&lt;/th&gt;
&lt;th&gt;Dedicated Base node&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prototypes and demos&lt;/td&gt;
&lt;td&gt;Usually fine&lt;/td&gt;
&lt;td&gt;Not needed yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low-volume reads&lt;/td&gt;
&lt;td&gt;Usually fine&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy &lt;code&gt;eth_getLogs&lt;/code&gt; indexing&lt;/td&gt;
&lt;td&gt;Risky under load&lt;/td&gt;
&lt;td&gt;Recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-frequency trading or bots&lt;/td&gt;
&lt;td&gt;Shared limits apply&lt;/td&gt;
&lt;td&gt;Recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compliance or data isolation needs&lt;/td&gt;
&lt;td&gt;Not suitable&lt;/td&gt;
&lt;td&gt;Recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Predictable production traffic&lt;/td&gt;
&lt;td&gt;Shared capacity&lt;/td&gt;
&lt;td&gt;Recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A useful rule: if your application's reliability depends on a specific request pattern that a shared endpoint cannot guarantee, isolate that pattern onto a dedicated node and leave everything else on the public endpoint. This keeps cost proportional to actual need. OnFinality offers both shared RPC API access and dedicated Base nodes; see &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; for the current options and &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; for the full list.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSocket and subscription considerations
&lt;/h2&gt;

&lt;p&gt;Base supports JSON-RPC over HTTP, which is what most applications use. If you need push-style updates, check whether your provider exposes WebSocket transport for Base before designing around subscriptions. HTTP polling of &lt;code&gt;eth_blockNumber&lt;/code&gt; or &lt;code&gt;eth_getTransactionReceipt&lt;/code&gt; is a reliable fallback and is easier to reason about under failure.&lt;/p&gt;

&lt;p&gt;If you do use subscriptions, plan for reconnection logic. Long-lived connections drop, and a subscription that silently stops delivering events is worse than one that fails loudly. Treat the connection as something that will need to be re-established.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operational checklist before launch
&lt;/h2&gt;

&lt;p&gt;Before you point production traffic at any Base endpoint, confirm the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chain ID is verified at runtime, not just in config.&lt;/li&gt;
&lt;li&gt;The endpoint is reachable from your deployment environment, not only from your laptop.&lt;/li&gt;
&lt;li&gt;Heavy methods such as &lt;code&gt;eth_getLogs&lt;/code&gt; are scoped and paginated.&lt;/li&gt;
&lt;li&gt;You have a fallback endpoint or a plan for one.&lt;/li&gt;
&lt;li&gt;Errors are logged with the JSON-RPC error code, not just a generic message.&lt;/li&gt;
&lt;li&gt;You know which network each contract address belongs to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple monitoring probe keeps you ahead of problems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;probe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eth_blockNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this on a schedule and alert on repeated failures. It is a small amount of code that catches a large class of incidents early.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Base uses standard Ethereum JSON-RPC; chain ID 8453 for mainnet and 84532 for Sepolia.&lt;/li&gt;
&lt;li&gt;Verify &lt;code&gt;eth_chainId&lt;/code&gt; at runtime to avoid silently querying the wrong network.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_getLogs&lt;/code&gt; is the most common source of timeouts; scope block ranges and filters.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_sendRawTransaction&lt;/code&gt; returns a hash, not a receipt; poll for the receipt to confirm success.&lt;/li&gt;
&lt;li&gt;Public endpoints suit prototypes and light reads; dedicated Base nodes suit heavy, predictable, or isolated workloads.&lt;/li&gt;
&lt;li&gt;OnFinality provides Base RPC API access and dedicated nodes; check &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; and &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported networks&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the Base chain ID?&lt;/strong&gt;&lt;br&gt;
Base mainnet uses chain ID 8453. Base Sepolia uses 84532. Always confirm with &lt;code&gt;eth_chainId&lt;/code&gt; at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the Base RPC endpoint?&lt;/strong&gt;&lt;br&gt;
Any JSON-RPC endpoint that serves the Base network. OnFinality exposes a public Base endpoint and dedicated options; see the &lt;a href="https://onfinality.io/networks/base" rel="noopener noreferrer"&gt;Base network page&lt;/a&gt; for current details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use Ethereum tooling with Base?&lt;/strong&gt;&lt;br&gt;
Yes. Base follows Ethereum conventions, so most Ethereum libraries and wallets work once you set the correct chain ID and endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does my Base transaction show as pending?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;eth_sendRawTransaction&lt;/code&gt; returns a hash before the transaction is included. Poll &lt;code&gt;eth_getTransactionReceipt&lt;/code&gt; until it returns a receipt, and check gas settings if it stalls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need a dedicated Base node?&lt;/strong&gt;&lt;br&gt;
Only if your workload needs private capacity, isolation, or predictable behavior under heavy reads. Prototypes and light apps usually do not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I debug a Base RPC timeout?&lt;/strong&gt;&lt;br&gt;
Start with the method. &lt;code&gt;eth_getLogs&lt;/code&gt; with a wide range is the usual culprit; narrow the range and add filters before investigating the endpoint itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/base" rel="noopener noreferrer"&gt;Base RPC network page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/base-sepolia" rel="noopener noreferrer"&gt;Base Sepolia RPC network page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/base-node-rpc" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Base L2 on Ethereum: RPC Setup and Connection Guide</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:19:15 +0000</pubDate>
      <link>https://dev.to/onfinality/base-l2-on-ethereum-rpc-setup-and-connection-guide-561c</link>
      <guid>https://dev.to/onfinality/base-l2-on-ethereum-rpc-setup-and-connection-guide-561c</guid>
      <description>&lt;p&gt;Base is an Ethereum Layer 2 network. It executes transactions on its own chain and posts the resulting data back to Ethereum, which is where the term "L2 on Ethereum" comes from. For developers, the practical consequence is simple: Base speaks the same JSON-RPC dialect as Ethereum, so most tools, libraries, and contracts work with only a chain ID and RPC URL change.&lt;/p&gt;

&lt;p&gt;This page answers the immediate question, then helps you decide how to connect. If you already know what Base is and just need settings, jump to the chain settings table. If you are evaluating how to run Base in production, the decision section below is the place to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick recommendation: which connection path fits your workload
&lt;/h2&gt;

&lt;p&gt;Not every project needs the same Base setup. Use the table below to match your situation to a connection approach. The right answer depends on request volume, whether you need archive or trace data, and how much operational work you want to own.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Suggested approach&lt;/th&gt;
&lt;th&gt;What to watch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prototyping, scripts, low-volume reads&lt;/td&gt;
&lt;td&gt;Public Base endpoint&lt;/td&gt;
&lt;td&gt;Shared capacity; fine for testing, not for traffic spikes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production dApp with steady traffic&lt;/td&gt;
&lt;td&gt;Managed RPC API&lt;/td&gt;
&lt;td&gt;Rate limits, failover, and monitoring matter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy indexing, archive, or trace calls&lt;/td&gt;
&lt;td&gt;Dedicated node&lt;/td&gt;
&lt;td&gt;Storage and sync time are your responsibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compliance or data-residency needs&lt;/td&gt;
&lt;td&gt;Dedicated node&lt;/td&gt;
&lt;td&gt;You control the deployment environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-chain app including Base&lt;/td&gt;
&lt;td&gt;Managed multi-chain RPC&lt;/td&gt;
&lt;td&gt;Consistent tooling across chains reduces bugs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are unsure, start with a managed endpoint and move to a dedicated node only when you can name the specific limit you are hitting. OnFinality provides both &lt;a href="https://onfinality.io/api-service" rel="noopener noreferrer"&gt;RPC API access&lt;/a&gt; and &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated node infrastructure&lt;/a&gt;, so you can scale the same Base workload without changing your application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Base actually is, in one paragraph
&lt;/h2&gt;

&lt;p&gt;Base is a Layer 2 built on the OP Stack. It batches transactions, executes them off Ethereum mainnet, and posts compressed data back to Ethereum for settlement and data availability. Users pay fees in ETH on Base, and the network exposes an EVM-compatible interface. That means &lt;code&gt;eth_call&lt;/code&gt;, &lt;code&gt;eth_getLogs&lt;/code&gt;, &lt;code&gt;eth_sendRawTransaction&lt;/code&gt;, and the rest of the standard Ethereum JSON-RPC method set behave as you expect.&lt;/p&gt;

&lt;p&gt;The important nuance for developers is that Base is not Ethereum. It has its own chain ID, its own block explorer, and its own gas market. Contracts deployed to Ethereum mainnet are not automatically available on Base; you deploy them separately. Addresses can match if you use the same deployer and nonce, but that is a convenience, not a guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chain settings at a glance
&lt;/h2&gt;

&lt;p&gt;Use these values when adding Base to a wallet, a Hardhat config, a Foundry profile, or a viem client.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Base mainnet&lt;/th&gt;
&lt;th&gt;Base Sepolia testnet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID&lt;/td&gt;
&lt;td&gt;8453&lt;/td&gt;
&lt;td&gt;84532&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;ETH (18 decimals)&lt;/td&gt;
&lt;td&gt;ETH (18 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://basescan.org" rel="noopener noreferrer"&gt;https://basescan.org&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://sepolia.basescan.org" rel="noopener noreferrer"&gt;https://sepolia.basescan.org&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OnFinality public RPC&lt;/td&gt;
&lt;td&gt;&lt;a href="https://base.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://base.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://base-sepolia.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://base-sepolia.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a full network reference, see the &lt;a href="https://onfinality.io/networks/base" rel="noopener noreferrer"&gt;Base network page&lt;/a&gt; and the &lt;a href="https://onfinality.io/networks/base-sepolia" rel="noopener noreferrer"&gt;Base Sepolia network page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting with curl and JavaScript
&lt;/h2&gt;

&lt;p&gt;The fastest way to confirm your endpoint works is a single JSON-RPC call. This returns the current block number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://base.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful response looks like &lt;code&gt;{"jsonrpc":"2.0","id":1,"result":"0x..."}&lt;/code&gt;. If you get an error object instead, check the URL, the method name, and whether your client is sending a POST with a JSON body.&lt;/p&gt;

&lt;p&gt;In JavaScript, the same call through viem looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;viem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;viem/chains&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://base.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blockNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using ethers, the pattern is similar: create a &lt;code&gt;JsonRpcProvider&lt;/code&gt; with the Base RPC URL and call &lt;code&gt;getBlockNumber()&lt;/code&gt;. The chain ID is validated by the library when you pass the chain object, which catches misconfigured endpoints early.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wallet and network configuration
&lt;/h2&gt;

&lt;p&gt;Adding Base to a wallet is a common first step for testers and support teams. The fields map directly to the chain settings table above. In MetaMask, choose "Add network manually" and enter the chain ID, RPC URL, and explorer URL. For Base Sepolia, use chain ID 84532 and the Sepolia explorer.&lt;/p&gt;

&lt;p&gt;A frequent mistake is mixing mainnet and testnet values. If your wallet shows a balance of zero after a successful faucet claim, confirm you are on the testnet chain ID and that the faucet sent funds to the same address the wallet is displaying. Faucet availability changes over time, so check the current Base documentation rather than relying on a cached link.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Base fits in an Ethereum stack
&lt;/h2&gt;

&lt;p&gt;Base is one of several L2s that share Ethereum tooling. If your application already supports Ethereum mainnet, adding Base is mostly a configuration change. The harder questions are operational: how do you handle reorgs, how do you index logs efficiently, and how do you keep latency predictable under load.&lt;/p&gt;

&lt;p&gt;For teams running multiple chains, a consistent RPC layer matters more than any single chain's quirks. OnFinality supports Base alongside Ethereum and other networks, so you can use one provider and one set of credentials across your stack. See &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; for the current list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production readiness checklist
&lt;/h2&gt;

&lt;p&gt;Before you point real users at a Base endpoint, work through these items. They are ordered by how often they cause incidents.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Failover.&lt;/strong&gt; Do you have a second endpoint configured? A single URL is a single point of failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits.&lt;/strong&gt; Do you know your requests per second ceiling, and does your client back off on 429 responses?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archive and trace needs.&lt;/strong&gt; Do you call &lt;code&gt;eth_getLogs&lt;/code&gt; over wide block ranges, or use trace methods? These are heavier and may need a dedicated node.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reorg handling.&lt;/strong&gt; Base, like other L2s, can reorg. Your indexer should confirm finality before treating data as settled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring.&lt;/strong&gt; Do you alert on error rate and latency, not just on total downtime?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key management.&lt;/strong&gt; Are RPC credentials stored outside your source tree?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If several of these are unanswered, a managed provider removes most of the operational burden. If you need control over the node itself, a &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated node&lt;/a&gt; gives you that at the cost of running the infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes and how to read them
&lt;/h2&gt;

&lt;p&gt;Most Base RPC problems fall into a small number of categories. The table below maps symptoms to likely causes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;method not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Method not supported by the endpoint&lt;/td&gt;
&lt;td&gt;Confirm the method is part of the standard EVM set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;429 Too Many Requests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rate limit reached&lt;/td&gt;
&lt;td&gt;Add backoff and consider a higher tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timeouts on &lt;code&gt;eth_getLogs&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Block range too wide&lt;/td&gt;
&lt;td&gt;Narrow the range or use an indexer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong chain data&lt;/td&gt;
&lt;td&gt;Endpoint points to a different network&lt;/td&gt;
&lt;td&gt;Verify chain ID with &lt;code&gt;eth_chainId&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stale block number&lt;/td&gt;
&lt;td&gt;Caching or a lagging node&lt;/td&gt;
&lt;td&gt;Compare against a second endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A quick diagnostic is to call &lt;code&gt;eth_chainId&lt;/code&gt; and compare the result to the expected value. For Base mainnet it should return &lt;code&gt;0x2105&lt;/code&gt; (8453 in decimal). For Base Sepolia it should return &lt;code&gt;0x14a34&lt;/code&gt; (84532). If those do not match, you are talking to the wrong network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing between public, managed, and dedicated
&lt;/h2&gt;

&lt;p&gt;The public endpoint is a good default for development and low-volume reads. It is shared, so it is not the right choice for production traffic that needs predictable latency.&lt;/p&gt;

&lt;p&gt;A managed RPC API sits in the middle. You get a stable URL, monitoring, and the ability to scale without running nodes. This is the common choice for dApps, wallets, and backends that need Base plus a few other chains.&lt;/p&gt;

&lt;p&gt;A dedicated node is for teams that need archive data, trace calls, custom configuration, or a specific deployment environment. The tradeoff is that you own sync time, storage, and upgrades. For most teams, the decision comes down to whether the workload justifies that ownership. OnFinality's &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; page outlines the options if you want to compare cost models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Base is an Ethereum L2 with an EVM-compatible JSON-RPC interface, so Ethereum tooling works with a chain ID and URL change.&lt;/li&gt;
&lt;li&gt;Base mainnet uses chain ID 8453; Base Sepolia uses 84532.&lt;/li&gt;
&lt;li&gt;The OnFinality public endpoints are &lt;code&gt;https://base.api.onfinality.io/public&lt;/code&gt; and &lt;code&gt;https://base-sepolia.api.onfinality.io/public&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Public endpoints suit development; production workloads usually need managed or dedicated infrastructure.&lt;/li&gt;
&lt;li&gt;Always verify chain ID with &lt;code&gt;eth_chainId&lt;/code&gt; when debugging unexpected data.&lt;/li&gt;
&lt;li&gt;Plan for failover, rate limits, and reorg handling before launch.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Base the same as Ethereum?&lt;/strong&gt;&lt;br&gt;
No. Base is a separate Layer 2 network that settles to Ethereum. It uses Ethereum tooling and ETH as its native currency, but it has its own chain ID and block explorer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the Base chain ID?&lt;/strong&gt;&lt;br&gt;
Base mainnet is 8453. Base Sepolia is 84532.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use Ethereum RPC methods on Base?&lt;/strong&gt;&lt;br&gt;
Yes. Standard EVM JSON-RPC methods such as &lt;code&gt;eth_call&lt;/code&gt;, &lt;code&gt;eth_getLogs&lt;/code&gt;, and &lt;code&gt;eth_sendRawTransaction&lt;/code&gt; work on Base. Some Ethereum-specific methods may not apply.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need a dedicated node for Base?&lt;/strong&gt;&lt;br&gt;
Only if you need archive data, trace calls, custom configuration, or a specific deployment environment. Most applications do fine with a managed endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I test Base without spending real ETH?&lt;/strong&gt;&lt;br&gt;
Use Base Sepolia and a faucet. Confirm you are on chain ID 84532 and that the faucet sent funds to your wallet address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where can I find OnFinality's Base endpoints?&lt;/strong&gt;&lt;br&gt;
See the &lt;a href="https://onfinality.io/networks/base" rel="noopener noreferrer"&gt;Base network page&lt;/a&gt; and the &lt;a href="https://onfinality.io/networks/base-sepolia" rel="noopener noreferrer"&gt;Base Sepolia network page&lt;/a&gt;. For pricing and plan details, visit &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/base" rel="noopener noreferrer"&gt;Base RPC network&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/base-sepolia" rel="noopener noreferrer"&gt;Base Sepolia RPC network&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/base-l2-ethereum" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Solana Devnet RPC: Endpoint, Faucet &amp; Debugging</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:18:43 +0000</pubDate>
      <link>https://dev.to/onfinality/solana-devnet-rpc-endpoint-faucet-debugging-25no</link>
      <guid>https://dev.to/onfinality/solana-devnet-rpc-endpoint-faucet-debugging-25no</guid>
      <description>&lt;p&gt;Solana devnet is a separate cluster from mainnet-beta and testnet. It runs the same runtime as mainnet, but the ledger is disposable, tokens have no value, and the network is explicitly allowed to reset. That makes it the right place to deploy a program, run integration tests, and reproduce bugs before you ship.&lt;/p&gt;

&lt;p&gt;The query "solana rpc devnet" usually comes from a developer who needs one of three things: a working endpoint URL, test SOL to pay for transactions, or a way to diagnose a failing request. This page answers all three, then explains when a public devnet endpoint stops being enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which devnet endpoint should you use?
&lt;/h2&gt;

&lt;p&gt;Pick your endpoint based on what you are doing, not on habit. Most developers start on a public endpoint and move to a managed or dedicated one when tests become part of a pipeline.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Sensible endpoint choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Learning Solana, running a few scripts&lt;/td&gt;
&lt;td&gt;Public devnet RPC&lt;/td&gt;
&lt;td&gt;Free, no setup, fine for low request volume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploying a program and iterating&lt;/td&gt;
&lt;td&gt;Public devnet RPC or a managed RPC plan&lt;/td&gt;
&lt;td&gt;You need reliable &lt;code&gt;sendTransaction&lt;/code&gt; and &lt;code&gt;getSignatureStatuses&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI pipeline running on every commit&lt;/td&gt;
&lt;td&gt;Managed RPC with a dedicated API key&lt;/td&gt;
&lt;td&gt;Predictable access and per-project keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load or latency testing&lt;/td&gt;
&lt;td&gt;Dedicated node&lt;/td&gt;
&lt;td&gt;You control the machine and can measure without noisy neighbours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testing WebSocket-driven UI&lt;/td&gt;
&lt;td&gt;Endpoint that supports &lt;code&gt;ws&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Subscriptions behave differently from polling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you only need to read accounts and send occasional transactions, a public devnet endpoint is fine. If your tests fail intermittently and you cannot tell whether the cause is your code or the endpoint, that is the signal to move to a managed service.&lt;/p&gt;

&lt;p&gt;OnFinality exposes Solana devnet as a supported network alongside Solana mainnet. You can review the &lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet network page&lt;/a&gt; for connection details, and compare plans on the &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; page if you need a keyed endpoint for CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solana devnet chain settings at a glance
&lt;/h2&gt;

&lt;p&gt;When you configure a wallet, an SDK, or a framework, you are choosing a cluster and an RPC URL. Solana does not use an EVM-style numeric chain ID for devnet in the same way Ethereum does; the cluster identity is what matters.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Devnet value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cluster name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;devnet&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;SOL (devnet, no value)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decimals&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical RPC transport&lt;/td&gt;
&lt;td&gt;HTTP JSON-RPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subscription transport&lt;/td&gt;
&lt;td&gt;WebSocket (&lt;code&gt;ws&lt;/code&gt;) where supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;Solana Explorer with the devnet cluster selected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mainnet equivalent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mainnet-beta&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Keep devnet and mainnet configuration in separate files or environment variables. A large share of "it worked locally" incidents come from a build that silently pointed at the wrong cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting with curl and JavaScript
&lt;/h2&gt;

&lt;p&gt;A minimal JSON-RPC call confirms the endpoint is reachable and returns the current slot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://your-devnet-endpoint.example &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getSlot",
    "params": []
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In JavaScript, the common pattern is to create a connection object and pass the cluster or an explicit endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clusterApiUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LAMPORTS_PER_SOL&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@solana/web3.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Option A: use the built-in devnet cluster URL&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;clusterApiUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devnet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Option B: use your own managed devnet endpoint&lt;/span&gt;
&lt;span class="c1"&gt;// const connection = new Connection(process.env.SOLANA_DEVNET_RPC, "confirmed");&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSlot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;current devnet slot:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;slot&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicKey&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For WebSocket subscriptions, construct the connection with the &lt;code&gt;ws&lt;/code&gt; endpoint and use &lt;code&gt;onAccountChange&lt;/code&gt; or &lt;code&gt;onLogs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wsConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOLANA_DEVNET_WS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;wsEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOLANA_DEVNET_WS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wsConnection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;programId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If subscriptions drop silently, log the subscription id and re-subscribe on error rather than assuming the endpoint is broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting test SOL from the devnet faucet
&lt;/h2&gt;

&lt;p&gt;The faucet is rate limited and shared. Treat it as a convenience, not a guarantee.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request a small amount first and confirm the balance before running a large test.&lt;/li&gt;
&lt;li&gt;If a request fails, wait and retry rather than hammering the endpoint.&lt;/li&gt;
&lt;li&gt;For repeatable tests, fund a known keypair once and reuse it, or run a local validator where you can mint SOL freely.&lt;/li&gt;
&lt;li&gt;Never reuse a devnet keypair on mainnet. Generate a fresh keypair for anything that holds real value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a faucet request appears to succeed but the balance does not change, check the transaction signature on the explorer and confirm you are querying the same cluster you requested from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common devnet failures and how to read them
&lt;/h2&gt;

&lt;p&gt;Most devnet errors fall into a small number of categories. The table below maps the symptom to the likely cause.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;First thing to check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AccountNotFound&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Account not yet created, or wrong cluster&lt;/td&gt;
&lt;td&gt;Confirm cluster and that the account was initialised&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Blockhash not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blockhash expired before send&lt;/td&gt;
&lt;td&gt;Fetch a fresh blockhash and retry quickly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transaction confirmed but state unchanged&lt;/td&gt;
&lt;td&gt;Wrong program id or stale client&lt;/td&gt;
&lt;td&gt;Re-check the program id and redeploy if needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;429&lt;/code&gt; or throttling&lt;/td&gt;
&lt;td&gt;Public endpoint rate limit&lt;/td&gt;
&lt;td&gt;Reduce request rate or move to a keyed endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket stops delivering&lt;/td&gt;
&lt;td&gt;Idle timeout or network drop&lt;/td&gt;
&lt;td&gt;Add reconnect logic and re-subscribe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slot jumps or data resets&lt;/td&gt;
&lt;td&gt;Devnet ledger reset&lt;/td&gt;
&lt;td&gt;Recreate accounts and re-run setup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Devnet resets are normal. If your tests depend on pre-existing state, build a setup step that recreates it rather than assuming it persists.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a public devnet endpoint is not enough
&lt;/h2&gt;

&lt;p&gt;Public endpoints are shared, and devnet traffic is unpredictable. Two things tend to push teams toward managed infrastructure.&lt;/p&gt;

&lt;p&gt;First, CI. If every commit triggers a test suite that sends transactions, you want a stable endpoint with its own credentials so one noisy job does not affect another. Second, observability. When a test fails, you need to know whether the request reached the node, what the node returned, and how long it took. A managed RPC service gives you per-key usage and clearer error responses.&lt;/p&gt;

&lt;p&gt;OnFinality provides RPC API access and dedicated node options across many networks, including Solana. If your devnet usage is light, the shared service is usually sufficient. If you are running sustained load or need isolation, a &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated node&lt;/a&gt; removes the noisy-neighbour problem. You can see the full list of supported chains on the &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; page.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical devnet workflow
&lt;/h2&gt;

&lt;p&gt;A repeatable workflow saves more time than any single optimisation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep cluster configuration in environment variables, never hard-coded.&lt;/li&gt;
&lt;li&gt;Run a local validator for unit tests where you control the ledger.&lt;/li&gt;
&lt;li&gt;Use devnet for integration tests that need realistic network conditions.&lt;/li&gt;
&lt;li&gt;Fund a dedicated test keypair and reuse it across runs.&lt;/li&gt;
&lt;li&gt;Log request ids, signatures, and slot numbers so failures are reproducible.&lt;/li&gt;
&lt;li&gt;Add a health check that calls &lt;code&gt;getSlot&lt;/code&gt; before a test suite starts.&lt;/li&gt;
&lt;li&gt;Move to a keyed managed endpoint once tests run in CI.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This sequence keeps the cheap, fast feedback loop local and reserves network access for the cases that actually need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Solana devnet is a separate cluster with no-value SOL, used for testing programs and clients before mainnet.&lt;/li&gt;
&lt;li&gt;The cluster name is &lt;code&gt;devnet&lt;/code&gt;; keep it in environment variables and never mix it with &lt;code&gt;mainnet-beta&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The devnet faucet is rate limited, so fund a reusable test keypair instead of requesting repeatedly.&lt;/li&gt;
&lt;li&gt;Most devnet errors are blockhash expiry, wrong cluster, or rate limiting, not node faults.&lt;/li&gt;
&lt;li&gt;Devnet resets are expected; build setup steps that recreate state.&lt;/li&gt;
&lt;li&gt;Move from a public endpoint to a managed or dedicated RPC service when tests run in CI or need isolation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the Solana devnet RPC URL?
&lt;/h3&gt;

&lt;p&gt;There is no single canonical URL. You can use the cluster URL provided by your SDK, or a managed endpoint from a provider. OnFinality lists Solana devnet as a supported network; see the &lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet network page&lt;/a&gt; for connection details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Solana devnet the same as testnet?
&lt;/h3&gt;

&lt;p&gt;No. Devnet and testnet are separate clusters. Devnet is the more commonly used testing environment and is more likely to be reset. Always confirm which cluster your endpoint points to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does my devnet transaction fail with "blockhash not found"?
&lt;/h3&gt;

&lt;p&gt;The blockhash expired before the transaction was processed. Fetch a fresh blockhash immediately before sending and retry. On a busy or throttled endpoint this happens more often.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use a public devnet endpoint in production?
&lt;/h3&gt;

&lt;p&gt;Devnet is for testing, not production. For production workloads you should use mainnet with a managed or dedicated RPC service. See &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; for plan options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does OnFinality support Solana devnet?
&lt;/h3&gt;

&lt;p&gt;Yes. Solana devnet is listed among OnFinality's supported networks. Check the &lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet network page&lt;/a&gt; and the &lt;a href="https://onfinality.io/api-service" rel="noopener noreferrer"&gt;RPC API service&lt;/a&gt; page for current details.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I test WebSocket subscriptions on devnet?
&lt;/h3&gt;

&lt;p&gt;Use a &lt;code&gt;ws&lt;/code&gt; endpoint, subscribe with &lt;code&gt;onLogs&lt;/code&gt; or &lt;code&gt;onAccountChange&lt;/code&gt;, and add reconnect logic. Public endpoints may drop idle connections, so handle re-subscription explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet network page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC network page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/api-service" rel="noopener noreferrer"&gt;RPC API service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/solana-rpc-devnet" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>solana</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Gnosis API: Chain Settings, Methods, and Endpoint Setup</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:18:09 +0000</pubDate>
      <link>https://dev.to/onfinality/gnosis-api-chain-settings-methods-and-endpoint-setup-2fco</link>
      <guid>https://dev.to/onfinality/gnosis-api-chain-settings-methods-and-endpoint-setup-2fco</guid>
      <description>&lt;p&gt;The Gnosis API is the JSON-RPC surface that Gnosis Chain nodes expose to applications. If you are wiring a wallet, a Safe-based treasury tool, a payments backend, or an indexer to Gnosis, this is the interface you call. This page gives you the chain settings, a working request, the methods that matter for typical Gnosis workloads, and a way to decide what kind of endpoint you actually need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Gnosis endpoint fits your workload?
&lt;/h2&gt;

&lt;p&gt;Before copying any URL, match the endpoint type to what your application does. Gnosis traffic is often a mix of light reads and heavier log queries, and the right choice depends on volume and consistency needs rather than on the chain itself.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Typical calls&lt;/th&gt;
&lt;th&gt;Endpoint fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wallet balance display&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;eth_getBalance&lt;/code&gt;, &lt;code&gt;eth_call&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Shared or public endpoint is usually enough&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe transaction service backend&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;eth_call&lt;/code&gt;, &lt;code&gt;eth_getTransactionReceipt&lt;/code&gt;, &lt;code&gt;eth_getLogs&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Managed endpoint with predictable throughput&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payments or payroll service&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;eth_sendRawTransaction&lt;/code&gt;, receipt polling&lt;/td&gt;
&lt;td&gt;Managed endpoint plus a fallback URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indexer or analytics pipeline&lt;/td&gt;
&lt;td&gt;Wide &lt;code&gt;eth_getLogs&lt;/code&gt; ranges, archive state&lt;/td&gt;
&lt;td&gt;Dedicated node or archive-capable endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bridge or oracle relayer&lt;/td&gt;
&lt;td&gt;WebSocket subscriptions, frequent reads&lt;/td&gt;
&lt;td&gt;Dedicated node with stable connections&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your calls are occasional and read-only, a shared endpoint is a reasonable starting point. If you poll receipts in a loop, scan logs across large block ranges, or need consistent response times under load, plan for a managed or dedicated setup. You can review &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; and the &lt;a href="https://onfinality.io/networks/gnosis" rel="noopener noreferrer"&gt;Gnosis network page&lt;/a&gt; to see what is available before you commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gnosis Chain settings at a glance
&lt;/h2&gt;

&lt;p&gt;These are the values you enter into a wallet, a Hardhat or Foundry config, or an ethers/viem provider. They are stable and safe to hardcode in client configuration.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Network name&lt;/td&gt;
&lt;td&gt;Gnosis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;xDAI (XDAI), 18 decimals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://gnosisscan.io" rel="noopener noreferrer"&gt;https://gnosisscan.io&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;td&gt;HTTP JSON-RPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public endpoint&lt;/td&gt;
&lt;td&gt;&lt;a href="https://gnosis.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://gnosis.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Gnosis uses xDAI as its gas token, which is a meaningful difference from chains that pay gas in a volatile asset. For payment and payroll use cases this keeps fee accounting simpler, but it also means your users need xDAI on hand before they can send transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wallet network configuration
&lt;/h3&gt;

&lt;p&gt;Most EVM wallets accept a custom network entry. The fields map directly to the table above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chainName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gnosis"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nativeCurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"xDAI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"XDAI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"decimals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rpcUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://gnosis.api.onfinality.io/public"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"blockExplorerUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://gnosisscan.io"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;0x64&lt;/code&gt; is the hexadecimal form of chain ID 100. Wallets that expect hex will reject the decimal value, so keep both forms handy when debugging connection errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making your first Gnosis API request
&lt;/h2&gt;

&lt;p&gt;Every Gnosis API call is a JSON-RPC POST. The shape is the same as any EVM chain, so existing tooling works without modification once the endpoint and chain ID are set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://gnosis.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_blockNumber",
    "params": []
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful response returns the latest block height as a hex string. From there, the common next calls are &lt;code&gt;eth_getBalance&lt;/code&gt; for xDAI balances, &lt;code&gt;eth_call&lt;/code&gt; for contract reads, and &lt;code&gt;eth_getLogs&lt;/code&gt; for event history.&lt;/p&gt;

&lt;p&gt;In JavaScript, the same request through a provider library looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;JsonRpcProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formatEther&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JsonRpcProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://gnosis.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;chainId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gnosis&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xYourAddressHere&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Passing the chain ID explicitly helps libraries detect a mismatch early instead of silently querying the wrong network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods that matter for Gnosis workloads
&lt;/h2&gt;

&lt;p&gt;Gnosis is EVM-compatible, so the standard method set applies. In practice, a few methods carry most of the traffic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;eth_call&lt;/code&gt; — read contract state without a transaction. This is the backbone of Safe balance checks, token metadata reads, and most dashboard queries.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_getLogs&lt;/code&gt; — retrieve events. Log queries are the most common source of rate pressure because a single request can span thousands of blocks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_getTransactionReceipt&lt;/code&gt; — confirm whether a submitted transaction landed. Payment services poll this heavily.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_sendRawTransaction&lt;/code&gt; — broadcast signed transactions. This is where endpoint reliability matters most, since a dropped broadcast can leave a user waiting.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_estimateGas&lt;/code&gt; and &lt;code&gt;eth_gasPrice&lt;/code&gt; — size transactions and set fees before signing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_getCode&lt;/code&gt; and &lt;code&gt;eth_getStorageAt&lt;/code&gt; — inspect deployed contracts and raw state, useful for tooling and debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you rely on live event streams rather than polling, check whether your chosen endpoint supports WebSocket subscriptions such as &lt;code&gt;eth_subscribe&lt;/code&gt; for new heads or logs. Not every shared endpoint exposes WebSocket transport, so confirm this before designing around subscriptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging common Gnosis API failures
&lt;/h2&gt;

&lt;p&gt;Most Gnosis API problems fall into a small number of categories. The fastest path is to match the symptom to the cause before changing anything else.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;-32602&lt;/code&gt; invalid params&lt;/td&gt;
&lt;td&gt;Wrong parameter shape or missing block tag&lt;/td&gt;
&lt;td&gt;Compare the request against the method spec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;-32000&lt;/code&gt; or timeout on &lt;code&gt;eth_getLogs&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Block range too wide for the endpoint&lt;/td&gt;
&lt;td&gt;Split the range and paginate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transaction stuck as pending&lt;/td&gt;
&lt;td&gt;Broadcast accepted but not mined, or fee too low&lt;/td&gt;
&lt;td&gt;Re-check gas price and re-broadcast if needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Balance looks wrong&lt;/td&gt;
&lt;td&gt;Querying the wrong chain ID&lt;/td&gt;
&lt;td&gt;Confirm chain ID 100 and the endpoint host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intermittent 429 responses&lt;/td&gt;
&lt;td&gt;Request rate above the shared endpoint budget&lt;/td&gt;
&lt;td&gt;Add backoff, batch calls, or move to a dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket disconnects&lt;/td&gt;
&lt;td&gt;Idle connection dropped&lt;/td&gt;
&lt;td&gt;Add reconnect logic with resubscribe&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A useful first diagnostic is a single &lt;code&gt;eth_chainId&lt;/code&gt; call. If it does not return &lt;code&gt;0x64&lt;/code&gt;, your client is pointed at the wrong network and nothing downstream will behave as expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://gnosis.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When a shared endpoint is not enough
&lt;/h2&gt;

&lt;p&gt;Shared public endpoints are convenient and fine for development, prototypes, and low-volume reads. They become a bottleneck when your application depends on consistent throughput or long-running queries.&lt;/p&gt;

&lt;p&gt;The signals that you have outgrown a shared endpoint are usually operational rather than dramatic: log queries that need to be split into many smaller calls, receipt polling that occasionally times out, or a spike in 429 responses during peak hours. At that point the question is not whether Gnosis works, but whether your access pattern needs reserved capacity.&lt;/p&gt;

&lt;p&gt;A dedicated node gives your application its own Gnosis node rather than a slice of a shared pool. That matters for indexers scanning wide log ranges, relayers that need stable WebSocket connections, and services that cannot tolerate another tenant's traffic affecting their response times. OnFinality provides both managed RPC API access and dedicated node infrastructure, so you can start on a shared endpoint and move to reserved capacity without changing your application code beyond the URL. See &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; for how that transition works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operational checklist before you ship
&lt;/h2&gt;

&lt;p&gt;A short checklist catches most production issues before users do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm chain ID 100 in your provider config, not just in the URL.&lt;/li&gt;
&lt;li&gt;Add a fallback endpoint so a single provider outage does not take your app down.&lt;/li&gt;
&lt;li&gt;Batch independent reads where your library supports it, rather than firing them sequentially.&lt;/li&gt;
&lt;li&gt;Cap &lt;code&gt;eth_getLogs&lt;/code&gt; block ranges and paginate instead of requesting everything at once.&lt;/li&gt;
&lt;li&gt;Add exponential backoff for 429 and 5xx responses.&lt;/li&gt;
&lt;li&gt;Log the raw JSON-RPC error code alongside your application error, so you can tell a client bug from an endpoint limit.&lt;/li&gt;
&lt;li&gt;For WebSocket use, implement reconnect and resubscribe rather than assuming a persistent connection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are still deciding between endpoint types, the &lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;RPC provider selection guide&lt;/a&gt; walks through the evaluation criteria in more depth, and &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; shows where Gnosis sits alongside the rest of the catalog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Gnosis API is standard EVM JSON-RPC, so existing ethers, viem, Hardhat, and Foundry tooling works once chain ID 100 is set.&lt;/li&gt;
&lt;li&gt;Gnosis pays gas in xDAI, which simplifies fee accounting but requires users to hold xDAI before transacting.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eth_call&lt;/code&gt;, &lt;code&gt;eth_getLogs&lt;/code&gt;, and &lt;code&gt;eth_getTransactionReceipt&lt;/code&gt; drive most Gnosis traffic; log queries are the usual source of rate pressure.&lt;/li&gt;
&lt;li&gt;A shared endpoint is fine for development and light reads; dedicated nodes make sense for indexers, relayers, and high-volume backends.&lt;/li&gt;
&lt;li&gt;Always verify &lt;code&gt;eth_chainId&lt;/code&gt; returns &lt;code&gt;0x64&lt;/code&gt; when debugging unexpected behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the Gnosis API the same as the Ethereum API?
&lt;/h3&gt;

&lt;p&gt;At the protocol level, yes. Gnosis is EVM-compatible, so it uses the same JSON-RPC method names and request format. The differences are the chain ID (100), the gas token (xDAI), and the specific contracts and state on the network.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the Gnosis Chain ID?
&lt;/h3&gt;

&lt;p&gt;Gnosis Chain uses chain ID 100, which is &lt;code&gt;0x64&lt;/code&gt; in hexadecimal. Wallets and libraries that expect hex will reject the decimal form.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need an API key to use the Gnosis API?
&lt;/h3&gt;

&lt;p&gt;It depends on the endpoint. Public endpoints are typically open and rate-limited, while managed and dedicated endpoints use an API key tied to your account so your traffic gets its own capacity and support path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use WebSockets with Gnosis?
&lt;/h3&gt;

&lt;p&gt;Gnosis supports WebSocket subscriptions at the node level, but not every shared endpoint exposes WebSocket transport. Confirm availability with your provider before designing around &lt;code&gt;eth_subscribe&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do my &lt;code&gt;eth_getLogs&lt;/code&gt; calls fail on Gnosis?
&lt;/h3&gt;

&lt;p&gt;Large block ranges are the most common cause. Split the range into smaller windows and paginate through results rather than requesting a wide span in one call.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I move from a public endpoint to a dedicated Gnosis node?
&lt;/h3&gt;

&lt;p&gt;In most cases you change the endpoint URL and add your API key. Application logic stays the same because the JSON-RPC interface does not change. Review &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; and the &lt;a href="https://onfinality.io/networks/gnosis" rel="noopener noreferrer"&gt;Gnosis network page&lt;/a&gt; to plan the move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/gnosis" rel="noopener noreferrer"&gt;Gnosis RPC network page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/gnosis-api" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>ETH Public RPC: Endpoint, Chain Settings &amp; When to Switch</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Tue, 15 Sep 2026 02:17:36 +0000</pubDate>
      <link>https://dev.to/onfinality/eth-public-rpc-endpoint-chain-settings-when-to-switch-4loo</link>
      <guid>https://dev.to/onfinality/eth-public-rpc-endpoint-chain-settings-when-to-switch-4loo</guid>
      <description>&lt;h2&gt;
  
  
  When a public ETH RPC is the right starting point
&lt;/h2&gt;

&lt;p&gt;A public RPC is the fastest way to get an Ethereum app talking to the chain. You paste a URL into your wallet, script, or framework config, and you can read balances, fetch blocks, and send transactions without provisioning anything. For a hackathon prototype, a one-off script, or a wallet you are configuring for the first time, that is exactly the right tradeoff.&lt;/p&gt;

&lt;p&gt;The decision to stay on a public endpoint is really a question about workload shape. If your requests are occasional, tolerant of retries, and never depend on subscriptions, a shared public RPC can carry you a long way. If your app serves real users, indexes history, or listens for events, the shared tier will become the bottleneck.&lt;/p&gt;

&lt;p&gt;Use this quick guide to decide where you are today:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Public RPC fit&lt;/th&gt;
&lt;th&gt;What to do next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Learning JSON-RPC, testing a wallet&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Use a public endpoint, keep request volume low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local scripts, CI smoke tests&lt;/td&gt;
&lt;td&gt;Acceptable&lt;/td&gt;
&lt;td&gt;Add retries and a fallback URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dApp with live users&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;td&gt;Move to a managed RPC plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indexer, analytics, or archive queries&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;td&gt;Use an archive-capable endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bots, event listeners, WebSocket subscriptions&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;td&gt;Use a dedicated or managed node with WS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are in the bottom three rows, the rest of this page explains the migration. If you are in the top two, read on for the endpoint details and debugging steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ethereum chain settings at a glance
&lt;/h2&gt;

&lt;p&gt;Before you debug anything, confirm you are pointed at the right network. Ethereum mainnet and Sepolia share the same JSON-RPC method set but have different chain IDs, and mixing them up is one of the most common causes of "wrong network" errors.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Ethereum mainnet&lt;/th&gt;
&lt;th&gt;Ethereum Sepolia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;11155111&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chain name&lt;/td&gt;
&lt;td&gt;Ethereum Mainnet&lt;/td&gt;
&lt;td&gt;Ethereum Sepolia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;ETH (18 decimals)&lt;/td&gt;
&lt;td&gt;Sepolia Ether (18 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://etherscan.io" rel="noopener noreferrer"&gt;https://etherscan.io&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://sepolia.etherscan.io" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OnFinality public RPC&lt;/td&gt;
&lt;td&gt;&lt;a href="https://eth.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://eth.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://eth-sepolia.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://eth-sepolia.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;td&gt;HTTP, WebSocket&lt;/td&gt;
&lt;td&gt;HTTP, WebSocket&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;OnFinality exposes public endpoints for both networks, so you can develop against Sepolia and switch to mainnet by changing a single URL and chain ID. For network-specific details, see the &lt;a href="https://onfinality.io/networks/eth-sepolia" rel="noopener noreferrer"&gt;Ethereum Sepolia network page&lt;/a&gt; and the full &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting a wallet or framework
&lt;/h2&gt;

&lt;p&gt;Most wallets and libraries accept a custom RPC URL plus a chain ID. A minimal wallet network configuration looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chainName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ethereum Mainnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nativeCurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ether"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"decimals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rpcUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://eth.api.onfinality.io/public"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"blockExplorerUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://etherscan.io"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Sepolia, change &lt;code&gt;chainId&lt;/code&gt; to &lt;code&gt;0xaa36a7&lt;/code&gt; (11155111 in decimal) and swap the RPC URL to the Sepolia endpoint. In JavaScript, the same config works with ethers or viem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;viem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mainnet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;viem/chains&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mainnet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://eth.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blockNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Latest block:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you prefer raw JSON-RPC, a single curl call confirms the endpoint is reachable and returning the chain you expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://eth.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response should be &lt;code&gt;{"jsonrpc":"2.0","id":1,"result":"0x1"}&lt;/code&gt;. If you get a different chain ID, you are on the wrong network. If you get an empty result or an HTTP error, the endpoint is unreachable or rate limited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debug path: what each failure actually means
&lt;/h2&gt;

&lt;p&gt;Public endpoints fail in a small number of predictable ways. Match the symptom to the cause before you change anything.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;429 Too Many Requests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shared rate limit exceeded&lt;/td&gt;
&lt;td&gt;Back off, batch requests, or move to a managed plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;-32005&lt;/code&gt; or "limit exceeded"&lt;/td&gt;
&lt;td&gt;Per-method or per-IP quota&lt;/td&gt;
&lt;td&gt;Reduce polling frequency, cache results&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empty &lt;code&gt;result&lt;/code&gt; for old blocks&lt;/td&gt;
&lt;td&gt;No archive data on the shared tier&lt;/td&gt;
&lt;td&gt;Use an archive-capable endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket disconnects&lt;/td&gt;
&lt;td&gt;Idle timeout or shared connection limits&lt;/td&gt;
&lt;td&gt;Reconnect with backoff or use a dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;eth_getLogs&lt;/code&gt; timeouts&lt;/td&gt;
&lt;td&gt;Wide block ranges on shared capacity&lt;/td&gt;
&lt;td&gt;Narrow the range or paginate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong chain ID&lt;/td&gt;
&lt;td&gt;Mainnet/Sepolia mismatch&lt;/td&gt;
&lt;td&gt;Correct the URL and chain ID&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A useful habit is to log the HTTP status and JSON-RPC error code together. A &lt;code&gt;429&lt;/code&gt; is a capacity signal, while a &lt;code&gt;-32601&lt;/code&gt; (method not found) is a capability signal. They point to different fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where public endpoints stop scaling
&lt;/h2&gt;

&lt;p&gt;Shared public RPCs are designed for broad, low-intensity access. Three workload patterns break that model quickly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;High-frequency polling.&lt;/strong&gt; Wallets and dashboards that poll &lt;code&gt;eth_blockNumber&lt;/code&gt; or &lt;code&gt;eth_getBalance&lt;/code&gt; every second will hit shared limits fast. Batch or cache instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Historical and archive queries.&lt;/strong&gt; Reading state at an old block requires an archive node. Most public endpoints serve recent state only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-driven apps.&lt;/strong&gt; WebSocket subscriptions (&lt;code&gt;eth_subscribe&lt;/code&gt;) need a stable, long-lived connection. Shared endpoints often cap concurrent sockets or drop idle ones.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If any of these describe your app, the public tier is a prototyping tool, not a production dependency. The next section covers what to evaluate when you move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluating a managed or dedicated ETH RPC
&lt;/h2&gt;

&lt;p&gt;When you outgrow the public endpoint, you are choosing between a managed RPC plan and a dedicated node. Both remove the shared-capacity problem; they differ in control, cost model, and operational burden.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider option&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Archive / trace&lt;/th&gt;
&lt;th&gt;WebSocket&lt;/th&gt;
&lt;th&gt;Operational load&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OnFinality RPC API&lt;/td&gt;
&lt;td&gt;Teams that want managed Ethereum endpoints with predictable capacity&lt;/td&gt;
&lt;td&gt;Available on request&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Low — managed for you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OnFinality dedicated nodes&lt;/td&gt;
&lt;td&gt;High-volume or compliance-sensitive workloads needing isolated capacity&lt;/td&gt;
&lt;td&gt;Configurable&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Low — OnFinality operates the node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted node&lt;/td&gt;
&lt;td&gt;Teams with strict data-residency or custom fork needs&lt;/td&gt;
&lt;td&gt;Full control&lt;/td&gt;
&lt;td&gt;Full control&lt;/td&gt;
&lt;td&gt;High — you run and upgrade it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other shared providers&lt;/td&gt;
&lt;td&gt;Low-cost, low-volume apps&lt;/td&gt;
&lt;td&gt;Varies&lt;/td&gt;
&lt;td&gt;Often limited&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;OnFinality is listed first because it is the option this site operates: managed RPC endpoints plus dedicated node infrastructure for teams that need isolated capacity. Compare plans on the &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing page&lt;/a&gt;, or review &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; if you need a private node rather than a shared endpoint.&lt;/p&gt;

&lt;p&gt;When you evaluate any provider, ask four questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capacity model:&lt;/strong&gt; Is throughput shared or reserved? What happens during a traffic spike?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Method coverage:&lt;/strong&gt; Are &lt;code&gt;debug_&lt;/code&gt; and &lt;code&gt;trace_&lt;/code&gt; methods available, and is archive data included?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport:&lt;/strong&gt; Is WebSocket supported for subscriptions, and how are idle connections handled?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failover:&lt;/strong&gt; Can you configure a secondary endpoint, and how do you detect a degraded primary?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions matter more than headline latency numbers, because they determine whether your app stays up under load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration checkpoints
&lt;/h2&gt;

&lt;p&gt;Moving from a public endpoint to a managed one is mostly a configuration change, but a few checkpoints prevent surprises:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Inventory your methods.&lt;/strong&gt; List every JSON-RPC method your app calls, including &lt;code&gt;eth_getLogs&lt;/code&gt;, &lt;code&gt;eth_call&lt;/code&gt;, and any &lt;code&gt;debug_&lt;/code&gt; or &lt;code&gt;trace_&lt;/code&gt; usage. Confirm the new endpoint supports all of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate read and write paths.&lt;/strong&gt; Reads can often use a shared endpoint; writes and subscriptions benefit from a dedicated connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add a fallback.&lt;/strong&gt; Configure a secondary RPC URL so a single endpoint failure does not take down your app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-test on Sepolia first.&lt;/strong&gt; Validate the new endpoint against &lt;a href="https://onfinality.io/networks/eth-sepolia" rel="noopener noreferrer"&gt;Sepolia&lt;/a&gt; before switching mainnet traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor after cutover.&lt;/strong&gt; Track error rates, &lt;code&gt;429&lt;/code&gt; counts, and WebSocket reconnects for the first few days.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A simple monitoring probe keeps you honest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;probe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eth_blockNumber&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this against both your primary and fallback endpoints on a schedule, and alert when either degrades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An ETH public RPC is a shared, unauthenticated endpoint — great for prototyping, weak for production.&lt;/li&gt;
&lt;li&gt;Always confirm chain ID: &lt;code&gt;0x1&lt;/code&gt; for mainnet, &lt;code&gt;0xaa36a7&lt;/code&gt; for Sepolia.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;429&lt;/code&gt; errors mean capacity; empty archive results mean missing history; WebSocket drops mean connection limits.&lt;/li&gt;
&lt;li&gt;Move to a managed or dedicated endpoint when you poll frequently, need archive data, or rely on subscriptions.&lt;/li&gt;
&lt;li&gt;Evaluate providers on capacity model, method coverage, transport, and failover — not just latency.&lt;/li&gt;
&lt;li&gt;OnFinality offers managed Ethereum RPC and dedicated nodes; see &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; and &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported networks&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is a public ETH RPC safe to use in production?
&lt;/h3&gt;

&lt;p&gt;It can work for low-volume, read-only traffic with retries and a fallback. For user-facing apps, high-frequency polling, archive queries, or WebSocket subscriptions, a managed or dedicated endpoint is the more reliable choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the chain ID for Ethereum mainnet and Sepolia?
&lt;/h3&gt;

&lt;p&gt;Ethereum mainnet uses chain ID &lt;code&gt;1&lt;/code&gt; (&lt;code&gt;0x1&lt;/code&gt;). Sepolia uses chain ID &lt;code&gt;11155111&lt;/code&gt; (&lt;code&gt;0xaa36a7&lt;/code&gt;). Setting the wrong one is a common cause of "wrong network" errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does my public RPC return empty results for old blocks?
&lt;/h3&gt;

&lt;p&gt;Most public endpoints serve recent state only. Reading historical state requires an archive node, which is typically available on managed or dedicated plans.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use WebSocket subscriptions on a public RPC?
&lt;/h3&gt;

&lt;p&gt;Some public endpoints expose WebSocket, but shared connection limits and idle timeouts make them unreliable for long-lived subscriptions. Use a managed or dedicated endpoint for event-driven apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I switch from a public RPC to OnFinality?
&lt;/h3&gt;

&lt;p&gt;Change your RPC URL and chain ID in your wallet or framework config, confirm method coverage, add a fallback endpoint, and test on Sepolia before moving mainnet traffic. See &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; for plan details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/eth-sepolia" rel="noopener noreferrer"&gt;Ethereum RPC on OnFinality&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/eth-public-rpc" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Triton One Solana RPC: Evaluation Checklist for Production</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Mon, 14 Sep 2026 01:55:13 +0000</pubDate>
      <link>https://dev.to/onfinality/triton-one-solana-rpc-evaluation-checklist-for-production-3h6o</link>
      <guid>https://dev.to/onfinality/triton-one-solana-rpc-evaluation-checklist-for-production-3h6o</guid>
      <description>&lt;h2&gt;
  
  
  What people actually mean by "Triton One Solana RPC"
&lt;/h2&gt;

&lt;p&gt;Triton One is a Solana-focused RPC provider. When developers search for "triton one solana rpc," they are usually trying to answer one of three questions: what endpoint do I point my app at, how does it behave under load, and is it the right long-term choice compared with other Solana RPC options. Those are provider-selection questions, not just endpoint-lookup questions.&lt;/p&gt;

&lt;p&gt;This article does not reproduce Triton One's documentation. Instead, it gives you a framework you can apply to any Solana RPC provider, including Triton One and OnFinality, so you can decide what to do next with evidence rather than marketing copy.&lt;/p&gt;

&lt;p&gt;Solana RPC is not a single thing. A provider may offer a shared public endpoint, a paid shared tier, and a dedicated node. Each has different rate limits, method availability, and transport support. The name on the endpoint tells you very little about which of those you are actually getting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decide first: shared endpoint or dedicated node?
&lt;/h2&gt;

&lt;p&gt;Before comparing providers, decide which class of service your workload needs. This is the single biggest fork in the road, and it determines which providers are even relevant.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload signal&lt;/th&gt;
&lt;th&gt;Shared RPC endpoint is usually fine&lt;/th&gt;
&lt;th&gt;Dedicated node is usually worth evaluating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Request volume&lt;/td&gt;
&lt;td&gt;Low to moderate, bursty&lt;/td&gt;
&lt;td&gt;Sustained high throughput&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method mix&lt;/td&gt;
&lt;td&gt;Standard reads (getAccountInfo, getBalance, sendTransaction)&lt;/td&gt;
&lt;td&gt;Heavy getProgramAccounts, getSignaturesForAddress, archive queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket use&lt;/td&gt;
&lt;td&gt;Occasional account or slot subscriptions&lt;/td&gt;
&lt;td&gt;Many concurrent subscriptions, low-latency slot feeds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency sensitivity&lt;/td&gt;
&lt;td&gt;Tolerant of variance&lt;/td&gt;
&lt;td&gt;Trading bots, liquidators, indexers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data depth&lt;/td&gt;
&lt;td&gt;Recent state only&lt;/td&gt;
&lt;td&gt;Historical or archive access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team capacity&lt;/td&gt;
&lt;td&gt;No node ops&lt;/td&gt;
&lt;td&gt;Wants managed dedicated infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If most of your answers land in the right column, a shared endpoint from any provider will eventually become a bottleneck, and you should be comparing dedicated node offerings. If most land in the left column, a well-run shared endpoint is the pragmatic choice and you should focus on reliability and method coverage instead.&lt;/p&gt;

&lt;p&gt;OnFinality offers both a &lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC API&lt;/a&gt; and &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt;, so you can start on a shared endpoint and move to dedicated infrastructure without changing providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solana endpoint settings at a glance
&lt;/h2&gt;

&lt;p&gt;If you are wiring up a Solana endpoint, these are the values your wallet or app config needs. Use the official OnFinality public endpoint only as a starting point for testing; production apps should use an authenticated endpoint.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain name&lt;/td&gt;
&lt;td&gt;Solana Mainnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;SOL (9 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP RPC (public test)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://solana.api.onfinality.io/public" rel="noopener noreferrer"&gt;https://solana.api.onfinality.io/public&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket RPC (public test)&lt;/td&gt;
&lt;td&gt;wss://solana.api.onfinality.io/public-ws&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://explorer.solana.com" rel="noopener noreferrer"&gt;https://explorer.solana.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transports supported&lt;/td&gt;
&lt;td&gt;HTTP, WebSocket&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A minimal connection test with curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://solana.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"getHealth"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A healthy node returns a result object. If you get an error or a timeout, check the endpoint URL and your network egress before assuming the provider is down.&lt;/p&gt;

&lt;p&gt;For wallet or app config, the same values apply. In a JavaScript client using the Solana web3 library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Connection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@solana/web3.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://solana.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSlot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Current slot:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;slot&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap the URL for your authenticated endpoint before shipping to production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Solana methods and transports matter most
&lt;/h2&gt;

&lt;p&gt;Not all Solana RPC methods are equal in cost. Some are cheap reads; others scan large state and are the first to be rate-limited on shared endpoints. When you evaluate Triton One or any provider, ask specifically about the methods you actually call.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Typical cost profile&lt;/th&gt;
&lt;th&gt;What to verify with the provider&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;getHealth, getSlot, getBlockHeight&lt;/td&gt;
&lt;td&gt;Cheap&lt;/td&gt;
&lt;td&gt;Always available, no special tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getAccountInfo, getBalance&lt;/td&gt;
&lt;td&gt;Cheap to moderate&lt;/td&gt;
&lt;td&gt;Included in your plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getTransaction, getSignaturesForAddress&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;History depth and rate limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getProgramAccounts&lt;/td&gt;
&lt;td&gt;Expensive&lt;/td&gt;
&lt;td&gt;Whether it is allowed and at what rate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sendTransaction&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Priority fee handling and retry behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket accountSubscribe, slotSubscribe&lt;/td&gt;
&lt;td&gt;Persistent&lt;/td&gt;
&lt;td&gt;Concurrent subscription limits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two things trip teams up here. First, &lt;code&gt;getProgramAccounts&lt;/code&gt; is often restricted or heavily throttled on shared endpoints because it can scan a large portion of state. Second, WebSocket subscriptions are persistent connections, and providers cap them differently from HTTP requests. If your app relies on either, confirm support before you migrate.&lt;/p&gt;

&lt;p&gt;OnFinality's Solana endpoint supports both HTTP and WebSocket transports, which matters if you run real-time subscriptions alongside standard reads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing an endpoint before you migrate
&lt;/h2&gt;

&lt;p&gt;Do not migrate on the strength of a status page. Run a short, representative test against the candidate endpoint using your own traffic shape.&lt;/p&gt;

&lt;p&gt;A simple latency and correctness probe you can run from your own infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 20&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{time_total}s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    https://solana.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"getSlot"}'&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What to look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistency, not just the best number. A tight distribution matters more than a single fast response.&lt;/li&gt;
&lt;li&gt;Error rate under your real method mix, especially expensive calls.&lt;/li&gt;
&lt;li&gt;WebSocket stability over several minutes, not a single message.&lt;/li&gt;
&lt;li&gt;Behavior during Solana slot spikes, when the network is busiest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the same probe against your current provider and the candidate. The comparison is the useful output, not the absolute numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure modes to watch for on Solana RPC
&lt;/h2&gt;

&lt;p&gt;Most Solana RPC problems fall into a small set of patterns. Recognizing them shortens debugging considerably.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;429 responses under load&lt;/td&gt;
&lt;td&gt;Shared endpoint rate limit&lt;/td&gt;
&lt;td&gt;Reduce request rate, batch calls, or move to a dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timeouts on getProgramAccounts&lt;/td&gt;
&lt;td&gt;Method throttled or disabled&lt;/td&gt;
&lt;td&gt;Confirm method support with the provider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket disconnects&lt;/td&gt;
&lt;td&gt;Subscription limit or idle timeout&lt;/td&gt;
&lt;td&gt;Add reconnect logic; check concurrent subscription cap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stale slot data&lt;/td&gt;
&lt;td&gt;Node lagging behind the cluster&lt;/td&gt;
&lt;td&gt;Compare getSlot against a second endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sendTransaction dropped&lt;/td&gt;
&lt;td&gt;Congestion or fee handling&lt;/td&gt;
&lt;td&gt;Add priority fees and retry with fresh blockhash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing historical data&lt;/td&gt;
&lt;td&gt;Endpoint not archive-enabled&lt;/td&gt;
&lt;td&gt;Request archive access or a dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you see 429s or timeouts only during peak Solana activity, that is a capacity signal, not a code bug. It usually means your workload has outgrown a shared endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  How OnFinality fits into a Solana RPC evaluation
&lt;/h2&gt;

&lt;p&gt;OnFinality provides RPC API access and dedicated node infrastructure across many networks, including Solana. For teams comparing Solana RPC providers, the relevant points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A managed &lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC API&lt;/a&gt; with HTTP and WebSocket support.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt; for workloads that need consistent capacity and isolation.&lt;/li&gt;
&lt;li&gt;A single provider across multiple chains, which simplifies operations if you support more than Solana.&lt;/li&gt;
&lt;li&gt;Transparent &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; so you can model cost against your request profile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a claim that OnFinality is faster than Triton One in every scenario. The right choice depends on your method mix, latency needs, and whether you want shared or dedicated infrastructure. Use the evaluation framework above to compare both against your actual workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration checkpoints
&lt;/h2&gt;

&lt;p&gt;If you decide to move from one Solana RPC provider to another, treat it as a controlled migration rather than a URL swap.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inventory your methods. List every JSON-RPC method and WebSocket subscription your app uses.&lt;/li&gt;
&lt;li&gt;Confirm support. Verify each method and subscription is available on the target endpoint.&lt;/li&gt;
&lt;li&gt;Run parallel traffic. Send a percentage of read traffic to the new endpoint and compare results.&lt;/li&gt;
&lt;li&gt;Add failover. Configure a secondary endpoint so a single provider outage does not take down your app.&lt;/li&gt;
&lt;li&gt;Move writes last. Shift sendTransaction traffic only after reads are stable.&lt;/li&gt;
&lt;li&gt;Monitor after cutover. Watch error rates, latency, and WebSocket reconnects for at least a full Solana activity cycle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A simple failover pattern in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endpoints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://solana.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://your-secondary-endpoint.example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;withFailover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Endpoint failed, trying next:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;All Solana RPC endpoints failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Failover is not a substitute for adequate capacity, but it prevents a single endpoint problem from becoming a full outage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"Triton One Solana RPC" is a provider-selection question, not just an endpoint lookup.&lt;/li&gt;
&lt;li&gt;Decide first whether you need a shared endpoint or a dedicated node; that determines which providers are relevant.&lt;/li&gt;
&lt;li&gt;Verify support for expensive methods like getProgramAccounts and for WebSocket subscriptions before migrating.&lt;/li&gt;
&lt;li&gt;Test candidate endpoints with your own traffic shape and compare distributions, not single numbers.&lt;/li&gt;
&lt;li&gt;Plan a controlled migration with parallel traffic, failover, and post-cutover monitoring.&lt;/li&gt;
&lt;li&gt;OnFinality offers both a &lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC API&lt;/a&gt; and &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt;, with &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; you can model against your workload.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is Triton One the same as a Solana RPC endpoint?
&lt;/h3&gt;

&lt;p&gt;Triton One is a Solana-focused RPC provider. The endpoint you use depends on the plan you are on, so treat the provider name and the endpoint as separate things when you evaluate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use a public Solana RPC endpoint in production?
&lt;/h3&gt;

&lt;p&gt;Public endpoints are useful for testing and low-volume use. Production apps generally need an authenticated endpoint with defined rate limits and support commitments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does OnFinality support Solana WebSocket subscriptions?
&lt;/h3&gt;

&lt;p&gt;OnFinality's Solana endpoint supports HTTP and WebSocket transports. Confirm the specific subscriptions you need against your plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I know if I need a dedicated Solana node?
&lt;/h3&gt;

&lt;p&gt;If you see repeated 429s, timeouts during peak activity, or you rely on expensive methods and many concurrent subscriptions, a dedicated node is worth evaluating.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I check before switching Solana RPC providers?
&lt;/h3&gt;

&lt;p&gt;Inventory your methods and subscriptions, confirm support on the target endpoint, run parallel traffic, add failover, and monitor after cutover.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC on OnFinality&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to Choose an RPC Provider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated Nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC Pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/triton-one-solana-rpc" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>solana</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Solana RPC Server: Endpoints, Config &amp; Scaling</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Mon, 14 Sep 2026 01:54:40 +0000</pubDate>
      <link>https://dev.to/onfinality/solana-rpc-server-endpoints-config-scaling-1k6</link>
      <guid>https://dev.to/onfinality/solana-rpc-server-endpoints-config-scaling-1k6</guid>
      <description>&lt;p&gt;A Solana RPC server is the service your application talks to when it needs to read blockchain state or submit a transaction. Instead of running a validator or an RPC node yourself, you point your client at an HTTP endpoint (and usually a WebSocket endpoint) that speaks Solana's JSON-RPC dialect. Everything from a wallet balance check to a token swap starts with a request to that server.&lt;/p&gt;

&lt;p&gt;This page is written for developers who already know they need a Solana RPC server and want to connect one correctly, then decide whether a shared endpoint is enough or whether a dedicated node is the better fit. If you are still comparing providers at a high level, start with &lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;how to choose an RPC provider&lt;/a&gt; and come back here for the Solana-specific configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing between public, managed, and dedicated Solana RPC
&lt;/h2&gt;

&lt;p&gt;The fastest way to decide is to match your workload to the endpoint type. Most teams start on a public or shared endpoint, then move up when they hit a specific limit rather than a vague feeling that things are slow.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Endpoint type that usually fits&lt;/th&gt;
&lt;th&gt;What to watch for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prototyping, scripts, low request volume&lt;/td&gt;
&lt;td&gt;Public endpoint&lt;/td&gt;
&lt;td&gt;Shared capacity, aggressive rate limits, no SLA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A production dApp with steady read traffic&lt;/td&gt;
&lt;td&gt;Managed RPC API (shared, keyed)&lt;/td&gt;
&lt;td&gt;Per-method limits, WebSocket connection caps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indexers, bots, high &lt;code&gt;getProgramAccounts&lt;/code&gt; use&lt;/td&gt;
&lt;td&gt;Dedicated node&lt;/td&gt;
&lt;td&gt;Memory and disk for account scans, archive needs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trading or latency-sensitive submission&lt;/td&gt;
&lt;td&gt;Dedicated node close to your infra&lt;/td&gt;
&lt;td&gt;Slot lag, transaction landing rate, failover&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need historical state or full ledger&lt;/td&gt;
&lt;td&gt;Archive-capable dedicated node&lt;/td&gt;
&lt;td&gt;Storage growth, snapshot restore time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;OnFinality provides Solana RPC through a managed &lt;a href="https://onfinality.io/api-service" rel="noopener noreferrer"&gt;RPC API service&lt;/a&gt; and through &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; when you need isolated capacity. The managed endpoint is the right starting point for most apps; dedicated nodes are for teams that have outgrown shared throughput or need predictable resources.&lt;/p&gt;

&lt;p&gt;A quick rule of thumb: if your errors are mostly &lt;code&gt;429&lt;/code&gt; responses, you need a keyed managed plan or a dedicated node. If your errors are timeouts on heavy calls like &lt;code&gt;getProgramAccounts&lt;/code&gt;, you need more memory and a dedicated node rather than a bigger shared plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solana RPC server settings at a glance
&lt;/h2&gt;

&lt;p&gt;When you configure a wallet, a framework, or a backend service, you need the network parameters, not just the URL. For Solana mainnet these are the values to use.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain name&lt;/td&gt;
&lt;td&gt;Solana Mainnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;SOL (9 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP RPC URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://solana.api.onfinality.io/public&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket RPC URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wss://solana.api.onfinality.io/public-ws&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://explorer.solana.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transports supported&lt;/td&gt;
&lt;td&gt;HTTP and WebSocket&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For development and testing, use a devnet endpoint instead of mainnet so you are not spending real SOL. OnFinality exposes a separate &lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet&lt;/a&gt; endpoint, and you can request devnet SOL from the standard Solana faucet to fund test transactions. Keep devnet and mainnet configuration in separate environment variables so a test key never points at mainnet by accident.&lt;/p&gt;

&lt;p&gt;A common pattern is to store the endpoint in an environment variable and read it at startup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SOLANA_RPC_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://solana.api.onfinality.io/public
&lt;span class="nv"&gt;SOLANA_WS_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wss://solana.api.onfinality.io/public-ws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Connecting with curl and JavaScript
&lt;/h2&gt;

&lt;p&gt;The simplest way to confirm a Solana RPC server is responding is a JSON-RPC call over HTTP. Solana uses the same JSON-RPC 2.0 envelope as other chains, but with Solana-specific methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://solana.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getLatestBlockhash",
    "params": [{"commitment": "confirmed"}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A healthy response returns a &lt;code&gt;result&lt;/code&gt; object containing a &lt;code&gt;blockhash&lt;/code&gt; and &lt;code&gt;lastValidBlockHeight&lt;/code&gt;. If you get an error object instead, the endpoint is reachable but the request was rejected, which usually points to a malformed method or parameter rather than a network problem.&lt;/p&gt;

&lt;p&gt;In JavaScript, the &lt;code&gt;@solana/web3.js&lt;/code&gt; library wraps these calls. Point the connection at your endpoint and pass a commitment level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clusterApiUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@solana/web3.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOLANA_RPC_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;wsEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOLANA_WS_URL&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11111111111111111111111111111111&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lamports:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commitment levels matter on Solana. &lt;code&gt;processed&lt;/code&gt; is fastest but can be rolled back, &lt;code&gt;confirmed&lt;/code&gt; is the common default for most apps, and &lt;code&gt;finalized&lt;/code&gt; is the safest for settlement logic. Choose the level that matches the risk of the action, not the fastest one available.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSocket subscriptions and when to use them
&lt;/h2&gt;

&lt;p&gt;Solana RPC servers also expose a WebSocket transport for push-based updates. Instead of polling &lt;code&gt;getSlot&lt;/code&gt; or &lt;code&gt;getAccountInfo&lt;/code&gt; in a loop, you subscribe and receive notifications when state changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onAccountChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11111111111111111111111111111111&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accountInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lamports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accountInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lamports&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebSocket subscriptions are efficient, but they hold a connection open, and shared endpoints often cap concurrent subscriptions. If you run many subscriptions across many users, track your connection count and plan for reconnects. Subscriptions can drop during network congestion, so always handle the disconnect event and resubscribe rather than assuming the stream is permanent.&lt;/p&gt;

&lt;p&gt;For high-frequency use, a dedicated node gives you a stable subscription budget and avoids competing with other tenants for notification delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes and how to read them
&lt;/h2&gt;

&lt;p&gt;Most Solana RPC problems fall into a small set of symptoms. Matching the symptom to the cause saves a lot of guessing.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;First fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTTP &lt;code&gt;429&lt;/code&gt; responses&lt;/td&gt;
&lt;td&gt;Rate limit on a shared endpoint&lt;/td&gt;
&lt;td&gt;Add a keyed plan or move to dedicated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request timeouts on &lt;code&gt;getProgramAccounts&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Large account scan, memory pressure&lt;/td&gt;
&lt;td&gt;Use filters, or move to a dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Blockhash not found&lt;/code&gt; on send&lt;/td&gt;
&lt;td&gt;Blockhash expired before landing&lt;/td&gt;
&lt;td&gt;Fetch a fresh blockhash and retry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transaction lands slowly&lt;/td&gt;
&lt;td&gt;Congestion or fee too low&lt;/td&gt;
&lt;td&gt;Add priority fee, resubmit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket disconnects&lt;/td&gt;
&lt;td&gt;Idle timeout or connection cap&lt;/td&gt;
&lt;td&gt;Implement reconnect and resubscribe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stale slot data&lt;/td&gt;
&lt;td&gt;Node behind the tip&lt;/td&gt;
&lt;td&gt;Check slot lag, consider a different node&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two of these deserve more detail. First, &lt;code&gt;getProgramAccounts&lt;/code&gt; without filters is one of the heaviest calls on Solana. It can scan a large amount of account data, and on a shared endpoint it is often the first call to be throttled. Add data-size and memcmp filters to narrow the result set before you blame the endpoint.&lt;/p&gt;

&lt;p&gt;Second, transaction landing is not just about the RPC server. Solana uses a blockhash that expires after a short window, so a transaction built with an old blockhash will fail even on a perfectly healthy endpoint. Fetch a fresh blockhash, set a reasonable priority fee, and retry with backoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production readiness checklist
&lt;/h2&gt;

&lt;p&gt;Before you send real traffic to a Solana RPC server, work through these items. They are the difference between a demo and something that survives a busy day.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separate environments.&lt;/strong&gt; Keep devnet and mainnet endpoints and keys in distinct configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set commitment levels deliberately.&lt;/strong&gt; Use &lt;code&gt;confirmed&lt;/code&gt; for most reads and &lt;code&gt;finalized&lt;/code&gt; for settlement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle rate limits.&lt;/strong&gt; Detect &lt;code&gt;429&lt;/code&gt; responses and back off instead of retrying immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan for failover.&lt;/strong&gt; Configure a secondary endpoint so a single outage does not take down your app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor slot lag.&lt;/strong&gt; Track how far your node is behind the cluster tip.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch WebSocket health.&lt;/strong&gt; Log disconnects and resubscription success.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget for heavy calls.&lt;/strong&gt; Know which methods your app uses most and size accordingly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If several of these items are already painful on a shared endpoint, that is the signal to evaluate a dedicated node. You can compare plans on the &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt; page and see the full list of &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; if you also operate on other chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running your own Solana RPC server vs renting one
&lt;/h2&gt;

&lt;p&gt;You can run a Solana RPC node yourself. The tradeoff is operational, not just financial. A Solana RPC node needs substantial RAM, fast NVMe storage, and ongoing attention to snapshots, upgrades, and monitoring. The ledger grows continuously, so storage planning is a recurring task, not a one-time setup.&lt;/p&gt;

&lt;p&gt;Renting a managed endpoint or a dedicated node shifts that operational load to the provider. You still choose the region, the capacity, and the transport, but you are not patching the node or restoring snapshots at 2am. For most product teams, that is the better use of engineering time. For teams with strict data-locality or compliance requirements, self-hosting may still be the right call, and a hybrid approach (self-hosted primary, managed failover) is common.&lt;/p&gt;

&lt;p&gt;OnFinality sits in the managed camp: you get a Solana RPC endpoint and, when needed, a dedicated node without running the infrastructure yourself. The &lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana network page&lt;/a&gt; lists the current endpoint details and transports.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating from a public endpoint without breaking things
&lt;/h2&gt;

&lt;p&gt;Moving from a public Solana RPC server to a managed or dedicated one should be a configuration change, not a rewrite. The steps are straightforward if you prepare them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add the new endpoint alongside the old one.&lt;/strong&gt; Do not delete the public URL yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route a small percentage of traffic&lt;/strong&gt; to the new endpoint and compare error rates and latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update WebSocket configuration&lt;/strong&gt; separately, since HTTP and WS endpoints are distinct.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify commitment levels&lt;/strong&gt; behave the same on the new endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Switch the default&lt;/strong&gt; once error rates are stable, keeping the old endpoint as failover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remove the public endpoint&lt;/strong&gt; only after a full traffic cycle with no regressions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because Solana RPC is JSON-RPC over HTTP, the migration is usually a URL swap in your environment variables plus a redeploy. The risk is in the details: forgetting the WebSocket URL, or changing commitment levels at the same time as the endpoint, which makes it hard to tell what caused a change in behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Solana RPC server is the HTTP and WebSocket interface your app uses to read state and submit transactions.&lt;/li&gt;
&lt;li&gt;Mainnet uses chain name Solana Mainnet, SOL with 9 decimals, and the explorer at explorer.solana.com.&lt;/li&gt;
&lt;li&gt;Start on a shared or public endpoint, then move to a managed or dedicated node when you hit rate limits or heavy-call timeouts.&lt;/li&gt;
&lt;li&gt;Commitment levels (&lt;code&gt;processed&lt;/code&gt;, &lt;code&gt;confirmed&lt;/code&gt;, &lt;code&gt;finalized&lt;/code&gt;) should match the risk of each action.&lt;/li&gt;
&lt;li&gt;WebSocket subscriptions are efficient but need reconnect and resubscription handling.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getProgramAccounts&lt;/code&gt; and expired blockhashes are two of the most common sources of confusion.&lt;/li&gt;
&lt;li&gt;Migration is usually a configuration change, but update HTTP and WebSocket endpoints together.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a Solana RPC server?
&lt;/h3&gt;

&lt;p&gt;It is a service that exposes Solana's JSON-RPC API over HTTP and WebSocket, letting your application read accounts, submit transactions, and subscribe to events without running a node yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the Solana RPC URL for mainnet?
&lt;/h3&gt;

&lt;p&gt;OnFinality exposes Solana mainnet at &lt;code&gt;https://solana.api.onfinality.io/public&lt;/code&gt; for HTTP and &lt;code&gt;wss://solana.api.onfinality.io/public-ws&lt;/code&gt; for WebSocket. Always confirm current endpoints on the &lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana network page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why am I getting 429 errors from my Solana RPC endpoint?
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;429&lt;/code&gt; means you hit a rate limit, which is common on shared or public endpoints. A keyed managed plan or a dedicated node removes that shared ceiling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use HTTP or WebSocket for Solana?
&lt;/h3&gt;

&lt;p&gt;Use HTTP for request-response calls and WebSocket for push updates such as account or slot changes. Most production apps use both.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use a public Solana RPC endpoint in production?
&lt;/h3&gt;

&lt;p&gt;You can, but public endpoints are shared and often rate limited. For steady production traffic, a managed or dedicated endpoint gives you more predictable behavior and a clear upgrade path.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I test without spending SOL?
&lt;/h3&gt;

&lt;p&gt;Use a devnet endpoint and request devnet SOL from the faucet. Keep devnet configuration separate from mainnet so keys never cross over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC network page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet RPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/solana-rpc-server" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>solana</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>solana.io: The Solana RPC Endpoint Developers Need</title>
      <dc:creator>OnFinality</dc:creator>
      <pubDate>Mon, 14 Sep 2026 01:54:07 +0000</pubDate>
      <link>https://dev.to/onfinality/solanaio-the-solana-rpc-endpoint-developers-need-317b</link>
      <guid>https://dev.to/onfinality/solanaio-the-solana-rpc-endpoint-developers-need-317b</guid>
      <description>&lt;h2&gt;
  
  
  What solana.io is, and what it is not
&lt;/h2&gt;

&lt;p&gt;If you typed &lt;code&gt;solana.io&lt;/code&gt; into a browser or a config file expecting a Solana RPC endpoint, you have hit a naming collision. The domain &lt;code&gt;solana.io&lt;/code&gt; is not the canonical Solana developer portal, and it is not a JSON-RPC endpoint you can POST requests to. The Solana network is accessed through RPC providers that expose HTTP and WebSocket endpoints, and the official developer documentation lives on the Solana docs site rather than a &lt;code&gt;.io&lt;/code&gt; domain.&lt;/p&gt;

&lt;p&gt;The practical takeaway: stop looking for &lt;code&gt;solana.io&lt;/code&gt; as an endpoint. What you actually need is a Solana mainnet or devnet RPC URL, the right transport (HTTP for request/response, WebSocket for subscriptions), and a decision about whether a shared public endpoint is enough or whether your workload needs dedicated capacity.&lt;/p&gt;

&lt;p&gt;This article answers that directly, then walks through connection settings, a working request, and the failure modes that show up when a Solana endpoint is not sized for your traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Solana endpoint should you point at?
&lt;/h2&gt;

&lt;p&gt;Before copying any URL, match the endpoint to the environment and the workload. The table below is the fastest way to decide.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;Transport&lt;/th&gt;
&lt;th&gt;Recommended access&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First script, learning JSON-RPC&lt;/td&gt;
&lt;td&gt;Devnet&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;Public devnet endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wallet or dApp testing&lt;/td&gt;
&lt;td&gt;Devnet&lt;/td&gt;
&lt;td&gt;HTTP + WebSocket&lt;/td&gt;
&lt;td&gt;Public or shared endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production dApp reads&lt;/td&gt;
&lt;td&gt;Mainnet&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;Shared or dedicated RPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time account or slot updates&lt;/td&gt;
&lt;td&gt;Mainnet&lt;/td&gt;
&lt;td&gt;WebSocket&lt;/td&gt;
&lt;td&gt;Endpoint with WS support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High request volume or indexing&lt;/td&gt;
&lt;td&gt;Mainnet&lt;/td&gt;
&lt;td&gt;HTTP + WebSocket&lt;/td&gt;
&lt;td&gt;Dedicated node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency-sensitive trading or bots&lt;/td&gt;
&lt;td&gt;Mainnet&lt;/td&gt;
&lt;td&gt;HTTP + WebSocket&lt;/td&gt;
&lt;td&gt;Dedicated node, co-located&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two rules keep you out of trouble. First, never point production traffic at a devnet endpoint, and never point tests at mainnet. Second, if your app opens WebSocket subscriptions, confirm the endpoint advertises WebSocket support before you ship.&lt;/p&gt;

&lt;p&gt;OnFinality exposes Solana mainnet over both HTTP and WebSocket, so the same provider can cover request/response calls and subscription-based flows. You can review the network details on the &lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC network page&lt;/a&gt;, and use &lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet&lt;/a&gt; while you are still building.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solana chain settings at a glance
&lt;/h2&gt;

&lt;p&gt;When you configure a wallet, a framework, or a custom client, these are the values that matter for Solana mainnet.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain name&lt;/td&gt;
&lt;td&gt;Solana Mainnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native currency&lt;/td&gt;
&lt;td&gt;SOL (9 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP RPC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://solana.api.onfinality.io/public&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket RPC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wss://solana.api.onfinality.io/public-ws&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block explorer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://explorer.solana.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note that Solana does not use an EVM-style numeric chain ID in the same way Ethereum networks do. If a tool asks for a chain ID, check that tool's Solana-specific documentation rather than guessing a number.&lt;/p&gt;

&lt;p&gt;For devnet work, keep your devnet and mainnet configuration in separate environment variables so a copy-paste mistake cannot send test transactions to mainnet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .env&lt;/span&gt;
&lt;span class="nv"&gt;SOLANA_MAINNET_RPC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://solana.api.onfinality.io/public
&lt;span class="nv"&gt;SOLANA_MAINNET_WS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wss://solana.api.onfinality.io/public-ws
&lt;span class="nv"&gt;SOLANA_DEVNET_RPC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-devnet-endpoint&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A working Solana JSON-RPC request
&lt;/h2&gt;

&lt;p&gt;Solana uses JSON-RPC over HTTP. The example below fetches the current slot, which is a lightweight way to confirm your endpoint is reachable and returning data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://solana.api.onfinality.io/public &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getSlot",
    "params": [{"commitment": "confirmed"}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A healthy response looks like a JSON object with a &lt;code&gt;result&lt;/code&gt; field containing a number. If you get an error object instead, jump to the debugging section below.&lt;/p&gt;

&lt;p&gt;The same call in JavaScript with &lt;code&gt;fetch&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://solana.api.onfinality.io/public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;getSlot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once basic calls work, move to the methods your app actually needs: &lt;code&gt;getAccountInfo&lt;/code&gt; for balances and account data, &lt;code&gt;getTransaction&lt;/code&gt; for confirmation checks, &lt;code&gt;sendTransaction&lt;/code&gt; for writes, and &lt;code&gt;getProgramAccounts&lt;/code&gt; for program-scoped queries. &lt;code&gt;getProgramAccounts&lt;/code&gt; is the method most likely to expose an underpowered endpoint because it can return large result sets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Public endpoint or dedicated node?
&lt;/h2&gt;

&lt;p&gt;This is the decision that determines whether your app stays responsive as usage grows. A public or shared endpoint is fine for development, low-volume scripts, and early testing. A dedicated node makes sense when your traffic is predictable but heavy, when you need consistent access to WebSocket subscriptions, or when you are running indexers and bots that issue many concurrent calls.&lt;/p&gt;

&lt;p&gt;Signals that you have outgrown a shared endpoint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You see intermittent &lt;code&gt;429&lt;/code&gt; responses during peak hours.&lt;/li&gt;
&lt;li&gt;WebSocket subscriptions drop and reconnect frequently.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getProgramAccounts&lt;/code&gt; or large &lt;code&gt;getTransaction&lt;/code&gt; batches time out.&lt;/li&gt;
&lt;li&gt;Your p95 latency varies widely across the day.&lt;/li&gt;
&lt;li&gt;You need predictable capacity for a launch or a trading window.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If two or more of those apply, evaluate dedicated capacity. OnFinality offers &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; for teams that need isolated resources, and you can compare access tiers on the &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing page&lt;/a&gt;. For a broader framework covering archive access, trace methods, and failover, see &lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;how to choose an RPC provider&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debug path for common Solana RPC failures
&lt;/h2&gt;

&lt;p&gt;When a call fails, the error usually points to one of a few causes. Work through this table before changing providers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;429 Too Many Requests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rate limiting on a shared endpoint&lt;/td&gt;
&lt;td&gt;Reduce concurrency or move to dedicated capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Method not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Method not enabled on that endpoint&lt;/td&gt;
&lt;td&gt;Confirm method support with the provider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timeout on &lt;code&gt;getProgramAccounts&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Large result set, endpoint limits&lt;/td&gt;
&lt;td&gt;Add filters, paginate, or use a stronger endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket disconnects&lt;/td&gt;
&lt;td&gt;Subscription limits or network instability&lt;/td&gt;
&lt;td&gt;Add reconnect logic, confirm WS support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Blockhash not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stale blockhash in a transaction&lt;/td&gt;
&lt;td&gt;Fetch a fresh blockhash before signing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empty &lt;code&gt;result&lt;/code&gt; for an account&lt;/td&gt;
&lt;td&gt;Wrong commitment level or account not yet created&lt;/td&gt;
&lt;td&gt;Retry with &lt;code&gt;confirmed&lt;/code&gt; or &lt;code&gt;finalized&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two debugging habits pay off. First, log the raw JSON-RPC error object, not just the HTTP status, because Solana returns useful error codes in the body. Second, test the same call against a second endpoint to separate an application bug from an endpoint problem.&lt;/p&gt;

&lt;p&gt;If you are chasing rate-limit and authentication issues specifically, the &lt;a href="https://onfinality.io/rpc-assistant/access-for-solana-2" rel="noopener noreferrer"&gt;Solana RPC access article&lt;/a&gt; goes deeper on those failure modes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commitment levels and why they change results
&lt;/h2&gt;

&lt;p&gt;Solana lets you choose how finalized a response must be. This affects both correctness and latency.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;processed&lt;/code&gt; returns the fastest but least settled data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;confirmed&lt;/code&gt; is a common default for user-facing reads.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;finalized&lt;/code&gt; is the safest for anything irreversible, such as crediting a deposit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A frequent bug is reading a balance at &lt;code&gt;processed&lt;/code&gt; and treating it as final. For anything that moves value, read at &lt;code&gt;confirmed&lt;/code&gt; or &lt;code&gt;finalized&lt;/code&gt;, and be explicit about the commitment in every call rather than relying on a default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running subscriptions over WebSocket
&lt;/h2&gt;

&lt;p&gt;Real-time features such as watching an account or tracking slots need a WebSocket connection. Solana exposes subscription methods like &lt;code&gt;accountSubscribe&lt;/code&gt; and &lt;code&gt;slotSubscribe&lt;/code&gt; over the WebSocket transport.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://solana.api.onfinality.io/public-ws&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;jsonrpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slotSubscribe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Production subscription code should include reconnect logic with backoff, a heartbeat to detect dead connections, and a cap on the number of simultaneous subscriptions per client. Dropped subscriptions that silently stop delivering updates are one of the hardest bugs to notice, so monitor message arrival rather than assuming the socket is healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;solana.io&lt;/code&gt; is not the Solana RPC endpoint or the official developer portal; use a real JSON-RPC URL instead.&lt;/li&gt;
&lt;li&gt;Solana mainnet is reachable over HTTP at &lt;code&gt;https://solana.api.onfinality.io/public&lt;/code&gt; and over WebSocket at &lt;code&gt;wss://solana.api.onfinality.io/public-ws&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Match the endpoint to the environment: devnet for building, mainnet for production, and never mix the two.&lt;/li&gt;
&lt;li&gt;Choose commitment levels deliberately; use &lt;code&gt;confirmed&lt;/code&gt; or &lt;code&gt;finalized&lt;/code&gt; for anything that moves value.&lt;/li&gt;
&lt;li&gt;Move from shared to dedicated capacity when you see sustained &lt;code&gt;429&lt;/code&gt;s, dropped subscriptions, or timeouts on large queries.&lt;/li&gt;
&lt;li&gt;Log raw JSON-RPC error bodies and test against a second endpoint to separate app bugs from endpoint limits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is solana.io the official Solana RPC endpoint?
&lt;/h3&gt;

&lt;p&gt;No. &lt;code&gt;solana.io&lt;/code&gt; is not a JSON-RPC endpoint. Solana is accessed through RPC providers that expose HTTP and WebSocket URLs, and the official developer documentation lives on the Solana docs site.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the Solana mainnet RPC URL?
&lt;/h3&gt;

&lt;p&gt;OnFinality exposes Solana mainnet over HTTP at &lt;code&gt;https://solana.api.onfinality.io/public&lt;/code&gt; and over WebSocket at &lt;code&gt;wss://solana.api.onfinality.io/public-ws&lt;/code&gt;. You can review the network on the &lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC network page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a WebSocket endpoint for Solana?
&lt;/h3&gt;

&lt;p&gt;Only if your app uses subscriptions such as &lt;code&gt;accountSubscribe&lt;/code&gt; or &lt;code&gt;slotSubscribe&lt;/code&gt;. If you only make request/response calls, HTTP is enough. If you need real-time updates, confirm the endpoint supports WebSocket before shipping.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should I move off a public Solana endpoint?
&lt;/h3&gt;

&lt;p&gt;When you see sustained rate-limit errors, dropped WebSocket subscriptions, or timeouts on large queries like &lt;code&gt;getProgramAccounts&lt;/code&gt;. At that point, evaluate &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; and compare tiers on the &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I test a Solana endpoint quickly?
&lt;/h3&gt;

&lt;p&gt;Send a &lt;code&gt;getSlot&lt;/code&gt; request with &lt;code&gt;curl&lt;/code&gt; as shown above. A numeric &lt;code&gt;result&lt;/code&gt; confirms the endpoint is reachable and responding; an error object tells you to check the method, commitment, or rate limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where can I see all the networks OnFinality supports?
&lt;/h3&gt;

&lt;p&gt;The full list is on the &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; page, including Solana mainnet and devnet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Start by pointing a test script at the Solana mainnet endpoint and confirming a &lt;code&gt;getSlot&lt;/code&gt; response. Then add the methods your app needs, set explicit commitment levels, and add WebSocket reconnect logic if you use subscriptions. When your traffic grows past what a shared endpoint handles comfortably, review &lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;dedicated nodes&lt;/a&gt; and &lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;, and keep the &lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;supported RPC networks&lt;/a&gt; page handy as you expand to other chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana" rel="noopener noreferrer"&gt;Solana RPC network&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks/solana-devnet" rel="noopener noreferrer"&gt;Solana Devnet RPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/pricing/rpc" rel="noopener noreferrer"&gt;RPC pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/networks" rel="noopener noreferrer"&gt;Supported RPC networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/rpc-assistant/how-to-choose-an-rpc-provider" rel="noopener noreferrer"&gt;How to choose an RPC provider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onfinality.io/dedicated-node" rel="noopener noreferrer"&gt;Dedicated nodes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://onfinality.io/en/rpc-assistant/solana-io" rel="noopener noreferrer"&gt;OnFinality&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>solana</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
