Anvil Local Network

Referenced Files in This Document - anvil.py - base.py - manager.py - w3.py - ethereum.py - bsc.py - config.py - chains.yaml - docker-compose.yml - crypto.py - dependencies.py - scanner.py - requirements.txt - README.md

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document explains the Anvil local blockchain network implementation used for development and testing. It focuses on the AnvilBlockchain class, its role in enabling fast and deterministic local testing, and how it integrates with the broader system for payment gateway functionality. You will learn how to set up Anvil, configure networks, manage private keys via HD wallets, and leverage Anvil’s capabilities for automated testing, local debugging, and streamlined development workflows.

Project Structure

The Anvil integration is centered around a small set of modules that provide a unified interface to EVM-compatible chains, with Anvil as a special-case local chain. Configuration is driven by environment variables and a chains YAML file, while runtime access is provided via a global registry of blockchain instances.

graph TB subgraph "Configuration" CFG["Settings (config.py)"] CHAINS["chains.yaml"] end subgraph "Blockchain Layer" BASE["BlockchainBase (base.py)"] ANVIL["AnvilBlockchain (anvil.py)"] ETH["EthereumBlockchain (ethereum.py)"] BSC["BSCBlockchain (bsc.py)"] MANAGER["get_blockchains (manager.py)"] W3REG["get_w3 (w3.py)"] end subgraph "Application" DEPS["get_blockchains/get_hdwallet (dependencies.py)"] SCANNER["ScannerService (scanner.py)"] CRYPTO["HDWalletManager (crypto.py)"] end CFG --> MANAGER CHAINS --> MANAGER MANAGER --> ANVIL MANAGER --> ETH MANAGER --> BSC ANVIL --> BASE ETH --> BASE BSC --> BASE W3REG --> MANAGER DEPS --> MANAGER SCANNER --> W3REG DEPS --> CRYPTO

Diagram sources - config.py - chains.yaml - manager.py - anvil.py - base.py - ethereum.py - bsc.py - w3.py - dependencies.py - scanner.py - crypto.py

Section sources - README.md - config.py - chains.yaml - manager.py - w3.py - dependencies.py

Core Components

  • AnvilBlockchain: Specialized EVM client for local development with Anvil, exposing mining, balance manipulation, impersonation, and reset controls.
  • BlockchainBase: Shared async Web3 utilities for connection checks, balances, gas estimation, transaction building, signing, sending, and receipts.
  • Manager and Registry: Build a chain registry from configuration, selecting Anvil or other chains based on settings.
  • HD Wallet: Deterministic key/address generation for local testing and payment address derivation.
  • Scanner: Detects incoming native and ERC20 payments on configured chains and advances statuses accordingly.

Key advantages for testing: - Fast block times and instant confirmations via mining control. - Deterministic state via impersonation and balance setting. - Easy reset and fork control for repeatable tests.

Section sources - anvil.py - base.py - manager.py - w3.py - crypto.py - scanner.py

Architecture Overview

The system initializes blockchain clients from configuration, exposes them via a registry, and allows services to scan and react to on-chain activity. Anvil is treated as a first-class chain with specialized RPC methods for rapid iteration.

sequenceDiagram participant App as "App Runtime" participant Manager as "get_blockchains" participant Registry as "w3 registry" participant Chain as "AnvilBlockchain" participant Web3 as "AsyncWeb3" App->>Manager : Load chains from settings + chains.yaml Manager->>Chain : Instantiate with provider_url Chain->>Web3 : Connect via AsyncHTTPProvider App->>Registry : get_w3("anvil") Registry-->>App : AsyncWeb3 instance App->>Chain : Mine/Impersonate/SetBalance/Reset Chain->>Web3 : Provider RPC calls

Diagram sources - manager.py - w3.py - anvil.py - base.py

Detailed Component Analysis

AnvilBlockchain

Purpose: - Provide Anvil-specific operations: mining blocks, setting balances, impersonating accounts, and resetting/forking the chain. - Wrap base Web3 utilities for gas, transactions, receipts, and balance queries.

Capabilities: - Mining: Mine N blocks in sequence to advance chain state deterministically. - Balance control: Set native ETH balance for any address. - Impersonation: Temporarily act as any account for signing and state reads. - Reset/Fork: Reset to clean state or fork from a remote endpoint at a specific block.

Implementation highlights: - Uses JSON-RPC methods exposed by Anvil (e.g., evm_mine, anvil_setBalance, anvil_impersonateAccount, anvil_reset). - Inherits robust gas estimation, transaction building, and signing from BlockchainBase.

