{"id":17592456,"url":"https://github.com/bobthebuidler/dank_mids","last_synced_at":"2026-03-02T11:04:58.439Z","repository":{"id":37956307,"uuid":"493012300","full_name":"BobTheBuidler/dank_mids","owner":"BobTheBuidler","description":"Async web3py middleware that collects eth calls and batches them into multicalls, then batches those multicalls into jsonrpc batches along with all your other calls in the background.","archived":false,"fork":false,"pushed_at":"2025-04-05T15:47:31.000Z","size":7665,"stargazers_count":86,"open_issues_count":7,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-10T00:17:22.718Z","etag":null,"topics":["asyncio","ethereum","evm","jsonrpc","multicall","python","web3","web3py"],"latest_commit_sha":null,"homepage":"https://bobthebuidler.github.io/dank_mids/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BobTheBuidler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-05-16T22:01:16.000Z","updated_at":"2025-04-05T14:12:15.000Z","dependencies_parsed_at":"2024-01-14T00:52:08.617Z","dependency_job_id":"7c0e1a98-53ec-426c-bdbb-f915db58872e","html_url":"https://github.com/BobTheBuidler/dank_mids","commit_stats":null,"previous_names":[],"tags_count":133,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobTheBuidler%2Fdank_mids","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobTheBuidler%2Fdank_mids/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobTheBuidler%2Fdank_mids/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobTheBuidler%2Fdank_mids/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BobTheBuidler","download_url":"https://codeload.github.com/BobTheBuidler/dank_mids/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248131318,"owners_count":21052820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncio","ethereum","evm","jsonrpc","multicall","python","web3","web3py"],"created_at":"2024-10-22T05:22:54.557Z","updated_at":"2026-02-16T23:47:00.494Z","avatar_url":"https://github.com/BobTheBuidler.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dank Mids\n\n[![PyPI](https://img.shields.io/pypi/v/dank-mids.svg?logo=Python\u0026logoColor=white)](https://pypi.org/project/dank-mids)\n[![Monthly Downloads](https://img.shields.io/pypi/dm/dank-mids)](https://pypistats.org/packages/dank-mids)\n\nDank 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](https://github.com/makerdao/multicall#multicall-) and bundles all RPC calls together in [jsonrpc](https://www.jsonrpc.org/specification#batch) [batch](https://geth.ethereum.org/docs/interacting-with-geth/rpc/batch) calls. \n\n##### tl;dr: its fast as fuck.\n\n![image](https://github.com/BobTheBuidler/dank_mids/assets/70677534/3ecb46aa-f33a-41bd-85fb-c6d2433c7154)\n\nThe 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.\n\n![](https://i.imgur.com/o9FUmAn.jpg)\n\n### Why is Dank so fast?\n\nThere are a number of optimizations that went into making Dank the fastest way to pull rpc data to Python.\n1. Implemented (mostly) in C.\n2. Bypasses the default formatters in [web3.py](https://github.com/ethereum/web3.py)\n3. JSON encoding and decoding is handled by [msgspec](https://jcristharif.com/msgspec/). All responses are decoded to specialized [msgspec.Struct](https://jcristharif.com/msgspec/structs.html) objects defined in the [evmspec](https://github.com/BobTheBuidler/evmspec) library.\n4. We use my C-compiled [faster-eth-abi](https://github.com/BobTheBuidler/faster-eth-abi/tree/master) and [faster-eth-utils](https://github.com/BobTheBuidler/faster-eth-utils/tree/master) instead of the original python implementations [eth-abi](https://github.com/ethereum/eth-abi) and [eth-utils](https://github.com/ethereum/eth-utils).\n5. 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. \n6. more stuff I'll write down later...\n\n### Batching Flow\n\nThis diagram shows how requests move from user calls into Dank Mids queues, then through batch execution and response spoofing.\n\n```mermaid\nflowchart TD\n    A[User code\u003cbr/\u003eawait w3.eth.call / other RPC] --\u003e B[DankMiddlewareController.__call__]\n\n    B --\u003e|eth_call| C[eth_call request]\n    B --\u003e|other RPC| D[RPCRequest]\n\n    C --\u003e|multicall compatible| E[pending_eth_calls\u003cbr/\u003eblock to Multicall]\n    C --\u003e|no multicall| D\n    D --\u003e F[pending_rpc_calls\u003cbr/\u003eJSONRPCBatch queue]\n\n    E --\u003e G[RPCRequest.get_response\u003cbr/\u003etriggers execute_batch when needed]\n    F --\u003e G\n\n    G --\u003e H[DankMiddlewareController.execute_batch]\n    H --\u003e I[DankBatch\u003cbr/\u003emulticalls + rpc_calls]\n    I --\u003e J[DankBatch.coroutines]\n\n    J --\u003e|large multicall| K[Multicall.get_response]\n    J --\u003e|small multicall split| L[JSONRPCBatch]\n    J --\u003e|rpc calls| L\n\n    K --\u003e M[_requester.post\u003cbr/\u003eeth_call to multicall contract]\n    M --\u003e N[Multicall.spoof_response\u003cbr/\u003esplit results to eth_call futures]\n\n    L --\u003e O[JSONRPCBatch.post\u003cbr/\u003ebuild JSON-RPC batch payload]\n    O --\u003e P[_requester.post batch\u003cbr/\u003e+ decode responses]\n    P --\u003e Q[JSONRPCBatch.spoof_response\u003cbr/\u003ematch by id, resolve futures]\n\n    N --\u003e R[User awaiters resolve]\n    Q --\u003e R\n```\n\nNotes:\n- Batches can start early when the queue is full (`_Batch.append` -\u003e `controller.early_start`).\n- Otherwise, the first waiter to need results will trigger `execute_batch` from `RPCRequest.get_response`.\n\n### Installation\n\nTo install Dank Mids, use pip:\n\n`pip install dank-mids`\n\n### Benchmark\n\nWe've included a [benchmark script](./examples/benchmark.py) 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 `poetry install` and then run the benchmark with `brownie run examples/benchmark`.\n\n```\nRunning 'examples/benchmark.py::main'...\n100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [08:50\u003c00:00,  7.95it/s]\nbrownie sync end: 2025-04-14 21:21:35.531099\nbrownie sync took: 0:08:50.212665\nbrownie 4 threads start: 2025-04-14 21:21:35.548373\n100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [08:31\u003c00:00,  8.23it/s]\nbrownie 4 threads end: 2025-04-14 21:30:08.065397\nbrownie 4 threads took: 0:08:32.517024\nbrownie 16 threads start: 2025-04-14 21:30:08.086342\n100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [08:26\u003c00:00,  8.32it/s]\nbrownie 16 threads end: 2025-04-14 21:38:38.141635\nbrownie 16 threads took: 0:08:30.055293\ndank start: 2025-04-14 21:38:38.161024\n100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4213/4213 [00:55\u003c00:00, 75.49it/s]\ndank end: 2025-04-14 21:39:33.982835\ndank took: 0:00:55.821811\n```\n\nAs 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!\n\n### Usage with web3.py\n\nThe 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\n\nExample usage of Dank Mids with web3py:\n\n```python\nfrom dank_mids.helpers import setup_dank_w3_from_sync\ndank_web3 = setup_dank_w3_from_sync(w3)\n# OR\nfrom dank_mids import dank_web3\n\n# Then:\nrandom_block = await dank_web3.eth.get_block(123)\n```\n\n### Usage with eth-brownie\n\n- [Dank Brownie Example Commented Code](./examples/dank_brownie_example.py)\n\n### Usage with ape\n\n- COMING SOON: Dank Mids will also work with [ape](https://github.com/ApeWorX/ape).\n\n### Testimonials\n\n[Yearn](https://yearn.finance) big brain [Tonkers Kuma](https://github.com/tonkers-kuma) had this to say:\n\n![image](https://user-images.githubusercontent.com/70677534/211255488-e76e641c-a0fe-461c-a4e5-27c45a3fea5b.png)\n\n### Notes\n\nYou can also set `DANK_MIDS_DEMO_MODE=True` to see a visual representation of the batching in real time on your console.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbobthebuidler%2Fdank_mids","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbobthebuidler%2Fdank_mids","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbobthebuidler%2Fdank_mids/lists"}