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.212.tar.gz (186.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.212-cp313-cp313-win_amd64.whl (867.1 kB view details)

Uploaded CPython 3.13Windows x86-64

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

Uploaded CPython 3.13macOS 11.0+ ARM64

dank_mids-4.20.212-cp312-cp312-win_amd64.whl (866.8 kB view details)

Uploaded CPython 3.12Windows x86-64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

dank_mids-4.20.212-cp311-cp311-win_amd64.whl (858.5 kB view details)

Uploaded CPython 3.11Windows x86-64

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

Uploaded CPython 3.11macOS 11.0+ ARM64

dank_mids-4.20.212-cp310-cp310-win_amd64.whl (858.8 kB view details)

Uploaded CPython 3.10Windows x86-64

dank_mids-4.20.212-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.212-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.212.tar.gz.

File metadata

  • Download URL: dank_mids-4.20.212.tar.gz
  • Upload date:
  • Size: 186.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.212.tar.gz
Algorithm Hash digest
SHA256 dd642056a1cb7511ee1fa0543b2f004678bb4196da0b2b65a20ce0b0cf80e14e
MD5 d5f9fc37d5710cc2d055ada19bbaffe5
BLAKE2b-256 017dbf56fb8565563370bf0b43ba1eb2c1574d11391b7d009c90b55864bf6c39

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 d0fa009cf0a8624a58d42df55bb7fcecf2078b1d8dffab30827521e7b6946201
MD5 2e7e764fc34716553150dfe682d46e18
BLAKE2b-256 5201b12e1372b3c211c799781670463d179e330ffc409effdf9a62999cb66ef1

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.212-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.212-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 34dac283a78c68b117b8f7db150e2ac130faaaa6eaa8912f6f9414009c605597
MD5 f8d5b496549901645d854d92fdf754a9
BLAKE2b-256 bc2f76c4a85dfcd46a0b23370360a1b5f1c13f020ffc346ef8038b1a24309314

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f5f7fce85dc679720b918e8e8cb1490ca2074a638412f2d2998637c93372e506
MD5 fb2381fa2cb760fe0b72c722fa1c7952
BLAKE2b-256 74eb4dcdda36177477d16b68073c1fc21c2c84cdb891309d79c1c26627de9e0c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 472dba309a8addedee3bf80a4a6dbb1de8506342b2da882a96a48cf939814d1e
MD5 8521bb50cb4b5148789d902217e816af
BLAKE2b-256 9aca9704b0f419b51b493def5270154900bb97b11a9f920363f1b70c8c3f8dbf

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.212-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.212-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5c1842c52b8d104c88e608beecf1c1305462d7fcdb09173a9b4efedd901ba0ac
MD5 cd29e63162a8f9136d0a10437e3c6cee
BLAKE2b-256 027a738fb11ed7096930f6c91f7c07240cbbe05689cf653017019dc5b3762b9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4addd612b3d58b154a192acdd8cdd6411a10d19387ed287540f2ea57399292d3
MD5 a9c8504cfe129ae5ca864ad66ddde23f
BLAKE2b-256 16799e62f2737e7ca8a555599627506f390a0b717f8791e0a69f444be128568e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 e1cb0fe16bf8a8f20e33f503d5f6a4aee81e03285f3914d262e6c62e30dd6681
MD5 e97ccd8ca227a10e704d03093e8f7737
BLAKE2b-256 a02631f99025a05e44594cb00259b32dd924f129ff5646817b3a2f720b9d19e9

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.212-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.212-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e8834e9861de70a3acb90455f65e378a88fab3836a6c0d5478f8db2c85942daa
MD5 8b5c8e57531fefb10c5783f791552212
BLAKE2b-256 ee90b70e6bb119b9c69a665c801b8d8b6d8721290b55c0760a9ce28344ee2836

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b310ec9776d8d2a0c29c5fb1f778af36cecdb6b543af792f7857467b83742961
MD5 d0fa9d9aac7ff06b034d7542a82c7f8b
BLAKE2b-256 c496c967f70a89c927fc99ebd4310fec10f75bb73d8b5ae9402d2eca3264c043

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 87c2a3fdd7c1b1b674e3c1069418e4bcc8dd9185e5637a6adaf3d3ce4dfcced3
MD5 091d1ac9bcdf69e4aee265680327f60c
BLAKE2b-256 a091333f3c663726baaa8bf81225944b2321a729ef5300ae8db727f76823648a

See more details on using hashes here.

File details

Details for the file dank_mids-4.20.212-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.212-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ca6363a49d28a011dc48e3705c64a55be4eedb6dd18dd8a01de1dca4d210da82
MD5 641d0eeccd73ee67fe14eaea10605da5
BLAKE2b-256 7083bcf6aaae359a46ea928b151ed25409c1f63e39aeeb75f859c7f9e48cbfa2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dank_mids-4.20.212-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9d1bc51eea8b5985bd2d956922863fb9326113f2f9b095a9c95c1d8bb54e5869
MD5 302e0b1581fba36a4084d222670a3e68
BLAKE2b-256 66e836ce05b00232bc3e612b0055578fe1ed746ba8e13f220a0f1d2431d171b6

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