Popular Libraries for Development, Testing & Fuzzing
Key frameworks, libraries, and practices for frontend development, wallet integration, smart contracts, testing and more.
Common Libraries & Tooling
These libraries are used across the stack to write tests, simulate transactions, connect wallets, and interface with the blockchain in both scripting and frontend contexts.
Ethers.js
Contract interaction, transaction signing, provider management in JS/TS environments
Provides Contract, Provider, Wallet, and Interface abstractions. Deep Hardhat integration. ABI coder, calldata utilities, and ENS support.
Viem
Modular TypeScript-first library for RPC, contract access, encoding, and data formatting
Tree-shakeable. Supports batching, client-side caching, EIP-1559 fees, multicalls, typed reads/writes. Used by Wagmi.
Wagmi
React hooks for wallet connection, chain state, and contract calls in frontend apps
Built on Viem. Includes useAccount, useConnect, useContractRead, and event subscriptions. Enables seamless integration with wallet modals.
Web3.js
Legacy Ethereum contract and RPC library
One of the earliest libraries. Now largely unmaintained. Lacks EIP-1559 support and modern modularity.
RainbowKit
React component library for wallet connection UI and chain management
Pre-built wallet connect buttons, chain switch UI, and custom themes. Integrates with Wagmi for wallet state management and tx handling.
Ethers and Viem serve similar purposes, but Viem is optimized for frontend apps. Wagmi builds on Viem. Web3.js is no longer recommended for new projects.
Testing Frameworks
Note Smart contract quality and security depend on a comprehensive testing strategy including but not limited to:
Unit Tests: Verify individual functions and components
Property-Based Fuzzing: Test invariants with random inputs
Code Coverage: Ensure all code paths are tested
Static Analysis: Detect common vulnerabilities and anti-patterns
The tools and frameworks below provide a foundation for each of these testing layers.
Foundry — Solidity-Native
Tests written directly in Solidity.
Very fast runner (
forge test) and rich cheatcodes for state manipulation.Built-in, configurable fuzzing (
forge test --fuzz-runs=N).Includes tools like
forge script,forge coverage, andforge snapshot.
Hardhat — JavaScript / TypeScript
Mocha + Chai test runner for JS/TS-based tests.
Flexible task system (
hardhat.config.js), plugin support, and network forking.Integrates with Ethers.js and Solidity tooling for deployments, gas tracking, and test orchestration.
v0.5.0 Compatibility Testing Framework
Ontomir EVM v0.5.0 introduces comprehensive compatibility testing to ensure seamless integration with major Ethereum development tools.
EVM Tools Compatibility Testing
Automated Testing Suites: Five comprehensive test suites validate compatibility with popular Ethereum tools:
Foundry
Contract deployment, testing, gas estimation
.github/workflows/tests-compatibility-foundry.yml
Hardhat
Contract deployment, ethers.js integration
.github/workflows/tests-compatibility-hardhat.yml
Viem
TypeScript client compatibility, RPC methods
.github/workflows/tests-compatibility-viem.yml
Web3.js
Legacy client compatibility, transaction handling
.github/workflows/tests-compatibility-web3js.yml
Foundry + UniswapV3
Complex DeFi protocol deployment
.github/workflows/tests-compatibility-foundry-uniswap-v3.yml
Running Compatibility Tests
Local Testing:
# Run JSON-RPC compatibility tests
cd /path/to/Ontomir-evm
make test-rpc-compat # Makefile:373
# Test specific tool
./scripts/tests_compatibility_foundry.sh
./scripts/tests_compatibility_hardhat.sh
./scripts/tests_compatibility_viem.sh
./scripts/tests_compatibility_web3js.sh
./scripts/tests_compatibility_foundry_uniswap_v3.shTest Structure:
tests/evm-tools-compatibility/
├── foundry/ # Foundry compatibility tests
├── hardhat/ # Hardhat + Ethers.js tests
├── viem/ # Viem TypeScript tests
├── web3.js/ # Web3.js legacy tests
└── foundry-uniswap-v3/ # Complex DeFi protocol testsJSON-RPC Compatibility Testing
Comprehensive RPC Validation: New framework compares Ontomir EVM responses against geth for accuracy.
Setup:
# Start comparison testing environment
cd tests/jsonrpc
# Build required Docker images
make localnet-build-env
# Start both evmd and geth for comparison
./scripts/start-networks.sh
# Run compatibility test suite
cd simulator && go build . && ./simulator
# Stop testing environment
./scripts/stop-networks.shTest Coverage:
Transaction Processing: Compare transaction execution results
Block Queries: Validate block structure and data
Account Queries: Verify balance and nonce handling
Event Logs: Ensure log filtering and retrieval accuracy
Gas Estimation: Compare gas estimation algorithms
Configuration:
// tests/jsonrpc/simulator/config/config.go:27-36
type Config struct {
EvmdHttpEndpoint string // Default: "http://localhost:8545"
EvmdWsEndpoint string // Default: "ws://localhost:8546"
GethHttpEndpoint string // Default: "http://localhost:8547"
GethWsEndpoint string // Default: "ws://localhost:8548"
RichPrivKey string
Timeout string
}Fuzz (Property-Based) Testing
Fuzz testing generates random inputs to find edge cases that violate expected properties.
// test/MyContract.t.sol (Foundry)
function test_myFunction_fuzz(uint256 amount) public {
vm.assume(amount > 0 && amount < 1e18); // constrain input
myContract.myFunction(amount);
assertEq(myContract.someState(), expectedValue);
}Foundry
Built-in fuzzing; enabled by default when running forge test.
Echidna
External, property-based fuzzer. Supports invariants and campaigns.
Use fuzzing to test against invariants such as:
balance never exceeds total supply
no overflow or underflow under bounded inputs
access control is consistently enforced
Supplementary Tools
Tools that enhance test coverage, assert correctness, or catch common vulnerabilities.
OpenZeppelin Test Helpers
Time travel, event assertions, reverts
JS/TS only. Works with Hardhat + Mocha.
solidity-coverage
Reports untested branches in Solidity
npx hardhat coverage · forge coverage
Slither
Static analysis for known vuln patterns
slither .
Example — OpenZeppelin Test Helpers
const { time, expectRevert } = require('@openzeppelin/test-helpers');
// advance clock by one day
await time.increase(time.duration.days(1));
// expect revert with specific reason
await expectRevert(contract.someFunction(), "Ownable: caller is not the owner");