From 7b8a9ad1662c87c877900af87c41307844208155 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 24 Feb 2024 06:57:56 +0000 Subject: [PATCH 1/4] feat: dank_web3 convenience obj --- dank_mids/__init__.py | 4 ++++ dank_mids/brownie_patch/__init__.py | 11 ++++++++++- dank_mids/helpers/helpers.py | 4 ++-- tests/fixtures.py | 5 ----- tests/test_brownie_patch.py | 11 +++++------ tests/test_dank_mids.py | 15 +++++++-------- 6 files changed, 28 insertions(+), 22 deletions(-) delete mode 100644 tests/fixtures.py diff --git a/dank_mids/__init__.py b/dank_mids/__init__.py index 0b501f1a..5b253259 100644 --- a/dank_mids/__init__.py +++ b/dank_mids/__init__.py @@ -3,6 +3,10 @@ from dank_mids.helpers import setup_dank_w3, setup_dank_w3_from_sync from dank_mids.middleware import dank_middleware +try: + from dank_mids.brownie_patch import dank_web3, patch_contract +except ImportError: + pass def _configure_concurrent_future_work_queue_size(): import concurrent.futures.process as _cfp diff --git a/dank_mids/brownie_patch/__init__.py b/dank_mids/brownie_patch/__init__.py index 0ef4767c..f72846ed 100644 --- a/dank_mids/brownie_patch/__init__.py +++ b/dank_mids/brownie_patch/__init__.py @@ -1,2 +1,11 @@ -from dank_mids.brownie_patch.contract import patch_contract +from dank_mids.helpers import setup_dank_w3_from_sync + +# If using dank_mids wih brownie, and brownie is connected when this file executes, you will get a 'dank_w3' async web3 instance with Dank Middleware here. +try: + from brownie import network, web3 + if network.is_connected(): + from dank_mids.brownie_patch.contract import patch_contract + dank_web3 = setup_dank_w3_from_sync(web3) +except ImportError: + pass \ No newline at end of file diff --git a/dank_mids/helpers/helpers.py b/dank_mids/helpers/helpers.py index 136db48b..8859a8b7 100644 --- a/dank_mids/helpers/helpers.py +++ b/dank_mids/helpers/helpers.py @@ -60,7 +60,7 @@ async def set_done_wrap(self: "RPCRequest", *args: P.args, **kwargs: P.kwargs) - retval = await fn(self, *args, **kwargs) self._done.set() return retval - return set_done_wrap + return set_done_wrap # Everything below is in web3.py now, but dank_mids currently needs a version that predates them. @@ -165,4 +165,4 @@ def _format_response( elif "error" in response and method in error_formatters: return _format_response("error", error_formatters[method]) else: - return response \ No newline at end of file + return response diff --git a/tests/fixtures.py b/tests/fixtures.py deleted file mode 100644 index 4cc1e070..00000000 --- a/tests/fixtures.py +++ /dev/null @@ -1,5 +0,0 @@ - -from brownie import web3 -from dank_mids import setup_dank_w3_from_sync - -dank_w3 = setup_dank_w3_from_sync(web3) diff --git a/tests/test_brownie_patch.py b/tests/test_brownie_patch.py index 8df727b4..3597dbcb 100644 --- a/tests/test_brownie_patch.py +++ b/tests/test_brownie_patch.py @@ -4,23 +4,22 @@ from brownie import Contract, web3 from multicall.utils import await_awaitable -from dank_mids import setup_dank_w3_from_sync +from dank_mids import dank_web3, setup_dank_w3_from_sync from dank_mids.brownie_patch import patch_contract from dank_mids.brownie_patch.call import _patch_call -from tests.fixtures import dank_w3 def test_patch_call(): # must use from_explorer for gh testing workflow weth = Contract.from_explorer('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') - _patch_call(weth.totalSupply, dank_w3) + _patch_call(weth.totalSupply, dank_web3) assert hasattr(weth.totalSupply, 'coroutine') assert await_awaitable(weth.totalSupply.coroutine(block_identifier=13_000_000)) == 6620041514474872981393155 def test_gather(): # must use from_explorer for gh testing workflow weth = Contract.from_explorer('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') - _patch_call(weth.totalSupply, dank_w3) + _patch_call(weth.totalSupply, dank_web3) assert hasattr(weth.totalSupply, 'coroutine') for result in await_awaitable(asyncio.gather(*[weth.totalSupply.coroutine(block_identifier=13_000_000) for _ in range(10_000)])): assert result == 6620041514474872981393155 @@ -28,13 +27,13 @@ def test_gather(): def test_patch_contract(): # ContractCall # must use from_explorer for gh testing workflow - weth = patch_contract(Contract.from_explorer('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'), dank_w3) + weth = patch_contract(Contract.from_explorer('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'), dank_web3) assert hasattr(weth.totalSupply, 'coroutine') assert await_awaitable(weth.totalSupply.coroutine(block_identifier=13_000_000)) == 6620041514474872981393155 # ContractTx # must use from_explorer for gh testing workflow - uni_v3_quoter = patch_contract(Contract.from_explorer('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6'), dank_w3) + uni_v3_quoter = patch_contract(Contract.from_explorer('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6'), dank_web3) assert hasattr(uni_v3_quoter.quoteExactInput, 'coroutine') assert await_awaitable( uni_v3_quoter.quoteExactInput.coroutine(b"\xc0*\xaa9\xb2#\xfe\x8d\n\x0e\\O'\xea\xd9\x08 Date: Fri, 24 Mar 2023 01:09:21 +0000 Subject: [PATCH 2/4] fix(test): adapt tests to new dank_web3 object --- tests/test_brownie_patch.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_brownie_patch.py b/tests/test_brownie_patch.py index 3597dbcb..f3534ec0 100644 --- a/tests/test_brownie_patch.py +++ b/tests/test_brownie_patch.py @@ -4,8 +4,7 @@ from brownie import Contract, web3 from multicall.utils import await_awaitable -from dank_mids import dank_web3, setup_dank_w3_from_sync -from dank_mids.brownie_patch import patch_contract +from dank_mids import dank_web3, patch_contract, setup_dank_w3_from_sync from dank_mids.brownie_patch.call import _patch_call From 45ed96b4e6a79330e2f243ca81f07773d1bc205a Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Fri, 24 Mar 2023 01:12:02 +0000 Subject: [PATCH 3/4] chore: update readme --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 28dddd75..3612e296 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,18 @@ To install Dank Mids, use pip: ### 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. +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: ```python -from dank_mids import setup_dank_w3_from_sync -dank_w3 = setup_dank_w3_from_sync(w3) -random_block = await dank_w3.eth.get_block(123) +from dank_mids.helpers import setup_dank_w3_from_sync +dank_web3 = setup_dank_w3_from_sync(w3) +# OR +from dank_mids.helpers import dank_web3 + +# Then: +random_block = await dank_web3.eth.get_block(123) ``` ### Usage with eth-brownie From f2a5e0f645c54bd3acd9b1276a081b9173187d7d Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Fri, 24 Mar 2023 01:14:22 +0000 Subject: [PATCH 4/4] feat: adapt patch_contract fn to new dank_web3 helper --- dank_mids/brownie_patch/contract.py | 11 +++++------ tests/test_brownie_patch.py | 4 +++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/dank_mids/brownie_patch/contract.py b/dank_mids/brownie_patch/contract.py index 4c89663a..b3a2838c 100644 --- a/dank_mids/brownie_patch/contract.py +++ b/dank_mids/brownie_patch/contract.py @@ -2,7 +2,7 @@ from types import MethodType from typing import Optional, Union -from brownie import Contract, network, web3 +from brownie import Contract, network from brownie.network.contract import ContractCall, ContractTx, OverloadedMethod from web3 import Web3 @@ -17,11 +17,10 @@ def _patch_if_method(method: ContractMethod, w3: Web3) -> None: elif isinstance(method, OverloadedMethod): _patch_overloaded_method(method, w3) - -def patch_contract(contract: Contract, w3: Optional[Web3]) -> Contract: - if w3 is None and network.is_connected(): - w3 = web3 - assert w3 is not None, "You must make sure either brownie is connected or you pass in a Web3 instance." +def patch_contract(contract: Contract, w3: Optional[Web3] = None) -> Contract: + if w3 is None: + assert network.is_connected(), "You must make sure either brownie is connected or you pass in a Web3 instance." + from dank_mids.helpers import dank_web3 as w3 for k, v in contract.__dict__.items(): _patch_if_method(v, w3) return contract diff --git a/tests/test_brownie_patch.py b/tests/test_brownie_patch.py index f3534ec0..64536d8e 100644 --- a/tests/test_brownie_patch.py +++ b/tests/test_brownie_patch.py @@ -26,13 +26,15 @@ def test_gather(): def test_patch_contract(): # ContractCall # must use from_explorer for gh testing workflow + # specify w3 weth = patch_contract(Contract.from_explorer('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'), dank_web3) assert hasattr(weth.totalSupply, 'coroutine') assert await_awaitable(weth.totalSupply.coroutine(block_identifier=13_000_000)) == 6620041514474872981393155 # ContractTx # must use from_explorer for gh testing workflow - uni_v3_quoter = patch_contract(Contract.from_explorer('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6'), dank_web3) + # dont specify w3 + uni_v3_quoter = patch_contract(Contract.from_explorer('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6')) assert hasattr(uni_v3_quoter.quoteExactInput, 'coroutine') assert await_awaitable( uni_v3_quoter.quoteExactInput.coroutine(b"\xc0*\xaa9\xb2#\xfe\x8d\n\x0e\\O'\xea\xd9\x08