<?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: Rahman</title>
    <description>The latest articles on DEV Community by Rahman (@rahmandefi).</description>
    <link>https://dev.to/rahmandefi</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%2F4023296%2F12697922-2dfc-4c2d-9a04-fe665b2b6db9.jpg</url>
      <title>DEV Community: Rahman</title>
      <link>https://dev.to/rahmandefi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rahmandefi"/>
    <language>en</language>
    <item>
      <title>Redbelly Network Troubleshooting: Fixes for the 21 Most Common Developer Errors</title>
      <dc:creator>Rahman</dc:creator>
      <pubDate>Thu, 09 Jul 2026 23:21:07 +0000</pubDate>
      <link>https://dev.to/rahmandefi/redbelly-network-troubleshooting-fixes-for-the-21-most-common-developer-errors-17i</link>
      <guid>https://dev.to/rahmandefi/redbelly-network-troubleshooting-fixes-for-the-21-most-common-developer-errors-17i</guid>
      <description>&lt;p&gt;I have been building on Redbelly Network for a while now, and the same pattern kept repeating: I would hit an error, spend an hour on trial and error, solve it, and then a week later watch someone ask about the exact same error in the developer Discord. The official docs are strong on architecture and SDK reference material, but there was no single place that answered "here is my error message, what do I do".&lt;/p&gt;

&lt;p&gt;So I built one. This guide documents the 21 most common Redbelly developer roadblocks, sourced from recurring questions in the Redbelly Discord and Telegram support channels and from my own projects on the network. Every entry follows the same structure: &lt;strong&gt;Symptom&lt;/strong&gt; (the exact error), &lt;strong&gt;Root Cause&lt;/strong&gt; (why it happens), &lt;strong&gt;Solution&lt;/strong&gt; (step-by-step fix with exact commands), and &lt;strong&gt;Prevention&lt;/strong&gt; (how to avoid it next time).&lt;/p&gt;

&lt;p&gt;Two findings worth calling out up front, both verified against the live network while writing this guide. First, Redbelly permissions write access per account: a freshly generated wallet cannot send any transaction until it is enabled through the official access dApp, and the resulting error, &lt;code&gt;Sender not authorised to write transactions&lt;/code&gt;, is covered in entry 21. Second, the testnet RPC hostname that several older guides reference, &lt;code&gt;rpc-testnet.redbelly.network&lt;/code&gt;, no longer resolves; the current canonical endpoint is &lt;code&gt;https://governors.testnet.redbelly.network&lt;/code&gt;, and entry 3 documents the migration.&lt;/p&gt;

