diff --git a/docs/source/all_moccasin_toml_parameters.rst b/docs/source/all_moccasin_toml_parameters.rst index d703c9a..20ca903 100644 --- a/docs/source/all_moccasin_toml_parameters.rst +++ b/docs/source/all_moccasin_toml_parameters.rst @@ -103,7 +103,7 @@ All possible options Environment Variables --------------------- -Additionally, there are a few environment variables that ``moccasin`` will look for, but it's also okay if they are not set. It's important to note, that the `.env` file you set in the config will be ignored for these values. +Additionally, there are a few environment variables that ``moccasin`` will look for, but it's also okay if they are not set. It's important to note, that the ``.env`` file you set in the config will be ignored for these values. .. code-block:: bash diff --git a/docs/source/core_concepts/dependencies.rst b/docs/source/core_concepts/dependencies.rst index 654dc73..b4458ac 100644 --- a/docs/source/core_concepts/dependencies.rst +++ b/docs/source/core_concepts/dependencies.rst @@ -41,7 +41,7 @@ This will create an entry in your ``moccasin.toml`` file that looks like this: "pcaversaccio/snekmate@0.1.0", ] -Which follows the same syntax that `pip` and `uv` to do installs from GitHub repositories. This will also download the GitHub repository into your `lib` folder. +Which follows the same syntax that ``pip`` and ``uv`` to do installs from GitHub repositories. This will also download the GitHub repository into your ``lib`` folder. You can then use these packages in your vyper contracts, for example in an miniaml ERC20 vyper contract: @@ -60,7 +60,7 @@ You can then use these packages in your vyper contracts, for example in an minia erc20.__init__("my_token", "MT", 18, "my_token_dapp", "0x02") ow.__init__() -``moccasin`` is smart enough to know that the `lib/github` and `lib/pypi` folders are part of the search path, but you can also explicitly add your dependencies. +``moccasin`` is smart enough to know that the ``lib/github`` and ``lib/pypi`` folders are part of the search path, but you can also explicitly add your dependencies. .. code-block:: python diff --git a/docs/source/core_concepts/named_contracts.rst b/docs/source/core_concepts/named_contracts.rst index 433e8e1..b5ed134 100644 --- a/docs/source/core_concepts/named_contracts.rst +++ b/docs/source/core_concepts/named_contracts.rst @@ -24,7 +24,7 @@ Let's look at a minimal ``moccasin.toml`` with a ETH mainnet network fork with a [networks.mainnet-fork.contracts] usdc = { address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"} -The `NamedContract` in this case, is `usdc`. And it's this named contract that we can access our scripts! +The ``NamedContract`` in this case, is ``usdc``. And it's this named contract that we can access our scripts! .. code-block:: python diff --git a/docs/source/core_concepts/named_contracts/manifest_named.rst b/docs/source/core_concepts/named_contracts/manifest_named.rst index 005c738..f1490cc 100644 --- a/docs/source/core_concepts/named_contracts/manifest_named.rst +++ b/docs/source/core_concepts/named_contracts/manifest_named.rst @@ -63,9 +63,9 @@ And this is awful! So instead, what we can do, is setup **ALL** of the configura .. code-block:: toml - # At the top, we can set some default parameters for the `usdc` named contract + # At the top, we can set some default parameters for the ``usdc``` named contract # Every named contract will use the ERC20.vy contract in the project as it's ABI - # If the contract doesn't exist, it'll deploy with the `deploy_feed.py` script (for example, on a locally running network) + # If the contract doesn't exist, it'll deploy with the ``deploy_feed.py``` script (for example, on a locally running network) [networks.contracts] usdc = { abi = "ERC20", deployer_script = "mock_deployer/deploy_feed.py"} @@ -104,7 +104,7 @@ And with this, we only need ONE script that works for all of these! def moccasin_main(): get_decimals() -Then, we just need to adjust the `--network` flag and everything else will work automatically. +Then, we just need to adjust the ``--network`` flag and everything else will work automatically. .. code-block:: bash diff --git a/docs/source/core_concepts/networks/forked_networks.rst b/docs/source/core_concepts/networks/forked_networks.rst index 69240d7..3f9dfa4 100644 --- a/docs/source/core_concepts/networks/forked_networks.rst +++ b/docs/source/core_concepts/networks/forked_networks.rst @@ -24,11 +24,11 @@ In testing, forking is an essential part of the development process. **Any scrip chain_id = 11155111 is_fork = true -Running a script with this setup will run your script locally, but pretending to be on the `sepolia` network, with contracts and everything! +Running a script with this setup will run your script locally, but pretending to be on the ``sepolia`` network, with contracts and everything! It essentially does some "lazy loading", where it'll only download information from the blockchain if/when you need. For example, if you want to get the balance of an account, it'll only download the balance of that account when your script calls for it. -You can also take any non-forked network and run a forked test just by adding the `--fork` flag to the command line. +You can also take any non-forked network and run a forked test just by adding the ``--fork`` flag to the command line. .. code-block:: toml diff --git a/docs/source/core_concepts/project.rst b/docs/source/core_concepts/project.rst index 11a1bfe..6ca6540 100644 --- a/docs/source/core_concepts/project.rst +++ b/docs/source/core_concepts/project.rst @@ -16,7 +16,7 @@ A typical moccasin project is structured as follows: Where: - ``README.md`` is a markdown file that you can use to describe your project. -- ``moccasin.toml`` is a configuration file that `moccasin` uses to manage the project. +- ``moccasin.toml`` is a configuration file that ``moccasin`` uses to manage the project. - ``script`` is a directory that contains python scripts that you can use to deploy your project. - ``src``` is a directory that contains your vyper smart contracts. - ``tests`` is a directory that contains your tests. diff --git a/docs/source/core_concepts/script.rst b/docs/source/core_concepts/script.rst index 983a163..f269745 100644 --- a/docs/source/core_concepts/script.rst +++ b/docs/source/core_concepts/script.rst @@ -90,7 +90,7 @@ You can directly import contracts from the ``src`` folder into your scripts, and Networking ========== -If you have :doc:`networks ` defined in your :doc:`moccasin.toml `, you can directly work with the network in your scripts. For example, if you have a `sepolia` network defined in your ``moccasin.toml``: +If you have :doc:`networks ` defined in your :doc:`moccasin.toml `, you can directly work with the network in your scripts. For example, if you have a ``sepolia`` network defined in your ``moccasin.toml``: .. code-block:: bash @@ -102,7 +102,7 @@ You can learn more about networks in the :doc:`networks documentation moccasin_main ============= -In your scripts, the `moccasin_main` function is special, if you have a function with this name in your script, `moccasin` will run this function by default after running the script like a regular python file. For example, you could also do this: +In your scripts, the ``moccasin_main`` function is special, if you have a function with this name in your script, ``moccasin`` will run this function by default after running the script like a regular python file. For example, you could also do this: .. code-block:: python diff --git a/docs/source/core_concepts/testing/gas_profiling.rst b/docs/source/core_concepts/testing/gas_profiling.rst index 4e7ddc4..fe25e81 100644 --- a/docs/source/core_concepts/testing/gas_profiling.rst +++ b/docs/source/core_concepts/testing/gas_profiling.rst @@ -3,7 +3,7 @@ Gas Profiling .. note:: See the `titanoboa gas-profiling documentation for more information. `_ -`moccasin` has a built in gas profiler that can be used to profile your contracts gas usage. It uses `titanoboa's `_ gas profiling under the hood. +``moccasin`` has a built in gas profiler that can be used to profile your contracts gas usage. It uses `titanoboa's `_ gas profiling under the hood. To use the gas profiler, you can run: diff --git a/docs/source/how-tos/stateful_fuzzing.rst b/docs/source/how-tos/stateful_fuzzing.rst index 495a7c8..a70708e 100644 --- a/docs/source/how-tos/stateful_fuzzing.rst +++ b/docs/source/how-tos/stateful_fuzzing.rst @@ -34,7 +34,7 @@ Let's say we have the following contract: def change_number(new_number: uint256): self.some_number = new_number -The `invariant` in this contract is that the function `always_returns_input_number` should always return the input number. But as we can see from looking at the function, we notice that if someone were to call ``change_number`` with an input of ``2``, the ``always_returns_input_number`` function will return 0 no matter what. +The `invariant` in this contract is that the function ``always_returns_input_number`` should always return the input number. But as we can see from looking at the function, we notice that if someone were to call ``change_number`` with an input of ``2``, the ``always_returns_input_number`` function will return 0 no matter what. This is easy for us to "see", but when contracts get sufficiently complicated, spotting these kinds of bugs becomes harder and harder, and this is where our tests come in. diff --git a/docs/source/how-tos/stateless_fuzzing.rst b/docs/source/how-tos/stateless_fuzzing.rst index 6dc35ef..2558564 100644 --- a/docs/source/how-tos/stateless_fuzzing.rst +++ b/docs/source/how-tos/stateless_fuzzing.rst @@ -30,7 +30,7 @@ Let's say you have a contract as such: return 0 return input_number -The `invariant` in this contract is that the function `always_returns_input_number` should always return the input number. But as we can see from looking at the function, we notice that if the input number is 2, the function will return 0. +The `invariant` in this contract is that the function ``always_returns_input_number`` should always return the input number. But as we can see from looking at the function, we notice that if the input number is 2, the function will return 0. This is easy for us to "see", but when contracts get sufficiently complicated, spotting these kinds of bugs becomes harder and harder, and this is where our tests come in. @@ -59,7 +59,7 @@ To fuzz test this, in ``moccasin`` we'd create a new file in our ``tests`` direc Essentially, what this will try to do will be: 1. It will deploy a our contract -2. It will call the `always_returns_input_number` function with a random `uint256` input +2. It will call the ``always_returns_input_number`` function with a random ``uint256`` input 3. It will check if the result is the same as the input number It will continue to do this for 1,000 "fuzz runs", which means 1,000 different random numbers. You can then test it with: diff --git a/docs/source/installing_moccasin.rst b/docs/source/installing_moccasin.rst index cf999db..874bee7 100644 --- a/docs/source/installing_moccasin.rst +++ b/docs/source/installing_moccasin.rst @@ -33,7 +33,7 @@ Prerequisites Installation with uv ==================== -For those unfamiliar, `uv `_ is a fast python package manager that helps us install moccasin into it's own isolated virtual environment, so we don't get any weird dependency conflicts with other python packages. It's similar to `pip` and `pipx` if you've used them before. It even comes with some `pip` compatibility, will tools like `uv pip install`. +For those unfamiliar, `uv `_ is a fast python package manager that helps us install moccasin into it's own isolated virtual environment, so we don't get any weird dependency conflicts with other python packages. It's similar to ``pip`` and ``pipx`` if you've used them before. It even comes with some ``pip`` compatibility, will tools like ``uv pip install``. It's highly recommended you understand how `virtual environments `_ work as well. @@ -133,9 +133,9 @@ To install ``pipx``: .. note:: - You may need to restart your terminal after installing `pipx`. + You may need to restart your terminal after installing ``pipx``. -To install moccasin then with `pipx`: +To install moccasin then with ``pipx``: .. code-block:: bash @@ -153,7 +153,7 @@ Installation with pip You can install with ``pip``, and if you do so, it's highly recommended you understand how `virtual environments `_ work. -To install with `pip`: +To install with ``pip``: .. code-block:: bash diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst index 0d324e8..94c5f3c 100644 --- a/docs/source/quickstart.rst +++ b/docs/source/quickstart.rst @@ -55,10 +55,10 @@ You'll get an output like: ├── conftest.py └── test_counter.py -This is a minimal project structure that `moccasin` creates. +This is a minimal project structure that ``moccasin`` creates. - ``README.md`` is a markdown file that you can use to describe your project. -- ``moccasin.toml`` is a configuration file that `moccasin` uses to manage the project. +- ``moccasin.toml`` is a configuration file that ``moccasin`` uses to manage the project. - ``script`` is a directory that contains scripts that you can use to deploy your project. - ``src`` is a directory that contains your vyper smart contracts. - ``tests``` is a directory that contains your tests. @@ -67,7 +67,7 @@ If you run ``tree . -a``, you'll also see the "hidden" files. - ``.gitignore`` is a file that tells git which files to ignore. - ``.gitattributes`` is a file that tells git how to handle line endings. -- ``.coveragerc`` is a file that tells `pytest` how to handle coverage. +- ``.coveragerc`` is a file that tells ``pytest`` how to handle coverage. Deploying a contract @@ -91,7 +91,7 @@ Now, unlike other frameworks, with ``moccasin``, we never need to compile! Mocca We can see a python script that will: -1. Deploy our `Counter` contract. +1. Deploy our ``Counter`` contract. 2. Print the starting count inside the contract. 3. Increment the count. 4. Print the ending count inside the contract. diff --git a/moccasin/_sys_path_and_config_setup.py b/moccasin/_sys_path_and_config_setup.py index ca541ea..807173c 100644 --- a/moccasin/_sys_path_and_config_setup.py +++ b/moccasin/_sys_path_and_config_setup.py @@ -1,4 +1,5 @@ import contextlib +import os import sys from pathlib import Path from typing import Iterator, List @@ -42,12 +43,23 @@ def get_sys_paths_list(config: Config) -> List[Path]: def _patch_sys_path(paths: List[Path]) -> Iterator[None]: str_paths = [str(p) for p in paths] anchor = sys.path + anchor2 = os.environ.get("PYTHONPATH") + python_path = anchor2 + if python_path is None: + python_path = ":".join(str_paths) + else: + python_path = ":".join([*str_paths, python_path]) + os.environ["PYTHONPATH"] = python_path try: # add these with highest precedence -- conflicts should prefer user modules/code sys.path = str_paths + sys.path yield finally: sys.path = anchor + if anchor2 is None: + del os.environ["PYTHONPATH"] + else: + os.environ["PYTHONPATH"] = anchor2 # REVIEW: Might be best to just set this as **kwargs diff --git a/moccasin/commands/compile.py b/moccasin/commands/compile.py index 16c8635..f5cf6d1 100644 --- a/moccasin/commands/compile.py +++ b/moccasin/commands/compile.py @@ -210,6 +210,7 @@ def compile_( return deployer + # discard the result of the compilation so that we don't need to pickle it # between processes def compile_noret(*args, **kwargs) -> None: diff --git a/moccasin/config.py b/moccasin/config.py index 5604d0b..3f82617 100644 --- a/moccasin/config.py +++ b/moccasin/config.py @@ -560,9 +560,15 @@ def get_or_deploy_named( vyper_contract: ( ABIContract | VyperContract | ZksyncContract | None ) = None + # REVIEW: This is a bit confusing. + # Right now, if the contract is in the DB, that takes precedence over + # a recently deployed contract. This is because the DB is the source of truth. vyper_contract = self.get_latest_contract_unchecked( contract_name=contract_name, chain_id=self.chain_id ) + if vyper_contract is None: + if self._check_valid_deploy(named_contract): + vyper_contract = named_contract.recently_deployed_contract if vyper_contract is not None: return vyper_contract else: @@ -702,7 +708,10 @@ def _get_abi_and_deployer_from_params( else: contract_path = config.find_contract(abi_like) deployer = boa.load_partial(str(contract_path)) - abi = build_abi_output(deployer.compiler_data) + if isinstance(deployer, VyperDeployer): + abi = build_abi_output(deployer.compiler_data) + elif isinstance(deployer, ZksyncDeployer): + abi = deployer.zkvyper_data abi = cast(list, abi) return abi, deployer if isinstance(abi_like, list): @@ -816,7 +825,6 @@ def __init__(self, toml_data: dict, project_root: Path): address=contract_data.get("address", None), ) toml_data = self._add_local_network_defaults(toml_data) - for network_name, network_data in toml_data["networks"].items(): # Check for restricted items for pyevm or eravm if network_name in [PYEVM, ERAVM]: diff --git a/pyproject.toml b/pyproject.toml index 131e6b6..a7c83b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,22 +1,22 @@ [project] name = "moccasin" -version = "0.3.4b4" +version = "0.3.4b5" description = "Pythonic smart contract development framework using Titanoboa" authors = [ { name = "PatrickAlphac", email = "54278053+PatrickAlphaC@users.noreply.github.com" }, { name = "charles-cooper", email = "3867501+charles-cooper@users.noreply.github.com" }, ] dependencies = [ - "titanoboa>=v0.2.5b1", + "titanoboa>=v0.2.5", "python-dotenv>=1.0.1", - "titanoboa-zksync>=0.2.7", + "titanoboa-zksync>=0.2.8", "tqdm>=4.66.5", - "tomlkit>=0.13.2", # For preserving comments when writing to toml + "tomlkit>=0.13.2", # For preserving comments when writing to toml "tomli-w>=1.0.0", "pytest-cov>=5.0.0", "uv>=0.4.15", "pytest-xdist>=3.6.1", - "vyper==0.4.0", # We will want to get rid of this hard-coded dependency in 0.3.4 of moccasin + "vyper==0.4.0", # We will want to get rid of this hard-coded dependency in 0.3.4 of moccasin ] readme = "README.md" requires-python = ">= 3.11, <= 3.13" diff --git a/tests/cli/deployments/test_unit_deployments_cli.py b/tests/cli/deployments/test_unit_deployments_cli.py index 4adc3b6..636f0c4 100644 --- a/tests/cli/deployments/test_unit_deployments_cli.py +++ b/tests/cli/deployments/test_unit_deployments_cli.py @@ -21,7 +21,7 @@ def test_generate_sql_from_args_with_where(blank_tempdir): sql_query, params = active_network._generate_sql_from_args( contract_name=contract_name, chain_id=chain_id, limit=limit, db=db ) - expected_sql = "SELECT contract_address,contract_name,rpc,deployer,tx_hash,broadcast_ts,tx_dict,receipt_dict,source_code,abi,session_id,deployment_id FROM deployments WHERE contract_name = ? AND json_extract(tx_dict, '$.chainId') = ? ORDER BY broadcast_ts DESC LIMIT ? " + expected_sql = "SELECT contract_address,contract_name,filename,rpc,deployer,tx_hash,broadcast_ts,tx_dict,receipt_dict,source_code,abi,session_id,deployment_id FROM deployments WHERE contract_name = ? AND json_extract(tx_dict, '$.chainId') = ? ORDER BY broadcast_ts DESC LIMIT ? " expected_parametrs = ("MockV3Aggregator", "31337", 1) # Assert @@ -39,7 +39,7 @@ def test_generate_sql_from_args_without_where(blank_tempdir): # Act sql_query, params = active_network._generate_sql_from_args(db=db) - expected_sql = "SELECT contract_address,contract_name,rpc,deployer,tx_hash,broadcast_ts,tx_dict,receipt_dict,source_code,abi,session_id,deployment_id FROM deployments ORDER BY broadcast_ts DESC " + expected_sql = "SELECT contract_address,contract_name,filename,rpc,deployer,tx_hash,broadcast_ts,tx_dict,receipt_dict,source_code,abi,session_id,deployment_id FROM deployments ORDER BY broadcast_ts DESC " expected_parametrs = () # Assert @@ -61,7 +61,7 @@ def test_generate_sql_from_args_without_and(blank_tempdir): sql_query, params = active_network._generate_sql_from_args( contract_name=contract_name, limit=limit, db=db ) - expected_sql = "SELECT contract_address,contract_name,rpc,deployer,tx_hash,broadcast_ts,tx_dict,receipt_dict,source_code,abi,session_id,deployment_id FROM deployments WHERE contract_name = ? ORDER BY broadcast_ts DESC LIMIT ? " + expected_sql = "SELECT contract_address,contract_name,filename,rpc,deployer,tx_hash,broadcast_ts,tx_dict,receipt_dict,source_code,abi,session_id,deployment_id FROM deployments WHERE contract_name = ? ORDER BY broadcast_ts DESC LIMIT ? " expected_parametrs = ("MockV3Aggregator", 1) # Assert diff --git a/tests/cli/test_cli_inspect.py b/tests/cli/test_cli_inspect.py new file mode 100644 index 0000000..5cf67ee --- /dev/null +++ b/tests/cli/test_cli_inspect.py @@ -0,0 +1,21 @@ +import os +import subprocess +from pathlib import Path + +from moccasin.commands.inspect import inspect_contract + + +def test_inspect_layout_imports(mox_path, installation_project_config, installation_temp_path): + current_dir = Path.cwd() + try: + os.chdir(current_dir.joinpath(installation_temp_path)) + result = subprocess.run( + [mox_path, "install"], check=True, capture_output=True, text=True + ) + result = inspect_contract("MyToken", "storage_layout", print_out=False) + finally: + os.chdir(current_dir) + layout = result["storage_layout"] + # Spot check + assert layout["ow"]["owner"] == {'type': 'address', 'n_slots': 1, 'slot': 0} + assert layout["erc20"]["balanceOf"] == {'type': 'HashMap[address, uint256]', 'n_slots': 1, 'slot': 1} \ No newline at end of file diff --git a/tests/cli/test_cli_install.py b/tests/cli/test_cli_install.py index d53d829..d523232 100644 --- a/tests/cli/test_cli_install.py +++ b/tests/cli/test_cli_install.py @@ -2,13 +2,11 @@ import subprocess from pathlib import Path -from tests.conftest import INSTALL_PROJECT_PATH - -def test_run_help(mox_path, installation_cleanup_dependencies): +def test_run_help(mox_path, installation_cleanup_dependencies, installation_temp_path): current_dir = Path.cwd() try: - os.chdir(INSTALL_PROJECT_PATH) + os.chdir(installation_temp_path) result = subprocess.run( [mox_path, "install", "-h"], check=True, capture_output=True, text=True ) diff --git a/tests/data/installation_project/moccasin.toml b/tests/data/installation_project/moccasin.toml index 1106748..bfa464f 100644 --- a/tests/data/installation_project/moccasin.toml +++ b/tests/data/installation_project/moccasin.toml @@ -1,5 +1,9 @@ [project] -dependencies = ["snekmate", "moccasin"] +dependencies = [ + "snekmate", + "moccasin", + "PatrickAlphaC/test_repo", +] # PRESERVE COMMENTS diff --git a/tests/unit/test_unit_inspect.py b/tests/unit/test_unit_inspect.py index 3657e9f..60316c8 100644 --- a/tests/unit/test_unit_inspect.py +++ b/tests/unit/test_unit_inspect.py @@ -17,16 +17,4 @@ def test_inspect_counter(complex_project_config, complex_temp_path): result = inspect_contract("Counter", "function_signatures", print_out=False) finally: os.chdir(current_dir) - assert result == expected_dir - -def test_inspect_layout_imports(installation_project_config, installation_temp_path): - current_dir = Path.cwd() - try: - os.chdir(current_dir.joinpath(installation_temp_path)) - result = inspect_contract("MyToken", "storage_layout", print_out=False) - finally: - os.chdir(current_dir) - layout = result["storage_layout"] - # Spot check - assert layout["ow"]["owner"] == {'type': 'address', 'n_slots': 1, 'slot': 0} - assert layout["erc20"]["balanceOf"] == {'type': 'HashMap[address, uint256]', 'n_slots': 1, 'slot': 1} \ No newline at end of file + assert result == expected_dir \ No newline at end of file diff --git a/uv.lock b/uv.lock index bbee266..6f62350 100644 --- a/uv.lock +++ b/uv.lock @@ -682,7 +682,7 @@ wheels = [ [[package]] name = "moccasin" -version = "0.3.4b4" +version = "0.3.4b5" source = { editable = "." } dependencies = [ { name = "pytest-cov" }, @@ -728,8 +728,8 @@ requires-dist = [ { name = "sphinx-copybutton", marker = "extra == 'docs'", specifier = ">=0.5.2" }, { name = "sphinx-multiversion", marker = "extra == 'docs'", specifier = ">=0.2.4" }, { name = "sphinx-tabs", marker = "extra == 'docs'", specifier = ">=3.4.5" }, - { name = "titanoboa", specifier = ">=0.2.5b1" }, - { name = "titanoboa-zksync", specifier = ">=0.2.7" }, + { name = "titanoboa", specifier = ">=0.2.5" }, + { name = "titanoboa-zksync", specifier = ">=0.2.8" }, { name = "tomli-w", specifier = ">=1.0.0" }, { name = "tomlkit", specifier = ">=0.13.2" }, { name = "tqdm", specifier = ">=4.66.5" }, @@ -1291,7 +1291,7 @@ wheels = [ [[package]] name = "titanoboa" -version = "0.2.5b1" +version = "0.2.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "eth-abi" }, @@ -1308,21 +1308,21 @@ dependencies = [ { name = "vvm" }, { name = "vyper" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/e0/c3749d2dcae01b0d1ddbd92ea55278610dca2551aed686d351df7c2cd84d/titanoboa-0.2.5b1.tar.gz", hash = "sha256:599ff6bed735f9e0a80ba160899486c144e51ce6d99c9f0dc51d91b0f50b0f09", size = 91748 } +sdist = { url = "https://files.pythonhosted.org/packages/72/b9/dd934b73f02fe802e3cb00f103e91e75e66f2d96271033b101212bcae4c0/titanoboa-0.2.5.tar.gz", hash = "sha256:734830569296e851255ddc4925359a9a25f040a4a41f88fe3682a456faa3c662", size = 91978 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6c/87/db4f83859c53f150de07b1e9154ae8bbf4e382af81751c0b3d5e065130ee/titanoboa-0.2.5b1-py3-none-any.whl", hash = "sha256:752ab527182d0df95a80ce952d24b5b0149c23de7a991204399071ead587f0d3", size = 102804 }, + { url = "https://files.pythonhosted.org/packages/ce/c5/315e398f5209e300cde62291f196485fee720269d953f65bdb9114d78fc3/titanoboa-0.2.5-py3-none-any.whl", hash = "sha256:e678aad87408ae5a664a9cb71b886cb23b95e6204141044ccd8fe3bc97b4e14f", size = 103011 }, ] [[package]] name = "titanoboa-zksync" -version = "0.2.7" +version = "0.2.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "titanoboa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/30/b4/a9f8287270297eeb85ab290387323c0900c441c8d99b7cc534f77479d3cf/titanoboa_zksync-0.2.7.tar.gz", hash = "sha256:9bba3bae2e002818a3af8a52e55732da9fb96eed743b262488bb0fb35665cfa3", size = 25867 } +sdist = { url = "https://files.pythonhosted.org/packages/4f/88/6abf3125f15475ac1640ffbea737c84a714d6fd9ad4c8bc0f5e98b982545/titanoboa_zksync-0.2.8.tar.gz", hash = "sha256:c59ad609427e53ac04f210482cee9aac205d73af8594a8e800bc7a5a71cc477d", size = 25904 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/8a/e872de7df5abca5ad1348365a6da47c7d22947c10396d96977f7e3001d21/titanoboa_zksync-0.2.7-py3-none-any.whl", hash = "sha256:a12f3d84b1033f8bbc949c067c9dd6418b701bc84d73b7f8a8c98f4f11e44b5a", size = 25281 }, + { url = "https://files.pythonhosted.org/packages/f4/88/cf5c261091a4c87a91f3d4962566d936056203e0614c0a9a242c05369fdd/titanoboa_zksync-0.2.8-py3-none-any.whl", hash = "sha256:631f3ed892183564223822a29bb2a4ee2642de5344de1d7f4e106bab3cc6715f", size = 25327 }, ] [[package]] @@ -1434,15 +1434,15 @@ wheels = [ [[package]] name = "vvm" -version = "0.3.1" +version = "0.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ff/da/7847c6a06e665381b41ef4cd05ed1a9d737c4abbe3a49136f65fb9a9b6d2/vvm-0.3.1.tar.gz", hash = "sha256:c6d9c82efda144400b4e2944c1988ab2a60461f1d5535139c9652b73172e0098", size = 13675 } +sdist = { url = "https://files.pythonhosted.org/packages/94/1c/3004928eaf560ed7164514cf66cdea6e84415e2a592b95bc466b568661b1/vvm-0.3.2.tar.gz", hash = "sha256:939838e6417923ef20c48d1a5f9d9fcb39e963c7e0152aaf99c966a6c332e770", size = 14164 } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/d3/dc8111eda61078db5559b3aadf2e2471a21c9c1f4bdb3ca92577c4b68a91/vvm-0.3.1-py3-none-any.whl", hash = "sha256:2aa753e5452ada83f5a3a68b065de12d01231f4e9db4be085fea50f7bd22dcc4", size = 13048 }, + { url = "https://files.pythonhosted.org/packages/98/38/a180481ac2369696f966cfb776c71569d7c0cc2676a03daedd83b21f5617/vvm-0.3.2-py3-none-any.whl", hash = "sha256:f9f4ccad6c9a8ff6978285f005fbb086777baa160e6132d454c35d66bc94d017", size = 13385 }, ] [[package]]