Skip to content

canopy-network/ethrpc-test-harness

Repository files navigation

ETH RPC Test Harness

This repo is a CEX-onboarding-oriented compatibility harness for Ethereum JSON-RPC surfaces.

It does not pretend to mathematically "guarantee" production readiness. What it does is give you a release-gate harness that exercises the failure modes that actually matter for centralized exchanges:

  • raw JSON-RPC request/response semantics
  • configured chain identity matching
  • ethers provider compatibility
  • viem public-client compatibility
  • web3.py compatibility
  • cast compatibility
  • ERC20-style eth_call probes across major client paths
  • transaction lookup and receipt semantics
  • transfer log indexing and address/topic-scoped eth_getLogs
  • address/topic-scoped filter lifecycle
  • active EOA-style and ERC20-style transfers in full mode

Why this exists

Wallets are a weak signal. MetaMask can work while exchange middleware still breaks on:

  • eth_getTransactionByHash
  • eth_getTransactionReceipt
  • eth_getLogs
  • eth_newFilter / eth_getFilterChanges
  • block walking by number and index
  • ABI-decoded eth_call
  • client-library assumptions in ethers, viem, or backend scripts

This harness tests those directly.

Client matrix

The harness currently exercises the same endpoint through five paths:

  • raw JSON-RPC over HTTP
  • cast
  • viem
  • ethers
  • web3.py with standard PoA middleware

The Python path is not just an example script. Its results are merged into the same readiness report.

Modes

read-only

Useful for smoke testing an endpoint without a funded test key.

This mode checks:

  • EXPECTED_CHAIN_ID against the target endpoint
  • chain metadata
  • latest block lookup
  • pseudo-contract eth_getCode
  • raw JSON-RPC 2.0 envelope semantics, including id echoing, method-not-found, malformed-filter, and null-vs-error behavior
  • ERC20 reads: name, symbol, decimals, totalSupply, balanceOf
  • the same standard ERC20 probe set through ethers and cast
  • unknown tx / receipt / block / by-index null semantics
  • ethers and viem latest-block and getLogs compatibility
  • cast chain / block / getLogs / eth_call compatibility
  • address/topic-scoped filter lifecycle and uninstall behavior

Read-only mode is not enough to claim exchange readiness.

full

This is the actual readiness gate.

In addition to read-only checks, it:

  • sends an EOA-style transfer
  • sends an ERC20-style transfer through the pseudo-contract
  • verifies the first receipt poll after submission returns either null or an already-mined receipt
  • waits for receipts
  • verifies transaction lookup by hash
  • verifies transaction and receipt field shape as clients see them
  • verifies transfer log presence and decodability
  • verifies address/topic-scoped eth_getLogs range queries
  • verifies address/topic-scoped eth_getFilterChanges and eth_getFilterLogs deliver the live transfer
  • verifies block transaction enumeration and by-index lookup
  • verifies missing by-index lookups return null
  • re-reads txs, receipts, logs, blocks, and ERC20 state through ethers, viem, cast, and web3.py

Install

npm install

For the Python suite:

python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r python/requirements.txt

Configuration

You can configure the harness via environment variables or a JSON config file.

Example files:

  • config.read-only.example.json
  • config.full.example.json

Minimal read-only run

RPC_URL=http://127.0.0.1:50002 \
EXPECTED_CHAIN_ID=1234 \
npm run check

Full readiness-gate run

RPC_URL=http://127.0.0.1:50002 \
EXPECTED_CHAIN_ID=1234 \
PRIVATE_KEY=0x... \
EOA_RECIPIENT=0x... \
ERC20_RECIPIENT=0x... \
npm run check -- --mode full

Env vars

  • EXPECTED_CHAIN_ID required; the harness aborts immediately if eth_chainId does not match
  • EXPECTED_NAME default: Canopy
  • EXPECTED_SYMBOL default: CNPY
  • EXPECTED_DECIMALS default: 6
  • CAST_BINARY default: cast
  • PYTHON_BINARY default: python3 unless .venv/bin/python exists
  • REPORT_DIR default: ./reports
  • POLL_INTERVAL_MS default: 1500
  • TX_TIMEOUT_MS default: 120000
  • EOA_AMOUNT_WEI default: 1000000000000
  • ERC20_AMOUNT_UNITS default: 1
  • MAX_FEE_PER_GAS_WEI
  • MAX_PRIORITY_FEE_PER_GAS_WEI

Exit codes

  • 0: all required checks passed for the selected mode
  • 1: at least one required check failed, or full mode was incomplete

Output

Each run prints a human-readable summary and writes a JSON report under reports/.

That report is intended to be the artifact you keep for release reviews.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors