chain

Documentation for eth_defi.chain Python module.

Chain specific configuration.

Many chains like Polygon and BNB Chain may need their own Web3 connection tuning. In this module, we have helpers.

Module Attributes

POA_MIDDLEWARE_NEEDED_CHAIN_IDS

List of chain ids that need to have proof-of-authority middleweare installed

CHAIN_NAMES

Manually maintained shorthand names for different EVM chains

CHAIN_HOMEPAGES

For linking on reports

EVM_BLOCK_TIMES

Chain avg block times.

Functions

fetch_block_timestamp(web3, block_number)

Get the block mined at timestamp.

get_block_time(chain_id)

Get average block time for a chain.

get_chain_homepage(chain_id)

Translate Ethereum chain id to a link to its homepage.

get_chain_id_by_name(name)

Get chain id by its name.

get_chain_name(chain_id)

Translate Ethereum chain id to its name.

get_default_call_gas_limit(chain_id)

Get the eth_call reasonable gas limit.

get_graphql_url(provider)

Resolve potential GraphQL endpoint API for a JSON-RPC provider.

has_graphql_support(provider)

Check if a node has GoEthereum GraphQL API turned on.

install_api_call_counter_middleware(web3)

Install API call counter middleware.

install_api_call_counter_middleware_on_provider(...)

Install API call counter middleware on a specific API provider.

install_chain_middleware(web3[, ...])

Install any chain-specific middleware to Web3 instance.

install_retry_middleware(web3)

Install gracefully HTTP request retry middleware.

install_retry_muiddleware(web3)

POA_MIDDLEWARE_NEEDED_CHAIN_IDS = {56, 137, 43114}

List of chain ids that need to have proof-of-authority middleweare installed

CHAIN_NAMES = {1: 'Ethereum', 10: 'Optimism', 56: 'Binance', 100: 'Gnosis', 130: 'Unichain', 137: 'Polygon', 143: 'Monad', 146: 'Sonic', 239: 'TAC', 324: 'ZKsync', 957: 'Derive', 999: 'Hyperliquid', 1868: 'Soneium', 2741: 'Abstract', 5000: 'Mantle', 8453: 'Base', 9745: 'Plasma', 34443: 'Mode', 42161: 'Arbitrum', 42220: 'Celo', 43111: 'Hemi', 43114: 'Avalanche', 57073: 'Ink', 59144: 'Linea', 80094: 'Berachain', 81457: 'Blast', 421614: 'Arbitrum_Sepolia', 645749: 'Hyperliquid', 747474: 'Katana', 7777777: 'Zora'}

Manually maintained shorthand names for different EVM chains

CHAIN_HOMEPAGES = {1: {'homepage': 'https://ethereum.org', 'name': 'Ethereum'}, 10: {'homepage': 'https://www.optimism.io', 'name': 'Optimism'}, 56: {'homepage': 'https://www.bnbchain.org', 'name': 'Binance'}, 100: {'homepage': 'https://www.gnosis.io', 'name': 'Gnosis'}, 130: {'homepage': 'https://www.uniswap.org/unichain', 'name': 'Unichain'}, 137: {'homepage': 'https://polygon.technology', 'name': 'Polygon'}, 143: {'homepage': 'https://monad.xyz', 'name': 'Monad'}, 146: {'homepage': 'https://www.soniclabs.com/', 'name': 'Sonic'}, 239: {'homepage': 'https://tac.build/', 'name': 'TAC'}, 324: {'homepage': 'https://zksync.io', 'name': 'ZKsync'}, 957: {'homepage': 'https://derive.xyz', 'name': 'Derive'}, 999: {'homepage': 'https://hyperliquid.xyz', 'name': 'Hyperliquid'}, 1868: {'homepage': 'https://www.soneium.org', 'name': 'Soneium'}, 2741: {'homepage': 'https://www.abstract.foundation', 'name': 'Abstract'}, 5000: {'homepage': 'https://www.mantle.xyz', 'name': 'Mantle'}, 8453: {'homepage': 'https://www.base.org', 'name': 'Base'}, 9745: {'homepage': 'https://www.plasma.to/', 'name': 'Plasma'}, 34443: {'homepage': 'https://www.mode.network', 'name': 'Mode'}, 42161: {'homepage': 'https://arbitrum.io', 'name': 'Arbitrum'}, 42220: {'homepage': 'https://celo.org', 'name': 'Celo'}, 43111: {'homepage': 'https://hemi.xyz/', 'name': 'Hemi'}, 43114: {'homepage': 'https://www.avax.network', 'name': 'Avalanche'}, 57073: {'homepage': 'https://inkonchain.com/', 'name': 'Ink'}, 59144: {'homepage': 'https://linea.build/', 'name': 'Linea'}, 80094: {'homepage': 'https://www.berachain.com', 'name': 'Berachain'}, 81457: {'homepage': 'https://blast.io', 'name': 'Blast'}, 645749: {'homepage': 'https://hyperliquid.xyz', 'name': 'Hyperliquid'}, 747474: {'homepage': 'https://katana.network/', 'name': 'Katana'}, 7777777: {'homepage': 'https://zora.co', 'name': 'Zora'}}

For linking on reports

