From 2fa51a02cddb5ea0482338e07a378b18dbc26375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Tue, 4 Jan 2022 12:25:48 +0100 Subject: [PATCH 01/21] build(deps): readded pytest-dotenv to dev deps --- poetry.lock | 18 +++++++++++++++++- pyproject.toml | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 46b19c6..21e3d63 100644 --- a/poetry.lock +++ b/poetry.lock @@ -754,6 +754,18 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +[[package]] +name = "pytest-dotenv" +version = "0.5.2" +description = "A py.test plugin that parses environment files before running tests" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pytest = ">=5.0.0" +python-dotenv = ">=0.9.1" + [[package]] name = "python-dotenv" version = "0.19.2" @@ -1114,7 +1126,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7.2" -content-hash = "51d27b631ce9c80ef9444a1c9fe74bb0868f36a1a2b1975772d77b7dc5b28406" +content-hash = "8612f0a41195010569327b91e689d6d62cab328089b9434f3d12d32ad3eb60d3" [metadata.files] aiohttp = [ @@ -1766,6 +1778,10 @@ pytest-cov = [ {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, ] +pytest-dotenv = [ + {file = "pytest-dotenv-0.5.2.tar.gz", hash = "sha256:2dc6c3ac6d8764c71c6d2804e902d0ff810fa19692e95fe138aefc9b1aa73732"}, + {file = "pytest_dotenv-0.5.2-py3-none-any.whl", hash = "sha256:40a2cece120a213898afaa5407673f6bd924b1fa7eafce6bda0e8abffe2f710f"}, +] python-dotenv = [ {file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"}, {file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"}, diff --git a/pyproject.toml b/pyproject.toml index f943fbd..964f7b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ mypy = "*" black = "*" pytest = "^6.0" pytest-cov = "*" +pytest-dotenv = "*" flake8 = "*" Sphinx = "*" sphinx-book-theme = "*" From e9d072e028f7c222e1fcbe20f4f1cb6daac559d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 3 Feb 2022 13:32:40 +0100 Subject: [PATCH 02/21] fix: fixed support for stable Ganache v7.0.1 (#233) Co-authored-by: Raphael Redmer --- .github/workflows/test.yml | 3 +-- tests/test_uniswap.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index acb725e..94e28d1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,8 +48,7 @@ jobs: - name: Install dependencies run: | poetry install - # TODO: Update to stable ganache when released! - npm install -g ganache@beta + npm install -g ganache@7.0.1 - name: Test env: PROVIDER: ${{ secrets.MAINNET_PROVIDER }} diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index 08ea0b7..c8511a1 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -94,7 +94,7 @@ def ganache() -> Generator[GanacheInstance, None, None]: --chain.chainId 1 --fork.url {os.environ['PROVIDER']} --miner.defaultGasPrice {defaultGasPrice} - --miner.legacyInstamine true + --miner.instamine "strict" """.replace( "\n", " " ), From 2ee0e3b0710f0606834be5e88837eb7e901099c7 Mon Sep 17 00:00:00 2001 From: nxet Date: Thu, 24 Feb 2022 17:30:15 +0100 Subject: [PATCH 03/21] feat: add support for Harmony One (mainnet and testnet) with SushiSwap V2 factory/router (#238) --- uniswap/constants.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/uniswap/constants.py b/uniswap/constants.py index 164514c..d6deeb4 100644 --- a/uniswap/constants.py +++ b/uniswap/constants.py @@ -15,6 +15,8 @@ 250: "fantom", 42161: "arbitrum", 421611: "arbitrum_testnet", + 1666600000: "harmony_mainnet", + 1666700000: "harmony_testnet", } _factory_contract_addresses_v1 = { @@ -36,6 +38,9 @@ "xdai": "0xA818b4F111Ccac7AA31D0BCc0806d64F2E0737D7", "binance": "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73", "binance_testnet": "0x6725F303b657a9451d8BA641348b6761A6CC7a17", + # SushiSwap on Harmony + "harmony_mainnet": "0xc35DADB65012eC5796536bD9864eD8773aBc74C4", + "harmony_testnet": "0xc35DADB65012eC5796536bD9864eD8773aBc74C4", } _router_contract_addresses_v2 = { @@ -46,4 +51,7 @@ "xdai": "0x1C232F01118CB8B424793ae03F870aa7D0ac7f77", "binance": "0x10ED43C718714eb63d5aA57B78B54704E256024E", "binance_testnet": "0xD99D1c33F9fC3444f8101754aBC46c52416550D1", + # SushiSwap on Harmony + "harmony_mainnet": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", + "harmony_testnet": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", } From 14bb039bf329b42d0ed02f2640a3501a59e09252 Mon Sep 17 00:00:00 2001 From: lfeng100 <59289011+lfeng100@users.noreply.github.com> Date: Wed, 29 Jun 2022 10:46:53 -0400 Subject: [PATCH 04/21] =?UTF-8?q?fix:=20add=20g=C3=B6rli=20to=20=5Fnetid?= =?UTF-8?q?=5Fto=5Fname=20(#261)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously "Unknown netid: 5" Exception would be thrown where 5 is the görli network id --- uniswap/constants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/uniswap/constants.py b/uniswap/constants.py index d6deeb4..3a51fad 100644 --- a/uniswap/constants.py +++ b/uniswap/constants.py @@ -6,6 +6,7 @@ 1: "mainnet", 3: "ropsten", 4: "rinkeby", + 5: "görli", 10: "optimism", 42: "kovan", 56: "binance", From 6b39de45aa3e427f03f7b39095e64d476ee384fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 08:44:03 +0200 Subject: [PATCH 05/21] ci: added public PROVIDERs for PRs, experimenting with testing beyond mainnet --- .github/workflows/test.yml | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 94e28d1..66111f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,14 +6,33 @@ on: pull_request: branches: [ master ] +env: + # Public key for PRs, plz don't abuse + PROVIDER_MAINNET: ${{ secrets.MAINNET_PROVIDER || 'https://mainnet.infura.io/v3/42ffb4f2549c4a5fa3b5d6db70f6fad1' }} + PROVIDER_ARBITRUM: 'https://rpc.ankr.com/arbitrum' + PROVIDER_XDAI: 'https://rpc.ankr.com/gnosis' + jobs: test: - name: test (v${{ matrix.uniswap-version }}) + name: test (v${{ matrix.uniswap-version }}, ${{ matrix.network }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: uniswap-version: [1, 2, 3] + network: ["mainnet"] + include: + - network: arbitrum + uniswap-version: 3 + #include: + # - network: xdai + # uniswap-version: 3 + #include: + # - network: optimism + # uniswap-version: 3 + #include: + # - network: polygon + # uniswap-version: 3 steps: - uses: actions/checkout@v2 @@ -35,12 +54,14 @@ jobs: run: | python -m pip install --upgrade pip poetry poetry config virtualenvs.in-project true + - name: Set up cache uses: actions/cache@v2 id: cache with: path: .venv key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} + - name: Ensure cache is healthy if: steps.cache.outputs.cache-hit == 'true' run: timeout 10s poetry run pip --version || rm -rf .venv @@ -48,13 +69,16 @@ jobs: - name: Install dependencies run: | poetry install - npm install -g ganache@7.0.1 + npm install -g ganache@7.3.2 + - name: Test env: - PROVIDER: ${{ secrets.MAINNET_PROVIDER }} + # Use the secret if available, otherwise fallback to the public key + PROVIDER: ${{ ((matrix.network == 'mainnet') && env.PROVIDER_MAINNET) || ((matrix.network == 'arbitrum') && env.PROVIDER_ARBITRUM) }} UNISWAP_VERSION: ${{ matrix.uniswap-version }} run: | make test + - name: "Upload coverage to Codecov" uses: codecov/codecov-action@v1 with: @@ -76,16 +100,19 @@ jobs: id: full-python-version run: | echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info[:3]))") + - name: Set up poetry run: | python -m pip install --upgrade pip poetry poetry config virtualenvs.in-project true + - name: Set up cache uses: actions/cache@v2 id: cache with: path: .venv key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} + - name: Ensure cache is healthy if: steps.cache.outputs.cache-hit == 'true' run: timeout 10s poetry run pip --version || rm -rf .venv @@ -94,6 +121,7 @@ jobs: run: | python -m pip install --upgrade pip poetry poetry install + - name: Typecheck run: | make typecheck From 8ea74cf517f7c27273867b1134fbf8c4262a07c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 10:25:16 +0200 Subject: [PATCH 06/21] test: added testing support for chains other than mainnet --- Makefile | 4 +- tests/test_uniswap.py | 158 +++++++++++++++++++++--------------------- uniswap/cli.py | 14 +++- uniswap/tokens.py | 30 +++++++- uniswap/uniswap.py | 28 ++------ 5 files changed, 126 insertions(+), 108 deletions(-) diff --git a/Makefile b/Makefile index ac1ebe7..aa3e4d5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: test typecheck lint precommit docs test: - poetry run pytest -v --tb=line --maxfail=4 --cov=uniswap --cov-report html --cov-report term --cov-report xml + poetry run pytest -v --maxfail=10 --cov=uniswap --cov-report html --cov-report term --cov-report xml typecheck: poetry run mypy --pretty @@ -11,7 +11,7 @@ lint: format: black uniswap - + format-abis: npx prettier --write --parser=json uniswap/assets/*/*.abi diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index c8511a1..9219604 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -15,6 +15,7 @@ from uniswap.constants import ETH_ADDRESS from uniswap.exceptions import InsufficientBalance from uniswap.util import _str_to_addr +from uniswap.tokens import get_tokens logger = logging.getLogger(__name__) @@ -47,12 +48,17 @@ def client(request, web3: Web3, ganache: GanacheInstance): ) +@pytest.fixture(scope="function", params=UNISWAP_VERSIONS) +def tokens(client: Uniswap): + return get_tokens(client.netname) + + @pytest.fixture(scope="module") def test_assets(client: Uniswap): """ Buy some DAI and USDC to test with. """ - tokens = client._get_token_addresses() + tokens = get_tokens(client.netname) for token_name, amount in [("DAI", 100 * 10 ** 18), ("USDC", 100 * 10 ** 6)]: token_addr = tokens[token_name] @@ -68,7 +74,7 @@ def test_assets(client: Uniswap): def web3(ganache: GanacheInstance): w3 = Web3(Web3.HTTPProvider(ganache.provider, request_kwargs={"timeout": 30})) if 1 != int(w3.net.version): - raise Exception("PROVIDER was not a mainnet provider, which the tests require") + logger.warning("PROVIDER was not a mainnet provider, which the tests require") return w3 @@ -114,26 +120,15 @@ def does_not_raise(): yield -# TODO: Change pytest.param(..., mark=pytest.mark.xfail) to the expectation/raises method -@pytest.mark.usefixtures("client", "web3") -class TestUniswap(object): - ONE_ETH = 10 ** 18 - ONE_USDC = 10 ** 6 +ONE_ETH = 10 ** 18 +ONE_USDC = 10 ** 6 - ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" - # TODO: Detect mainnet vs rinkeby and set accordingly, like _get_token_addresses in the Uniswap class - # For Mainnet testing (with `ganache --fork` as per the ganache fixture) - eth = "0x0000000000000000000000000000000000000000" - weth = Web3.toChecksumAddress("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2") - bat = Web3.toChecksumAddress("0x0D8775F648430679A709E98d2b0Cb6250d2887EF") - dai = Web3.toChecksumAddress("0x6b175474e89094c44da98b954eedeac495271d0f") - usdc = Web3.toChecksumAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48") - # For Rinkeby - # eth = "0x0000000000000000000000000000000000000000" - # bat = "0xDA5B056Cfb861282B4b59d29c9B395bcC238D29B" - # dai = "0x2448eE2641d78CC42D7AD76498917359D961A783" +# TODO: Change pytest.param(..., mark=pytest.mark.xfail) to the expectation/raises method +@pytest.mark.usefixtures("client", "web3") +class TestUniswap(object): # ------ Exchange ------------------------------------------------------------------ def test_get_fee_maker(self, client: Uniswap): @@ -152,20 +147,19 @@ def test_get_fee_taker(self, client: Uniswap): @pytest.mark.parametrize( "token0, token1, qty, kwargs", [ - (eth, bat, ONE_ETH, {}), - (bat, eth, ONE_ETH, {}), - (eth, dai, ONE_ETH, {}), - (dai, eth, ONE_ETH, {}), - (eth, bat, 2 * ONE_ETH, {}), - (bat, eth, 2 * ONE_ETH, {}), - (weth, dai, ONE_ETH, {}), - (dai, weth, ONE_ETH, {}), - (dai, usdc, ONE_ETH, {"fee": 500}), - pytest.param(eth, "btc", ONE_ETH, {}, marks=pytest.mark.xfail), - pytest.param("btc", eth, ONE_ETH, {}, marks=pytest.mark.xfail), + ("ETH", "UNI", ONE_ETH, {}), + ("UNI", "ETH", ONE_ETH, {}), + ("ETH", "DAI", ONE_ETH, {}), + ("DAI", "ETH", ONE_ETH, {}), + ("ETH", "UNI", 2 * ONE_ETH, {}), + ("UNI", "ETH", 2 * ONE_ETH, {}), + ("WETH", "DAI", ONE_ETH, {}), + ("DAI", "WETH", ONE_ETH, {}), + ("DAI", "USDC", ONE_ETH, {"fee": 500}), ], ) - def test_get_price_input(self, client, token0, token1, qty, kwargs): + def test_get_price_input(self, client, tokens, token0, token1, qty, kwargs): + token0, token1 = tokens[token0], tokens[token1] if client.version == 1 and ETH_ADDRESS not in [token0, token1]: pytest.skip("Not supported in this version of Uniswap") r = client.get_price_input(token0, token1, qty, **kwargs) @@ -174,55 +168,59 @@ def test_get_price_input(self, client, token0, token1, qty, kwargs): @pytest.mark.parametrize( "token0, token1, qty, kwargs", [ - (eth, bat, ONE_ETH, {}), - (bat, eth, ONE_ETH, {}), - (eth, dai, ONE_ETH, {}), - (dai, eth, ONE_ETH, {}), - (eth, bat, 2 * ONE_ETH, {}), - (bat, eth, 2 * ONE_ETH, {}), - (weth, dai, ONE_ETH, {}), - (dai, weth, ONE_ETH, {}), - (dai, usdc, ONE_USDC, {"fee": 500}), - pytest.param(eth, "btc", ONE_ETH, {}, marks=pytest.mark.xfail), - pytest.param("btc", eth, ONE_ETH, {}, marks=pytest.mark.xfail), + ("ETH", "UNI", ONE_ETH, {}), + ("UNI", "ETH", ONE_ETH, {}), + ("ETH", "DAI", ONE_ETH, {}), + ("DAI", "ETH", ONE_ETH, {}), + ("ETH", "UNI", 2 * ONE_ETH, {}), + ("UNI", "ETH", 2 * ONE_ETH, {}), + ("WETH", "DAI", ONE_ETH, {}), + ("DAI", "WETH", ONE_ETH, {}), + ("DAI", "USDC", ONE_USDC, {"fee": 500}), ], ) - def test_get_price_output(self, client, token0, token1, qty, kwargs): + def test_get_price_output(self, client, tokens, token0, token1, qty, kwargs): + token0, token1 = tokens[token0], tokens[token1] if client.version == 1 and ETH_ADDRESS not in [token0, token1]: pytest.skip("Not supported in this version of Uniswap") r = client.get_price_output(token0, token1, qty, **kwargs) assert r # ------ ERC20 Pool ---------------------------------------------------------------- - @pytest.mark.parametrize("token", [(bat), (dai)]) + @pytest.mark.parametrize("token", [("UNI"), ("DAI")]) def test_get_ex_eth_balance( self, client: Uniswap, + tokens, token, ): if not client.version == 1: - pytest.skip("Tested method only supported on Uniswap v1") - r = client.get_ex_eth_balance(token) + pytest.skip("Only supported on Uniswap v1") + r = client.get_ex_eth_balance(tokens[token]) assert r - @pytest.mark.parametrize("token", [(bat), (dai)]) + @pytest.mark.parametrize("token", [("UNI"), ("DAI")]) def test_get_ex_token_balance( self, client: Uniswap, + tokens, token, ): if not client.version == 1: - pytest.skip("Tested method only supported on Uniswap v1") - r = client.get_ex_token_balance(token) + pytest.skip("Only supported on Uniswap v1") + r = client.get_ex_token_balance(tokens[token]) assert r - @pytest.mark.parametrize("token", [(bat), (dai)]) - def get_exchange_rate( + @pytest.mark.parametrize("token", [("UNI"), ("DAI")]) + def test_get_exchange_rate( self, client: Uniswap, + tokens, token, ): - r = client.get_exchange_rate(token) + if not client.version == 1: + pytest.skip("Only supported on Uniswap v1") + r = client.get_exchange_rate(tokens[token]) assert r # ------ Liquidity ----------------------------------------------------------------- @@ -230,12 +228,12 @@ def get_exchange_rate( @pytest.mark.parametrize( "token, max_eth", [ - (bat, 0.00001 * ONE_ETH), - (dai, 0.00001 * ONE_ETH), - pytest.param("btc", ONE_ETH, marks=pytest.mark.xfail), + ("UNI", 0.00001 * ONE_ETH), + ("DAI", 0.00001 * ONE_ETH), ], ) - def test_add_liquidity(self, client: Uniswap, web3: Web3, token, max_eth): + def test_add_liquidity(self, client: Uniswap, tokens, web3: Web3, token, max_eth): + token = tokens[token] r = client.add_liquidity(token, max_eth) tx = web3.eth.wait_for_transaction_receipt(r, timeout=RECEIPT_TIMEOUT) assert tx["status"] @@ -244,16 +242,16 @@ def test_add_liquidity(self, client: Uniswap, web3: Web3, token, max_eth): @pytest.mark.parametrize( "token, max_token, expectation", [ - (bat, 0.00001 * ONE_ETH, does_not_raise()), - (dai, 0.00001 * ONE_ETH, does_not_raise()), - ("btc", ONE_ETH, pytest.raises(NameNotFound)), + ("UNI", 0.00001 * ONE_ETH, does_not_raise()), + ("DAI", 0.00001 * ONE_ETH, does_not_raise()), ], ) def test_remove_liquidity( - self, client: Uniswap, web3: Web3, token, max_token, expectation + self, client: Uniswap, web3: Web3, tokens, token, max_token, expectation ): + token = tokens[token] with expectation: - r = client.remove_liquidity(token, max_token) + r = client.remove_liquidity(tokens[token], max_token) tx = web3.eth.wait_for_transaction_receipt(r) assert tx["status"] @@ -262,21 +260,21 @@ def test_remove_liquidity( "input_token, output_token, qty, recipient, expectation", [ # ETH -> Token - (eth, dai, ONE_ETH, None, does_not_raise), + ("ETH", "DAI", ONE_ETH, None, does_not_raise), # Token -> Token - (dai, usdc, ONE_ETH, None, does_not_raise), + ("DAI", "USDC", ONE_ETH, None, does_not_raise), # Token -> ETH - (usdc, eth, 100 * ONE_USDC, None, does_not_raise), - # (eth, bat, 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), - # (bat, eth, 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), - # (dai, bat, 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), - (dai, "btc", ONE_ETH, None, lambda: pytest.raises(NameNotFound)), + ("USDC", "ETH", 100 * ONE_USDC, None, does_not_raise), + # ("ETH", "UNI", 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), + # ("UNI", "ETH", 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), + # ("DAI", "UNI", 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), ], ) def test_make_trade( self, client: Uniswap, web3: Web3, + tokens, test_assets, input_token, output_token, @@ -284,6 +282,7 @@ def test_make_trade( recipient, expectation, ): + input_token, output_token = tokens[input_token], tokens[output_token] if client.version == 1 and ETH_ADDRESS not in [input_token, output_token]: pytest.skip( "Not supported in this version of Uniswap, or at least no liquidity" @@ -297,36 +296,36 @@ def test_make_trade( # TODO: Checks for ETH, taking gas into account bal_in_after = client.get_token_balance(input_token) - if input_token != self.eth: + if input_token != tokens["ETH"]: assert bal_in_before - qty == bal_in_after @pytest.mark.parametrize( "input_token, output_token, qty, recipient, expectation", [ # ETH -> Token - (eth, dai, 10 ** 18, None, does_not_raise), + ("ETH", "DAI", 10 ** 18, None, does_not_raise), # Token -> Token - (dai, usdc, ONE_USDC, None, does_not_raise), + ("DAI", "USDC", ONE_USDC, None, does_not_raise), # Token -> ETH - (dai, eth, 10 ** 16, None, does_not_raise), + ("DAI", "ETH", 10 ** 16, None, does_not_raise), # FIXME: These should probably be uncommented eventually - # (eth, bat, int(0.000001 * ONE_ETH), ZERO_ADDRESS), - # (bat, eth, int(0.000001 * ONE_ETH), ZERO_ADDRESS), - # (dai, bat, int(0.000001 * ONE_ETH), ZERO_ADDRESS), + # ("ETH", "UNI", int(0.000001 * ONE_ETH), ZERO_ADDRESS), + # ("UNI", "ETH", int(0.000001 * ONE_ETH), ZERO_ADDRESS), + # ("DAI", "UNI", int(0.000001 * ONE_ETH), ZERO_ADDRESS), ( - dai, - eth, + "DAI", + "ETH", 10 * 10 ** 18, None, lambda: pytest.raises(InsufficientBalance), ), - (dai, "btc", ONE_ETH, None, lambda: pytest.raises(NameNotFound)), ], ) def test_make_trade_output( self, client: Uniswap, web3: Web3, + tokens, test_assets, input_token, output_token, @@ -334,6 +333,7 @@ def test_make_trade_output( recipient, expectation, ): + input_token, output_token = tokens[input_token], tokens[output_token] if client.version == 1 and ETH_ADDRESS not in [input_token, output_token]: pytest.skip( "Not supported in this version of Uniswap, or at least no liquidity" @@ -347,5 +347,5 @@ def test_make_trade_output( # TODO: Checks for ETH, taking gas into account balance_after = client.get_token_balance(output_token) - if output_token != self.eth: + if output_token != tokens["ETH"]: assert balance_before + qty == balance_after diff --git a/uniswap/cli.py b/uniswap/cli.py index 633ab91..76e18dd 100644 --- a/uniswap/cli.py +++ b/uniswap/cli.py @@ -4,17 +4,23 @@ import click from dotenv import load_dotenv from web3 import Web3 +from typing import Optional from .uniswap import Uniswap, AddressLike, _str_to_addr from .token import BaseToken -from .tokens import tokens +from .tokens import get_tokens from .constants import ETH_ADDRESS logger = logging.getLogger(__name__) +# Global used in _coerce_to_checksum to look up tokens +_uni: Optional[Uniswap] = None + def _coerce_to_checksum(addr: str) -> str: + assert _uni + tokens = get_tokens(_uni.netname) if not addr.startswith("0x"): if addr.upper() in tokens: return tokens[addr.upper()] @@ -33,7 +39,7 @@ def _coerce_to_checksum(addr: str) -> str: @click.option( "--version", type=click.Choice(["1", "2", "3"]), - default=os.getenv("UNISWAP_VERSION", "2"), + default=os.getenv("UNISWAP_VERSION", "3"), ) @click.pass_context def main(ctx: click.Context, verbose: bool, version: str) -> None: @@ -43,6 +49,8 @@ def main(ctx: click.Context, verbose: bool, version: str) -> None: ctx.ensure_object(dict) ctx.obj["VERBOSE"] = verbose ctx.obj["UNISWAP"] = Uniswap(None, None, version=int(version)) + global _uni + _uni = ctx.obj["UNISWAP"] @main.command() @@ -100,7 +108,7 @@ def token(ctx: click.Context, token: AddressLike) -> None: def tokendb(ctx: click.Context, metadata: bool) -> None: """List known token addresses""" uni: Uniswap = ctx.obj["UNISWAP"] - for symbol, addr in tokens.items(): + for symbol, addr in get_tokens(uni.netname).items(): if metadata and addr != "0x0000000000000000000000000000000000000000": data = uni.get_token(_str_to_addr(addr)) assert data.symbol.lower() == symbol.lower() diff --git a/uniswap/tokens.py b/uniswap/tokens.py index ed5ee60..551b77e 100644 --- a/uniswap/tokens.py +++ b/uniswap/tokens.py @@ -1,10 +1,10 @@ from typing import Dict from web3 import Web3 -from web3.types import ChecksumAddress +from eth_typing.evm import ChecksumAddress -tokens: Dict[str, ChecksumAddress] = { +tokens_mainnet: Dict[str, ChecksumAddress] = { k: Web3.toChecksumAddress(v) for k, v in { "ETH": "0x0000000000000000000000000000000000000000", @@ -25,3 +25,29 @@ "BAT": "0xDA5B056Cfb861282B4b59d29c9B395bcC238D29B", }.items() } + +tokens_arbitrum: Dict[str, ChecksumAddress] = { + k: Web3.toChecksumAddress(v) + for k, v in { + "ETH": "0x0000000000000000000000000000000000000000", + "WETH": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", + "DAI": "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", + "USDC": "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8", + "UNI": "0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0", + }.items() +} + + +def get_tokens(netname: str) -> Dict[str, ChecksumAddress]: + """ + Returns a dict with addresses for tokens for the current net. + Used in testing. + """ + if netname == "mainnet": + return tokens_mainnet + elif netname == "rinkeby": + return tokens_rinkeby + elif netname == "arbitrum": + return tokens_arbitrum + else: + raise Exception(f"Unknown net '{netname}'") diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index ccc5639..b84d1f5 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -2,24 +2,22 @@ import time import logging import functools -from typing import List, Any, Optional, Union, Tuple, Dict, Iterable +from typing import List, Any, Optional, Union, Tuple, Iterable from web3 import Web3 -from web3.eth import Contract -from web3.contract import ContractFunction +from web3.contract import Contract, ContractFunction from web3.exceptions import BadFunctionCallOutput, ContractLogicError from web3.types import ( TxParams, Wei, - Address, - ChecksumAddress, Nonce, - HexBytes, ) +from eth_typing.evm import Address, ChecksumAddress +from hexbytes import HexBytes from .types import AddressLike from .token import ERC20Token -from .tokens import tokens, tokens_rinkeby +from .tokens import get_tokens from .exceptions import InvalidToken, InsufficientBalance from .util import ( _str_to_addr, @@ -1256,7 +1254,7 @@ def get_raw_price( token_out = self.get_weth_address() if self.version == 2: - params: Iterable[Union[ChecksumAddress,Optional[int]]] = [ + params: Iterable[Union[ChecksumAddress, Optional[int]]] = [ self.w3.toChecksumAddress(token_in), self.w3.toChecksumAddress(token_out), ] @@ -1364,20 +1362,6 @@ def get_fee_taker(self) -> float: """Get the taker fee.""" return 0.003 - # ------ Test utilities ------------------------------------------------------------ - - def _get_token_addresses(self) -> Dict[str, ChecksumAddress]: - """ - Returns a dict with addresses for tokens for the current net. - Used in testing. - """ - if self.netname == "mainnet": - return tokens - elif self.netname == "rinkeby": - return tokens_rinkeby - else: - raise Exception(f"Unknown net '{self.netname}'") - # ---- Old v1 utils ---- @supports([1]) From f74d23ada093d338738b4f9cdc3f82b463dfd57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 10:35:40 +0200 Subject: [PATCH 07/21] test: fixed test for v1 --- tests/test_uniswap.py | 3 +-- uniswap/uniswap.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index 9219604..f526575 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -169,11 +169,10 @@ def test_get_price_input(self, client, tokens, token0, token1, qty, kwargs): "token0, token1, qty, kwargs", [ ("ETH", "UNI", ONE_ETH, {}), - ("UNI", "ETH", ONE_ETH, {}), + ("UNI", "ETH", ONE_ETH // 100, {}), ("ETH", "DAI", ONE_ETH, {}), ("DAI", "ETH", ONE_ETH, {}), ("ETH", "UNI", 2 * ONE_ETH, {}), - ("UNI", "ETH", 2 * ONE_ETH, {}), ("WETH", "DAI", ONE_ETH, {}), ("DAI", "WETH", ONE_ETH, {}), ("DAI", "USDC", ONE_USDC, {"fee": 500}), diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index b84d1f5..c43c328 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -1210,6 +1210,15 @@ def get_token(self, address: AddressLike, abi_name: str = "erc20") -> ERC20Token """ # FIXME: This function should always return the same output for the same input # and would therefore benefit from caching + if address == "0x0000000000000000000000000000000000000000": + # This isn't exactly right, but for all intents and purposes, + # ETH is treated as a ERC20 by Uniswap. + return ERC20Token( + address=address, + name="ETH", + symbol="ETH", + decimals=18, + ) token_contract = _load_contract(self.w3, abi_name, address=address) try: _name = token_contract.functions.name().call() @@ -1222,11 +1231,11 @@ def get_token(self, address: AddressLike, abi_name: str = "erc20") -> ERC20Token raise InvalidToken(address) try: name = _name.decode() - except: + except Exception: name = _name try: symbol = _symbol.decode() - except: + except Exception: symbol = _symbol return ERC20Token(symbol, address, name, decimals) From a0c8ac06f3720afc153b7bec4bddb76b1706eed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 11:10:45 +0200 Subject: [PATCH 08/21] test: added test for get_raw_price --- tests/test_uniswap.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index f526575..0198a0b 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -185,6 +185,20 @@ def test_get_price_output(self, client, tokens, token0, token1, qty, kwargs): r = client.get_price_output(token0, token1, qty, **kwargs) assert r + @pytest.mark.parametrize("token0,token1", [("UNI", "DAI")]) + def test_get_raw_price( + self, + client: Uniswap, + tokens, + token0, + token1, + ): + token0, token1 = tokens[token0], tokens[token1] + if client.version == 1: + pytest.skip("Only supported on Uniswap v2 and v3") + r = client.get_raw_price(token0, token1) + assert r + # ------ ERC20 Pool ---------------------------------------------------------------- @pytest.mark.parametrize("token", [("UNI"), ("DAI")]) def test_get_ex_eth_balance( From 0cc51ef76c19d62e3ebd19016f1402081ab7d723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 11:19:56 +0200 Subject: [PATCH 09/21] test: fixed test for get_raw_price --- tests/test_uniswap.py | 12 +++--------- uniswap/uniswap.py | 8 +++++--- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index 0198a0b..e7f0b76 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -185,18 +185,12 @@ def test_get_price_output(self, client, tokens, token0, token1, qty, kwargs): r = client.get_price_output(token0, token1, qty, **kwargs) assert r - @pytest.mark.parametrize("token0,token1", [("UNI", "DAI")]) - def test_get_raw_price( - self, - client: Uniswap, - tokens, - token0, - token1, - ): + @pytest.mark.parametrize("token0, token1, fee", [("DAI", "USDC", 500)]) + def test_get_raw_price(self, client: Uniswap, tokens, token0, token1, fee): token0, token1 = tokens[token0], tokens[token1] if client.version == 1: pytest.skip("Only supported on Uniswap v2 and v3") - r = client.get_raw_price(token0, token1) + r = client.get_raw_price(token0, token1, fee=fee) assert r # ------ ERC20 Pool ---------------------------------------------------------------- diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index c43c328..6a25411 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -1254,9 +1254,11 @@ def get_weth_address(self) -> ChecksumAddress: def get_raw_price( self, token_in: AddressLike, token_out: AddressLike, fee: int = 3000 ) -> float: - """Returns current price for pair of tokens [token_in, token_out] regrading liquidity that is being locked in the pool""" - """Parameter `fee` is required for V3 only, can be omitted for V2""" - """Requires pair [token_in, token_out] having direct pool""" + """ + Returns current price for pair of tokens [token_in, token_out] regrading liquidity that is being locked in the pool + Parameter `fee` is required for V3 only, can be omitted for V2 + Requires pair [token_in, token_out] having direct pool + """ if token_in == ETH_ADDRESS: token_in = self.get_weth_address() if token_out == ETH_ADDRESS: From 170bf314ea200dc0a45ecc470c8bb6224a6bf48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 11:43:32 +0200 Subject: [PATCH 10/21] fix: fixed lint complaints about non-exhaustive cases by raising ValueError, added 'pragma: no cover' --- uniswap/uniswap.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index 6a25411..83785de 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -86,6 +86,10 @@ def __init__( ) self.version = version + if self.version not in [1, 2, 3]: + raise Exception( + f"Invalid version '{self.version}', only 1, 2 or 3 supported" + ) # pragma: no cover # TODO: Write tests for slippage self.default_slippage = default_slippage @@ -104,7 +108,7 @@ def __init__( if self.netid in _netid_to_name: self.netname = _netid_to_name[self.netid] else: - raise Exception(f"Unknown netid: {self.netid}") + raise Exception(f"Unknown netid: {self.netid}") # pragma: no cover logger.info(f"Using {self.w3} ('{self.netname}', netid: {self.netid})") self.last_nonce: Nonce = self.w3.eth.get_transaction_count(self.address) @@ -164,10 +168,6 @@ def __init__( self.router = _load_contract( self.w3, abi_name="uniswap-v3/router", address=self.router_address ) - else: - raise Exception( - f"Invalid version '{self.version}', only 1, 2 or 3 supported" - ) if hasattr(self, "factory_contract"): logger.info(f"Using factory contract: {self.factory_contract}") @@ -234,6 +234,8 @@ def _get_eth_token_input_price( price = self._get_token_token_input_price( self.get_weth_address(), token, qty, fee=fee ) # type: ignore + else: + raise ValueError # pragma: no cover return price def _get_token_eth_input_price( @@ -254,6 +256,8 @@ def _get_token_eth_input_price( price = self._get_token_token_input_price( token, self.get_weth_address(), qty, fee=fee ) + else: + raise ValueError # pragma: no cover return price def _get_token_token_input_price( @@ -320,6 +324,8 @@ def _get_eth_token_output_price( self.get_weth_address(), token, qty, fee=fee ) ) + else: + raise ValueError # pragma: no cover return price def _get_token_eth_output_price( @@ -339,8 +345,11 @@ def _get_token_eth_output_price( price = self._get_token_token_output_price( token, self.get_weth_address(), qty, fee=fee ) + else: + raise ValueError # pragma: no cover return price + @supports([2, 3]) def _get_token_token_output_price( self, token0: AddressLike, # input token @@ -385,7 +394,7 @@ def _get_token_token_output_price( token0, token1, fee, qty, sqrtPriceLimitX96 ).call() else: - raise ValueError("function not supported for this version of Uniswap") + raise ValueError # pragma: no cover return price # ------ Make Trade ---------------------------------------------------------------- @@ -548,7 +557,7 @@ def _eth_to_token_swap_input( self._get_tx_params(value=qty), ) else: - raise ValueError + raise ValueError # pragma: no cover def _token_to_eth_swap_input( self, @@ -637,9 +646,8 @@ def _token_to_eth_swap_input( self.router.functions.multicall([swap_data, unwrap_data]), self._get_tx_params(), ) - else: - raise ValueError + raise ValueError # pragma: no cover def _token_to_token_swap_input( self, @@ -734,7 +742,7 @@ def _token_to_token_swap_input( self._get_tx_params(), ) else: - raise ValueError + raise ValueError # pragma: no cover def _eth_to_token_swap_output( self, From d3621e90818a1df4a100a2c6073561725c9deefb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 12:11:36 +0200 Subject: [PATCH 11/21] fix: improved typing --- uniswap/decorators.py | 23 ++++++++++++++++++----- uniswap/uniswap.py | 11 +++++++++-- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/uniswap/decorators.py b/uniswap/decorators.py index 476bc85..dd448f0 100644 --- a/uniswap/decorators.py +++ b/uniswap/decorators.py @@ -1,5 +1,6 @@ import functools -from typing import Callable, Any, List, Dict, TYPE_CHECKING +from typing import Callable, Any, List, TYPE_CHECKING, TypeVar +from typing_extensions import ParamSpec, Concatenate from .constants import ETH_ADDRESS @@ -7,7 +8,13 @@ from .uniswap import Uniswap -def check_approval(method: Callable) -> Callable: +T = TypeVar("T") +P = ParamSpec("P") + + +def check_approval( + method: Callable[Concatenate[Uniswap, P], T] +) -> Callable[Concatenate[Uniswap, P], T]: """Decorator to check if user is approved for a token. It approves them if they need to be approved.""" @@ -32,8 +39,14 @@ def approved(self: Any, *args: Any, **kwargs: Any) -> Any: return approved -def supports(versions: List[int]) -> Callable: - def g(f: Callable) -> Callable: +def supports( + versions: List[int], +) -> Callable[ + [Callable[Concatenate[Uniswap, P], T]], Callable[Concatenate[Uniswap, P], T] +]: + def g( + f: Callable[Concatenate[Uniswap, P], T] + ) -> Callable[Concatenate[Uniswap, P], T]: if f.__doc__ is None: f.__doc__ = "" f.__doc__ += """\n\n @@ -43,7 +56,7 @@ def g(f: Callable) -> Callable: ) @functools.wraps(f) - def check_version(self: "Uniswap", *args: List, **kwargs: Dict) -> Any: + def check_version(self: "Uniswap", *args: P.args, **kwargs: P.kwargs) -> T: if self.version not in versions: raise Exception( f"Function {f.__name__} does not support version {self.version} of Uniswap passed to constructor" diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index 83785de..b553360 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -316,7 +316,7 @@ def _get_eth_token_output_price( route = [self.get_weth_address(), token] price = self.router.functions.getAmountsIn(qty, route).call()[0] elif self.version == 3: - if not fee: + if fee is None: logger.warning("No fee set, assuming 0.3%") fee = 3000 price = Wei( @@ -1256,17 +1256,24 @@ def get_weth_address(self) -> ChecksumAddress: address: ChecksumAddress = self.router.functions.WETH().call() elif self.version == 3: address = self.router.functions.WETH9().call() + else: + raise ValueError # pragma: no cover return address @supports([2, 3]) def get_raw_price( - self, token_in: AddressLike, token_out: AddressLike, fee: int = 3000 + self, token_in: AddressLike, token_out: AddressLike, fee: int = None ) -> float: """ Returns current price for pair of tokens [token_in, token_out] regrading liquidity that is being locked in the pool Parameter `fee` is required for V3 only, can be omitted for V2 Requires pair [token_in, token_out] having direct pool """ + if not fee: + fee = 3000 + if self.version == 3: + logger.warning("No fee set, assuming 0.3%") + if token_in == ETH_ADDRESS: token_in = self.get_weth_address() if token_out == ETH_ADDRESS: From d0fc84a8c43c277605791754a839e0e979fd0163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 12:12:01 +0200 Subject: [PATCH 12/21] build(deps): added typing-extensions, updated deps --- poetry.lock | 478 ++++++++----------------------------------------- pyproject.toml | 1 + 2 files changed, 77 insertions(+), 402 deletions(-) diff --git a/poetry.lock b/poetry.lock index 21e3d63..1c2354f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -193,14 +193,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.2" +version = "6.4.2" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -tomli = {version = "*", optional = true, markers = "extra == \"toml\""} +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] toml = ["tomli"] @@ -249,27 +249,27 @@ tools = ["hypothesis (>=3.6.1,<4)"] [[package]] name = "eth-account" -version = "0.5.6" +version = "0.5.8" description = "eth-account: Sign Ethereum transactions and messages with local private keys" category = "main" optional = false python-versions = ">=3.6, <4" [package.dependencies] -bitarray = ">=1.2.1,<1.3.0" +bitarray = ">=1.2.1,<3" eth-abi = ">=2.0.0b7,<3" eth-keyfile = ">=0.5.0,<0.6.0" -eth-keys = ">=0.2.1,<0.3.2 || >0.3.2,<0.4.0" +eth-keys = ">=0.3.4,<0.4.0" eth-rlp = ">=0.1.2,<2" eth-utils = ">=1.3.0,<2" hexbytes = ">=0.1.0,<1" rlp = ">=1.0.0,<3" [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "hypothesis (>=4.18.0,<5)", "pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] +dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21.9.0)"] +doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21.9.0)"] lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)"] -test = ["hypothesis (>=4.18.0,<5)", "pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)"] +test = ["hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)"] [[package]] name = "eth-hash" @@ -306,7 +306,7 @@ pycryptodome = ">=3.4.7,<4.0.0" [[package]] name = "eth-keys" -version = "0.3.3" +version = "0.3.4" description = "Common API for Ethereum key operations." category = "main" optional = false @@ -314,14 +314,14 @@ python-versions = "*" [package.dependencies] eth-typing = ">=2.2.1,<3.0.0" -eth-utils = ">=1.3.0,<2.0.0" +eth-utils = ">=1.8.2,<2.0.0" [package.extras] coincurve = ["coincurve (>=7.0.0,<13.0.0)"] -dev = ["tox (==2.7.0)", "bumpversion (==0.5.3)", "twine", "eth-utils (>=1.3.0,<2.0.0)", "eth-typing (>=2.2.1,<3.0.0)", "flake8 (==3.0.4)", "mypy (==0.701)", "asn1tools (>=0.146.2,<0.147)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==3.2.2)", "hypothesis (>=4.56.1,<5.0.0)", "eth-hash", "eth-hash"] -eth-keys = ["eth-utils (>=1.3.0,<2.0.0)", "eth-typing (>=2.2.1,<3.0.0)"] -lint = ["flake8 (==3.0.4)", "mypy (==0.701)"] -test = ["asn1tools (>=0.146.2,<0.147)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==3.2.2)", "hypothesis (>=4.56.1,<5.0.0)", "eth-hash", "eth-hash"] +dev = ["tox (==3.20.0)", "bumpversion (==0.5.3)", "twine", "eth-utils (>=1.8.2,<2.0.0)", "eth-typing (>=2.2.1,<3.0.0)", "flake8 (==3.0.4)", "mypy (==0.782)", "asn1tools (>=0.146.2,<0.147)", "factory-boy (>=3.0.1,<3.1)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==5.4.1)", "hypothesis (>=5.10.3,<6.0.0)", "eth-hash", "eth-hash"] +eth-keys = ["eth-utils (>=1.8.2,<2.0.0)", "eth-typing (>=2.2.1,<3.0.0)"] +lint = ["flake8 (==3.0.4)", "mypy (==0.782)"] +test = ["asn1tools (>=0.146.2,<0.147)", "factory-boy (>=3.0.1,<3.1)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==5.4.1)", "hypothesis (>=5.10.3,<6.0.0)", "eth-hash", "eth-hash"] [[package]] name = "eth-rlp" @@ -544,7 +544,7 @@ python-versions = ">=3.6" [[package]] name = "mypy" -version = "0.930" +version = "0.961" description = "Optional static typing for Python" category = "dev" optional = false @@ -552,13 +552,14 @@ python-versions = ">=3.6" [package.dependencies] mypy-extensions = ">=0.4.3" -tomli = ">=1.1.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} typing-extensions = ">=3.10" [package.extras] dmypy = ["psutil (>=4.0)"] python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] [[package]] name = "mypy-extensions" @@ -1032,11 +1033,11 @@ python-versions = ">=3.6" [[package]] name = "typing-extensions" -version = "3.10.0.2" -description = "Backported and Experimental Type Hints for Python 3.5+" +version = "4.3.0" +description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [[package]] name = "urllib3" @@ -1061,7 +1062,7 @@ python-versions = "*" [[package]] name = "web3" -version = "5.25.0" +version = "5.30.0" description = "Web3.py" category = "main" optional = false @@ -1070,25 +1071,26 @@ python-versions = ">=3.6,<4" [package.dependencies] aiohttp = ">=3.7.4.post0,<4" eth-abi = ">=2.0.0b6,<3.0.0" -eth-account = ">=0.5.6,<0.6.0" +eth-account = ">=0.5.7,<0.6.0" eth-hash = {version = ">=0.2.0,<1.0.0", extras = ["pycryptodome"]} +eth-rlp = "<0.3" eth-typing = ">=2.0.0,<3.0.0" eth-utils = ">=1.9.5,<2.0.0" hexbytes = ">=0.1.0,<1.0.0" ipfshttpclient = "0.8.0a2" -jsonschema = ">=3.2.0,<4.0.0" +jsonschema = ">=3.2.0,<5" lru-dict = ">=1.1.6,<2.0.0" protobuf = ">=3.10.0,<4" pywin32 = {version = ">=223", markers = "platform_system == \"Windows\""} requests = ">=2.16.0,<3.0.0" -typing-extensions = {version = ">=3.7.4.1,<4", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.4.1,<5", markers = "python_version < \"3.8\""} websockets = ">=9.1,<10" [package.extras] -dev = ["eth-tester[py-evm] (==v0.6.0-beta.4)", "py-geth (>=3.6.0,<4)", "flake8 (==3.8.3)", "isort (>=4.2.15,<4.3.5)", "mypy (==0.812)", "mock", "sphinx-better-theme (>=0.1.4)", "click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "py-solc (>=0.4.0)", "pytest (>=4.4.0,<5.0.0)", "sphinx (>=3.0,<4)", "sphinx-rtd-theme (>=0.1.9)", "toposort (>=1.4)", "towncrier (==18.5.0)", "urllib3", "wheel", "bumpversion", "flaky (>=3.7.0,<4)", "hypothesis (>=3.31.2,<6)", "pytest-asyncio (>=0.10.0,<0.11)", "pytest-mock (>=1.10,<2)", "pytest-pythonpath (>=0.3)", "pytest-watch (>=4.2,<5)", "pytest-xdist (>=1.29,<2)", "setuptools (>=38.6.0)", "tox (>=1.8.0)", "tqdm (>4.32,<5)", "twine (>=1.13,<2)", "pluggy (==0.13.1)", "when-changed (>=0.3.0,<0.4)"] -docs = ["mock", "sphinx-better-theme (>=0.1.4)", "click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "py-geth (>=3.6.0,<4)", "py-solc (>=0.4.0)", "pytest (>=4.4.0,<5.0.0)", "sphinx (>=3.0,<4)", "sphinx-rtd-theme (>=0.1.9)", "toposort (>=1.4)", "towncrier (==18.5.0)", "urllib3", "wheel"] -linter = ["flake8 (==3.8.3)", "isort (>=4.2.15,<4.3.5)", "mypy (==0.812)"] -tester = ["eth-tester[py-evm] (==v0.6.0-beta.4)", "py-geth (>=3.6.0,<4)"] +dev = ["eth-tester[py-evm] (==v0.6.0-beta.6)", "py-geth (>=3.8.0,<4)", "flake8 (==3.8.3)", "isort (>=4.2.15,<4.3.5)", "mypy (==0.910)", "types-setuptools (>=57.4.4,<58)", "types-requests (>=2.26.1,<3)", "types-protobuf (==3.19.13)", "mock", "sphinx-better-theme (>=0.1.4)", "click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "py-solc (>=0.4.0)", "pytest (>=4.4.0,<5.0.0)", "sphinx (>=3.0,<4)", "sphinx-rtd-theme (>=0.1.9)", "toposort (>=1.4)", "towncrier (==18.5.0)", "urllib3", "wheel", "Jinja2 (<=3.0.3)", "bumpversion", "flaky (>=3.7.0,<4)", "hypothesis (>=3.31.2,<6)", "pytest-asyncio (>=0.10.0,<0.11)", "pytest-mock (>=1.10,<2)", "pytest-pythonpath (>=0.3)", "pytest-watch (>=4.2,<5)", "pytest-xdist (>=1.29,<2)", "setuptools (>=38.6.0)", "tox (>=1.8.0)", "tqdm (>4.32,<5)", "twine (>=1.13,<2)", "pluggy (==0.13.1)", "when-changed (>=0.3.0,<0.4)"] +docs = ["mock", "sphinx-better-theme (>=0.1.4)", "click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "py-geth (>=3.8.0,<4)", "py-solc (>=0.4.0)", "pytest (>=4.4.0,<5.0.0)", "sphinx (>=3.0,<4)", "sphinx-rtd-theme (>=0.1.9)", "toposort (>=1.4)", "towncrier (==18.5.0)", "urllib3", "wheel", "Jinja2 (<=3.0.3)"] +linter = ["flake8 (==3.8.3)", "isort (>=4.2.15,<4.3.5)", "mypy (==0.910)", "types-setuptools (>=57.4.4,<58)", "types-requests (>=2.26.1,<3)", "types-protobuf (==3.19.13)"] +tester = ["eth-tester[py-evm] (==v0.6.0-beta.6)", "py-geth (>=3.8.0,<4)"] [[package]] name = "websockets" @@ -1126,7 +1128,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7.2" -content-hash = "8612f0a41195010569327b91e689d6d62cab328089b9434f3d12d32ad3eb60d3" +content-hash = "d07ae8eb53da8184c07323ef0526c990d90c6a0951430995c226dda515b5a86b" [metadata.files] aiohttp = [ @@ -1215,10 +1217,7 @@ async-timeout = [ {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] -asynctest = [ - {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, - {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, -] +asynctest = [] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, @@ -1235,25 +1234,16 @@ base58 = [ {file = "base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2"}, {file = "base58-2.1.1.tar.gz", hash = "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c"}, ] -beautifulsoup4 = [ - {file = "beautifulsoup4-4.10.0-py3-none-any.whl", hash = "sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf"}, - {file = "beautifulsoup4-4.10.0.tar.gz", hash = "sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"}, -] +beautifulsoup4 = [] bitarray = [ {file = "bitarray-1.2.2.tar.gz", hash = "sha256:27a69ffcee3b868abab3ce8b17c69e02b63e722d4d64ffd91d659f81e9984954"}, ] -black = [ - {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"}, - {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"}, -] +black = [] certifi = [ {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, ] -charset-normalizer = [ - {file = "charset-normalizer-2.0.9.tar.gz", hash = "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"}, - {file = "charset_normalizer-2.0.9-py3-none-any.whl", hash = "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721"}, -] +charset-normalizer = [] click = [ {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, @@ -1262,55 +1252,7 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] -coverage = [ - {file = "coverage-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840"}, - {file = "coverage-6.2-cp310-cp310-win32.whl", hash = "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c"}, - {file = "coverage-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f"}, - {file = "coverage-6.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76"}, - {file = "coverage-6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47"}, - {file = "coverage-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64"}, - {file = "coverage-6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781"}, - {file = "coverage-6.2-cp36-cp36m-win32.whl", hash = "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a"}, - {file = "coverage-6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0"}, - {file = "coverage-6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8"}, - {file = "coverage-6.2-cp37-cp37m-win32.whl", hash = "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4"}, - {file = "coverage-6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74"}, - {file = "coverage-6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57"}, - {file = "coverage-6.2-cp38-cp38-win32.whl", hash = "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c"}, - {file = "coverage-6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2"}, - {file = "coverage-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3"}, - {file = "coverage-6.2-cp39-cp39-win32.whl", hash = "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282"}, - {file = "coverage-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644"}, - {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, - {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, -] +coverage = [] cytoolz = [ {file = "cytoolz-0.11.2.tar.gz", hash = "sha256:ea23663153806edddce7e4153d1d407d62357c05120a4e8485bddf1bd5ab22b4"}, ] @@ -1322,10 +1264,7 @@ eth-abi = [ {file = "eth_abi-2.1.1-py3-none-any.whl", hash = "sha256:78df5d2758247a8f0766a7cfcea4575bcfe568c34a33e6d05a72c328a9040444"}, {file = "eth_abi-2.1.1.tar.gz", hash = "sha256:4bb1d87bb6605823379b07f6c02c8af45df01a27cc85bd6abb7cf1446ce7d188"}, ] -eth-account = [ - {file = "eth-account-0.5.6.tar.gz", hash = "sha256:baef80956e88af5643f8602e72aab6bcd91d8a9f71dd03c7a7f1145f5e6fd694"}, - {file = "eth_account-0.5.6-py3-none-any.whl", hash = "sha256:d324daf5a40bd5bdaf5ddaebfec71e7440b21f9ae4989921ce1253d63f8fe436"}, -] +eth-account = [] eth-hash = [ {file = "eth-hash-0.3.2.tar.gz", hash = "sha256:3f40cecd5ead88184aa9550afc19d057f103728108c5102f592f8415949b5a76"}, {file = "eth_hash-0.3.2-py3-none-any.whl", hash = "sha256:de7385148a8e0237ba1240cddbc06d53f56731140f8593bdb8429306f6b42271"}, @@ -1335,17 +1274,14 @@ eth-keyfile = [ {file = "eth_keyfile-0.5.1-py3-none-any.whl", hash = "sha256:70d734af17efdf929a90bb95375f43522be4ed80c3b9e0a8bca575fb11cd1159"}, ] eth-keys = [ - {file = "eth-keys-0.3.3.tar.gz", hash = "sha256:a9a1e83e443bd369265b1a1b66dc30f6841bdbb3577ecd042e037b7b405b6cb0"}, - {file = "eth_keys-0.3.3-py3-none-any.whl", hash = "sha256:412dd5c9732b8e92af40c9c77597f4661c57eba3897aaa55e527af56a8c5ab47"}, + {file = "eth-keys-0.3.4.tar.gz", hash = "sha256:e5590797f5e2930086c705a6dd1ac14397f74f19bdcd1b5f837475554f354ad8"}, + {file = "eth_keys-0.3.4-py3-none-any.whl", hash = "sha256:565bf62179b8143bcbd302a0ec6c49882d9c7678f9e6ab0484a8a5725f5ef10e"}, ] eth-rlp = [ {file = "eth-rlp-0.2.1.tar.gz", hash = "sha256:f016f980b0ed42ee7650ba6e4e4d3c4e9aa06d8b9c6825a36d3afe5aa0187a8b"}, {file = "eth_rlp-0.2.1-py3-none-any.whl", hash = "sha256:cc389ef8d7b6f76a98f90bcdbff1b8684b3a78f53d47e871191b50d4d6aee5a1"}, ] -eth-typing = [ - {file = "eth-typing-2.2.2.tar.gz", hash = "sha256:97ba0f83da7cf1d3668f6ed54983f21168076c552762bf5e06d4a20921877f3f"}, - {file = "eth_typing-2.2.2-py3-none-any.whl", hash = "sha256:1140c7592321dbf10d6663c46f7e43eb0e6410b011b03f14b3df3eb1f76aa9bb"}, -] +eth-typing = [] eth-utils = [ {file = "eth-utils-1.10.0.tar.gz", hash = "sha256:bf82762a46978714190b0370265a7148c954d3f0adaa31c6f085ea375e4c61af"}, {file = "eth_utils-1.10.0-py3-none-any.whl", hash = "sha256:74240a8c6f652d085ed3c85f5f1654203d2f10ff9062f83b3bad0a12ff321c7a"}, @@ -1354,80 +1290,7 @@ flake8 = [ {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, ] -frozenlist = [ - {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:977a1438d0e0d96573fd679d291a1542097ea9f4918a8b6494b06610dfeefbf9"}, - {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8d86547a5e98d9edd47c432f7a14b0c5592624b496ae9880fb6332f34af1edc"}, - {file = "frozenlist-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:181754275d5d32487431a0a29add4f897968b7157204bc1eaaf0a0ce80c5ba7d"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5df31bb2b974f379d230a25943d9bf0d3bc666b4b0807394b131a28fca2b0e5f"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4766632cd8a68e4f10f156a12c9acd7b1609941525569dd3636d859d79279ed3"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16eef427c51cb1203a7c0ab59d1b8abccaba9a4f58c4bfca6ed278fc896dc193"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:01d79515ed5aa3d699b05f6bdcf1fe9087d61d6b53882aa599a10853f0479c6c"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28e164722ea0df0cf6d48c4d5bdf3d19e87aaa6dfb39b0ba91153f224b912020"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e63ad0beef6ece06475d29f47d1f2f29727805376e09850ebf64f90777962792"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41de4db9b9501679cf7cddc16d07ac0f10ef7eb58c525a1c8cbff43022bddca4"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a9d84ee6427b65a81fc24e6ef589cb794009f5ca4150151251c062773e7ed2"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:f5f3b2942c3b8b9bfe76b408bbaba3d3bb305ee3693e8b1d631fe0a0d4f93673"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c98d3c04701773ad60d9545cd96df94d955329efc7743fdb96422c4b669c633b"}, - {file = "frozenlist-1.2.0-cp310-cp310-win32.whl", hash = "sha256:72cfbeab7a920ea9e74b19aa0afe3b4ad9c89471e3badc985d08756efa9b813b"}, - {file = "frozenlist-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:11ff401951b5ac8c0701a804f503d72c048173208490c54ebb8d7bb7c07a6d00"}, - {file = "frozenlist-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b46f997d5ed6d222a863b02cdc9c299101ee27974d9bbb2fd1b3c8441311c408"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:351686ca020d1bcd238596b1fa5c8efcbc21bffda9d0efe237aaa60348421e2a"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfbaa08cf1452acad9cb1c1d7b89394a41e712f88df522cea1a0f296b57782a0"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ae2f5e9fa10805fb1c9adbfefaaecedd9e31849434be462c3960a0139ed729"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6790b8d96bbb74b7a6f4594b6f131bd23056c25f2aa5d816bd177d95245a30e3"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:41f62468af1bd4e4b42b5508a3fe8cc46a693f0cdd0ca2f443f51f207893d837"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:ec6cf345771cdb00791d271af9a0a6fbfc2b6dd44cb753f1eeaa256e21622adb"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:14a5cef795ae3e28fb504b73e797c1800e9249f950e1c964bb6bdc8d77871161"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8b54cdd2fda15467b9b0bfa78cee2ddf6dbb4585ef23a16e14926f4b076dfae4"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f025f1d6825725b09c0038775acab9ae94264453a696cc797ce20c0769a7b367"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:84e97f59211b5b9083a2e7a45abf91cfb441369e8bb6d1f5287382c1c526def3"}, - {file = "frozenlist-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:c5328ed53fdb0a73c8a50105306a3bc013e5ca36cca714ec4f7bd31d38d8a97f"}, - {file = "frozenlist-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9ade70aea559ca98f4b1b1e5650c45678052e76a8ab2f76d90f2ac64180215a2"}, - {file = "frozenlist-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0d3ffa8772464441b52489b985d46001e2853a3b082c655ec5fad9fb6a3d618"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3457f8cf86deb6ce1ba67e120f1b0128fcba1332a180722756597253c465fc1d"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a72eecf37eface331636951249d878750db84034927c997d47f7f78a573b72b"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:acc4614e8d1feb9f46dd829a8e771b8f5c4b1051365d02efb27a3229048ade8a"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:87521e32e18a2223311afc2492ef2d99946337da0779ddcda77b82ee7319df59"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b4c7665a17c3a5430edb663e4ad4e1ad457614d1b2f2b7f87052e2ef4fa45ca"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ed58803563a8c87cf4c0771366cf0ad1aa265b6b0ae54cbbb53013480c7ad74d"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa44c4740b4e23fcfa259e9dd52315d2b1770064cde9507457e4c4a65a04c397"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2de5b931701257d50771a032bba4e448ff958076380b049fd36ed8738fdb375b"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6e105013fa84623c057a4381dc8ea0361f4d682c11f3816cc80f49a1f3bc17c6"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:705c184b77565955a99dc360f359e8249580c6b7eaa4dc0227caa861ef46b27a"}, - {file = "frozenlist-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:a37594ad6356e50073fe4f60aa4187b97d15329f2138124d252a5a19c8553ea4"}, - {file = "frozenlist-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:25b358aaa7dba5891b05968dd539f5856d69f522b6de0bf34e61f133e077c1a4"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af2a51c8a381d76eabb76f228f565ed4c3701441ecec101dd18be70ebd483cfd"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:82d22f6e6f2916e837c91c860140ef9947e31194c82aaeda843d6551cec92f19"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cfe6fef507f8bac40f009c85c7eddfed88c1c0d38c75e72fe10476cef94e10f"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f602e380a5132880fa245c92030abb0fc6ff34e0c5500600366cedc6adb06a"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ad065b2ebd09f32511ff2be35c5dfafee6192978b5a1e9d279a5c6e121e3b03"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc93f5f62df3bdc1f677066327fc81f92b83644852a31c6aa9b32c2dde86ea7d"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:89fdfc84c6bf0bff2ff3170bb34ecba8a6911b260d318d377171429c4be18c73"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:47b2848e464883d0bbdcd9493c67443e5e695a84694efff0476f9059b4cb6257"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4f52d0732e56906f8ddea4bd856192984650282424049c956857fed43697ea43"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:16ef7dd5b7d17495404a2e7a49bac1bc13d6d20c16d11f4133c757dd94c4144c"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1cf63243bc5f5c19762943b0aa9e0d3fb3723d0c514d820a18a9b9a5ef864315"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:54a1e09ab7a69f843cd28fefd2bcaf23edb9e3a8d7680032c8968b8ac934587d"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:954b154a4533ef28bd3e83ffdf4eadf39deeda9e38fb8feaf066d6069885e034"}, - {file = "frozenlist-1.2.0-cp38-cp38-win32.whl", hash = "sha256:cb3957c39668d10e2b486acc85f94153520a23263b6401e8f59422ef65b9520d"}, - {file = "frozenlist-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0a7c7cce70e41bc13d7d50f0e5dd175f14a4f1837a8549b0936ed0cbe6170bf9"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4c457220468d734e3077580a3642b7f682f5fd9507f17ddf1029452450912cdc"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e74f8b4d8677ebb4015ac01fcaf05f34e8a1f22775db1f304f497f2f88fdc697"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fbd4844ff111449f3bbe20ba24fbb906b5b1c2384d0f3287c9f7da2354ce6d23"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0081a623c886197ff8de9e635528fd7e6a387dccef432149e25c13946cb0cd0"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b6e21e5770df2dea06cb7b6323fbc008b13c4a4e3b52cb54685276479ee7676"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:406aeb340613b4b559db78d86864485f68919b7141dec82aba24d1477fd2976f"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:878ebe074839d649a1cdb03a61077d05760624f36d196884a5cafb12290e187b"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1fef737fd1388f9b93bba8808c5f63058113c10f4e3c0763ced68431773f72f9"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a495c3d513573b0b3f935bfa887a85d9ae09f0627cf47cad17d0cc9b9ba5c38"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e7d0dd3e727c70c2680f5f09a0775525229809f1a35d8552b92ff10b2b14f2c2"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:66a518731a21a55b7d3e087b430f1956a36793acc15912e2878431c7aec54210"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94728f97ddf603d23c8c3dd5cae2644fa12d33116e69f49b1644a71bb77b89ae"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c1e8e9033d34c2c9e186e58279879d78c94dd365068a3607af33f2bc99357a53"}, - {file = "frozenlist-1.2.0-cp39-cp39-win32.whl", hash = "sha256:83334e84a290a158c0c4cc4d22e8c7cfe0bba5b76d37f1c2509dabd22acafe15"}, - {file = "frozenlist-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:735f386ec522e384f511614c01d2ef9cf799f051353876b4c6fb93ef67a6d1ee"}, - {file = "frozenlist-1.2.0.tar.gz", hash = "sha256:68201be60ac56aff972dc18085800b6ee07973c49103a8aba669dee3d71079de"}, -] +frozenlist = [] hexbytes = [ {file = "hexbytes-0.2.2-py3-none-any.whl", hash = "sha256:ef53c37ea9f316fff86fcb1df057b4c6ba454da348083e972031bbf7bc9c3acc"}, {file = "hexbytes-0.2.2.tar.gz", hash = "sha256:a5881304d186e87578fb263a85317c808cf130e1d4b3d37d30142ab0f7898d03"}, @@ -1464,28 +1327,12 @@ lru-dict = [ {file = "lru-dict-1.1.7.tar.gz", hash = "sha256:45b81f67d75341d4433abade799a47e9c42a9e22a118531dcb5e549864032d7c"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1494,27 +1341,14 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1524,12 +1358,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -1542,101 +1370,31 @@ multiaddr = [ {file = "multiaddr-0.0.9-py2.py3-none-any.whl", hash = "sha256:5c0f862cbcf19aada2a899f80ef896ddb2e85614e0c8f04dd287c06c69dac95b"}, {file = "multiaddr-0.0.9.tar.gz", hash = "sha256:30b2695189edc3d5b90f1c303abb8f02d963a3a4edf2e7178b975eb417ab0ecf"}, ] -multidict = [ - {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55"}, - {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e"}, - {file = "multidict-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9b668c065968c5979fe6b6fa6760bb6ab9aeb94b75b73c0a9c1acf6393ac3bf"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517d75522b7b18a3385726b54a081afd425d4f41144a5399e5abd97ccafdf36b"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b4ac3ba7a97b35a5ccf34f41b5a8642a01d1e55454b699e5e8e7a99b5a3acf5"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df23c83398715b26ab09574217ca21e14694917a0c857e356fd39e1c64f8283f"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e58a9b5cc96e014ddf93c2227cbdeca94b56a7eb77300205d6e4001805391747"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f76440e480c3b2ca7f843ff8a48dc82446b86ed4930552d736c0bac507498a52"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cfde464ca4af42a629648c0b0d79b8f295cf5b695412451716531d6916461628"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0fed465af2e0eb6357ba95795d003ac0bdb546305cc2366b1fc8f0ad67cc3fda"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b70913cbf2e14275013be98a06ef4b412329fe7b4f83d64eb70dce8269ed1e1a"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5635bcf1b75f0f6ef3c8a1ad07b500104a971e38d3683167b9454cb6465ac86"}, - {file = "multidict-5.2.0-cp310-cp310-win32.whl", hash = "sha256:77f0fb7200cc7dedda7a60912f2059086e29ff67cefbc58d2506638c1a9132d7"}, - {file = "multidict-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:9416cf11bcd73c861267e88aea71e9fcc35302b3943e45e1dbb4317f91a4b34f"}, - {file = "multidict-5.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd77c8f3cba815aa69cb97ee2b2ef385c7c12ada9c734b0f3b32e26bb88bbf1d"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98ec9aea6223adf46999f22e2c0ab6cf33f5914be604a404f658386a8f1fba37"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5283c0a00f48e8cafcecadebfa0ed1dac8b39e295c7248c44c665c16dc1138b"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f79c19c6420962eb17c7e48878a03053b7ccd7b69f389d5831c0a4a7f1ac0a1"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e4a67f1080123de76e4e97a18d10350df6a7182e243312426d508712e99988d4"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:94b117e27efd8e08b4046c57461d5a114d26b40824995a2eb58372b94f9fca02"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2e77282fd1d677c313ffcaddfec236bf23f273c4fba7cdf198108f5940ae10f5"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:116347c63ba049c1ea56e157fa8aa6edaf5e92925c9b64f3da7769bdfa012858"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:dc3a866cf6c13d59a01878cd806f219340f3e82eed514485e094321f24900677"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac42181292099d91217a82e3fa3ce0e0ddf3a74fd891b7c2b347a7f5aa0edded"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:f0bb0973f42ffcb5e3537548e0767079420aefd94ba990b61cf7bb8d47f4916d"}, - {file = "multidict-5.2.0-cp36-cp36m-win32.whl", hash = "sha256:ea21d4d5104b4f840b91d9dc8cbc832aba9612121eaba503e54eaab1ad140eb9"}, - {file = "multidict-5.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e6453f3cbeb78440747096f239d282cc57a2997a16b5197c9bc839099e1633d0"}, - {file = "multidict-5.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3def943bfd5f1c47d51fd324df1e806d8da1f8e105cc7f1c76a1daf0f7e17b0"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35591729668a303a02b06e8dba0eb8140c4a1bfd4c4b3209a436a02a5ac1de11"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8cacda0b679ebc25624d5de66c705bc53dcc7c6f02a7fb0f3ca5e227d80422"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:baf1856fab8212bf35230c019cde7c641887e3fc08cadd39d32a421a30151ea3"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43616aec0f0d53c411582c451f5d3e1123a68cc7b3475d6f7d97a626f8ff90d"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25cbd39a9029b409167aa0a20d8a17f502d43f2efebfe9e3ac019fe6796c59ac"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a2cbcfbea6dc776782a444db819c8b78afe4db597211298dd8b2222f73e9cd0"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d2d7d1fff8e09d99354c04c3fd5b560fb04639fd45926b34e27cfdec678a704"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a37e9a68349f6abe24130846e2f1d2e38f7ddab30b81b754e5a1fde32f782b23"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:637c1896497ff19e1ee27c1c2c2ddaa9f2d134bbb5e0c52254361ea20486418d"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9815765f9dcda04921ba467957be543423e5ec6a1136135d84f2ae092c50d87b"}, - {file = "multidict-5.2.0-cp37-cp37m-win32.whl", hash = "sha256:8b911d74acdc1fe2941e59b4f1a278a330e9c34c6c8ca1ee21264c51ec9b67ef"}, - {file = "multidict-5.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:380b868f55f63d048a25931a1632818f90e4be71d2081c2338fcf656d299949a"}, - {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e7d81ce5744757d2f05fc41896e3b2ae0458464b14b5a2c1e87a6a9d69aefaa8"}, - {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d1d55cdf706ddc62822d394d1df53573d32a7a07d4f099470d3cb9323b721b6"}, - {file = "multidict-5.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4771d0d0ac9d9fe9e24e33bed482a13dfc1256d008d101485fe460359476065"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7d57ea65744d249427793c042094c4016789eb2562576fb831870f9c878d9e"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdd68778f96216596218b4e8882944d24a634d984ee1a5a049b300377878fa7c"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecc99bce8ee42dcad15848c7885197d26841cb24fa2ee6e89d23b8993c871c64"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:067150fad08e6f2dd91a650c7a49ba65085303fcc3decbd64a57dc13a2733031"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:78c106b2b506b4d895ddc801ff509f941119394b89c9115580014127414e6c2d"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6c4fa1ec16e01e292315ba76eb1d012c025b99d22896bd14a66628b245e3e01"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b227345e4186809d31f22087d0265655114af7cda442ecaf72246275865bebe4"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:06560fbdcf22c9387100979e65b26fba0816c162b888cb65b845d3def7a54c9b"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7878b61c867fb2df7a95e44b316f88d5a3742390c99dfba6c557a21b30180cac"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:246145bff76cc4b19310f0ad28bd0769b940c2a49fc601b86bfd150cbd72bb22"}, - {file = "multidict-5.2.0-cp38-cp38-win32.whl", hash = "sha256:c30ac9f562106cd9e8071c23949a067b10211917fdcb75b4718cf5775356a940"}, - {file = "multidict-5.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:f19001e790013ed580abfde2a4465388950728861b52f0da73e8e8a9418533c0"}, - {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c1ff762e2ee126e6f1258650ac641e2b8e1f3d927a925aafcfde943b77a36d24"}, - {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd6c9c50bf2ad3f0448edaa1a3b55b2e6866ef8feca5d8dbec10ec7c94371d21"}, - {file = "multidict-5.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc66d4016f6e50ed36fb39cd287a3878ffcebfa90008535c62e0e90a7ab713ae"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9acb76d5f3dd9421874923da2ed1e76041cb51b9337fd7f507edde1d86535d6"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfc924a7e946dd3c6360e50e8f750d51e3ef5395c95dc054bc9eab0f70df4f9c"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32fdba7333eb2351fee2596b756d730d62b5827d5e1ab2f84e6cbb287cc67fe0"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b9aad49466b8d828b96b9e3630006234879c8d3e2b0a9d99219b3121bc5cdb17"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:93de39267c4c676c9ebb2057e98a8138bade0d806aad4d864322eee0803140a0"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9bef5cff994ca3026fcc90680e326d1a19df9841c5e3d224076407cc21471a1"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5f841c4f14331fd1e36cbf3336ed7be2cb2a8f110ce40ea253e5573387db7621"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:38ba256ee9b310da6a1a0f013ef4e422fca30a685bcbec86a969bd520504e341"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3bc3b1621b979621cee9f7b09f024ec76ec03cc365e638126a056317470bde1b"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6ee908c070020d682e9b42c8f621e8bb10c767d04416e2ebe44e37d0f44d9ad5"}, - {file = "multidict-5.2.0-cp39-cp39-win32.whl", hash = "sha256:1c7976cd1c157fa7ba5456ae5d31ccdf1479680dc9b8d8aa28afabc370df42b8"}, - {file = "multidict-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac"}, - {file = "multidict-5.2.0.tar.gz", hash = "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"}, -] +multidict = [] mypy = [ - {file = "mypy-0.930-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:221cc94dc6a801ccc2be7c0c9fd791c5e08d1fa2c5e1c12dec4eab15b2469871"}, - {file = "mypy-0.930-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db3a87376a1380f396d465bed462e76ea89f838f4c5e967d68ff6ee34b785c31"}, - {file = "mypy-0.930-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1d2296f35aae9802eeb1327058b550371ee382d71374b3e7d2804035ef0b830b"}, - {file = "mypy-0.930-cp310-cp310-win_amd64.whl", hash = "sha256:959319b9a3cafc33a8185f440a433ba520239c72e733bf91f9efd67b0a8e9b30"}, - {file = "mypy-0.930-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:45a4dc21c789cfd09b8ccafe114d6de66f0b341ad761338de717192f19397a8c"}, - {file = "mypy-0.930-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1e689e92cdebd87607a041585f1dc7339aa2e8a9f9bad9ba7e6ece619431b20c"}, - {file = "mypy-0.930-cp36-cp36m-win_amd64.whl", hash = "sha256:ed4e0ea066bb12f56b2812a15ff223c57c0a44eca817ceb96b214bb055c7051f"}, - {file = "mypy-0.930-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a9d8dffefba634b27d650e0de2564379a1a367e2e08d6617d8f89261a3bf63b2"}, - {file = "mypy-0.930-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b419e9721260161e70d054a15abbd50603c16f159860cfd0daeab647d828fc29"}, - {file = "mypy-0.930-cp37-cp37m-win_amd64.whl", hash = "sha256:601f46593f627f8a9b944f74fd387c9b5f4266b39abad77471947069c2fc7651"}, - {file = "mypy-0.930-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ea7199780c1d7940b82dbc0a4e37722b4e3851264dbba81e01abecc9052d8a7"}, - {file = "mypy-0.930-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:70b197dd8c78fc5d2daf84bd093e8466a2b2e007eedaa85e792e513a820adbf7"}, - {file = "mypy-0.930-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5feb56f8bb280468fe5fc8e6f56f48f99aa0df9eed3c507a11505ee4657b5380"}, - {file = "mypy-0.930-cp38-cp38-win_amd64.whl", hash = "sha256:2e9c5409e9cb81049bb03fa1009b573dea87976713e3898561567a86c4eaee01"}, - {file = "mypy-0.930-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:554873e45c1ca20f31ddf873deb67fa5d2e87b76b97db50669f0468ccded8fae"}, - {file = "mypy-0.930-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0feb82e9fa849affca7edd24713dbe809dce780ced9f3feca5ed3d80e40b777f"}, - {file = "mypy-0.930-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bc1a0607ea03c30225347334af66b0af12eefba018a89a88c209e02b7065ea95"}, - {file = "mypy-0.930-cp39-cp39-win_amd64.whl", hash = "sha256:f9f665d69034b1fcfdbcd4197480d26298bbfb5d2dfe206245b6498addb34999"}, - {file = "mypy-0.930-py3-none-any.whl", hash = "sha256:bf4a44e03040206f7c058d1f5ba02ef2d1820720c88bc4285c7d9a4269f54173"}, - {file = "mypy-0.930.tar.gz", hash = "sha256:51426262ae4714cc7dd5439814676e0992b55bcc0f6514eccb4cf8e0678962c2"}, + {file = "mypy-0.961-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:697540876638ce349b01b6786bc6094ccdaba88af446a9abb967293ce6eaa2b0"}, + {file = "mypy-0.961-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b117650592e1782819829605a193360a08aa99f1fc23d1d71e1a75a142dc7e15"}, + {file = "mypy-0.961-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bdd5ca340beffb8c44cb9dc26697628d1b88c6bddf5c2f6eb308c46f269bb6f3"}, + {file = "mypy-0.961-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3e09f1f983a71d0672bbc97ae33ee3709d10c779beb613febc36805a6e28bb4e"}, + {file = "mypy-0.961-cp310-cp310-win_amd64.whl", hash = "sha256:e999229b9f3198c0c880d5e269f9f8129c8862451ce53a011326cad38b9ccd24"}, + {file = "mypy-0.961-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b24be97351084b11582fef18d79004b3e4db572219deee0212078f7cf6352723"}, + {file = "mypy-0.961-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f4a21d01fc0ba4e31d82f0fff195682e29f9401a8bdb7173891070eb260aeb3b"}, + {file = "mypy-0.961-cp36-cp36m-win_amd64.whl", hash = "sha256:439c726a3b3da7ca84a0199a8ab444cd8896d95012c4a6c4a0d808e3147abf5d"}, + {file = "mypy-0.961-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a0b53747f713f490affdceef835d8f0cb7285187a6a44c33821b6d1f46ed813"}, + {file = "mypy-0.961-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e9f70df36405c25cc530a86eeda1e0867863d9471fe76d1273c783df3d35c2e"}, + {file = "mypy-0.961-cp37-cp37m-win_amd64.whl", hash = "sha256:b88f784e9e35dcaa075519096dc947a388319cb86811b6af621e3523980f1c8a"}, + {file = "mypy-0.961-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d5aaf1edaa7692490f72bdb9fbd941fbf2e201713523bdb3f4038be0af8846c6"}, + {file = "mypy-0.961-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9f5f5a74085d9a81a1f9c78081d60a0040c3efb3f28e5c9912b900adf59a16e6"}, + {file = "mypy-0.961-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f4b794db44168a4fc886e3450201365c9526a522c46ba089b55e1f11c163750d"}, + {file = "mypy-0.961-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:64759a273d590040a592e0f4186539858c948302c653c2eac840c7a3cd29e51b"}, + {file = "mypy-0.961-cp38-cp38-win_amd64.whl", hash = "sha256:63e85a03770ebf403291ec50097954cc5caf2a9205c888ce3a61bd3f82e17569"}, + {file = "mypy-0.961-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f1332964963d4832a94bebc10f13d3279be3ce8f6c64da563d6ee6e2eeda932"}, + {file = "mypy-0.961-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:006be38474216b833eca29ff6b73e143386f352e10e9c2fbe76aa8549e5554f5"}, + {file = "mypy-0.961-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9940e6916ed9371809b35b2154baf1f684acba935cd09928952310fbddaba648"}, + {file = "mypy-0.961-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a5ea0875a049de1b63b972456542f04643daf320d27dc592d7c3d9cd5d9bf950"}, + {file = "mypy-0.961-cp39-cp39-win_amd64.whl", hash = "sha256:1ece702f29270ec6af25db8cf6185c04c02311c6bb21a69f423d40e527b75c56"}, + {file = "mypy-0.961-py3-none-any.whl", hash = "sha256:03c6cc893e7563e7b2949b969e63f02c000b32502a1b4d1314cabe391aa87d66"}, + {file = "mypy-0.961.tar.gz", hash = "sha256:f730d56cb924d371c26b8eaddeea3cc07d78ff51c521c6d04899ac6904b75492"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, @@ -1657,40 +1415,12 @@ pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] -platformdirs = [ - {file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"}, - {file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"}, -] +platformdirs = [] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] -protobuf = [ - {file = "protobuf-3.19.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d80f80eb175bf5f1169139c2e0c5ada98b1c098e2b3c3736667f28cbbea39fc8"}, - {file = "protobuf-3.19.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a529e7df52204565bcd33738a7a5f288f3d2d37d86caa5d78c458fa5fabbd54d"}, - {file = "protobuf-3.19.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28ccea56d4dc38d35cd70c43c2da2f40ac0be0a355ef882242e8586c6d66666f"}, - {file = "protobuf-3.19.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b30a7de128c46b5ecb343917d9fa737612a6e8280f440874e5cc2ba0d79b8f6"}, - {file = "protobuf-3.19.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5935c8ce02e3d89c7900140a8a42b35bc037ec07a6aeb61cc108be8d3c9438a6"}, - {file = "protobuf-3.19.1-cp36-cp36m-win32.whl", hash = "sha256:74f33edeb4f3b7ed13d567881da8e5a92a72b36495d57d696c2ea1ae0cfee80c"}, - {file = "protobuf-3.19.1-cp36-cp36m-win_amd64.whl", hash = "sha256:038daf4fa38a7e818dd61f51f22588d61755160a98db087a046f80d66b855942"}, - {file = "protobuf-3.19.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e51561d72efd5bd5c91490af1f13e32bcba8dab4643761eb7de3ce18e64a853"}, - {file = "protobuf-3.19.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:6e8ea9173403219239cdfd8d946ed101f2ab6ecc025b0fda0c6c713c35c9981d"}, - {file = "protobuf-3.19.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db3532d9f7a6ebbe2392041350437953b6d7a792de10e629c1e4f5a6b1fe1ac6"}, - {file = "protobuf-3.19.1-cp37-cp37m-win32.whl", hash = "sha256:615b426a177780ce381ecd212edc1e0f70db8557ed72560b82096bd36b01bc04"}, - {file = "protobuf-3.19.1-cp37-cp37m-win_amd64.whl", hash = "sha256:d8919368410110633717c406ab5c97e8df5ce93020cfcf3012834f28b1fab1ea"}, - {file = "protobuf-3.19.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:71b0250b0cfb738442d60cab68abc166de43411f2a4f791d31378590bfb71bd7"}, - {file = "protobuf-3.19.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3cd0458870ea7d1c58e948ac8078f6ba8a7ecc44a57e03032ed066c5bb318089"}, - {file = "protobuf-3.19.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:655264ed0d0efe47a523e2255fc1106a22f6faab7cc46cfe99b5bae085c2a13e"}, - {file = "protobuf-3.19.1-cp38-cp38-win32.whl", hash = "sha256:b691d996c6d0984947c4cf8b7ae2fe372d99b32821d0584f0b90277aa36982d3"}, - {file = "protobuf-3.19.1-cp38-cp38-win_amd64.whl", hash = "sha256:e7e8d2c20921f8da0dea277dfefc6abac05903ceac8e72839b2da519db69206b"}, - {file = "protobuf-3.19.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fd390367fc211cc0ffcf3a9e149dfeca78fecc62adb911371db0cec5c8b7472d"}, - {file = "protobuf-3.19.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d83e1ef8cb74009bebee3e61cc84b1c9cd04935b72bca0cbc83217d140424995"}, - {file = "protobuf-3.19.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36d90676d6f426718463fe382ec6274909337ca6319d375eebd2044e6c6ac560"}, - {file = "protobuf-3.19.1-cp39-cp39-win32.whl", hash = "sha256:e7b24c11df36ee8e0c085e5b0dc560289e4b58804746fb487287dda51410f1e2"}, - {file = "protobuf-3.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:77d2fadcf369b3f22859ab25bd12bb8e98fb11e05d9ff9b7cd45b711c719c002"}, - {file = "protobuf-3.19.1-py2.py3-none-any.whl", hash = "sha256:e813b1c9006b6399308e917ac5d298f345d95bb31f46f02b60cd92970a9afa17"}, - {file = "protobuf-3.19.1.tar.gz", hash = "sha256:62a8e4baa9cb9e064eb62d1002eca820857ab2138440cb4b3ea4243830f94ca7"}, -] +protobuf = [] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, @@ -1699,38 +1429,7 @@ pycodestyle = [ {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, ] -pycryptodome = [ - {file = "pycryptodome-3.12.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:90ad3381ccdc6a24cc2841e295706a168f32abefe64c679695712acac71fd5da"}, - {file = "pycryptodome-3.12.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e80f7469b0b3ea0f694230477d8501dc5a30a717e94fddd4821e6721f3053eae"}, - {file = "pycryptodome-3.12.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:b91404611767a7485837a6f1fd20cf9a5ae0ad362040a022cd65827ecb1b0d00"}, - {file = "pycryptodome-3.12.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:db66ccda65d5d20c17b00768e462a86f6f540f9aea8419a7f76cc7d9effd82cd"}, - {file = "pycryptodome-3.12.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:dc88355c4b261ed259268e65705b28b44d99570337694d593f06e3b1698eaaf3"}, - {file = "pycryptodome-3.12.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:6f8f5b7b53516da7511951910ab458e799173722c91fea54e2ba2f56d102e4aa"}, - {file = "pycryptodome-3.12.0-cp27-cp27m-win32.whl", hash = "sha256:93acad54a72d81253242eb0a15064be559ec9d989e5173286dc21cad19f01765"}, - {file = "pycryptodome-3.12.0-cp27-cp27m-win_amd64.whl", hash = "sha256:5a8c24d39d4a237dbfe181ea6593792bf9b5582c7fcfa7b8e0e12fda5eec07af"}, - {file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:32d15da81959faea6cbed95df2bb44f7f796211c110cf90b5ad3b2aeeb97fc8e"}, - {file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:aed7eb4b64c600fbc5e6d4238991ad1b4179a558401f203d1fcbd24883748982"}, - {file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:341c6bbf932c406b4f3ee2372e8589b67ac0cf4e99e7dc081440f43a3cde9f0f"}, - {file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:de0b711d673904dd6c65307ead36cb76622365a393569bf880895cba21195b7a"}, - {file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:3558616f45d8584aee3eba27559bc6fd0ba9be6c076610ed3cc62bd5229ffdc3"}, - {file = "pycryptodome-3.12.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a78e4324e566b5fbc2b51e9240950d82fa9e1c7eb77acdf27f58712f65622c1d"}, - {file = "pycryptodome-3.12.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:3f2f3dd596c6128d91314e60a6bcf4344610ef0e97f4ae4dd1770f86dd0748d8"}, - {file = "pycryptodome-3.12.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:e05f994f30f1cda3cbe57441f41220d16731cf99d868bb02a8f6484c454c206b"}, - {file = "pycryptodome-3.12.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:4cded12e13785bbdf4ba1ff5fb9d261cd98162145f869e4fbc4a4b9083392f0b"}, - {file = "pycryptodome-3.12.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:1181c90d1a6aee68a84826825548d0db1b58d8541101f908d779d601d1690586"}, - {file = "pycryptodome-3.12.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:6bb0d340c93bcb674ea8899e2f6408ec64c6c21731a59481332b4b2a8143cc60"}, - {file = "pycryptodome-3.12.0-cp35-abi3-win32.whl", hash = "sha256:39da5807aa1ff820799c928f745f89432908bf6624b9e981d2d7f9e55d91b860"}, - {file = "pycryptodome-3.12.0-cp35-abi3-win_amd64.whl", hash = "sha256:212c7f7fe11cad9275fbcff50ca977f1c6643f13560d081e7b0f70596df447b8"}, - {file = "pycryptodome-3.12.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:b07a4238465eb8c65dd5df2ab8ba6df127e412293c0ed7656c003336f557a100"}, - {file = "pycryptodome-3.12.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:a6e1bcd9d5855f1a3c0f8d585f44c81b08f39a02754007f374fb8db9605ba29c"}, - {file = "pycryptodome-3.12.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:aceb1d217c3a025fb963849071446cf3aca1353282fe1c3cb7bd7339a4d47947"}, - {file = "pycryptodome-3.12.0-pp27-pypy_73-win32.whl", hash = "sha256:f699360ae285fcae9c8f53ca6acf33796025a82bb0ccd7c1c551b04c1726def3"}, - {file = "pycryptodome-3.12.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d845c587ceb82ac7cbac7d0bf8c62a1a0fe7190b028b322da5ca65f6e5a18b9e"}, - {file = "pycryptodome-3.12.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:d8083de50f6dec56c3c6f270fb193590999583a1b27c9c75bc0b5cac22d438cc"}, - {file = "pycryptodome-3.12.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:9ea2f6674c803602a7c0437fccdc2ea036707e60456974fe26ca263bd501ec45"}, - {file = "pycryptodome-3.12.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:5d4264039a2087977f50072aaff2346d1c1c101cb359f9444cf92e3d1f42b4cd"}, - {file = "pycryptodome-3.12.0.zip", hash = "sha256:12c7343aec5a3b3df5c47265281b12b611f26ec9367b6129199d67da54b768c1"}, -] +pycryptodome = [] pydata-sphinx-theme = [ {file = "pydata-sphinx-theme-0.6.3.tar.gz", hash = "sha256:32e0580ef985734d652eec2bf25e0995a330a9d4f76deaa353571ce8e180ab14"}, {file = "pydata_sphinx_theme-0.6.3-py3-none-any.whl", hash = "sha256:f0fee20dc33fa5efa6b9be57368be760d236d8b9c1486b14ad1d17b7e7e0db04"}, @@ -1739,10 +1438,7 @@ pyflakes = [ {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] -pygments = [ - {file = "Pygments-2.11.1-py3-none-any.whl", hash = "sha256:9135c1af61eec0f650cd1ea1ed8ce298e54d56bcd8cc2ef46edd7702c171337c"}, - {file = "Pygments-2.11.1.tar.gz", hash = "sha256:59b895e326f0fb0d733fd28c6839bd18ad0687ba20efc26d4277fd1d30b971f4"}, -] +pygments = [] pyparsing = [ {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, @@ -1855,22 +1551,13 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -soupsieve = [ - {file = "soupsieve-2.3.1-py3-none-any.whl", hash = "sha256:1a3cca2617c6b38c0343ed661b1fa5de5637f257d4fe22bd9f1338010a1efefb"}, - {file = "soupsieve-2.3.1.tar.gz", hash = "sha256:b8d49b1cd4f037c7082a9683dfa1801aa2597fb11c3a1155b7a5b94829b4f1f9"}, -] +soupsieve = [] sphinx = [ {file = "Sphinx-3.5.4-py3-none-any.whl", hash = "sha256:2320d4e994a191f4b4be27da514e46b3d6b420f2ff895d064f52415d342461e8"}, {file = "Sphinx-3.5.4.tar.gz", hash = "sha256:19010b7b9fa0dc7756a6e105b2aacd3a80f798af3c25c273be64d7beeb482cb1"}, ] -sphinx-book-theme = [ - {file = "sphinx-book-theme-0.1.3.tar.gz", hash = "sha256:2fa4320264f4e365959f6a1370df7f76922781f0cc755a9e0974b1b17fa99888"}, - {file = "sphinx_book_theme-0.1.3-py3-none-any.whl", hash = "sha256:ae530dcb78195723e335f1b9adeedfd46b3e1920fa5a566dd0ef1687ec546684"}, -] -sphinx-click = [ - {file = "sphinx-click-3.0.2.tar.gz", hash = "sha256:29896dd12bfaacb566a8c7af2e2b675d010d69b0c5aad3b52495d4842358b15b"}, - {file = "sphinx_click-3.0.2-py3-none-any.whl", hash = "sha256:8529a02bea8cd2cd47daba2f71d7935c727c89d70baabec7fca31af49a0c379f"}, -] +sphinx-book-theme = [] +sphinx-click = [] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, @@ -1899,10 +1586,7 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -tomli = [ - {file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"}, - {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, -] +tomli = [] toolz = [ {file = "toolz-0.11.2-py3-none-any.whl", hash = "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f"}, {file = "toolz-0.11.2.tar.gz", hash = "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33"}, @@ -1928,22 +1612,12 @@ typed-ast = [ {file = "typed_ast-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:b6d17f37f6edd879141e64a5db17b67488cfeffeedad8c5cec0392305e9bc775"}, {file = "typed_ast-1.5.1.tar.gz", hash = "sha256:484137cab8ecf47e137260daa20bafbba5f4e3ec7fda1c1e69ab299b75fa81c5"}, ] -typing-extensions = [ - {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, - {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, - {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, -] -urllib3 = [ - {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, - {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, -] +typing-extensions = [] +urllib3 = [] varint = [ {file = "varint-1.0.2.tar.gz", hash = "sha256:a6ecc02377ac5ee9d65a6a8ad45c9ff1dac8ccee19400a5950fb51d594214ca5"}, ] -web3 = [ - {file = "web3-5.25.0-py3-none-any.whl", hash = "sha256:24fdedb85eac0068f7c964e8b6713a5623e4a1e0d95ebabd1939fef933007c02"}, - {file = "web3-5.25.0.tar.gz", hash = "sha256:0e9ae7db064a3efee611af0c18d921cc7a4b320380a1f734b0c837518e62484b"}, -] +web3 = [] websockets = [ {file = "websockets-9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da"}, {file = "websockets-9.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4"}, diff --git a/pyproject.toml b/pyproject.toml index 964f7b4..130f47c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ python = "^3.7.2" web3 = "^5.23.0" click = "^8.0.3" python-dotenv = "*" +typing-extensions = "^4.3.0" [tool.poetry.dev-dependencies] mypy = "*" From f0f244fde910e9eb8ffe2814670e0bb730420a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 12:27:09 +0200 Subject: [PATCH 13/21] fix: fixed typing --- uniswap/decorators.py | 17 +++++++++-------- uniswap/types.py | 3 +-- uniswap/util.py | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/uniswap/decorators.py b/uniswap/decorators.py index dd448f0..da3ba4f 100644 --- a/uniswap/decorators.py +++ b/uniswap/decorators.py @@ -1,7 +1,8 @@ import functools -from typing import Callable, Any, List, TYPE_CHECKING, TypeVar +from typing import Callable, List, TYPE_CHECKING, TypeVar, Optional from typing_extensions import ParamSpec, Concatenate +from .types import AddressLike from .constants import ETH_ADDRESS if TYPE_CHECKING: @@ -13,15 +14,15 @@ def check_approval( - method: Callable[Concatenate[Uniswap, P], T] -) -> Callable[Concatenate[Uniswap, P], T]: + method: Callable[Concatenate["Uniswap", P], T] +) -> Callable[Concatenate["Uniswap", P], T]: """Decorator to check if user is approved for a token. It approves them if they need to be approved.""" @functools.wraps(method) - def approved(self: Any, *args: Any, **kwargs: Any) -> Any: + def approved(self: "Uniswap", *args: P.args, **kwargs: P.kwargs) -> T: # Check to see if the first token is actually ETH - token = args[0] if args[0] != ETH_ADDRESS else None + token: Optional[AddressLike] = args[0] if args[0] != ETH_ADDRESS else None # type: ignore token_two = None # Check second token, if needed @@ -42,11 +43,11 @@ def approved(self: Any, *args: Any, **kwargs: Any) -> Any: def supports( versions: List[int], ) -> Callable[ - [Callable[Concatenate[Uniswap, P], T]], Callable[Concatenate[Uniswap, P], T] + [Callable[Concatenate["Uniswap", P], T]], Callable[Concatenate["Uniswap", P], T] ]: def g( - f: Callable[Concatenate[Uniswap, P], T] - ) -> Callable[Concatenate[Uniswap, P], T]: + f: Callable[Concatenate["Uniswap", P], T] + ) -> Callable[Concatenate["Uniswap", P], T]: if f.__doc__ is None: f.__doc__ = "" f.__doc__ += """\n\n diff --git a/uniswap/types.py b/uniswap/types.py index 62f2b4d..d55ec98 100644 --- a/uniswap/types.py +++ b/uniswap/types.py @@ -1,6 +1,5 @@ from typing import Union -from web3.eth import Contract # noqa: F401 -from web3.types import Address, ChecksumAddress +from eth_typing.evm import Address, ChecksumAddress AddressLike = Union[Address, ChecksumAddress] diff --git a/uniswap/util.py b/uniswap/util.py index 1c7b710..47d5f1e 100644 --- a/uniswap/util.py +++ b/uniswap/util.py @@ -5,8 +5,9 @@ from web3 import Web3 from web3.exceptions import NameNotFound +from web3.contract import Contract -from .types import AddressLike, Address, Contract +from .types import AddressLike, Address def _str_to_addr(s: Union[AddressLike, str]) -> Address: From 208843c8b6e1530920e6558eb3d2dd0ce766560f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 14 Jul 2022 12:38:18 +0200 Subject: [PATCH 14/21] fix: switch from deprecated buildTransaction to build_transaction --- uniswap/uniswap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index b553360..609f92c 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -1110,11 +1110,11 @@ def _build_and_send_tx( """Build and send a transaction.""" if not tx_params: tx_params = self._get_tx_params() - transaction = function.buildTransaction(tx_params) + transaction = function.build_transaction(tx_params) if "gas" not in tx_params: # `use_estimate_gas` needs to be True for networks like Arbitrum (can't assume 250000 gas), - # but it breaks tests for unknown reasons because estimateGas takes forever on some tx's. + # but it breaks tests for unknown reasons because estimate_gas takes forever on some tx's. # Maybe an issue with ganache? (got GC warnings once...) if self.use_estimate_gas: # The Uniswap V3 UI uses 20% margin for transactions From 9edfbaa5354b2d2df70cccb06c19a4a4c33fc64d Mon Sep 17 00:00:00 2001 From: KeremP Date: Tue, 18 Jan 2022 00:51:38 -0500 Subject: [PATCH 15/21] feat: implemented V3 features, like create pool, mint/close liquidity position, TVL calculation (#264) implementing V3 features. added methods to fetch on-chain pool data feature: adding position miniting (WIP) WIP testing V3 pool position minting wip v3 features feat: create v3 pool and mint/add liquidity position fix: add 0x0 address assert in get_pool_instance feat: close v3 liquidity position minor cleanups add get_tvl_in_pool to return total value locked in pool implementing V3 features. added methods to fetch on-chain pool data feature: adding position miniting (WIP) WIP testing V3 pool position minting wip v3 features feat: create v3 pool and mint/add liquidity position feat: close v3 liquidity position minor cleanups fixing minor errors afer rebase cleanup asset amounts for tests fix: ensure asset amounts are correct for v3 liquidity position tests add tests for TVL calculations. include method for fetching TVL from V3 subgraph as on-chain method takes long to run add arbitrum subgraph endpoint fix typo skip tvl tests for now feat: get TVL on chain minor cleanups fix aribitrum multicall2 address. clean up TVL test update get_liquidity_positions to take arbitrary address param --- Makefile | 4 +- tests/test_uniswap.py | 143 +- uniswap/assets/uniswap-v3/multicall.abi | 313 +++++ .../uniswap-v3/nonFungiblePositionManager.abi | 1221 +++++++++++++++++ uniswap/constants.py | 19 + uniswap/uniswap.py | 554 +++++++- uniswap/util.py | 47 +- 7 files changed, 2288 insertions(+), 13 deletions(-) create mode 100644 uniswap/assets/uniswap-v3/multicall.abi create mode 100644 uniswap/assets/uniswap-v3/nonFungiblePositionManager.abi diff --git a/Makefile b/Makefile index aa3e4d5..7fbdeb8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: test typecheck lint precommit docs test: - poetry run pytest -v --maxfail=10 --cov=uniswap --cov-report html --cov-report term --cov-report xml + poetry run pytest -v --tb=line --maxfail=4 --cov=uniswap --cov-report html --cov-report term --cov-report xml typecheck: poetry run mypy --pretty @@ -21,4 +21,4 @@ precommit: make test docs: - cd docs/ && make html + cd docs/ && make html \ No newline at end of file diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index e7f0b76..a8989c1 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -1,3 +1,4 @@ +from async_timeout import timeout import pytest import os import subprocess @@ -11,11 +12,11 @@ from web3 import Web3 from web3.exceptions import NameNotFound -from uniswap import Uniswap -from uniswap.constants import ETH_ADDRESS +from uniswap import Uniswap, token +from uniswap.constants import ETH_ADDRESS, WETH9_ADDRESS from uniswap.exceptions import InsufficientBalance -from uniswap.util import _str_to_addr from uniswap.tokens import get_tokens +from uniswap.util import _str_to_addr, default_tick_range, _addr_to_str, _load_contract_erc20 logger = logging.getLogger(__name__) @@ -193,6 +194,60 @@ def test_get_raw_price(self, client: Uniswap, tokens, token0, token1, fee): r = client.get_raw_price(token0, token1, fee=fee) assert r + @pytest.mark.parametrize( + "token0, token1, kwargs", + [ + (weth, dai, {"fee": 500}), + ] + ) + def test_get_pool_instance(self, client, token0, token1, kwargs): + if client.version != 3: + pytest.skip("Not supported in this version of Uniswap") + r = client.get_pool_instance(token0, token1, **kwargs) + assert r + + @pytest.mark.parametrize( + "token0, token1, kwargs", + [ + (weth, dai, {"fee": 500}), + ] + ) + def test_get_pool_immutables(self, client, token0, token1, kwargs): + if client.version != 3: + pytest.skip("Not supported in this version of Uniswap") + pool = client.get_pool_instance(token0, token1, **kwargs) + r = client.get_pool_immutables(pool) + print(r) + assert r + + @pytest.mark.parametrize( + "token0, token1, kwargs", + [ + (weth, dai, {"fee": 500}), + ] + ) + def test_get_pool_state(self, client, token0, token1, kwargs): + if client.version != 3: + pytest.skip("Not supported in this version of Uniswap") + pool = client.get_pool_instance(token0, token1, **kwargs) + r = client.get_pool_state(pool) + print(r) + assert r + + @pytest.mark.parametrize( + "amount0, amount1, token0, token1, kwargs", + [ + (1, 10, weth, dai, {"fee":500}), + ] + ) + def test_mint_position(self, client, amount0, amount1, token0, token1, kwargs): + if client.version != 3: + pytest.skip("Not supported in this version of Uniswap") + pool = client.get_pool_instance(token0, token1, **kwargs) + r = client.mint_position(pool, amount0, amount1) + print(r) + assert r + # ------ ERC20 Pool ---------------------------------------------------------------- @pytest.mark.parametrize("token", [("UNI"), ("DAI")]) def test_get_ex_eth_balance( @@ -231,6 +286,80 @@ def test_get_exchange_rate( assert r # ------ Liquidity ----------------------------------------------------------------- + @pytest.mark.parametrize( + "token0, token1, amount0, amount1, qty, fee", + [ + ('DAI', 'USDC', ONE_ETH, ONE_USDC, ONE_ETH, 3000), + ] + ) + def test_v3_deploy_pool_with_liquidity(self, client: Uniswap, tokens, token0, token1, amount0, amount1, qty, fee): + if client.version != 3: + pytest.skip("Not supported in this version of Uniswap") + + try: + pool = client.create_pool_instance(tokens[token0], tokens[token1], fee) + except Exception: + pool = client.get_pool_instance(tokens[token0], tokens[token1], fee) + + print(pool.address) + # Ensuring client has sufficient balance of both tokens + eth_to_dai = client.make_trade(tokens['ETH'], tokens[token0], qty, client.address) + eth_to_dai_tx = client.w3.eth.wait_for_transaction_receipt(eth_to_dai, timeout=RECEIPT_TIMEOUT) + assert eth_to_dai_tx["status"] + dai_to_usdc = client.make_trade(tokens[token0], tokens[token1], qty*10, client.address) + dai_to_usdc_tx = client.w3.eth.wait_for_transaction_receipt(dai_to_usdc, timeout=RECEIPT_TIMEOUT) + assert dai_to_usdc_tx["status"] + + balance_0 = client.get_token_balance(tokens[token0]) + balance_1 = client.get_token_balance(tokens[token1]) + + assert balance_0 > amount0, f'Have: {balance_0} need {amount0}' + assert balance_1 > amount1, f'Have: {balance_1} need {amount1}' + + + min_tick, max_tick = default_tick_range(fee) + r = client.mint_liquidity( + pool, + amount0, + amount1, + tick_lower=min_tick, + tick_upper=max_tick, + deadline=2**64 + ) + assert r["status"] + + position_balance = client.nonFungiblePositionManager.functions.balanceOf(_addr_to_str(client.address)).call() + assert position_balance > 0 + + position_array = client.get_liquidity_positions() + assert len(position_array) > 0 + + + @pytest.mark.parametrize( + "deadline", + [(2**64)], + ) + def test_close_position(self, client: Uniswap, deadline): + if client.version != 3: + pytest.skip("Not supported in this version of Uniswap") + position_array = client.get_liquidity_positions() + tokenId = position_array[0] + r = client.close_position(tokenId, deadline=deadline) + assert r["status"] + + @pytest.mark.parametrize( + "token0, token1", + [("DAI", "USDC")] + ) + def test_get_tvl_in_pool_on_chain(self, client: Uniswap, tokens, token0, token1): + if client.version != 3: + pytest.skip("Not supported in this version of Uniswap") + + pool = client.get_pool_instance(tokens[token0], tokens[token1]) + tvl_0, tvl_1 = client.get_tvl_in_pool(pool) + assert tvl_0 > 0 + assert tvl_1 > 0 + @pytest.mark.skip @pytest.mark.parametrize( "token, max_eth", @@ -271,7 +400,7 @@ def test_remove_liquidity( # Token -> Token ("DAI", "USDC", ONE_ETH, None, does_not_raise), # Token -> ETH - ("USDC", "ETH", 100 * ONE_USDC, None, does_not_raise), + ("USDC", "ETH", ONE_USDC, None, does_not_raise), # ("ETH", "UNI", 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), # ("UNI", "ETH", 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), # ("DAI", "UNI", 0.00001 * ONE_ETH, ZERO_ADDRESS, does_not_raise), @@ -310,11 +439,11 @@ def test_make_trade( "input_token, output_token, qty, recipient, expectation", [ # ETH -> Token - ("ETH", "DAI", 10 ** 18, None, does_not_raise), + ("ETH", "DAI", ONE_ETH, None, does_not_raise), # Token -> Token ("DAI", "USDC", ONE_USDC, None, does_not_raise), # Token -> ETH - ("DAI", "ETH", 10 ** 16, None, does_not_raise), + ("DAI", "ETH", 100 * ONE_USDC, None, does_not_raise), # FIXME: These should probably be uncommented eventually # ("ETH", "UNI", int(0.000001 * ONE_ETH), ZERO_ADDRESS), # ("UNI", "ETH", int(0.000001 * ONE_ETH), ZERO_ADDRESS), @@ -322,7 +451,7 @@ def test_make_trade( ( "DAI", "ETH", - 10 * 10 ** 18, + 10 * ONE_ETH, None, lambda: pytest.raises(InsufficientBalance), ), diff --git a/uniswap/assets/uniswap-v3/multicall.abi b/uniswap/assets/uniswap-v3/multicall.abi new file mode 100644 index 0000000..2760624 --- /dev/null +++ b/uniswap/assets/uniswap-v3/multicall.abi @@ -0,0 +1,313 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "returnData", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "blockAndAggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall2.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getBlockHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockCoinbase", + "outputs": [ + { + "internalType": "address", + "name": "coinbase", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockDifficulty", + "outputs": [ + { + "internalType": "uint256", + "name": "difficulty", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockGasLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "gaslimit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "getEthBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastBlockHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryAggregate", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall2.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryBlockAndAggregate", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "internalType": "struct Multicall2.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/uniswap/assets/uniswap-v3/nonFungiblePositionManager.abi b/uniswap/assets/uniswap-v3/nonFungiblePositionManager.abi new file mode 100644 index 0000000..5412fa6 --- /dev/null +++ b/uniswap/assets/uniswap-v3/nonFungiblePositionManager.abi @@ -0,0 +1,1221 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_WETH9", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenDescriptor_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "DecreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "IncreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH9", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Max", + "type": "uint128" + } + ], + "internalType": "struct INonfungiblePositionManager.CollectParams", + "name": "params", + "type": "tuple" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "createAndInitializePoolIfNecessary", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct INonfungiblePositionManager.DecreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "decreaseLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct INonfungiblePositionManager.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct INonfungiblePositionManager.MintParams", + "name": "params", + "type": "tuple" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint96", + "name": "nonce", + "type": "uint96" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "refundETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Owed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Owed", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/uniswap/constants.py b/uniswap/constants.py index 3a51fad..d73d87e 100644 --- a/uniswap/constants.py +++ b/uniswap/constants.py @@ -56,3 +56,22 @@ "harmony_mainnet": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", "harmony_testnet": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", } + +MAX_UINT_128 = (2**128)-1 + +# Source: https://github.com/Uniswap/v3-core/blob/v1.0.0/contracts/libraries/TickMath.sol#L8-L11 +MIN_TICK = -887272 +MAX_TICK = -MIN_TICK + +# Source: https://github.com/Uniswap/v3-core/blob/v1.0.0/contracts/UniswapV3Factory.sol#L26-L31 +_tick_spacing = { + 500: 10, + 3_000: 60, + 10_000: 200 +} + +_tick_bitmap_range = { + 500: (-347, 346), + 3_000: (-58, 57), + 10_000: (-18, 17) +} diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index 609f92c..f2cda86 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -1,14 +1,18 @@ +from collections import namedtuple import os import time import logging import functools -from typing import List, Any, Optional, Union, Tuple, Iterable +from typing import List, Any, Optional, Sequence, Union, Tuple, Iterable, Dict from web3 import Web3 +from web3._utils.abi import map_abi_data +from web3._utils.normalizers import BASE_RETURN_NORMALIZERS from web3.contract import Contract, ContractFunction from web3.exceptions import BadFunctionCallOutput, ContractLogicError from web3.types import ( TxParams, + TxReceipt, Wei, Nonce, ) @@ -25,14 +29,24 @@ _validate_address, _load_contract, _load_contract_erc20, + chunks, + encode_sqrt_ratioX96, + get_max_tick, is_same_address, + nearest_tick, ) from .decorators import supports, check_approval from .constants import ( + MAX_TICK, + MAX_UINT_128, + MIN_TICK, + WETH9_ADDRESS, _netid_to_name, _factory_contract_addresses_v1, _factory_contract_addresses_v2, _router_contract_addresses_v2, + _tick_spacing, + _tick_bitmap_range, ETH_ADDRESS, ) @@ -168,6 +182,21 @@ def __init__( self.router = _load_contract( self.w3, abi_name="uniswap-v3/router", address=self.router_address ) + self.positionManager_addr = _str_to_addr("0xC36442b4a4522E871399CD717aBDD847Ab11FE88") + self.nonFungiblePositionManager = _load_contract( + self.w3, abi_name="uniswap-v3/nonFungiblePositionManager", address=self.positionManager_addr + ) + if self.netname == 'arbitrum': + multicall2_addr = _str_to_addr("0x50075F151ABC5B6B448b1272A0a1cFb5CFA25828") + else: + multicall2_addr = _str_to_addr("0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696") + self.multicall2 = _load_contract( + self.w3, abi_name="uniswap-v3/multicall", address=multicall2_addr + ) + else: + raise Exception( + f"Invalid version '{self.version}', only 1, 2 or 3 supported" + ) if hasattr(self, "factory_contract"): logger.info(f"Using factory contract: {self.factory_contract}") @@ -430,6 +459,7 @@ def make_trade( input_token, qty, recipient, fee, slippage, fee_on_transfer ) else: + print(input_token) return self._token_to_token_swap_input( input_token, output_token, @@ -1063,6 +1093,239 @@ def remove_liquidity(self, token: str, max_token: int) -> HexBytes: ) return self._build_and_send_tx(function) + @supports([3]) + def mint_liquidity( + self, + pool: Contract, + amount_0: int, + amount_1: int, + tick_lower: int, + tick_upper: int, + deadline: int = 2**64 + ) -> TxReceipt: + """ + add liquidity to pool and mint position nft + """ + + token_0 = pool.functions.token0().call() + token_1 = pool.functions.token1().call() + token_0_instance = _load_contract( + self.w3, abi_name="erc20", address=token_0 + ) + token_1_instance = _load_contract( + self.w3, abi_name="erc20", address=token_1 + ) + + balance_0 = self.get_token_balance(token_0) + balance_1 = self.get_token_balance(token_1) + + assert balance_0 > amount_0, f'Have {balance_0}, need {amount_0}: {token_0}' + assert balance_1 > amount_1, f'Have {balance_1}, need {amount_1}: {token_1}' + + fee = pool.functions.fee().call() + tick_lower = nearest_tick(tick_lower, fee) + tick_upper = nearest_tick(tick_upper, fee) + assert tick_lower < tick_upper, "Invalid tick range" + + *_, isInit = pool.functions.slot0().call() + # If pool is not initialized, init pool w/ sqrt_price_x96 encoded from amount_0 & amount_1 + if isInit is False: + sqrt_pricex96 = encode_sqrt_ratioX96(amount_0, amount_1) + pool.functions.initialize(sqrt_pricex96).transact({'from':_addr_to_str(self.address)}) + + nft_manager = self.nonFungiblePositionManager + token_0_instance.functions.approve(nft_manager.address, amount_0).transact({'from':_addr_to_str(self.address)}) + token_1_instance.functions.approve(nft_manager.address, amount_1).transact({'from':_addr_to_str(self.address)}) + + # TODO: add slippage param + tx_hash = nft_manager.functions.mint( + ( + token_0, + token_1, + fee, + tick_lower, + tick_upper, + amount_0, + amount_1, + 0, + 0, + self.address, + deadline + ) + ).transact({'from':_addr_to_str(self.address)}) + receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash) + return receipt + + # TODO: should this be multiple functions? + @supports([3]) + def close_position( + self, + tokenId: int, + amount0Min: int = 0, + amount1Min: int = 0, + deadline: int = None + ) -> TxReceipt: + """ + remove all liquidity from the position associated w/ tokenId, collect fees, and burn token. + """ + position = self.nonFungiblePositionManager.functions.positions(tokenId).call() + + if deadline is None: + deadline = self._deadline() + + # If collecting fees in ETH, fees must be precomputed to protect against reentrancy + # source: https://docs.uniswap.org/sdk/guides/liquidity/removing + + if position[2] == WETH9_ADDRESS or position[3] == WETH9_ADDRESS: + amount0Min, amount1Min = self.nonFungiblePositionManager.functions.collect(( + tokenId,_addr_to_str(self.address),MAX_UINT_128,MAX_UINT_128 + )).call() + + tx_remove_liquidity = self.nonFungiblePositionManager.functions.decreaseLiquidity(( + tokenId, position[7], amount0Min, amount1Min, deadline + )).transact({"from":_addr_to_str(self.address)}) + self.w3.eth.wait_for_transaction_receipt(tx_remove_liquidity) + + tx_collect_fees = self.nonFungiblePositionManager.functions.collect(( + tokenId,_addr_to_str(self.address),MAX_UINT_128,MAX_UINT_128 + )).transact({"from":_addr_to_str(self.address)}) + self.w3.eth.wait_for_transaction_receipt(tx_collect_fees) + + tx_burn = self.nonFungiblePositionManager.functions.burn(tokenId).transact({"from":_addr_to_str(self.address)}) + receipt = self.w3.eth.wait_for_transaction_receipt(tx_burn) + + return receipt + + # Below two functions derived from: https://stackoverflow.com/questions/71814845/how-to-calculate-uniswap-v3-pools-total-value-locked-tvl-on-chain + def get_token0_in_pool(self, liquidity: float, sqrtPrice: float, sqrtPriceLow: float, sqrtPriceHigh: float) -> float: + sqrtPrice = max(min(sqrtPrice, sqrtPriceHigh), sqrtPriceLow) + return liquidity * (sqrtPriceHigh - sqrtPrice) / (sqrtPrice * sqrtPriceHigh) + + def get_token1_in_pool(self, liquidity: float, sqrtPrice: float, sqrtPriceLow: float, sqrtPriceHigh: float) -> float: + sqrtPrice = max(min(sqrtPrice, sqrtPriceHigh), sqrtPriceLow) + return liquidity * (sqrtPrice - sqrtPriceLow) + + # Find maximum tick of the word at the largest index (wordPos) in the tickBitmap that contains an initialized tick + def get_max_tick_from_wordpos(self, wordPos: int, bitmap: str, tick_spacing: int, fee: int) -> int: + compressed_tick = wordPos << 8 + _tick = compressed_tick * tick_spacing + min_tick_in_word = nearest_tick(_tick, fee) + max_tick_in_word = min_tick_in_word + (len(bitmap) * tick_spacing) + return max_tick_in_word + + # Find minimum tick of word at the smallest index (wordPos) in the tickBitmap that contains an initialized tick + def get_min_tick_from_wordpos(self, wordPos: int, tick_spacing: int, fee: int) -> int: + compressed_tick = wordPos << 8 + _tick = compressed_tick * tick_spacing + min_tick_in_word = nearest_tick(_tick, fee) + return min_tick_in_word + + # Find min or max tick in initialized tick range using the tickBitmap + def find_tick_from_bitmap(self, bitmap_spacing: Tuple[int, int], pool: Contract, tick_spacing: int, fee: int, left: bool = True) -> Union[int, bool]: + # searching to the left (finding max tick) + if left: + min_wordPos = bitmap_spacing[1] + max_wordPos = bitmap_spacing[0] + step = -1 + # searching to the right (finding min tick) + else: + min_wordPos = bitmap_spacing[0] + max_wordPos = bitmap_spacing[1] + step = 1 + + # Some fun tickBitmap hacks below. + # Iterate thru each possible wordPos (based on tick_spacing), get the bitmap "word" (basically a sub-array of the full bitmap), + # check if there is an initialized tick, derive largest (or smallest) tick in this word + # + # Since wordPos (int16 index of tickBitmap mapping) are calculated by (tick/tickspacing) >> 8, deriving tick from wordPos + # is done by (wordPos << 8)*tickSpacing. This however does not find the precise tick (only a possible tick that could map to that bitmap sub-array, or word), + # thus we must calculate the nearest viable tick depending on the tick_spacing of the pool using nearest_tick(). + # If searching for the maximum tick, we must then add-back len(bitmap)*tick_spacing as each bit in the bitmap should correspond to a tick. + + for wordPos in range(min_wordPos, max_wordPos, step): + word = pool.functions.tickBitmap(wordPos).call() + bitmap = bin(word) + for bit in bitmap[3:]: + if int(bit) == 1: + if left: + _max_tick = self.get_max_tick_from_wordpos(wordPos, bitmap, tick_spacing, fee) + return _max_tick + else: + _min_tick = self.get_min_tick_from_wordpos(wordPos, tick_spacing, fee) + return _min_tick + return False + + def get_tvl_in_pool(self, pool: Contract) -> Tuple[float,float]: + """ + Iterate through each tick in a pool and calculate the TVL on-chain + + Note: the output of this function may differ from what is returned by the + UniswapV3 subgraph api (https://github.com/Uniswap/v3-subgraph/issues/74) + + Params + ------ + pool: Contract + pool contract instance to find TVL + """ + pool_tick_output_types = ( + 'uint128', + 'int128', + 'uint256', + 'uint256', + 'int56', + 'uint160', + 'uint32', + 'bool' + ) + + pool_immutables = self.get_pool_immutables(pool) + pool_state = self.get_pool_state(pool) + fee = pool_immutables['fee'] + sqrtPrice = pool_state['sqrtPriceX96'] / (1 << 96) + + token0_liquidity = 0.0 + token1_liquidity = 0.0 + liquidity_total = 0.0 + + TICK_SPACING = _tick_spacing[fee] + BITMAP_SPACING = _tick_bitmap_range[fee] + + _max_tick = self.find_tick_from_bitmap(BITMAP_SPACING, pool, TICK_SPACING, fee, True) + _min_tick = self.find_tick_from_bitmap(BITMAP_SPACING, pool, TICK_SPACING, fee, False) + assert _max_tick != False, "Error finding max tick" + assert _min_tick != False, "Error finding min tick" + + Batch = namedtuple("Batch", "ticks batchResults") + ticks = [] + # Batching pool.functions.tick() calls as these are the major bottleneck to performance + for batch in list(chunks(range(_min_tick, _max_tick, TICK_SPACING), 100)): + _batch = [] + _ticks = [] + for tick in batch: + _batch.append((pool.address, HexBytes(pool.functions.ticks(tick)._encode_transaction_data()))) + _ticks.append(tick) + ticks.append(Batch(_ticks, self.multicall(_batch, pool_tick_output_types))) + + for tickBatch in ticks: + tick_arr = tickBatch.ticks + for i in range(len(tick_arr)): + tick = tick_arr[i] + tickData = tickBatch.batchResults[i] + # source: https://stackoverflow.com/questions/71814845/how-to-calculate-uniswap-v3-pools-total-value-locked-tvl-on-chain + liquidityNet = tickData[1] + liquidity_total += liquidityNet + sqrtPriceLow = 1.0001 ** (tick // 2) + sqrtPriceHigh = 1.0001 ** ((tick + TICK_SPACING) // 2) + token0_liquidity += self.get_token0_in_pool(liquidity_total, sqrtPrice, sqrtPriceLow, sqrtPriceHigh) + token1_liquidity += self.get_token1_in_pool(liquidity_total, sqrtPrice, sqrtPriceLow, sqrtPriceHigh) + + # Correcting for each token's respective decimals + token0_decimals = _load_contract_erc20(self.w3, pool_immutables['token0']).functions.decimals().call() + token1_decimals = _load_contract_erc20(self.w3, pool_immutables['token1']).functions.decimals().call() + token0_liquidity = token0_liquidity // (10 ** token0_decimals) + token1_liquidity = token1_liquidity // (10**token1_decimals) + return (token0_liquidity, token1_liquidity) + # ------ Approval Utils ------------------------------------------------------------ def approve(self, token: AddressLike, max_approval: Optional[int] = None) -> None: """Give an exchange/router max approval of a token.""" @@ -1212,6 +1475,33 @@ def _calculate_max_output_token( # ------ Helpers ------------------------------------------------------------ + # Batch contract function calls to speed up large on-chain data queries + def multicall( + self, + encoded_functions:Sequence[Tuple[ChecksumAddress, bytes]], + output_types: Sequence[str] + ) -> List[Any]: + """ + Calls aggregate() on Uniswap Multicall2 contract + + Params + ------ + encoded_functions : Sequence[Tuple[ChecksumAddress, bytes]] + array of tuples containing address of contract and byte-encoded transaction data + + output_types: Sequence[str] + array of solidity output types for decoding (e.g. uint256, bool, etc.) + + returns decoded results + """ + params = [{"target":target, "callData":callData} for target,callData in encoded_functions] + _, results = self.multicall2.functions.aggregate(params).call(block_identifier="latest") + decoded_results = [self.w3.codec.decode_abi(output_types, multicall_result) for multicall_result in results] + normalized_results =[ map_abi_data( + BASE_RETURN_NORMALIZERS, output_types, decoded_result + ) for decoded_result in decoded_results] + return normalized_results + def get_token(self, address: AddressLike, abi_name: str = "erc20") -> ERC20Token: """ Retrieves metadata from the ERC20 contract of a given token, like its name, symbol, and decimals. @@ -1260,6 +1550,268 @@ def get_weth_address(self) -> ChecksumAddress: raise ValueError # pragma: no cover return address + @supports([3]) + def get_pool_instance( + self, token_0: AddressLike, token_1: AddressLike, fee: int = 3_000 + ) -> Contract: + """ + Returns an instance of a pool contract for a given token pair and fee. + Requires pair [token_in, token_out, fee] has a direct pool. + Will return 0x0 address if pool does not exist. + """ + + assert token_0 != token_1, "Token addresses cannot be the same" + assert fee in list(_tick_spacing.keys()), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" + + pool_address = self.factory_contract.functions.getPool(token_0, token_1, fee).call() + assert pool_address != ETH_ADDRESS, "0 address returned. Pool does not exist" + pool_instance = _load_contract( + self.w3, abi_name="uniswap-v3/pool", address=pool_address + ) + + return pool_instance + + @supports([3]) + def create_pool_instance( + self, token_0: AddressLike, token_1: AddressLike, fee: int = 3_000 + ) -> Contract: + """ + Creates and returns UniswapV3 Pool instance. Requires that fee is valid and no similar pool already exists. + + """ + address = _addr_to_str(self.address) + assert token_0 != token_1, "Token addresses cannot be the same" + assert fee in list(_tick_spacing.keys()), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" + + tx = self.factory_contract.functions.createPool(token_0, token_1, fee).transact({'from':address}) + receipt = self.w3.eth.wait_for_transaction_receipt(tx) + + event_logs = self.factory_contract.events.PoolCreated().processReceipt(receipt) + pool_address = event_logs[0]['args']['pool'] + pool_instance = _load_contract( + self.w3, abi_name="uniswap-v3/pool", address=pool_address + ) + + return pool_instance + + @supports([3]) + def create_pool_instance( + self, token_0: AddressLike, token_1: AddressLike, fee: int = 3_000 + ) -> Contract: + """ + Creates and returns UniswapV3 Pool instance. Requires that fee is valid and no similar pool already exists. + + """ + address = _addr_to_str(self.address) + assert token_0 != token_1, "Token addresses cannot be the same" + assert fee in list(_tick_spacing.keys()), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" + + tx = self.factory_contract.functions.createPool(token_0, token_1, fee).transact({'from':address}) + receipt = self.w3.eth.wait_for_transaction_receipt(tx) + + event_logs = self.factory_contract.events.PoolCreated().processReceipt(receipt) + pool_address = event_logs[0]['args']['pool'] + pool_instance = _load_contract( + self.w3, abi_name="uniswap-v3/pool", address=pool_address + ) + + return pool_instance + + @supports([3]) + def mint_liquidity( + self, + pool: Contract, + amount_0: int, + amount_1: int, + tick_lower: int, + tick_upper: int, + deadline: int = 2**64 + ) -> TxReceipt: + """ + add liquidity to pool and mint position nft + """ + address = _addr_to_str(self.address) + token_0 = pool.functions.token0().call() + token_1 = pool.functions.token1().call() + + token_0_instance = _load_contract( + self.w3, abi_name="erc20", address=token_0 + ) + token_1_instance = _load_contract( + self.w3, abi_name="erc20", address=token_1 + ) + + assert token_0_instance.functions.balanceOf(address).call() > amount_0 + assert token_1_instance.functions.balanceOf(address).call() > amount_1 + + fee = pool.functions.fee().call() + tick_lower = nearest_tick(tick_lower, fee) + tick_upper = nearest_tick(tick_upper, fee) + assert tick_lower < tick_upper, "Invalid tick range" + + *_, isInit = pool.functions.slot0().call() + # If pool is not initialized, init pool w/ sqrt_price_x96 encoded from amount_0 & amount_1 + if isInit is False: + sqrt_pricex96 = encode_sqrt_ratioX96(amount_0, amount_1) + pool.functions.initialize(sqrt_pricex96).transact({'from':address}) + + nft_manager = self.nonFungiblePositionManager + token_0_instance.functions.approve(nft_manager.address, amount_0).transact({'from':address}) + token_1_instance.functions.approve(nft_manager.address, amount_1).transact({'from':address}) + + # TODO: add slippage param + tx_hash = nft_manager.functions.mint( + ( + token_0, + token_1, + fee, + tick_lower, + tick_upper, + amount_0, + amount_1, + 0, + 0, + self.address, + deadline + ) + ).transact({'from':address}) + receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash) + + return receipt + + @supports([3]) + def get_pool_immutables( + self, pool: Contract + ) -> Dict: + """ + Fetch on-chain pool data. + """ + pool_immutables = { + 'factory': pool.functions.factory().call(), + 'token0': pool.functions.token0().call(), + 'token1': pool.functions.token1().call(), + 'fee': pool.functions.fee().call(), + 'tickSpacing': pool.functions.tickSpacing().call(), + 'maxLiquidityPerTick': pool.functions.maxLiquidityPerTick().call() + } + + return pool_immutables + + @supports([3]) + def get_pool_state( + self, pool: Contract + ) -> Dict: + """ + Fetch on-chain pool state. + """ + liquidity = pool.functions.liquidity().call() + slot = pool.functions.slot0().call() + pool_state = { + 'liquidity':liquidity, + 'sqrtPriceX96': slot[0], + 'tick': slot[1], + 'observationIndex': slot[2], + 'observationCardinality': slot[3], + 'observationCardinalityNext': slot[4], + 'feeProtocol': slot[5], + 'unlocked': slot[6] + } + + return pool_state + + @supports([3]) + def get_liquidity_positions(self, address: Optional[AddressLike] = None) -> List[int]: + """ + Enumerates liquidity position tokens owned by address. + Returns array of token IDs. + """ + if address is None: + address = self.address + + positions: List[int] = [] + number_of_positions = self.nonFungiblePositionManager.functions.balanceOf(_addr_to_str(address)).call() + if number_of_positions > 0: + for idx in range(number_of_positions): + position = self.nonFungiblePositionManager.functions.tokenOfOwnerByIndex(_addr_to_str(address), idx).call() + positions.append(position) + return positions + + @supports([3]) + def get_liquidity_positions(self) -> List[int]: + """ + Enumerates liquidity position tokens owned by address. + Returns array of token IDs. + """ + positions: List[int] = [] + number_of_positions = self.nonFungiblePositionManager.functions.balanceOf(_addr_to_str(self.address)).call() + if number_of_positions > 0: + for idx in range(number_of_positions): + position = self.nonFungiblePositionManager.functions.tokenOfOwnerByIndex(_addr_to_str(self.address), idx).call() + positions.append(position) + return positions + + # FIXME: mint call reverting - likely to do w/ passing struct args to contract function call + # FIXME: mint call reverting - likely due to handling of token amounts + + @supports([3]) + def mint_position( + self, pool: Contract, amount0: int, amount1: int + ) -> None: + + #TODO: add to constants.py + MIN_TICK = -887272 + MAX_TICK = -MIN_TICK + + pool_sate = self.get_pool_state(pool) + pool_immutables = self.get_pool_immutables(pool) + + token0 = pool_immutables['token0'] + token1 = pool_immutables['token1'] + fee = pool_immutables['fee'] + + positionManager = self.nonFungiblePositionManager + + approve0 = _load_contract_erc20(self.w3, token0).functions.approve( + self.positionManager_addr, amount0 + ) + logger.warning(f"Approving {_addr_to_str(token0)}...") + tx0 = self._build_and_send_tx(approve0) + self.w3.eth.wait_for_transaction_receipt(tx0, timeout=6000) + + approve1 = _load_contract_erc20(self.w3, token1).functions.approve( + self.positionManager_addr, amount1*1000 + ) + logger.warning(f"Approving {_addr_to_str(token1)}...") + tx1 = self._build_and_send_tx(approve1) + self.w3.eth.wait_for_transaction_receipt(tx1, timeout=6000) + + # tx_mint = pool.functions.mint(self.address, MIN_TICK, MAX_TICK, amount0,'').transact(); + + position = positionManager.encodeABI(fn_name="mint", args=[{'token0':token0,'token1':token1,'fee':fee,'tickLower':MIN_TICK,'tickUpper':MAX_TICK, + 'amount0Desired':amount0,'amount1Desired':amount1,'amount0Min':0,'amount1Min':0,'recipient':_addr_to_str(self.address),'deadline':self._deadline() + }]) + print(position) + + multicall = positionManager.functions.multicall([position]).transact({"from":_addr_to_str(self.address), "gas":417918}) + + print(multicall) + # mint_position = positionManager.functions.mint({'token0':token0,'token1':token1,'fee':fee,'tickLower':MIN_TICK,'tickUpper':MAX_TICK, + # 'amount0Desired':amount0,'amount1Desired':amount1,'amount0Min':0,'amount1Min':0,'recipient':_addr_to_str(self.address),'deadline':self._deadline() + # }) + + # mint_tx = self._build_and_send_tx(mint_position) + # self.w3.eth.wait_for_transaction_receipt(mint_tx, timeout=6000) + # + # tx2 = self._build_and_send_tx(multicall,) + # self.w3.eth.wait_for_transaction_receipt(tx2, timeout=6000) + + + # position = positionManager.functions.mint().buildTransaction() + # print(position['data']) + + + return multicall + @supports([2, 3]) def get_raw_price( self, token_in: AddressLike, token_out: AddressLike, fee: int = None diff --git a/uniswap/util.py b/uniswap/util.py index 47d5f1e..548d652 100644 --- a/uniswap/util.py +++ b/uniswap/util.py @@ -1,14 +1,15 @@ import os import json +import math import functools -from typing import Union, List, Tuple +from typing import Any, Dict, Generator, Iterable, Sequence, Union, List, Tuple from web3 import Web3 from web3.exceptions import NameNotFound from web3.contract import Contract -from .types import AddressLike, Address - +from .constants import MIN_TICK, MAX_TICK, _tick_spacing +from .types import AddressLike, Address, Contract def _str_to_addr(s: Union[AddressLike, str]) -> Address: """Idempotent""" @@ -65,3 +66,43 @@ def _encode_path(token_in: AddressLike, route: List[Tuple[int, AddressLike]]) -> https://github.com/Uniswap/uniswap-v3-sdk/blob/1a74d5f0a31040fec4aeb1f83bba01d7c03f4870/src/utils/encodeRouteToPath.ts """ raise NotImplementedError + +# Adapted from: https://github.com/Uniswap/v3-sdk/blob/main/src/utils/encodeSqrtRatioX96.ts +def encode_sqrt_ratioX96(amount_0: int, amount_1: int) -> int: + numerator = amount_1 << 192 + denominator = amount_0 + ratioX192 = numerator // denominator + return int(math.sqrt(ratioX192)) + +# Adapted from: https://github.com/tradingstrategy-ai/web3-ethereum-defi/blob/c3c68bc723d55dda0cc8252a0dadb534c4fdb2c5/eth_defi/uniswap_v3/utils.py#L77 +def get_min_tick(fee: int) -> int: + min_tick_spacing: int = _tick_spacing[fee] + return -(MIN_TICK // -min_tick_spacing) * min_tick_spacing + +def get_max_tick(fee: int) -> int: + max_tick_spacing: int = _tick_spacing[fee] + return (MAX_TICK // max_tick_spacing) * max_tick_spacing + +def default_tick_range(fee: int) -> Tuple[int, int]: + min_tick = get_min_tick(fee) + max_tick = get_max_tick(fee) + + return min_tick, max_tick + +def nearest_tick(tick: int, fee: int) -> int: + min_tick, max_tick = default_tick_range(fee) + assert min_tick <= tick <= max_tick, f'Provided tick is out of bounds: {(min_tick, max_tick)}' + + tick_spacing = _tick_spacing[fee] + rounded_tick_spacing = round(tick/tick_spacing) * tick_spacing + + if rounded_tick_spacing < min_tick: + return rounded_tick_spacing + tick_spacing + elif rounded_tick_spacing > max_tick: + return rounded_tick_spacing - tick_spacing + else: + return rounded_tick_spacing + +def chunks(arr: Sequence[Any], n: int) -> Generator: + for i in range(0, len(arr), n): + yield arr[i:i+n] From ee857fb25b9eb6316b271e8aa30edaa7cef7e3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Mon, 29 Aug 2022 10:01:38 +0200 Subject: [PATCH 16/21] fix: removed print in internal code --- uniswap/uniswap.py | 1 - 1 file changed, 1 deletion(-) diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index f2cda86..eaa93cd 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -459,7 +459,6 @@ def make_trade( input_token, qty, recipient, fee, slippage, fee_on_transfer ) else: - print(input_token) return self._token_to_token_swap_input( input_token, output_token, From 0d163c52c0acc59be15c17a54bf420825b5caa9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Mon, 29 Aug 2022 09:58:15 +0200 Subject: [PATCH 17/21] style: applied black --- uniswap/cli.py | 4 +- uniswap/constants.py | 14 +- uniswap/uniswap.py | 421 +++++++++++++++++++++---------------------- uniswap/util.py | 15 +- 4 files changed, 223 insertions(+), 231 deletions(-) diff --git a/uniswap/cli.py b/uniswap/cli.py index 76e18dd..4e22df0 100644 --- a/uniswap/cli.py +++ b/uniswap/cli.py @@ -80,7 +80,7 @@ def price( decimals = 18 else: decimals = uni.get_token(token_in).decimals - quantity = 10 ** decimals + quantity = 10**decimals price = uni.get_price_input(token_in, token_out, qty=quantity) if raw: click.echo(price) @@ -89,7 +89,7 @@ def price( decimals = 18 else: decimals = uni.get_token(token_out).decimals - click.echo(price / 10 ** decimals) + click.echo(price / 10**decimals) @main.command() diff --git a/uniswap/constants.py b/uniswap/constants.py index d73d87e..60fd4c3 100644 --- a/uniswap/constants.py +++ b/uniswap/constants.py @@ -57,21 +57,13 @@ "harmony_testnet": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", } -MAX_UINT_128 = (2**128)-1 +MAX_UINT_128 = (2**128) - 1 # Source: https://github.com/Uniswap/v3-core/blob/v1.0.0/contracts/libraries/TickMath.sol#L8-L11 MIN_TICK = -887272 MAX_TICK = -MIN_TICK # Source: https://github.com/Uniswap/v3-core/blob/v1.0.0/contracts/UniswapV3Factory.sol#L26-L31 -_tick_spacing = { - 500: 10, - 3_000: 60, - 10_000: 200 -} +_tick_spacing = {500: 10, 3_000: 60, 10_000: 200} -_tick_bitmap_range = { - 500: (-347, 346), - 3_000: (-58, 57), - 10_000: (-18, 17) -} +_tick_bitmap_range = {500: (-347, 346), 3_000: (-58, 57), 10_000: (-18, 17)} diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index eaa93cd..fa47fb1 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -182,14 +182,22 @@ def __init__( self.router = _load_contract( self.w3, abi_name="uniswap-v3/router", address=self.router_address ) - self.positionManager_addr = _str_to_addr("0xC36442b4a4522E871399CD717aBDD847Ab11FE88") + self.positionManager_addr = _str_to_addr( + "0xC36442b4a4522E871399CD717aBDD847Ab11FE88" + ) self.nonFungiblePositionManager = _load_contract( - self.w3, abi_name="uniswap-v3/nonFungiblePositionManager", address=self.positionManager_addr + self.w3, + abi_name="uniswap-v3/nonFungiblePositionManager", + address=self.positionManager_addr, ) - if self.netname == 'arbitrum': - multicall2_addr = _str_to_addr("0x50075F151ABC5B6B448b1272A0a1cFb5CFA25828") - else: - multicall2_addr = _str_to_addr("0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696") + if self.netname == "arbitrum": + multicall2_addr = _str_to_addr( + "0x50075F151ABC5B6B448b1272A0a1cFb5CFA25828" + ) + else: + multicall2_addr = _str_to_addr( + "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696" + ) self.multicall2 = _load_contract( self.w3, abi_name="uniswap-v3/multicall", address=multicall2_addr ) @@ -1100,7 +1108,7 @@ def mint_liquidity( amount_1: int, tick_lower: int, tick_upper: int, - deadline: int = 2**64 + deadline: int = 2**64, ) -> TxReceipt: """ add liquidity to pool and mint position nft @@ -1108,18 +1116,14 @@ def mint_liquidity( token_0 = pool.functions.token0().call() token_1 = pool.functions.token1().call() - token_0_instance = _load_contract( - self.w3, abi_name="erc20", address=token_0 - ) - token_1_instance = _load_contract( - self.w3, abi_name="erc20", address=token_1 - ) + token_0_instance = _load_contract(self.w3, abi_name="erc20", address=token_0) + token_1_instance = _load_contract(self.w3, abi_name="erc20", address=token_1) balance_0 = self.get_token_balance(token_0) balance_1 = self.get_token_balance(token_1) - assert balance_0 > amount_0, f'Have {balance_0}, need {amount_0}: {token_0}' - assert balance_1 > amount_1, f'Have {balance_1}, need {amount_1}: {token_1}' + assert balance_0 > amount_0, f"Have {balance_0}, need {amount_0}: {token_0}" + assert balance_1 > amount_1, f"Have {balance_1}, need {amount_1}: {token_1}" fee = pool.functions.fee().call() tick_lower = nearest_tick(tick_lower, fee) @@ -1130,11 +1134,17 @@ def mint_liquidity( # If pool is not initialized, init pool w/ sqrt_price_x96 encoded from amount_0 & amount_1 if isInit is False: sqrt_pricex96 = encode_sqrt_ratioX96(amount_0, amount_1) - pool.functions.initialize(sqrt_pricex96).transact({'from':_addr_to_str(self.address)}) + pool.functions.initialize(sqrt_pricex96).transact( + {"from": _addr_to_str(self.address)} + ) nft_manager = self.nonFungiblePositionManager - token_0_instance.functions.approve(nft_manager.address, amount_0).transact({'from':_addr_to_str(self.address)}) - token_1_instance.functions.approve(nft_manager.address, amount_1).transact({'from':_addr_to_str(self.address)}) + token_0_instance.functions.approve(nft_manager.address, amount_0).transact( + {"from": _addr_to_str(self.address)} + ) + token_1_instance.functions.approve(nft_manager.address, amount_1).transact( + {"from": _addr_to_str(self.address)} + ) # TODO: add slippage param tx_hash = nft_manager.functions.mint( @@ -1149,9 +1159,9 @@ def mint_liquidity( 0, 0, self.address, - deadline + deadline, ) - ).transact({'from':_addr_to_str(self.address)}) + ).transact({"from": _addr_to_str(self.address)}) receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash) return receipt @@ -1162,8 +1172,8 @@ def close_position( tokenId: int, amount0Min: int = 0, amount1Min: int = 0, - deadline: int = None - ) -> TxReceipt: + deadline: int = None, + ) -> TxReceipt: """ remove all liquidity from the position associated w/ tokenId, collect fees, and burn token. """ @@ -1176,36 +1186,54 @@ def close_position( # source: https://docs.uniswap.org/sdk/guides/liquidity/removing if position[2] == WETH9_ADDRESS or position[3] == WETH9_ADDRESS: - amount0Min, amount1Min = self.nonFungiblePositionManager.functions.collect(( - tokenId,_addr_to_str(self.address),MAX_UINT_128,MAX_UINT_128 - )).call() + amount0Min, amount1Min = self.nonFungiblePositionManager.functions.collect( + (tokenId, _addr_to_str(self.address), MAX_UINT_128, MAX_UINT_128) + ).call() - tx_remove_liquidity = self.nonFungiblePositionManager.functions.decreaseLiquidity(( - tokenId, position[7], amount0Min, amount1Min, deadline - )).transact({"from":_addr_to_str(self.address)}) + tx_remove_liquidity = ( + self.nonFungiblePositionManager.functions.decreaseLiquidity( + (tokenId, position[7], amount0Min, amount1Min, deadline) + ).transact({"from": _addr_to_str(self.address)}) + ) self.w3.eth.wait_for_transaction_receipt(tx_remove_liquidity) - tx_collect_fees = self.nonFungiblePositionManager.functions.collect(( - tokenId,_addr_to_str(self.address),MAX_UINT_128,MAX_UINT_128 - )).transact({"from":_addr_to_str(self.address)}) + tx_collect_fees = self.nonFungiblePositionManager.functions.collect( + (tokenId, _addr_to_str(self.address), MAX_UINT_128, MAX_UINT_128) + ).transact({"from": _addr_to_str(self.address)}) self.w3.eth.wait_for_transaction_receipt(tx_collect_fees) - tx_burn = self.nonFungiblePositionManager.functions.burn(tokenId).transact({"from":_addr_to_str(self.address)}) + tx_burn = self.nonFungiblePositionManager.functions.burn(tokenId).transact( + {"from": _addr_to_str(self.address)} + ) receipt = self.w3.eth.wait_for_transaction_receipt(tx_burn) return receipt # Below two functions derived from: https://stackoverflow.com/questions/71814845/how-to-calculate-uniswap-v3-pools-total-value-locked-tvl-on-chain - def get_token0_in_pool(self, liquidity: float, sqrtPrice: float, sqrtPriceLow: float, sqrtPriceHigh: float) -> float: + def get_token0_in_pool( + self, + liquidity: float, + sqrtPrice: float, + sqrtPriceLow: float, + sqrtPriceHigh: float, + ) -> float: sqrtPrice = max(min(sqrtPrice, sqrtPriceHigh), sqrtPriceLow) return liquidity * (sqrtPriceHigh - sqrtPrice) / (sqrtPrice * sqrtPriceHigh) - def get_token1_in_pool(self, liquidity: float, sqrtPrice: float, sqrtPriceLow: float, sqrtPriceHigh: float) -> float: + def get_token1_in_pool( + self, + liquidity: float, + sqrtPrice: float, + sqrtPriceLow: float, + sqrtPriceHigh: float, + ) -> float: sqrtPrice = max(min(sqrtPrice, sqrtPriceHigh), sqrtPriceLow) return liquidity * (sqrtPrice - sqrtPriceLow) # Find maximum tick of the word at the largest index (wordPos) in the tickBitmap that contains an initialized tick - def get_max_tick_from_wordpos(self, wordPos: int, bitmap: str, tick_spacing: int, fee: int) -> int: + def get_max_tick_from_wordpos( + self, wordPos: int, bitmap: str, tick_spacing: int, fee: int + ) -> int: compressed_tick = wordPos << 8 _tick = compressed_tick * tick_spacing min_tick_in_word = nearest_tick(_tick, fee) @@ -1213,14 +1241,23 @@ def get_max_tick_from_wordpos(self, wordPos: int, bitmap: str, tick_spacing: int return max_tick_in_word # Find minimum tick of word at the smallest index (wordPos) in the tickBitmap that contains an initialized tick - def get_min_tick_from_wordpos(self, wordPos: int, tick_spacing: int, fee: int) -> int: + def get_min_tick_from_wordpos( + self, wordPos: int, tick_spacing: int, fee: int + ) -> int: compressed_tick = wordPos << 8 _tick = compressed_tick * tick_spacing min_tick_in_word = nearest_tick(_tick, fee) return min_tick_in_word # Find min or max tick in initialized tick range using the tickBitmap - def find_tick_from_bitmap(self, bitmap_spacing: Tuple[int, int], pool: Contract, tick_spacing: int, fee: int, left: bool = True) -> Union[int, bool]: + def find_tick_from_bitmap( + self, + bitmap_spacing: Tuple[int, int], + pool: Contract, + tick_spacing: int, + fee: int, + left: bool = True, + ) -> Union[int, bool]: # searching to the left (finding max tick) if left: min_wordPos = bitmap_spacing[1] @@ -1247,14 +1284,18 @@ def find_tick_from_bitmap(self, bitmap_spacing: Tuple[int, int], pool: Contract, for bit in bitmap[3:]: if int(bit) == 1: if left: - _max_tick = self.get_max_tick_from_wordpos(wordPos, bitmap, tick_spacing, fee) + _max_tick = self.get_max_tick_from_wordpos( + wordPos, bitmap, tick_spacing, fee + ) return _max_tick else: - _min_tick = self.get_min_tick_from_wordpos(wordPos, tick_spacing, fee) + _min_tick = self.get_min_tick_from_wordpos( + wordPos, tick_spacing, fee + ) return _min_tick return False - def get_tvl_in_pool(self, pool: Contract) -> Tuple[float,float]: + def get_tvl_in_pool(self, pool: Contract) -> Tuple[float, float]: """ Iterate through each tick in a pool and calculate the TVL on-chain @@ -1267,20 +1308,20 @@ def get_tvl_in_pool(self, pool: Contract) -> Tuple[float,float]: pool contract instance to find TVL """ pool_tick_output_types = ( - 'uint128', - 'int128', - 'uint256', - 'uint256', - 'int56', - 'uint160', - 'uint32', - 'bool' - ) + "uint128", + "int128", + "uint256", + "uint256", + "int56", + "uint160", + "uint32", + "bool", + ) pool_immutables = self.get_pool_immutables(pool) pool_state = self.get_pool_state(pool) - fee = pool_immutables['fee'] - sqrtPrice = pool_state['sqrtPriceX96'] / (1 << 96) + fee = pool_immutables["fee"] + sqrtPrice = pool_state["sqrtPriceX96"] / (1 << 96) token0_liquidity = 0.0 token1_liquidity = 0.0 @@ -1289,8 +1330,12 @@ def get_tvl_in_pool(self, pool: Contract) -> Tuple[float,float]: TICK_SPACING = _tick_spacing[fee] BITMAP_SPACING = _tick_bitmap_range[fee] - _max_tick = self.find_tick_from_bitmap(BITMAP_SPACING, pool, TICK_SPACING, fee, True) - _min_tick = self.find_tick_from_bitmap(BITMAP_SPACING, pool, TICK_SPACING, fee, False) + _max_tick = self.find_tick_from_bitmap( + BITMAP_SPACING, pool, TICK_SPACING, fee, True + ) + _min_tick = self.find_tick_from_bitmap( + BITMAP_SPACING, pool, TICK_SPACING, fee, False + ) assert _max_tick != False, "Error finding max tick" assert _min_tick != False, "Error finding min tick" @@ -1301,7 +1346,12 @@ def get_tvl_in_pool(self, pool: Contract) -> Tuple[float,float]: _batch = [] _ticks = [] for tick in batch: - _batch.append((pool.address, HexBytes(pool.functions.ticks(tick)._encode_transaction_data()))) + _batch.append( + ( + pool.address, + HexBytes(pool.functions.ticks(tick)._encode_transaction_data()), + ) + ) _ticks.append(tick) ticks.append(Batch(_ticks, self.multicall(_batch, pool_tick_output_types))) @@ -1315,13 +1365,25 @@ def get_tvl_in_pool(self, pool: Contract) -> Tuple[float,float]: liquidity_total += liquidityNet sqrtPriceLow = 1.0001 ** (tick // 2) sqrtPriceHigh = 1.0001 ** ((tick + TICK_SPACING) // 2) - token0_liquidity += self.get_token0_in_pool(liquidity_total, sqrtPrice, sqrtPriceLow, sqrtPriceHigh) - token1_liquidity += self.get_token1_in_pool(liquidity_total, sqrtPrice, sqrtPriceLow, sqrtPriceHigh) + token0_liquidity += self.get_token0_in_pool( + liquidity_total, sqrtPrice, sqrtPriceLow, sqrtPriceHigh + ) + token1_liquidity += self.get_token1_in_pool( + liquidity_total, sqrtPrice, sqrtPriceLow, sqrtPriceHigh + ) # Correcting for each token's respective decimals - token0_decimals = _load_contract_erc20(self.w3, pool_immutables['token0']).functions.decimals().call() - token1_decimals = _load_contract_erc20(self.w3, pool_immutables['token1']).functions.decimals().call() - token0_liquidity = token0_liquidity // (10 ** token0_decimals) + token0_decimals = ( + _load_contract_erc20(self.w3, pool_immutables["token0"]) + .functions.decimals() + .call() + ) + token1_decimals = ( + _load_contract_erc20(self.w3, pool_immutables["token1"]) + .functions.decimals() + .call() + ) + token0_liquidity = token0_liquidity // (10**token0_decimals) token1_liquidity = token1_liquidity // (10**token1_decimals) return (token0_liquidity, token1_liquidity) @@ -1477,9 +1539,9 @@ def _calculate_max_output_token( # Batch contract function calls to speed up large on-chain data queries def multicall( self, - encoded_functions:Sequence[Tuple[ChecksumAddress, bytes]], - output_types: Sequence[str] - ) -> List[Any]: + encoded_functions: Sequence[Tuple[ChecksumAddress, bytes]], + output_types: Sequence[str], + ) -> List[Any]: """ Calls aggregate() on Uniswap Multicall2 contract @@ -1493,12 +1555,21 @@ def multicall( returns decoded results """ - params = [{"target":target, "callData":callData} for target,callData in encoded_functions] - _, results = self.multicall2.functions.aggregate(params).call(block_identifier="latest") - decoded_results = [self.w3.codec.decode_abi(output_types, multicall_result) for multicall_result in results] - normalized_results =[ map_abi_data( - BASE_RETURN_NORMALIZERS, output_types, decoded_result - ) for decoded_result in decoded_results] + params = [ + {"target": target, "callData": callData} + for target, callData in encoded_functions + ] + _, results = self.multicall2.functions.aggregate(params).call( + block_identifier="latest" + ) + decoded_results = [ + self.w3.codec.decode_abi(output_types, multicall_result) + for multicall_result in results + ] + normalized_results = [ + map_abi_data(BASE_RETURN_NORMALIZERS, output_types, decoded_result) + for decoded_result in decoded_results + ] return normalized_results def get_token(self, address: AddressLike, abi_name: str = "erc20") -> ERC20Token: @@ -1560,9 +1631,13 @@ def get_pool_instance( """ assert token_0 != token_1, "Token addresses cannot be the same" - assert fee in list(_tick_spacing.keys()), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" + assert fee in list( + _tick_spacing.keys() + ), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" - pool_address = self.factory_contract.functions.getPool(token_0, token_1, fee).call() + pool_address = self.factory_contract.functions.getPool( + token_0, token_1, fee + ).call() assert pool_address != ETH_ADDRESS, "0 address returned. Pool does not exist" pool_instance = _load_contract( self.w3, abi_name="uniswap-v3/pool", address=pool_address @@ -1576,40 +1651,20 @@ def create_pool_instance( ) -> Contract: """ Creates and returns UniswapV3 Pool instance. Requires that fee is valid and no similar pool already exists. - """ address = _addr_to_str(self.address) assert token_0 != token_1, "Token addresses cannot be the same" - assert fee in list(_tick_spacing.keys()), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" + assert fee in list( + _tick_spacing.keys() + ), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" - tx = self.factory_contract.functions.createPool(token_0, token_1, fee).transact({'from':address}) - receipt = self.w3.eth.wait_for_transaction_receipt(tx) - - event_logs = self.factory_contract.events.PoolCreated().processReceipt(receipt) - pool_address = event_logs[0]['args']['pool'] - pool_instance = _load_contract( - self.w3, abi_name="uniswap-v3/pool", address=pool_address + tx = self.factory_contract.functions.createPool(token_0, token_1, fee).transact( + {"from": address} ) - - return pool_instance - - @supports([3]) - def create_pool_instance( - self, token_0: AddressLike, token_1: AddressLike, fee: int = 3_000 - ) -> Contract: - """ - Creates and returns UniswapV3 Pool instance. Requires that fee is valid and no similar pool already exists. - - """ - address = _addr_to_str(self.address) - assert token_0 != token_1, "Token addresses cannot be the same" - assert fee in list(_tick_spacing.keys()), "Uniswap V3 only supports three levels of fees: 0.05%, 0.3%, 1%" - - tx = self.factory_contract.functions.createPool(token_0, token_1, fee).transact({'from':address}) receipt = self.w3.eth.wait_for_transaction_receipt(tx) event_logs = self.factory_contract.events.PoolCreated().processReceipt(receipt) - pool_address = event_logs[0]['args']['pool'] + pool_address = event_logs[0]["args"]["pool"] pool_instance = _load_contract( self.w3, abi_name="uniswap-v3/pool", address=pool_address ) @@ -1617,124 +1672,41 @@ def create_pool_instance( return pool_instance @supports([3]) - def mint_liquidity( - self, - pool: Contract, - amount_0: int, - amount_1: int, - tick_lower: int, - tick_upper: int, - deadline: int = 2**64 - ) -> TxReceipt: - """ - add liquidity to pool and mint position nft - """ - address = _addr_to_str(self.address) - token_0 = pool.functions.token0().call() - token_1 = pool.functions.token1().call() - - token_0_instance = _load_contract( - self.w3, abi_name="erc20", address=token_0 - ) - token_1_instance = _load_contract( - self.w3, abi_name="erc20", address=token_1 - ) - - assert token_0_instance.functions.balanceOf(address).call() > amount_0 - assert token_1_instance.functions.balanceOf(address).call() > amount_1 - - fee = pool.functions.fee().call() - tick_lower = nearest_tick(tick_lower, fee) - tick_upper = nearest_tick(tick_upper, fee) - assert tick_lower < tick_upper, "Invalid tick range" - - *_, isInit = pool.functions.slot0().call() - # If pool is not initialized, init pool w/ sqrt_price_x96 encoded from amount_0 & amount_1 - if isInit is False: - sqrt_pricex96 = encode_sqrt_ratioX96(amount_0, amount_1) - pool.functions.initialize(sqrt_pricex96).transact({'from':address}) - - nft_manager = self.nonFungiblePositionManager - token_0_instance.functions.approve(nft_manager.address, amount_0).transact({'from':address}) - token_1_instance.functions.approve(nft_manager.address, amount_1).transact({'from':address}) - - # TODO: add slippage param - tx_hash = nft_manager.functions.mint( - ( - token_0, - token_1, - fee, - tick_lower, - tick_upper, - amount_0, - amount_1, - 0, - 0, - self.address, - deadline - ) - ).transact({'from':address}) - receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash) - - return receipt - - @supports([3]) - def get_pool_immutables( - self, pool: Contract - ) -> Dict: + def get_pool_immutables(self, pool: Contract) -> Dict: """ Fetch on-chain pool data. """ pool_immutables = { - 'factory': pool.functions.factory().call(), - 'token0': pool.functions.token0().call(), - 'token1': pool.functions.token1().call(), - 'fee': pool.functions.fee().call(), - 'tickSpacing': pool.functions.tickSpacing().call(), - 'maxLiquidityPerTick': pool.functions.maxLiquidityPerTick().call() + "factory": pool.functions.factory().call(), + "token0": pool.functions.token0().call(), + "token1": pool.functions.token1().call(), + "fee": pool.functions.fee().call(), + "tickSpacing": pool.functions.tickSpacing().call(), + "maxLiquidityPerTick": pool.functions.maxLiquidityPerTick().call(), } return pool_immutables @supports([3]) - def get_pool_state( - self, pool: Contract - ) -> Dict: + def get_pool_state(self, pool: Contract) -> Dict: """ Fetch on-chain pool state. """ liquidity = pool.functions.liquidity().call() slot = pool.functions.slot0().call() pool_state = { - 'liquidity':liquidity, - 'sqrtPriceX96': slot[0], - 'tick': slot[1], - 'observationIndex': slot[2], - 'observationCardinality': slot[3], - 'observationCardinalityNext': slot[4], - 'feeProtocol': slot[5], - 'unlocked': slot[6] + "liquidity": liquidity, + "sqrtPriceX96": slot[0], + "tick": slot[1], + "observationIndex": slot[2], + "observationCardinality": slot[3], + "observationCardinalityNext": slot[4], + "feeProtocol": slot[5], + "unlocked": slot[6], } return pool_state - @supports([3]) - def get_liquidity_positions(self, address: Optional[AddressLike] = None) -> List[int]: - """ - Enumerates liquidity position tokens owned by address. - Returns array of token IDs. - """ - if address is None: - address = self.address - - positions: List[int] = [] - number_of_positions = self.nonFungiblePositionManager.functions.balanceOf(_addr_to_str(address)).call() - if number_of_positions > 0: - for idx in range(number_of_positions): - position = self.nonFungiblePositionManager.functions.tokenOfOwnerByIndex(_addr_to_str(address), idx).call() - positions.append(position) - return positions - @supports([3]) def get_liquidity_positions(self) -> List[int]: """ @@ -1742,10 +1714,16 @@ def get_liquidity_positions(self) -> List[int]: Returns array of token IDs. """ positions: List[int] = [] - number_of_positions = self.nonFungiblePositionManager.functions.balanceOf(_addr_to_str(self.address)).call() + number_of_positions = self.nonFungiblePositionManager.functions.balanceOf( + _addr_to_str(self.address) + ).call() if number_of_positions > 0: for idx in range(number_of_positions): - position = self.nonFungiblePositionManager.functions.tokenOfOwnerByIndex(_addr_to_str(self.address), idx).call() + position = ( + self.nonFungiblePositionManager.functions.tokenOfOwnerByIndex( + _addr_to_str(self.address), idx + ).call() + ) positions.append(position) return positions @@ -1753,20 +1731,18 @@ def get_liquidity_positions(self) -> List[int]: # FIXME: mint call reverting - likely due to handling of token amounts @supports([3]) - def mint_position( - self, pool: Contract, amount0: int, amount1: int - ) -> None: + def mint_position(self, pool: Contract, amount0: int, amount1: int) -> None: - #TODO: add to constants.py + # TODO: add to constants.py MIN_TICK = -887272 MAX_TICK = -MIN_TICK pool_sate = self.get_pool_state(pool) pool_immutables = self.get_pool_immutables(pool) - token0 = pool_immutables['token0'] - token1 = pool_immutables['token1'] - fee = pool_immutables['fee'] + token0 = pool_immutables["token0"] + token1 = pool_immutables["token1"] + fee = pool_immutables["fee"] positionManager = self.nonFungiblePositionManager @@ -1778,7 +1754,7 @@ def mint_position( self.w3.eth.wait_for_transaction_receipt(tx0, timeout=6000) approve1 = _load_contract_erc20(self.w3, token1).functions.approve( - self.positionManager_addr, amount1*1000 + self.positionManager_addr, amount1 * 1000 ) logger.warning(f"Approving {_addr_to_str(token1)}...") tx1 = self._build_and_send_tx(approve1) @@ -1786,12 +1762,29 @@ def mint_position( # tx_mint = pool.functions.mint(self.address, MIN_TICK, MAX_TICK, amount0,'').transact(); - position = positionManager.encodeABI(fn_name="mint", args=[{'token0':token0,'token1':token1,'fee':fee,'tickLower':MIN_TICK,'tickUpper':MAX_TICK, - 'amount0Desired':amount0,'amount1Desired':amount1,'amount0Min':0,'amount1Min':0,'recipient':_addr_to_str(self.address),'deadline':self._deadline() - }]) + position = positionManager.encodeABI( + fn_name="mint", + args=[ + { + "token0": token0, + "token1": token1, + "fee": fee, + "tickLower": MIN_TICK, + "tickUpper": MAX_TICK, + "amount0Desired": amount0, + "amount1Desired": amount1, + "amount0Min": 0, + "amount1Min": 0, + "recipient": _addr_to_str(self.address), + "deadline": self._deadline(), + } + ], + ) print(position) - multicall = positionManager.functions.multicall([position]).transact({"from":_addr_to_str(self.address), "gas":417918}) + multicall = positionManager.functions.multicall([position]).transact( + {"from": _addr_to_str(self.address), "gas": 417918} + ) print(multicall) # mint_position = positionManager.functions.mint({'token0':token0,'token1':token1,'fee':fee,'tickLower':MIN_TICK,'tickUpper':MAX_TICK, @@ -1804,11 +1797,9 @@ def mint_position( # tx2 = self._build_and_send_tx(multicall,) # self.w3.eth.wait_for_transaction_receipt(tx2, timeout=6000) - # position = positionManager.functions.mint().buildTransaction() # print(position['data']) - return multicall @supports([2, 3]) @@ -1845,7 +1836,7 @@ def get_raw_price( ).call() ) token_in_decimals = self.get_token(token_in).decimals - token_in_balance = token_in_balance / (10 ** token_in_decimals) + token_in_balance = token_in_balance / (10**token_in_decimals) token_out_erc20 = _load_contract_erc20( self.w3, self.w3.toChecksumAddress(token_out) @@ -1856,7 +1847,7 @@ def get_raw_price( ).call() ) token_out_decimals = self.get_token(token_out).decimals - token_out_balance = token_out_balance / (10 ** token_out_decimals) + token_out_balance = token_out_balance / (10**token_out_decimals) raw_price = token_out_balance / token_in_balance else: @@ -1878,8 +1869,8 @@ def get_raw_price( den0 = self.get_token(token_out).decimals den1 = self.get_token(token_in).decimals sqrtPriceX96 = pool_contract.functions.slot0().call()[0] - raw_price = (sqrtPriceX96 * sqrtPriceX96 * 10 ** den1 >> (96 * 2)) / ( - 10 ** den0 + raw_price = (sqrtPriceX96 * sqrtPriceX96 * 10**den1 >> (96 * 2)) / ( + 10**den0 ) if t1.lower() == token_in.lower(): raw_price = 1 / raw_price diff --git a/uniswap/util.py b/uniswap/util.py index 548d652..2f8fa48 100644 --- a/uniswap/util.py +++ b/uniswap/util.py @@ -11,6 +11,7 @@ from .constants import MIN_TICK, MAX_TICK, _tick_spacing from .types import AddressLike, Address, Contract + def _str_to_addr(s: Union[AddressLike, str]) -> Address: """Idempotent""" if isinstance(s, str): @@ -67,6 +68,7 @@ def _encode_path(token_in: AddressLike, route: List[Tuple[int, AddressLike]]) -> """ raise NotImplementedError + # Adapted from: https://github.com/Uniswap/v3-sdk/blob/main/src/utils/encodeSqrtRatioX96.ts def encode_sqrt_ratioX96(amount_0: int, amount_1: int) -> int: numerator = amount_1 << 192 @@ -74,27 +76,33 @@ def encode_sqrt_ratioX96(amount_0: int, amount_1: int) -> int: ratioX192 = numerator // denominator return int(math.sqrt(ratioX192)) + # Adapted from: https://github.com/tradingstrategy-ai/web3-ethereum-defi/blob/c3c68bc723d55dda0cc8252a0dadb534c4fdb2c5/eth_defi/uniswap_v3/utils.py#L77 def get_min_tick(fee: int) -> int: min_tick_spacing: int = _tick_spacing[fee] return -(MIN_TICK // -min_tick_spacing) * min_tick_spacing + def get_max_tick(fee: int) -> int: max_tick_spacing: int = _tick_spacing[fee] return (MAX_TICK // max_tick_spacing) * max_tick_spacing + def default_tick_range(fee: int) -> Tuple[int, int]: min_tick = get_min_tick(fee) max_tick = get_max_tick(fee) return min_tick, max_tick + def nearest_tick(tick: int, fee: int) -> int: min_tick, max_tick = default_tick_range(fee) - assert min_tick <= tick <= max_tick, f'Provided tick is out of bounds: {(min_tick, max_tick)}' + assert ( + min_tick <= tick <= max_tick + ), f"Provided tick is out of bounds: {(min_tick, max_tick)}" tick_spacing = _tick_spacing[fee] - rounded_tick_spacing = round(tick/tick_spacing) * tick_spacing + rounded_tick_spacing = round(tick / tick_spacing) * tick_spacing if rounded_tick_spacing < min_tick: return rounded_tick_spacing + tick_spacing @@ -103,6 +111,7 @@ def nearest_tick(tick: int, fee: int) -> int: else: return rounded_tick_spacing + def chunks(arr: Sequence[Any], n: int) -> Generator: for i in range(0, len(arr), n): - yield arr[i:i+n] + yield arr[i : i + n] From 1c9e5886242990b70c6b1d082c39ae9ea81c9274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Mon, 29 Aug 2022 11:47:05 +0200 Subject: [PATCH 18/21] fix: fixed lint and bug in tests --- tests/test_uniswap.py | 90 ++++++++++++++++++++++++++----------------- uniswap/uniswap.py | 5 --- uniswap/util.py | 3 +- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index a8989c1..d72ebb4 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -16,7 +16,12 @@ from uniswap.constants import ETH_ADDRESS, WETH9_ADDRESS from uniswap.exceptions import InsufficientBalance from uniswap.tokens import get_tokens -from uniswap.util import _str_to_addr, default_tick_range, _addr_to_str, _load_contract_erc20 +from uniswap.util import ( + _str_to_addr, + default_tick_range, + _addr_to_str, + _load_contract_erc20, +) logger = logging.getLogger(__name__) @@ -197,10 +202,11 @@ def test_get_raw_price(self, client: Uniswap, tokens, token0, token1, fee): @pytest.mark.parametrize( "token0, token1, kwargs", [ - (weth, dai, {"fee": 500}), - ] + ("WETH", "DAI", {"fee": 500}), + ], ) - def test_get_pool_instance(self, client, token0, token1, kwargs): + def test_get_pool_instance(self, client, tokens, token0, token1, kwargs): + token0, token1 = tokens[token0], tokens[token1] if client.version != 3: pytest.skip("Not supported in this version of Uniswap") r = client.get_pool_instance(token0, token1, **kwargs) @@ -209,10 +215,11 @@ def test_get_pool_instance(self, client, token0, token1, kwargs): @pytest.mark.parametrize( "token0, token1, kwargs", [ - (weth, dai, {"fee": 500}), - ] + ("WETH", "DAI", {"fee": 500}), + ], ) - def test_get_pool_immutables(self, client, token0, token1, kwargs): + def test_get_pool_immutables(self, client, tokens, token0, token1, kwargs): + token0, token1 = tokens[token0], tokens[token1] if client.version != 3: pytest.skip("Not supported in this version of Uniswap") pool = client.get_pool_instance(token0, token1, **kwargs) @@ -223,10 +230,11 @@ def test_get_pool_immutables(self, client, token0, token1, kwargs): @pytest.mark.parametrize( "token0, token1, kwargs", [ - (weth, dai, {"fee": 500}), - ] + ("WETH", "DAI", {"fee": 500}), + ], ) - def test_get_pool_state(self, client, token0, token1, kwargs): + def test_get_pool_state(self, client, tokens, token0, token1, kwargs): + token0, token1 = tokens[token0], tokens[token1] if client.version != 3: pytest.skip("Not supported in this version of Uniswap") pool = client.get_pool_instance(token0, token1, **kwargs) @@ -237,10 +245,13 @@ def test_get_pool_state(self, client, token0, token1, kwargs): @pytest.mark.parametrize( "amount0, amount1, token0, token1, kwargs", [ - (1, 10, weth, dai, {"fee":500}), - ] + (1, 10, "WETH", "DAI", {"fee": 500}), + ], ) - def test_mint_position(self, client, amount0, amount1, token0, token1, kwargs): + def test_mint_position( + self, client, tokens, amount0, amount1, token0, token1, kwargs + ): + token0, token1 = tokens[token0], tokens[token1] if client.version != 3: pytest.skip("Not supported in this version of Uniswap") pool = client.get_pool_instance(token0, token1, **kwargs) @@ -289,10 +300,12 @@ def test_get_exchange_rate( @pytest.mark.parametrize( "token0, token1, amount0, amount1, qty, fee", [ - ('DAI', 'USDC', ONE_ETH, ONE_USDC, ONE_ETH, 3000), - ] + ("DAI", "USDC", ONE_ETH, ONE_USDC, ONE_ETH, 3000), + ], ) - def test_v3_deploy_pool_with_liquidity(self, client: Uniswap, tokens, token0, token1, amount0, amount1, qty, fee): + def test_v3_deploy_pool_with_liquidity( + self, client: Uniswap, tokens, token0, token1, amount0, amount1, qty, fee + ): if client.version != 3: pytest.skip("Not supported in this version of Uniswap") @@ -303,41 +316,49 @@ def test_v3_deploy_pool_with_liquidity(self, client: Uniswap, tokens, token0, to print(pool.address) # Ensuring client has sufficient balance of both tokens - eth_to_dai = client.make_trade(tokens['ETH'], tokens[token0], qty, client.address) - eth_to_dai_tx = client.w3.eth.wait_for_transaction_receipt(eth_to_dai, timeout=RECEIPT_TIMEOUT) + eth_to_dai = client.make_trade( + tokens["ETH"], tokens[token0], qty, client.address + ) + eth_to_dai_tx = client.w3.eth.wait_for_transaction_receipt( + eth_to_dai, timeout=RECEIPT_TIMEOUT + ) assert eth_to_dai_tx["status"] - dai_to_usdc = client.make_trade(tokens[token0], tokens[token1], qty*10, client.address) - dai_to_usdc_tx = client.w3.eth.wait_for_transaction_receipt(dai_to_usdc, timeout=RECEIPT_TIMEOUT) + dai_to_usdc = client.make_trade( + tokens[token0], tokens[token1], qty * 10, client.address + ) + dai_to_usdc_tx = client.w3.eth.wait_for_transaction_receipt( + dai_to_usdc, timeout=RECEIPT_TIMEOUT + ) assert dai_to_usdc_tx["status"] balance_0 = client.get_token_balance(tokens[token0]) balance_1 = client.get_token_balance(tokens[token1]) - assert balance_0 > amount0, f'Have: {balance_0} need {amount0}' - assert balance_1 > amount1, f'Have: {balance_1} need {amount1}' - + assert balance_0 > amount0, f"Have: {balance_0} need {amount0}" + assert balance_1 > amount1, f"Have: {balance_1} need {amount1}" min_tick, max_tick = default_tick_range(fee) r = client.mint_liquidity( - pool, - amount0, - amount1, - tick_lower=min_tick, - tick_upper=max_tick, - deadline=2**64 + pool, + amount0, + amount1, + tick_lower=min_tick, + tick_upper=max_tick, + deadline=2 ** 64, ) assert r["status"] - position_balance = client.nonFungiblePositionManager.functions.balanceOf(_addr_to_str(client.address)).call() + position_balance = client.nonFungiblePositionManager.functions.balanceOf( + _addr_to_str(client.address) + ).call() assert position_balance > 0 position_array = client.get_liquidity_positions() assert len(position_array) > 0 - @pytest.mark.parametrize( "deadline", - [(2**64)], + [(2 ** 64)], ) def test_close_position(self, client: Uniswap, deadline): if client.version != 3: @@ -347,10 +368,7 @@ def test_close_position(self, client: Uniswap, deadline): r = client.close_position(tokenId, deadline=deadline) assert r["status"] - @pytest.mark.parametrize( - "token0, token1", - [("DAI", "USDC")] - ) + @pytest.mark.parametrize("token0, token1", [("DAI", "USDC")]) def test_get_tvl_in_pool_on_chain(self, client: Uniswap, tokens, token0, token1): if client.version != 3: pytest.skip("Not supported in this version of Uniswap") diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index fa47fb1..949224c 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -21,7 +21,6 @@ from .types import AddressLike from .token import ERC20Token -from .tokens import get_tokens from .exceptions import InvalidToken, InsufficientBalance from .util import ( _str_to_addr, @@ -31,15 +30,12 @@ _load_contract_erc20, chunks, encode_sqrt_ratioX96, - get_max_tick, is_same_address, nearest_tick, ) from .decorators import supports, check_approval from .constants import ( - MAX_TICK, MAX_UINT_128, - MIN_TICK, WETH9_ADDRESS, _netid_to_name, _factory_contract_addresses_v1, @@ -1737,7 +1733,6 @@ def mint_position(self, pool: Contract, amount0: int, amount1: int) -> None: MIN_TICK = -887272 MAX_TICK = -MIN_TICK - pool_sate = self.get_pool_state(pool) pool_immutables = self.get_pool_immutables(pool) token0 = pool_immutables["token0"] diff --git a/uniswap/util.py b/uniswap/util.py index 2f8fa48..1361c37 100644 --- a/uniswap/util.py +++ b/uniswap/util.py @@ -2,7 +2,7 @@ import json import math import functools -from typing import Any, Dict, Generator, Iterable, Sequence, Union, List, Tuple +from typing import Any, Generator, Sequence, Union, List, Tuple from web3 import Web3 from web3.exceptions import NameNotFound @@ -12,6 +12,7 @@ from .types import AddressLike, Address, Contract + def _str_to_addr(s: Union[AddressLike, str]) -> Address: """Idempotent""" if isinstance(s, str): From 212c10cdec6a94b5b3538ae075d5270e689932d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Mon, 29 Aug 2022 11:55:39 +0200 Subject: [PATCH 19/21] fix: fixed typing and imports --- tests/test_uniswap.py | 1 - uniswap/uniswap.py | 11 ++++------- uniswap/util.py | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/test_uniswap.py b/tests/test_uniswap.py index d72ebb4..f969375 100644 --- a/tests/test_uniswap.py +++ b/tests/test_uniswap.py @@ -1,4 +1,3 @@ -from async_timeout import timeout import pytest import os import subprocess diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index 949224c..ae5ad16 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -36,6 +36,8 @@ from .decorators import supports, check_approval from .constants import ( MAX_UINT_128, + MAX_TICK, + MIN_TICK, WETH9_ADDRESS, _netid_to_name, _factory_contract_addresses_v1, @@ -1727,12 +1729,7 @@ def get_liquidity_positions(self) -> List[int]: # FIXME: mint call reverting - likely due to handling of token amounts @supports([3]) - def mint_position(self, pool: Contract, amount0: int, amount1: int) -> None: - - # TODO: add to constants.py - MIN_TICK = -887272 - MAX_TICK = -MIN_TICK - + def mint_position(self, pool: Contract, amount0: int, amount1: int) -> HexBytes: pool_immutables = self.get_pool_immutables(pool) token0 = pool_immutables["token0"] @@ -1778,7 +1775,7 @@ def mint_position(self, pool: Contract, amount0: int, amount1: int) -> None: print(position) multicall = positionManager.functions.multicall([position]).transact( - {"from": _addr_to_str(self.address), "gas": 417918} + {"from": _addr_to_str(self.address), "gas": Wei(417918)} ) print(multicall) diff --git a/uniswap/util.py b/uniswap/util.py index 1361c37..2f65ab2 100644 --- a/uniswap/util.py +++ b/uniswap/util.py @@ -9,8 +9,7 @@ from web3.contract import Contract from .constants import MIN_TICK, MAX_TICK, _tick_spacing -from .types import AddressLike, Address, Contract - +from .types import AddressLike, Address def _str_to_addr(s: Union[AddressLike, str]) -> Address: From 0ab10b560fae016c56e169061bcd521854eb7df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Mon, 29 Aug 2022 11:59:55 +0200 Subject: [PATCH 20/21] build(deps): updated dependencies --- poetry.lock | 834 +++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 420 insertions(+), 416 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1c2354f..7bd4a89 100644 --- a/poetry.lock +++ b/poetry.lock @@ -60,7 +60,7 @@ python-versions = ">=3.5" [[package]] name = "atomicwrites" -version = "1.4.0" +version = "1.4.1" description = "Atomic file writes." category = "dev" optional = false @@ -68,25 +68,25 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "21.4.0" +version = "22.1.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] +tests_no_zope = ["cloudpickle", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] +tests = ["cloudpickle", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] +docs = ["sphinx-notfound-page", "zope.interface", "sphinx", "furo"] +dev = ["cloudpickle", "pre-commit", "sphinx-notfound-page", "sphinx", "furo", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] [[package]] name = "babel" -version = "2.9.1" +version = "2.10.3" description = "Internationalization utilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] pytz = ">=2015.7" @@ -104,11 +104,11 @@ tests = ["mypy", "PyHamcrest (>=2.0.2)", "pytest (>=4.6)", "pytest-benchmark", " [[package]] name = "beautifulsoup4" -version = "4.10.0" +version = "4.11.1" description = "Screen-scraping library" category = "dev" optional = false -python-versions = ">3.0.0" +python-versions = ">=3.6.0" [package.dependencies] soupsieve = ">1.2" @@ -119,7 +119,7 @@ lxml = ["lxml"] [[package]] name = "bitarray" -version = "1.2.2" +version = "2.6.0" description = "efficient arrays of booleans -- C extension" category = "main" optional = false @@ -127,57 +127,53 @@ python-versions = "*" [[package]] name = "black" -version = "21.12b0" +version = "22.6.0" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.6.2" [package.dependencies] -click = ">=7.1.2" +click = ">=8.0.0" mypy-extensions = ">=0.4.3" -pathspec = ">=0.9.0,<1" +pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = ">=0.2.6,<2.0.0" +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} -typing-extensions = [ - {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, - {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""}, -] +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -python2 = ["typed-ast (>=1.4.3)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2021.10.8" +version = "2022.6.15" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "charset-normalizer" -version = "2.0.9" +version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false -python-versions = ">=3.5.0" +python-versions = ">=3.6.0" [package.extras] unicode_backport = ["unicodedata2"] [[package]] name = "click" -version = "8.0.3" +version = "8.1.3" description = "Composable command line interface toolkit" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -185,7 +181,7 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.5" description = "Cross-platform colored terminal text." category = "main" optional = false @@ -193,7 +189,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.4.2" +version = "6.4.4" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -207,7 +203,7 @@ toml = ["tomli"] [[package]] name = "cytoolz" -version = "0.11.2" +version = "0.12.0" description = "Cython implementation of Toolz: High performance functional utilities" category = "main" optional = false @@ -221,7 +217,7 @@ cython = ["cython"] [[package]] name = "docutils" -version = "0.16" +version = "0.17.1" description = "Docutils -- Python Documentation Utilities" category = "dev" optional = false @@ -229,7 +225,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "eth-abi" -version = "2.1.1" +version = "2.2.0" description = "eth_abi: Python utilities for working with Ethereum ABI definitions, especially encoding and decoding" category = "main" optional = false @@ -241,15 +237,15 @@ eth-utils = ">=1.2.0,<2.0.0" parsimonious = ">=0.8.0,<0.9.0" [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "pytest (==4.4.1)", "pytest-pythonpath (>=0.7.1)", "pytest-xdist (==1.22.3)", "tox (>=2.9.1,<3)", "eth-hash", "hypothesis (>=3.6.1,<4)", "flake8 (==3.4.1)", "isort (>=4.2.15,<5)", "mypy (==0.701)", "pydocstyle (>=3.0.0,<4)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.4.1)", "isort (>=4.2.15,<5)", "mypy (==0.701)", "pydocstyle (>=3.0.0,<4)"] -test = ["pytest (==4.4.1)", "pytest-pythonpath (>=0.7.1)", "pytest-xdist (==1.22.3)", "tox (>=2.9.1,<3)", "eth-hash", "hypothesis (>=3.6.1,<4)"] -tools = ["hypothesis (>=3.6.1,<4)"] +tools = ["hypothesis (>=4.18.2,<5.0.0)"] +test = ["hypothesis (>=4.18.2,<5.0.0)", "eth-hash", "tox (>=2.9.1,<3)", "pytest-xdist (==1.22.3)", "pytest-pythonpath (>=0.7.1)", "pytest (==4.4.1)"] +lint = ["pydocstyle (>=3.0.0,<4)", "mypy (==0.910)", "isort (>=4.2.15,<5)", "flake8 (==4.0.1)"] +doc = ["towncrier (>=21,<22)", "sphinx-rtd-theme (>=0.1.9)", "jinja2 (>=3.0.0,<3.1.0)", "Sphinx (>=1.6.5,<2)"] +dev = ["towncrier (>=21,<22)", "sphinx-rtd-theme (>=0.1.9)", "jinja2 (>=3.0.0,<3.1.0)", "Sphinx (>=1.6.5,<2)", "pydocstyle (>=3.0.0,<4)", "mypy (==0.910)", "isort (>=4.2.15,<5)", "flake8 (==4.0.1)", "hypothesis (>=4.18.2,<5.0.0)", "eth-hash", "tox (>=2.9.1,<3)", "pytest-xdist (==1.22.3)", "pytest-pythonpath (>=0.7.1)", "pytest (==4.4.1)", "ipython", "twine", "wheel", "pytest-watch (>=4.1.0,<5)", "bumpversion (>=0.5.3,<1)"] [[package]] name = "eth-account" -version = "0.5.8" +version = "0.5.9" description = "eth-account: Sign Ethereum transactions and messages with local private keys" category = "main" optional = false @@ -266,14 +262,14 @@ hexbytes = ">=0.1.0,<1" rlp = ">=1.0.0,<3" [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21.9.0)"] +dev = ["bumpversion (>=0.5.3,<1)", "pytest-watch (>=4.1.0,<5)", "wheel", "twine", "ipython", "hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.910)", "pydocstyle (>=5.0.0,<6)", "Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21.9.0)"] doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21.9.0)"] -lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)"] +lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.910)", "pydocstyle (>=5.0.0,<6)"] test = ["hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)"] [[package]] name = "eth-hash" -version = "0.3.2" +version = "0.3.3" description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (erroneously) called sha3" category = "main" optional = false @@ -344,7 +340,7 @@ test = ["eth-hash", "pytest-xdist", "pytest (==5.4.1)", "tox (==3.14.6)"] [[package]] name = "eth-typing" -version = "2.2.2" +version = "2.3.0" description = "eth-typing: Common type annotations for ethereum python packages" category = "main" optional = false @@ -378,39 +374,39 @@ test = ["hypothesis (>=4.43.0,<5.0.0)", "pytest (==5.4.1)", "pytest-xdist", "tox [[package]] name = "flake8" -version = "4.0.1" +version = "3.9.2" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] -importlib-metadata = {version = "<4.3", markers = "python_version < \"3.8\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.8.0,<2.9.0" -pyflakes = ">=2.4.0,<2.5.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "frozenlist" -version = "1.2.0" +version = "1.3.1" description = "A list-like structure which implements collections.abc.MutableSequence" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "hexbytes" -version = "0.2.2" +version = "0.3.0" description = "hexbytes: Python `bytes` subclass that decodes hex, with a readable console output" category = "main" optional = false -python-versions = ">=3.6, <4" +python-versions = ">=3.7, <4" [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "bumpversion (>=0.5.3,<1)", "eth-utils (>=1.0.1,<2)", "flake8 (==3.7.9)", "hypothesis (>=3.44.24,<4)", "ipython", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "pytest (==5.4.1)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)", "tox (==3.14.6)", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=5.0.0,<6)"] -test = ["eth-utils (>=1.0.1,<2)", "hypothesis (>=3.44.24,<4)", "pytest-xdist", "pytest (==5.4.1)", "tox (==3.14.6)"] +test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "tox (>=3.25.1,<4)", "pytest-xdist", "pytest (>=7,<8)"] +lint = ["black (>=22,<23)", "pydocstyle (>=5.0.0,<6)", "mypy (==0.971)", "isort (>=4.2.15,<5)", "flake8 (==3.7.9)"] +doc = ["towncrier (>=21,<22)", "sphinx-rtd-theme (>=0.1.9,<1)", "Sphinx (>=4.0.0,<5)"] +dev = ["towncrier (>=21,<22)", "sphinx-rtd-theme (>=0.1.9,<1)", "Sphinx (>=4.0.0,<5)", "black (>=22,<23)", "pydocstyle (>=5.0.0,<6)", "mypy (==0.971)", "isort (>=4.2.15,<5)", "flake8 (==3.7.9)", "eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "tox (>=3.25.1,<4)", "pytest-xdist", "pytest (>=7,<8)", "ipython", "twine", "wheel", "pytest-watch (>=4.1.0,<5)", "bumpversion (>=0.5.3,<1)"] [[package]] name = "idna" @@ -422,7 +418,7 @@ python-versions = ">=3.5" [[package]] name = "imagesize" -version = "1.3.0" +version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" category = "dev" optional = false @@ -430,19 +426,35 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "4.2.0" +version = "4.12.0" description = "Read metadata from Python packages" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +perf = ["ipython"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] + +[[package]] +name = "importlib-resources" +version = "5.9.0" +description = "Read resources from Python packages" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +testing = ["pytest-mypy (>=0.9.1)", "pytest-black (>=0.3.7)", "pytest-enabler (>=1.3)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=6)"] +docs = ["jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "jaraco.packaging (>=9)", "sphinx"] [[package]] name = "iniconfig" @@ -466,11 +478,11 @@ requests = ">=2.11" [[package]] name = "jinja2" -version = "3.0.3" +version = "3.1.2" description = "A very fast and expressive template engine." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] MarkupSafe = ">=2.0" @@ -480,37 +492,42 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.14.0" description = "An implementation of JSON Schema validation for Python" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] attrs = ">=17.4.0" importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -pyrsistent = ">=0.14.0" -six = ">=1.11.0" +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "lru-dict" -version = "1.1.7" +version = "1.1.8" description = "An Dict like LRU container." category = "main" optional = false python-versions = "*" +[package.extras] +test = ["pytest"] + [[package]] name = "markupsafe" -version = "2.0.1" +version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "mccabe" @@ -536,15 +553,15 @@ varint = "*" [[package]] name = "multidict" -version = "5.2.0" +version = "6.0.2" description = "multidict implementation" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "mypy" -version = "0.961" +version = "0.971" description = "Optional static typing for Python" category = "dev" optional = false @@ -557,9 +574,9 @@ typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} typing-extensions = ">=3.10" [package.extras] -dmypy = ["psutil (>=4.0)"] -python2 = ["typed-ast (>=1.4.0,<2)"] reports = ["lxml"] +python2 = ["typed-ast (>=1.4.0,<2)"] +dmypy = ["psutil (>=4.0)"] [[package]] name = "mypy-extensions" @@ -607,17 +624,25 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "platformdirs" -version = "2.4.1" +version = "2.5.2" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" [package.extras] -docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] -test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] +test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] [[package]] name = "pluggy" @@ -636,11 +661,11 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "protobuf" -version = "3.19.1" +version = "3.20.1" description = "Protocol Buffers" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [[package]] name = "py" @@ -652,15 +677,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pycodestyle" -version = "2.8.0" +version = "2.7.0" description = "Python style guide checker" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pycryptodome" -version = "3.12.0" +version = "3.15.0" description = "Cryptographic library for Python" category = "main" optional = false @@ -668,24 +693,27 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pydata-sphinx-theme" -version = "0.6.3" +version = "0.8.1" description = "Bootstrap-based Sphinx theme from the PyData community" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [package.dependencies] beautifulsoup4 = "*" -docutils = "<0.17" -sphinx = "*" +docutils = "!=0.17.0" +packaging = "*" +sphinx = ">=3.5.4,<5" [package.extras] -coverage = ["pytest-cov", "codecov", "sphinx", "numpydoc", "recommonmark", "pandas", "pytest", "pytest-regressions", "beautifulsoup4", "jupyter-sphinx", "plotly", "numpy", "xarray", "docutils (==0.16)"] -test = ["sphinx", "numpydoc", "recommonmark", "pandas", "pytest", "pytest-regressions", "beautifulsoup4", "jupyter-sphinx", "plotly", "numpy", "xarray", "docutils (==0.16)"] +doc = ["numpydoc", "myst-parser", "pandas", "pytest", "pytest-regressions", "sphinxext-rediraffe", "sphinx-sitemap", "jupyter-sphinx", "plotly", "numpy", "xarray"] +test = ["pytest", "pydata-sphinx-theme"] +coverage = ["pytest-cov", "codecov", "pydata-sphinx-theme"] +dev = ["pyyaml", "pre-commit", "nox", "pydata-sphinx-theme"] [[package]] name = "pyflakes" -version = "2.4.0" +version = "2.3.1" description = "passive checker of Python programs" category = "dev" optional = false @@ -693,30 +721,33 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" -version = "2.11.1" +version = "2.13.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" + +[package.extras] +plugins = ["importlib-metadata"] [[package]] name = "pyparsing" -version = "3.0.6" -description = "Python parsing module" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.6.8" [package.extras] -diagrams = ["jinja2", "railroad-diagrams"] +diagrams = ["railroad-diagrams", "jinja2"] [[package]] name = "pyrsistent" -version = "0.18.0" +version = "0.18.1" description = "Persistent/Functional/Immutable data structures" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "pytest" @@ -769,7 +800,7 @@ python-dotenv = ">=0.9.1" [[package]] name = "python-dotenv" -version = "0.19.2" +version = "0.20.0" description = "Read key-value pairs from a .env file and set them as environment variables" category = "main" optional = false @@ -780,7 +811,7 @@ cli = ["click (>=5.0)"] [[package]] name = "pytz" -version = "2021.3" +version = "2022.2.1" description = "World timezone definitions, modern and historical" category = "dev" optional = false @@ -788,7 +819,7 @@ python-versions = "*" [[package]] name = "pywin32" -version = "303" +version = "304" description = "Python for Window Extensions" category = "main" optional = false @@ -804,21 +835,21 @@ python-versions = ">=3.6" [[package]] name = "requests" -version = "2.26.0" +version = "2.28.1" description = "Python HTTP for Humans." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.7, <4" [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" [package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rlp" @@ -856,7 +887,7 @@ python-versions = "*" [[package]] name = "soupsieve" -version = "2.3.1" +version = "2.3.2.post1" description = "A modern CSS selector implementation for Beautiful Soup." category = "dev" optional = false @@ -864,18 +895,19 @@ python-versions = ">=3.6" [[package]] name = "sphinx" -version = "3.5.4" +version = "4.5.0" description = "Python documentation generator" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=1.3" colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.12,<0.17" +docutils = ">=0.14,<0.18" imagesize = "*" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" @@ -883,45 +915,41 @@ requests = ">=2.5.0" snowballstemmer = ">=1.1" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" sphinxcontrib-jsmath = "*" sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.800)", "docutils-stubs"] +lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "docutils-stubs", "types-typed-ast", "types-requests"] test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] [[package]] name = "sphinx-book-theme" -version = "0.1.3" -description = "Jupyter Book: Create an online book with Jupyter Notebooks" +version = "0.3.3" +description = "A clean book theme for scientific explanations and documentation with Sphinx" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -beautifulsoup4 = ">=4.6.1,<5" -click = "*" -docutils = ">=0.15" -pydata-sphinx-theme = ">=0.6.0,<0.7.0" +pydata-sphinx-theme = ">=0.8.0,<0.9.0" pyyaml = "*" -sphinx = ">=2,<4" +sphinx = ">=3,<5" [package.extras] +test = ["sphinx-thebe", "pytest-regressions (>=2.0.1,<2.1.0)", "pytest-cov", "pytest (>=6.0.1,<6.1.0)", "myst-nb (>=0.13.2,<0.14.0)", "coverage", "beautifulsoup4 (>=4.6.1,<5)"] +doc = ["sphinxext-opengraph", "sphinxcontrib-youtube", "sphinxcontrib-bibtex (>=2.2,<3.0)", "sphinx-thebe (>=0.1.1)", "sphinx-togglebutton (>=0.2.1)", "sphinx-tabs", "sphinx-copybutton", "sphinx-examples", "sphinx-design", "sphinx (>=4.0,<5.0)", "plotly", "pandas", "nbclient", "myst-nb (>=0.13.2,<0.14.0)", "numpydoc", "matplotlib", "numpy", "folium", "ipywidgets", "ablog (>=0.10.13,<0.11.0)"] code_style = ["pre-commit (>=2.7.0,<2.8.0)"] -live-dev = ["sphinx-autobuild", "web-compile (>=0.2.1,<0.3.0)"] -sphinx = ["ablog (>=0.10.13,<0.11.0)", "ipywidgets", "folium", "numpy", "matplotlib", "myst-nb (>=0.11.1,<0.12.0)", "nbclient", "pandas", "plotly", "sphinx-design", "sphinx-copybutton", "sphinx-togglebutton (>=0.2.1)", "sphinx-thebe", "sphinxcontrib-bibtex (>=2.2,<3.0)", "sphinxext-opengraph"] -testing = ["myst-nb (>=0.11.1,<0.12.0)", "sphinx-thebe", "coverage", "pytest (>=6.0.1,<6.1.0)", "pytest-cov", "pytest-regressions (>=2.0.1,<2.1.0)"] [[package]] name = "sphinx-click" -version = "3.0.2" +version = "4.3.0" description = "Sphinx extension that automatically documents click applications" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] click = ">=7.0" @@ -1009,15 +1037,15 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomli" -version = "1.2.3" +version = "2.0.1" description = "A lil' TOML parser" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "toolz" -version = "0.11.2" +version = "0.12.0" description = "List processing tools and functional utilities" category = "main" optional = false @@ -1025,7 +1053,7 @@ python-versions = ">=3.5" [[package]] name = "typed-ast" -version = "1.5.1" +version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false @@ -1041,15 +1069,15 @@ python-versions = ">=3.7" [[package]] name = "urllib3" -version = "1.26.7" +version = "1.26.12" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] @@ -1102,11 +1130,11 @@ python-versions = ">=3.6.1" [[package]] name = "yarl" -version = "1.7.2" +version = "1.8.1" description = "Yet another URL library" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] idna = ">=2.0" @@ -1115,20 +1143,20 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [[package]] name = "zipp" -version = "3.7.0" +version = "3.8.1" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = "^3.7.2" -content-hash = "d07ae8eb53da8184c07323ef0526c990d90c6a0951430995c226dda515b5a86b" +content-hash = "91c2a7758ab3e96328084a8b1064ec4f2df6a6638e5f52b7572ab742a80da0e0" [metadata.files] aiohttp = [ @@ -1218,57 +1246,44 @@ async-timeout = [ {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] asynctest = [] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, -] -attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, -] +atomicwrites = [] +attrs = [] babel = [ - {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, - {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, + {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"}, + {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"}, ] base58 = [ {file = "base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2"}, {file = "base58-2.1.1.tar.gz", hash = "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c"}, ] -beautifulsoup4 = [] -bitarray = [ - {file = "bitarray-1.2.2.tar.gz", hash = "sha256:27a69ffcee3b868abab3ce8b17c69e02b63e722d4d64ffd91d659f81e9984954"}, +beautifulsoup4 = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, ] +bitarray = [] black = [] certifi = [ - {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, - {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, + {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, + {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, ] charset-normalizer = [] click = [ - {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, - {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, ] coverage = [] -cytoolz = [ - {file = "cytoolz-0.11.2.tar.gz", hash = "sha256:ea23663153806edddce7e4153d1d407d62357c05120a4e8485bddf1bd5ab22b4"}, -] +cytoolz = [] docutils = [ - {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, - {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, -] -eth-abi = [ - {file = "eth_abi-2.1.1-py3-none-any.whl", hash = "sha256:78df5d2758247a8f0766a7cfcea4575bcfe568c34a33e6d05a72c328a9040444"}, - {file = "eth_abi-2.1.1.tar.gz", hash = "sha256:4bb1d87bb6605823379b07f6c02c8af45df01a27cc85bd6abb7cf1446ce7d188"}, + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, ] +eth-abi = [] eth-account = [] -eth-hash = [ - {file = "eth-hash-0.3.2.tar.gz", hash = "sha256:3f40cecd5ead88184aa9550afc19d057f103728108c5102f592f8415949b5a76"}, - {file = "eth_hash-0.3.2-py3-none-any.whl", hash = "sha256:de7385148a8e0237ba1240cddbc06d53f56731140f8593bdb8429306f6b42271"}, -] +eth-hash = [] eth-keyfile = [ {file = "eth-keyfile-0.5.1.tar.gz", hash = "sha256:939540efb503380bc30d926833e6a12b22c6750de80feef3720d79e5a79de47d"}, {file = "eth_keyfile-0.5.1-py3-none-any.whl", hash = "sha256:70d734af17efdf929a90bb95375f43522be4ed80c3b9e0a8bca575fb11cd1159"}, @@ -1281,32 +1296,27 @@ eth-rlp = [ {file = "eth-rlp-0.2.1.tar.gz", hash = "sha256:f016f980b0ed42ee7650ba6e4e4d3c4e9aa06d8b9c6825a36d3afe5aa0187a8b"}, {file = "eth_rlp-0.2.1-py3-none-any.whl", hash = "sha256:cc389ef8d7b6f76a98f90bcdbff1b8684b3a78f53d47e871191b50d4d6aee5a1"}, ] -eth-typing = [] +eth-typing = [ + {file = "eth-typing-2.3.0.tar.gz", hash = "sha256:39cce97f401f082739b19258dfa3355101c64390914c73fe2b90012f443e0dc7"}, + {file = "eth_typing-2.3.0-py3-none-any.whl", hash = "sha256:b7fa58635c1cb0cbf538b2f5f1e66139575ea4853eac1d6000f0961a4b277422"}, +] eth-utils = [ {file = "eth-utils-1.10.0.tar.gz", hash = "sha256:bf82762a46978714190b0370265a7148c954d3f0adaa31c6f085ea375e4c61af"}, {file = "eth_utils-1.10.0-py3-none-any.whl", hash = "sha256:74240a8c6f652d085ed3c85f5f1654203d2f10ff9062f83b3bad0a12ff321c7a"}, ] flake8 = [ - {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, - {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] frozenlist = [] -hexbytes = [ - {file = "hexbytes-0.2.2-py3-none-any.whl", hash = "sha256:ef53c37ea9f316fff86fcb1df057b4c6ba454da348083e972031bbf7bc9c3acc"}, - {file = "hexbytes-0.2.2.tar.gz", hash = "sha256:a5881304d186e87578fb263a85317c808cf130e1d4b3d37d30142ab0f7898d03"}, -] +hexbytes = [] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] -imagesize = [ - {file = "imagesize-1.3.0-py2.py3-none-any.whl", hash = "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c"}, - {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, -] -importlib-metadata = [ - {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, - {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, -] +imagesize = [] +importlib-metadata = [] +importlib-resources = [] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, @@ -1316,51 +1326,52 @@ ipfshttpclient = [ {file = "ipfshttpclient-0.8.0a2.tar.gz", hash = "sha256:0d80e95ee60b02c7d414e79bf81a36fc3c8fbab74265475c52f70b2620812135"}, ] jinja2 = [ - {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, - {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, -] -jsonschema = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] -lru-dict = [ - {file = "lru-dict-1.1.7.tar.gz", hash = "sha256:45b81f67d75341d4433abade799a47e9c42a9e22a118531dcb5e549864032d7c"}, + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] +jsonschema = [] +lru-dict = [] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, @@ -1370,32 +1381,68 @@ multiaddr = [ {file = "multiaddr-0.0.9-py2.py3-none-any.whl", hash = "sha256:5c0f862cbcf19aada2a899f80ef896ddb2e85614e0c8f04dd287c06c69dac95b"}, {file = "multiaddr-0.0.9.tar.gz", hash = "sha256:30b2695189edc3d5b90f1c303abb8f02d963a3a4edf2e7178b975eb417ab0ecf"}, ] -multidict = [] -mypy = [ - {file = "mypy-0.961-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:697540876638ce349b01b6786bc6094ccdaba88af446a9abb967293ce6eaa2b0"}, - {file = "mypy-0.961-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b117650592e1782819829605a193360a08aa99f1fc23d1d71e1a75a142dc7e15"}, - {file = "mypy-0.961-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bdd5ca340beffb8c44cb9dc26697628d1b88c6bddf5c2f6eb308c46f269bb6f3"}, - {file = "mypy-0.961-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3e09f1f983a71d0672bbc97ae33ee3709d10c779beb613febc36805a6e28bb4e"}, - {file = "mypy-0.961-cp310-cp310-win_amd64.whl", hash = "sha256:e999229b9f3198c0c880d5e269f9f8129c8862451ce53a011326cad38b9ccd24"}, - {file = "mypy-0.961-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b24be97351084b11582fef18d79004b3e4db572219deee0212078f7cf6352723"}, - {file = "mypy-0.961-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f4a21d01fc0ba4e31d82f0fff195682e29f9401a8bdb7173891070eb260aeb3b"}, - {file = "mypy-0.961-cp36-cp36m-win_amd64.whl", hash = "sha256:439c726a3b3da7ca84a0199a8ab444cd8896d95012c4a6c4a0d808e3147abf5d"}, - {file = "mypy-0.961-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a0b53747f713f490affdceef835d8f0cb7285187a6a44c33821b6d1f46ed813"}, - {file = "mypy-0.961-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e9f70df36405c25cc530a86eeda1e0867863d9471fe76d1273c783df3d35c2e"}, - {file = "mypy-0.961-cp37-cp37m-win_amd64.whl", hash = "sha256:b88f784e9e35dcaa075519096dc947a388319cb86811b6af621e3523980f1c8a"}, - {file = "mypy-0.961-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d5aaf1edaa7692490f72bdb9fbd941fbf2e201713523bdb3f4038be0af8846c6"}, - {file = "mypy-0.961-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9f5f5a74085d9a81a1f9c78081d60a0040c3efb3f28e5c9912b900adf59a16e6"}, - {file = "mypy-0.961-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f4b794db44168a4fc886e3450201365c9526a522c46ba089b55e1f11c163750d"}, - {file = "mypy-0.961-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:64759a273d590040a592e0f4186539858c948302c653c2eac840c7a3cd29e51b"}, - {file = "mypy-0.961-cp38-cp38-win_amd64.whl", hash = "sha256:63e85a03770ebf403291ec50097954cc5caf2a9205c888ce3a61bd3f82e17569"}, - {file = "mypy-0.961-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f1332964963d4832a94bebc10f13d3279be3ce8f6c64da563d6ee6e2eeda932"}, - {file = "mypy-0.961-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:006be38474216b833eca29ff6b73e143386f352e10e9c2fbe76aa8549e5554f5"}, - {file = "mypy-0.961-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9940e6916ed9371809b35b2154baf1f684acba935cd09928952310fbddaba648"}, - {file = "mypy-0.961-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a5ea0875a049de1b63b972456542f04643daf320d27dc592d7c3d9cd5d9bf950"}, - {file = "mypy-0.961-cp39-cp39-win_amd64.whl", hash = "sha256:1ece702f29270ec6af25db8cf6185c04c02311c6bb21a69f423d40e527b75c56"}, - {file = "mypy-0.961-py3-none-any.whl", hash = "sha256:03c6cc893e7563e7b2949b969e63f02c000b32502a1b4d1314cabe391aa87d66"}, - {file = "mypy-0.961.tar.gz", hash = "sha256:f730d56cb924d371c26b8eaddeea3cc07d78ff51c521c6d04899ac6904b75492"}, -] +multidict = [ + {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"}, + {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"}, + {file = "multidict-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88"}, + {file = "multidict-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87"}, + {file = "multidict-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389"}, + {file = "multidict-6.0.2-cp310-cp310-win32.whl", hash = "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293"}, + {file = "multidict-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658"}, + {file = "multidict-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b"}, + {file = "multidict-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b"}, + {file = "multidict-6.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15"}, + {file = "multidict-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc"}, + {file = "multidict-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a"}, + {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60"}, + {file = "multidict-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86"}, + {file = "multidict-6.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693"}, + {file = "multidict-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9"}, + {file = "multidict-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d"}, + {file = "multidict-6.0.2-cp38-cp38-win32.whl", hash = "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57"}, + {file = "multidict-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96"}, + {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c"}, + {file = "multidict-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e"}, + {file = "multidict-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9"}, + {file = "multidict-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360"}, + {file = "multidict-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937"}, + {file = "multidict-6.0.2-cp39-cp39-win32.whl", hash = "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a"}, + {file = "multidict-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae"}, + {file = "multidict-6.0.2.tar.gz", hash = "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013"}, +] +mypy = [] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, @@ -1415,56 +1462,85 @@ pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] -platformdirs = [] +pkgutil-resolve-name = [] +platformdirs = [ + {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, + {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, +] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] -protobuf = [] +protobuf = [ + {file = "protobuf-3.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3cc797c9d15d7689ed507b165cd05913acb992d78b379f6014e013f9ecb20996"}, + {file = "protobuf-3.20.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:ff8d8fa42675249bb456f5db06c00de6c2f4c27a065955917b28c4f15978b9c3"}, + {file = "protobuf-3.20.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cd68be2559e2a3b84f517fb029ee611546f7812b1fdd0aa2ecc9bc6ec0e4fdde"}, + {file = "protobuf-3.20.1-cp310-cp310-win32.whl", hash = "sha256:9016d01c91e8e625141d24ec1b20fed584703e527d28512aa8c8707f105a683c"}, + {file = "protobuf-3.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:32ca378605b41fd180dfe4e14d3226386d8d1b002ab31c969c366549e66a2bb7"}, + {file = "protobuf-3.20.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9be73ad47579abc26c12024239d3540e6b765182a91dbc88e23658ab71767153"}, + {file = "protobuf-3.20.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:097c5d8a9808302fb0da7e20edf0b8d4703274d140fd25c5edabddcde43e081f"}, + {file = "protobuf-3.20.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e250a42f15bf9d5b09fe1b293bdba2801cd520a9f5ea2d7fb7536d4441811d20"}, + {file = "protobuf-3.20.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cdee09140e1cd184ba9324ec1df410e7147242b94b5f8b0c64fc89e38a8ba531"}, + {file = "protobuf-3.20.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:af0ebadc74e281a517141daad9d0f2c5d93ab78e9d455113719a45a49da9db4e"}, + {file = "protobuf-3.20.1-cp37-cp37m-win32.whl", hash = "sha256:755f3aee41354ae395e104d62119cb223339a8f3276a0cd009ffabfcdd46bb0c"}, + {file = "protobuf-3.20.1-cp37-cp37m-win_amd64.whl", hash = "sha256:62f1b5c4cd6c5402b4e2d63804ba49a327e0c386c99b1675c8a0fefda23b2067"}, + {file = "protobuf-3.20.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:06059eb6953ff01e56a25cd02cca1a9649a75a7e65397b5b9b4e929ed71d10cf"}, + {file = "protobuf-3.20.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:cb29edb9eab15742d791e1025dd7b6a8f6fcb53802ad2f6e3adcb102051063ab"}, + {file = "protobuf-3.20.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:69ccfdf3657ba59569c64295b7d51325f91af586f8d5793b734260dfe2e94e2c"}, + {file = "protobuf-3.20.1-cp38-cp38-win32.whl", hash = "sha256:dd5789b2948ca702c17027c84c2accb552fc30f4622a98ab5c51fcfe8c50d3e7"}, + {file = "protobuf-3.20.1-cp38-cp38-win_amd64.whl", hash = "sha256:77053d28427a29987ca9caf7b72ccafee011257561259faba8dd308fda9a8739"}, + {file = "protobuf-3.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f50601512a3d23625d8a85b1638d914a0970f17920ff39cec63aaef80a93fb7"}, + {file = "protobuf-3.20.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:284f86a6207c897542d7e956eb243a36bb8f9564c1742b253462386e96c6b78f"}, + {file = "protobuf-3.20.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7403941f6d0992d40161aa8bb23e12575637008a5a02283a930addc0508982f9"}, + {file = "protobuf-3.20.1-cp39-cp39-win32.whl", hash = "sha256:db977c4ca738dd9ce508557d4fce0f5aebd105e158c725beec86feb1f6bc20d8"}, + {file = "protobuf-3.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:7e371f10abe57cee5021797126c93479f59fccc9693dafd6bd5633ab67808a91"}, + {file = "protobuf-3.20.1-py2.py3-none-any.whl", hash = "sha256:adfc6cf69c7f8c50fd24c793964eef18f0ac321315439d94945820612849c388"}, + {file = "protobuf-3.20.1.tar.gz", hash = "sha256:adc31566d027f45efe3f44eeb5b1f329da43891634d61c75a5944e9be6dd42c9"}, +] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pycodestyle = [ - {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, - {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, ] pycryptodome = [] pydata-sphinx-theme = [ - {file = "pydata-sphinx-theme-0.6.3.tar.gz", hash = "sha256:32e0580ef985734d652eec2bf25e0995a330a9d4f76deaa353571ce8e180ab14"}, - {file = "pydata_sphinx_theme-0.6.3-py3-none-any.whl", hash = "sha256:f0fee20dc33fa5efa6b9be57368be760d236d8b9c1486b14ad1d17b7e7e0db04"}, + {file = "pydata_sphinx_theme-0.8.1-py3-none-any.whl", hash = "sha256:af2c99cb0b43d95247b1563860942ba75d7f1596360594fce510caaf8c4fcc16"}, + {file = "pydata_sphinx_theme-0.8.1.tar.gz", hash = "sha256:96165702253917ece13dd895e23b96ee6dce422dcc144d560806067852fe1fed"}, ] pyflakes = [ - {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, - {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pygments = [] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pyrsistent = [ - {file = "pyrsistent-0.18.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f4c8cabb46ff8e5d61f56a037974228e978f26bfefce4f61a4b1ac0ba7a2ab72"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:da6e5e818d18459fa46fac0a4a4e543507fe1110e808101277c5a2b5bab0cd2d"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5e4395bbf841693eaebaa5bb5c8f5cdbb1d139e07c975c682ec4e4f8126e03d2"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-win32.whl", hash = "sha256:527be2bfa8dc80f6f8ddd65242ba476a6c4fb4e3aedbf281dfbac1b1ed4165b1"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2aaf19dc8ce517a8653746d98e962ef480ff34b6bc563fc067be6401ffb457c7"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58a70d93fb79dc585b21f9d72487b929a6fe58da0754fa4cb9f279bb92369396"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4916c10896721e472ee12c95cdc2891ce5890898d2f9907b1b4ae0f53588b710"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:73ff61b1411e3fb0ba144b8f08d6749749775fe89688093e1efef9839d2dcc35"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-win32.whl", hash = "sha256:b29b869cf58412ca5738d23691e96d8aff535e17390128a1a52717c9a109da4f"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-win_amd64.whl", hash = "sha256:097b96f129dd36a8c9e33594e7ebb151b1515eb52cceb08474c10a5479e799f2"}, - {file = "pyrsistent-0.18.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:772e94c2c6864f2cd2ffbe58bb3bdefbe2a32afa0acb1a77e472aac831f83427"}, - {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1a9ff320fa699337e05edcaae79ef8c2880b52720bc031b219e5b5008ebbdef"}, - {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd3caef37a415fd0dae6148a1b6957a8c5f275a62cca02e18474608cb263640c"}, - {file = "pyrsistent-0.18.0-cp38-cp38-win32.whl", hash = "sha256:e79d94ca58fcafef6395f6352383fa1a76922268fa02caa2272fff501c2fdc78"}, - {file = "pyrsistent-0.18.0-cp38-cp38-win_amd64.whl", hash = "sha256:a0c772d791c38bbc77be659af29bb14c38ced151433592e326361610250c605b"}, - {file = "pyrsistent-0.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d5ec194c9c573aafaceebf05fc400656722793dac57f254cd4741f3c27ae57b4"}, - {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6b5eed00e597b5b5773b4ca30bd48a5774ef1e96f2a45d105db5b4ebb4bca680"}, - {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:48578680353f41dca1ca3dc48629fb77dfc745128b56fc01096b2530c13fd426"}, - {file = "pyrsistent-0.18.0-cp39-cp39-win32.whl", hash = "sha256:f3ef98d7b76da5eb19c37fda834d50262ff9167c65658d1d8f974d2e4d90676b"}, - {file = "pyrsistent-0.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:404e1f1d254d314d55adb8d87f4f465c8693d6f902f67eb6ef5b4526dc58e6ea"}, - {file = "pyrsistent-0.18.0.tar.gz", hash = "sha256:773c781216f8c2900b42a7b638d5b517bb134ae1acbebe4d1e8f1f41ea60eb4b"}, + {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, + {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, + {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, + {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -1479,26 +1555,25 @@ pytest-dotenv = [ {file = "pytest_dotenv-0.5.2-py3-none-any.whl", hash = "sha256:40a2cece120a213898afaa5407673f6bd924b1fa7eafce6bda0e8abffe2f710f"}, ] python-dotenv = [ - {file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"}, - {file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"}, -] -pytz = [ - {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, - {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, + {file = "python-dotenv-0.20.0.tar.gz", hash = "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f"}, + {file = "python_dotenv-0.20.0-py3-none-any.whl", hash = "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938"}, ] +pytz = [] pywin32 = [ - {file = "pywin32-303-cp310-cp310-win32.whl", hash = "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb"}, - {file = "pywin32-303-cp310-cp310-win_amd64.whl", hash = "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51"}, - {file = "pywin32-303-cp311-cp311-win32.whl", hash = "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee"}, - {file = "pywin32-303-cp311-cp311-win_amd64.whl", hash = "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439"}, - {file = "pywin32-303-cp36-cp36m-win32.whl", hash = "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9"}, - {file = "pywin32-303-cp36-cp36m-win_amd64.whl", hash = "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559"}, - {file = "pywin32-303-cp37-cp37m-win32.whl", hash = "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e"}, - {file = "pywin32-303-cp37-cp37m-win_amd64.whl", hash = "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca"}, - {file = "pywin32-303-cp38-cp38-win32.whl", hash = "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b"}, - {file = "pywin32-303-cp38-cp38-win_amd64.whl", hash = "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba"}, - {file = "pywin32-303-cp39-cp39-win32.whl", hash = "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352"}, - {file = "pywin32-303-cp39-cp39-win_amd64.whl", hash = "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34"}, + {file = "pywin32-304-cp310-cp310-win32.whl", hash = "sha256:3c7bacf5e24298c86314f03fa20e16558a4e4138fc34615d7de4070c23e65af3"}, + {file = "pywin32-304-cp310-cp310-win_amd64.whl", hash = "sha256:4f32145913a2447736dad62495199a8e280a77a0ca662daa2332acf849f0be48"}, + {file = "pywin32-304-cp310-cp310-win_arm64.whl", hash = "sha256:d3ee45adff48e0551d1aa60d2ec066fec006083b791f5c3527c40cd8aefac71f"}, + {file = "pywin32-304-cp311-cp311-win32.whl", hash = "sha256:30c53d6ce44c12a316a06c153ea74152d3b1342610f1b99d40ba2795e5af0269"}, + {file = "pywin32-304-cp311-cp311-win_amd64.whl", hash = "sha256:7ffa0c0fa4ae4077e8b8aa73800540ef8c24530057768c3ac57c609f99a14fd4"}, + {file = "pywin32-304-cp311-cp311-win_arm64.whl", hash = "sha256:cbbe34dad39bdbaa2889a424d28752f1b4971939b14b1bb48cbf0182a3bcfc43"}, + {file = "pywin32-304-cp36-cp36m-win32.whl", hash = "sha256:be253e7b14bc601718f014d2832e4c18a5b023cbe72db826da63df76b77507a1"}, + {file = "pywin32-304-cp36-cp36m-win_amd64.whl", hash = "sha256:de9827c23321dcf43d2f288f09f3b6d772fee11e809015bdae9e69fe13213988"}, + {file = "pywin32-304-cp37-cp37m-win32.whl", hash = "sha256:f64c0377cf01b61bd5e76c25e1480ca8ab3b73f0c4add50538d332afdf8f69c5"}, + {file = "pywin32-304-cp37-cp37m-win_amd64.whl", hash = "sha256:bb2ea2aa81e96eee6a6b79d87e1d1648d3f8b87f9a64499e0b92b30d141e76df"}, + {file = "pywin32-304-cp38-cp38-win32.whl", hash = "sha256:94037b5259701988954931333aafd39cf897e990852115656b014ce72e052e96"}, + {file = "pywin32-304-cp38-cp38-win_amd64.whl", hash = "sha256:ead865a2e179b30fb717831f73cf4373401fc62fbc3455a0889a7ddac848f83e"}, + {file = "pywin32-304-cp39-cp39-win32.whl", hash = "sha256:25746d841201fd9f96b648a248f731c1dec851c9a08b8e33da8b56148e4c65cc"}, + {file = "pywin32-304-cp39-cp39-win_amd64.whl", hash = "sha256:d24a3382f013b21aa24a5cfbfad5a2cd9926610c0affde3e8ab5b3d7dbcf4ac9"}, ] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, @@ -1535,10 +1610,7 @@ pyyaml = [ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] -requests = [ - {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, - {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, -] +requests = [] rlp = [ {file = "rlp-2.0.1-py2.py3-none-any.whl", hash = "sha256:52a57c9f53f03c88b189283734b397314288250cc4a3c4113e9e36e2ac6bdd16"}, {file = "rlp-2.0.1.tar.gz", hash = "sha256:665e8312750b3fc5f7002e656d05b9dcb6e93b6063df40d95c49ad90c19d1f0e"}, @@ -1551,10 +1623,13 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -soupsieve = [] +soupsieve = [ + {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, + {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, +] sphinx = [ - {file = "Sphinx-3.5.4-py3-none-any.whl", hash = "sha256:2320d4e994a191f4b4be27da514e46b3d6b420f2ff895d064f52415d342461e8"}, - {file = "Sphinx-3.5.4.tar.gz", hash = "sha256:19010b7b9fa0dc7756a6e105b2aacd3a80f798af3c25c273be64d7beeb482cb1"}, + {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, + {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, ] sphinx-book-theme = [] sphinx-click = [] @@ -1586,31 +1661,36 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -tomli = [] -toolz = [ - {file = "toolz-0.11.2-py3-none-any.whl", hash = "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f"}, - {file = "toolz-0.11.2.tar.gz", hash = "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33"}, +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +toolz = [] typed-ast = [ - {file = "typed_ast-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d8314c92414ce7481eee7ad42b353943679cf6f30237b5ecbf7d835519e1212"}, - {file = "typed_ast-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b53ae5de5500529c76225d18eeb060efbcec90ad5e030713fe8dab0fb4531631"}, - {file = "typed_ast-1.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:24058827d8f5d633f97223f5148a7d22628099a3d2efe06654ce872f46f07cdb"}, - {file = "typed_ast-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a6d495c1ef572519a7bac9534dbf6d94c40e5b6a608ef41136133377bba4aa08"}, - {file = "typed_ast-1.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:de4ecae89c7d8b56169473e08f6bfd2df7f95015591f43126e4ea7865928677e"}, - {file = "typed_ast-1.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:256115a5bc7ea9e665c6314ed6671ee2c08ca380f9d5f130bd4d2c1f5848d695"}, - {file = "typed_ast-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7c42707ab981b6cf4b73490c16e9d17fcd5227039720ca14abe415d39a173a30"}, - {file = "typed_ast-1.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:71dcda943a471d826ea930dd449ac7e76db7be778fcd722deb63642bab32ea3f"}, - {file = "typed_ast-1.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4f30a2bcd8e68adbb791ce1567fdb897357506f7ea6716f6bbdd3053ac4d9471"}, - {file = "typed_ast-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ca9e8300d8ba0b66d140820cf463438c8e7b4cdc6fd710c059bfcfb1531d03fb"}, - {file = "typed_ast-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9caaf2b440efb39ecbc45e2fabde809cbe56272719131a6318fd9bf08b58e2cb"}, - {file = "typed_ast-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c9bcad65d66d594bffab8575f39420fe0ee96f66e23c4d927ebb4e24354ec1af"}, - {file = "typed_ast-1.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:591bc04e507595887160ed7aa8d6785867fb86c5793911be79ccede61ae96f4d"}, - {file = "typed_ast-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:a80d84f535642420dd17e16ae25bb46c7f4c16ee231105e7f3eb43976a89670a"}, - {file = "typed_ast-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:38cf5c642fa808300bae1281460d4f9b7617cf864d4e383054a5ef336e344d32"}, - {file = "typed_ast-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b6ab14c56bc9c7e3c30228a0a0b54b915b1579613f6e463ba6f4eb1382e7fd4"}, - {file = "typed_ast-1.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2b8d7007f6280e36fa42652df47087ac7b0a7d7f09f9468f07792ba646aac2d"}, - {file = "typed_ast-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:b6d17f37f6edd879141e64a5db17b67488cfeffeedad8c5cec0392305e9bc775"}, - {file = "typed_ast-1.5.1.tar.gz", hash = "sha256:484137cab8ecf47e137260daa20bafbba5f4e3ec7fda1c1e69ab299b75fa81c5"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] typing-extensions = [] urllib3 = [] @@ -1653,81 +1733,5 @@ websockets = [ {file = "websockets-9.1-cp39-cp39-win_amd64.whl", hash = "sha256:85db8090ba94e22d964498a47fdd933b8875a1add6ebc514c7ac8703eb97bbf0"}, {file = "websockets-9.1.tar.gz", hash = "sha256:276d2339ebf0df4f45df453923ebd2270b87900eda5dfd4a6b0cfa15f82111c3"}, ] -yarl = [ - {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"}, - {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b"}, - {file = "yarl-1.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72"}, - {file = "yarl-1.7.2-cp310-cp310-win32.whl", hash = "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c"}, - {file = "yarl-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265"}, - {file = "yarl-1.7.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d"}, - {file = "yarl-1.7.2-cp36-cp36m-win32.whl", hash = "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1"}, - {file = "yarl-1.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913"}, - {file = "yarl-1.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b"}, - {file = "yarl-1.7.2-cp37-cp37m-win32.whl", hash = "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1"}, - {file = "yarl-1.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b"}, - {file = "yarl-1.7.2-cp38-cp38-win32.whl", hash = "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef"}, - {file = "yarl-1.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8"}, - {file = "yarl-1.7.2-cp39-cp39-win32.whl", hash = "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d"}, - {file = "yarl-1.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58"}, - {file = "yarl-1.7.2.tar.gz", hash = "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd"}, -] -zipp = [ - {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, - {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, -] +yarl = [] +zipp = [] diff --git a/pyproject.toml b/pyproject.toml index 130f47c..9e69f95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ python = "^3.7.2" web3 = "^5.23.0" click = "^8.0.3" python-dotenv = "*" -typing-extensions = "^4.3.0" +typing-extensions = "*" [tool.poetry.dev-dependencies] mypy = "*" From ff26afbab70226d782f2e74557f2139a25c9afa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Mon, 29 Aug 2022 12:01:53 +0200 Subject: [PATCH 21/21] chore: release v0.6.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9e69f95..2599a56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "uniswap-python" -version = "0.5.5" +version = "0.6.0" description = "An unofficial Python wrapper for the decentralized exchange Uniswap" repository = "https://github.com/shanefontaine/uniswap-python" readme = "README.md"