Skip to main content

Multicall batching middleware for asynchronous scripts using web3.py

Project description

Dank Mids

PyPI Monthly Downloads

Dank Mids is a EVM RPC batching library that helps reduce the number of HTTP requests to a node, saving time and resources. It automatically collects eth_call calls into multicalls and bundles all RPC calls together in jsonrpc batch calls.

tl;dr: its fast as fuck.

image

The goal of this tool is to reduce the workload on RPC nodes and allow users to make calls to their preferred node more efficiently. This optimization is especially useful for developers writing scripts that perform large-scale blockchain analysis, as it can save development time and resources.

Why is Dank so fast?

There are a number of optimizations that went into making Dank the fastest way to pull rpc data to Python.

  1. Implemented (mostly) in C.
  2. Bypasses the default formatters in web3.py
  3. JSON encoding and decoding is handled by msgspec. All responses are decoded to specialized msgspec.Struct objects defined in the evmspec library.
  4. We use my C-compiled faster-eth-abi and faster-eth-utils instead of the original python implementations eth-abi and eth-utils.
  5. Responses are decoded on a JIT (just-in-time) basis, meaning individual task cancellation works as expected even when response data is received as part of a larger batch.
  6. more stuff I'll write down later...

Batching Flow

This diagram shows how requests move from user calls into Dank Mids queues, then through batch execution and response spoofing.

flowchart TD
    A[User code<br/>await w3.eth.call / other RPC] --> B[DankMiddlewareController.__call__]

    B -->|eth_call| C[eth_call request]
    B -->|other RPC| D[RPCRequest]

    C -->|multicall compatible| E[pending_eth_calls<br/>block to Multicall]
    C -->|no multicall| D
    D --> F[pending_rpc_calls<br/>JSONRPCBatch queue]

    E --> G[RPCRequest.get_response<br/>triggers execute_batch when needed]
    F --> G

    G --> H[DankMiddlewareController.execute_batch]
    H --> I[DankBatch<br/>multicalls + rpc_calls]
    I --> J[DankBatch.coroutines]

    J -->|large multicall| K[Multicall.get_response]
    J -->|small multicall split| L[JSONRPCBatch]
    J -->|rpc calls| L

    K --> M[_requester.post<br/>eth_call to multicall contract]
    M --> N[Multicall.spoof_response<br/>split results to eth_call futures]

    L --> O[JSONRPCBatch.post<br/>build JSON-RPC batch payload]
    O --> P[_requester.post batch<br/>+ decode responses]
    P --> Q[JSONRPCBatch.spoof_response<br/>match by id, resolve futures]

    N --> R[User awaiters resolve]
    Q --> R

Notes:

  • Batches can start early when the queue is full (_Batch.append -> controller.early_start).
  • Otherwise, the first waiter to need results will trigger execute_batch from RPCRequest.get_response.

Installation

To install Dank Mids, use pip:

pip install dank-mids

Development and Contributing

This repository uses pre-commit for local commit-time checks. Setup and usage instructions live in CONTRIBUTING.md.

Benchmark

We've included a benchmark script that compares the time it takes to fetch the pool tokens (token0 and token1) for each pool on Sushiswap on Ethereum mainnet. To run it, first install the repo with uv sync and then run the benchmark with uv run brownie run examples/benchmark.

Running 'examples/benchmark.py::main'...
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [08:50<00:00,  7.95it/s]
brownie sync end: 2025-04-14 21:21:35.531099
brownie sync took: 0:08:50.212665
brownie 4 threads start: 2025-04-14 21:21:35.548373
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [08:31<00:00,  8.23it/s]
brownie 4 threads end: 2025-04-14 21:30:08.065397
brownie 4 threads took: 0:08:32.517024
brownie 16 threads start: 2025-04-14 21:30:08.086342
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [08:26<00:00,  8.32it/s]
brownie 16 threads end: 2025-04-14 21:38:38.141635
brownie 16 threads took: 0:08:30.055293
dank start: 2025-04-14 21:38:38.161024
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [00:55<00:00, 75.49it/s]
dank end: 2025-04-14 21:39:33.982835
dank took: 0:00:55.821811

As you can see, dank_mids allowed us to save 7 minutes and 34 seconds vs brownie with 16 threads. That's an 89% reduction in runtime, or about 9x as fast as brownie!

Usage with web3.py

The primary function you need to use Dank Mids is setup_dank_w3_from_sync. This function takes a sync Web3 instance and wraps it for async use. If using dank_mids with eth-brownie, you can just import the premade dank_web3 object as well

Example usage of Dank Mids with web3py:

from dank_mids.helpers import setup_dank_w3_from_sync
dank_web3 = setup_dank_w3_from_sync(w3)
# OR
from dank_mids import dank_web3

# Then:
random_block = await dank_web3.eth.get_block(123)

Usage with eth-brownie

Usage with ape

  • COMING SOON: Dank Mids will also work with ape.

Observability (Retry Events)

Dank Mids exposes a retry observer API for capturing retry decisions, plus a stats observer for collector metrics. Internal emit points are deferred to a follow-up PR. For the full explanation and examples (structured logging, Prometheus, Sentry/Stats), see docs/retry_observer.rst.

Testimonials

Yearn big brain Tonkers Kuma had this to say:

image

Notes

