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.213.tar.gz (187.0 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.213-cp313-cp313-win_amd64.whl (867.9 kB view details)

Uploaded CPython 3.13Windows x86-64

dank_mids-4.20.213-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.213-cp313-cp313-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

dank_mids-4.20.213-cp312-cp312-win_amd64.whl (867.5 kB view details)

Uploaded CPython 3.12Windows x86-64

dank_mids-4.20.213-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.213-cp312-cp312-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

dank_mids-4.20.213-cp311-cp311-win_amd64.whl (859.5 kB view details)

Uploaded CPython 3.11Windows x86-64

dank_mids-4.20.213-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.213-cp311-cp311-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

dank_mids-4.20.213-cp310-cp310-win_amd64.whl (859.7 kB view details)

Uploaded CPython 3.10Windows x86-64

dank_mids-4.20.213-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.213-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.213.tar.gz.

File metadata

  • Download URL: dank_mids-4.20.213.tar.gz
  • Upload date:
  • Size: 187.0 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.213.tar.gz
Algorithm Hash digest
SHA256 74d02a6275f31e99663cf7f5fb1ab235021731d1f3609e7a87abcb5479407d96
MD5 cac9ac4d40cf87caad250ba791dcbf49
BLAKE2b-256 92e0a287f13a72a16092ddf330ba4224da52d95eaf7d61da3f8e0b2eb9fa5783

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 4b776a1b1d4c74e1dbbc72a23650a21812d42496a74d9db9af79af38fb8f32d4
MD5 fd03be9e7ef284fed388d05716dc4c99
BLAKE2b-256 ee09ff5d73eaac96f409ac7c6838fe54e148201fc5387ccb127447f8093556f4

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.213-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.213-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fbc8c4fb7c873ee17107d7de084b364b4c80ec23b0f04513ec2d6d29a7dd8113
MD5 b60eb7e5bb9283bb6883d9f3499dedb9
BLAKE2b-256 f8f3ab74964fff01d9146ffc9989a4e0904c8421450d9ed0e2e54852f3081575

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ca1a2d0631e894e544b7f67a937b035c7f4b6cf11b9914d072430e2c31ca12d7
MD5 04f31c7d849ed34413384fade88cfb7b
BLAKE2b-256 41e6eb875504c280b3fe9d2b893cfa52335d9f025b590d5767609e63cf15efe7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 997b5ad83ead8c52da7401db996411fc25064b7c86afbeacdb55fd6f546892e6
MD5 d1e80bcb8e08a0835b5de8699c6db098
BLAKE2b-256 0846746516e0efc6964f5cb6e0cf32a79e9dd76a9604ec4a8fa7215ea6deef70

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.213-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.213-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8ecf802ffe81dfb5819944557f30893dfb60c16195941d2b2429b7b2a15067f0
MD5 ef43da0298f3a33dee57dc8f882428e1
BLAKE2b-256 317e495d205cdabda16362b27f524c71a2077fced08bb0cc5f84077e161d11a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fd4e81e61d40c85c797b8bd8516bfb74095c3563ddc5540705856caf2eb996ee
MD5 16d05f14484f2c73944721af3aad9801
BLAKE2b-256 0639039682742fe503bf5dc82cf06204259d5b9cc1911b35b0448e81e1ff7c56

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 2aae5c9e4e228c78ad2f09d1ef3ca16310186900ea70e80c4eb9798a322c4510
MD5 857425b24089950cf2f6a55ed944d77c
BLAKE2b-256 2380e92a95ad065813fc11a62c794ef7107b8dbc1b2a6e92474ac632a81824c1

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.213-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.213-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6891047aae8f4c1896192f0e9d40746180937f55634920ca962fc63aac7fdb09
MD5 696b2e1b6fe5913151968229ae5c08e1
BLAKE2b-256 c8c25cfa8fa8466b91df9a86f9fd9c35f1e5fc984308ee48f68dfa0f05a77c1d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d38241367f2d119522a1bf0706fe3a20584b7c2075d60dd3bc22f5eb31c7083a
MD5 861794381b8862472fc82a4782e8e19b
BLAKE2b-256 dd744b76cc23d86beb6c0d4a9d11764f905007fa7b97e115a1e1ac6ee6f62708

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 315758d5b73c7bacee6d837d557ba1bebe4501c41208e4006952839e68900644
MD5 19158d6879570e605c8901d931edf50e
BLAKE2b-256 1e882d686d8090350ba73dd370ab531fd1f5f40a9ada6445104023472bb1dbc0

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.213-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.213-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 66de1dfe9d74b1ae7a7fb379a3d0f688150e8a2c6d57338cb6bc45f0af74a326
MD5 62997cdce63921a3c3db5c68eaf04f50
BLAKE2b-256 1e256827f818322f908d4bf79739fea3a1a6a7f5684e29a166792f1e04e63800

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.213-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 302b86df66fe871e7f5abcebdf665e2a0970e36d80e76c62d771e4689013a060
MD5 302e7e1f4ec017a21057375cc1d20fda
BLAKE2b-256 5a365d349cc3dd27b379eab07d16696990c57c12d84be57d22b30b50b817ac48

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