classDiagram class BlockchainBase { +provider_url +chain_id +use_poa +is_connected() +get_balance() +get_token_balance() +get_gas_price() +get_fee_history() +estimate_gas() +build_transaction() +send_transaction() +get_receipt() +get_latest_block() } class AnvilBlockchain { +mine_blocks(num_blocks) +set_balance(address, balance_eth) +impersonate_account(address) +stop_impersonating_account(address) +reset(forking_url, block_number) } BlockchainBase <|-- AnvilBlockchain

Diagram sources - base.py - anvil.py

Section sources - anvil.py - base.py

BlockchainBase Utilities

Purpose: - Provide a shared async Web3 toolkit for gas pricing, fee history, transaction construction, signing, sending, and receipt polling.

Notable features: - Gas caching and fallback logic. - EIP-1559 fee calculation with legacy fallback. - Robust transaction building with dynamic gas limits and buffers. - Receipt polling with timeouts.

flowchart TD Start(["Build Transaction"]) --> GetNonce["Get pending nonce"] GetNonce --> SetFields["Set chainId, from, to, value, data"] SetFields --> FeeMode{"Can fetch fee history?"} FeeMode --> |Yes| EIP1559["Compute maxFeePerGas/maxPriorityFeePerGas"] FeeMode --> |No| Legacy["Use legacy gasPrice"] EIP1559 --> Estimate["Estimate gas"] Legacy --> Estimate Estimate --> Buffer["Apply 10% buffer"] Buffer --> Done(["Return tx dict"])

Diagram sources - base.py

Section sources - base.py

Chain Registry and Access

Purpose: - Construct a registry of blockchain clients from configuration and expose a simple accessor for async Web3.

How it works: - Loads chain configs from settings and chains.yaml. - Instantiates AnvilBlockchain for the "anvil" chain, EthereumBlockchain for "ethereum", BSCBlockchain for "bsc", or a generic BlockchainBase otherwise. - Provides a fallback to a default Anvil instance if configuration is missing. - Exposes get_w3(chain_name) to retrieve an AsyncWeb3 instance for a given chain.

sequenceDiagram participant Cfg as "Settings + chains.yaml" participant Manager as "get_blockchains" participant Reg as "Registry (_blockchains)" participant Access as "get_w3" Cfg-->>Manager : chains[] Manager->>Reg : Populate {name : BlockchainBase subclass} Access->>Reg : Lookup AsyncWeb3 by chain name Reg-->>Access : AsyncWeb3 instance

Diagram sources - manager.py - w3.py - config.py - chains.yaml

Section sources - manager.py - w3.py - config.py - chains.yaml

HD Wallet and Private Key Management

Purpose: - Generate deterministic payment addresses using BIP-44 derivation for local testing and payment address allocation.

Highlights: - Mnemonic-based HD derivation with configurable seed. - Derives Ethereum addresses at m/44'/60'/0'/0/{index}. - Provides helpers to generate multiple addresses and retrieve mnemonic for backup.

Integration: - Used by payment creation to derive unique addresses per payment. - Private keys are managed via environment configuration and used by BlockchainBase to sign transactions.

classDiagram class HDWalletManager { +mnemonic +get_address(index) +get_multiple_addresses(count, start_index) +get_mnemonic() }

Diagram sources - crypto.py

Section sources - crypto.py - config.py

Payment Scanning and Confirmation

Purpose: - Scan blocks for incoming native and ERC20 payments to a set of target addresses and confirm them after required block confirmations.

Key steps: - Retrieve last scanned block from state and scan in batches. - For native payments, check transaction values to destination addresses. - For ERC20, filter logs by transfer topic and match token addresses and amounts. - Advance status to detected and later confirmed after sufficient confirmations.

sequenceDiagram participant Scanner as "ScannerService" participant Registry as "get_w3" participant Chain as "AsyncWeb3" participant DB as "Database" Scanner->>Registry : get_w3(chain_name) Registry-->>Scanner : AsyncWeb3 Scanner->>Chain : block_number Scanner->>DB : Load pending payments for chain loop For each block in batch Scanner->>Chain : get_block(full_transactions=True) Scanner->>Chain : get_logs(ERC20 Transfer) Scanner->>DB : Update status to detected/confirmed end

Diagram sources - scanner.py - w3.py

Section sources - scanner.py - w3.py

Dependency Analysis