&lt;p&gt;The maintained version of this guide lives on GitHub: &lt;a href="https://github.com/Rahmandefi/Redbelly-troubleshooting-wiki" rel="noopener noreferrer"&gt;https://github.com/Rahmandefi/Redbelly-troubleshooting-wiki&lt;/a&gt;. Issues and pull requests are welcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network quick reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Testnet&lt;/th&gt;
&lt;th&gt;Mainnet&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;
&lt;code&gt;153&lt;/code&gt; (hex &lt;code&gt;0x99&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;151&lt;/code&gt; (hex &lt;code&gt;0x97&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPC URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://governors.testnet.redbelly.network&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://governors.mainnet.redbelly.network&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Explorer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://redbelly.testnet.routescan.io" rel="noopener noreferrer"&gt;https://redbelly.testnet.routescan.io&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://redbelly.routescan.io" rel="noopener noreferrer"&gt;https://redbelly.routescan.io&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gas token&lt;/td&gt;
&lt;td&gt;RBNT&lt;/td&gt;
&lt;td&gt;RBNT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faucet&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://redbelly.faucetme.pro" rel="noopener noreferrer"&gt;https://redbelly.faucetme.pro&lt;/a&gt; (Discord login)&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Account Access and Permissioning
&lt;/h2&gt;

&lt;p&gt;The single most Redbelly-specific roadblock: write access to the network is permissioned per account. Entry 21.&lt;/p&gt;




&lt;h3&gt;
  
  
  21. "Sender not authorised to write transactions"
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Reproduced and resolved end to end on Redbelly Testnet, July 2026: a freshly generated wallet's first deployment attempt returned this exact error; after completing the credential and enablement flow below, the same key deployed successfully (tx &lt;code&gt;0x6b852e17bc77f0cad8a7e5b03e264a08eed9f297c20a72f1b8498c6ee51a40e9&lt;/code&gt;).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ProviderError: Sender not authorised to write transactions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The very first transaction from a wallet fails with this error: contract deployment, token transfer, anything that writes. Read calls (&lt;code&gt;eth_call&lt;/code&gt;, balance queries) work fine. This hits hardest in scripted setups, because a deployer key generated by Hardhat, a CI pipeline or a tool like thirdweb has never been near the access flow.&lt;/p&gt;

&lt;p&gt;Related symptoms in the access dApp itself: &lt;strong&gt;"Account status: Not enabled"&lt;/strong&gt; even though the account holds the access credential, and &lt;strong&gt;"Balance: Insufficient funds to enable account"&lt;/strong&gt; even though you funded the account on testnet (the dApp is checking your balance on a different network than the one you funded).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redbelly is a compliance-first chain: unlike most EVM networks, the protocol itself restricts transaction submission to enabled accounts. Getting write access is a three-part sequence, and each part is separate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The account must hold the &lt;strong&gt;Redbelly Network Access Credential&lt;/strong&gt;, issued by the accredited issuer (Averer) after identity verification.&lt;/li&gt;
&lt;li&gt;The account must be &lt;strong&gt;funded&lt;/strong&gt;, because the enablement itself is an on-chain transaction that costs gas. You cannot enable an empty account.&lt;/li&gt;
&lt;li&gt;The account must be &lt;strong&gt;enabled on each network separately&lt;/strong&gt;. Enabling on Mainnet does not enable Testnet, and the access dApp operates against the network your wallet is currently connected to, so it can report "insufficient funds" while your testnet balance is healthy simply because your wallet is pointed at Mainnet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A brand-new keypair, however well funded, is not authorised until all three parts are complete. Receiving RBNT does not require enablement (transfers in always work), which makes the situation confusing: the faucet succeeds, the explorer shows a balance, and the first outgoing transaction still fails. This also breaks tools that deploy through auto-generated intermediate wallets (thirdweb's presumptive deployment fails on Redbelly for exactly this reason; see thirdweb-dev/contracts issue 615).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The working order is: credential, fund, connect to the right network, enable, transact.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the official access dApp at &lt;a href="https://access.redbelly.network/" rel="noopener noreferrer"&gt;https://access.redbelly.network/&lt;/a&gt; and connect the wallet your transactions will be sent from (MetaMask and Coinbase Wallet are supported).&lt;/li&gt;
&lt;li&gt;First time on the network: follow the prompts to verify your identity with the accredited issuer (Averer) and claim the Redbelly Network Access Credential. Identity verification is free; the issuer covers the associated fees.&lt;/li&gt;
&lt;li&gt;Already verified: you do not need to repeat identity verification for additional wallets. The access dApp lets you add more accounts connected to your existing identity, which is the right way to set up a dedicated deployer key for scripts (import the key into MetaMask, add it as an additional account, then keep it in your project's &lt;code&gt;.env&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Fund the account before enabling it: the enablement is an on-chain transaction and an empty account cannot pay for it. On Testnet use the faucet (entry 20 in Faucet and Funding).&lt;/li&gt;
&lt;li&gt;Switch your wallet to the network you want access on (chain 153 for Testnet) so the dApp targets the right chain, then complete the enable step and sign the transaction. Repeat per network; Mainnet and Testnet enablement are independent.&lt;/li&gt;
&lt;li&gt;Retry your deployment. If a deployment tool creates its own throwaway deployer wallet under the hood, bypass that feature and deploy directly from an enabled wallet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because enablement is tied to an identity credential, the practical pattern is to enable one or two long-lived deployer accounts per environment and reuse them across projects, rather than generating a fresh key per project the way you would on other EVM chains. Treat "credential, fund, enable, deploy" as standard onboarding for any new account, and document it in your project README; it is the sequence most tutorials written for other chains will not mention.&lt;/p&gt;

&lt;p&gt;A security note that follows from this: if your only enabled wallet is a personal one, do not export its private key into a script's &lt;code&gt;.env&lt;/code&gt; just to deploy. Enable a dedicated deployer address under your existing credential (no repeat identity verification needed), or deploy through a browser workflow (Remix with an injected wallet) so the key never leaves your wallet. Keep scripted &lt;code&gt;.env&lt;/code&gt; keys for accounts that hold nothing you care about.&lt;/p&gt;




&lt;h2&gt;
  
  
  Network and RPC Issues
&lt;/h2&gt;

&lt;p&gt;Connection problems between your tooling and the Redbelly RPC endpoints. Entries 1 to 4.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. RPC endpoint returns 429 (Too Many Requests)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ProviderError: 429 Too Many Requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scripts that loop over many &lt;code&gt;eth_call&lt;/code&gt; requests (indexers, test suites, dashboards) fail intermittently. Single requests work fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The public Redbelly RPC endpoints are shared infrastructure and rate-limit aggressive clients. Batch-heavy tools (Hardhat tests, multicall loops, polling dashboards) exceed the per-IP request budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add retry with exponential backoff. With ethers v6:
&lt;/li&gt;
&lt;/ol&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;withRetry&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="nx"&gt;retries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;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="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="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="nc"&gt;String&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="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;429&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;retries&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="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;i&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;balance&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;withRetry&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;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="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Throttle concurrent requests. Replace &lt;code&gt;Promise.all&lt;/code&gt; over hundreds of calls with a small concurrency pool (for example &lt;code&gt;p-limit&lt;/code&gt; set to 3 to 5 concurrent requests).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache anything static. Contract ABIs, decimals and historical blocks never change; fetch once and store.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design for a rate-limited RPC from day one: batch reads with &lt;code&gt;Multicall3&lt;/code&gt; where deployed, poll no faster than the block time, and keep a client-side cache. For production dashboards, run your own node or request a dedicated endpoint from the Redbelly team.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. RPC connection timeouts and "could not detect network"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&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="err"&gt;Error:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;could&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;detect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;network&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(event=&lt;/span&gt;&lt;span class="s2"&gt;"noNetwork"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;code=NETWORK_ERROR)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FetchError: request to https://governors.testnet.redbelly.network failed, reason: connect ETIMEDOUT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of three things: (a) the RPC URL is typed incorrectly or missing &lt;code&gt;https://&lt;/code&gt;, (b) a local firewall, VPN or corporate proxy blocks the request, or (c) a transient outage of the shared endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify the endpoint responds before blaming your code:
&lt;/li&gt;
&lt;/ol&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="nt"&gt;-X&lt;/span&gt; POST https://governors.testnet.redbelly.network &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;Expected response: &lt;code&gt;{"jsonrpc":"2.0","id":1,"result":"0x99"}&lt;/code&gt; (0x99 = 153, the Testnet chain ID).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If curl works but your app does not, the problem is your environment. Check for &lt;code&gt;HTTP_PROXY&lt;/code&gt;/&lt;code&gt;HTTPS_PROXY&lt;/code&gt; environment variables, VPN split tunnelling, and that your &lt;code&gt;.env&lt;/code&gt; value has no trailing whitespace or quotes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If curl also fails, test from another network (mobile hotspot). If it fails everywhere, check the Redbelly Discord announcements channel for maintenance notices before opening a support thread.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On WSL2 specifically, Node.js can pick a broken IPv6 route. Force IPv4-first resolution:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NODE_OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--no-network-family-autoselection"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the &lt;code&gt;eth_chainId&lt;/code&gt; curl check to your project README as a first diagnostic. In long-running services, wrap the provider in retry logic and alert on repeated network errors instead of crashing.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Wrong or deprecated RPC endpoint
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Verified on Redbelly Testnet, July 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: getaddrinfo ENOTFOUND rpc-testnet.redbelly.network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or requests to a DevNet URL hang or return errors, even though the URL came from an older guide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redbelly's endpoints have changed over time. Older community guides still reference &lt;code&gt;rpc-testnet.redbelly.network&lt;/code&gt; or DevNet URLs. DevNet is officially deprecated, the &lt;code&gt;rpc-testnet&lt;/code&gt; hostname no longer resolves, and the current canonical endpoints (per the developer portal at vine.redbelly.network) are the &lt;code&gt;governors.*&lt;/code&gt; URLs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Replace any old endpoint with the current one:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Testnet: &lt;code&gt;https://governors.testnet.redbelly.network&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Mainnet: &lt;code&gt;https://governors.mainnet.redbelly.network&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Confirm with the chain ID check:
&lt;/li&gt;
&lt;/ol&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="nt"&gt;-X&lt;/span&gt; POST https://governors.testnet.redbelly.network &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;span class="c"&gt;## expect "result":"0x99"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update &lt;code&gt;hardhat.config.js&lt;/code&gt;/&lt;code&gt;foundry.toml&lt;/code&gt;, &lt;code&gt;.env&lt;/code&gt; files and any wagmi/viem chain definitions in the same pass so no stale URL survives.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Define the RPC URL once (an &lt;code&gt;.env&lt;/code&gt; variable or a shared &lt;code&gt;chains.ts&lt;/code&gt;) and import it everywhere. When following any tutorial older than a few months, cross-check endpoints against &lt;a href="https://vine.redbelly.network/environments/" rel="noopener noreferrer"&gt;https://vine.redbelly.network/environments/&lt;/a&gt; before running anything.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Chain ID mismatch ("network changed" or "Unrecognized chain")
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&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="err"&gt;NetworkError:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;underlying&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;network&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;changed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(event=&lt;/span&gt;&lt;span class="s2"&gt;"changed"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;network=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;153&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or MetaMask rejects a transaction with &lt;code&gt;Unrecognized chain ID&lt;/code&gt;, or Hardhat aborts with a chain ID assertion error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The chain ID configured in your tooling does not match what the RPC actually reports. Common causes: using Mainnet chain ID &lt;code&gt;151&lt;/code&gt; with the Testnet RPC (or vice versa), a leftover DevNet chain ID, or MetaMask connected to a different network than your dApp expects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ask the RPC what it really is (see the curl in entry 3). &lt;code&gt;0x99&lt;/code&gt; = 153 = Testnet, &lt;code&gt;0x97&lt;/code&gt; = 151 = Mainnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make your Hardhat config match:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// hardhat.config.js&lt;/span&gt;
&lt;span class="nx"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;redbellyTestnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&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;https://governors.testnet.redbelly.network&lt;/span&gt;&lt;span class="dl"&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;153&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;:&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;PRIVATE_KEY&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;ol&gt;
&lt;li&gt;In the frontend, prompt a network switch instead of failing silently:
&lt;/li&gt;
&lt;/ol&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_switchEthereumChain&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;0x99&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;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Never hardcode chain IDs in more than one place. Keep a single chain definition object and reference it from Hardhat, wagmi/viem config and deployment scripts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wallet and MetaMask Issues
&lt;/h2&gt;

&lt;p&gt;Problems connecting MetaMask and other wallets to Redbelly. Entries 5 and 6.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. MetaMask not detecting Redbelly Network
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redbelly does not appear in MetaMask's network list, or the "Add network" search finds nothing, so the user cannot connect to your dApp at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redbelly is not in MetaMask's built-in popular networks list, so it must be added manually or programmatically. Users following a dApp prompt may also hit this if the dApp only calls &lt;code&gt;wallet_switchEthereumChain&lt;/code&gt;, which fails with error &lt;code&gt;4902&lt;/code&gt; when the chain has never been added.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Manual (for users):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MetaMask &amp;gt; Networks &amp;gt; Add a custom network, and enter:

&lt;ul&gt;
&lt;li&gt;Network name: &lt;code&gt;Redbelly Testnet&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;RPC URL: &lt;code&gt;https://governors.testnet.redbelly.network&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Chain ID: &lt;code&gt;153&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Currency symbol: &lt;code&gt;RBNT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Explorer: &lt;code&gt;https://redbelly.testnet.routescan.io&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Programmatic (for dApp developers), handling the 4902 case:&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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&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_switchEthereumChain&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;0x99&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="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="k"&gt;if &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="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;4902&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&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;0x99&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;Redbelly Testnet&lt;/span&gt;&lt;span class="dl"&gt;"&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://governors.testnet.redbelly.network&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;RBNT&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;RBNT&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;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://redbelly.testnet.routescan.io&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users can also add the chain in one click from &lt;a href="https://chainlist.org/chain/153" rel="noopener noreferrer"&gt;https://chainlist.org/chain/153&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A related point of confusion once the network is added: RBNT is the network's &lt;strong&gt;native gas coin&lt;/strong&gt;, not an ERC-20 token, so there is no contract address to import and MetaMask's "Import tokens" flow is not needed. If a guide asks you for an RBNT contract address, it is describing wrapped RBNT on a different chain, which is a separate asset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every Redbelly dApp should ship the &lt;code&gt;wallet_addEthereumChain&lt;/code&gt; fallback above in its connect flow. Do not assume the user has the network configured.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. MetaMask shows wrong balance or stuck account state
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The balance in MetaMask does not match the explorer, sent transactions do not appear, or every new transaction immediately fails even though the account has funds. A variant reported by RBNT holders: the balance appears for a split second when switching networks and then vanishes, while the explorer shows the funds are untouched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MetaMask caches account state (nonce, balance, activity) per network. After a testnet reset, an RPC switch, or heavy scripted use of the same key outside MetaMask, that cache goes stale and MetaMask signs with wrong assumptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First confirm the truth on-chain: look the address up on &lt;a href="https://redbelly.testnet.routescan.io" rel="noopener noreferrer"&gt;https://redbelly.testnet.routescan.io&lt;/a&gt;. The explorer reflects actual state.&lt;/li&gt;
&lt;li&gt;In MetaMask: Settings &amp;gt; Advanced &amp;gt; &lt;strong&gt;Clear activity tab data&lt;/strong&gt;. This resets cached activity and nonce for the selected account and network. It does not touch your keys or funds.&lt;/li&gt;
&lt;li&gt;If the balance is still wrong, remove the Redbelly network entry and re-add it with the current RPC URL (entry 5), then reselect the account. Community members have confirmed this fixes the disappearing-balance variant.&lt;/li&gt;
&lt;li&gt;If MetaMask keeps misbehaving on Redbelly, an ERC-20 compatible alternative such as Rabby works with the same seed or key and the same network details, and is what network moderators suggest for persistent display glitches.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do not share one private key between MetaMask and automated scripts on the same network; the nonce cache will constantly desync (see entry 7 in Gas and Transactions). Use a dedicated deployer key for scripts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Gas and Transaction Issues
&lt;/h2&gt;

&lt;p&gt;Nonce errors, gas estimation failures, stuck and underfunded transactions. Entries 7 to 11.&lt;/p&gt;




&lt;h3&gt;
  
  
  7. "Nonce too low" transaction failures
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: nonce too low: next nonce 42, tx nonce 40
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The transaction's nonce has already been used. Typical triggers: MetaMask's cached nonce is behind the chain (after scripted transactions from the same key), two scripts sending from the same account concurrently, or resubmitting an already-mined transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the real next nonce from the chain:
&lt;/li&gt;
&lt;/ol&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="nt"&gt;-X&lt;/span&gt; POST https://governors.testnet.redbelly.network &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_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In MetaMask: Settings &amp;gt; Advanced &amp;gt; Clear activity tab data, so it refetches the nonce.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In scripts, fetch the pending nonce explicitly instead of trusting a cached signer:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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;nonce&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;getTransactionCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&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&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;tx&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;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendTransaction&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;txRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If two processes share a key, serialise them or give each its own key.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One key, one sender. Deployment scripts, keeper bots and your personal MetaMask should each use separate accounts. In bots, track nonces in a single queue rather than firing transactions in parallel.&lt;/p&gt;




&lt;h3&gt;
  
  
  8. "Replacement transaction underpriced"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: replacement transaction underpriced
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when re-sending a transaction that is already pending.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A transaction with the same nonce is already in the mempool. Nodes only accept a replacement if it bumps the gas price by a sufficient margin (typically at least 10 per cent over the pending one).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check whether the original is still pending on the explorer. If it confirmed, just resend with a fresh nonce (or let your signer pick one).&lt;/li&gt;
&lt;li&gt;To genuinely replace a stuck transaction, reuse the same nonce with a higher gas price:
&lt;/li&gt;
&lt;/ol&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;pending&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;getTransactionCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&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&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;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;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTransactionCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt; &lt;span class="o"&gt;&amp;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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;feeData&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;getFeeData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendTransaction&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// self-send 0 to cancel&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;nonce&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="c1"&gt;// the stuck nonce&lt;/span&gt;
    &lt;span class="na"&gt;gasPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasPrice&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// +25%&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;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do not blind-retry sends on timeout; check pending state first. If your script retries, always bump the gas price by at least 25 per cent on each attempt.&lt;/p&gt;




&lt;h3&gt;
  
  
  9. Gas estimation returning null or "cannot estimate gas"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&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="err"&gt;Error:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cannot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;estimate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;gas;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;transaction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;may&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fail&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;may&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;manual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;gas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;limit&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;(reason=&lt;/span&gt;&lt;span class="s2"&gt;"execution reverted"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;method=&lt;/span&gt;&lt;span class="s2"&gt;"estimateGas"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or &lt;code&gt;eth_estimateGas&lt;/code&gt; returns null or empty in your tooling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nine times out of ten this is not a gas problem: &lt;code&gt;eth_estimateGas&lt;/code&gt; simulates the transaction, and if the simulation reverts (failed &lt;code&gt;require&lt;/code&gt;, missing approval, unverified wallet blocked by an eligibility check, wrong constructor arguments), estimation fails. The remaining cases are RPC hiccups or a signer with zero balance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the actual revert reason by simulating with &lt;code&gt;eth_call&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;staticCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sender&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;log&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="nx"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&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;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// the real error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Common Redbelly-specific revert: contracts gated by the EligibilitySDK revert for wallets that have not completed KYC. Check permission first:
&lt;/li&gt;
&lt;/ol&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;ok&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;eligibilityContract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasChainPermission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If the call genuinely should succeed, retry estimation once (transient RPC issue), and as a last resort set a manual gas limit to surface the real on-chain revert:
&lt;/li&gt;
&lt;/ol&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="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;gasLimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Treat estimation failure as "this transaction would revert" and surface the decoded reason to users. In eligibility-gated dApps, check &lt;code&gt;hasChainPermission&lt;/code&gt; in the UI before enabling action buttons.&lt;/p&gt;




&lt;h3&gt;
  
  
  10. Transaction pending indefinitely
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A transaction sits in "pending" in MetaMask or your script for many minutes. Redbelly's DBFT consensus gives fast, deterministic finality, so anything pending for more than a minute is stuck, not slow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Either (a) the gas price is below what nodes currently accept, (b) an earlier nonce from the same account is stuck, blocking everything behind it, or (c) the transaction never actually reached the network (an RPC error swallowed by the app).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check whether the network ever saw it: search the transaction hash on &lt;a href="https://redbelly.testnet.routescan.io" rel="noopener noreferrer"&gt;https://redbelly.testnet.routescan.io&lt;/a&gt;. Not found means it never landed; resend it.&lt;/li&gt;
&lt;li&gt;Check for a nonce gap:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## compare "latest" vs "pending" counts; a gap means a stuck earlier tx&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://governors.testnet.redbelly.network &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_getTransactionCount","params":["0xYOU","latest"],"id":1}'&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://governors.testnet.redbelly.network &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_getTransactionCount","params":["0xYOU","pending"],"id":2}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Clear the stuck nonce with a self-send replacement at a higher gas price (exact snippet in entry 8), after which the queued transactions behind it will process.&lt;/li&gt;
&lt;li&gt;In MetaMask, use the built-in "Speed up" on the oldest pending transaction rather than sending new ones on top.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the network's suggested gas price (&lt;code&gt;provider.getFeeData()&lt;/code&gt;) instead of hardcoding one. In scripts, &lt;code&gt;await tx.wait()&lt;/code&gt; before sending the next transaction from the same account.&lt;/p&gt;




&lt;h3&gt;
  
  
  11. "Insufficient funds for gas * price + value"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: insufficient funds for gas * price + value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;often during &lt;code&gt;npx hardhat run scripts/deploy.js --network redbellyTestnet&lt;/code&gt;, sometimes even though you believe the wallet is funded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The sending account cannot cover gas cost plus sent value on the network you are actually targeting. The three classic variants: (a) the account genuinely has 0 RBNT, (b) Hardhat derived a different address than the one you funded (wrong &lt;code&gt;PRIVATE_KEY&lt;/code&gt; in &lt;code&gt;.env&lt;/code&gt;), or (c) you funded the account on a different network than the one being used.&lt;/p&gt;

&lt;p&gt;Note that on Redbelly a brand-new account fails earlier with &lt;code&gt;Sender not authorised to write transactions&lt;/code&gt; (entry 21 in Account Access and Permissioning); this entry applies to accounts already enabled for write access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Print which address your script is actually using:
&lt;/li&gt;
&lt;/ol&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;]&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;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigners&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;Deployer:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&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;Balance:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ethers&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&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="nx"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RBNT&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;ol&gt;
&lt;li&gt;If the address is not the one you funded, fix &lt;code&gt;PRIVATE_KEY&lt;/code&gt; in &lt;code&gt;.env&lt;/code&gt; (no duplicated &lt;code&gt;0x&lt;/code&gt; prefix, no whitespace) and confirm &lt;code&gt;dotenv&lt;/code&gt; is loaded at the top of &lt;code&gt;hardhat.config.js&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If the address is right but the balance is 0, fund it from the faucet (entry 20 in Faucet and Funding) and verify on the explorer before retrying.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the balance looks fine, check you are on the intended network: &lt;code&gt;console.log(await ethers.provider.getNetwork())&lt;/code&gt; should report chain ID 153 for Testnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a balance-and-network preflight to every deploy script that aborts with a clear message when the deployer has no RBNT or is on an unexpected chain ID.&lt;/p&gt;




&lt;h2&gt;
  
  
  Contract Deployment Issues
&lt;/h2&gt;

&lt;p&gt;Hardhat configuration, explorer verification and EVM compatibility. Entries 12 to 14.&lt;/p&gt;




&lt;h3&gt;
  
  
  12. Hardhat cannot connect (HH108) or misconfigured network
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Verified on Redbelly Testnet, July 2026: the config block below deployed a live contract to &lt;code&gt;0xd583cbaf72849Ad868445C4D025dc49dF84358d6&lt;/code&gt; (tx &lt;code&gt;0x6b852e17bc77f0cad8a7e5b03e264a08eed9f297c20a72f1b8498c6ee51a40e9&lt;/code&gt;).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error HH108: Cannot connect to the network redbellyTestnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error HH100: Network redbellyTestnet doesn't exist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HH100: the &lt;code&gt;--network&lt;/code&gt; name you passed does not match any key under &lt;code&gt;networks&lt;/code&gt; in &lt;code&gt;hardhat.config.js&lt;/code&gt;. HH108: the name matches but the RPC URL is wrong, unreachable, or the environment variable holding it is undefined (so Hardhat sees &lt;code&gt;url: undefined&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use a known-good config block:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@nomicfoundation/hardhat-toolbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;solidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.8.24&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;redbellyTestnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&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;https://governors.testnet.redbelly.network&lt;/span&gt;&lt;span class="dl"&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;153&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;accounts&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;PRIVATE_KEY&lt;/span&gt; &lt;span class="p"&gt;?&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;PRIVATE_KEY&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="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Confirm the exact network name in the command matches the config key:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx hardhat run scripts/deploy.js &lt;span class="nt"&gt;--network&lt;/span&gt; redbellyTestnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If HH108 persists, run the &lt;code&gt;eth_chainId&lt;/code&gt; curl from entry 2 in Network and RPC. If curl succeeds but Hardhat fails, check proxies and the WSL2 IPv6 note in the same entry.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Commit a working &lt;code&gt;hardhat.config.js&lt;/code&gt; with the Redbelly network block to your project template, and validate required environment variables at config load with a clear throw if missing.&lt;/p&gt;




&lt;h3&gt;
  
  
  13. Contract verification failing on the block explorer
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Verified on Redbelly Testnet, July 2026: the custom chain config below verified the contract at &lt;code&gt;0xd583cbaf72849Ad868445C4D025dc49dF84358d6&lt;/code&gt; on Routescan; the explorer now serves its full source and ABI.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx hardhat verify&lt;/code&gt; fails with "network not supported", "unable to verify" or bytecode mismatch errors; or manual verification on the explorer rejects the source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redbelly's explorer is Routescan, which is not in hardhat-verify's built-in chain list, so it must be added as a custom chain. Bytecode mismatches come from verifying with different compiler settings (version, optimizer runs, evmVersion) or different constructor arguments than the deployed build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add Routescan's Etherscan-compatible API as a custom chain in &lt;code&gt;hardhat.config.js&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;etherscan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;redbellyTestnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;verifyContract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;  &lt;span class="c1"&gt;// Routescan accepts any non-empty string&lt;/span&gt;
  &lt;span class="nx"&gt;customChains&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;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;redbellyTestnet&lt;/span&gt;&lt;span class="dl"&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;153&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;apiURL&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://api.routescan.io/v2/network/testnet/evm/153/etherscan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;browserURL&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://redbelly.testnet.routescan.io&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="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify with the exact constructor arguments used at deployment:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx hardhat verify &lt;span class="nt"&gt;--network&lt;/span&gt; redbellyTestnet 0xDEPLOYED_ADDRESS &lt;span class="s2"&gt;"constructorArg1"&lt;/span&gt; &lt;span class="s2"&gt;"constructorArg2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;On bytecode mismatch: verify from the same commit and the same &lt;code&gt;hardhat.config.js&lt;/code&gt; (solc version, optimizer settings, evmVersion) that produced the deployment. Run &lt;code&gt;npx hardhat clean &amp;amp;&amp;amp; npx hardhat compile&lt;/code&gt; first to rule out stale artefacts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manual alternative: on the contract's page at &lt;a href="https://redbelly.testnet.routescan.io" rel="noopener noreferrer"&gt;https://redbelly.testnet.routescan.io&lt;/a&gt;, use "Verify Contract" and paste the flattened source, selecting the exact compiler version, optimizer setting and EVM version used at deployment. Useful when the deployment was done through Remix or another tool outside Hardhat.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verify immediately after deploying, from the same machine and commit, ideally in the deploy script itself via &lt;code&gt;hardhat.run("verify:verify", {...})&lt;/code&gt;. Record constructor arguments in your deployment output JSON.&lt;/p&gt;




&lt;h3&gt;
  
  
  14. "Invalid opcode" on deployment (EVM version mismatch)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Tested on Redbelly Testnet, July 2026: the same contract was deployed three times with solc 0.8.24 targeting paris, shanghai and cancun. All three deployed and executed correctly, including the shanghai build carrying 27 &lt;code&gt;PUSH0&lt;/code&gt; opcodes in its runtime bytecode. Testnet currently accepts post-paris builds.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A contract that compiles cleanly and deploys fine on another network reverts on Redbelly with &lt;code&gt;invalid opcode&lt;/code&gt; during deployment or on first interaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Solidity 0.8.20 and later target the Shanghai EVM by default and emit the &lt;code&gt;PUSH0&lt;/code&gt; opcode (Cancun targets add &lt;code&gt;MCOPY&lt;/code&gt; and transient storage opcodes on top). Chains whose execution layer has not enabled a given fork reject those opcodes, and older reports of this error on Redbelly stem from that gap. As of July 2026, Redbelly Testnet executes shanghai and cancun builds correctly (see the test note above), so a fresh &lt;code&gt;invalid opcode&lt;/code&gt; there usually has a different cause: stale build artefacts deployed from an old &lt;code&gt;artifacts/&lt;/code&gt; directory, a constructor revert being misreported by the tooling, or a library compiled with different settings than the importing project.&lt;/p&gt;

&lt;p&gt;Two version caveats worth knowing. Hardhat 2 pins the EVM target to paris for solc 0.8.20 to 0.8.24 precisely to avoid &lt;code&gt;PUSH0&lt;/code&gt; incompatibilities, so a default Hardhat build is already pre-shanghai without you asking. And Mainnet enablement of a fork can lag Testnet, so retest there before assuming parity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Rule out stale artefacts first: &lt;code&gt;npx hardhat clean &amp;amp;&amp;amp; npx hardhat compile&lt;/code&gt;, then redeploy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Isolate the EVM version question: deploy a trivial contract compiled with &lt;code&gt;evmVersion: "paris"&lt;/code&gt; (pre-PUSH0). If the paris build works while the default build fails, it is a fork mismatch on the network you are targeting; pin the version in &lt;code&gt;hardhat.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;solidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.8.24&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;evmVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paris&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;Foundry equivalent in &lt;code&gt;foundry.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;evm_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"paris"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If the paris build fails the same way, the EVM version is not your problem: check that the deployer account is enabled for the target network (entry 21 in Account Access) and inspect the transaction on Routescan for the actual revert point.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set &lt;code&gt;evmVersion&lt;/code&gt; explicitly in your project template rather than relying on compiler or framework defaults, retest after every Solidity version bump, and remember that the same settings must be used again at verification time (entry 13). When targeting Mainnet, confirm fork support there rather than extrapolating from Testnet.&lt;/p&gt;




&lt;h2&gt;
  
  
  EligibilitySDK and Onboarding SDK Issues
&lt;/h2&gt;

&lt;p&gt;Installation, widget rendering, cross-origin behaviour and verification checks for Redbelly's compliance tooling. Entries 15 to 19.&lt;/p&gt;




&lt;h3&gt;
  
  
  15. npm install fails with 401 for @redbellynetwork packages
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm ERR! code E401
npm ERR! 401 Unauthorized - GET https://npm.pkg.github.com/@redbellynetwork%2feligibility-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or &lt;code&gt;404 Not Found&lt;/code&gt; for the same package.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redbelly SDK packages are hosted on &lt;strong&gt;GitHub Packages&lt;/strong&gt;, not the public npm registry. Without an &lt;code&gt;.npmrc&lt;/code&gt; pointing the &lt;code&gt;@redbellynetwork&lt;/code&gt; scope at GitHub's registry plus a valid GitHub token, npm either looks in the wrong registry (404) or is rejected (401).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a GitHub Personal Access Token (classic) with the &lt;code&gt;read:packages&lt;/code&gt; scope: GitHub &amp;gt; Settings &amp;gt; Developer settings &amp;gt; Personal access tokens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create &lt;code&gt;.npmrc&lt;/code&gt; in your project root:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="py"&gt;redbellynetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;registry=https://npm.pkg.github.com&lt;/span&gt;
&lt;span class="err"&gt;//npm.pkg.github.com/:&lt;/span&gt;&lt;span class="py"&gt;_authToken&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;${GITHUB_TOKEN}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Export the token and install:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_token_here
npm i @redbellynetwork/eligibility-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;In CI, set &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; as a secret; never commit a literal token in &lt;code&gt;.npmrc&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Commit the &lt;code&gt;.npmrc&lt;/code&gt; with the &lt;code&gt;${GITHUB_TOKEN}&lt;/code&gt; placeholder (safe, contains no secret) and document the token requirement in your README so every new contributor and CI runner sets it before &lt;code&gt;npm install&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  16. EligibilitySDK widget not rendering
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The onboarding widget area is blank, stuck on a spinner, or the component mounts with no iframe. The browser console may show SDK initialisation errors or 401/403 responses from the verifier service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The widget aborts silently when its required configuration is missing or wrong. The usual suspects: &lt;code&gt;REDBELLY_API_KEY&lt;/code&gt; or &lt;code&gt;ALLOWED_ISSUER_DID&lt;/code&gt; unset (or not exposed to the browser build), the SDK initialised for the wrong environment, or the component rendered server-side where &lt;code&gt;window&lt;/code&gt; does not exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Check the browser console and network tab first: a 401 from the verifier API means the API key is missing or invalid; contact the Redbelly team if you have not been issued one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm the environment variables are present in &lt;code&gt;.env.local&lt;/code&gt; and actually reach the client. In Next.js, server-only names are invisible to browser code; the widget config must come from &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt;-prefixed variables or be passed down from a server component:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## .env.local&lt;/span&gt;
&lt;span class="nv"&gt;REDBELLY_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_key           &lt;span class="c"&gt;# server-side verification&lt;/span&gt;
&lt;span class="nv"&gt;ALLOWED_ISSUER_DID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;did:receptor:redbelly:testnet:31K82iKCtE6ciDc7oAr3T5EpjZb4S1EFM7c4xJaWkM2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;In the Next.js App Router, render the widget client-side only:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&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="nx"&gt;dynamic&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;next/dynamic&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;OnboardingWidget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./OnboardingWidget&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;ssr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the dev server after any &lt;code&gt;.env.local&lt;/code&gt; change; Next.js only reads env files at startup.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Validate SDK config at startup and render a visible error state ("Verification service not configured") instead of an empty div. Keep testnet and mainnet issuer DIDs in separate env files.&lt;/p&gt;




&lt;h3&gt;
  
  
  17. Cross-origin and iframe issues with the SDK
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blocked a frame with origin "https://..." from accessing a cross-origin frame
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or the SDK iframe refuses to load with a CSP / &lt;code&gt;X-Frame-Options&lt;/code&gt; error in the console, or &lt;code&gt;postMessage&lt;/code&gt; events from the widget never arrive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The onboarding widget runs in an iframe served from a Redbelly domain and communicates via &lt;code&gt;postMessage&lt;/code&gt;. Your site's Content-Security-Policy can block the frame from loading (&lt;code&gt;frame-src&lt;/code&gt;), and overly strict message-origin filtering (or third-party cookie blocking in the browser) can break the callback channel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the exact console error. &lt;code&gt;Refused to frame ...&lt;/code&gt; means your own CSP is the blocker. Allow the SDK origin in &lt;code&gt;frame-src&lt;/code&gt;. In Next.js:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// next.config.js&lt;/span&gt;
&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &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="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/(.*)&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="na"&gt;key&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-Security-Policy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;frame-src 'self' https://*.redbelly.network;&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;ol&gt;
&lt;li&gt;&lt;p&gt;If you listen for widget events yourself, do not drop messages by checking the wrong origin; log &lt;code&gt;event.origin&lt;/code&gt; once to see the real value, then allowlist exactly that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test in a normal browser profile. Extensions and "block third-party cookies" settings break iframe sessions; if it works in a clean profile, it is a browser privacy setting, not your code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Serve your app over HTTPS (or localhost); mixed-content rules block an HTTPS iframe inside an HTTP page.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you deploy a CSP, include &lt;code&gt;frame-src&lt;/code&gt; for Redbelly domains from the start, and test the full onboarding flow in Chrome, Firefox and Safari before release; Safari's tracking prevention is the strictest.&lt;/p&gt;




&lt;h3&gt;
  
  
  18. Onboarding wallet callback never arrives in local development
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You scan the QR code or open the identity wallet (Keyper or Privado), complete the credential step on your phone, but your locally running dApp never receives the completion callback. The flow works when deployed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The onboarding flow depends on the identity wallet calling your application back over the network. &lt;code&gt;http://localhost:3000&lt;/code&gt; is not reachable from your phone or from Redbelly's services, so the callback dies. This is why the official getting-started guide requires a tunnel (ngrok) for local development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start a tunnel to your dev server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Use the generated &lt;code&gt;https://xxxx.ngrok-free.app&lt;/code&gt; URL as the app URL in your SDK configuration and open the app through that URL (not localhost) while testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart the flow from scratch after switching URLs; sessions started on localhost will not resume on the tunnel URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the phone and callback still fail, confirm the phone has internet access (not just isolated local Wi-Fi) and that the tunnel is still alive; free ngrok URLs change on every restart.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Script the tunnel into your dev workflow (for example an npm script that starts ngrok and prints the URL to paste into &lt;code&gt;.env.local&lt;/code&gt;). For team testing, use a deployed preview environment instead of individual tunnels.&lt;/p&gt;




&lt;h3&gt;
  
  
  19. hasChainPermission returns false for a verified user
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A user completed the KYC flow in the onboarding widget, but &lt;code&gt;hasChainPermission(address)&lt;/code&gt; (contract call or &lt;code&gt;useHasChainPermission&lt;/code&gt; hook) still returns &lt;code&gt;false&lt;/code&gt;, so your gated contract reverts or your UI keeps them locked out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verification status is per-address, per-environment and per-issuer. The mismatch is usually one of: the user verified a different wallet address than the one connected, they verified on a different environment (testnet vs mainnet) than your app queries, your app trusts a different issuer DID than the one that issued the credential, or the credential has expired.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log exactly what you are checking:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;checking address:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&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;ok&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;eligibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasChainPermission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&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;hasChainPermission:&lt;/span&gt;&lt;span class="dl"&gt;"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that address character for character with the wallet the user verified. Multiple accounts in MetaMask is the most common source of this bug.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Confirm your app and the verification flow point at the same environment: chain ID 153 config with a testnet issuer DID, or 151 with mainnet. A testnet credential never validates on mainnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check &lt;code&gt;ALLOWED_ISSUER_DID&lt;/code&gt; matches the issuer used by the onboarding widget configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If everything matches and it worked before, the credential may have expired; run the user through the onboarding flow again.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the UI, always display which connected address is being checked, and gate actions on the same address object you pass to the hook. Keep environment config (chain plus issuer DID) in one shared module so testnet and mainnet cannot mix.&lt;/p&gt;




&lt;h2&gt;
  
  
  Faucet and Funding Issues
&lt;/h2&gt;

&lt;p&gt;Getting and keeping testnet RBNT. Entry 20.&lt;/p&gt;




&lt;h3&gt;
  
  
  20. Testnet faucet not distributing RBNT
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You request testnet RBNT but nothing arrives, the faucet reports you as rate-limited, or the faucet page errors out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The official faucet (FAUCETME) requires joining with a Discord account and enforces a claim cooldown (one claim per 24 hours). Requests fail when the Discord link is not completed, the cooldown has not elapsed, the wrong address was pasted, or the faucet is temporarily out of funds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the official faucet at &lt;a href="https://redbelly.faucetme.pro" rel="noopener noreferrer"&gt;https://redbelly.faucetme.pro&lt;/a&gt; and complete the "join with Discord" step; claims without the Discord link do not process.&lt;/li&gt;
&lt;li&gt;Double-check the address you pasted and that you are watching the same address on the explorer: search it at &lt;a href="https://redbelly.testnet.routescan.io" rel="noopener noreferrer"&gt;https://redbelly.testnet.routescan.io&lt;/a&gt; to see whether the transfer actually landed (MetaMask can display stale balances; see entry 6 in Wallet and MetaMask).&lt;/li&gt;
&lt;li&gt;If you claimed recently, wait out the 24-hour cooldown; repeat attempts inside the window are rejected.&lt;/li&gt;
&lt;li&gt;Try the third-party thirdweb faucet at &lt;a href="https://thirdweb.com/redbelly-network-testnet" rel="noopener noreferrer"&gt;https://thirdweb.com/redbelly-network-testnet&lt;/a&gt; as a fallback (small amounts, also rate-limited).&lt;/li&gt;
&lt;li&gt;If nothing arrives after the cooldown, ask in the Redbelly Discord developer channel with your address and timestamp; the faucet occasionally needs a refill by the team.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claim faucet funds before you need them, and consolidate testing on one or two funded addresses instead of spreading dust across many throwaway wallets. Deployment-heavy days may need more than one day's claim, so plan a day ahead.&lt;/p&gt;







&lt;p&gt;If this saved you an hour, the full maintained version with a searchable index is on GitHub: &lt;a href="https://github.com/Rahmandefi/Redbelly-troubleshooting-wiki" rel="noopener noreferrer"&gt;https://github.com/Rahmandefi/Redbelly-troubleshooting-wiki&lt;/a&gt;. Found an error pattern I missed? Open an issue or find me in the Redbelly Discord developer channel.&lt;/p&gt;

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