You can also set DANK_MIDS_DEMO_MODE=True to see a visual representation of the batching in real time on your console.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dank_mids-4.20.211.tar.gz (185.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

dank_mids-4.20.211-cp313-cp313-win_amd64.whl (887.5 kB view details)

Uploaded CPython 3.13Windows x86-64

dank_mids-4.20.211-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

dank_mids-4.20.211-cp313-cp313-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

dank_mids-4.20.211-cp312-cp312-win_amd64.whl (886.6 kB view details)

Uploaded CPython 3.12Windows x86-64

dank_mids-4.20.211-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

dank_mids-4.20.211-cp312-cp312-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

dank_mids-4.20.211-cp311-cp311-win_amd64.whl (878.1 kB view details)

Uploaded CPython 3.11Windows x86-64

dank_mids-4.20.211-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

dank_mids-4.20.211-cp311-cp311-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

dank_mids-4.20.211-cp310-cp310-win_amd64.whl (878.5 kB view details)

Uploaded CPython 3.10Windows x86-64

dank_mids-4.20.211-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

dank_mids-4.20.211-cp310-cp310-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file dank_mids-4.20.211.tar.gz.

File metadata

  • Download URL: dank_mids-4.20.211.tar.gz
  • Upload date:
  • Size: 185.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dank_mids-4.20.211.tar.gz
Algorithm Hash digest
SHA256 5824609dae061854b7dafc88d2f3a248dedc4a65b50ba9c1f75d53444aabfd24
MD5 cd74a14ae422305794c0f2593180866a
BLAKE2b-256 282696dc1315aa4114e7ac9bcd670011e9bbab32371bec25709d9c82aa68f215

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 a0318326a656fda0eb8738d065fa4c359caeb8366b50987d506e6cca4f956ce1
MD5 ef2aacc9ba5851fb404860d1135ac795
BLAKE2b-256 a810219c59ab4aba90e7e6aa8f23b94015519569b3bdd040f2847c22d2aaefd1

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fe2f80a772ebad3def99571a3df191f3cceb2445ab6364fbc26c5eb7c7430c93
MD5 911a4cf21067337bc497151985367e95
BLAKE2b-256 61f0b7f7431e31d6a7277c75130799ffa3ebebed17eba1fd46831fef36d229a8

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f368a3b85cc280788836e5aeed90dd1451ffa58c825ba89decbf4369ea0c7a22
MD5 5e8dc5d94f5b899fd2f780604ef4763c
BLAKE2b-256 9bdc260bbe332e924be5322cb3d2d48b66eee861a1e3eefc8d3d1264c3afd78f

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d95ce755b9103b64d8e84f0dd616c8f4e04ee9390c68dcecdfa03d9d3c0b6339
MD5 599c7a2d753654c7ec5341c86fcd3300
BLAKE2b-256 e94ff239fc23e3c59733d28fed8e737b676d999829291534dc2f155fec7f5306

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0aa22199d825fe735e68edd5192ff2b759aeee903b32812878f13a1958c894a7
MD5 07b62987a863bc759c90eebfdc0f6f7c
BLAKE2b-256 dc5369780ffe95c3503196d847ff33fac6da44509e03c210bd83f267067c53b8

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 136e0a91d31aef8be2e8f8302c0451302c045a1747644692821c50b53f1be504
MD5 c9e7eafe5e9b137809472695d10cdc27
BLAKE2b-256 6d02dcbf7c7e3fb3503fb43b3ea390e78a9dad4cddd280832be54b0cfd24d1bf

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 c5e37207302982db4643de578db2437c8b1cbc254165fa70dbcbec38e854561f
MD5 5d60c573601a9ae906cc1cee39b17762
BLAKE2b-256 b7652a4583c6582f086bf185ebba4f69313740828badac8812bf05136d6caec0

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c28c9645273662578a5636022c906f3411e1fbfcf3eef59cdca3e33c24378b4a
MD5 8f7c03c13253ce2260c634e9185b74dd
BLAKE2b-256 000a84ac1de34d0f60e71711c61051cd9b92f8bb05c0d577362ca4b03fc952a2

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8045f546f16ca9464560d36b42123b4cd3d011dd9320825e9c74b83f3785ebbc
MD5 22bbfb61b4c2dc099739dfb0fa8ffa30
BLAKE2b-256 93e35db96b8c78cf3b8897b9b549ee65cd6fa16b62e53c130a0e28235437e422

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 9510c4ecfe9da74aeef5a400f55a10e2e55066bc0ee502b381a4fe72ed41a803
MD5 adaa8d100dc560feaa15c4a060c7aee9
BLAKE2b-256 9062269aede4b0500bed01afc113dba736aabea79109da64496637db552b52fd

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e991d79432080553bf2d12eb17487462ed99ff77322145391190b60c0bea111c
MD5 32c26a2145042276839c18f8282c3b39
BLAKE2b-256 c0526241e26e4d3ee4e5ae0202e51203fb99df1aa2ee962516f8bcc1d3e7c255

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.211-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for dank_mids-4.20.211-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 54685ed8928851de9a568216ff3b8afdf7dd7dff822fb0183326a3d7725b2100
MD5 c0f658d2fee012efcf5190e624907758
BLAKE2b-256 11e0a5e53eb3515037d979054b006be5d563d18d2393f47427a79865689d86ad

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page