External dependencies relevant to Anvil and blockchain operations: - web3: AsyncWeb3 provider and middleware stack. - eth-account: HD wallet and private key utilities. - pydantic/pydantic-settings: Strongly typed configuration with environment loading. - yaml: Chains configuration parsing.

graph LR REQ["requirements.txt"] --> WEB3["web3"] REQ --> ETHACC["eth-account"] REQ --> PYD["pydantic-settings"] REQ --> YAML["PyYAML"] CFG["config.py"] --> PYD CFG --> WEB3 CFG --> ETHACC CHAINS["chains.yaml"] --> MAN["manager.py"] MAN --> WEB3 ANV["anvil.py"] --> WEB3 BASE["base.py"] --> WEB3 CRYPTO["crypto.py"] --> ETHACC

Diagram sources - requirements.txt - config.py - chains.yaml - manager.py - anvil.py - base.py - crypto.py

Section sources - requirements.txt - config.py - chains.yaml - manager.py - anvil.py - base.py - crypto.py

Performance Considerations

  • Mining control: Use mining APIs to advance blocks instantly during tests, avoiding long waits.
  • Gas caching: Base class caches gas prices to reduce repeated RPC calls.
  • Batch scanning: ScannerService processes blocks in batches to avoid overloading the node.
  • Confirmations: Tune confirmations to balance speed vs. safety in local tests.

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common issues and resolutions: - Provider connectivity failures: Use the base connection checker to verify RPC reachability. - Missing chain configuration: Manager falls back to a default Anvil instance; ensure chains.yaml or settings are correct. - Invalid private key: Settings validator rejects invalid keys; ensure PRIVATE_KEY is a valid Ethereum private key. - HD wallet mnemonic errors: Mnemonic must be valid; regenerate if corrupted. - Scanner not finding payments: Verify target addresses, token addresses, and that the chain is properly registered.

Section sources - base.py - manager.py - config.py - crypto.py - scanner.py

Conclusion

Anvil is integrated as a first-class local chain with powerful developer controls for rapid iteration. By combining AnvilBlockchain’s specialized methods with BlockchainBase utilities and HD wallet management, the system enables deterministic, fast, and repeatable testing of payment gateway flows. The registry pattern and configuration-driven chain selection keep the system flexible and maintainable across environments.

[No sources needed since this section summarizes without analyzing specific files]

Appendices

A. Anvil Setup Procedures

  • Run Anvil locally or via Docker Compose. The default RPC URL is configured in settings and can be overridden via environment variables.
  • Ensure the chains configuration includes the "anvil" chain with the correct RPC URL.

Practical steps: - Start Anvil on port 8545. - Confirm connectivity using the base connection checker. - Optionally fork from a mainnet endpoint for realistic testing.

Section sources - config.py - chains.yaml - docker-compose.yml - base.py

B. Network Configuration and Chain Selection

  • Configure chains in chains.yaml and load them via settings.
  • Manager selects AnvilBlockchain for "anvil", EthereumBlockchain for "ethereum", BSCBlockchain for "bsc", or a generic base class otherwise.
  • Fallback ensures Anvil is available even if configuration is empty.

Section sources - chains.yaml - config.py - manager.py

C. Private Key Management for Local Development

  • Private key is validated by settings and used by BlockchainBase to sign transactions.
  • Mnemonic is used by HDWalletManager to derive deterministic addresses for payment generation.
  • Keep mnemonics and private keys secure; use environment variables and secrets management.

Section sources - config.py - crypto.py - base.py

D. Advantages for Testing Payment Gateways

  • Fast transaction speeds: Mine blocks instantly to simulate confirmations.
  • Deterministic behavior: Impersonate accounts and set balances for reproducible tests.
  • Easy state management: Reset/fork to known states between test runs.

Section sources - anvil.py - base.py

E. Integration with Development Workflows

  • API endpoints depend on the chain registry to validate and route requests.
  • Background workers scan chains and update payment statuses.
  • Use the registry to access AsyncWeb3 for chain-specific operations.

Section sources - dependencies.py - w3.py - scanner.py

F. Practical Examples and Best Practices

  • Example operations:
  • Mine blocks to advance time: mine_blocks
  • Set balances for test accounts: set_balance
  • Impersonate accounts for signing: impersonate_account
  • Reset/fork to clean state: reset
  • Best practices:
  • Use separate test mnemonics and private keys.
  • Keep chains.yaml minimal and environment overrides for local dev.
  • Use reset/fork between test suites to avoid cross-test contamination.

Section sources - anvil.py - config.py - chains.yaml