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.209.tar.gz (185.6 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.209-cp313-cp313-win_amd64.whl (861.2 kB view details)

Uploaded CPython 3.13Windows x86-64

dank_mids-4.20.209-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.6 MB view details)

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

dank_mids-4.20.209-cp313-cp313-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

dank_mids-4.20.209-cp312-cp312-win_amd64.whl (860.1 kB view details)

Uploaded CPython 3.12Windows x86-64

dank_mids-4.20.209-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.6 MB view details)

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

dank_mids-4.20.209-cp312-cp312-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

dank_mids-4.20.209-cp311-cp311-win_amd64.whl (852.7 kB view details)

Uploaded CPython 3.11Windows x86-64

dank_mids-4.20.209-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.5 MB view details)

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

dank_mids-4.20.209-cp311-cp311-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

dank_mids-4.20.209-cp310-cp310-win_amd64.whl (853.3 kB view details)

Uploaded CPython 3.10Windows x86-64

dank_mids-4.20.209-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.209-cp310-cp310-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: dank_mids-4.20.209.tar.gz
  • Upload date:
  • Size: 185.6 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.209.tar.gz
Algorithm Hash digest
SHA256 986af334206e9a7e96ab5871996e090070e0733ff3b2b2d2af2d0418f61d0472
MD5 2b7bf45b9f8421a7f507c2253b25ea02
BLAKE2b-256 0e0509784a365f8a3826d693dfc575e812e79bec7c94c8a86dee2412401c0cc9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 8418d79474544bef3c49e7b7c6cd2bd9dd498844373849d17983915de4087501
MD5 d25f70a0a895d97ba96bfe70021b37fb
BLAKE2b-256 10ac12e3cbbb00f448a10631998052e1fb05f6f73c2c267d1152acafca445ec4

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.209-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.209-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0ea15aa4eacbf0b9802dd50de3397e30a44ea946eb9f2bd72aba6848352a88e5
MD5 f65bb0eeee79f2021dfada55dde93b33
BLAKE2b-256 09089e655118325c9022cead8a0e083c60b8a0d93936570ee432749dadfeb4fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 587de8c53d59438712fce9ebd67e8dd42d7ea5ab8f3de8c4a2a044a75b8ce7a3
MD5 bedcba4a1b837ff0228e631be8e51444
BLAKE2b-256 b26d0476634e7f3bf49cb1646c5b6f8cdbaff7bc31015bbc6f612d69e1f00eb3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 8a82155903d7ca1573fd0fd971d951984dced63e8cedf1f9525ad27404f1b92c
MD5 7db58013d59a53eb306125b22099c8a2
BLAKE2b-256 74d9d0abe175c2033245bf00050a6e362b57c72734258f36f7e61a81ff480485

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.209-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.209-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 16066d6f1822b13f25cc5c2d73e073e486b7d6c6b0d0b2c4193bab3c0be05464
MD5 ae2eb379ebbea27771b9f5eb6aace6bb
BLAKE2b-256 1dc9db56f73779ab83cc6c55a0fa29323c82d058a9170d66485b86a849c7e65e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 20a3f885d146c97bf9050e8ea4e3743c1afcb352807948bebe64df61d5765e04
MD5 b02600f8f7cfeaf7bf1d4693cff120ca
BLAKE2b-256 fa02ec4025839a4cf3a584826271e17071539dc3b9b9140077160e8462f4f3db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 71338b887d31a7cc1278d0d0cef32a682257db486bdf1f9dbb6b9162556d9bb3
MD5 b9180129c866801f83825b015980f778
BLAKE2b-256 5fca00853385ca5526db3a811156b66ca151a67c8ec43f2d36695a0f3a38f3e4

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.209-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.209-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1b86c863bf01f8c5664d9da79e400f61bdbabb3f131e3f196a832610df15adfa
MD5 5f72bd2c1371f64ecc22b1ccf98b1561
BLAKE2b-256 2ee5a056288e7d0172f732b730b6d1f50b4fbfcedda23ab9cabc7bf0a16e089d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fb345fe64b000a62c4548985b679c487c7d902c69967ebb9d5007debed692a0d
MD5 d5e5f649f8ef4d52ae87f2afe6676d91
BLAKE2b-256 ce0f0b1a28e7930441df7c54af64712ac5bafb07a04c744ef75a02f4dc9351c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 dfa05eb92e44fed30d06182aea1b07e7e468ae2befb9301c577d429a52c29185
MD5 10562ced9cf973156312b8d99e663fd4
BLAKE2b-256 0f67705663d2e0ef44c3b1ebe682f2775a850cc9f0103fc59b2adc657e90680b

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.209-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.209-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c953b6131447b78d6a339b82e3df0abac8f7835f1bb51d1eab4d283dd52c8b08
MD5 9612ac4ea8f4ed53393b8f5a4bf02ba6
BLAKE2b-256 d0190d78553dd17ab88e8c032654cfc2dd070b54ebf51651b5fa7b801d59fc52

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.209-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 579e2f0055e565ebdd19ffc9713c20700a0c2c6a6f6c4f8587c92c119f720a95
MD5 e79e3047566c22630efb109fc9fc4469
BLAKE2b-256 ddfdeffcc33eaa94f513498b37a3c7620f9e9715a00e97f569d563a4667c6a27

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