From 9994283effac2ff4b5715f32d9c6dbd86ea83cb8 Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Wed, 31 Jan 2024 18:41:27 -0600 Subject: [PATCH] feat: upgrade to 0.7 --- .github/workflows/commitlint.yaml | 6 ++-- .github/workflows/publish.yaml | 6 ++-- .github/workflows/test.yaml | 6 ++-- .github/workflows/title.yaml | 6 ++-- .mdformat.toml | 1 - .pre-commit-config.yaml | 10 +++--- CONTRIBUTING.md | 4 +-- README.md | 6 ++-- ape_keyring/_secrets.py | 4 +-- ape_keyring/accounts.py | 55 +++++++++++++++++++++++++++---- pyproject.toml | 5 ++- setup.py | 22 +++++++------ tests/test_accounts.py | 3 +- 13 files changed, 92 insertions(+), 42 deletions(-) delete mode 100644 .mdformat.toml diff --git a/.github/workflows/commitlint.yaml b/.github/workflows/commitlint.yaml index 1d19118..3b8de5e 100644 --- a/.github/workflows/commitlint.yaml +++ b/.github/workflows/commitlint.yaml @@ -9,14 +9,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: "3.10" - name: Install Dependencies run: pip install .[dev] diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 736a2f3..2c55069 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -10,12 +10,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: "3.10" - name: Install dependencies run: | diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4c4f73c..1ad5259 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,7 +19,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: 3.8 + python-version: "3.10" - name: Install Dependencies run: pip install .[lint] @@ -45,7 +45,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: 3.8 + python-version: "3.10" - name: Install Dependencies run: pip install .[lint,test] # Might need test deps @@ -59,7 +59,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] # eventually add `windows-latest` - python-version: [3.8, 3.9, "3.10"] + python-version: [3.9, "3.10", "3.11"] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/title.yaml b/.github/workflows/title.yaml index e52d792..6e8999f 100644 --- a/.github/workflows/title.yaml +++ b/.github/workflows/title.yaml @@ -12,12 +12,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: "3.10" - name: Install Dependencies run: pip install commitizen diff --git a/.mdformat.toml b/.mdformat.toml deleted file mode 100644 index 01b2fb0..0000000 --- a/.mdformat.toml +++ /dev/null @@ -1 +0,0 @@ -number = true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66ed7d6..e8dfcaa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.5.0 hooks: - id: check-yaml @@ -10,24 +10,24 @@ repos: - id: isort - repo: https://github.com/psf/black - rev: 22.12.0 + rev: 24.1.1 hooks: - id: black name: black - repo: https://github.com/pycqa/flake8 - rev: 5.0.4 + rev: 7.0.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.991 + rev: v1.8.0 hooks: - id: mypy additional_dependencies: [types-setuptools, pydantic==1.10.4] - repo: https://github.com/executablebooks/mdformat - rev: 0.7.14 + rev: 0.7.17 hooks: - id: mdformat additional_dependencies: [mdformat-gfm, mdformat-frontmatter] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1cebf2d..66702a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ To get started with working on the codebase, use the following steps prepare you ```bash # clone the github repo and navigate into the folder -git clone https://github.com/ApeWorX/ape-keyring.git +git clone https://github.com/antazoey/ape-keyring.git cd ape-keyring # create and load a virtual environment @@ -46,4 +46,4 @@ A pull request represents the start of a discussion, and doesn't necessarily nee If you are opening a work-in-progress pull request to verify that it passes CI tests, please consider [marking it as a draft](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). -Join the Ethereum Python [Discord](https://discord.gg/PcEJ54yX) if you have any questions. +Join the ApeWorX [Discord](https://discord.gg/apeworx) if you have any questions. diff --git a/README.md b/README.md index d2f0349..6e8a488 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This guide demonstrates how to use `ape-keyring` as an account plugin and secret ## Dependencies -- [python3](https://www.python.org/downloads) version 3.8 or greater, python3-dev +- [python3](https://www.python.org/downloads) version 3.9 or greater, python3-dev ## Installation @@ -26,13 +26,15 @@ pip install ape-keyring You can clone the repository and use [`setuptools`](https://github.com/pypa/setuptools) for the most up-to-date version: ```bash -git clone https://github.com/ApeWorX/ape-keyring.git +git clone https://github.com/antazoey/ape-keyring.git cd ape_keyring python3 setup.py install ``` ## Quick Usage +Use `ape-keyring` for both accounts and secrets. + ### Accounts Use `ape-keyring` as an account plugin. diff --git a/ape_keyring/_secrets.py b/ape_keyring/_secrets.py index 6eb94bf..05a54b9 100644 --- a/ape_keyring/_secrets.py +++ b/ape_keyring/_secrets.py @@ -48,11 +48,11 @@ def global_keys(self) -> List[str]: @property def config(self) -> KeyringConfig: raw_config = load_config(self._path / "ape-config.yaml") - return KeyringConfig.parse_obj(raw_config.get("keyring", {})) + return KeyringConfig.model_validate(raw_config.get("keyring", {})) @property def do_set_env_vars(self) -> bool: - stored_value = self.config.dict().get("set_env_vars") or "f" + stored_value = self.config.model_dump(mode="json", by_alias=True).get("set_env_vars") or "f" return str(stored_value).lower() in ["1", "true", "t"] def get_secret(self, key, scope: Union[str, Scope] = Scope.GLOBAL) -> str: diff --git a/ape_keyring/accounts.py b/ape_keyring/accounts.py index a2f074a..df01593 100644 --- a/ape_keyring/accounts.py +++ b/ape_keyring/accounts.py @@ -1,12 +1,14 @@ -from typing import Iterator, Optional +from typing import Any, Iterator, Optional from ape.api import AccountAPI, AccountContainerAPI, TransactionAPI from ape.exceptions import AccountsError from ape.logging import logger from ape.types import AddressType, MessageSignature, TransactionSignature from ape.utils import cached_property +from eip712 import EIP712Message from eth_account import Account as EthAccount -from eth_account.messages import SignableMessage +from eth_account.messages import SignableMessage, encode_defunct +from eth_pydantic_types import HexBytes from eth_utils import to_bytes from ape_keyring.exceptions import EmptyAliasError, MissingSecretError @@ -84,18 +86,59 @@ def __key(self) -> str: return key - def sign_message(self, msg: SignableMessage) -> Optional[MessageSignature]: - if not self.__autosign and not agree_to_sign(msg, "message"): + def sign_message(self, msg: Any, **signer_options) -> Optional[MessageSignature]: + if isinstance(msg, str): + msg = encode_defunct(text=msg) + + elif isinstance(msg, int): + msg = encode_defunct(hexstr=HexBytes(msg).hex()) + + elif isinstance(msg, bytes): + msg = encode_defunct(primitive=msg) + + elif isinstance(msg, EIP712Message): + # Display message data to user + display_msg = "Signing EIP712 Message\n" + + # Domain Data + display_msg += "Domain\n" + if msg._name_: + display_msg += f"\tName: {msg._name_}\n" + if msg._version_: + display_msg += f"\tVersion: {msg._version_}\n" + if msg._chainId_: + display_msg += f"\tChain ID: {msg._chainId_}\n" + if msg._verifyingContract_: + display_msg += f"\tContract: {msg._verifyingContract_}\n" + if msg._salt_: + display_msg += f"\tSalt: 0x{msg._salt_.hex()}\n" + + # Message Data + display_msg += "Message\n" + for field, value in msg._body_["message"].items(): + display_msg += f"\t{field}: {value}\n" + + # Convert EIP712Message to SignableMessage for handling below + msg = msg.signable_message + + elif not isinstance(msg, SignableMessage): + logger.warning("Unsupported message type, (type=%r, msg=%r)", type(msg), msg) return None signed_msg = EthAccount.sign_message(msg, self.__key) - return MessageSignature(v=signed_msg.v, r=to_bytes(signed_msg.r), s=to_bytes(signed_msg.s)) + return MessageSignature( + v=signed_msg.v, + r=to_bytes(signed_msg.r), + s=to_bytes(signed_msg.s), + ) def sign_transaction(self, txn: TransactionAPI, **signer_options) -> Optional[TransactionAPI]: if not self.__autosign and not agree_to_sign(txn, "transaction"): return None - signed_txn = EthAccount.sign_transaction(txn.dict(), self.__key) + signed_txn = EthAccount.sign_transaction( + txn.model_dump(by_alias=True, mode="json"), self.__key + ) txn.signature = TransactionSignature( v=signed_txn.v, r=to_bytes(signed_txn.r), s=to_bytes(signed_txn.s) ) diff --git a/pyproject.toml b/pyproject.toml index 4583f03..c80c6fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ write_to = "ape_keyring/version.py" [tool.black] line-length = 100 -target-version = ['py37', 'py38', 'py39', 'py310'] +target-version = ['py39', 'py310', 'py311'] include = '\.pyi?$' [tool.pytest.ini_options] @@ -36,3 +36,6 @@ force_grid_wrap = 0 include_trailing_comma = true multi_line_output = 3 use_parentheses = true + +[tool.mdformat] +number = true diff --git a/setup.py b/setup.py index 00e3cd1..16b0621 100644 --- a/setup.py +++ b/setup.py @@ -10,14 +10,15 @@ "hypothesis>=6.2.0,<7.0", # Strategy-based fuzzer ], "lint": [ - "black>=22.10.0", # auto-formatter and linter - "mypy>=0.991,<1", # Static type analyzer + "black>=24.1.1", # auto-formatter and linter + "mypy>=1.8.0,<2", # Static type analyzer "types-setuptools", # Needed for mypy typeshed - "flake8>=5.0.4", # Style linter + "flake8>=7.0.0", # Style linter "isort>=5.10.1", # Import sorting linter - "mdformat>=0.7.16", # Auto-formatter for markdown + "mdformat>=0.7.17", # Auto-formatter for markdown "mdformat-gfm>=0.3.5", # Needed for formatting GitHub-flavored markdown "mdformat-frontmatter>=0.4.1", # Needed for frontmatters-style headers in issue templates + "mdformat-pyproject>=0.0.1", # Allows configuring in pyproject.toml ], "release": [ # `release` GitHub Action job uses this "setuptools", # Installation tool @@ -51,16 +52,17 @@ description="""ape-keyring: Store secrets for ape using Keyring.""", long_description=long_description, long_description_content_type="text/markdown", - author="Juliya Smith", - author_email="juliya@juliyasmith.com", - url="https://github.com/unparalleled-js/ape-keyring", + author="antazoey", + author_email="antyzoa@gmail.com", + url="https://github.com/antazoey/ape-keyring", include_package_data=True, install_requires=[ "click", # Use same version as eth-ape - "eth-ape>=0.6.5,<0.7", + "eth-ape>=0.7.7,<0.8", "eth-account", # Use same version as eth-ape "eth-utils", # Use same version as eth-ape - "keyring>=23.9.1,<24", + "eip712", # Use same version as eth-ape + "keyring>=24.3.0,<25", ], entry_points={"ape_cli_subcommands": ["ape_keyring=ape_keyring._cli:cli"]}, python_requires=">=3.8,<4", @@ -79,8 +81,8 @@ "Operating System :: MacOS", "Operating System :: POSIX", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", ], ) diff --git a/tests/test_accounts.py b/tests/test_accounts.py index 44b2fbe..6b0b71b 100644 --- a/tests/test_accounts.py +++ b/tests/test_accounts.py @@ -48,7 +48,8 @@ def test_set_autosign(keyring_account, eip191_message, runner): def test_delete(cli, runner, keyring_account): result = runner.invoke(cli, ["keyring", "accounts", "delete", keyring_account.alias]) - assert f"SUCCESS: Account '{keyring_account.alias}' removed from keying" in result.output + assert "SUCCESS" in result.output + assert f"Account '{keyring_account.alias}' removed from keying" in result.output # Verify account is NOT listed in 'list' command result = runner.invoke(cli, ["keyring", "accounts", "list"])