Setting up a Local Environment and Forking
Testing smart contracts in a local environment before deploying to mainnet is the safest and most cost-effective way to find bugs and verify logic without risking real funds.
Prerequisites
Node.js 18+
npm or yarn
Hardhat (or Foundry/Anvil if you prefer)
A
.envfile with Somnia RPCs:
# .env (example)
SOMNIA_RPC_MAINNET=https://api.infra.mainnet.somnia.network/
SOMNIA_RPC_TESTNET=https://dream-rpc.somnia.network/
# Optional: pin block numbers for reproducible forks
FORK_BLOCK_MAINNET=
FORK_BLOCK_TESTNET=Do not commit real keys/tokens. Use environment variables.
Quick Start (Hardhat)
npm i -D hardhat @nomicfoundation/hardhat-ethers ethers dotenv
npx hardhat # if project not initialized yet
cp .env.example .env || trueimport { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-ethers";
import * as dotenv from "dotenv";
dotenv.config();
const cfgFromEnv = {
mainnetUrl: process.env.SOMNIA_RPC_MAINNET || "https://api.infra.mainnet.somnia.network/",
testnetUrl: process.env.SOMNIA_RPC_TESTNET || "https://dream-rpc.somnia.network/",
forkMainnetBlock: process.env.FORK_BLOCK_MAINNET ? Number(process.env.FORK_BLOCK_MAINNET) : undefined,
forkTestnetBlock: process.env.FORK_BLOCK_TESTNET ? Number(process.env.FORK_BLOCK_TESTNET) : undefined,
};
const config: HardhatUserConfig = {
solidity: "0.8.19",
networks: {
hardhat: {
chainId: 31337,
},
localhost: {
url: "http://127.0.0.1:8545",
chainId: 31337,
},
somnia_testnet: {
url: cfgFromEnv.testnetUrl,
chainId: 50312,
},
somnia_mainnet: {
url: cfgFromEnv.mainnetUrl,
chainId: 5031,
},
},
};
export default config;Testing Your DApp Locally
Once your Hardhat environment is set up, you can write and run tests for your smart contracts. This ensures your code works as expected before deploying it.
Create a Simple Smart Contract
First, create a basic smart contract to test. The Counter.sol contract below includes fundamental functions for incrementing a counter and retrieving its current value. Save this file in your project's contracts directory.
Write a Test File
Next, write a test file to verify the functionality of your smart contract. The Counter.test.ts file below deploys the Counter contract on a local test network, calls the increment function, and checks whether the outcome is as expected. Save this file in your project's test directory.
Run Your Tests
To run your tests, navigate to your project's root directory in the terminal and use the following command. This command will execute your test scripts using Hardhat's built-in test network and display the results.
Forking Somnia (Testnet vs Mainnet)
Forking is the process of copying the state of a live network, like Somnia Mainnet or Testnet, at a specific block and creating a simulation of it on your local machine. This powerful feature allows you to test how your contract will interact with other deployed contracts on the live network (such as a DEX, oracle, or NFT marketplace) using real-world data, but without any of the risk or cost.
You can fork Shannon Testnet for faster iteration or Mainnet for production-like state. For deterministic CI, always pin a blockNumber.
Testnet (STT) is ideal for validating flows and cheaper RPC limits; Mainnet (SOMI) reflects real contract/state and gas rules.
Handy RPC Tricks (Hardhat)
These RPC methods provided by Hardhat Network allow you to manipulate the blockchain state for advanced testing scenarios.
Impersonate an account
This allows you to execute transactions from any wallet address on the forked chain, which is perfect for testing functions with admin privileges or interacting with contracts using an account that holds a large amount of tokens ("whale").
Time travel
This feature lets you change the timestamp of future blocks. It's incredibly useful for testing time-dependent smart contract logic, such as vesting schedules, lock-up periods, or any functionality that relies on block.timestamp.
Snapshot & revert
This allows you to save the current state of the blockchain and later restore it instantly. It's an efficient way to isolate your tests, ensuring that each test case starts from the same clean state without needing to restart the local node.
Reset fork
This command resets the local Hardhat node to a fresh state forked from the blockchain. You can use it to switch to a different block number or even a different RPC endpoint without restarting your entire testing process.
Alternative: Anvil (Foundry)
Point your app/tests to http://127.0.0.1:8546.
Anvil JSON-RPC is Hardhat-compatible for most calls (evm_*). Replace hardhat_* with Anvil equivalents where needed.
Tips & Best Practices
Always pin block numbers in forks for reproducibility.
Prefer
localhostnetwork when you need state persistence across multiple test files.Keep Anvil/Hardhat on separate ports if you run both simultaneously.
Use labels/comments in tests to describe assumptions tied to a specific fork block.
Avoid draining RPC rate limits: cache fixtures, use snapshots, and fork testnet for most flows.
Common Issues
Last updated