Developer Guide: RPC, Nodes & Using MetaMask for dApp Testing

Try Tangem secure wallet →

Table of contents

Developer Guide: RPC, Nodes & Using MetaMask for dApp Testing

This developer MetaMask guide explains how RPC nodes, custom RPC settings, and local test nodes (Ganache/Hardhat) fit into a reliable dApp testing workflow. I’ve been using MetaMask with local and hosted nodes for months while building and testing contracts; the steps below reflect hands-on testing and real bugs I fixed (chainId mismatches and nonce issues, among others). What you’ll get is practical, step-by-step, and reproducible.

Overview & who this is for

This guide is for:

Who should look elsewhere:

And one practical note: I believe running a local node is worth the time if you need deterministic snapshots for tests.

Quick terms: RPC, node, chainId

Short sentence. Test networks matter.

RPC options: hosted vs local vs test node (comparison table)

Option Good for Example RPC URL Pros Cons
Hosted node provider (RPC-as-a-service) Quick dev + public testnets https://rpc.example.com/ Zero ops, global availability, predictable response Rate limits, privacy concerns, API keys required
Local full node (self-hosted) Deterministic test runs, privacy http://127.0.0.1:8545 No rate limits, full control, mirrors mainnet behaviour Sync time, disk & memory cost
In-memory test node (Ganache / Hardhat) Fast iteration, CI, snapshots http://127.0.0.1:8545 Prefunded accounts, fast reset, deterministic state Not identical to mainnet; chainId differences
L2 RPC endpoint L2-specific testing https://l2.rpc.example Low-cost tx testing (on L2); L2 semantics Different gas model; different finality /

(Image placeholder)

Add a Custom RPC in MetaMask — step-by-step

MetaMask exposes two common ways to add a network: the UI and programmatic (EIP-3085 / wallet_addEthereumChain).

UI steps (extension):

  1. Open MetaMask and click the network dropdown at the top (it shows the current network name).
  2. Choose “Add network” or go to Settings → Networks → Add a network.
  3. Fill the fields:
    • Network name: Localhost 8545 (example)
    • RPC URL: http://127.0.0.1:8545
    • Chain ID: 1337 (decimal) — match your node
    • Currency symbol: ETH (optional)
    • Block explorer URL: optional
  4. Save and switch network.

Programmatic add (useful for dApp setup):

await window.ethereum.request({
  method: 'wallet_addEthereumChain',
  params: [{
    chainId: '0x539', // hex for 1337
    chainName: 'Localhost 8545',
    rpcUrls: ['http://127.0.0.1:8545'],
    nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
  }]
})

Note: MetaMask expects chainId in hex. Check your node output to avoid chainId mismatch.

For a guide specifically on custom network fields, see custom RPC network settings and add L2 networks.

Connect Ganache / Hardhat (local) to MetaMask

Typical local workflow:

But be careful: never import a mainnet seed phrase into a test environment. I've learned that the hard way (lost time and a few headaches). If you use Ganache, check the CLI output for private keys and chainId.

For more on running nodes locally, read running your own node and the developer integration guide.

Common RPC errors & fixes (rpc error metamask)

What if MetaMask shows an RPC error? Here are frequent causes and fixes.

If errors persist, check the node logs, then consult transaction errors and fixes for deeper troubleshooting.

Gas behavior & EIP-1559 on local nodes

MetaMask prefers EIP-1559 (maxPriorityFee and maxFee). Local test nodes behave differently:

Tip: when testing fee-related code, explicitly assert for both legacy and EIP-1559 paths in unit tests. And keep an eye on the gas UI in MetaMask; it shows priority fee and total max fee when EIP-1559 is used.

dApp testing workflow & programmatic chain add

Typical test cycle:

  1. Start local node and deploy contracts.
  2. Add or switch MetaMask to the node RPC (manual or via wallet_addEthereumChain).
  3. From your dApp, call await provider.send('eth_requestAccounts', []) or await window.ethereum.request({ method: 'eth_requestAccounts' }) to connect.
  4. Send signed transactions and inspect the node logs and the local block explorer (if running).

Example to get a signer using ethers.js:

const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send('eth_requestAccounts', []);
const signer = provider.getSigner();
await signer.sendTransaction({ to: addr, value: ethers.utils.parseEther('0.01') });

Security & best practices for developers

But remember: testing convenience and safety are trade-offs. Choose the right balance for your project.

Advanced topics & links

Wrapping up & next steps (CTA)

If you want a quick task: start a local node (npx hardhat node), add the RPC to MetaMask using the UI, import one prefunded test key, and deploy a simple contract. You’ll see how changing chainId or RPC URL produces different errors (and how to fix them). I recommend reading the linked pages above for network-specific steps and deeper troubleshooting.

Ready to test? Follow the steps above and then check the developer integration and custom RPC network settings pages for concrete examples and code snippets.

Try Tangem secure wallet →