EVM_BLOCK_TIMES = {1: 12, 10: 2, 56: 3, 100: 5, 130: 1, 137: 2, 143: 0.4, 146: 1, 239: 1.5, 324: 1, 957: 2, 999: 0.1, 1868: 2, 2741: 2, 5000: 2, 8453: 2, 9745: 1, 34443: 2, 42161: 0.25, 42220: 5, 43111: 12, 43114: 2, 57073: 2, 59144: 2, 80094: 1, 81457: 2, 421614: 0.25, 645749: 0.1, 747474: 1, 7777777: 2}

Chain avg block times.

Note that for many chains these are approximate and can vary based on network conditions and upgrades.

get_chain_homepage(chain_id)

Translate Ethereum chain id to a link to its homepage.

Returns

name, homepage link tuple

Parameters

chain_id (int) –

Return type

tuple[str, str]

get_chain_name(chain_id)

Translate Ethereum chain id to its name.

Parameters

chain_id (int) –

Return type

str

get_chain_id_by_name(name)

Get chain id by its name.

Parameters

name (str) – Case-insensitive chain name, e.g. “Ethereum”, “Polygon”, “BNB Chain”

Returns

Chain id or None if not found

Return type

Optional[int]

get_block_time(chain_id)

Get average block time for a chain.

Parameters

chain_id (int) – Chain id to get the block time for

Returns

Average block time in seconds.

Return type

float

get_default_call_gas_limit(chain_id)

Get the eth_call reasonable gas limit.

  • 15M except for Mantle 99M

  • Mantle has weird policy and all transactions and calls cost much more than other chains

Parameters

chain_id (int) –

Return type

int

install_chain_middleware(web3, poa_middleware=None, hint='')

Install any chain-specific middleware to Web3 instance.

Mainly this is POA middleware for BNB Chain, Polygon, Avalanche C-chain.

Example:

web3 = Web3(HTTPProvider(json_rpc_url))
print(f"Connected to blockchain, chain id is {web3.eth.chain_id}. the latest block is {web3.eth.block_number:,}")

# Read and setup a local private key
private_key = os.environ.get("PRIVATE_KEY")
assert private_key is not None, "You must set PRIVATE_KEY environment variable"
assert private_key.startswith("0x"), "Private key must start with 0x hex prefix"
account: LocalAccount = Account.from_key(private_key)
web3.middleware_onion.add(construct_sign_and_send_raw_middleware(account))

# Support Polygon, BNG chain
install_chain_middleware(web3)

# ... code goes here...z
tx_hash = erc_20.functions.transfer(to_address, raw_amount).transact({"from": account.address})
Parameters
  • poa_middleware

    If set, force the installation of proof-of-authority GoEthereum middleware.

    Needed e.g. when using forked Polygon with Anvil.

  • hint (str) – Optional hint for error logs when something goes wrong. Useful for debugging and logging.

  • web3 (web3.main.Web3) –

install_retry_middleware(web3)

Install gracefully HTTP request retry middleware.

In the case your Internet connection or JSON-RPC node has issues, gracefully do exponential backoff retries.

Parameters

web3 (web3.main.Web3) –

install_api_call_counter_middleware(web3)

Install API call counter middleware.

Measure total and per-API EVM call counts for your application.

  • Every time a Web3 API is called increase its count.

  • Attach web3.api_counter object to the connection

Compatible with both web3.py v6 and v7.

Example:

from eth_defi.chain import install_api_call_counter_middleware

web3 = Web3(tester)
counter = install_api_call_counter_middleware(web3)

# Make an API call
chain_id = web3.eth.chain_id
assert counter["total"] == 1
assert counter["eth_chainId"] == 1

# Make another API call
block_number = web3.eth.block_number
assert counter["total"] == 2
assert counter["eth_blockNumber"] == 1
Returns

Counter object with columns per RPC endpoint and “total”

Parameters

web3 (web3.main.Web3) –

Return type

collections.Counter

install_api_call_counter_middleware_on_provider(provider)

Install API call counter middleware on a specific API provider.

Allows per-provider API call counting when using complex provider setups.

Compatible with both web3.py v6 and v7.

See also

Returns

Counter object with columns per RPC endpoint and “total”

Parameters

provider (web3.providers.base.JSONBaseProvider) –

Return type

collections.Counter

get_graphql_url(provider)

Resolve potential GraphQL endpoint API for a JSON-RPC provider.

See has_graphql_support().

Parameters

provider (web3.providers.base.BaseProvider) –

Return type

str

has_graphql_support(provider)

Check if a node has GoEthereum GraphQL API turned on.

You can check if GraphQL has been turned on for your node with:

curl -X POST             https://mynode.example.com/graphql             -H "Content-Type: application/json"             --data '{ "query": "query { block { number } }" }'

A valid response looks like:

{"data":{"block":{"number":16328259}}}
Parameters

provider (web3.providers.base.BaseProvider) –

Return type

bool

fetch_block_timestamp(web3, block_number)

Get the block mined at timestamp.

Warning

Uses eth_getBlock. Very slow for large number of blocks. Use alternative methods for managing timestamps for large block ranges.

Example:

# Get when the first block was mined
timestamp = fetch_block_timestamp(web3, 1)
print(timestamp)
Parameters
  • web3 (web3.main.Web3) – Web3 connection

  • block_number (int) – Block number of which timestamp we are going to get

Returns

UTC naive datetime of the block timestamp

Return type

datetime.datetime