Verified ABI files, EVM chain metadata, contract addresses, token records, and pinned on-chain evidence for blockchain developers.
Uniswap v4 singleton contracts and the BSC PancakeSwap Infinity CLAMM/LBAMM
contracts are available through get_contract() and list_contracts(), including
pool managers, quoters, position managers, routers, and shared dependencies.
See singleton DEX usage for read-only state, quote,
and event decoding examples. The generated
deployment catalog lists chain coverage.
Legacy factory/router DEX deployments:
- arbitrum:
- [1] SushiSwap
- [2] Uniswap V3
- avalanche:
- base:
- [1] Aerodrome Slipstream (Gauges V3)
- [2] Uniswap V3
- [3] PancakeSwap V3
- bsc:
- [1] PancakeSwap v2
- [2] PancakeSwap v3
- [3] Uniswap V3
- bsc-test:
- cronos:
- [1] VVS Finance V2
- eth:
- [1] Uniswap V2
- [2] Uniswap V3
- monad:
- [1] Uniswap V3
- polygon:
- [1] QuickSwap
- [2] Uniswap V3
- optimism:
- [1] Uniswap V3
- [2] Velodrome Slipstream
- robinhood:
- [1] Uniswap V3
- sonic:
- unichain:
- [1] Uniswap V3
- xlayer:
- [1] Uniswap V3
Chain, token, RPC, and DEX contract entries follow the documented source and verification policy. DEX volume is used to prioritize candidates, while official deployment documentation and on-chain bytecode are required before an address is added. These checks do not replace a smart-contract security audit.
Python 3.13 or newer is required.
uv add many-abis
# pip remains supported when integrating with a non-uv project.
python -m pip install --upgrade many-abisimport many_abis as ma
# Chain, contract, and token lookups return defensive copies.
base = ma.get_chain(name="base")
router = ma.get_contract("base:dex:uniswap-v3:router")
usdc = ma.get_token("base", "USDC")
snapshot = ma.get_verification("base", usdc["address"])
print(base["chain_id"], base["rpc"])
print(router["address"], router["provenance_status"])
print(usdc["origin"], usdc["decimals"])
print(snapshot["block_number"], snapshot["runtime_code_keccak256"])
# ABI files are loaded lazily and cached as recursively read-only values.
router_abi = ma.get_abi(router["abi"])
abi_info = ma.get_abi_info(router["abi"])
print(len(router_abi), abi_info["canonical_sha256"])
print(ma.loaded_abis())
# Filter the generated catalogs without accessing the network.
print(ma.list_contracts(chain="base", role="router"))
print(ma.list_tokens(chain="base", role="stablecoin"))
print(ma.find_abis(contract_role="router"))Use copy.deepcopy() before changing an ABI. The public ABIS and CHAINS
registries are intentionally read-only so one caller cannot corrupt cached
state for the rest of a process.
To retrieve an ABI that is not bundled, use an API key from the environment and pass an EVM chain ID. The request always uses the fixed Etherscan V2 endpoint:
import os
import many_abis as ma
abi_json = ma.get_abi_from_address(
"0x2626664c2603336E57B271c5C0b26F421741e481",
os.environ["ETHERSCAN_API_KEY"],
chain_id=8453,
)Complete runnable examples cover offline catalog inspection, safe Etherscan
lookup, and optional web3.py integration in the
examples directory.
Runtime data is generated offline. Edit one reviewed source file under
registry/chains/, registry/deployments/, or registry/abi-metadata.json, then regenerate and verify:
uv sync --locked --dev
uv run python scripts/generate_registry.py --write
uv run python scripts/generate_registry.py --check
uv run python -m unittest discover -s tests -v
uv run mypyOn-chain evidence refreshes are explicit network operations and are separate from the offline generator. Refresh only through the reviewed RPC list, inspect the diff, and then regenerate:
uv run python scripts/refresh_verifications.py --chain base --write
uv run python scripts/generate_registry.py --writeDo not edit many_abis/assets/utils/chains.json, abi-index.json, generated
documentation, or many_abis/abis.pyi directly. Generation is deterministic
and never accesses the network. See the generated chain registry,
ABI provenance, and the detailed
verification policy. Usage-specific caveats for
standards, oracles, multicall, Permit2, and proxy events are documented in
common contract ABIs. API-driven bridge and
aggregator boundaries are documented in
cross-chain aggregators.
The generated contract/token catalogs, snapshot semantics, proxy limitations,
and query API are documented in
registry verification.
Pre-0.3 ABI files without complete provenance are quarantined under
registry/legacy-abis/ and are not included in the runtime package or PyPI
artifacts. Public ABIs require verified provenance, an immutable source
reference, license evidence, and required function/event signatures.
Project metadata, runtime dependencies, and development dependencies live in
pyproject.toml; uv.lock pins the complete development environment. Build
both distribution formats from a clean commit with:
uv sync --locked --dev
uv run python scripts/build_release_artifacts.py --output-dir dist
uv run python scripts/check_distribution.py dist
uv run twine check dist/*The release builder invokes uv build --no-sources twice from independent Git
archives and rejects non-identical outputs. GitHub Actions publishes the checked
artifacts with uv publish --trusted-publishing always, PyPI Trusted Publishing,
and PEP 740 attestations. Publishing requires GitHub's OIDC identity; no PyPI API
token or GitHub repository secret is needed.
-
In the GitHub repository's Settings > Environments, create an environment named
pypi. If deployment rules restrict refs, allow release tags such asv*. Required reviewers introduce a manual approval before publishing; omit them if releases should publish automatically. -
Open the PyPI project's Publishing settings and add a GitHub Trusted Publisher with these exact values:
Field Value Owner acknessRepository name many_abisWorkflow name python-publish.ymlEnvironment name pypiThe workflow name is the filename, without
.github/workflows/, rather than its display name. If the PyPI project does not exist yet, register a pending publisher in Your publishing settings with project namemany-abisand the same values.
See the official PyPI Trusted Publisher setup guide and uv GitHub Actions guide.
Commit and push the release files, including the workflow and uv.lock. Set
project.version in pyproject.toml to the new version, and refresh uv.lock
with uv lock. The runtime version comes from installed package metadata.
Create a matching tag, such as v0.5.0 for
version 0.5.0, on that commit, then publish a GitHub Release for the tag.
Pushing a tag alone or saving a draft release does not trigger publishing.
Published prereleases also trigger this workflow; use a matching prerelease
package version such as 0.5.1rc1 and tag v0.5.1rc1.
The workflow tests Python 3.13 and 3.14, checks the tag against the package
version, builds and validates the wheel and source distribution, then publishes
those artifacts from a separate job with id-token: write. A failed check
blocks publication. PyPI does not allow overwriting a published distribution;
use a new version for a changed release.
Original Python code is MIT-licensed. Bundled verified ABI data remains subject
to its recorded upstream terms. See
THIRD_PARTY_NOTICES.md
and the license texts shipped under LICENSES/. Quarantined legacy ABI files
have unresolved provenance or licensing and are not part of the distribution.