From a5b0c84d2a4956a021327b7677cd90f7092549c3 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 13 Sep 2023 16:19:03 +0300 Subject: [PATCH 01/62] install rust globally --- multiversx_sdk_cli/dependencies/modules.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 2e367fc2..405a2f76 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -269,12 +269,12 @@ def _do_install(self, tag: str) -> None: toolchain = "nightly" args = [str(installer_path), "--verbose", "--default-toolchain", toolchain, "--profile", - "minimal", "--target", "wasm32-unknown-unknown", "--no-modify-path", "-y"] - output = myprocess.run_process(args, env=self.get_env_for_install()) + "minimal", "--target", "wasm32-unknown-unknown", "-y"] + output = myprocess.run_process(args) if output: sc_meta_args = ["cargo", "install", "multiversx-sc-meta"] - myprocess.run_process(sc_meta_args, env=self.get_env_for_install()) + myprocess.run_process(sc_meta_args) def _get_installer_url(self) -> str: if workstation.is_windows(): @@ -347,14 +347,7 @@ def _get_env_for_is_installed_in_sdk(self) -> Dict[str, str]: } def get_env_for_install(self): - directory = self.get_directory("") - - env = { - # For installation, wget (or curl) and cc (build-essential) are also required. - "PATH": f"{path.join(directory, 'bin')}:{os.environ['PATH']}", - "RUSTUP_HOME": str(directory), - "CARGO_HOME": str(directory) - } + env: Dict[str, str] = {} if workstation.is_windows(): env["RUSTUP_USE_HYPER"] = "1" From 7250ffa609932e731ec447dcc7896713bdeda3fd Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 13 Sep 2023 16:34:53 +0300 Subject: [PATCH 02/62] try fix env --- multiversx_sdk_cli/dependencies/modules.py | 1 + 1 file changed, 1 insertion(+) diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 405a2f76..86234393 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -318,6 +318,7 @@ def get_directory(self, tag: str) -> Path: return tools_folder / "vendor-rust" def get_env(self): + return os.environ directory = self.get_directory("") resolution = self.get_resolution() From 69fba5ed552b244b6b548624afec5d61e0291c44 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 13 Sep 2023 17:06:29 +0300 Subject: [PATCH 03/62] code cleanup --- multiversx_sdk_cli/dependencies/modules.py | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 86234393..3a15121e 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -317,26 +317,8 @@ def get_directory(self, tag: str) -> Path: tools_folder = workstation.get_tools_folder() return tools_folder / "vendor-rust" - def get_env(self): - return os.environ - directory = self.get_directory("") - resolution = self.get_resolution() - - if resolution == DependencyResolution.Host: - return { - "PATH": os.environ.get("PATH", ""), - "RUSTUP_HOME": os.environ.get("RUSTUP_HOME", ""), - "CARGO_HOME": os.environ.get("CARGO_HOME", "") - } - if resolution == DependencyResolution.SDK: - return { - # At this moment, cc (build-essential) is sometimes required by the meta crate (e.g. for reports) - "PATH": f"{path.join(directory, 'bin')}:{os.environ['PATH']}", - "RUSTUP_HOME": str(directory), - "CARGO_HOME": str(directory) - } - - raise errors.BadDependencyResolution(self.key, resolution) + def get_env(self) -> Dict[str, str]: + return dict(os.environ) def _get_env_for_is_installed_in_sdk(self) -> Dict[str, str]: directory = self.get_directory("") From 0bb5667fdae5e96cd52f5908146c8ff92703a917 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 15 Sep 2023 14:00:25 +0300 Subject: [PATCH 04/62] update version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a464b548..d61e5d8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "multiversx-sdk-cli" -version = "8.1.0" +version = "8.2.0b1" authors = [ { name="MultiversX" }, ] From 5295378a41206d5bbf8c7f41d04420553b096602 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 15 Sep 2023 14:54:32 +0300 Subject: [PATCH 05/62] remove code related to old rust env --- multiversx_sdk_cli/config.py | 1 - multiversx_sdk_cli/dependencies/modules.py | 39 +++------------------- 2 files changed, 5 insertions(+), 35 deletions(-) diff --git a/multiversx_sdk_cli/config.py b/multiversx_sdk_cli/config.py index 638a22e4..e29ba820 100644 --- a/multiversx_sdk_cli/config.py +++ b/multiversx_sdk_cli/config.py @@ -154,7 +154,6 @@ def get_defaults() -> Dict[str, Any]: # ide.elrond.com will be removed, TBD if clang will still be downloaded "dependencies.llvm.urlTemplate.linux": "https://ide.elrond.com/vendor-llvm/{TAG}/linux-amd64.tar.gz?t=19feb", "dependencies.llvm.urlTemplate.osx": "https://ide.elrond.com/vendor-llvm/{TAG}/darwin-amd64.tar.gz?t=19feb", - "dependencies.rust.resolution": "SDK", "dependencies.rust.tag": "nightly-2023-05-26", "dependencies.golang.resolution": "SDK", "dependencies.golang.tag": "go1.20.7", diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 3a15121e..6e4d075e 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -294,24 +294,12 @@ def uninstall(self, tag: str): shutil.rmtree(directory) def is_installed(self, tag: str) -> bool: - resolution = self.get_resolution() - - if resolution == DependencyResolution.Host: - which_rustc = shutil.which("rustc") - which_cargo = shutil.which("cargo") - logger.info(f"which rustc: {which_rustc}") - logger.info(f"which cargo: {which_cargo}") - - return which_rustc is not None and which_cargo is not None - if resolution == DependencyResolution.SDK: - try: - env = self._get_env_for_is_installed_in_sdk() - myprocess.run_process(["rustc", "--version"], env=env) - return True - except Exception: - return False + which_rustc = shutil.which("rustc") + which_cargo = shutil.which("cargo") + logger.info(f"which rustc: {which_rustc}") + logger.info(f"which cargo: {which_cargo}") - raise errors.BadDependencyResolution(self.key, resolution) + return which_rustc is not None and which_cargo is not None def get_directory(self, tag: str) -> Path: tools_folder = workstation.get_tools_folder() @@ -320,23 +308,6 @@ def get_directory(self, tag: str) -> Path: def get_env(self) -> Dict[str, str]: return dict(os.environ) - def _get_env_for_is_installed_in_sdk(self) -> Dict[str, str]: - directory = self.get_directory("") - - return { - "PATH": str(directory / "bin"), - "RUSTUP_HOME": str(directory), - "CARGO_HOME": str(directory) - } - - def get_env_for_install(self): - env: Dict[str, str] = {} - - if workstation.is_windows(): - env["RUSTUP_USE_HYPER"] = "1" - - return env - def get_latest_release(self) -> str: raise errors.UnsupportedConfigurationValue("Rust tag must either be explicit, empty or 'nightly'") From 2845d07babf34db4f91abafdb185950967ede622 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 15 Sep 2023 15:02:02 +0300 Subject: [PATCH 06/62] install rust for tests --- .github/workflows/build.yml | 75 +++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 24757526..ad43b77c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,13 +5,13 @@ name: build on: pull_request: - branches: [ main, feat/* ] + branches: [main, feat/*] workflow_dispatch: jobs: build: name: Build and Test mxpy for ${{ matrix.os }}, python ${{ matrix.python-version }} - + runs-on: ${{ matrix.os }} strategy: @@ -20,38 +20,39 @@ jobs: python-version: [3.8] steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python3 -m pip install --upgrade pip - pip3 install -r requirements.txt - pip3 install pytest - - name: Install libtinfo5 - if: ${{ matrix.os != 'macos-latest' }} - run: | - sudo apt update - sudo apt install -y libtinfo5 - - name: Set github_api_token - run: | - mkdir ~/multiversx-sdk - export PYTHONPATH=. - python3 -m multiversx_sdk_cli.cli config new test - python3 -m multiversx_sdk_cli.cli config set github_api_token ${{ secrets.GITHUB_TOKEN }} - - name: Setup test dependencies - run: | - python3 -m multiversx_sdk_cli.cli deps install testwallets - python3 -m multiversx_sdk_cli.cli deps install wasm-opt - - name: Run unit tests - run: | - export PYTHONPATH=. - pytest . - - name: Run CLI tests - run: | - python3 -m multiversx_sdk_cli.cli config set dependencies.vmtools.tag v1.4.60 - cd ./multiversx_sdk_cli/tests - source ./test_cli_contracts.sh && testAll || return 1 - source ./test_cli_dns.sh && testOffline || return 1 + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + pip3 install -r requirements.txt + pip3 install pytest + - name: Install libtinfo5 + if: ${{ matrix.os != 'macos-latest' }} + run: | + sudo apt update + sudo apt install -y libtinfo5 + - name: Set github_api_token + run: | + mkdir ~/multiversx-sdk + export PYTHONPATH=. + python3 -m multiversx_sdk_cli.cli config new test + python3 -m multiversx_sdk_cli.cli config set github_api_token ${{ secrets.GITHUB_TOKEN }} + - name: Setup test dependencies + run: | + python3 -m multiversx_sdk_cli.cli deps install testwallets + python3 -m multiversx_sdk_cli.cli deps install wasm-opt + python3 -m multiversx_sdk_cli.cli deps install rust + - name: Run unit tests + run: | + export PYTHONPATH=. + pytest . + - name: Run CLI tests + run: | + python3 -m multiversx_sdk_cli.cli config set dependencies.vmtools.tag v1.4.60 + cd ./multiversx_sdk_cli/tests + source ./test_cli_contracts.sh && testAll || return 1 + source ./test_cli_dns.sh && testOffline || return 1 From 6906afaf9ce74b3d0a3a0aee2f97304429783d01 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 18 Sep 2023 14:02:42 +0300 Subject: [PATCH 07/62] remove explicit rust installation for workflow --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad43b77c..107c0815 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,6 @@ jobs: run: | python3 -m multiversx_sdk_cli.cli deps install testwallets python3 -m multiversx_sdk_cli.cli deps install wasm-opt - python3 -m multiversx_sdk_cli.cli deps install rust - name: Run unit tests run: | export PYTHONPATH=. From 47c897e4338a50fc1e84fa654bcebbda18df064b Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 18 Sep 2023 14:26:08 +0300 Subject: [PATCH 08/62] add pytest flag for showing logs --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 107c0815..84e51b8f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: - name: Run unit tests run: | export PYTHONPATH=. - pytest . + pytest -s . - name: Run CLI tests run: | python3 -m multiversx_sdk_cli.cli config set dependencies.vmtools.tag v1.4.60 From 7ef887f4f64f5cf78b8cdebadcb11a8a6dd3a60f Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 18 Sep 2023 15:53:20 +0300 Subject: [PATCH 09/62] set flag for pytest logs --- multiversx_sdk_cli/tests/test_cli_contracts.py | 2 +- pytest.ini | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/multiversx_sdk_cli/tests/test_cli_contracts.py b/multiversx_sdk_cli/tests/test_cli_contracts.py index 774bab25..4cf406b7 100644 --- a/multiversx_sdk_cli/tests/test_cli_contracts.py +++ b/multiversx_sdk_cli/tests/test_cli_contracts.py @@ -38,7 +38,7 @@ def test_contract_new_with_bad_code(): def replace_variable_with_unknown_variable(): - # this is done in order to replace the value added in the adder contract witha unknown variable + # this is done in order to replace the value added in the adder contract with a unknown variable with open(parent / "testdata-out" / "SANDBOX" / "adder-bad-src" / "src" / "adder.rs", "r") as f: contract_lines = f.readlines() diff --git a/pytest.ini b/pytest.ini index 81836503..1d51c3ca 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,5 @@ [pytest] markers = skip_on_windows: marks tests as being skiped when running on windows (deselect with '-m "skip_on_windows"') + +log_cli = True From 6c22bac3f61cc1b7c04bad27121056e588b31d6b Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 21 Sep 2023 10:49:47 +0300 Subject: [PATCH 10/62] remove pytest for testing purposes --- .github/workflows/build.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 84e51b8f..955a1c4e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,10 +45,6 @@ jobs: run: | python3 -m multiversx_sdk_cli.cli deps install testwallets python3 -m multiversx_sdk_cli.cli deps install wasm-opt - - name: Run unit tests - run: | - export PYTHONPATH=. - pytest -s . - name: Run CLI tests run: | python3 -m multiversx_sdk_cli.cli config set dependencies.vmtools.tag v1.4.60 From e9542fe2e562bfb03aaf34df4b89630f5dd8cc5b Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 21 Sep 2023 15:40:03 +0300 Subject: [PATCH 11/62] debugging --- .github/workflows/build.yml | 9 +++++++++ multiversx_sdk_cli/dependencies/modules.py | 2 ++ 2 files changed, 11 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 955a1c4e..19314250 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,6 +45,15 @@ jobs: run: | python3 -m multiversx_sdk_cli.cli deps install testwallets python3 -m multiversx_sdk_cli.cli deps install wasm-opt + python3 -m multiversx_sdk_cli.cli deps install rust + ls $HOME/.cargo/bin + echo $PATH + cat $HOME/.bashrc + - name: Run unit tests + run: | + export PYTHONPATH=. + echo $PATH + pytest . - name: Run CLI tests run: | python3 -m multiversx_sdk_cli.cli config set dependencies.vmtools.tag v1.4.60 diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 6e4d075e..4a67c6a0 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -296,6 +296,8 @@ def uninstall(self, tag: str): def is_installed(self, tag: str) -> bool: which_rustc = shutil.which("rustc") which_cargo = shutil.which("cargo") + print(which_rustc) + print(which_cargo) logger.info(f"which rustc: {which_rustc}") logger.info(f"which cargo: {which_cargo}") From 45e9698e10e46ccc5d6fe6fc8cf18ae8688a0dfe Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 21 Sep 2023 15:42:11 +0300 Subject: [PATCH 12/62] remove python 3.8 from GH action --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 88376b8c..755b2e46 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: [3.8, 3.11] + python-version: [3.11] steps: - uses: actions/checkout@v2 From 362cb9b139d5b1278f1b8a167265b24c1b1bf99f Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 21 Sep 2023 16:09:24 +0300 Subject: [PATCH 13/62] install sc-meta on GH action --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 755b2e46..ede01e88 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: run: | python3 -m multiversx_sdk_cli.cli deps install testwallets python3 -m multiversx_sdk_cli.cli deps install wasm-opt - python3 -m multiversx_sdk_cli.cli deps install rust + cargo install multiversx-sc-meta ls $HOME/.cargo/bin echo $PATH cat $HOME/.bashrc From edb1c59f53bb30ad56a6339956b8fad4671ee685 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 21 Sep 2023 16:13:53 +0300 Subject: [PATCH 14/62] set rust toolchain to nightly --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ede01e88..32a3296a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,6 +45,7 @@ jobs: run: | python3 -m multiversx_sdk_cli.cli deps install testwallets python3 -m multiversx_sdk_cli.cli deps install wasm-opt + rustup default nightly-2023-05-26 cargo install multiversx-sc-meta ls $HOME/.cargo/bin echo $PATH From 0c9aaa9a744829318e5a001d0f21ddb3f7adb1dc Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 21 Sep 2023 16:50:34 +0300 Subject: [PATCH 15/62] remove default sc-meta installation when installing rust --- .github/workflows/build.yml | 8 ++------ multiversx_sdk_cli/dependencies/modules.py | 5 +---- multiversx_sdk_cli/projects/project_rust.py | 10 ++++++++++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 32a3296a..79cf4040 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,12 +44,8 @@ jobs: - name: Setup test dependencies run: | python3 -m multiversx_sdk_cli.cli deps install testwallets - python3 -m multiversx_sdk_cli.cli deps install wasm-opt - rustup default nightly-2023-05-26 - cargo install multiversx-sc-meta - ls $HOME/.cargo/bin - echo $PATH - cat $HOME/.bashrc + python3 -m multiversx_sdk_cli.cli deps install wasm-op + python3 -m multiversx_sdk_cli.cli deps install rust --overwrite - name: Run unit tests run: | export PYTHONPATH=. diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 4a67c6a0..d51a941b 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -270,11 +270,8 @@ def _do_install(self, tag: str) -> None: args = [str(installer_path), "--verbose", "--default-toolchain", toolchain, "--profile", "minimal", "--target", "wasm32-unknown-unknown", "-y"] - output = myprocess.run_process(args) - if output: - sc_meta_args = ["cargo", "install", "multiversx-sc-meta"] - myprocess.run_process(sc_meta_args) + myprocess.run_process(args) def _get_installer_url(self) -> str: if workstation.is_windows(): diff --git a/multiversx_sdk_cli/projects/project_rust.py b/multiversx_sdk_cli/projects/project_rust.py index 498dae16..58355de9 100644 --- a/multiversx_sdk_cli/projects/project_rust.py +++ b/multiversx_sdk_cli/projects/project_rust.py @@ -1,4 +1,5 @@ import logging +import shutil import subprocess from pathlib import Path from typing import Any, Dict, List, Set, cast @@ -53,7 +54,14 @@ def prepare_build_wasm_args(self, args: List[str]): self.get_output_folder() ]) + def check_if_sc_meta_is_installed(self): + which_sc_meta = shutil.which("sc-meta") + + if which_sc_meta is None: + raise errors.KnownError("'sc-meta' is not installed. Run 'cargo install multiversx-sc-meta' then try again.") + def run_meta(self): + self.check_if_sc_meta_is_installed() env = self.get_env() with_wasm_opt = not self.options.get("no-wasm-opt") @@ -123,6 +131,8 @@ def get_env(self): return dependencies.get_module_by_key("rust").get_env() def build_wasm_with_debug_symbols(self, build_options: Dict[str, Any]): + self.check_if_sc_meta_is_installed() + cwd = self.path env = self.get_env() target_dir: str = build_options.get("target-dir", "") From d7681ddcf62f949f9708363b6f38cb340f4cd834 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 21 Sep 2023 16:53:47 +0300 Subject: [PATCH 16/62] fix typo --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79cf4040..75fb7ad8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: - name: Setup test dependencies run: | python3 -m multiversx_sdk_cli.cli deps install testwallets - python3 -m multiversx_sdk_cli.cli deps install wasm-op + python3 -m multiversx_sdk_cli.cli deps install wasm-opt python3 -m multiversx_sdk_cli.cli deps install rust --overwrite - name: Run unit tests run: | From 87df9d4dbcf7fbcce2163f3476950a7e7f8d988b Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 22 Sep 2023 10:08:29 +0300 Subject: [PATCH 17/62] add new pytest marker --- .github/workflows/build.yml | 1 - pytest.ini | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 75fb7ad8..ace0a349 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,7 +49,6 @@ jobs: - name: Run unit tests run: | export PYTHONPATH=. - echo $PATH pytest . - name: Run CLI tests run: | diff --git a/pytest.ini b/pytest.ini index 1d51c3ca..6669f27f 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,6 @@ [pytest] markers = skip_on_windows: marks tests as being skiped when running on windows (deselect with '-m "skip_on_windows"') + only: only run a specific test (run using: pytest -m "only") log_cli = True From 84ce195974cafaf03e6939b1a2194b1ac16d3f49 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 22 Sep 2023 10:37:07 +0300 Subject: [PATCH 18/62] install sc-meta in GH workflow --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ace0a349..1b3d6ece 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,6 +46,7 @@ jobs: python3 -m multiversx_sdk_cli.cli deps install testwallets python3 -m multiversx_sdk_cli.cli deps install wasm-opt python3 -m multiversx_sdk_cli.cli deps install rust --overwrite + cargo install multiversx-sc-meta - name: Run unit tests run: | export PYTHONPATH=. From b3c6a0cc13f41d9dc3ef8884ab48799ec4845c9a Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 22 Sep 2023 11:27:25 +0300 Subject: [PATCH 19/62] remove unnecessary prints --- multiversx_sdk_cli/dependencies/modules.py | 2 -- pyproject.toml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index d51a941b..a59ea632 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -293,8 +293,6 @@ def uninstall(self, tag: str): def is_installed(self, tag: str) -> bool: which_rustc = shutil.which("rustc") which_cargo = shutil.which("cargo") - print(which_rustc) - print(which_cargo) logger.info(f"which rustc: {which_rustc}") logger.info(f"which cargo: {which_cargo}") diff --git a/pyproject.toml b/pyproject.toml index d61e5d8f..60739b90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "multiversx-sdk-cli" -version = "8.2.0b1" +version = "8.1.1" authors = [ { name="MultiversX" }, ] From 3cbff95d9389b305112ebed9498f9e690c610729 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 22 Sep 2023 11:50:18 +0300 Subject: [PATCH 20/62] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 60739b90..61b18480 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "multiversx-sdk-cli" -version = "8.1.1" +version = "8.2.0" authors = [ { name="MultiversX" }, ] From c597e34c7a04d709476edf4f8994b88388438e5e Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 22 Sep 2023 16:46:23 +0300 Subject: [PATCH 21/62] started refactoring --- multiversx_sdk_cli/cli_deps.py | 3 +- multiversx_sdk_cli/dependencies/modules.py | 57 +++++++++++++++++----- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/multiversx_sdk_cli/cli_deps.py b/multiversx_sdk_cli/cli_deps.py index 701c3866..8bb56da7 100644 --- a/multiversx_sdk_cli/cli_deps.py +++ b/multiversx_sdk_cli/cli_deps.py @@ -41,9 +41,8 @@ def check(args: Any): module = dependencies.get_module_by_key(name) default_tag: str = config.get_dependency_tag(module.key) tag_to_check = tag or default_tag - resolution: str = config.get_dependency_resolution(module.key) - logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}; default tag = {default_tag}, resolution = {resolution}") + logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}; default tag = {default_tag}") installed = module.is_installed(tag_to_check) if installed: diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index a59ea632..19ba3656 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -9,6 +9,7 @@ myprocess, utils, workstation) from multiversx_sdk_cli.dependencies.resolution import ( DependencyResolution, get_dependency_resolution) +from multiversx_sdk_cli.ux import show_warning logger = logging.getLogger("modules") @@ -34,7 +35,6 @@ def install(self, tag: str, overwrite: bool) -> None: logger.info("Already exists. Skip install.") return - self._guard_cannot_install_on_host() self.uninstall(tag) self._do_install(tag) @@ -66,10 +66,6 @@ def get_latest_release(self) -> str: def get_resolution(self) -> DependencyResolution: return get_dependency_resolution(self.key) - def _guard_cannot_install_on_host(self): - if self.get_resolution() == DependencyResolution.Host: - raise errors.KnownError(f"Installation of {self.key} on the host machine is not supported. Perhaps set 'dependencies.{self.key}.resolution' to 'SDK' in config?") - class StandaloneModule(DependencyModule): def __init__(self, @@ -256,6 +252,28 @@ def get_latest_release(self) -> str: class Rust(DependencyModule): + def is_installed(self, tag: str) -> bool: + which_rustc = shutil.which("rustc") + which_cargo = shutil.which("cargo") + logger.info(f"which rustc: {which_rustc}") + logger.info(f"which cargo: {which_cargo}") + + return which_rustc is not None and which_cargo is not None + + def install(self, tag: str, overwrite: bool) -> None: + # Fallback to default tag if not provided + tag = tag or config.get_dependency_tag(self.key) + + logger.info(f"install: key={self.key}, tag={tag}, overwrite={overwrite}") + + if overwrite: + logger.info("Overwriting the current rust version...") + elif self._is_installed_and_set_to_nightly(): + return + + self._do_install(tag) + self._post_install(tag) + def _do_install(self, tag: str) -> None: installer_url = self._get_installer_url() installer_path = self._get_installer_path() @@ -290,13 +308,30 @@ def uninstall(self, tag: str): if os.path.isdir(directory): shutil.rmtree(directory) - def is_installed(self, tag: str) -> bool: - which_rustc = shutil.which("rustc") - which_cargo = shutil.which("cargo") - logger.info(f"which rustc: {which_rustc}") - logger.info(f"which cargo: {which_cargo}") + def _is_installed_and_set_to_nightly(self) -> bool: + # the method parameter is not used in this specific module + is_rust_installed = self.is_installed("") - return which_rustc is not None and which_cargo is not None + if not is_rust_installed: + return is_rust_installed + else: + if self._is_the_correct_rust_version_installed(): + return True + else: + return False + + def _is_the_correct_rust_version_installed(self) -> bool: + args = ["mxpy", "deps", "check", "rust"] + already_installed_rust_version = myprocess.run_process(args) + + module = dependencies.get_module_by_key("rust") + default_tag: str = config.get_dependency_tag(module.key) + + if default_tag in already_installed_rust_version: + return True + + show_warning("The rust version you have installed does not match the version we recommand. If you'd like to overwrite your current version please run `mxpy deps install rust --overwrite`.") + return False def get_directory(self, tag: str) -> Path: tools_folder = workstation.get_tools_folder() From 485bfaf7b6e8d55f8726c1b1229e486f298fffbe Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 25 Sep 2023 12:34:30 +0300 Subject: [PATCH 22/62] Install sc-meta when installing rust --- multiversx_sdk_cli/dependencies/modules.py | 24 +++++------- multiversx_sdk_cli/tests/shared.sh | 2 +- multiversx_sdk_cli/tests/test_cli_deps.py | 45 ++++++++++++++++++++++ multiversx_sdk_cli/tests/test_cli_deps.sh | 15 -------- 4 files changed, 56 insertions(+), 30 deletions(-) create mode 100644 multiversx_sdk_cli/tests/test_cli_deps.py delete mode 100644 multiversx_sdk_cli/tests/test_cli_deps.sh diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 19ba3656..4979bd9f 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -272,6 +272,7 @@ def install(self, tag: str, overwrite: bool) -> None: return self._do_install(tag) + self._install_sc_meta() self._post_install(tag) def _do_install(self, tag: str) -> None: @@ -291,6 +292,11 @@ def _do_install(self, tag: str) -> None: myprocess.run_process(args) + def _install_sc_meta(self): + logger.info("Installing multiversx-sc-meta") + args = ["cargo", "install", "multiversx-sc-meta"] + myprocess.run_process(args) + def _get_installer_url(self) -> str: if workstation.is_windows(): return "https://win.rustup.rs" @@ -315,23 +321,13 @@ def _is_installed_and_set_to_nightly(self) -> bool: if not is_rust_installed: return is_rust_installed else: - if self._is_the_correct_rust_version_installed(): - return True - else: - return False - - def _is_the_correct_rust_version_installed(self) -> bool: - args = ["mxpy", "deps", "check", "rust"] - already_installed_rust_version = myprocess.run_process(args) + self._recommend_default_rust_version() + return True + def _recommend_default_rust_version(self): module = dependencies.get_module_by_key("rust") default_tag: str = config.get_dependency_tag(module.key) - - if default_tag in already_installed_rust_version: - return True - - show_warning("The rust version you have installed does not match the version we recommand. If you'd like to overwrite your current version please run `mxpy deps install rust --overwrite`.") - return False + show_warning(f"We recommend using rust {default_tag}. If you'd like to overwrite your current version please run `mxpy deps install rust --overwrite`.") def get_directory(self, tag: str) -> Path: tools_folder = workstation.get_tools_folder() diff --git a/multiversx_sdk_cli/tests/shared.sh b/multiversx_sdk_cli/tests/shared.sh index 57f3dda8..8ca40072 100755 --- a/multiversx_sdk_cli/tests/shared.sh +++ b/multiversx_sdk_cli/tests/shared.sh @@ -16,7 +16,7 @@ PROXY="${PROXY:-http://localhost:7950}" CHAIN_ID="${CHAIN_ID:-localnet}" TestUser=./testdata/testUser.pem TestUser2=./testdata/testUser2.pem -RUST_VERSION="nightly-2023-04-24" +RUST_VERSION="nightly-2023-05-26" cleanSandbox() { rm -rf ${SANDBOX} diff --git a/multiversx_sdk_cli/tests/test_cli_deps.py b/multiversx_sdk_cli/tests/test_cli_deps.py new file mode 100644 index 00000000..b5d5ca4c --- /dev/null +++ b/multiversx_sdk_cli/tests/test_cli_deps.py @@ -0,0 +1,45 @@ +import shutil + +from multiversx_sdk_cli.cli import main +from multiversx_sdk_cli.config import get_dependency_tag + + +def test_deps_install_rust(): + default_tag = get_dependency_tag("rust") + return_code = main(["deps", "install", "rust", "--tag", default_tag]) + if return_code: + assert False + else: + assert True + + +def test_deps_install_vmtools(): + return_code = main(["deps", "install", "vmtools"]) + if return_code: + assert False + else: + assert True + + +def test_deps_check_rust(): + return_code = main(["deps", "check", "rust"]) + if return_code: + assert False + else: + assert True + + +def test_check_sc_meta(): + which_sc_meta = shutil.which("sc-meta") + if which_sc_meta: + assert True + elif which_sc_meta is None: + assert False + + +def test_deps_check_vmtools(): + return_code = main(["deps", "check", "vmtools"]) + if return_code: + assert False + else: + assert True diff --git a/multiversx_sdk_cli/tests/test_cli_deps.sh b/multiversx_sdk_cli/tests/test_cli_deps.sh deleted file mode 100644 index e191201b..00000000 --- a/multiversx_sdk_cli/tests/test_cli_deps.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -source "./shared.sh" - -testAll() { - set -x - - ${CLI} --verbose deps install rust --tag=${RUST_VERSION} - ${CLI} --verbose deps install vmtools --overwrite - - ${CLI} --verbose deps check rust - ${CLI} --verbose deps check vmtools - - set +x -} From d5999e95e38e5a11ab8b899eb2c56fa5d3fe8516 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 25 Sep 2023 15:11:01 +0300 Subject: [PATCH 23/62] skip some tests on windows --- .github/workflows/build-windows.yml | 76 +++++++++++------------ .github/workflows/build.yml | 1 - multiversx_sdk_cli/cli_deps.py | 3 +- multiversx_sdk_cli/tests/test_cli_deps.py | 6 +- 4 files changed, 45 insertions(+), 41 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 38108868..cf67736b 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -5,13 +5,13 @@ name: build on: pull_request: - branches: [ main, feat/* ] + branches: [main, feat/*] workflow_dispatch: jobs: build: name: Build and Test mxpy for ${{ matrix.os }}, python ${{ matrix.python-version }} - + runs-on: ${{ matrix.os }} strategy: @@ -20,39 +20,39 @@ jobs: python-version: [3.8] steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - shell: bash - run: | - python3 -m pip install --upgrade pip - pip3 install -r requirements.txt - pip3 install pytest - - name: Set github_api_token - shell: bash - run: | - mkdir ~/multiversx-sdk - export PYTHONPATH=. - python3 -m multiversx_sdk_cli.cli config new test - python3 -m multiversx_sdk_cli.cli config set github_api_token ${{ secrets.GITHUB_TOKEN }} - - name: Setup test dependencies - shell: bash - run: | - python3 -m multiversx_sdk_cli.cli deps install testwallets - - name: Run unit tests - shell: bash - run: | - export PYTHONPATH=. - pytest -m "not skip_on_windows" . - - name: Run CLI tests - shell: bash - run: | - export PROXY=https://testnet-gateway.multiversx.com - export CHAIN_ID=T - cd ./multiversx_sdk_cli/tests - source ./test_cli_tx.sh && testAll || return 1 - source ./test_cli_dns.sh && testOffline || return 1 - source ./test_cli_validators.sh && testAll || return 1 + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + shell: bash + run: | + python3 -m pip install --upgrade pip + pip3 install -r requirements.txt + pip3 install pytest + - name: Set github_api_token + shell: bash + run: | + mkdir ~/multiversx-sdk + export PYTHONPATH=. + python3 -m multiversx_sdk_cli.cli config new test + python3 -m multiversx_sdk_cli.cli config set github_api_token ${{ secrets.GITHUB_TOKEN }} + - name: Setup test dependencies + shell: bash + run: | + python3 -m multiversx_sdk_cli.cli deps install testwallets + - name: Run unit tests + shell: bash + run: | + export PYTHONPATH=. + pytest -m "not skip_on_windows" . + - name: Run CLI tests + shell: bash + run: | + export PROXY=https://testnet-gateway.multiversx.com + export CHAIN_ID=T + cd ./multiversx_sdk_cli/tests + source ./test_cli_tx.sh && testAll || return 1 + source ./test_cli_dns.sh && testOffline || return 1 + source ./test_cli_validators.sh && testAll || return 1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1b3d6ece..ace0a349 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,6 @@ jobs: python3 -m multiversx_sdk_cli.cli deps install testwallets python3 -m multiversx_sdk_cli.cli deps install wasm-opt python3 -m multiversx_sdk_cli.cli deps install rust --overwrite - cargo install multiversx-sc-meta - name: Run unit tests run: | export PYTHONPATH=. diff --git a/multiversx_sdk_cli/cli_deps.py b/multiversx_sdk_cli/cli_deps.py index 8bb56da7..701c3866 100644 --- a/multiversx_sdk_cli/cli_deps.py +++ b/multiversx_sdk_cli/cli_deps.py @@ -41,8 +41,9 @@ def check(args: Any): module = dependencies.get_module_by_key(name) default_tag: str = config.get_dependency_tag(module.key) tag_to_check = tag or default_tag + resolution: str = config.get_dependency_resolution(module.key) - logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}; default tag = {default_tag}") + logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}; default tag = {default_tag}, resolution = {resolution}") installed = module.is_installed(tag_to_check) if installed: diff --git a/multiversx_sdk_cli/tests/test_cli_deps.py b/multiversx_sdk_cli/tests/test_cli_deps.py index b5d5ca4c..e726032c 100644 --- a/multiversx_sdk_cli/tests/test_cli_deps.py +++ b/multiversx_sdk_cli/tests/test_cli_deps.py @@ -1,18 +1,21 @@ import shutil +import pytest + from multiversx_sdk_cli.cli import main from multiversx_sdk_cli.config import get_dependency_tag def test_deps_install_rust(): default_tag = get_dependency_tag("rust") - return_code = main(["deps", "install", "rust", "--tag", default_tag]) + return_code = main(["deps", "install", "rust", "--tag", default_tag, "--overwrite"]) if return_code: assert False else: assert True +@pytest.mark.skip_on_windows def test_deps_install_vmtools(): return_code = main(["deps", "install", "vmtools"]) if return_code: @@ -29,6 +32,7 @@ def test_deps_check_rust(): assert True +@pytest.mark.skip_on_windows def test_check_sc_meta(): which_sc_meta = shutil.which("sc-meta") if which_sc_meta: From 837b794884e75db8f5ca7c65c8131a27301303ab Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 25 Sep 2023 15:20:21 +0300 Subject: [PATCH 24/62] skip test on windows --- multiversx_sdk_cli/tests/test_cli_deps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/multiversx_sdk_cli/tests/test_cli_deps.py b/multiversx_sdk_cli/tests/test_cli_deps.py index e726032c..ebaaaa80 100644 --- a/multiversx_sdk_cli/tests/test_cli_deps.py +++ b/multiversx_sdk_cli/tests/test_cli_deps.py @@ -41,6 +41,7 @@ def test_check_sc_meta(): assert False +@pytest.mark.skip_on_windows def test_deps_check_vmtools(): return_code = main(["deps", "check", "vmtools"]) if return_code: From 39f1b77e8784fbfb09a626b5c2f0222604ec1a2f Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 26 Sep 2023 17:22:18 +0300 Subject: [PATCH 25/62] install wasm-opt and twiggy using cargo --- multiversx_sdk_cli/config.py | 7 +- multiversx_sdk_cli/dependencies/install.py | 9 +- multiversx_sdk_cli/dependencies/modules.py | 99 ++++++--------------- multiversx_sdk_cli/projects/project_rust.py | 16 ---- multiversx_sdk_cli/tests/test_cli_deps.py | 9 ++ 5 files changed, 42 insertions(+), 98 deletions(-) diff --git a/multiversx_sdk_cli/config.py b/multiversx_sdk_cli/config.py index 3830121d..71a90f56 100644 --- a/multiversx_sdk_cli/config.py +++ b/multiversx_sdk_cli/config.py @@ -160,17 +160,12 @@ def get_defaults() -> Dict[str, Any]: "dependencies.golang.urlTemplate.linux": "https://golang.org/dl/{TAG}.linux-amd64.tar.gz", "dependencies.golang.urlTemplate.osx": "https://golang.org/dl/{TAG}.darwin-amd64.tar.gz", "dependencies.golang.urlTemplate.windows": "https://golang.org/dl/{TAG}.windows-amd64.zip", - "dependencies.wasm-opt.tag": "latest", "dependencies.twiggy.tag": "latest", "dependencies.testwallets.tag": "latest", "dependencies.testwallets.urlTemplate.linux": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz", "dependencies.testwallets.urlTemplate.osx": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz", "dependencies.testwallets.urlTemplate.windows": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz", - "dependencies.wasm-opt.resolution": "SDK", - "dependencies.wasm-opt.tag": "version_112", - "dependencies.wasm-opt.urlTemplate.linux": "https://github.com/WebAssembly/binaryen/releases/download/{TAG}/binaryen-{TAG}-x86_64-linux.tar.gz", - "dependencies.wasm-opt.urlTemplate.osx": "https://github.com/WebAssembly/binaryen/releases/download/{TAG}/binaryen-{TAG}-x86_64-macos.tar.gz", - "dependencies.wasm-opt.urlTemplate.windows": "https://github.com/WebAssembly/binaryen/releases/download/{TAG}/binaryen-{TAG}-x86_64-windows.tar.gz", + "dependencies.wasm-opt.tag": "0.112.0", "github_api_token": "", } diff --git a/multiversx_sdk_cli/dependencies/install.py b/multiversx_sdk_cli/dependencies/install.py index 9d340de1..ca5951c9 100644 --- a/multiversx_sdk_cli/dependencies/install.py +++ b/multiversx_sdk_cli/dependencies/install.py @@ -3,8 +3,11 @@ from typing import Dict, List from multiversx_sdk_cli import config, errors -from multiversx_sdk_cli.dependencies.modules import (CargoModule, TestWalletsModule, VMToolsModule, - DependencyModule, GolangModule, Rust, StandaloneModule, WasmOptModule) +from multiversx_sdk_cli.dependencies.modules import (DependencyModule, + GolangModule, Rust, + StandaloneModule, + TestWalletsModule, + VMToolsModule) logger = logging.getLogger("install") @@ -64,8 +67,6 @@ def _get_implicitly_installable_deps() -> List[DependencyModule]: VMToolsModule(key="vmtools"), StandaloneModule(key="mx_chain_go", repo_name="mx-chain-go", organisation="multiversx"), StandaloneModule(key="mx_chain_proxy_go", repo_name="mx-chain-proxy-go", organisation="multiversx"), - WasmOptModule(key="wasm-opt"), - CargoModule(key="twiggy"), TestWalletsModule(key="testwallets") ] diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 4979bd9f..6c95d5e2 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -255,10 +255,17 @@ class Rust(DependencyModule): def is_installed(self, tag: str) -> bool: which_rustc = shutil.which("rustc") which_cargo = shutil.which("cargo") + which_sc_meta = shutil.which("sc-meta") + which_wasm_opt = shutil.which("wasm-opt") + which_twiggy = shutil.which("twiggy") logger.info(f"which rustc: {which_rustc}") logger.info(f"which cargo: {which_cargo}") + logger.info(f"which sc-meta: {which_sc_meta}") + logger.info(f"which wasm-opt: {which_wasm_opt}") + logger.info(f"which twiggy: {which_twiggy}") - return which_rustc is not None and which_cargo is not None + dependencies = [which_rustc, which_cargo, which_sc_meta, which_wasm_opt, which_twiggy] + return all(dependency is not None for dependency in dependencies) def install(self, tag: str, overwrite: bool) -> None: # Fallback to default tag if not provided @@ -273,7 +280,8 @@ def install(self, tag: str, overwrite: bool) -> None: self._do_install(tag) self._install_sc_meta() - self._post_install(tag) + self._install_wasm_opt() + self._install_twiggy() def _do_install(self, tag: str) -> None: installer_url = self._get_installer_url() @@ -293,10 +301,26 @@ def _do_install(self, tag: str) -> None: myprocess.run_process(args) def _install_sc_meta(self): - logger.info("Installing multiversx-sc-meta") + logger.info("Installing multiversx-sc-meta.") args = ["cargo", "install", "multiversx-sc-meta"] myprocess.run_process(args) + def _install_wasm_opt(self): + logger.info("Installing wasm-opt. This may take a while.") + tag = config.get_dependency_tag("wasm-opt") + args = ["cargo", "install", "wasm-opt", "--version", tag] + myprocess.run_process(args) + + def _install_twiggy(self): + logger.info("Installing twiggy.") + default_tag = config.get_dependency_tag("twiggy") + args = ["cargo", "install", "twiggy"] + + if default_tag != "latest": + args.extend(["--version", default_tag]) + + myprocess.run_process(args) + def _get_installer_url(self) -> str: if workstation.is_windows(): return "https://win.rustup.rs" @@ -340,30 +364,6 @@ def get_latest_release(self) -> str: raise errors.UnsupportedConfigurationValue("Rust tag must either be explicit, empty or 'nightly'") -class CargoModule(DependencyModule): - def _do_install(self, tag: str) -> None: - self._run_command_with_rust_env(["cargo", "install", self.key]) - - def is_installed(self, tag: str) -> bool: - rust = dependencies.get_module_by_key("rust") - output = myprocess.run_process(["cargo", "install", "--list"], rust.get_env()) - for line in output.splitlines(): - if self.key == line.strip(): - return True - return False - - def uninstall(self, tag: str): - if self.is_installed(tag): - self._run_command_with_rust_env(["cargo", "uninstall", self.key]) - - def get_latest_release(self) -> str: - return "latest" - - def _run_command_with_rust_env(self, args: List[str]) -> str: - rust = dependencies.get_module_by_key("rust") - return myprocess.run_process(args, rust.get_env()) - - class TestWalletsModule(StandaloneModule): def __init__(self, key: str): super().__init__(key, []) @@ -375,48 +375,3 @@ def _post_install(self, tag: str): target = self.get_source_directory(tag) link = path.join(self.get_parent_directory(), "latest") utils.symlink(str(target), link) - - -class WasmOptModule(StandaloneModule): - def __init__(self, key: str): - super().__init__(key, []) - self.organisation = "WebAssembly" - self.repo_name = "binaryen" - - def _post_install(self, tag: str): - # Bit of cleanup, we don't need the rest of the binaries. - bin_to_remove = list(self._get_bin_directory(tag).glob("*")) - bin_to_remove = [file for file in bin_to_remove if file.name != "wasm-opt"] - lib_to_remove = list((self.get_source_directory(tag) / "lib").glob("*")) - lib_to_remove = [file for file in lib_to_remove if file.suffix != ".dylib"] - - for file in bin_to_remove + lib_to_remove: - file.unlink() - - def _get_bin_directory(self, tag: str) -> Path: - return self.get_source_directory(tag) / "bin" - - def is_installed(self, tag: str) -> bool: - resolution = self.get_resolution() - tag = tag or config.get_dependency_tag(self.key) - bin_file = self._get_bin_directory(tag) / "wasm-opt" - - if resolution == DependencyResolution.Host: - which_wasm_opt = shutil.which("wasm-opt") - logger.info(f"which wasm-opt: {which_wasm_opt}") - - return shutil.which("wasm-opt") is not None - if resolution == DependencyResolution.SDK: - return bin_file.exists() - raise errors.BadDependencyResolution(self.key, resolution) - - def get_env(self): - tag = config.get_dependency_tag(self.key) - bin_directory = self._get_bin_directory(tag) - - return { - "PATH": f"{bin_directory}:{os.environ['PATH']}", - } - - def get_latest_release(self) -> str: - raise errors.UnsupportedConfigurationValue("wasm-opt tag must either be explicit") diff --git a/multiversx_sdk_cli/projects/project_rust.py b/multiversx_sdk_cli/projects/project_rust.py index 58355de9..2bd7fdc3 100644 --- a/multiversx_sdk_cli/projects/project_rust.py +++ b/multiversx_sdk_cli/projects/project_rust.py @@ -66,7 +66,6 @@ def run_meta(self): with_wasm_opt = not self.options.get("no-wasm-opt") if with_wasm_opt: - check_wasm_opt_installed() wasm_opt = dependencies.get_module_by_key("wasm-opt") env = merge_env(env, wasm_opt.get_env()) @@ -263,18 +262,3 @@ def merge_env(first: Dict[str, str], second: Dict[str, str]) -> Dict[str, str]: values = paths_of(first, key).union(paths_of(second, key)) merged[key] = ":".join(sorted(values)) return merged - - -def check_wasm_opt_installed() -> None: - wasm_opt = dependencies.get_module_by_key("wasm-opt") - if not wasm_opt.is_installed(""): - logger.warn(""" - Skipping optimization because wasm-opt is not installed. - - To install it run: - mxpy deps install wasm-opt - - Alternatively, pass the "--no-wasm-opt" argument in order to skip the optimization step. - """) - else: - logger.info("wasm-opt is installed.") diff --git a/multiversx_sdk_cli/tests/test_cli_deps.py b/multiversx_sdk_cli/tests/test_cli_deps.py index ebaaaa80..a962f693 100644 --- a/multiversx_sdk_cli/tests/test_cli_deps.py +++ b/multiversx_sdk_cli/tests/test_cli_deps.py @@ -41,6 +41,15 @@ def test_check_sc_meta(): assert False +@pytest.mark.skip_on_windows +def test_check_wasm_opt(): + which_wasm_opt = shutil.which("wasm-opt") + if which_wasm_opt: + assert True + elif which_wasm_opt is None: + assert False + + @pytest.mark.skip_on_windows def test_deps_check_vmtools(): return_code = main(["deps", "check", "vmtools"]) From 177d2637736b5e73408822eb5d8cffb13f8efdac Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 27 Sep 2023 10:20:59 +0300 Subject: [PATCH 26/62] fix resolution --- multiversx_sdk_cli/cli_deps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/multiversx_sdk_cli/cli_deps.py b/multiversx_sdk_cli/cli_deps.py index 701c3866..1f0d9188 100644 --- a/multiversx_sdk_cli/cli_deps.py +++ b/multiversx_sdk_cli/cli_deps.py @@ -42,6 +42,7 @@ def check(args: Any): default_tag: str = config.get_dependency_tag(module.key) tag_to_check = tag or default_tag resolution: str = config.get_dependency_resolution(module.key) + resolution = resolution if resolution else "HOST" logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}; default tag = {default_tag}, resolution = {resolution}") From 340e5e1a0716d910d0c40f7750cb1cc294819c5a Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 27 Sep 2023 18:44:38 +0300 Subject: [PATCH 27/62] remove clang installation --- multiversx_sdk_cli/cli_deps.py | 4 +-- multiversx_sdk_cli/config.py | 4 --- multiversx_sdk_cli/dependencies/install.py | 23 +++----------- multiversx_sdk_cli/dependencies/modules.py | 24 ++++++--------- multiversx_sdk_cli/projects/project_base.py | 2 ++ multiversx_sdk_cli/projects/project_clang.py | 9 +++++- multiversx_sdk_cli/projects/project_cpp.py | 13 ++++++-- multiversx_sdk_cli/projects/project_rust.py | 2 +- multiversx_sdk_cli/projects/shared.py | 32 ++++++++++++++++++++ 9 files changed, 67 insertions(+), 46 deletions(-) diff --git a/multiversx_sdk_cli/cli_deps.py b/multiversx_sdk_cli/cli_deps.py index 1f0d9188..471e0610 100644 --- a/multiversx_sdk_cli/cli_deps.py +++ b/multiversx_sdk_cli/cli_deps.py @@ -16,7 +16,6 @@ def setup_parser(subparsers: Any) -> Any: sub = cli_shared.add_command_subparser(subparsers, "deps", "install", "Install dependencies or multiversx-sdk modules.") sub.add_argument("name", choices=choices, help="the dependency to install") sub.add_argument("--overwrite", action="store_true", default=False, help="whether to overwrite an existing installation") - sub.add_argument("--tag", help="the tag or version to install") sub.set_defaults(func=install) sub = cli_shared.add_command_subparser(subparsers, "deps", "check", "Check whether a dependency is installed.") @@ -30,9 +29,8 @@ def setup_parser(subparsers: Any) -> Any: def install(args: Any): name: str = args.name - tag: str = args.tag overwrite: bool = args.overwrite - dependencies.install_module(name, tag, overwrite) + dependencies.install_module(name, overwrite) def check(args: Any): diff --git a/multiversx_sdk_cli/config.py b/multiversx_sdk_cli/config.py index 71a90f56..31972ffb 100644 --- a/multiversx_sdk_cli/config.py +++ b/multiversx_sdk_cli/config.py @@ -150,10 +150,6 @@ def get_defaults() -> Dict[str, Any]: "dependencies.vmtools.urlTemplate.linux": "https://github.com/multiversx/mx-chain-vm-go/archive/{TAG}.tar.gz", "dependencies.vmtools.urlTemplate.osx": "https://github.com/multiversx/mx-chain-vm-go/archive/{TAG}.tar.gz", "dependencies.vmtools.urlTemplate.windows": "https://github.com/multiversx/mx-chain-vm-go/archive/{TAG}.tar.gz", - "dependencies.llvm.tag": "v9-19feb", - # ide.elrond.com will be removed, TBD if clang will still be downloaded - "dependencies.llvm.urlTemplate.linux": "https://ide.elrond.com/vendor-llvm/{TAG}/linux-amd64.tar.gz?t=19feb", - "dependencies.llvm.urlTemplate.osx": "https://ide.elrond.com/vendor-llvm/{TAG}/darwin-amd64.tar.gz?t=19feb", "dependencies.rust.tag": "nightly-2023-05-26", "dependencies.golang.resolution": "SDK", "dependencies.golang.tag": "go1.20.7", diff --git a/multiversx_sdk_cli/dependencies/install.py b/multiversx_sdk_cli/dependencies/install.py index ca5951c9..64945e4f 100644 --- a/multiversx_sdk_cli/dependencies/install.py +++ b/multiversx_sdk_cli/dependencies/install.py @@ -5,21 +5,20 @@ from multiversx_sdk_cli import config, errors from multiversx_sdk_cli.dependencies.modules import (DependencyModule, GolangModule, Rust, - StandaloneModule, TestWalletsModule, VMToolsModule) logger = logging.getLogger("install") -def install_module(key: str, tag: str = "", overwrite: bool = False): +def install_module(key: str, overwrite: bool = False): if key == 'all': - modules = _get_implicitly_installable_deps() + modules = _get_all_deps() else: modules = [get_module_by_key(key)] for module in modules: - module.install(tag, overwrite) + module.install(overwrite) def get_module_directory(key: str) -> Path: @@ -49,24 +48,10 @@ def get_deps_dict() -> Dict[str, DependencyModule]: def _get_all_deps() -> List[DependencyModule]: - return _get_explicitly_installable_deps() + _get_implicitly_installable_deps() - - -def _get_explicitly_installable_deps() -> List[DependencyModule]: return [ - StandaloneModule(key="llvm", aliases=["clang", "cpp"]), Rust(key="rust"), - GolangModule(key="golang") - ] - - -def _get_implicitly_installable_deps() -> List[DependencyModule]: - # See: https://github.com/multiversx/mx-sdk-py-cli/pull/55 - - return [ + GolangModule(key="golang"), VMToolsModule(key="vmtools"), - StandaloneModule(key="mx_chain_go", repo_name="mx-chain-go", organisation="multiversx"), - StandaloneModule(key="mx_chain_proxy_go", repo_name="mx-chain-proxy-go", organisation="multiversx"), TestWalletsModule(key="testwallets") ] diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 6c95d5e2..d672d8bc 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -22,9 +22,9 @@ def __init__(self, key: str, aliases: List[str] = []): def get_directory(self, tag: str) -> Path: raise NotImplementedError() - def install(self, tag: str, overwrite: bool) -> None: - # Fallback to default tag if not provided - tag = tag or config.get_dependency_tag(self.key) + def install(self, overwrite: bool) -> None: + # We install the default tag + tag = config.get_dependency_tag(self.key) if tag == 'latest': tag = self.get_latest_release() @@ -267,10 +267,11 @@ def is_installed(self, tag: str) -> bool: dependencies = [which_rustc, which_cargo, which_sc_meta, which_wasm_opt, which_twiggy] return all(dependency is not None for dependency in dependencies) - def install(self, tag: str, overwrite: bool) -> None: - # Fallback to default tag if not provided - tag = tag or config.get_dependency_tag(self.key) + def install(self, overwrite: bool) -> None: + module = dependencies.get_module_by_key("rust") + tag: str = config.get_dependency_tag(module.key) + show_warning(f"We recommend using rust {tag}. If you'd like to overwrite your current version please run `mxpy deps install rust --overwrite`.") logger.info(f"install: key={self.key}, tag={tag}, overwrite={overwrite}") if overwrite: @@ -343,15 +344,8 @@ def _is_installed_and_set_to_nightly(self) -> bool: is_rust_installed = self.is_installed("") if not is_rust_installed: - return is_rust_installed - else: - self._recommend_default_rust_version() - return True - - def _recommend_default_rust_version(self): - module = dependencies.get_module_by_key("rust") - default_tag: str = config.get_dependency_tag(module.key) - show_warning(f"We recommend using rust {default_tag}. If you'd like to overwrite your current version please run `mxpy deps install rust --overwrite`.") + return False + return True def get_directory(self, tag: str) -> Path: tools_folder = workstation.get_tools_folder() diff --git a/multiversx_sdk_cli/projects/project_base.py b/multiversx_sdk_cli/projects/project_base.py index aadd5ebc..74777af1 100644 --- a/multiversx_sdk_cli/projects/project_base.py +++ b/multiversx_sdk_cli/projects/project_base.py @@ -38,6 +38,8 @@ def clean(self): def _ensure_dependencies_installed(self): module_keys = self.get_dependencies() for module_key in module_keys: + if module_key == "": + continue dependencies.install_module(module_key) def get_dependencies(self) -> List[str]: diff --git a/multiversx_sdk_cli/projects/project_clang.py b/multiversx_sdk_cli/projects/project_clang.py index 3985955c..467cafc0 100644 --- a/multiversx_sdk_cli/projects/project_clang.py +++ b/multiversx_sdk_cli/projects/project_clang.py @@ -1,11 +1,14 @@ import logging import subprocess +import sys from os import path from pathlib import Path from typing import List from multiversx_sdk_cli import dependencies, errors, myprocess, utils from multiversx_sdk_cli.projects.project_base import Project, rename_wasm_files +from multiversx_sdk_cli.projects.shared import \ + are_clang_and_cpp_dependencies_installed logger = logging.getLogger('ProjectClang') @@ -26,6 +29,10 @@ def perform_build(self): self.file_output = self.unit.with_suffix('.wasm') try: + is_installed = are_clang_and_cpp_dependencies_installed() + if not is_installed: + sys.exit(1) + self.do_clang() self.do_llvm_link() self.do_llc() @@ -151,4 +158,4 @@ def get_source_files_from_folder(self): return list(map(str, self.path.rglob('*.c'))) def get_dependencies(self): - return ['llvm'] + return [""] diff --git a/multiversx_sdk_cli/projects/project_cpp.py b/multiversx_sdk_cli/projects/project_cpp.py index 12b62dc5..72567927 100644 --- a/multiversx_sdk_cli/projects/project_cpp.py +++ b/multiversx_sdk_cli/projects/project_cpp.py @@ -1,12 +1,15 @@ import logging import os -from pathlib import Path import subprocess +import sys from os import path +from pathlib import Path from typing import List from multiversx_sdk_cli import dependencies, errors, myprocess, utils from multiversx_sdk_cli.projects.project_base import Project, rename_wasm_files +from multiversx_sdk_cli.projects.shared import \ + are_clang_and_cpp_dependencies_installed logger = logging.getLogger("ProjectCpp") @@ -23,6 +26,10 @@ def perform_build(self): self.file_export = self.unit.with_suffix(".export") try: + is_installed = are_clang_and_cpp_dependencies_installed() + if not is_installed: + sys.exit(1) + self._do_clang() self._do_llc() self._do_wasm() @@ -87,7 +94,7 @@ def _do_after_build_custom(self) -> List[Path]: os.remove(source_file.with_suffix(".wasm")) os.remove(source_file.with_suffix(".ll")) os.remove(source_file.with_suffix(".o")) - + paths = rename_wasm_files([output_wasm_file], self.options.get("wasm-name")) return paths @@ -95,7 +102,7 @@ def _get_llvm_path(self): return dependencies.get_module_directory("llvm") def get_dependencies(self): - return ["llvm"] + return [""] class CppBuildConfiguration: diff --git a/multiversx_sdk_cli/projects/project_rust.py b/multiversx_sdk_cli/projects/project_rust.py index 2bd7fdc3..879ccb8e 100644 --- a/multiversx_sdk_cli/projects/project_rust.py +++ b/multiversx_sdk_cli/projects/project_rust.py @@ -58,7 +58,7 @@ def check_if_sc_meta_is_installed(self): which_sc_meta = shutil.which("sc-meta") if which_sc_meta is None: - raise errors.KnownError("'sc-meta' is not installed. Run 'cargo install multiversx-sc-meta' then try again.") + raise errors.KnownError("'sc-meta' is not installed. Install it manually or simply run `mxpy deps install rust --overwrite` then try again.") def run_meta(self): self.check_if_sc_meta_is_installed() diff --git a/multiversx_sdk_cli/projects/shared.py b/multiversx_sdk_cli/projects/shared.py index ef7f375d..51ebbd32 100644 --- a/multiversx_sdk_cli/projects/shared.py +++ b/multiversx_sdk_cli/projects/shared.py @@ -1,5 +1,11 @@ +import logging +import shutil from pathlib import Path +from multiversx_sdk_cli.ux import show_critical_error + +logger = logging.getLogger("projects.shared") + def is_source_clang(directory: Path) -> bool: return _directory_contains_file(directory, ".c") @@ -22,3 +28,29 @@ def _directory_contains_file(directory: Path, name_suffix: str) -> bool: if str(file).lower().endswith(name_suffix.lower()): return True return False + + +def are_clang_and_cpp_dependencies_installed() -> bool: + which_clang = shutil.which("clang") + which_llc = shutil.which("llc") + which_wasm_ld = shutil.which("wasm-ld") + which_llvm_link = shutil.which("llvm-link") + + logger.info(f"which_clang: {which_clang}") + logger.info(f"which_llc: {which_llc}") + logger.info(f"which_wasm_ld: {which_wasm_ld}") + logger.info(f"which_llvm_link: {which_llvm_link}") + + dependencies = [which_clang, which_llc, which_wasm_ld, which_llvm_link] + is_installed = all(dependency is not None for dependency in dependencies) + if is_installed: + return True + + message = """ +`clang` is not installed. Please install it manually, then try again. +How to install on Ubuntu: https://linux.how2shout.com/how-to-install-clang-on-ubuntu-linux/ +How to install on MacOS: https://www.incredibuild.com/integrations/clang +For more details check out this page: https://clang.llvm.org/get_started.html""" + + show_critical_error(message) + return False From fc8609ac2afb3dd8db3b846f0ea0d80a83640fe6 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 27 Sep 2023 19:03:15 +0300 Subject: [PATCH 28/62] fix localnet and unit tests --- .../localnet/step_prerequisites.py | 2 +- multiversx_sdk_cli/tests/test_cli_deps.py | 54 ++++++++----------- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/multiversx_sdk_cli/localnet/step_prerequisites.py b/multiversx_sdk_cli/localnet/step_prerequisites.py index c372e3ee..bff27822 100644 --- a/multiversx_sdk_cli/localnet/step_prerequisites.py +++ b/multiversx_sdk_cli/localnet/step_prerequisites.py @@ -16,7 +16,7 @@ def fetch_prerequisites(configfile: Path): config = ConfigRoot.from_file(configfile) - dependencies.install_module("testwallets", tag="", overwrite=True) + dependencies.install_module("testwallets", overwrite=True) if config.software.mx_chain_go.resolution == SoftwareResolution.Remote: download_software_component(config.software.mx_chain_go) diff --git a/multiversx_sdk_cli/tests/test_cli_deps.py b/multiversx_sdk_cli/tests/test_cli_deps.py index a962f693..1d9cc278 100644 --- a/multiversx_sdk_cli/tests/test_cli_deps.py +++ b/multiversx_sdk_cli/tests/test_cli_deps.py @@ -1,53 +1,45 @@ import shutil +from pathlib import Path import pytest from multiversx_sdk_cli.cli import main -from multiversx_sdk_cli.config import get_dependency_tag def test_deps_install_rust(): - default_tag = get_dependency_tag("rust") - return_code = main(["deps", "install", "rust", "--tag", default_tag, "--overwrite"]) - if return_code: - assert False - else: - assert True - - -@pytest.mark.skip_on_windows -def test_deps_install_vmtools(): - return_code = main(["deps", "install", "vmtools"]) - if return_code: - assert False - else: - assert True + return_code = main(["deps", "install", "rust", "--overwrite"]) + assert True if return_code == 0 else False def test_deps_check_rust(): return_code = main(["deps", "check", "rust"]) - if return_code: - assert False - else: - assert True + assert True if return_code == 0 else False + which_rustc = shutil.which("rustc") + if which_rustc: + assert Path.is_file(Path(which_rustc)) + + which_cargo = shutil.which("cargo") + if which_cargo: + assert Path.is_file(Path(which_cargo)) -@pytest.mark.skip_on_windows -def test_check_sc_meta(): which_sc_meta = shutil.which("sc-meta") if which_sc_meta: - assert True - elif which_sc_meta is None: - assert False - + assert Path.is_file(Path(which_sc_meta)) -@pytest.mark.skip_on_windows -def test_check_wasm_opt(): which_wasm_opt = shutil.which("wasm-opt") if which_wasm_opt: - assert True - elif which_wasm_opt is None: - assert False + assert Path.is_file(Path(which_wasm_opt)) + + which_twiggy = shutil.which("twiggy") + if which_twiggy: + assert Path.is_file(Path(which_twiggy)) + + +@pytest.mark.skip_on_windows +def test_deps_install_vmtools(): + return_code = main(["deps", "install", "vmtools"]) + assert True if return_code == 0 else False @pytest.mark.skip_on_windows From 8eea743ae852ac4ffec251f911d8b2f3a44dec85 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 27 Sep 2023 19:06:59 +0300 Subject: [PATCH 29/62] fix workflow --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ace0a349..90bca16b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,6 @@ jobs: - name: Setup test dependencies run: | python3 -m multiversx_sdk_cli.cli deps install testwallets - python3 -m multiversx_sdk_cli.cli deps install wasm-opt python3 -m multiversx_sdk_cli.cli deps install rust --overwrite - name: Run unit tests run: | From ad585eafde6a4fb5c753549d96a217172e9a97cb Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 28 Sep 2023 11:32:56 +0300 Subject: [PATCH 30/62] run GH actions using newer python version & wasm-opt fixes --- .github/workflows/build-windows.yml | 2 +- .github/workflows/build.yml | 1 - .github/workflows/install-macos.yml | 4 ++-- .github/workflows/install-ubuntu.yml | 4 ++-- .github/workflows/install-windows.yml | 4 ++-- multiversx_sdk_cli/dependencies/modules.py | 1 + multiversx_sdk_cli/projects/project_rust.py | 5 ----- multiversx_sdk_cli/tests/test_cli_contracts.py | 2 +- 8 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index cf67736b..97a5225d 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [windows-2019] - python-version: [3.8] + python-version: [3.11] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 90bca16b..d4825988 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,6 @@ jobs: - name: Setup test dependencies run: | python3 -m multiversx_sdk_cli.cli deps install testwallets - python3 -m multiversx_sdk_cli.cli deps install rust --overwrite - name: Run unit tests run: | export PYTHONPATH=. diff --git a/.github/workflows/install-macos.yml b/.github/workflows/install-macos.yml index 39966e83..b815c17c 100644 --- a/.github/workflows/install-macos.yml +++ b/.github/workflows/install-macos.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: env: - BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} jobs: install: @@ -14,7 +14,7 @@ jobs: strategy: matrix: - python-version: [3.8] + python-version: [3.11] steps: - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/install-ubuntu.yml b/.github/workflows/install-ubuntu.yml index 1615a19d..734e3593 100644 --- a/.github/workflows/install-ubuntu.yml +++ b/.github/workflows/install-ubuntu.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: env: - BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} jobs: install: @@ -14,7 +14,7 @@ jobs: strategy: matrix: - python-version: [3.8] + python-version: [3.11] steps: - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/install-windows.yml b/.github/workflows/install-windows.yml index eef56de0..0e7d6dca 100644 --- a/.github/workflows/install-windows.yml +++ b/.github/workflows/install-windows.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: env: - BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} jobs: install: @@ -14,7 +14,7 @@ jobs: strategy: matrix: - python-version: [3.8] + python-version: [3.11] steps: - name: Set up Python ${{ matrix.python-version }} diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index d672d8bc..0b313210 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -299,6 +299,7 @@ def _do_install(self, tag: str) -> None: args = [str(installer_path), "--verbose", "--default-toolchain", toolchain, "--profile", "minimal", "--target", "wasm32-unknown-unknown", "-y"] + logger.info("Installing rust.") myprocess.run_process(args) def _install_sc_meta(self): diff --git a/multiversx_sdk_cli/projects/project_rust.py b/multiversx_sdk_cli/projects/project_rust.py index 879ccb8e..092b6456 100644 --- a/multiversx_sdk_cli/projects/project_rust.py +++ b/multiversx_sdk_cli/projects/project_rust.py @@ -64,11 +64,6 @@ def run_meta(self): self.check_if_sc_meta_is_installed() env = self.get_env() - with_wasm_opt = not self.options.get("no-wasm-opt") - if with_wasm_opt: - wasm_opt = dependencies.get_module_by_key("wasm-opt") - env = merge_env(env, wasm_opt.get_env()) - args = [ "sc-meta", "all", diff --git a/multiversx_sdk_cli/tests/test_cli_contracts.py b/multiversx_sdk_cli/tests/test_cli_contracts.py index 4cf406b7..46f5cddd 100644 --- a/multiversx_sdk_cli/tests/test_cli_contracts.py +++ b/multiversx_sdk_cli/tests/test_cli_contracts.py @@ -60,7 +60,7 @@ def test_contract_build(): f"{parent}/testdata-out/SANDBOX/adder" ]) - assert Path.is_file(Path(Path(parent) / "testdata-out" / "SANDBOX" / "adder" / "output" / "adder.wasm")) + assert Path.is_file(parent / "testdata-out" / "SANDBOX" / "adder" / "output" / "adder.wasm") @pytest.mark.skip_on_windows From 851bd30dce0d6657094495e861cc1ed523527c21 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 28 Sep 2023 11:36:09 +0300 Subject: [PATCH 31/62] fix test assert --- multiversx_sdk_cli/tests/test_cli_deps.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/multiversx_sdk_cli/tests/test_cli_deps.py b/multiversx_sdk_cli/tests/test_cli_deps.py index 1d9cc278..7493dee7 100644 --- a/multiversx_sdk_cli/tests/test_cli_deps.py +++ b/multiversx_sdk_cli/tests/test_cli_deps.py @@ -45,7 +45,4 @@ def test_deps_install_vmtools(): @pytest.mark.skip_on_windows def test_deps_check_vmtools(): return_code = main(["deps", "check", "vmtools"]) - if return_code: - assert False - else: - assert True + assert True if return_code == 0 else False From d2af8f58d58eae02393d2610c2c854bc678baa71 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 28 Sep 2023 15:14:48 +0300 Subject: [PATCH 32/62] fixes after review --- multiversx_sdk_cli/config.py | 1 + multiversx_sdk_cli/dependencies/modules.py | 25 +++++++++----------- multiversx_sdk_cli/projects/project_clang.py | 7 ++---- multiversx_sdk_cli/projects/project_cpp.py | 7 ++---- multiversx_sdk_cli/projects/project_rust.py | 12 +++------- multiversx_sdk_cli/projects/shared.py | 12 +++++----- multiversx_sdk_cli/tests/test_cli_deps.py | 21 +++++++--------- 7 files changed, 33 insertions(+), 52 deletions(-) diff --git a/multiversx_sdk_cli/config.py b/multiversx_sdk_cli/config.py index 31972ffb..3cf89ba4 100644 --- a/multiversx_sdk_cli/config.py +++ b/multiversx_sdk_cli/config.py @@ -157,6 +157,7 @@ def get_defaults() -> Dict[str, Any]: "dependencies.golang.urlTemplate.osx": "https://golang.org/dl/{TAG}.darwin-amd64.tar.gz", "dependencies.golang.urlTemplate.windows": "https://golang.org/dl/{TAG}.windows-amd64.zip", "dependencies.twiggy.tag": "latest", + "dependencies.sc-meta.tag": "latest", "dependencies.testwallets.tag": "latest", "dependencies.testwallets.urlTemplate.linux": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz", "dependencies.testwallets.urlTemplate.osx": "https://github.com/multiversx/mx-sdk-testwallets/archive/{TAG}.tar.gz", diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 0b313210..19224462 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -276,15 +276,15 @@ def install(self, overwrite: bool) -> None: if overwrite: logger.info("Overwriting the current rust version...") - elif self._is_installed_and_set_to_nightly(): + elif self.is_installed(""): return - self._do_install(tag) + self._install_rust(tag) self._install_sc_meta() self._install_wasm_opt() self._install_twiggy() - def _do_install(self, tag: str) -> None: + def _install_rust(self, tag: str) -> None: installer_url = self._get_installer_url() installer_path = self._get_installer_path() @@ -304,7 +304,12 @@ def _do_install(self, tag: str) -> None: def _install_sc_meta(self): logger.info("Installing multiversx-sc-meta.") + tag = config.get_dependency_tag("sc-meta") args = ["cargo", "install", "multiversx-sc-meta"] + + if tag != "latest": + args.extend(["--version", tag]) + myprocess.run_process(args) def _install_wasm_opt(self): @@ -315,11 +320,11 @@ def _install_wasm_opt(self): def _install_twiggy(self): logger.info("Installing twiggy.") - default_tag = config.get_dependency_tag("twiggy") + tag = config.get_dependency_tag("twiggy") args = ["cargo", "install", "twiggy"] - if default_tag != "latest": - args.extend(["--version", default_tag]) + if tag != "latest": + args.extend(["--version", tag]) myprocess.run_process(args) @@ -340,14 +345,6 @@ def uninstall(self, tag: str): if os.path.isdir(directory): shutil.rmtree(directory) - def _is_installed_and_set_to_nightly(self) -> bool: - # the method parameter is not used in this specific module - is_rust_installed = self.is_installed("") - - if not is_rust_installed: - return False - return True - def get_directory(self, tag: str) -> Path: tools_folder = workstation.get_tools_folder() return tools_folder / "vendor-rust" diff --git a/multiversx_sdk_cli/projects/project_clang.py b/multiversx_sdk_cli/projects/project_clang.py index 467cafc0..1b800b7c 100644 --- a/multiversx_sdk_cli/projects/project_clang.py +++ b/multiversx_sdk_cli/projects/project_clang.py @@ -1,6 +1,5 @@ import logging import subprocess -import sys from os import path from pathlib import Path from typing import List @@ -8,7 +7,7 @@ from multiversx_sdk_cli import dependencies, errors, myprocess, utils from multiversx_sdk_cli.projects.project_base import Project, rename_wasm_files from multiversx_sdk_cli.projects.shared import \ - are_clang_and_cpp_dependencies_installed + check_clang_and_cpp_dependencies_installed logger = logging.getLogger('ProjectClang') @@ -29,9 +28,7 @@ def perform_build(self): self.file_output = self.unit.with_suffix('.wasm') try: - is_installed = are_clang_and_cpp_dependencies_installed() - if not is_installed: - sys.exit(1) + check_clang_and_cpp_dependencies_installed() self.do_clang() self.do_llvm_link() diff --git a/multiversx_sdk_cli/projects/project_cpp.py b/multiversx_sdk_cli/projects/project_cpp.py index 72567927..eb2dafef 100644 --- a/multiversx_sdk_cli/projects/project_cpp.py +++ b/multiversx_sdk_cli/projects/project_cpp.py @@ -1,7 +1,6 @@ import logging import os import subprocess -import sys from os import path from pathlib import Path from typing import List @@ -9,7 +8,7 @@ from multiversx_sdk_cli import dependencies, errors, myprocess, utils from multiversx_sdk_cli.projects.project_base import Project, rename_wasm_files from multiversx_sdk_cli.projects.shared import \ - are_clang_and_cpp_dependencies_installed + check_clang_and_cpp_dependencies_installed logger = logging.getLogger("ProjectCpp") @@ -26,9 +25,7 @@ def perform_build(self): self.file_export = self.unit.with_suffix(".export") try: - is_installed = are_clang_and_cpp_dependencies_installed() - if not is_installed: - sys.exit(1) + check_clang_and_cpp_dependencies_installed() self._do_clang() self._do_llc() diff --git a/multiversx_sdk_cli/projects/project_rust.py b/multiversx_sdk_cli/projects/project_rust.py index 092b6456..cc837eb1 100644 --- a/multiversx_sdk_cli/projects/project_rust.py +++ b/multiversx_sdk_cli/projects/project_rust.py @@ -1,11 +1,11 @@ import logging -import shutil import subprocess from pathlib import Path from typing import Any, Dict, List, Set, cast from multiversx_sdk_cli import dependencies, errors, utils, workstation from multiversx_sdk_cli.constants import DEFAULT_CARGO_TARGET_DIR_NAME +from multiversx_sdk_cli.dependencies.modules import Rust from multiversx_sdk_cli.projects.project_base import Project logger = logging.getLogger("ProjectRust") @@ -54,14 +54,7 @@ def prepare_build_wasm_args(self, args: List[str]): self.get_output_folder() ]) - def check_if_sc_meta_is_installed(self): - which_sc_meta = shutil.which("sc-meta") - - if which_sc_meta is None: - raise errors.KnownError("'sc-meta' is not installed. Install it manually or simply run `mxpy deps install rust --overwrite` then try again.") - def run_meta(self): - self.check_if_sc_meta_is_installed() env = self.get_env() args = [ @@ -125,7 +118,8 @@ def get_env(self): return dependencies.get_module_by_key("rust").get_env() def build_wasm_with_debug_symbols(self, build_options: Dict[str, Any]): - self.check_if_sc_meta_is_installed() + rust_module = Rust("rust") + rust_module.install(overwrite=False) cwd = self.path env = self.get_env() diff --git a/multiversx_sdk_cli/projects/shared.py b/multiversx_sdk_cli/projects/shared.py index 51ebbd32..a99bb42b 100644 --- a/multiversx_sdk_cli/projects/shared.py +++ b/multiversx_sdk_cli/projects/shared.py @@ -2,6 +2,7 @@ import shutil from pathlib import Path +from multiversx_sdk_cli.errors import KnownError from multiversx_sdk_cli.ux import show_critical_error logger = logging.getLogger("projects.shared") @@ -30,7 +31,7 @@ def _directory_contains_file(directory: Path, name_suffix: str) -> bool: return False -def are_clang_and_cpp_dependencies_installed() -> bool: +def check_clang_and_cpp_dependencies_installed() -> None: which_clang = shutil.which("clang") which_llc = shutil.which("llc") which_wasm_ld = shutil.which("wasm-ld") @@ -43,14 +44,13 @@ def are_clang_and_cpp_dependencies_installed() -> bool: dependencies = [which_clang, which_llc, which_wasm_ld, which_llvm_link] is_installed = all(dependency is not None for dependency in dependencies) - if is_installed: - return True - message = """ + if is_installed is False: + message = """ `clang` is not installed. Please install it manually, then try again. How to install on Ubuntu: https://linux.how2shout.com/how-to-install-clang-on-ubuntu-linux/ How to install on MacOS: https://www.incredibuild.com/integrations/clang For more details check out this page: https://clang.llvm.org/get_started.html""" - show_critical_error(message) - return False + show_critical_error(message) + raise KnownError("The required dependencies are not installed. Please check the above message.") diff --git a/multiversx_sdk_cli/tests/test_cli_deps.py b/multiversx_sdk_cli/tests/test_cli_deps.py index 7493dee7..3859505b 100644 --- a/multiversx_sdk_cli/tests/test_cli_deps.py +++ b/multiversx_sdk_cli/tests/test_cli_deps.py @@ -8,7 +8,7 @@ def test_deps_install_rust(): return_code = main(["deps", "install", "rust", "--overwrite"]) - assert True if return_code == 0 else False + assert return_code == 0 def test_deps_check_rust(): @@ -16,33 +16,28 @@ def test_deps_check_rust(): assert True if return_code == 0 else False which_rustc = shutil.which("rustc") - if which_rustc: - assert Path.is_file(Path(which_rustc)) + assert which_rustc and Path.is_file(Path(which_rustc)) which_cargo = shutil.which("cargo") - if which_cargo: - assert Path.is_file(Path(which_cargo)) + assert which_cargo and Path.is_file(Path(which_cargo)) which_sc_meta = shutil.which("sc-meta") - if which_sc_meta: - assert Path.is_file(Path(which_sc_meta)) + assert which_sc_meta and Path.is_file(Path(which_sc_meta)) which_wasm_opt = shutil.which("wasm-opt") - if which_wasm_opt: - assert Path.is_file(Path(which_wasm_opt)) + assert which_wasm_opt and Path.is_file(Path(which_wasm_opt)) which_twiggy = shutil.which("twiggy") - if which_twiggy: - assert Path.is_file(Path(which_twiggy)) + assert which_twiggy and Path.is_file(Path(which_twiggy)) @pytest.mark.skip_on_windows def test_deps_install_vmtools(): return_code = main(["deps", "install", "vmtools"]) - assert True if return_code == 0 else False + assert return_code == 0 @pytest.mark.skip_on_windows def test_deps_check_vmtools(): return_code = main(["deps", "check", "vmtools"]) - assert True if return_code == 0 else False + assert return_code == 0 From d8bb7a43e9a70feec72ab08da1bc639bddf8a5f5 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 28 Sep 2023 15:33:42 +0300 Subject: [PATCH 33/62] add link to mxpy cookbook --- multiversx_sdk_cli/projects/shared.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/multiversx_sdk_cli/projects/shared.py b/multiversx_sdk_cli/projects/shared.py index a99bb42b..83e52585 100644 --- a/multiversx_sdk_cli/projects/shared.py +++ b/multiversx_sdk_cli/projects/shared.py @@ -48,8 +48,7 @@ def check_clang_and_cpp_dependencies_installed() -> None: if is_installed is False: message = """ `clang` is not installed. Please install it manually, then try again. -How to install on Ubuntu: https://linux.how2shout.com/how-to-install-clang-on-ubuntu-linux/ -How to install on MacOS: https://www.incredibuild.com/integrations/clang +Check out the cookbook: https://docs.multiversx.com/sdk-and-tools/sdk-py/mxpy-cli For more details check out this page: https://clang.llvm.org/get_started.html""" show_critical_error(message) From 15d4f6a5811649236d304691d8e350c671e23990 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 29 Sep 2023 17:09:38 +0300 Subject: [PATCH 34/62] use sc-meta for contract templates and contract new from template --- .gitignore | 2 + multiversx_sdk_cli/cli_contracts.py | 21 +- multiversx_sdk_cli/projects/__init__.py | 9 +- multiversx_sdk_cli/projects/templates.py | 273 +++--------------- .../projects/templates_config.py | 38 --- .../projects/templates_repository.py | 77 ----- multiversx_sdk_cli/test_txs.py | 216 ++++++++++++++ .../tests/test_cli_contracts.py | 12 +- .../tests/test_cli_contracts.sh | 143 +++++---- .../tests/testdata-out/.gitignore | 6 - 10 files changed, 364 insertions(+), 433 deletions(-) delete mode 100644 multiversx_sdk_cli/projects/templates_config.py delete mode 100644 multiversx_sdk_cli/projects/templates_repository.py create mode 100644 multiversx_sdk_cli/test_txs.py delete mode 100644 multiversx_sdk_cli/tests/testdata-out/.gitignore diff --git a/.gitignore b/.gitignore index 2f359c4d..50374163 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ venv.bak/ # Typings typings + +multiversx_sdk_cli/tests/testdata-out diff --git a/multiversx_sdk_cli/cli_contracts.py b/multiversx_sdk_cli/cli_contracts.py index ebf431e4..82ca633e 100644 --- a/multiversx_sdk_cli/cli_contracts.py +++ b/multiversx_sdk_cli/cli_contracts.py @@ -18,6 +18,8 @@ from multiversx_sdk_cli.docker import is_docker_installed, run_docker from multiversx_sdk_cli.errors import DockerMissingError, NoWalletProvided from multiversx_sdk_cli.projects.core import get_project_paths_recursively +from multiversx_sdk_cli.projects.templates import Contract +from multiversx_sdk_cli.ux import show_message logger = logging.getLogger("cli.contracts") @@ -28,14 +30,16 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: sub = cli_shared.add_command_subparser(subparsers, "contract", "new", "Create a new Smart Contract project based on a template.") - sub.add_argument("name") + sub.add_argument("--name", help="The name of the contract. If missing, the name of the template will be used.") sub.add_argument("--template", required=True, help="the template to use") - sub.add_argument("--directory", type=str, default=os.getcwd(), - help="🗀 the parent directory of the project (default: current directory)") + sub.add_argument("--tag", help="the framework version on which the contract should be created") + sub.add_argument("--path", type=str, default=os.getcwd(), + help="the parent directory of the project (default: current directory)") sub.set_defaults(func=create) sub = cli_shared.add_command_subparser(subparsers, "contract", "templates", "List the available Smart Contract templates.") + sub.add_argument("--tag", help="the sc-meta framework version reffered to") sub.set_defaults(func=list_templates) sub = cli_shared.add_command_subparser(subparsers, "contract", "build", @@ -242,15 +246,20 @@ def _add_metadata_arg(sub: Any): def list_templates(args: Any): - projects.list_project_templates() + tag = args.tag + contract = Contract(tag) + templates = contract.get_contract_templates() + show_message(templates) def create(args: Any): name = args.name template = args.template - directory = Path(args.directory) + tag = args.tag + path = Path(args.path) - projects.create_from_template(name, template, directory) + contract = Contract(tag, name, template, path) + contract.create_from_template() def get_project_paths(args: Any) -> List[Path]: diff --git a/multiversx_sdk_cli/projects/__init__.py b/multiversx_sdk_cli/projects/__init__.py index 284a7ca8..0607f0cd 100644 --- a/multiversx_sdk_cli/projects/__init__.py +++ b/multiversx_sdk_cli/projects/__init__.py @@ -1,13 +1,12 @@ from multiversx_sdk_cli.projects.core import (build_project, clean_project, - get_projects_in_workspace, load_project, - run_tests) + get_projects_in_workspace, + load_project, run_tests) from multiversx_sdk_cli.projects.project_base import Project from multiversx_sdk_cli.projects.project_clang import ProjectClang from multiversx_sdk_cli.projects.project_cpp import ProjectCpp from multiversx_sdk_cli.projects.project_rust import ProjectRust from multiversx_sdk_cli.projects.project_sol import ProjectSol from multiversx_sdk_cli.projects.report.do_report import do_report -from multiversx_sdk_cli.projects.templates import (create_from_template, - list_project_templates) +from multiversx_sdk_cli.projects.templates import Contract -__all__ = ["build_project", "clean_project", "do_report", "run_tests", "get_projects_in_workspace", "load_project", "Project", "ProjectClang", "ProjectCpp", "ProjectRust", "ProjectSol", "create_from_template", "list_project_templates"] +__all__ = ["build_project", "clean_project", "do_report", "run_tests", "get_projects_in_workspace", "load_project", "Project", "ProjectClang", "ProjectCpp", "ProjectRust", "ProjectSol", "Contract"] diff --git a/multiversx_sdk_cli/projects/templates.py b/multiversx_sdk_cli/projects/templates.py index d5589f4b..58cf206b 100644 --- a/multiversx_sdk_cli/projects/templates.py +++ b/multiversx_sdk_cli/projects/templates.py @@ -1,254 +1,55 @@ -import json import logging -import shutil from pathlib import Path -from typing import Any, List, Tuple +from typing import Union -from multiversx_sdk_cli import errors, utils -from multiversx_sdk_cli.projects import shared -from multiversx_sdk_cli.projects.project_rust import CargoFile -from multiversx_sdk_cli.projects.templates_config import \ - get_templates_repositories -from multiversx_sdk_cli.projects.templates_repository import \ - TemplatesRepository +from multiversx_sdk_cli import myprocess +from multiversx_sdk_cli.dependencies.install import install_module logger = logging.getLogger("projects.templates") -def list_project_templates(): - summaries: List[TemplateSummary] = [] - - for repository in get_templates_repositories(): - repository.download() - for template in repository.get_templates(): - summaries.append(TemplateSummary(template, repository)) - - summaries = sorted(summaries, key=lambda item: item.name) - - pretty_json = json.dumps([item.__dict__ for item in summaries], indent=4) - print(pretty_json) - - -class TemplateSummary(): - def __init__(self, name: str, repository: TemplatesRepository): +class Contract: + def __init__(self, + tag: Union[str, None] = None, + name: Union[str, None] = None, + template: str = "", + path: Path = Path() + ) -> None: + self.tag = tag self.name = name - self.github = repository.github - self.language = repository.get_language(name) - - -def create_from_template(project_name: str, template_name: str, directory: Path): - directory = directory.expanduser() - - logger.info("create_from_template.project_name: %s", project_name) - logger.info("create_from_template.template_name: %s", template_name) - logger.info("create_from_template.directory: %s", directory) - - if not directory: - logger.info("Using current directory") - directory = Path.cwd() - - project_directory = Path(directory) / project_name - if project_directory.exists(): - raise errors.BadDirectory(str(project_directory)) - - _download_templates_repositories() - _copy_template(template_name, project_directory, project_name) - - template = _load_as_template(project_directory) - template.apply(template_name, project_name) - - logger.info("Project created, template applied.") - - -def _download_templates_repositories(): - for repo in get_templates_repositories(): - repo.download() - - -def _copy_template(template: str, destination_path: Path, project_name: str): - for repo in get_templates_repositories(): - if repo.has_template(template): - source_path = repo.get_template_folder(template) - shutil.copytree(source_path, destination_path) - return - - raise errors.TemplateMissingError(template) - - -def _load_as_template(directory: Path): - if shared.is_source_rust(directory): - return TemplateRust(directory) - raise errors.BadTemplateError(directory) - - -class Template: - def __init__(self, directory: Path): - self.directory = directory - - def apply(self, template_name: str, project_name: str): - self.template_name = template_name - self.project_name = project_name - self._patch() - - def _patch(self): - """Implemented by derived classes""" - pass - - -class TemplateRust(Template): - CARGO_TOML = "Cargo.toml" - - def _patch(self): - logger.info("Patching cargo files...") - self._patch_cargo() - self._patch_sub_crate("wasm") - self._patch_sub_crate("abi") - self._patch_sub_crate("meta") - template_name = self._with_underscores(self.template_name) - - tests = (self.directory / "tests").glob("*.rs") - - source_code_files = [ - self.directory / "src" / f"{template_name}.rs", - self.directory / "src" / "lib.rs", - self.directory / "abi" / "src" / "main.rs", - self.directory / "wasm" / "src" / "lib.rs", - self.directory / "meta" / "src" / "main.rs", - ] - - source_code_files.extend(tests) - - logger.info("Patching source code...") - self._patch_source_code_files(source_code_files, ignore_missing=True) - self._patch_source_code_tests() - - logger.info("Patching test files...") - self._patch_scenarios_tests() - - def _patch_cargo(self): - cargo_path = self.directory / TemplateRust.CARGO_TOML - - cargo_file = CargoFile(cargo_path) - cargo_file.package_name = self.project_name - cargo_file.version = "0.0.0" - cargo_file.authors = ["you"] - cargo_file.edition = "2018" - cargo_file.publish = False - - remove_path_from_dependencies(cargo_file) - - cargo_file.save() - - def _patch_sub_crate(self, sub_name: str) -> None: - cargo_path = self.directory / sub_name / TemplateRust.CARGO_TOML - if not cargo_path.is_file(): - return - - cargo_file = CargoFile(cargo_path) - cargo_file.package_name = f"{self.project_name}-{sub_name}" - cargo_file.version = "0.0.0" - cargo_file.authors = ["you"] - cargo_file.edition = "2018" - cargo_file.publish = False - - remove_path_from_dependencies(cargo_file) - - # Patch the path towards the project crate (one folder above): - cargo_file.get_dependency(self.template_name)["path"] = ".." - - cargo_file.save() - - self._replace_in_files( - [cargo_path], - [ - (f"[dependencies.{self.template_name}]", f"[dependencies.{self.project_name}]") - ], - ignore_missing=False - ) - - def _with_underscores(self, name: str) -> str: - return name.replace('-', '_') - - def _contract_name(self, name: str) -> str: - chars = name.replace("-", " ").replace("_", " ").split() - return ''.join(i.capitalize() for i in chars[0:]) - - def _patch_source_code_files(self, source_paths: List[Path], ignore_missing: bool) -> None: - template_name = self._with_underscores(self.template_name) - project_name = self._with_underscores(self.project_name) - template_contract_name = self._contract_name(self.template_name) - project_contract_name = self._contract_name(self.project_name) - - self._replace_in_files( - source_paths, - [ - # Example: replace contract name "pub trait SimpleERC20" to "pub trait MyContract" - (f"pub trait {template_contract_name}", f"pub trait {project_contract_name}"), - # Example: replace "simple_erc20.wasm" to "my_token.wasm" - (f"{self.template_name}.wasm", f"{self.project_name}.wasm"), - # Example: replace "use simple_erc20::*" to "use my_token::*" - (f"use {template_name}::*", f"use {project_name}::*"), - # Example: replace "()" to "()" - (f"<{template_name}::AbiProvider>()", f"<{project_name}::AbiProvider>()"), - # Example: replace "extern crate adder;" to "extern crate myadder;" - (f"extern crate {template_name};", f"extern crate {project_name};"), - # Example: replace "empty::ContractObj" to "foo_bar::ContractObj" - (f"{template_name}::ContractObj", f"{project_name}::ContractObj"), - (f"{template_name}::ContractBuilder", f"{project_name}::ContractBuilder"), - (f"{template_name}::contract_obj", f"{project_name}::contract_obj"), - ], - ignore_missing - ) - - def _patch_source_code_tests(self): - test_dir_path = self.directory / "tests" - if not test_dir_path.is_dir(): - return - - test_paths = utils.list_files(test_dir_path) - self._patch_source_code_files(test_paths, ignore_missing=False) + self.template = template + self.path = path - def _patch_scenarios_tests(self): - test_dir_path = self.directory / "scenarios" - if not test_dir_path.is_dir(): - return + def get_contract_templates(self) -> str: + self._check_if_dependencies_installed() + args = self._prepare_args_to_list_templates() + templates = myprocess.run_process(args=args, dump_to_stdout=False) + return templates - test_paths = utils.list_files(test_dir_path, suffix=".json") - self._replace_in_files( - test_paths, - [ - (f"{self.template_name}.wasm", f"{self.project_name}.wasm") - ], - ignore_missing=False - ) + def create_from_template(self) -> None: + self._check_if_dependencies_installed() + args = self._prepare_args_to_create_new_contract_from_template() + myprocess.run_process(args) - for file in test_paths: - data = utils.read_json_file(file) - # Patch fields - data["name"] = data.get("name", "").replace(self.template_name, self.project_name) - utils.write_json_file(str(file), data) + def _check_if_dependencies_installed(self): + logger.info("Checking if the necessarry dependencies are installed.") + install_module("rust") - def _replace_in_files(self, files: List[Path], replacements: List[Tuple[str, str]], ignore_missing: bool) -> None: - for file in files: - if ignore_missing and not file.exists(): - continue - content = file.read_text() + def _prepare_args_to_list_templates(self) -> list[str]: + args = ["sc-meta", "templates"] - for to_replace, replacement in replacements: - content = content.replace(to_replace, replacement) + if self.tag: + args.extend(["--tag", self.tag]) - utils.write_file(file, content) + return args + def _prepare_args_to_create_new_contract_from_template(self) -> list[str]: + args = ["sc-meta", "new", "--template", self.template, "--path", str(self.path)] -def remove_path(dependency: Any) -> None: - try: - del dependency["path"] - except TypeError: - pass + if self.name: + args.extend(["--name", self.name]) + if self.tag: + args.extend(["--tag", self.tag]) -def remove_path_from_dependencies(cargo_file: CargoFile) -> None: - for dependency in cargo_file.get_dependencies().values(): - remove_path(dependency) - for dependency in cargo_file.get_dev_dependencies().values(): - remove_path(dependency) + return args diff --git a/multiversx_sdk_cli/projects/templates_config.py b/multiversx_sdk_cli/projects/templates_config.py deleted file mode 100644 index 2fbd6b45..00000000 --- a/multiversx_sdk_cli/projects/templates_config.py +++ /dev/null @@ -1,38 +0,0 @@ -import time - -from multiversx_sdk_cli import config -from multiversx_sdk_cli.projects.templates_repository import \ - TemplatesRepository -from multiversx_sdk_cli.utils import query_latest_release_tag - - -def get_templates_repositories(): - timestamp = int(time.time()) - examples_rs_tag = config.get_dependency_tag('mx_sdk_rs') - - if examples_rs_tag == 'latest': - examples_rs_tag = query_latest_release_tag('multiversx/mx-sdk-rs') - - examples_rs_tag_no_v = remove_initial_v_from_version(examples_rs_tag) - - return [ - TemplatesRepository( - key="mx-sdk-rs", - url=f"https://github.com/multiversx/mx-sdk-rs/archive/{examples_rs_tag}.zip?t={timestamp}", - github="multiversx/mx-sdk-rs", - relative_path=f"mx-sdk-rs-{examples_rs_tag_no_v}/contracts/examples" - ) - ] - - -def remove_initial_v_from_version(version: str) -> str: - """Remove the initial 'v' from semver strings 'vX.XX.XX', but leave branch - names or non-semver tags unchanged""" - if version[0] != 'v': - return version - - version_no_v = version[1:] - if not version_no_v[0].isnumeric(): - return version - - return version_no_v diff --git a/multiversx_sdk_cli/projects/templates_repository.py b/multiversx_sdk_cli/projects/templates_repository.py deleted file mode 100644 index 5d4f2ee0..00000000 --- a/multiversx_sdk_cli/projects/templates_repository.py +++ /dev/null @@ -1,77 +0,0 @@ -import shutil -import time -from os import path -from pathlib import Path - -from multiversx_sdk_cli import downloader, utils, workstation -from multiversx_sdk_cli.projects.constants import PROJECT_CONFIG_FILENAME -from multiversx_sdk_cli.projects.migrations import migrate_project_templates - - -class TemplatesRepository: - def __init__(self, key: str, url: str, github: str, relative_path: str): - self.key = key - self.url = url - self.github = github - self.relative_path = relative_path - - def download(self): - self._download_if_old() - - templates_folder = self.get_folder() - try: - shutil.rmtree(templates_folder) - except FileNotFoundError: - pass - - archive = self._get_archive_path() - utils.unzip(archive, templates_folder) - migrate_project_templates(self.get_payload_folder()) - - def _download_if_old(self): - CACHE_DURATION = 30 - archive = self._get_archive_path() - - if path.isfile(archive): - if time.time() - path.getmtime(archive) < CACHE_DURATION: - return - - downloader.download(self.url, str(archive)) - - def _get_archive_path(self) -> Path: - tools_folder = workstation.get_tools_folder() - archive = tools_folder / f"{self.key}.zip" - return archive - - def get_folder(self) -> Path: - tools_folder = workstation.get_tools_folder() - folder = tools_folder / "templates" / self.key - return folder - - def has_template(self, template: str) -> bool: - folder = self.get_template_folder(template) - has = folder.is_dir() - return has - - def get_template_folder(self, template: str) -> Path: - return self.get_payload_folder() / template - - def get_templates(self): - templates = utils.get_subfolders(self.get_payload_folder()) - templates = [item for item in templates if self.is_template(item)] - return templates - - def is_template(self, subfolder: str) -> bool: - project_config_file = self.get_metadata_file(subfolder) - return project_config_file.is_file() - - def get_metadata_file(self, template: str) -> Path: - return self.get_payload_folder() / template / PROJECT_CONFIG_FILENAME - - def get_language(self, template: str): - metadata_file = self.get_metadata_file(template) - metadata = utils.read_json_file(metadata_file) - return metadata.get("language", "unknown") - - def get_payload_folder(self) -> Path: - return self.get_folder() / self.relative_path diff --git a/multiversx_sdk_cli/test_txs.py b/multiversx_sdk_cli/test_txs.py new file mode 100644 index 00000000..b317c06f --- /dev/null +++ b/multiversx_sdk_cli/test_txs.py @@ -0,0 +1,216 @@ +from multiversx_sdk_cli.cli import main as mxpy + +unguarded_pem = "~/Desktop/Guardians/unguarded.pem" +alice = "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" + +guarded = "~/Desktop/Guardians/address.pem" +guardian_address = "erd1nufxjweqjgk44drr49nxdnjc5ety288gd2hvvvm9tjkhlhgnnlusw2vmvt" +guardian = "~/Desktop/Guardians/guardian.pem" + +guarded_keystore = "~/Desktop/Guardians/address_keystore.json" +passfile = "/home/alex/Desktop/Guardians/keystore_pass.txt" + +service_guarded = "~/Desktop/Guardians/service_guarded.pem" +service_guardian = "erd16rq0gvkehwl4w5clh3np7352203spd8ts33ceuvxvtp84q0edfys65pquu" + +chain = "1" +gas_limit = "500000000" +proxy = "https://express-api-up-mad.elrond.ro" +options = "2" +value = "1000000" + +guardian_service_url = "https://mx-mfa-auth.elrond.ro/guardian" + +unguarded_saved_tx = "/home/alex/Desktop/Guardians/unguarded_unsigned.json" +pem_guarded_saved_tx = "/home/alex/Desktop/Guardians/pem_guarded_unsigned.json" +service_guarded_saved_tx = "/home/alex/Desktop/Guardians/service_guarded_unsigned.json" + + +def unguarded_tx(): + mxpy([ + "tx", + "new", + "--pem", + unguarded_pem, + "--receiver", + alice, + "--recall-nonce", + "--chain", + chain, + "--gas-limit", + gas_limit, + "--proxy", + proxy, + "--value", + value, + "--send" + ]) + + +def pem_gurded_tx(): + mxpy([ + "tx", + "new", + "--pem", + guarded, + "--receiver", + alice, + "--recall-nonce", + "--chain", + chain, + "--gas-limit", + gas_limit, + "--proxy", + proxy, + "--options", + options, + "--value", + value, + "--guardian", + guardian_address, + "--guardian-pem", + guardian, + "--send" + ]) + + +def keystore_guarded_tx(): + mxpy([ + "tx", + "new", + "--keyfile", + guarded_keystore, + "--passfile", + passfile, + "--receiver", + alice, + "--recall-nonce", + "--chain", + chain, + "--gas-limit", + gas_limit, + "--proxy", + proxy, + "--options", + options, + "--value", + value, + "--guardian", + guardian_address, + "--guardian-pem", + guardian, + "--send" + ]) + + +def service_guarded_tx(code: str): + mxpy([ + "tx", + "new", + "--pem", + service_guarded, + "--receiver", + alice, + "--recall-nonce", + "--chain", + chain, + "--gas-limit", + gas_limit, + "--proxy", + proxy, + "--options", + options, + "--value", + value, + "--guardian", + service_guardian, + "--guardian-service-url", + guardian_service_url, + "--guardian-2fa-code", + code, + "--send" + ]) + + +def cold_sign_unguarded(): + mxpy([ + "tx", + "sign", + "--pem", + unguarded_pem, + "--proxy", + proxy, + "--infile", + unguarded_saved_tx + ]) + + +def cold_sign_pem_guarded(): + mxpy([ + "tx", + "sign", + "--pem", + guarded, + "--proxy", + proxy, + "--guardian", + guardian_address, + "--guardian-pem", + guardian, + "--infile", + pem_guarded_saved_tx, + ]) + + +def cold_sign_keystore(): + mxpy([ + "tx", + "sign", + "--keyfile", + guarded_keystore, + "--passfile", + passfile, + "--proxy", + proxy, + "--guardian", + guardian_address, + "--guardian-pem", + guardian, + "--infile", + pem_guarded_saved_tx + ]) + + +def cold_sign_service_guarded(code: str): + mxpy([ + "tx", + "sign", + "--pem", + service_guarded, + "--proxy", + proxy, + "--guardian", + service_guardian, + "--guardian-service-url", + guardian_service_url, + "--guardian-2fa-code", + code, + "--infile", + service_guarded_saved_tx + ]) + + +def main(): + # unguarded_tx() + # pem_gurded_tx() + # keystore_guarded_tx() + # service_guarded_tx("895317") + # cold_sign_unguarded() + # cold_sign_pem_guarded() + # cold_sign_keystore() + # cold_sign_service_guarded("123456") + pass + + +if __name__ == '__main__': + main() diff --git a/multiversx_sdk_cli/tests/test_cli_contracts.py b/multiversx_sdk_cli/tests/test_cli_contracts.py index 46f5cddd..63323a97 100644 --- a/multiversx_sdk_cli/tests/test_cli_contracts.py +++ b/multiversx_sdk_cli/tests/test_cli_contracts.py @@ -14,9 +14,8 @@ def test_contract_new(): "new", "--template", "adder", - "--directory", - f"{parent}/testdata-out/SANDBOX", - "adder" + "--path", + f"{parent}/testdata-out/SANDBOX" ]) assert Path.is_dir(parent / "testdata-out" / "SANDBOX" / "adder") @@ -28,8 +27,9 @@ def test_contract_new_with_bad_code(): "new", "--template", "adder", - "--directory", + "--path", f"{parent}/testdata-out/SANDBOX", + "--name", "adder-bad-src" ]) @@ -39,7 +39,7 @@ def test_contract_new_with_bad_code(): def replace_variable_with_unknown_variable(): # this is done in order to replace the value added in the adder contract with a unknown variable - with open(parent / "testdata-out" / "SANDBOX" / "adder-bad-src" / "src" / "adder.rs", "r") as f: + with open(parent / "testdata-out" / "SANDBOX" / "adder-bad-src" / "src" / "adder_bad_src.rs", "r") as f: contract_lines = f.readlines() for index, line in reversed(list(enumerate(contract_lines))): @@ -47,7 +47,7 @@ def replace_variable_with_unknown_variable(): contract_lines[index] = line.replace("value", "unknown_variable") break - with open(parent / "testdata-out" / "SANDBOX" / "adder-bad-src" / "src" / "adder.rs", "w") as f: + with open(parent / "testdata-out" / "SANDBOX" / "adder-bad-src" / "src" / "adder_bad_src.rs", "w") as f: f.writelines(contract_lines) diff --git a/multiversx_sdk_cli/tests/test_cli_contracts.sh b/multiversx_sdk_cli/tests/test_cli_contracts.sh index 174e0b2f..04f023f6 100755 --- a/multiversx_sdk_cli/tests/test_cli_contracts.sh +++ b/multiversx_sdk_cli/tests/test_cli_contracts.sh @@ -9,12 +9,16 @@ testTrivialCommands() { testCreateContracts() { echo "testCreateContracts" - ${CLI} contract new --template adder --directory ${SANDBOX} myadder-rs || return 1 - ${CLI} contract new --template factorial --directory ${SANDBOX} myfactorial-rs || return 1 - ${CLI} contract new --template crypto-bubbles --directory ${SANDBOX} mybubbles-rs || return 1 - ${CLI} contract new --template lottery-esdt --directory ${SANDBOX} mylottery-rs || return 1 - ${CLI} contract new --template crowdfunding-esdt --directory ${SANDBOX} myfunding-rs || return 1 - ${CLI} contract new --template multisig --directory ${SANDBOX} multisig-rs || return 1 + ${CLI} contract new --template adder --path ${SANDBOX} || return 1 + ${CLI} contract new --template crypto-zombies --path ${SANDBOX} || return 1 + ${CLI} contract new --template empty --path ${SANDBOX} || return 1 + + # uncomment when other contract templates are available in sc-meta + # ${CLI} contract new --template factorial --path ${SANDBOX} myfactorial-rs || return 1 + # ${CLI} contract new --template crypto-bubbles --path ${SANDBOX} mybubbles-rs || return 1 + # ${CLI} contract new --template lottery-esdt --path ${SANDBOX} mylottery-rs || return 1 + # ${CLI} contract new --template crowdfunding-esdt --path ${SANDBOX} myfunding-rs || return 1 + # ${CLI} contract new --template multisig --path ${SANDBOX} multisig-rs || return 1 } testBuildContracts() { @@ -24,77 +28,98 @@ testBuildContracts() { export TARGET_DIR=$(pwd)/${SANDBOX}/TARGET mkdir -p ${TARGET_DIR} - ${CLI} contract build --path=${SANDBOX}/myadder-rs --target-dir=${TARGET_DIR} || return 1 - assertFileExists ${SANDBOX}/myadder-rs/output/myadder-rs.wasm || return 1 - assertFileExists ${SANDBOX}/myadder-rs/output/myadder-rs.abi.json || return 1 + ${CLI} contract build --path=${SANDBOX}/adder --target-dir=${TARGET_DIR} || return 1 + assertFileExists ${SANDBOX}/adder/output/adder.wasm || return 1 + assertFileExists ${SANDBOX}/adder/output/adder.abi.json || return 1 - ${CLI} contract build --path=${SANDBOX}/myfactorial-rs --target-dir=${TARGET_DIR} || return 1 - assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 - assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 + ${CLI} contract build --path=${SANDBOX}/crypto-zombies --target-dir=${TARGET_DIR} || return 1 + assertFileExists ${SANDBOX}/crypto-zombies/output/crypto-zombies.wasm || return 1 + assertFileExists ${SANDBOX}/crypto-zombies/output/crypto-zombies.abi.json || return 1 - ${CLI} contract build --path=${SANDBOX}/mybubbles-rs --target-dir=${TARGET_DIR} || return 1 - assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 - assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 + ${CLI} contract build --path=${SANDBOX}/empty --target-dir=${TARGET_DIR} || return 1 + assertFileExists ${SANDBOX}/empty/output/empty.wasm || return 1 + assertFileExists ${SANDBOX}/empty/output/empty.abi.json || return 1 - ${CLI} contract build --path=${SANDBOX}/mylottery-rs --target-dir=${TARGET_DIR} || return 1 - assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 - assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 + # uncomment when other contract templates are available in sc-meta + # ${CLI} contract build --path=${SANDBOX}/myfactorial-rs --target-dir=${TARGET_DIR} || return 1 + # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 - ${CLI} contract build --path=${SANDBOX}/myfunding-rs --target-dir=${TARGET_DIR} || return 1 - assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 - assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 + # ${CLI} contract build --path=${SANDBOX}/mybubbles-rs --target-dir=${TARGET_DIR} || return 1 + # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 + + # ${CLI} contract build --path=${SANDBOX}/mylottery-rs --target-dir=${TARGET_DIR} || return 1 + # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 + + # ${CLI} contract build --path=${SANDBOX}/myfunding-rs --target-dir=${TARGET_DIR} || return 1 + # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 } testRunScenarios() { echo "testRunScenarios" - ${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/myadder-rs || return 1 - ${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/mybubbles-rs || return 1 - ${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/mylottery-rs || return 1 - ${CLI} --verbose contract test --directory="scenarios" --recursive ${SANDBOX}/myfunding-rs || return 1 + ${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/adder || return 1 + ${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/empty || return 1 + # ${CLI} --verbose contract test --directory="scenarios" --recursive ${SANDBOX}/myfunding-rs || return 1 } testWasmName() { echo "testWasmName" - ${CLI} contract clean --path ${SANDBOX}/myadder-rs - assertFileDoesNotExist ${SANDBOX}/myadder-rs/output/myadder-2-rs.wasm || return 1 - ${CLI} contract build --path=${SANDBOX}/myadder-rs --target-dir=${TARGET_DIR} --wasm-name myadder-2-rs || return 1 - assertFileExists ${SANDBOX}/myadder-rs/output/myadder-2-rs.wasm || return 1 - assertFileExists ${SANDBOX}/myadder-rs/output/myadder-rs.abi.json || return 1 + ${CLI} contract clean --path ${SANDBOX}/adder + assertFileDoesNotExist ${SANDBOX}/adder/output/adder-2.wasm || return 1 + ${CLI} contract build --path=${SANDBOX}/adder --target-dir=${TARGET_DIR} --wasm-name adder-2 || return 1 + assertFileExists ${SANDBOX}/adder/output/adder-2.wasm || return 1 + assertFileExists ${SANDBOX}/adder/output/adder.abi.json || return 1 } testCleanContracts() { echo "testCleanContracts" - assertFileExists ${SANDBOX}/myadder-rs/output/myadder-rs.wasm || return 1 - assertFileExists ${SANDBOX}/myadder-rs/output/myadder-rs.abi.json || return 1 - ${CLI} contract clean --path ${SANDBOX}/myadder-rs || return 1 - assertFileDoesNotExist ${SANDBOX}/myadder-rs/output/myadder-rs.wasm || return 1 - assertFileDoesNotExist ${SANDBOX}/myadder-rs/output/myadder-rs.abi.json || return 1 - - assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 - assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 - ${CLI} contract clean --path ${SANDBOX}/myfactorial-rs || return 1 - assertFileDoesNotExist ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 - assertFileDoesNotExist ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 - - assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 - assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 - ${CLI} contract clean --path ${SANDBOX}/mybubbles-rs || return 1 - assertFileDoesNotExist ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 - assertFileDoesNotExist ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 - - assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 - assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 - ${CLI} contract clean --path ${SANDBOX}/mylottery-rs || return 1 - assertFileDoesNotExist ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 - assertFileDoesNotExist ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 - - assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 - assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 - ${CLI} contract clean --path ${SANDBOX}/myfunding-rs || return 1 - assertFileDoesNotExist ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 - assertFileDoesNotExist ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 + assertFileExists ${SANDBOX}/adder/output/adder.wasm || return 1 + assertFileExists ${SANDBOX}/adder/output/adder.abi.json || return 1 + ${CLI} contract clean --path ${SANDBOX}/adder || return 1 + assertFileDoesNotExist ${SANDBOX}/adder/output/adder.wasm || return 1 + assertFileDoesNotExist ${SANDBOX}/adder/output/adder.abi.json || return 1 + + assertFileExists ${SANDBOX}/crypto-zombies/output/crypto-zombies.wasm || return 1 + assertFileExists ${SANDBOX}/crypto-zombies/output/crypto-zombies.abi.json || return 1 + ${CLI} contract clean --path ${SANDBOX}/crypto-zombies || return 1 + assertFileDoesNotExist ${SANDBOX}/crypto-zombies/output/crypto-zombies.wasm || return 1 + assertFileDoesNotExist ${SANDBOX}/crypto-zombies/output/crypto-zombies.abi.json || return 1 + + assertFileExists ${SANDBOX}/empty/output/empty.wasm || return 1 + assertFileExists ${SANDBOX}/empty/output/empty.abi.json || return 1 + ${CLI} contract clean --path ${SANDBOX}/empty || return 1 + assertFileDoesNotExist ${SANDBOX}/empty/output/empty.wasm || return 1 + assertFileDoesNotExist ${SANDBOX}/empty/output/empty.abi.json || return 1 + + # uncomment when other contract templates are available in sc-meta + # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 + # ${CLI} contract clean --path ${SANDBOX}/myfactorial-rs || return 1 + # assertFileDoesNotExist ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 + # assertFileDoesNotExist ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 + + # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 + # ${CLI} contract clean --path ${SANDBOX}/mybubbles-rs || return 1 + # assertFileDoesNotExist ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 + # assertFileDoesNotExist ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 + + # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 + # ${CLI} contract clean --path ${SANDBOX}/mylottery-rs || return 1 + # assertFileDoesNotExist ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 + # assertFileDoesNotExist ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 + + # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 + # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 + # ${CLI} contract clean --path ${SANDBOX}/myfunding-rs || return 1 + # assertFileDoesNotExist ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 + # assertFileDoesNotExist ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 } testVerifyContract(){ diff --git a/multiversx_sdk_cli/tests/testdata-out/.gitignore b/multiversx_sdk_cli/tests/testdata-out/.gitignore deleted file mode 100644 index 210accf2..00000000 --- a/multiversx_sdk_cli/tests/testdata-out/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Ignore everything -* - -# But not these files... -!.gitignore - From dc95f24f8db682ccc09857abb3dad0e84346a330 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 2 Oct 2023 11:45:51 +0300 Subject: [PATCH 35/62] start wallet sign-message command --- multiversx_sdk_cli/cli_wallet.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index 57bfbb6c..6d547546 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -78,6 +78,15 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: group.add_argument("--decode", action="store_true", help="whether to decode") sub.set_defaults(func=do_bech32) + sub = cli_shared.add_command_subparser( + subparsers, + "wallet", + "sign-message", + "Sign a message" + ) + sub.add_argument("--message", required=True, help="the message you want to sign") + sub.set_defaults(func=sign_message) + parser.epilog = cli_shared.build_group_epilog(subparsers) return subparsers @@ -247,3 +256,7 @@ def do_bech32(args: Any): print(result) return result + + +def sign_message(args: Any): + pass From 4dbf0184200ca5882295137b1244e3056d092c7a Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 2 Oct 2023 11:53:00 +0300 Subject: [PATCH 36/62] remove file --- multiversx_sdk_cli/test_txs.py | 216 --------------------------------- 1 file changed, 216 deletions(-) delete mode 100644 multiversx_sdk_cli/test_txs.py diff --git a/multiversx_sdk_cli/test_txs.py b/multiversx_sdk_cli/test_txs.py deleted file mode 100644 index b317c06f..00000000 --- a/multiversx_sdk_cli/test_txs.py +++ /dev/null @@ -1,216 +0,0 @@ -from multiversx_sdk_cli.cli import main as mxpy - -unguarded_pem = "~/Desktop/Guardians/unguarded.pem" -alice = "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" - -guarded = "~/Desktop/Guardians/address.pem" -guardian_address = "erd1nufxjweqjgk44drr49nxdnjc5ety288gd2hvvvm9tjkhlhgnnlusw2vmvt" -guardian = "~/Desktop/Guardians/guardian.pem" - -guarded_keystore = "~/Desktop/Guardians/address_keystore.json" -passfile = "/home/alex/Desktop/Guardians/keystore_pass.txt" - -service_guarded = "~/Desktop/Guardians/service_guarded.pem" -service_guardian = "erd16rq0gvkehwl4w5clh3np7352203spd8ts33ceuvxvtp84q0edfys65pquu" - -chain = "1" -gas_limit = "500000000" -proxy = "https://express-api-up-mad.elrond.ro" -options = "2" -value = "1000000" - -guardian_service_url = "https://mx-mfa-auth.elrond.ro/guardian" - -unguarded_saved_tx = "/home/alex/Desktop/Guardians/unguarded_unsigned.json" -pem_guarded_saved_tx = "/home/alex/Desktop/Guardians/pem_guarded_unsigned.json" -service_guarded_saved_tx = "/home/alex/Desktop/Guardians/service_guarded_unsigned.json" - - -def unguarded_tx(): - mxpy([ - "tx", - "new", - "--pem", - unguarded_pem, - "--receiver", - alice, - "--recall-nonce", - "--chain", - chain, - "--gas-limit", - gas_limit, - "--proxy", - proxy, - "--value", - value, - "--send" - ]) - - -def pem_gurded_tx(): - mxpy([ - "tx", - "new", - "--pem", - guarded, - "--receiver", - alice, - "--recall-nonce", - "--chain", - chain, - "--gas-limit", - gas_limit, - "--proxy", - proxy, - "--options", - options, - "--value", - value, - "--guardian", - guardian_address, - "--guardian-pem", - guardian, - "--send" - ]) - - -def keystore_guarded_tx(): - mxpy([ - "tx", - "new", - "--keyfile", - guarded_keystore, - "--passfile", - passfile, - "--receiver", - alice, - "--recall-nonce", - "--chain", - chain, - "--gas-limit", - gas_limit, - "--proxy", - proxy, - "--options", - options, - "--value", - value, - "--guardian", - guardian_address, - "--guardian-pem", - guardian, - "--send" - ]) - - -def service_guarded_tx(code: str): - mxpy([ - "tx", - "new", - "--pem", - service_guarded, - "--receiver", - alice, - "--recall-nonce", - "--chain", - chain, - "--gas-limit", - gas_limit, - "--proxy", - proxy, - "--options", - options, - "--value", - value, - "--guardian", - service_guardian, - "--guardian-service-url", - guardian_service_url, - "--guardian-2fa-code", - code, - "--send" - ]) - - -def cold_sign_unguarded(): - mxpy([ - "tx", - "sign", - "--pem", - unguarded_pem, - "--proxy", - proxy, - "--infile", - unguarded_saved_tx - ]) - - -def cold_sign_pem_guarded(): - mxpy([ - "tx", - "sign", - "--pem", - guarded, - "--proxy", - proxy, - "--guardian", - guardian_address, - "--guardian-pem", - guardian, - "--infile", - pem_guarded_saved_tx, - ]) - - -def cold_sign_keystore(): - mxpy([ - "tx", - "sign", - "--keyfile", - guarded_keystore, - "--passfile", - passfile, - "--proxy", - proxy, - "--guardian", - guardian_address, - "--guardian-pem", - guardian, - "--infile", - pem_guarded_saved_tx - ]) - - -def cold_sign_service_guarded(code: str): - mxpy([ - "tx", - "sign", - "--pem", - service_guarded, - "--proxy", - proxy, - "--guardian", - service_guardian, - "--guardian-service-url", - guardian_service_url, - "--guardian-2fa-code", - code, - "--infile", - service_guarded_saved_tx - ]) - - -def main(): - # unguarded_tx() - # pem_gurded_tx() - # keystore_guarded_tx() - # service_guarded_tx("895317") - # cold_sign_unguarded() - # cold_sign_pem_guarded() - # cold_sign_keystore() - # cold_sign_service_guarded("123456") - pass - - -if __name__ == '__main__': - main() From 88fc3d9d152d82842b7a8cae9cd15b7dacfdc4e8 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 2 Oct 2023 14:54:10 +0300 Subject: [PATCH 37/62] add new command: mxpy wallet sign-message --- multiversx_sdk_cli/cli_wallet.py | 10 ++++++++-- multiversx_sdk_cli/message.py | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 multiversx_sdk_cli/message.py diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index 6d547546..a27a37ab 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -10,9 +10,10 @@ from multiversx_sdk_wallet.mnemonic import Mnemonic from multiversx_sdk_wallet.user_pem import UserPEM -from multiversx_sdk_cli import cli_shared +from multiversx_sdk_cli import cli_shared, utils from multiversx_sdk_cli.constants import DEFAULT_HRP from multiversx_sdk_cli.errors import KnownError +from multiversx_sdk_cli.message import SignableMessage logger = logging.getLogger("cli.wallet") @@ -85,6 +86,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: "Sign a message" ) sub.add_argument("--message", required=True, help="the message you want to sign") + cli_shared.add_wallet_args(args, sub) sub.set_defaults(func=sign_message) parser.epilog = cli_shared.build_group_epilog(subparsers) @@ -259,4 +261,8 @@ def do_bech32(args: Any): def sign_message(args: Any): - pass + message: str = args.message + account = cli_shared.prepare_account(args) + signable_message = SignableMessage(message, account) + signable_message.sign() + utils.dump_out_json(signable_message.to_dictionary()) diff --git a/multiversx_sdk_cli/message.py b/multiversx_sdk_cli/message.py new file mode 100644 index 00000000..1fedab73 --- /dev/null +++ b/multiversx_sdk_cli/message.py @@ -0,0 +1,20 @@ +from typing import Dict + +from multiversx_sdk_cli.accounts import Account + + +class SignableMessage: + def __init__(self, message: str, account: Account) -> None: + self.message = message + self.account = account + + def sign(self) -> None: + hex_signature = self.account.sign_message(self.message.encode()) + self.signature = bytes.fromhex(hex_signature) + + def to_dictionary(self) -> Dict[str, str]: + return { + "address": self.account.address.bech32(), + "message": "0x" + self.message.encode().hex(), + "signature": "0x" + self.signature.hex() + } From 68abe21d221edb4920844e79003a947ea0779647 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 2 Oct 2023 21:05:27 +0300 Subject: [PATCH 38/62] fixes after review --- multiversx_sdk_cli/cli_contracts.py | 2 +- multiversx_sdk_cli/projects/templates.py | 6 +-- .../tests/test_cli_contracts.py | 4 +- .../tests/test_cli_contracts.sh | 50 ------------------- 4 files changed, 6 insertions(+), 56 deletions(-) diff --git a/multiversx_sdk_cli/cli_contracts.py b/multiversx_sdk_cli/cli_contracts.py index 82ca633e..27be0001 100644 --- a/multiversx_sdk_cli/cli_contracts.py +++ b/multiversx_sdk_cli/cli_contracts.py @@ -39,7 +39,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: sub = cli_shared.add_command_subparser(subparsers, "contract", "templates", "List the available Smart Contract templates.") - sub.add_argument("--tag", help="the sc-meta framework version reffered to") + sub.add_argument("--tag", help="the sc-meta framework version referred to") sub.set_defaults(func=list_templates) sub = cli_shared.add_command_subparser(subparsers, "contract", "build", diff --git a/multiversx_sdk_cli/projects/templates.py b/multiversx_sdk_cli/projects/templates.py index 58cf206b..bfd9fdb2 100644 --- a/multiversx_sdk_cli/projects/templates.py +++ b/multiversx_sdk_cli/projects/templates.py @@ -21,17 +21,17 @@ def __init__(self, self.path = path def get_contract_templates(self) -> str: - self._check_if_dependencies_installed() + self._ensure_dependencies_installed() args = self._prepare_args_to_list_templates() templates = myprocess.run_process(args=args, dump_to_stdout=False) return templates def create_from_template(self) -> None: - self._check_if_dependencies_installed() + self._ensure_dependencies_installed() args = self._prepare_args_to_create_new_contract_from_template() myprocess.run_process(args) - def _check_if_dependencies_installed(self): + def _ensure_dependencies_installed(self): logger.info("Checking if the necessarry dependencies are installed.") install_module("rust") diff --git a/multiversx_sdk_cli/tests/test_cli_contracts.py b/multiversx_sdk_cli/tests/test_cli_contracts.py index 63323a97..259b1a0e 100644 --- a/multiversx_sdk_cli/tests/test_cli_contracts.py +++ b/multiversx_sdk_cli/tests/test_cli_contracts.py @@ -34,10 +34,10 @@ def test_contract_new_with_bad_code(): ]) assert Path.is_dir(parent / "testdata-out" / "SANDBOX" / "adder-bad-src") - replace_variable_with_unknown_variable() + replace_variable_with_unknown_variable_for_adder() -def replace_variable_with_unknown_variable(): +def replace_variable_with_unknown_variable_for_adder(): # this is done in order to replace the value added in the adder contract with a unknown variable with open(parent / "testdata-out" / "SANDBOX" / "adder-bad-src" / "src" / "adder_bad_src.rs", "r") as f: contract_lines = f.readlines() diff --git a/multiversx_sdk_cli/tests/test_cli_contracts.sh b/multiversx_sdk_cli/tests/test_cli_contracts.sh index 04f023f6..fe980cfe 100755 --- a/multiversx_sdk_cli/tests/test_cli_contracts.sh +++ b/multiversx_sdk_cli/tests/test_cli_contracts.sh @@ -12,13 +12,6 @@ testCreateContracts() { ${CLI} contract new --template adder --path ${SANDBOX} || return 1 ${CLI} contract new --template crypto-zombies --path ${SANDBOX} || return 1 ${CLI} contract new --template empty --path ${SANDBOX} || return 1 - - # uncomment when other contract templates are available in sc-meta - # ${CLI} contract new --template factorial --path ${SANDBOX} myfactorial-rs || return 1 - # ${CLI} contract new --template crypto-bubbles --path ${SANDBOX} mybubbles-rs || return 1 - # ${CLI} contract new --template lottery-esdt --path ${SANDBOX} mylottery-rs || return 1 - # ${CLI} contract new --template crowdfunding-esdt --path ${SANDBOX} myfunding-rs || return 1 - # ${CLI} contract new --template multisig --path ${SANDBOX} multisig-rs || return 1 } testBuildContracts() { @@ -39,30 +32,12 @@ testBuildContracts() { ${CLI} contract build --path=${SANDBOX}/empty --target-dir=${TARGET_DIR} || return 1 assertFileExists ${SANDBOX}/empty/output/empty.wasm || return 1 assertFileExists ${SANDBOX}/empty/output/empty.abi.json || return 1 - - # uncomment when other contract templates are available in sc-meta - # ${CLI} contract build --path=${SANDBOX}/myfactorial-rs --target-dir=${TARGET_DIR} || return 1 - # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 - - # ${CLI} contract build --path=${SANDBOX}/mybubbles-rs --target-dir=${TARGET_DIR} || return 1 - # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 - - # ${CLI} contract build --path=${SANDBOX}/mylottery-rs --target-dir=${TARGET_DIR} || return 1 - # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 - - # ${CLI} contract build --path=${SANDBOX}/myfunding-rs --target-dir=${TARGET_DIR} || return 1 - # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 } testRunScenarios() { echo "testRunScenarios" ${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/adder || return 1 ${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/empty || return 1 - # ${CLI} --verbose contract test --directory="scenarios" --recursive ${SANDBOX}/myfunding-rs || return 1 } testWasmName() { @@ -95,31 +70,6 @@ testCleanContracts() { ${CLI} contract clean --path ${SANDBOX}/empty || return 1 assertFileDoesNotExist ${SANDBOX}/empty/output/empty.wasm || return 1 assertFileDoesNotExist ${SANDBOX}/empty/output/empty.abi.json || return 1 - - # uncomment when other contract templates are available in sc-meta - # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 - # ${CLI} contract clean --path ${SANDBOX}/myfactorial-rs || return 1 - # assertFileDoesNotExist ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.wasm || return 1 - # assertFileDoesNotExist ${SANDBOX}/myfactorial-rs/output/myfactorial-rs.abi.json || return 1 - - # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 - # ${CLI} contract clean --path ${SANDBOX}/mybubbles-rs || return 1 - # assertFileDoesNotExist ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.wasm || return 1 - # assertFileDoesNotExist ${SANDBOX}/mybubbles-rs/output/mybubbles-rs.abi.json || return 1 - - # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 - # ${CLI} contract clean --path ${SANDBOX}/mylottery-rs || return 1 - # assertFileDoesNotExist ${SANDBOX}/mylottery-rs/output/mylottery-rs.wasm || return 1 - # assertFileDoesNotExist ${SANDBOX}/mylottery-rs/output/mylottery-rs.abi.json || return 1 - - # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 - # assertFileExists ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 - # ${CLI} contract clean --path ${SANDBOX}/myfunding-rs || return 1 - # assertFileDoesNotExist ${SANDBOX}/myfunding-rs/output/myfunding-rs.wasm || return 1 - # assertFileDoesNotExist ${SANDBOX}/myfunding-rs/output/myfunding-rs.abi.json || return 1 } testVerifyContract(){ From 8cf6e069881adc85c9b7eb1e0eb48aa5c7b37eff Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 3 Oct 2023 12:12:59 +0300 Subject: [PATCH 39/62] implement sign and verify message --- multiversx_sdk_cli/cli_wallet.py | 36 ++++++++++++- multiversx_sdk_cli/message.py | 2 +- multiversx_sdk_cli/tests/test_cli_wallet.py | 57 +++++++++++++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index a27a37ab..73489d7d 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -5,8 +5,8 @@ from pathlib import Path from typing import Any, List, Optional, Tuple -from multiversx_sdk_core import Address -from multiversx_sdk_wallet import UserSecretKey, UserWallet +from multiversx_sdk_core import Address, MessageV1 +from multiversx_sdk_wallet import UserSecretKey, UserVerifier, UserWallet from multiversx_sdk_wallet.mnemonic import Mnemonic from multiversx_sdk_wallet.user_pem import UserPEM @@ -14,6 +14,7 @@ from multiversx_sdk_cli.constants import DEFAULT_HRP from multiversx_sdk_cli.errors import KnownError from multiversx_sdk_cli.message import SignableMessage +from multiversx_sdk_cli.ux import show_critical_error, show_message logger = logging.getLogger("cli.wallet") @@ -89,6 +90,17 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: cli_shared.add_wallet_args(args, sub) sub.set_defaults(func=sign_message) + sub = cli_shared.add_command_subparser( + subparsers, + "wallet", + "verify-message", + "Verify a previously message" + ) + sub.add_argument("--bech32-address", required=True, help="the bech32 address of the signer") + sub.add_argument("--message", required=True, help="the previously signed message(readable text, as it was signed)") + sub.add_argument("--signature", required=True, help="the signature in hex format") + sub.set_defaults(func=verify_signed_message) + parser.epilog = cli_shared.build_group_epilog(subparsers) return subparsers @@ -266,3 +278,23 @@ def sign_message(args: Any): signable_message = SignableMessage(message, account) signable_message.sign() utils.dump_out_json(signable_message.to_dictionary()) + + +def verify_signed_message(args: Any): + bech32_address = args.bech32_address + verifier = UserVerifier.from_address(Address.from_bech32(bech32_address)) + + message: str = args.message + verifiable_message = MessageV1.from_string(message) + + signature: str = args.signature + if signature.startswith("0x"): + signature = signature[2:] + + verifiable_message.signature = bytes.fromhex(signature) + is_signed = verifier.verify(verifiable_message) + + if is_signed: + show_message(f"""The message "{message}" was signed by {bech32_address}""") + else: + show_critical_error(f"""The message "{message}" was NOT signed by {bech32_address}""") diff --git a/multiversx_sdk_cli/message.py b/multiversx_sdk_cli/message.py index 1fedab73..17000ac0 100644 --- a/multiversx_sdk_cli/message.py +++ b/multiversx_sdk_cli/message.py @@ -15,6 +15,6 @@ def sign(self) -> None: def to_dictionary(self) -> Dict[str, str]: return { "address": self.account.address.bech32(), - "message": "0x" + self.message.encode().hex(), + "message": self.message, "signature": "0x" + self.signature.hex() } diff --git a/multiversx_sdk_cli/tests/test_cli_wallet.py b/multiversx_sdk_cli/tests/test_cli_wallet.py index b6353fb7..0f97b609 100644 --- a/multiversx_sdk_cli/tests/test_cli_wallet.py +++ b/multiversx_sdk_cli/tests/test_cli_wallet.py @@ -239,6 +239,63 @@ def test_wallet_convert_pem_to_pubkey(capsys: Any): assert out == "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1" +def test_wallet_sign_message(capsys: Any): + message = "test" + pem = testdata_path / "alice.pem" + + return_code = main(["wallet", "sign-message", "--message", message, "--pem", str(pem)]) + out = json.loads(_read_stdout(capsys)) + + assert False if return_code else True + assert out == { + "address": "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + "message": "test", + "signature": "0x7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e" + } + + +def test_verify_previously_signed_message(capsys: Any): + message = "test" + address = "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" + signature = "0x7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e" + + return_code = main([ + "wallet", + "verify-message", + "--bech32-address", + address, + "--message", + message, + "--signature", + signature + ]) + out = _read_stdout(capsys) + + assert False if return_code else True + assert """The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""" in out + + +def test_verify_not_signed_message(capsys: Any): + message = "this message is not signed" + address = "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" + signature = "0x7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e" + + return_code = main([ + "wallet", + "verify-message", + "--bech32-address", + address, + "--message", + message, + "--signature", + signature + ]) + out = _read_stdout(capsys) + + assert False if return_code else True + assert """The message "this message is not signed" was NOT signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""" in out + + def _read_stdout_mnemonic(capsys: Any) -> str: return _read_stdout(capsys).replace("Mnemonic:", "").strip() From 8c35561141fcba6feb93e6a49f79f9a984453b27 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 3 Oct 2023 13:59:32 +0300 Subject: [PATCH 40/62] fix unit tests --- multiversx_sdk_cli/tests/test_cli_wallet.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/multiversx_sdk_cli/tests/test_cli_wallet.py b/multiversx_sdk_cli/tests/test_cli_wallet.py index 0f97b609..490b1b9f 100644 --- a/multiversx_sdk_cli/tests/test_cli_wallet.py +++ b/multiversx_sdk_cli/tests/test_cli_wallet.py @@ -269,10 +269,11 @@ def test_verify_previously_signed_message(capsys: Any): "--signature", signature ]) - out = _read_stdout(capsys) - assert False if return_code else True - assert """The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""" in out + + out = _read_stdout(capsys) + text = """The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + assert all(word in out for word in text) def test_verify_not_signed_message(capsys: Any): @@ -290,10 +291,11 @@ def test_verify_not_signed_message(capsys: Any): "--signature", signature ]) - out = _read_stdout(capsys) - assert False if return_code else True - assert """The message "this message is not signed" was NOT signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""" in out + + out = _read_stdout(capsys) + text = """The message "this message is not signed" was NOT signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + assert all(word in out for word in text) def _read_stdout_mnemonic(capsys: Any) -> str: From 96d21cf9e4f4cf925009b0a858f582c7fe129bc4 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 3 Oct 2023 15:37:01 +0300 Subject: [PATCH 41/62] remove --tag argument from mxpy deps --- CLI.md | 70 ++++++++++++++++------ CLI.md.sh | 2 + multiversx_sdk_cli/cli_deps.py | 9 +-- multiversx_sdk_cli/dependencies/modules.py | 2 +- 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/CLI.md b/CLI.md index 6b7e9c6b..089d07d6 100644 --- a/CLI.md +++ b/CLI.md @@ -85,13 +85,12 @@ usage: mxpy contract new [-h] ... Create a new Smart Contract project based on a template. -positional arguments: - name - options: - -h, --help show this help message and exit - --template TEMPLATE the template to use - --directory DIRECTORY 🗀 the parent directory of the project (default: current directory) + -h, --help show this help message and exit + --name NAME The name of the contract. If missing, the name of the template will be used. + --template TEMPLATE the template to use + --tag TAG the framework version on which the contract should be created + --path PATH the parent directory of the project (default: current directory) ``` ### Contract.Templates @@ -105,6 +104,7 @@ List the available Smart Contract templates. options: -h, --help show this help message and exit + --tag TAG the sc-meta framework version referred to ``` ### Contract.Build @@ -994,7 +994,7 @@ usage: mxpy wallet COMMAND [-h] ... Create wallet, derive secret key from mnemonic, bech32 address helpers etc. COMMANDS: - {new,convert,bech32} + {new,convert,bech32,sign-message,verify-message} OPTIONS: -h, --help show this help message and exit @@ -1005,6 +1005,8 @@ COMMANDS summary new Create a new wallet and print its mnemonic; optionally save as password-protected JSON (recommended) or PEM (not recommended) convert Convert a wallet from one format to another bech32 Helper for encoding and decoding bech32 addresses +sign-message Sign a message +verify-message Verify a previously message ``` ### Wallet.New @@ -1041,7 +1043,7 @@ options: --outfile OUTFILE path to the output file --in-format {raw-mnemonic,keystore-mnemonic,keystore-secret-key,pem} the format of the input file - --out-format {raw-mnemonic,keystore-mnemonic,keystore-secret-key,pem} + --out-format {raw-mnemonic,keystore-mnemonic,keystore-secret-key,pem,address-bech32,address-hex} the format of the output file --address-index ADDRESS_INDEX the address index, if input format is raw-mnemonic, keystore-mnemonic or pem (with multiple entries) and the output format is keystore- @@ -1067,6 +1069,44 @@ options: --encode whether to encode --decode whether to decode +``` +### Wallet.SignMessage + + +``` +$ mxpy wallet sign-message --help +usage: mxpy wallet sign-message [-h] ... + +Sign a message + +options: + -h, --help show this help message and exit + --message MESSAGE the message you want to sign + --pem PEM 🔑 the PEM file, if keyfile not provided + --pem-index PEM_INDEX 🔑 the index in the PEM file (default: 0) + --keyfile KEYFILE 🔑 a JSON keyfile, if PEM not provided + --passfile PASSFILE 🔑 a file containing keyfile's password, if keyfile provided + --ledger 🔐 bool flag for signing transaction using ledger + --ledger-account-index LEDGER_ACCOUNT_INDEX 🔐 the index of the account when using Ledger + --ledger-address-index LEDGER_ADDRESS_INDEX 🔐 the index of the address when using Ledger + --sender-username SENDER_USERNAME 🖄 the username of the sender + +``` +### Wallet.VerifyMessage + + +``` +$ mxpy wallet verify-message --help +usage: mxpy wallet verify-message [-h] ... + +Verify a previously message + +options: + -h, --help show this help message and exit + --bech32-address BECH32_ADDRESS the bech32 address of the signer + --message MESSAGE the previously signed message(readable text, as it was signed) + --signature SIGNATURE the signature in hex format + ``` ## Group **Localnet** @@ -1217,13 +1257,11 @@ usage: mxpy deps install [-h] ... Install dependencies or multiversx-sdk modules. positional arguments: - {all,llvm,clang,cpp,rust,golang,vmtools,mx_chain_go,mx_chain_proxy_go,wasm-opt,twiggy,testwallets} - the dependency to install + {all,rust,golang,vmtools,testwallets} the dependency to install options: - -h, --help show this help message and exit - --overwrite whether to overwrite an existing installation - --tag TAG the tag or version to install + -h, --help show this help message and exit + --overwrite whether to overwrite an existing installation ``` ### Dependencies.Check @@ -1236,12 +1274,10 @@ usage: mxpy deps check [-h] ... Check whether a dependency is installed. positional arguments: - {all,llvm,clang,cpp,rust,golang,vmtools,mx_chain_go,mx_chain_proxy_go,wasm-opt,twiggy,testwallets} - the dependency to check + {all,rust,golang,vmtools,testwallets} the dependency to check options: - -h, --help show this help message and exit - --tag TAG the tag or version to check + -h, --help show this help message and exit ``` ## Group **Configuration** diff --git a/CLI.md.sh b/CLI.md.sh index 7b686d87..db02f98f 100755 --- a/CLI.md.sh +++ b/CLI.md.sh @@ -70,6 +70,8 @@ generate() { command "Wallet.New" "wallet new" command "Wallet.Convert" "wallet convert" command "Wallet.Bech32" "wallet bech32" + command "Wallet.SignMessage" "wallet sign-message" + command "Wallet.VerifyMessage" "wallet verify-message" group "Localnet" "localnet" command "Localnet.Setup" "localnet setup" diff --git a/multiversx_sdk_cli/cli_deps.py b/multiversx_sdk_cli/cli_deps.py index 471e0610..095eb5ce 100644 --- a/multiversx_sdk_cli/cli_deps.py +++ b/multiversx_sdk_cli/cli_deps.py @@ -20,7 +20,6 @@ def setup_parser(subparsers: Any) -> Any: sub = cli_shared.add_command_subparser(subparsers, "deps", "check", "Check whether a dependency is installed.") sub.add_argument("name", choices=choices, help="the dependency to check") - sub.add_argument("--tag", help="the tag or version to check") sub.set_defaults(func=check) parser.epilog = cli_shared.build_group_epilog(subparsers) @@ -35,18 +34,16 @@ def install(args: Any): def check(args: Any): name: str = args.name - tag: str = args.tag module = dependencies.get_module_by_key(name) - default_tag: str = config.get_dependency_tag(module.key) - tag_to_check = tag or default_tag + tag_to_check: str = config.get_dependency_tag(module.key) resolution: str = config.get_dependency_resolution(module.key) resolution = resolution if resolution else "HOST" - logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}; default tag = {default_tag}, resolution = {resolution}") + logger.info(f"Checking dependency: module = {module.key}, tag = {tag_to_check}, resolution = {resolution}") installed = module.is_installed(tag_to_check) if installed: - logger.info(f"[{name} {tag_to_check}] is installed. Default version (tag) is [{default_tag}].") + logger.info(f"[{name} {tag_to_check}] is installed.") return raise errors.DependencyMissing(name, tag_to_check) diff --git a/multiversx_sdk_cli/dependencies/modules.py b/multiversx_sdk_cli/dependencies/modules.py index 19224462..a9a6dc16 100644 --- a/multiversx_sdk_cli/dependencies/modules.py +++ b/multiversx_sdk_cli/dependencies/modules.py @@ -129,7 +129,7 @@ def _get_download_url(self, tag: str) -> str: platform = workstation.get_platform() url = config.get_dependency_url(self.key, tag, platform) - if url is None: + if not url: raise errors.PlatformNotSupported(self.key, platform) url = url.replace("{TAG}", tag) From c0b710ce0decc39034c5a4567c942b60ed5c68ac Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 5 Oct 2023 15:17:51 +0300 Subject: [PATCH 42/62] fixes after review --- multiversx_sdk_cli/cli_wallet.py | 34 ++++++++------------ multiversx_sdk_cli/message.py | 35 ++++++++++++++++----- multiversx_sdk_cli/tests/test_cli_wallet.py | 8 ++--- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index 73489d7d..eb6d676e 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -5,15 +5,15 @@ from pathlib import Path from typing import Any, List, Optional, Tuple -from multiversx_sdk_core import Address, MessageV1 -from multiversx_sdk_wallet import UserSecretKey, UserVerifier, UserWallet +from multiversx_sdk_core import Address +from multiversx_sdk_wallet import UserSecretKey, UserWallet from multiversx_sdk_wallet.mnemonic import Mnemonic from multiversx_sdk_wallet.user_pem import UserPEM from multiversx_sdk_cli import cli_shared, utils from multiversx_sdk_cli.constants import DEFAULT_HRP from multiversx_sdk_cli.errors import KnownError -from multiversx_sdk_cli.message import SignableMessage +from multiversx_sdk_cli.message import SignedMessage, sign_message from multiversx_sdk_cli.ux import show_critical_error, show_message logger = logging.getLogger("cli.wallet") @@ -88,7 +88,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: ) sub.add_argument("--message", required=True, help="the message you want to sign") cli_shared.add_wallet_args(args, sub) - sub.set_defaults(func=sign_message) + sub.set_defaults(func=sign_user_message) sub = cli_shared.add_command_subparser( subparsers, @@ -96,7 +96,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: "verify-message", "Verify a previously message" ) - sub.add_argument("--bech32-address", required=True, help="the bech32 address of the signer") + sub.add_argument("--address", required=True, help="the bech32 address of the signer") sub.add_argument("--message", required=True, help="the previously signed message(readable text, as it was signed)") sub.add_argument("--signature", required=True, help="the signature in hex format") sub.set_defaults(func=verify_signed_message) @@ -272,29 +272,21 @@ def do_bech32(args: Any): return result -def sign_message(args: Any): +def sign_user_message(args: Any): message: str = args.message account = cli_shared.prepare_account(args) - signable_message = SignableMessage(message, account) - signable_message.sign() - utils.dump_out_json(signable_message.to_dictionary()) + signed_message = sign_message(message, account) + utils.dump_out_json(signed_message.to_dictionary()) def verify_signed_message(args: Any): - bech32_address = args.bech32_address - verifier = UserVerifier.from_address(Address.from_bech32(bech32_address)) - + bech32_address = args.address message: str = args.message - verifiable_message = MessageV1.from_string(message) - signature: str = args.signature - if signature.startswith("0x"): - signature = signature[2:] - - verifiable_message.signature = bytes.fromhex(signature) - is_signed = verifier.verify(verifiable_message) + signed_message = SignedMessage(bech32_address, message, signature) + is_signed = signed_message.verify_signature() if is_signed: - show_message(f"""The message "{message}" was signed by {bech32_address}""") + show_message(f"""SUCCESS: The message "{message}" was signed by {bech32_address}""") else: - show_critical_error(f"""The message "{message}" was NOT signed by {bech32_address}""") + show_critical_error(f"""FAILED: The message "{message}" was NOT signed by {bech32_address}""") diff --git a/multiversx_sdk_cli/message.py b/multiversx_sdk_cli/message.py index 17000ac0..6e893620 100644 --- a/multiversx_sdk_cli/message.py +++ b/multiversx_sdk_cli/message.py @@ -1,20 +1,39 @@ from typing import Dict +from multiversx_sdk_core import Address, MessageV1 +from multiversx_sdk_wallet import UserVerifier + from multiversx_sdk_cli.accounts import Account -class SignableMessage: - def __init__(self, message: str, account: Account) -> None: +class SignedMessage: + def __init__(self, address: str, message: str, signature: str) -> None: + self.address = address self.message = message - self.account = account - def sign(self) -> None: - hex_signature = self.account.sign_message(self.message.encode()) - self.signature = bytes.fromhex(hex_signature) + hex_prefixes = ["0x", "0X"] + signature_start_sequence = signature[0:2] + + if signature_start_sequence in hex_prefixes: + signature = signature[2:] + + self.signature = signature + + def verify_signature(self) -> bool: + verifier = UserVerifier.from_address(Address.from_bech32(self.address)) + verifiable_message = MessageV1.from_string(self.message) + verifiable_message.signature = bytes.fromhex(self.signature) + is_signed = verifier.verify(verifiable_message) + return is_signed def to_dictionary(self) -> Dict[str, str]: return { - "address": self.account.address.bech32(), + "address": self.address, "message": self.message, - "signature": "0x" + self.signature.hex() + "signature": "0x" + self.signature } + + +def sign_message(message: str, account: Account) -> SignedMessage: + signature = account.sign_message(message.encode()) + return SignedMessage(account.address.bech32(), message, signature) diff --git a/multiversx_sdk_cli/tests/test_cli_wallet.py b/multiversx_sdk_cli/tests/test_cli_wallet.py index 490b1b9f..aef3bf74 100644 --- a/multiversx_sdk_cli/tests/test_cli_wallet.py +++ b/multiversx_sdk_cli/tests/test_cli_wallet.py @@ -262,7 +262,7 @@ def test_verify_previously_signed_message(capsys: Any): return_code = main([ "wallet", "verify-message", - "--bech32-address", + "--address", address, "--message", message, @@ -272,7 +272,7 @@ def test_verify_previously_signed_message(capsys: Any): assert False if return_code else True out = _read_stdout(capsys) - text = """The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + text = """SUCCESS: The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() assert all(word in out for word in text) @@ -284,7 +284,7 @@ def test_verify_not_signed_message(capsys: Any): return_code = main([ "wallet", "verify-message", - "--bech32-address", + "--address", address, "--message", message, @@ -294,7 +294,7 @@ def test_verify_not_signed_message(capsys: Any): assert False if return_code else True out = _read_stdout(capsys) - text = """The message "this message is not signed" was NOT signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + text = """FAILED: The message "this message is not signed" was NOT signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() assert all(word in out for word in text) From cd2b0cdeec8cb4a9c895405e5ddcfc97cd8468d7 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 5 Oct 2023 15:18:47 +0300 Subject: [PATCH 43/62] rename file --- multiversx_sdk_cli/cli_wallet.py | 2 +- multiversx_sdk_cli/{message.py => sign_verify.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename multiversx_sdk_cli/{message.py => sign_verify.py} (100%) diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index eb6d676e..e48416c8 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -13,7 +13,7 @@ from multiversx_sdk_cli import cli_shared, utils from multiversx_sdk_cli.constants import DEFAULT_HRP from multiversx_sdk_cli.errors import KnownError -from multiversx_sdk_cli.message import SignedMessage, sign_message +from multiversx_sdk_cli.sign_verify import SignedMessage, sign_message from multiversx_sdk_cli.ux import show_critical_error, show_message logger = logging.getLogger("cli.wallet") diff --git a/multiversx_sdk_cli/message.py b/multiversx_sdk_cli/sign_verify.py similarity index 100% rename from multiversx_sdk_cli/message.py rename to multiversx_sdk_cli/sign_verify.py From 6963397f08ad46cbe24569140cf43957e5b02bda Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 10 Oct 2023 16:20:34 +0300 Subject: [PATCH 44/62] fix typo --- multiversx_sdk_cli/cli_wallet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index e48416c8..e9cd9a34 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -94,7 +94,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: subparsers, "wallet", "verify-message", - "Verify a previously message" + "Verify a previously signed message" ) sub.add_argument("--address", required=True, help="the bech32 address of the signer") sub.add_argument("--message", required=True, help="the previously signed message(readable text, as it was signed)") From 7ed05f54d2f2a44bdd592316a4d8abc68664dd1b Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 10 Oct 2023 16:58:41 +0300 Subject: [PATCH 45/62] re-generate CLI.md --- CLI.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CLI.md b/CLI.md index 089d07d6..178324a6 100644 --- a/CLI.md +++ b/CLI.md @@ -1006,7 +1006,7 @@ new Create a new wallet and print its mnemonic; optio convert Convert a wallet from one format to another bech32 Helper for encoding and decoding bech32 addresses sign-message Sign a message -verify-message Verify a previously message +verify-message Verify a previously signed message ``` ### Wallet.New @@ -1099,13 +1099,13 @@ options: $ mxpy wallet verify-message --help usage: mxpy wallet verify-message [-h] ... -Verify a previously message +Verify a previously signed message options: - -h, --help show this help message and exit - --bech32-address BECH32_ADDRESS the bech32 address of the signer - --message MESSAGE the previously signed message(readable text, as it was signed) - --signature SIGNATURE the signature in hex format + -h, --help show this help message and exit + --address ADDRESS the bech32 address of the signer + --message MESSAGE the previously signed message(readable text, as it was signed) + --signature SIGNATURE the signature in hex format ``` ## Group **Localnet** From 227b4d75dd30d1ee895b84c6dfeb1f374e049494 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 13 Oct 2023 16:19:46 +0300 Subject: [PATCH 46/62] fix type of pem index parameter --- multiversx_sdk_cli/cli_shared.py | 4 +- multiversx_sdk_cli/tests/test_cli_wallet.py | 68 +++++++++++++++++++ .../tests/testdata/multiple_addresses.pem | 15 ++++ 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 multiversx_sdk_cli/tests/testdata/multiple_addresses.pem diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index 75fa665d..d6f87eb9 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -100,7 +100,7 @@ def add_guardian_args(sub: Any): def add_wallet_args(args: List[str], sub: Any): sub.add_argument("--pem", required=check_if_sign_method_required(args, "--pem"), help="🔑 the PEM file, if keyfile not provided") - sub.add_argument("--pem-index", default=0, help="🔑 the index in the PEM file (default: %(default)s)") + sub.add_argument("--pem-index", type=int, default=0, help="🔑 the index in the PEM file (default: %(default)s)") sub.add_argument("--keyfile", required=check_if_sign_method_required(args, "--keyfile"), help="🔑 a JSON keyfile, if PEM not provided") sub.add_argument("--passfile", help="🔑 a file containing keyfile's password, if keyfile provided") sub.add_argument("--ledger", action="store_true", required=check_if_sign_method_required(args, "--ledger"), default=False, help="🔐 bool flag for signing transaction using ledger") @@ -111,7 +111,7 @@ def add_wallet_args(args: List[str], sub: Any): def add_guardian_wallet_args(args: List[str], sub: Any): sub.add_argument("--guardian-pem", required=check_if_sign_method_required(args, "--guardian-pem"), help="🔑 the PEM file, if keyfile not provided") - sub.add_argument("--guardian-pem-index", default=0, help="🔑 the index in the PEM file (default: %(default)s)") + sub.add_argument("--guardian-pem-index", type=int, default=0, help="🔑 the index in the PEM file (default: %(default)s)") sub.add_argument("--guardian-keyfile", required=check_if_sign_method_required(args, "--guardian-keyfile"), help="🔑 a JSON keyfile, if PEM not provided") sub.add_argument("--guardian-passfile", help="🔑 a file containing keyfile's password, if keyfile provided") sub.add_argument("--guardian-ledger", action="store_true", required=check_if_sign_method_required(args, "--guardian-ledger"), default=False, help="🔐 bool flag for signing transaction using ledger") diff --git a/multiversx_sdk_cli/tests/test_cli_wallet.py b/multiversx_sdk_cli/tests/test_cli_wallet.py index aef3bf74..2e495382 100644 --- a/multiversx_sdk_cli/tests/test_cli_wallet.py +++ b/multiversx_sdk_cli/tests/test_cli_wallet.py @@ -298,6 +298,74 @@ def test_verify_not_signed_message(capsys: Any): assert all(word in out for word in text) +def test_sign_and_verify_message_with_multi_address_pem(capsys: Any): + multi_address_pem_path = testdata_path / "multiple_addresses.pem" + message = "test" + + return_code = main(["wallet", "sign-message", "--message", message, "--pem", str(multi_address_pem_path), "--pem-index", "0"]) + out = json.loads(_read_stdout(capsys)) + + assert False if return_code else True + assert out == { + "address": "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + "message": "test", + "signature": "0x7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e" + } + + return_code = main(["wallet", "verify-message", + "--address", "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + "--message", message, + "--signature", "0x7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e" + ]) + assert False if return_code else True + + out = _read_stdout(capsys) + text = """SUCCESS: The message "test" was signed by erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th""".split() + assert all(word in out for word in text) + + return_code = main(["wallet", "sign-message", "--message", message, "--pem", str(multi_address_pem_path), "--pem-index", "1"]) + out = json.loads(_read_stdout(capsys)) + + assert False if return_code else True + assert out == { + "address": "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx", + "message": "test", + "signature": "0x50024bd755f8801e4ffbe76f93e6b8d82220673981cc44952a52bbfa02d262020ce933a2216e0e16e838dc5691f5701a1e0c250279cdae29268344d1523ea805" + } + + return_code = main(["wallet", "verify-message", + "--address", "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx", + "--message", message, + "--signature", "0x50024bd755f8801e4ffbe76f93e6b8d82220673981cc44952a52bbfa02d262020ce933a2216e0e16e838dc5691f5701a1e0c250279cdae29268344d1523ea805" + ]) + assert False if return_code else True + + out = _read_stdout(capsys) + text = """SUCCESS: The message "test" was signed by erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx""".split() + assert all(word in out for word in text) + + return_code = main(["wallet", "sign-message", "--message", message, "--pem", str(multi_address_pem_path), "--pem-index", "2"]) + out = json.loads(_read_stdout(capsys)) + + assert False if return_code else True + assert out == { + "address": "erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8", + "message": "test", + "signature": "0x99dd1ebf2bf47a7cb99f362d2458b5c83c727686517c97c877babeb8be7f840c543785edf2f9688a1fc2c076b0887d8ee6d2be7b181bba4dc3984a4ee406fa0f" + } + + return_code = main(["wallet", "verify-message", + "--address", "erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8", + "--message", message, + "--signature", "0x99dd1ebf2bf47a7cb99f362d2458b5c83c727686517c97c877babeb8be7f840c543785edf2f9688a1fc2c076b0887d8ee6d2be7b181bba4dc3984a4ee406fa0f" + ]) + assert False if return_code else True + + out = _read_stdout(capsys) + text = """SUCCESS: The message "test" was signed by erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8""".split() + assert all(word in out for word in text) + + def _read_stdout_mnemonic(capsys: Any) -> str: return _read_stdout(capsys).replace("Mnemonic:", "").strip() diff --git a/multiversx_sdk_cli/tests/testdata/multiple_addresses.pem b/multiversx_sdk_cli/tests/testdata/multiple_addresses.pem new file mode 100644 index 00000000..c8e708ef --- /dev/null +++ b/multiversx_sdk_cli/tests/testdata/multiple_addresses.pem @@ -0,0 +1,15 @@ +-----BEGIN PRIVATE KEY for erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th----- +NDEzZjQyNTc1ZjdmMjZmYWQzMzE3YTc3ODc3MTIxMmZkYjgwMjQ1ODUwOTgxZTQ4 +YjU4YTRmMjVlMzQ0ZThmOTAxMzk0NzJlZmY2ODg2NzcxYTk4MmYzMDgzZGE1ZDQy +MWYyNGMyOTE4MWU2Mzg4ODIyOGRjODFjYTYwZDY5ZTE= +-----END PRIVATE KEY for erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th----- +-----BEGIN PRIVATE KEY for erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx----- +YjhjYTZmODIwM2ZiNGI1NDVhOGU4M2M1Mzg0ZGEwMzNjNDE1ZGIxNTViNTNmYjVi +OGViYTdmZjVhMDM5ZDYzOTgwNDlkNjM5ZTVhNjk4MGQxY2QyMzkyYWJjY2U0MTAy +OWNkYTc0YTE1NjM1MjNhMjAyZjA5NjQxY2MyNjE4Zjg= +-----END PRIVATE KEY for erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx----- +-----BEGIN PRIVATE KEY for erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8----- +ZTI1M2E1NzFjYTE1M2RjMmFlZTg0NTgxOWY3NGJjYzk3NzNiMDU4NmVkZWFkMTVh +OTRjYjcyMzVhNTAyNzQzNmIyYTExNTU1Y2U1MjFlNDk0NGUwOWFiMTc1NDlkODVi +NDg3ZGNkMjZjODRiNTAxN2EzOWUzMWEzNjcwODg5YmE= +-----END PRIVATE KEY for erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8----- From c0db6ed86b90e54a94adf1cfd5f7021c2bbcc9c6 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 13 Oct 2023 17:53:54 +0300 Subject: [PATCH 47/62] fix test --- multiversx_sdk_cli/tests/test_cli_validators.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multiversx_sdk_cli/tests/test_cli_validators.sh b/multiversx_sdk_cli/tests/test_cli_validators.sh index 69db881c..dad1eb52 100755 --- a/multiversx_sdk_cli/tests/test_cli_validators.sh +++ b/multiversx_sdk_cli/tests/test_cli_validators.sh @@ -9,7 +9,7 @@ testAll() { echo "Stake with recall nonce" ${CLI} --verbose validator stake --pem="${USERS}/alice.pem" --value="2500${DENOMINATION}" --validators-file=./testdata/validators.json --reward-address=${REWARD_ADDRESS} --chain=${CHAIN_ID} --proxy=${PROXY} --estimate-gas --recall-nonce --send || return 1 echo "Stake with provided nonce" - ${CLI} --verbose validator stake --pem="${USERS}/bob.pem" --value="2500${DENOMINATION}" --validators-file=./testdata/validators.json --reward-address=${REWARD_ADDRESS} --chain=${CHAIN_ID} --proxy=${PROXY} --estimate-gas --nonce=5000 --send || return 1 + ${CLI} --verbose validator stake --pem="${USERS}/bob.pem" --value="2500${DENOMINATION}" --validators-file=./testdata/validators.json --reward-address=${REWARD_ADDRESS} --chain=${CHAIN_ID} --proxy=${PROXY} --estimate-gas --nonce=300 --send || return 1 echo "Stake with topUP" From 226de8498d8811434921656404dda33cb31a4257 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 16 Oct 2023 15:09:22 +0300 Subject: [PATCH 48/62] smart contract projects cleanup --- CLI.md | 4 +- multiversx_sdk_cli/cli_contracts.py | 2 +- multiversx_sdk_cli/projects/__init__.py | 6 +- multiversx_sdk_cli/projects/core.py | 29 +--- multiversx_sdk_cli/projects/project_clang.py | 158 ------------------- multiversx_sdk_cli/projects/project_cpp.py | 114 ------------- multiversx_sdk_cli/projects/project_rust.py | 132 +--------------- multiversx_sdk_cli/projects/project_sol.py | 21 --- multiversx_sdk_cli/projects/shared.py | 40 ----- 9 files changed, 6 insertions(+), 500 deletions(-) delete mode 100644 multiversx_sdk_cli/projects/project_clang.py delete mode 100644 multiversx_sdk_cli/projects/project_cpp.py delete mode 100644 multiversx_sdk_cli/projects/project_sol.py diff --git a/CLI.md b/CLI.md index 178324a6..47628693 100644 --- a/CLI.md +++ b/CLI.md @@ -64,7 +64,7 @@ COMMANDS summary ---------------- new Create a new Smart Contract project based on a template. templates List the available Smart Contract templates. -build Build a Smart Contract project using the appropriate buildchain. +build Build a Smart Contract project. clean Clean a Smart Contract project. test Run scenarios (tests). report Print a detailed report of the smart contracts. @@ -114,7 +114,7 @@ options: $ mxpy contract build --help usage: mxpy contract build [-h] ... -Build a Smart Contract project using the appropriate buildchain. +Build a Smart Contract project. options: -h, --help show this help message and exit diff --git a/multiversx_sdk_cli/cli_contracts.py b/multiversx_sdk_cli/cli_contracts.py index 27be0001..0c7325d2 100644 --- a/multiversx_sdk_cli/cli_contracts.py +++ b/multiversx_sdk_cli/cli_contracts.py @@ -43,7 +43,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any: sub.set_defaults(func=list_templates) sub = cli_shared.add_command_subparser(subparsers, "contract", "build", - "Build a Smart Contract project using the appropriate buildchain.") + "Build a Smart Contract project.") _add_build_options_sc_meta(sub) sub.set_defaults(func=build) diff --git a/multiversx_sdk_cli/projects/__init__.py b/multiversx_sdk_cli/projects/__init__.py index 0607f0cd..db23619f 100644 --- a/multiversx_sdk_cli/projects/__init__.py +++ b/multiversx_sdk_cli/projects/__init__.py @@ -1,12 +1,8 @@ from multiversx_sdk_cli.projects.core import (build_project, clean_project, - get_projects_in_workspace, load_project, run_tests) from multiversx_sdk_cli.projects.project_base import Project -from multiversx_sdk_cli.projects.project_clang import ProjectClang -from multiversx_sdk_cli.projects.project_cpp import ProjectCpp from multiversx_sdk_cli.projects.project_rust import ProjectRust -from multiversx_sdk_cli.projects.project_sol import ProjectSol from multiversx_sdk_cli.projects.report.do_report import do_report from multiversx_sdk_cli.projects.templates import Contract -__all__ = ["build_project", "clean_project", "do_report", "run_tests", "get_projects_in_workspace", "load_project", "Project", "ProjectClang", "ProjectCpp", "ProjectRust", "ProjectSol", "Contract"] +__all__ = ["build_project", "clean_project", "do_report", "run_tests", "load_project", "Project", "ProjectRust", "Contract"] diff --git a/multiversx_sdk_cli/projects/core.py b/multiversx_sdk_cli/projects/core.py index a9cffb88..ebba16e6 100644 --- a/multiversx_sdk_cli/projects/core.py +++ b/multiversx_sdk_cli/projects/core.py @@ -2,15 +2,12 @@ from pathlib import Path from typing import Any, List -from multiversx_sdk_cli import dependencies, errors, guards, utils +from multiversx_sdk_cli import dependencies, errors, guards from multiversx_sdk_cli.projects import shared from multiversx_sdk_cli.projects.constants import (OLD_PROJECT_CONFIG_FILENAME, PROJECT_CONFIG_FILENAME) from multiversx_sdk_cli.projects.project_base import Project -from multiversx_sdk_cli.projects.project_clang import ProjectClang -from multiversx_sdk_cli.projects.project_cpp import ProjectCpp from multiversx_sdk_cli.projects.project_rust import ProjectRust -from multiversx_sdk_cli.projects.project_sol import ProjectSol logger = logging.getLogger("projects.core") @@ -18,12 +15,6 @@ def load_project(directory: Path) -> Project: guards.is_directory(directory) - if shared.is_source_clang(directory): - return ProjectClang(directory) - if shared.is_source_cpp(directory): - return ProjectCpp(directory) - if shared.is_source_sol(directory): - return ProjectSol(directory) if shared.is_source_rust(directory): return ProjectRust(directory) else: @@ -35,7 +26,6 @@ def build_project(directory: Path, args: List[str]): logger.info("build_project.directory: %s", directory) - guards.is_directory(directory) project = load_project(directory) outputs = project.build(args) logger.info("Build ran.") @@ -65,23 +55,6 @@ def run_tests(project_path: Path, args: Any): project.run_tests(directory, wildcard) -def get_projects_in_workspace(workspace: Path) -> List[Project]: - guards.is_directory(workspace) - subfolders = utils.get_subfolders(workspace) - projects = [] - - for folder in subfolders: - project_directory = workspace / folder - - try: - project = load_project(project_directory) - projects.append(project) - except Exception: - pass - - return projects - - def get_project_paths_recursively(base_path: Path) -> List[Path]: guards.is_directory(base_path) old_markers = list(base_path.glob(f"**/{OLD_PROJECT_CONFIG_FILENAME}")) diff --git a/multiversx_sdk_cli/projects/project_clang.py b/multiversx_sdk_cli/projects/project_clang.py deleted file mode 100644 index 1b800b7c..00000000 --- a/multiversx_sdk_cli/projects/project_clang.py +++ /dev/null @@ -1,158 +0,0 @@ -import logging -import subprocess -from os import path -from pathlib import Path -from typing import List - -from multiversx_sdk_cli import dependencies, errors, myprocess, utils -from multiversx_sdk_cli.projects.project_base import Project, rename_wasm_files -from multiversx_sdk_cli.projects.shared import \ - check_clang_and_cpp_dependencies_installed - -logger = logging.getLogger('ProjectClang') - - -class ProjectClang(Project): - - def __init__(self, directory: Path): - super().__init__(directory) - - def perform_build(self): - self.config = self.load_config() - self.ensure_source_files() - - self.unit = self.get_unit_file() - self.file_ll = self.unit.with_suffix('.ll') - self.file_o = self.unit.with_suffix('.o') - self.file_export = self.unit.with_suffix('.export') - self.file_output = self.unit.with_suffix('.wasm') - - try: - check_clang_and_cpp_dependencies_installed() - - self.do_clang() - self.do_llvm_link() - self.do_llc() - self.do_wasm() - except subprocess.CalledProcessError as err: - raise errors.BuildError(err.output) - - def do_clang(self): - logger.info('do_clang') - - tool = path.join(self._get_llvm_path(), 'clang-9') - args = [ - tool, - '-cc1', '-emit-llvm', - '-triple=wasm32-unknown-unknown-wasm', - ] - - if self.options.get('optimized', False): - args.append('-Ofast') - else: - args.append('-O0') - - args.extend(map(str, self.get_source_files())) - myprocess.run_process(args) - - def do_llvm_link(self): - logger.info('do_llvm_link') - tool = path.join(self._get_llvm_path(), 'llvm-link') - args = [tool] - args.extend(['-o', str(self.file_ll)]) - args.extend(map(str, self.get_ll_files())) - myprocess.run_process(args) - - def do_llc(self): - logger.info('do_llc') - tool = path.join(self._get_llvm_path(), 'llc') - args = [tool] - - if self.options.get('optimized', False): - args.append('-O3') - else: - args.append('-O0') - - args.append('-filetype=obj') - args.append(str(self.file_ll)) - - args.extend(['-o', str(self.file_o)]) - myprocess.run_process(args) - - def do_wasm(self): - logger.info('do_wasm') - tool = path.join(self._get_llvm_path(), 'wasm-ld') - args = [ - tool, - '--no-entry', - str(self.file_o), - '-o', str(self.file_output), - '--strip-all', - '-allow-undefined' - ] - - if self.options.get('verbose', False): - args.append('--verbose') - - logger.info('exported functions:') - for export in self.get_exported_functions(): - logger.info(f'\t{export}') - args.append(f'-export={export}') - - myprocess.run_process(args) - - def _do_after_build_custom(self) -> List[Path]: - output_wasm_file = self._copy_to_output(self.file_output) - self.file_output.unlink() - self.file_ll.unlink() - self.file_o.unlink() - for ll_file in self.get_ll_files(): - try: - ll_file.unlink() - except FileNotFoundError: - pass - - paths = rename_wasm_files([output_wasm_file], self.options.get("wasm-name")) - return paths - - def _get_llvm_path(self): - return dependencies.get_module_directory('llvm') - - def get_source_files(self): - for filename in self.config['source_files']: - yield (self.path / filename).expanduser().resolve() - - def get_ll_files(self): - for source_file in self.get_source_files(): - yield source_file.with_suffix('.ll') - - def get_unit_file(self): - first_file = next(self.get_source_files()) - return first_file - - def ensure_source_files(self): - try: - source_files = self.config['source_files'] - if len(source_files) == 0: - source_files = self.get_source_files_from_folder() - except KeyError: - source_files = self.get_source_files_from_folder() - - self.config['source_files'] = source_files - - def get_exported_functions(self) -> List[str]: - file_export = self.find_file_globally('*.export') - lines = utils.read_lines(file_export) - return lines - - def default_config(self): - config = super().default_config() - config['language'] = 'clang' - config['source_files'] = self.get_source_files_from_folder() - return config - - def get_source_files_from_folder(self): - return list(map(str, self.path.rglob('*.c'))) - - def get_dependencies(self): - return [""] diff --git a/multiversx_sdk_cli/projects/project_cpp.py b/multiversx_sdk_cli/projects/project_cpp.py deleted file mode 100644 index eb2dafef..00000000 --- a/multiversx_sdk_cli/projects/project_cpp.py +++ /dev/null @@ -1,114 +0,0 @@ -import logging -import os -import subprocess -from os import path -from pathlib import Path -from typing import List - -from multiversx_sdk_cli import dependencies, errors, myprocess, utils -from multiversx_sdk_cli.projects.project_base import Project, rename_wasm_files -from multiversx_sdk_cli.projects.shared import \ - check_clang_and_cpp_dependencies_installed - -logger = logging.getLogger("ProjectCpp") - - -class ProjectCpp(Project): - def __init__(self, directory: Path): - super().__init__(directory) - - def perform_build(self): - self.build_configuration = CppBuildConfiguration(self, self.debug) - self.unit = self.find_file_globally("*.cpp") - self.file_ll = self.unit.with_suffix(".ll") - self.file_o = self.unit.with_suffix(".o") - self.file_export = self.unit.with_suffix(".export") - - try: - check_clang_and_cpp_dependencies_installed() - - self._do_clang() - self._do_llc() - self._do_wasm() - except subprocess.CalledProcessError as err: - raise errors.BuildError(err.output) - - def _do_clang(self): - logger.info("_do_clang") - tool = path.join(self._get_llvm_path(), "clang-9") - args = [ - tool, - "-cc1", "-emit-llvm", - "-triple=wasm32-unknown-unknown-wasm", - "-ObjC++", - "-std=c++17", - "-nostdinc++", - "-nobuiltininc", - "-fno-builtin", - ] - if self.options.get("optimized", False): - args.append("-Ofast") - else: - args.append("-O0") - args.append(str(self.unit)) - myprocess.run_process(args) - - def _do_llc(self): - logger.info("_do_llc") - tool = path.join(self._get_llvm_path(), "llc") - args = [tool] - if self.options.get("optimized", False): - args.append("-O3") - else: - args.append("-O0") - args.extend(["-filetype=obj", self.file_ll, "-o", self.file_o]) - myprocess.run_process(args) - - def _do_wasm(self): - logger.info("_do_wasm") - tool = path.join(self._get_llvm_path(), "wasm-ld") - args = [ - tool, - "--no-entry", - str(self.file_o), - "-o", self.find_file_globally("*.cpp").with_suffix(".wasm"), - "--strip-all", - "--allow-undefined", - "--demangle" - ] - - if self.options.get("verbose", False): - args.append("--verbose") - - for export in self.build_configuration.exports: - args.append(f"-export={export}") - - myprocess.run_process(args) - - def _do_after_build_custom(self) -> List[Path]: - source_file = self.find_file_globally("*.cpp") - output_wasm_file = self._copy_to_output(source_file.with_suffix(".wasm")) - os.remove(source_file.with_suffix(".wasm")) - os.remove(source_file.with_suffix(".ll")) - os.remove(source_file.with_suffix(".o")) - - paths = rename_wasm_files([output_wasm_file], self.options.get("wasm-name")) - return paths - - def _get_llvm_path(self): - return dependencies.get_module_directory("llvm") - - def get_dependencies(self): - return [""] - - -class CppBuildConfiguration: - def __init__(self, project: Project, debug): - self.project = project - self.debug = debug - self.exports = self._get_exports() - - def _get_exports(self): - file_export = self.project.find_file_globally("*.export") - lines = utils.read_lines(file_export) - return lines diff --git a/multiversx_sdk_cli/projects/project_rust.py b/multiversx_sdk_cli/projects/project_rust.py index cc837eb1..7825d5d6 100644 --- a/multiversx_sdk_cli/projects/project_rust.py +++ b/multiversx_sdk_cli/projects/project_rust.py @@ -1,7 +1,7 @@ import logging import subprocess from pathlib import Path -from typing import Any, Dict, List, Set, cast +from typing import Any, Dict, List from multiversx_sdk_cli import dependencies, errors, utils, workstation from multiversx_sdk_cli.constants import DEFAULT_CARGO_TARGET_DIR_NAME @@ -14,7 +14,6 @@ class ProjectRust(Project): def __init__(self, directory: Path): super().__init__(directory) - self.cargo_file = self.get_cargo_file() def clean(self): env = self.get_env() @@ -29,10 +28,6 @@ def clean(self): subprocess.check_call(args, env=env) - def get_cargo_file(self): - cargo_path = self.path / 'Cargo.toml' - return CargoFile(cargo_path) - def get_meta_folder(self): return self.path / 'meta' @@ -91,21 +86,7 @@ def get_abi_filepath(self): def get_abi_folder(self): return Path(self.directory, "abi") - def get_wasm_default_name(self, suffix: str = "") -> str: - return f"{self.cargo_file.package_name}{suffix}.wasm" - def _do_after_build_custom(self) -> List[Path]: - if not self.has_meta(): - base_name = str(self.cargo_file.package_name) - temporary_wasm_base_name = base_name.replace("-", "_") - wasm_file = self.get_wasm_path(f"{temporary_wasm_base_name}_wasm.wasm") - wasm_file.rename(self.get_wasm_default_path()) - - if self.has_abi(): - abi_file = self.get_abi_filepath() - abi_file_renamed = Path(self.get_output_folder(), f"{base_name}.abi.json") - abi_file.rename(abi_file_renamed) - outputs = [self.get_wasm_default_path()] if self.has_wasm_view(): outputs.append(self.get_wasm_view_default_path()) @@ -140,114 +121,3 @@ def build_wasm_with_debug_symbols(self, build_options: Dict[str, Any]): subprocess.check_call(args, env=env, cwd=cwd) except subprocess.CalledProcessError as err: raise errors.BuildError(f"error code = {err.returncode}, see output") - - -class CargoFile: - data: Dict[str, Any] - - def __init__(self, path: Path): - self.data = {} - self.path = path - - try: - self._parse_file() - except Exception as err: - raise errors.BuildError("Can't read or parse [Cargo.toml] file", err) - - def _parse_file(self): - self.data = utils.read_toml_file(self.path) - - @property - def package_name(self): - return self._get_package().get("name") - - @package_name.setter - def package_name(self, value): - self._get_package().update({"name": value}) - - @property - def version(self): - return self._get_package().get("version") - - @version.setter - def version(self, value): - self._get_package().update({"version": value}) - - @property - def authors(self): - return self._get_package().get("authors") - - @authors.setter - def authors(self, value): - self._get_package().update({"authors": value}) - - @property - def edition(self): - return self._get_package().get("edition") - - @edition.setter - def edition(self, value): - self._get_package().update({"edition": value}) - - @property - def publish(self): - return self._get_package().get("publish") - - @publish.setter - def publish(self, value): - self._get_package().update({"publish": value}) - - def save(self): - utils.write_toml_file(self.path, self.data) - - def _get_package(self) -> Dict[str, Any]: - if "package" not in self.data: - self.data["package"] = {} - package = cast(Dict[str, Any], self.data['package']) - return package - - def get_dependencies(self) -> Dict[str, Any]: - if "dependencies" not in self.data: - self.data["dependencies"] = {} - dependencies = cast(Dict[str, Any], self.data['dependencies']) - return dependencies - - def get_dev_dependencies(self) -> Dict[str, Any]: - if "dev-dependencies" not in self.data: - self.data["dev-dependencies"] = {} - dev_dependencies = cast(Dict[str, Any], self.data['dev-dependencies']) - return dev_dependencies - - def get_dependency(self, name: str) -> Dict[str, Any]: - dependencies = self.get_dependencies() - dependency = cast(Dict[str, Any], dependencies.get(name)) - if dependency is None: - raise errors.BuildError(f"Can't get cargo dependency: {name}") - return dependency - - def get_dev_dependency(self, name) -> Dict[str, Any]: - dependencies = self.get_dev_dependencies() - dependency = cast(Dict[str, Any], dependencies.get(name)) - if dependency is None: - raise errors.BuildError(f"Can't get cargo dev-dependency: {name}") - return dependency - - -def paths_of(env: Dict[str, str], key: str) -> Set[str]: - try: - return set(env[key].split(":")) - except KeyError: - return set() - - -def merge_env(first: Dict[str, str], second: Dict[str, str]) -> Dict[str, str]: - """ ->>> merge_env({'PATH':'first:common', 'CARGO_PATH': 'cargo_path'}, {'PATH':'second:common', 'EXAMPLE': 'other'}) -{'CARGO_PATH': 'cargo_path', 'EXAMPLE': 'other', 'PATH': 'common:first:second'} - """ - keys = set(first.keys()).union(second.keys()) - merged: Dict[str, str] = dict() - for key in sorted(keys): - values = paths_of(first, key).union(paths_of(second, key)) - merged[key] = ":".join(sorted(values)) - return merged diff --git a/multiversx_sdk_cli/projects/project_sol.py b/multiversx_sdk_cli/projects/project_sol.py deleted file mode 100644 index 5bf2e6fc..00000000 --- a/multiversx_sdk_cli/projects/project_sol.py +++ /dev/null @@ -1,21 +0,0 @@ -import logging -from pathlib import Path -from typing import List - -from multiversx_sdk_cli.projects.project_base import Project - -logger = logging.getLogger("ProjectSol") - - -class ProjectSol(Project): - def __init__(self, directory: Path): - super().__init__(directory) - - def perform_build(self): - pass - - def get_dependencies(self) -> List[str]: - return [] - - def _do_after_build_custom(self) -> List[Path]: - raise NotImplementedError() diff --git a/multiversx_sdk_cli/projects/shared.py b/multiversx_sdk_cli/projects/shared.py index 83e52585..25cdbfd4 100644 --- a/multiversx_sdk_cli/projects/shared.py +++ b/multiversx_sdk_cli/projects/shared.py @@ -1,25 +1,9 @@ import logging -import shutil from pathlib import Path -from multiversx_sdk_cli.errors import KnownError -from multiversx_sdk_cli.ux import show_critical_error - logger = logging.getLogger("projects.shared") -def is_source_clang(directory: Path) -> bool: - return _directory_contains_file(directory, ".c") - - -def is_source_cpp(directory: Path) -> bool: - return _directory_contains_file(directory, ".cpp") - - -def is_source_sol(directory: Path) -> bool: - return _directory_contains_file(directory, ".sol") - - def is_source_rust(directory: Path) -> bool: return _directory_contains_file(directory, "Cargo.toml") @@ -29,27 +13,3 @@ def _directory_contains_file(directory: Path, name_suffix: str) -> bool: if str(file).lower().endswith(name_suffix.lower()): return True return False - - -def check_clang_and_cpp_dependencies_installed() -> None: - which_clang = shutil.which("clang") - which_llc = shutil.which("llc") - which_wasm_ld = shutil.which("wasm-ld") - which_llvm_link = shutil.which("llvm-link") - - logger.info(f"which_clang: {which_clang}") - logger.info(f"which_llc: {which_llc}") - logger.info(f"which_wasm_ld: {which_wasm_ld}") - logger.info(f"which_llvm_link: {which_llvm_link}") - - dependencies = [which_clang, which_llc, which_wasm_ld, which_llvm_link] - is_installed = all(dependency is not None for dependency in dependencies) - - if is_installed is False: - message = """ -`clang` is not installed. Please install it manually, then try again. -Check out the cookbook: https://docs.multiversx.com/sdk-and-tools/sdk-py/mxpy-cli -For more details check out this page: https://clang.llvm.org/get_started.html""" - - show_critical_error(message) - raise KnownError("The required dependencies are not installed. Please check the above message.") From 4bf62ec3818397602705cd874544cb68ca08e26d Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 27 Oct 2023 11:15:16 +0300 Subject: [PATCH 49/62] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 61b18480..8597e46f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "multiversx-sdk-cli" -version = "8.2.0" +version = "9.0.0" authors = [ { name="MultiversX" }, ] From 1d11b67b22dbb652ccf2555cb29ddb2114c4fbb1 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 27 Oct 2023 11:20:51 +0300 Subject: [PATCH 50/62] bump version for beta release --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8597e46f..6643f88a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "multiversx-sdk-cli" -version = "9.0.0" +version = "9.0.0b1" authors = [ { name="MultiversX" }, ] From fecb99de915a64352a5bd0599d9dfbe1f171fbc4 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 31 Oct 2023 16:04:11 +0200 Subject: [PATCH 51/62] use wallet v0.8.0 --- multiversx_sdk_cli/accounts.py | 4 ++-- multiversx_sdk_cli/delegation/staking_provider.py | 6 ++---- multiversx_sdk_cli/sign_verify.py | 2 +- multiversx_sdk_cli/validators/core.py | 6 ++---- pyproject.toml | 2 +- requirements.txt | 2 +- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/multiversx_sdk_cli/accounts.py b/multiversx_sdk_cli/accounts.py index 26037d3c..ca53d2a8 100644 --- a/multiversx_sdk_cli/accounts.py +++ b/multiversx_sdk_cli/accounts.py @@ -69,12 +69,12 @@ def __init__(self, def sign_transaction(self, transaction: ITransaction) -> str: assert self.signer is not None - return self.signer.sign(transaction).hex() + return self.signer.sign(transaction.serialize_for_signing()).hex() def sign_message(self, data: bytes) -> str: assert self.signer is not None message = MessageV1(data) - signature = self.signer.sign(message) + signature = self.signer.sign(message.serialize_for_signing()) logger.debug(f"Account.sign_message(): raw_data_to_sign = {data.hex()}, message_data_to_sign = {message.serialize_for_signing().hex()}, signature = {signature.hex()}") return signature.hex() diff --git a/multiversx_sdk_cli/delegation/staking_provider.py b/multiversx_sdk_cli/delegation/staking_provider.py index 61d43d87..1bae35a1 100644 --- a/multiversx_sdk_cli/delegation/staking_provider.py +++ b/multiversx_sdk_cli/delegation/staking_provider.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Any -from multiversx_sdk_core import Address, ArbitraryMessage +from multiversx_sdk_core import Address from multiversx_sdk_wallet.validator_pem import ValidatorPEM from multiversx_sdk_wallet.validator_signer import ValidatorSigner @@ -52,9 +52,7 @@ def prepare_args_for_add_nodes(args: Any): pem_file = ValidatorPEM.from_file(validator_pem) validator_signer = ValidatorSigner(pem_file.secret_key) - message = ArbitraryMessage(bytes.fromhex(account.address.hex())) - - signed_message = validator_signer.sign(message).hex() + signed_message = validator_signer.sign(account.address.pubkey).hex() add_nodes_data += f"@{pem_file.secret_key.generate_public_key().hex()}@{signed_message}" diff --git a/multiversx_sdk_cli/sign_verify.py b/multiversx_sdk_cli/sign_verify.py index 6e893620..1e79eef2 100644 --- a/multiversx_sdk_cli/sign_verify.py +++ b/multiversx_sdk_cli/sign_verify.py @@ -23,7 +23,7 @@ def verify_signature(self) -> bool: verifier = UserVerifier.from_address(Address.from_bech32(self.address)) verifiable_message = MessageV1.from_string(self.message) verifiable_message.signature = bytes.fromhex(self.signature) - is_signed = verifier.verify(verifiable_message) + is_signed = verifier.verify(verifiable_message.serialize_for_signing(), verifiable_message.signature) return is_signed def to_dictionary(self) -> Dict[str, str]: diff --git a/multiversx_sdk_cli/validators/core.py b/multiversx_sdk_cli/validators/core.py index bc327ad6..e4c3b0b7 100644 --- a/multiversx_sdk_cli/validators/core.py +++ b/multiversx_sdk_cli/validators/core.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Any, List, Tuple, Union -from multiversx_sdk_core import Address, ArbitraryMessage +from multiversx_sdk_core import Address from multiversx_sdk_wallet.validator_pem import ValidatorPEM from multiversx_sdk_wallet.validator_signer import ValidatorSigner @@ -60,9 +60,7 @@ def prepare_transaction_data_for_stake(node_operator_address: Address, validator pem_file = ValidatorPEM.from_file(validator_pem) validator_signer = ValidatorSigner(pem_file.secret_key) - message = ArbitraryMessage(bytes.fromhex(node_operator_address.hex())) - - signed_message = validator_signer.sign(message).hex() + signed_message = validator_signer.sign(node_operator_address.pubkey).hex() call_arguments.append(f"0x{pem_file.secret_key.generate_public_key().hex()}") call_arguments.append(f"0x{signed_message}") diff --git a/pyproject.toml b/pyproject.toml index e24bb482..178bf3b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "requests-cache", "rich==13.3.4", "multiversx-sdk-network-providers>=0.11.0", - "multiversx-sdk-wallet>=0.7.0, <0.8.0", + "multiversx-sdk-wallet>=0.8.0", "multiversx-sdk-core>=0.5.0" ] diff --git a/requirements.txt b/requirements.txt index 1038a8ac..cb9ddb4a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,4 @@ rich==13.3.4 multiversx-sdk-core==0.6.0 multiversx-sdk-network-providers>=0.11.0 -multiversx-sdk-wallet>=0.7.0, < 0.8.0 +multiversx-sdk-wallet>=0.8.0 From 345229a247ee769c1df6340ef3dc5ffc66098210 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 31 Oct 2023 17:36:10 +0200 Subject: [PATCH 52/62] set upper bound for requirements --- pyproject.toml | 6 +++--- requirements.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 178bf3b2..63920162 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,9 +27,9 @@ dependencies = [ "semver", "requests-cache", "rich==13.3.4", - "multiversx-sdk-network-providers>=0.11.0", - "multiversx-sdk-wallet>=0.8.0", - "multiversx-sdk-core>=0.5.0" + "multiversx-sdk-network-providers>=0.11.0,<0.12.0", + "multiversx-sdk-wallet>=0.8.0",<0.9.0, + "multiversx-sdk-core>=0.6.0,<0.7.0" ] [tool.hatch.build] diff --git a/requirements.txt b/requirements.txt index cb9ddb4a..c6c65f71 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,6 @@ semver requests-cache rich==13.3.4 -multiversx-sdk-core==0.6.0 -multiversx-sdk-network-providers>=0.11.0 -multiversx-sdk-wallet>=0.8.0 +multiversx-sdk-core>=0.6.0,<0.7.0 +multiversx-sdk-network-providers>=0.11.0,<0.12.0 +multiversx-sdk-wallet>=0.8.0,<0.9.9 From 194216122f5aa4c9c1fea87fcacc115a9cc2f9c8 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 31 Oct 2023 17:39:18 +0200 Subject: [PATCH 53/62] fix --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 63920162..11ae69f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "requests-cache", "rich==13.3.4", "multiversx-sdk-network-providers>=0.11.0,<0.12.0", - "multiversx-sdk-wallet>=0.8.0",<0.9.0, + "multiversx-sdk-wallet>=0.8.0,<0.9.0", "multiversx-sdk-core>=0.6.0,<0.7.0" ] From 5fc04d74f6c37e622d8014d9e63d2140a3cad09c Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 31 Oct 2023 19:03:07 +0200 Subject: [PATCH 54/62] fix typo --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c6c65f71..9059d3d6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,4 @@ rich==13.3.4 multiversx-sdk-core>=0.6.0,<0.7.0 multiversx-sdk-network-providers>=0.11.0,<0.12.0 -multiversx-sdk-wallet>=0.8.0,<0.9.9 +multiversx-sdk-wallet>=0.8.0,<0.9.0 From e10f7588b6dac10c4d08c6b6b0cc68f2625987bb Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 2 Nov 2023 12:28:19 +0200 Subject: [PATCH 55/62] fix unit tests --- multiversx_sdk_cli/tests/test_proxy.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/multiversx_sdk_cli/tests/test_proxy.py b/multiversx_sdk_cli/tests/test_proxy.py index cf570768..4f78a7ac 100644 --- a/multiversx_sdk_cli/tests/test_proxy.py +++ b/multiversx_sdk_cli/tests/test_proxy.py @@ -17,18 +17,14 @@ def test_get_account(): "https://testnet-api.multiversx.com" ] ) - if not result: - assert True - else: - assert False + assert False if result else True def test_sync_nonce(): account = Account(address=Address.from_bech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th")) proxy = ProxyNetworkProvider("https://devnet-api.multiversx.com") account.sync_nonce(proxy) - - assert account.nonce >= 11480 + assert True if account.nonce else False def test_query_contract(): @@ -36,17 +32,14 @@ def test_query_contract(): [ "contract", "query", - "erd1qqqqqqqqqqqqqpgquykqja5c4v33zdmnwglj3jphqwrelzdn396qlc9g33", + "erd1qqqqqqqqqqqqqpgqpuz9r56ylk39x45cgqmaw2w8hfn47ft3d8ssavktr5", "--function", "getSum", "--proxy", "https://devnet-api.multiversx.com", ] ) - if not result: - assert True - else: - assert False + assert False if result else True def test_get_transaction(): @@ -57,11 +50,7 @@ def test_get_transaction(): "--proxy", "https://devnet-api.multiversx.com", "--hash", - "cbe2026b8d9c3ee75f2846ea8e0b646b19e6fca754e43edb4113757fc3350952", + "9e6ca966b18dc0317ff3be9b53be183ddb068a163769d286b2c1b1dff3ac00e5", ] ) - - if not result: - assert True - else: - assert False + assert False if result else True From 09fe5368657996df907c8f8103dc09b9d99e7faf Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Mon, 6 Nov 2023 17:33:33 +0200 Subject: [PATCH 56/62] reference latest packages & start fixes --- multiversx_sdk_cli/accounts.py | 15 ++++++++------- multiversx_sdk_cli/cli_accounts.py | 2 +- multiversx_sdk_cli/cli_contracts.py | 4 ++-- multiversx_sdk_cli/cli_dns.py | 2 +- multiversx_sdk_cli/cli_output.py | 2 +- multiversx_sdk_cli/cli_shared.py | 4 ++-- multiversx_sdk_cli/cli_wallet.py | 14 +++++++------- multiversx_sdk_cli/contract_verification.py | 4 ++-- multiversx_sdk_cli/contracts.py | 7 ++++--- multiversx_sdk_cli/delegation/staking_provider.py | 2 +- multiversx_sdk_cli/dns.py | 11 ++++------- multiversx_sdk_cli/interfaces.py | 4 ++-- multiversx_sdk_cli/localnet/genesis.py | 7 ++++--- multiversx_sdk_cli/localnet/genesis_json.py | 6 +++--- multiversx_sdk_cli/sign_verify.py | 10 ++++++---- multiversx_sdk_cli/tests/test_contracts.py | 7 ++++--- multiversx_sdk_cli/tests/test_proxy.py | 2 +- multiversx_sdk_cli/tests/test_validators_core.py | 2 +- multiversx_sdk_cli/validators/core.py | 6 +++--- pyproject.toml | 6 +++--- requirements.txt | 8 ++++---- 21 files changed, 64 insertions(+), 61 deletions(-) diff --git a/multiversx_sdk_cli/accounts.py b/multiversx_sdk_cli/accounts.py index ca53d2a8..40adf2f4 100644 --- a/multiversx_sdk_cli/accounts.py +++ b/multiversx_sdk_cli/accounts.py @@ -2,7 +2,7 @@ from pathlib import Path from typing import Any, Optional, Protocol -from multiversx_sdk_core import Address, MessageV1 +from multiversx_sdk_core import Address, Message, MessageComputer from multiversx_sdk_network_providers.accounts import AccountOnNetwork from multiversx_sdk_wallet import UserSigner @@ -25,10 +25,10 @@ def get_account(self, address: IAddress) -> AccountOnNetwork: class EmptyAddress(IAddress): - def hex(self) -> str: + def to_hex(self) -> str: return "" - def bech32(self) -> str: + def to_bech32(self) -> str: return "" @@ -73,10 +73,11 @@ def sign_transaction(self, transaction: ITransaction) -> str: def sign_message(self, data: bytes) -> str: assert self.signer is not None - message = MessageV1(data) - signature = self.signer.sign(message.serialize_for_signing()) + message = Message(data) + message_computer = MessageComputer() + signature = self.signer.sign(message_computer.compute_bytes_for_signing(message)) - logger.debug(f"Account.sign_message(): raw_data_to_sign = {data.hex()}, message_data_to_sign = {message.serialize_for_signing().hex()}, signature = {signature.hex()}") + logger.debug(f"Account.sign_message(): raw_data_to_sign = {data.hex()}, message_data_to_sign = {message_computer.compute_bytes_for_signing(message).hex()}, signature = {signature.hex()}") return signature.hex() @@ -85,7 +86,7 @@ def __init__(self, account_index: int = 0, address_index: int = 0) -> None: super().__init__() self.account_index = account_index self.address_index = address_index - self.address = Address.from_bech32(do_get_ledger_address(account_index=account_index, address_index=address_index)) + self.address = Address.new_from_bech32(do_get_ledger_address(account_index=account_index, address_index=address_index)) def sign_transaction(self, transaction: ITransaction) -> str: ledger_version = do_get_ledger_version() diff --git a/multiversx_sdk_cli/cli_accounts.py b/multiversx_sdk_cli/cli_accounts.py index 8970c5d2..1ebf8bc6 100644 --- a/multiversx_sdk_cli/cli_accounts.py +++ b/multiversx_sdk_cli/cli_accounts.py @@ -36,7 +36,7 @@ def get_account(args: Any): proxy_url = args.proxy address = args.address proxy = ProxyNetworkProvider(proxy_url) - account = proxy.get_account(Address.from_bech32(address)) + account = proxy.get_account(Address.new_from_bech32(address)) if args.balance: print(account.balance) diff --git a/multiversx_sdk_cli/cli_contracts.py b/multiversx_sdk_cli/cli_contracts.py index 0c7325d2..5b34d106 100644 --- a/multiversx_sdk_cli/cli_contracts.py +++ b/multiversx_sdk_cli/cli_contracts.py @@ -312,8 +312,8 @@ def deploy(args: Any): tx = contract.deploy(sender, arguments, gas_price, gas_limit, value, args.chain, version, args.guardian, args.options) tx = _sign_guarded_tx(args, tx) - logger.info("Contract address: %s", contract.address.bech32()) - utils.log_explorer_contract_address(args.chain, contract.address.bech32()) + logger.info("Contract address: %s", contract.address.to_bech32()) + utils.log_explorer_contract_address(args.chain, contract.address.to_bech32()) _send_or_simulate(tx, contract, args) diff --git a/multiversx_sdk_cli/cli_dns.py b/multiversx_sdk_cli/cli_dns.py index 2e915539..23309d18 100644 --- a/multiversx_sdk_cli/cli_dns.py +++ b/multiversx_sdk_cli/cli_dns.py @@ -74,7 +74,7 @@ def _add_name_arg(sub: Any): def dns_resolve(args: Any): addr = resolve(args.name, ProxyNetworkProvider(args.proxy)) - if addr.hex() != Address.from_bech32(ADDRESS_ZERO_BECH32).hex(): + if addr.hex() != Address.new_from_bech32(ADDRESS_ZERO_BECH32).hex(): print(addr.bech32()) diff --git a/multiversx_sdk_cli/cli_output.py b/multiversx_sdk_cli/cli_output.py index bbdc5e02..4d5abf64 100644 --- a/multiversx_sdk_cli/cli_output.py +++ b/multiversx_sdk_cli/cli_output.py @@ -61,7 +61,7 @@ def build(self) -> Dict[str, Any]: output["emittedTransactionHash"] = emitted_transaction_hash if self.contract_address: - contract_address = self.contract_address.bech32() + contract_address = self.contract_address.to_bech32() output["contractAddress"] = contract_address if self.transaction_on_network: diff --git a/multiversx_sdk_cli/cli_shared.py b/multiversx_sdk_cli/cli_shared.py index d6f87eb9..1a7f970f 100644 --- a/multiversx_sdk_cli/cli_shared.py +++ b/multiversx_sdk_cli/cli_shared.py @@ -151,7 +151,7 @@ def prepare_account(args: Any): account = Account(key_file=args.keyfile, password=password) elif args.ledger: address = do_get_ledger_address(account_index=args.ledger_account_index, address_index=args.ledger_address_index) - account = Account(address=Address.from_bech32(address)) + account = Account(address=Address.new_from_bech32(address)) else: raise errors.NoWalletProvided() @@ -166,7 +166,7 @@ def prepare_guardian_account(args: Any): account = Account(key_file=args.guardian_keyfile, password=password) elif args.guardian_ledger: address = do_get_ledger_address(account_index=args.guardian_ledger_account_index, address_index=args.guardian_ledger_address_index) - account = Account(Address.from_bech32(address)) + account = Account(Address.new_from_bech32(address)) else: raise errors.NoWalletProvided() diff --git a/multiversx_sdk_cli/cli_wallet.py b/multiversx_sdk_cli/cli_wallet.py index e9cd9a34..337bd0aa 100644 --- a/multiversx_sdk_cli/cli_wallet.py +++ b/multiversx_sdk_cli/cli_wallet.py @@ -137,7 +137,7 @@ def wallet_new(args: Any): secret_key = mnemonic.derive_key() pubkey = secret_key.generate_public_key() address = pubkey.to_address(address_hrp) - pem_file = UserPEM(address.bech32(), secret_key) + pem_file = UserPEM(address.to_bech32(), secret_key) pem_file.save(outfile) else: raise KnownError(f"Unknown format: {format}") @@ -234,7 +234,7 @@ def _create_wallet_content( pubkey = secret_key.generate_public_key() address = pubkey.to_address(address_hrp) - pem = UserPEM(address.bech32(), secret_key) + pem = UserPEM(address.to_bech32(), secret_key) return pem.to_text() if out_format == WALLET_FORMAT_ADDRESS_BECH32: @@ -244,7 +244,7 @@ def _create_wallet_content( pubkey = secret_key.generate_public_key() address = pubkey.to_address(address_hrp) - return address.bech32() + return address.to_bech32() if out_format == WALLET_FORMAT_ADDRESS_HEX: if mnemonic: @@ -262,11 +262,11 @@ def do_bech32(args: Any): value = args.value if encode: - address = Address.from_hex(value, DEFAULT_HRP) - result = address.bech32() + address = Address.new_from_hex(value, DEFAULT_HRP) + result = address.to_bech32() else: - address = Address.from_bech32(value) - result = address.hex() + address = Address.new_from_bech32(value) + result = address.to_hex() print(result) return result diff --git a/multiversx_sdk_cli/contract_verification.py b/multiversx_sdk_cli/contract_verification.py index d9b78824..7c6266da 100644 --- a/multiversx_sdk_cli/contract_verification.py +++ b/multiversx_sdk_cli/contract_verification.py @@ -54,7 +54,7 @@ def __init__(self, contract: Address, source_code: Dict[str, Any], docker_image: def serialize(self) -> str: payload = { - "contract": self.contract.bech32(), + "contract": self.contract.to_bech32(), "dockerImage": self.docker_image, "sourceCode": self.source_code, "contractVariant": self.contract_variant @@ -103,7 +103,7 @@ def trigger_contract_verification( def _create_request_signature(account: Account, contract_address: Address, request_payload: bytes) -> bytes: hashed_payload: str = hashlib.sha256(request_payload).hexdigest() - raw_data_to_sign = f"{contract_address.bech32()}{hashed_payload}" + raw_data_to_sign = f"{contract_address.to_bech32()}{hashed_payload}" signature_hex = account.sign_message(raw_data_to_sign.encode()) signature = bytes.fromhex(signature_hex) diff --git a/multiversx_sdk_cli/contracts.py b/multiversx_sdk_cli/contracts.py index 267d9922..4650c8a3 100644 --- a/multiversx_sdk_cli/contracts.py +++ b/multiversx_sdk_cli/contracts.py @@ -3,7 +3,7 @@ from typing import Any, List, Optional, Protocol, Sequence, Tuple from multiversx_sdk_core import Transaction, TransactionPayload -from multiversx_sdk_core.address import Address, compute_contract_address +from multiversx_sdk_core.address import Address, AddressComputer from multiversx_sdk_network_providers.interface import IAddress, IContractQuery from multiversx_sdk_cli import config, constants, errors @@ -69,7 +69,8 @@ def __init__(self, address: Optional[IAddress] = EmptyAddress(), bytecode=None, def deploy(self, owner: Account, arguments: List[Any], gas_price: int, gas_limit: int, value: int, chain: str, version: int, guardian: str, options: int) -> Transaction: self.owner = owner - self.address = compute_contract_address(self.owner.address, self.owner.nonce, DEFAULT_HRP) + address_computer = AddressComputer(number_of_shards=3) + self.address = address_computer.compute_contract_address(self.owner.address, self.owner.nonce) arguments = arguments or [] gas_price = int(gas_price) @@ -79,7 +80,7 @@ def deploy(self, owner: Account, arguments: List[Any], gas_price: int, gas_limit tx = Transaction( chain_id=chain, sender=owner.address, - receiver=Address.from_bech32(ADDRESS_ZERO_BECH32), + receiver=Address.new_from_bech32(ADDRESS_ZERO_BECH32), gas_limit=gas_limit, gas_price=gas_price, nonce=owner.nonce, diff --git a/multiversx_sdk_cli/delegation/staking_provider.py b/multiversx_sdk_cli/delegation/staking_provider.py index 1bae35a1..8ed5936b 100644 --- a/multiversx_sdk_cli/delegation/staking_provider.py +++ b/multiversx_sdk_cli/delegation/staking_provider.py @@ -35,7 +35,7 @@ def prepare_args_for_add_nodes(args: Any): # TODO: Refactor, so that only address is received here. if args.using_delegation_manager: - account = Account(address=Address.from_bech32(args.delegation_contract)) + account = Account(address=Address.new_from_bech32(args.delegation_contract)) elif args.pem: account = Account(pem_file=args.pem) elif args.keyfile: diff --git a/multiversx_sdk_cli/dns.py b/multiversx_sdk_cli/dns.py index 47472d99..86ffb555 100644 --- a/multiversx_sdk_cli/dns.py +++ b/multiversx_sdk_cli/dns.py @@ -1,7 +1,7 @@ from typing import Any, List, Protocol from Cryptodome.Hash import keccak -from multiversx_sdk_core.address import Address, compute_contract_address +from multiversx_sdk_core.address import Address, AddressComputer from multiversx_sdk_cli import cli_shared, utils from multiversx_sdk_cli.accounts import Account @@ -96,12 +96,9 @@ def compute_dns_address_for_shard_id(shard_id: int) -> Address: deployer_pubkey = deployer_pubkey_prefix + bytes([0, shard_id]) deployer = Account(address=Address(deployer_pubkey, DEFAULT_HRP)) deployer.nonce = 0 - # Workaround: In order to compute the address of a contract, one has to create an instance of the class "SmartContract". - # This might change in the future. - contract = SmartContract() - contract.owner = deployer - contract.address = compute_contract_address(contract.owner.address, contract.owner.nonce, DEFAULT_HRP) - return contract.address + address_computer = AddressComputer(number_of_shards=3) + contract_address = address_computer.compute_contract_address(deployer.address, deployer.nonce) + return contract_address def dns_register_data(name: str) -> str: diff --git a/multiversx_sdk_cli/interfaces.py b/multiversx_sdk_cli/interfaces.py index 947433b2..7e085b43 100644 --- a/multiversx_sdk_cli/interfaces.py +++ b/multiversx_sdk_cli/interfaces.py @@ -2,10 +2,10 @@ class IAddress(Protocol): - def hex(self) -> str: + def to_hex(self) -> str: ... - def bech32(self) -> str: + def to_bech32(self) -> str: ... diff --git a/multiversx_sdk_cli/localnet/genesis.py b/multiversx_sdk_cli/localnet/genesis.py index aea5d9c4..90a3e3c6 100644 --- a/multiversx_sdk_cli/localnet/genesis.py +++ b/multiversx_sdk_cli/localnet/genesis.py @@ -1,6 +1,5 @@ -from multiversx_sdk_core.address import Address, compute_contract_address +from multiversx_sdk_core.address import Address, AddressComputer -from multiversx_sdk_cli.constants import DEFAULT_HRP from multiversx_sdk_cli.contracts import SmartContract from multiversx_sdk_cli.localnet import wallets @@ -14,7 +13,9 @@ def get_delegation_address() -> Address: contract = SmartContract() contract.owner = get_owner_of_genesis_contracts() contract.owner.nonce = 0 - contract.address = compute_contract_address(contract.owner.address, contract.owner.nonce, DEFAULT_HRP) + + address_computer = AddressComputer() + contract.address = address_computer.compute_contract_address(contract.owner.address, contract.owner.nonce) return contract.address diff --git a/multiversx_sdk_cli/localnet/genesis_json.py b/multiversx_sdk_cli/localnet/genesis_json.py index cf7042c2..9bf75cd8 100644 --- a/multiversx_sdk_cli/localnet/genesis_json.py +++ b/multiversx_sdk_cli/localnet/genesis_json.py @@ -45,7 +45,7 @@ def build(config: ConfigRoot) -> List[Any]: def _build_validator_entry(nickname: str, account: Account, value: int) -> Dict[str, Any]: return { "nickname": nickname, - "address": account.address.bech32(), + "address": account.address.to_bech32(), "supply": str(value), "balance": "0", "stakingvalue": str(value), @@ -59,12 +59,12 @@ def _build_validator_entry(nickname: str, account: Account, value: int) -> Dict[ def _build_user_entry(nickname: str, account: Account, value: int, delegated_value: int, delegation_address: Address) -> Dict[str, Any]: return { "nickname": nickname, - "address": account.address.bech32(), + "address": account.address.to_bech32(), "supply": str(value), "balance": str(value - delegated_value), "stakingvalue": "0", "delegation": { - "address": delegation_address.bech32(), + "address": delegation_address.to_bech32(), "value": str(delegated_value) } } diff --git a/multiversx_sdk_cli/sign_verify.py b/multiversx_sdk_cli/sign_verify.py index 1e79eef2..240a843e 100644 --- a/multiversx_sdk_cli/sign_verify.py +++ b/multiversx_sdk_cli/sign_verify.py @@ -1,6 +1,6 @@ from typing import Dict -from multiversx_sdk_core import Address, MessageV1 +from multiversx_sdk_core import Address, Message, MessageComputer from multiversx_sdk_wallet import UserVerifier from multiversx_sdk_cli.accounts import Account @@ -20,10 +20,12 @@ def __init__(self, address: str, message: str, signature: str) -> None: self.signature = signature def verify_signature(self) -> bool: - verifier = UserVerifier.from_address(Address.from_bech32(self.address)) - verifiable_message = MessageV1.from_string(self.message) + verifiable_message = Message(self.message.encode()) verifiable_message.signature = bytes.fromhex(self.signature) - is_signed = verifier.verify(verifiable_message.serialize_for_signing(), verifiable_message.signature) + message_computer = MessageComputer() + + verifier = UserVerifier.from_address(Address.from_bech32(self.address)) + is_signed = verifier.verify(message_computer.compute_bytes_for_signing(verifiable_message), verifiable_message.signature) return is_signed def to_dictionary(self) -> Dict[str, str]: diff --git a/multiversx_sdk_cli/tests/test_contracts.py b/multiversx_sdk_cli/tests/test_contracts.py index f7a63b7f..2ea5674f 100644 --- a/multiversx_sdk_cli/tests/test_contracts.py +++ b/multiversx_sdk_cli/tests/test_contracts.py @@ -3,7 +3,7 @@ import pytest from Cryptodome.Hash import keccak -from multiversx_sdk_core.address import Address, compute_contract_address +from multiversx_sdk_core.address import Address, AddressComputer from multiversx_sdk_cli import errors from multiversx_sdk_cli.accounts import Account @@ -24,17 +24,18 @@ def test_playground_keccak(): def test_compute_address(): + address_computer = AddressComputer() contract = SmartContract() contract.owner = Account(address=Address.from_hex("93ee6143cdc10ce79f15b2a6c2ad38e9b6021c72a1779051f47154fd54cfbd5e", DEFAULT_HRP)) contract.owner.nonce = 0 - contract.address = compute_contract_address(contract.owner.address, contract.owner.nonce, DEFAULT_HRP) + contract.address = address_computer.compute_contract_address(contract.owner.address, contract.owner.nonce) assert contract.address assert contract.address.hex() == "00000000000000000500bb652200ed1f994200ab6699462cab4b1af7b11ebd5e" assert contract.address.bech32() == "erd1qqqqqqqqqqqqqpgqhdjjyq8dr7v5yq9tv6v5vt9tfvd00vg7h40q6779zn" contract.owner.nonce = 1 - contract.address = compute_contract_address(contract.owner.address, contract.owner.nonce, DEFAULT_HRP) + contract.address = address_computer.compute_contract_address(contract.owner.address, contract.owner.nonce DEFAULT_HRP) assert contract.address.hex() == "000000000000000005006e4f90488e27342f9a46e1809452c85ee7186566bd5e" assert contract.address.bech32() == "erd1qqqqqqqqqqqqqpgqde8eqjywyu6zlxjxuxqfg5kgtmn3setxh40qen8egy" diff --git a/multiversx_sdk_cli/tests/test_proxy.py b/multiversx_sdk_cli/tests/test_proxy.py index 4f78a7ac..3f234793 100644 --- a/multiversx_sdk_cli/tests/test_proxy.py +++ b/multiversx_sdk_cli/tests/test_proxy.py @@ -21,7 +21,7 @@ def test_get_account(): def test_sync_nonce(): - account = Account(address=Address.from_bech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th")) + account = Account(address=Address.new_from_bech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th")) proxy = ProxyNetworkProvider("https://devnet-api.multiversx.com") account.sync_nonce(proxy) assert True if account.nonce else False diff --git a/multiversx_sdk_cli/tests/test_validators_core.py b/multiversx_sdk_cli/tests/test_validators_core.py index bf473af0..f3a7bcce 100644 --- a/multiversx_sdk_cli/tests/test_validators_core.py +++ b/multiversx_sdk_cli/tests/test_validators_core.py @@ -9,7 +9,7 @@ def test_prepare_transaction_data_for_stake(): - node_operator_address = Address.from_bech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th") + node_operator_address = Address.new_from_bech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th") validators_file_path = TESTDATA_FOLDER / "validators.json" data, gas_limit = prepare_transaction_data_for_stake(node_operator_address, validators_file_path, node_operator_address) diff --git a/multiversx_sdk_cli/validators/core.py b/multiversx_sdk_cli/validators/core.py index e4c3b0b7..b19a21ca 100644 --- a/multiversx_sdk_cli/validators/core.py +++ b/multiversx_sdk_cli/validators/core.py @@ -34,7 +34,7 @@ def prepare_args_for_stake(args: Any): raise BadUsage("cannot initialize node operator") validators_file_path = Path(args.validators_file) - reward_address = Address.from_bech32(args.reward_address) if args.reward_address else None + reward_address = Address.new_from_bech32(args.reward_address) if args.reward_address else None data, gas_limit = prepare_transaction_data_for_stake(node_operator.address, validators_file_path, reward_address) args.data = data @@ -66,7 +66,7 @@ def prepare_transaction_data_for_stake(node_operator_address: Address, validator call_arguments.append(f"0x{signed_message}") if reward_address: - call_arguments.append(f"0x{reward_address.hex()}") + call_arguments.append(f"0x{reward_address.to_hex()}") data = SmartContract().prepare_execute_transaction_data("stake", call_arguments) gas_limit = estimate_system_sc_call(str(data), MetaChainSystemSCsCost.STAKE, num_of_nodes) @@ -110,7 +110,7 @@ def prepare_args_for_unjail(args: Any): def prepare_args_for_change_reward_address(args: Any): - reward_address = Address.from_bech32(args.reward_address) + reward_address = Address.new_from_bech32(args.reward_address) args.data = 'changeRewardAddress@' + reward_address.hex() args.receiver = VALIDATORS_SMART_CONTRACT_ADDRESS diff --git a/pyproject.toml b/pyproject.toml index 11ae69f6..b0e3f36d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,9 +27,9 @@ dependencies = [ "semver", "requests-cache", "rich==13.3.4", - "multiversx-sdk-network-providers>=0.11.0,<0.12.0", - "multiversx-sdk-wallet>=0.8.0,<0.9.0", - "multiversx-sdk-core>=0.6.0,<0.7.0" + "multiversx-sdk-network-providers==0.12.0", + "multiversx-sdk-wallet==0.8.2,", + "multiversx-sdk-core==0.7.1" ] [tool.hatch.build] diff --git a/requirements.txt b/requirements.txt index 9059d3d6..3cd44031 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ toml>=0.10.2 types-toml -requests~=2.24.0 +requests~=2.31.0 types-requests prettytable types-prettytable @@ -9,6 +9,6 @@ semver requests-cache rich==13.3.4 -multiversx-sdk-core>=0.6.0,<0.7.0 -multiversx-sdk-network-providers>=0.11.0,<0.12.0 -multiversx-sdk-wallet>=0.8.0,<0.9.0 +multiversx-sdk-core==0.7.1 +multiversx-sdk-network-providers==0.12.0 +multiversx-sdk-wallet==0.8.2 From cb6734becf16deb8763c904f5d8df98f41407bf6 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 7 Nov 2023 12:43:47 +0200 Subject: [PATCH 57/62] fixes --- multiversx_sdk_cli/accounts.py | 11 ++++-- multiversx_sdk_cli/cli_delegation.py | 2 +- multiversx_sdk_cli/cli_output.py | 7 ++-- multiversx_sdk_cli/contracts.py | 30 ++++++++-------- multiversx_sdk_cli/cosign_transaction.py | 2 +- multiversx_sdk_cli/interfaces.py | 40 ++++++++-------------- multiversx_sdk_cli/tests/test_contracts.py | 2 +- multiversx_sdk_cli/transactions.py | 30 ++++++++-------- multiversx_sdk_cli/utils.py | 6 +++- 9 files changed, 66 insertions(+), 64 deletions(-) diff --git a/multiversx_sdk_cli/accounts.py b/multiversx_sdk_cli/accounts.py index 40adf2f4..bb563ae5 100644 --- a/multiversx_sdk_cli/accounts.py +++ b/multiversx_sdk_cli/accounts.py @@ -2,7 +2,8 @@ from pathlib import Path from typing import Any, Optional, Protocol -from multiversx_sdk_core import Address, Message, MessageComputer +from multiversx_sdk_core import (Address, Message, MessageComputer, + TransactionComputer) from multiversx_sdk_network_providers.accounts import AccountOnNetwork from multiversx_sdk_wallet import UserSigner @@ -69,7 +70,9 @@ def __init__(self, def sign_transaction(self, transaction: ITransaction) -> str: assert self.signer is not None - return self.signer.sign(transaction.serialize_for_signing()).hex() + + transaction_computer = TransactionComputer() + return self.signer.sign(transaction_computer.compute_bytes_for_signing(transaction)).hex() def sign_message(self, data: bytes) -> str: assert self.signer is not None @@ -95,8 +98,10 @@ def sign_transaction(self, transaction: ITransaction) -> str: transaction.version = TX_HASH_SIGN_VERSION transaction.options = TX_HASH_SIGN_OPTIONS + transaction_computer = TransactionComputer() + signature = do_sign_transaction_with_ledger( - transaction.serialize_for_signing(), + transaction_computer.compute_bytes_for_signing(transaction), account_index=self.account_index, address_index=self.address_index, sign_using_hash=should_use_hash_signing diff --git a/multiversx_sdk_cli/cli_delegation.py b/multiversx_sdk_cli/cli_delegation.py index c0728ace..6b781e52 100644 --- a/multiversx_sdk_cli/cli_delegation.py +++ b/multiversx_sdk_cli/cli_delegation.py @@ -159,7 +159,7 @@ def get_contract_address_by_deploy_tx_hash(args: Any): transaction_events = transaction.logs.events if len(transaction_events) == 1: contract_address = transaction_events[0].address - print(contract_address.bech32()) + print(contract_address.to_bech32()) else: raise errors.ProgrammingError("Tx has more than one event. Make sure it's a staking provider SC Deploy transaction.") diff --git a/multiversx_sdk_cli/cli_output.py b/multiversx_sdk_cli/cli_output.py index 4d5abf64..36fb6ffe 100644 --- a/multiversx_sdk_cli/cli_output.py +++ b/multiversx_sdk_cli/cli_output.py @@ -51,12 +51,15 @@ def build(self) -> Dict[str, Any]: output: Dict[str, Any] = OrderedDict() if self.emitted_transaction: - emitted_transaction_dict = self.emitted_transaction.to_dictionary() + emitted_transaction_dict = self.emitted_transaction.__dict__ emitted_transaction_hash = self.emitted_transaction_hash or "" - emitted_transaction_data = str(self.emitted_transaction.data) + emitted_transaction_data = self.emitted_transaction.data.decode() utils.omit_fields(emitted_transaction_dict, self.emitted_transaction_omitted_fields) output["emittedTransaction"] = emitted_transaction_dict + signature: bytes = output["emittedTransaction"]["signature"] + output["emittedTransaction"]["signature"] = signature.hex() if type(signature) is not str else signature + output["emittedTransactionData"] = emitted_transaction_data output["emittedTransactionHash"] = emitted_transaction_hash diff --git a/multiversx_sdk_cli/contracts.py b/multiversx_sdk_cli/contracts.py index 4650c8a3..6575ce77 100644 --- a/multiversx_sdk_cli/contracts.py +++ b/multiversx_sdk_cli/contracts.py @@ -79,19 +79,19 @@ def deploy(self, owner: Account, arguments: List[Any], gas_price: int, gas_limit tx = Transaction( chain_id=chain, - sender=owner.address, - receiver=Address.new_from_bech32(ADDRESS_ZERO_BECH32), + sender=owner.address.to_bech32(), + receiver=ADDRESS_ZERO_BECH32, gas_limit=gas_limit, gas_price=gas_price, nonce=owner.nonce, - value=value, - data=self.prepare_deploy_transaction_data(arguments), + amount=value, + data=self.prepare_deploy_transaction_data(arguments).data, version=version, options=options ) if guardian: - tx.guardian = Address.from_bech32(guardian) + tx.guardian = guardian tx.signature = bytes.fromhex(owner.sign_transaction(tx)) return tx @@ -115,19 +115,19 @@ def execute(self, caller: Account, function: str, arguments: List[str], gas_pric tx = Transaction( chain_id=chain, - sender=caller.address, - receiver=receiver, + sender=caller.address.to_bech32(), + receiver=receiver.to_bech32(), gas_limit=gas_limit, gas_price=gas_price, nonce=caller.nonce, - value=value, - data=self.prepare_execute_transaction_data(function, arguments), + amount=value, + data=self.prepare_execute_transaction_data(function, arguments).data, version=version, options=options ) if guardian: - tx.guardian = Address.from_bech32(guardian) + tx.guardian = guardian tx.signature = bytes.fromhex(caller.sign_transaction(tx)) return tx @@ -151,19 +151,19 @@ def upgrade(self, owner: Account, arguments: List[Any], gas_price: int, gas_limi tx = Transaction( chain_id=chain, - sender=owner.address, - receiver=receiver, + sender=owner.address.to_bech32(), + receiver=receiver.to_bech32(), gas_limit=gas_limit, gas_price=gas_price, nonce=owner.nonce, - value=value, - data=self.prepare_upgrade_transaction_data(arguments), + amount=value, + data=self.prepare_upgrade_transaction_data(arguments).data, version=version, options=options ) if guardian: - tx.guardian = Address.from_bech32(guardian) + tx.guardian = guardian tx.signature = bytes.fromhex(owner.sign_transaction(tx)) return tx diff --git a/multiversx_sdk_cli/cosign_transaction.py b/multiversx_sdk_cli/cosign_transaction.py index 6c5383dc..26aada47 100644 --- a/multiversx_sdk_cli/cosign_transaction.py +++ b/multiversx_sdk_cli/cosign_transaction.py @@ -9,7 +9,7 @@ def cosign_transaction(transaction: ITransaction, service_url: str, guardian_code: str) -> ITransaction: payload = { "code": f"{guardian_code}", - "transaction": transaction.to_dictionary() + "transaction": transaction.__dict__ } url = f"{service_url}/sign-transaction" diff --git a/multiversx_sdk_cli/interfaces.py b/multiversx_sdk_cli/interfaces.py index 7e085b43..9e736b17 100644 --- a/multiversx_sdk_cli/interfaces.py +++ b/multiversx_sdk_cli/interfaces.py @@ -9,32 +9,22 @@ def to_bech32(self) -> str: ... -ITransactionOptions = int -ITransactionVersion = int -ISignature = bytes - - -class ITransactionPayload(Protocol): - data: bytes - def encoded(self) -> str: ... - def length(self) -> int: ... - - class ITransaction(Protocol): - version: ITransactionVersion - options: ITransactionOptions - signature: ISignature - guardian_signature: ISignature - - @property - def data(self) -> ITransactionPayload: - ... - - def serialize_for_signing(self) -> bytes: - ... - - def to_dictionary(self, with_signature: bool = True) -> Dict[str, Any]: - ... + sender: str + receiver: str + gas_limit: int + chain_id: str + nonce: int + amount: int + sender_username: str + receiver_username: str + gas_price: int + data: bytes + version: int + options: int + guardian: str + signature: bytes + guardian_signature: bytes class IAccount(Protocol): diff --git a/multiversx_sdk_cli/tests/test_contracts.py b/multiversx_sdk_cli/tests/test_contracts.py index 2ea5674f..f6eed78d 100644 --- a/multiversx_sdk_cli/tests/test_contracts.py +++ b/multiversx_sdk_cli/tests/test_contracts.py @@ -35,7 +35,7 @@ def test_compute_address(): assert contract.address.bech32() == "erd1qqqqqqqqqqqqqpgqhdjjyq8dr7v5yq9tv6v5vt9tfvd00vg7h40q6779zn" contract.owner.nonce = 1 - contract.address = address_computer.compute_contract_address(contract.owner.address, contract.owner.nonce DEFAULT_HRP) + contract.address = address_computer.compute_contract_address(contract.owner.address, contract.owner.nonce) assert contract.address.hex() == "000000000000000005006e4f90488e27342f9a46e1809452c85ee7186566bd5e" assert contract.address.bech32() == "erd1qqqqqqqqqqqqqpgqde8eqjywyu6zlxjxuxqfg5kgtmn3setxh40qen8egy" diff --git a/multiversx_sdk_cli/transactions.py b/multiversx_sdk_cli/transactions.py index 5b8d2a9f..ba2cceee 100644 --- a/multiversx_sdk_cli/transactions.py +++ b/multiversx_sdk_cli/transactions.py @@ -69,21 +69,21 @@ def do_prepare_transaction(args: Any) -> Transaction: tx = Transaction( chain_id=args.chain, - sender=account.address, - receiver=Address.from_bech32(args.receiver), + sender=account.address.to_bech32(), + receiver=args.receiver, gas_limit=int(args.gas_limit), sender_username=getattr(args, "sender_username", ""), receiver_username=getattr(args, "receiver_username", ""), gas_price=int(args.gas_price), - data=TransactionPayload.from_str(args.data), + data=TransactionPayload.from_str(args.data).data, nonce=int(args.nonce), - value=int(args.value), + amount=int(args.value), version=int(args.version), options=int(args.options) ) if args.guardian: - tx.guardian = Address.from_bech32(args.guardian) + tx.guardian = args.guardian tx.signature = bytes.fromhex(account.sign_transaction(tx)) tx = sign_tx_by_guardian(args, tx) @@ -148,12 +148,12 @@ def _send_transaction_and_wait_for_result(proxy: INetworkProvider, payload: ITra def tx_to_dictionary_as_inner(tx: Transaction) -> Dict[str, Any]: - dictionary = tx.to_dictionary() - dictionary["receiver"] = base64.b64encode(bytes.fromhex(tx.receiver.hex())).decode() # type: ignore - dictionary["sender"] = base64.b64encode(bytes.fromhex(tx.sender.hex())).decode() # type: ignore - dictionary["chainID"] = base64.b64encode(tx.chainID.encode()).decode() + dictionary = tx.__dict__ + dictionary["receiver"] = base64.b64encode(Address.new_from_bech32(tx.receiver).get_public_key()).decode() + dictionary["sender"] = base64.b64encode(Address.new_from_bech32(tx.sender).get_public_key()).decode() + dictionary["chainID"] = base64.b64encode(tx.chain_id.encode()).decode() dictionary["signature"] = base64.b64encode(bytes(bytearray(tx.signature))).decode() - dictionary["value"] = tx.value + dictionary["value"] = tx.amount return dictionary @@ -179,21 +179,21 @@ def load_transaction_from_file(f: TextIO) -> Transaction: loaded_tx = Transaction( chain_id=instance.chainID, - sender=Address.from_bech32(instance.sender), - receiver=Address.from_bech32(instance.receiver), + sender=instance.sender, + receiver=instance.receiver, sender_username=decode_field_value(instance.senderUsername), receiver_username=decode_field_value(instance.receiverUsername), gas_limit=instance.gasLimit, gas_price=instance.gasPrice, - value=int(instance.value), - data=TransactionPayload.from_encoded_str(instance.data), + amount=int(instance.value), + data=TransactionPayload.from_encoded_str(instance.data).data, version=instance.version, options=instance.options, nonce=instance.nonce ) if instance.guardian: - loaded_tx.guardian = Address.from_bech32(instance.guardian) + loaded_tx.guardian = instance.guardian if instance.signature: loaded_tx.signature = bytes.fromhex(instance.signature) diff --git a/multiversx_sdk_cli/utils.py b/multiversx_sdk_cli/utils.py index 89ce3e5c..a4905076 100644 --- a/multiversx_sdk_cli/utils.py +++ b/multiversx_sdk_cli/utils.py @@ -1,3 +1,4 @@ +import base64 import json import logging import os @@ -40,9 +41,12 @@ def to_json(self): class BasicEncoder(json.JSONEncoder): def default(self, o: Any): + if isinstance(o, bytes): + # Encode bytes as a base64 string + return base64.b64encode(o).decode('utf-8') if isinstance(o, ISerializable): return o.to_dictionary() - return json.JSONEncoder.default(self, o) + return super().default(o) def omit_fields(data: Any, fields: List[str] = []): From b75e7279e7b6592d08acdafc5032afef8c8f6721 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Tue, 7 Nov 2023 15:24:05 +0200 Subject: [PATCH 58/62] reference latest network provider package --- multiversx_sdk_cli/cli_output.py | 7 +++---- multiversx_sdk_cli/transactions.py | 2 +- multiversx_sdk_cli/utils.py | 4 ---- requirements.txt | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/multiversx_sdk_cli/cli_output.py b/multiversx_sdk_cli/cli_output.py index 36fb6ffe..e56a3758 100644 --- a/multiversx_sdk_cli/cli_output.py +++ b/multiversx_sdk_cli/cli_output.py @@ -4,6 +4,8 @@ from typing import Any, Dict, List, Optional, Union from multiversx_sdk_core import Address +from multiversx_sdk_network_providers.transactions import \ + transaction_to_dictionary from multiversx_sdk_cli import utils from multiversx_sdk_cli.interfaces import ITransaction @@ -51,15 +53,12 @@ def build(self) -> Dict[str, Any]: output: Dict[str, Any] = OrderedDict() if self.emitted_transaction: - emitted_transaction_dict = self.emitted_transaction.__dict__ + emitted_transaction_dict = transaction_to_dictionary(self.emitted_transaction) emitted_transaction_hash = self.emitted_transaction_hash or "" emitted_transaction_data = self.emitted_transaction.data.decode() utils.omit_fields(emitted_transaction_dict, self.emitted_transaction_omitted_fields) output["emittedTransaction"] = emitted_transaction_dict - signature: bytes = output["emittedTransaction"]["signature"] - output["emittedTransaction"]["signature"] = signature.hex() if type(signature) is not str else signature - output["emittedTransactionData"] = emitted_transaction_data output["emittedTransactionHash"] = emitted_transaction_hash diff --git a/multiversx_sdk_cli/transactions.py b/multiversx_sdk_cli/transactions.py index ba2cceee..58e41622 100644 --- a/multiversx_sdk_cli/transactions.py +++ b/multiversx_sdk_cli/transactions.py @@ -75,7 +75,7 @@ def do_prepare_transaction(args: Any) -> Transaction: sender_username=getattr(args, "sender_username", ""), receiver_username=getattr(args, "receiver_username", ""), gas_price=int(args.gas_price), - data=TransactionPayload.from_str(args.data).data, + data=str(args.data).encode(), nonce=int(args.nonce), amount=int(args.value), version=int(args.version), diff --git a/multiversx_sdk_cli/utils.py b/multiversx_sdk_cli/utils.py index a4905076..4cfbccb9 100644 --- a/multiversx_sdk_cli/utils.py +++ b/multiversx_sdk_cli/utils.py @@ -1,4 +1,3 @@ -import base64 import json import logging import os @@ -41,9 +40,6 @@ def to_json(self): class BasicEncoder(json.JSONEncoder): def default(self, o: Any): - if isinstance(o, bytes): - # Encode bytes as a base64 string - return base64.b64encode(o).decode('utf-8') if isinstance(o, ISerializable): return o.to_dictionary() return super().default(o) diff --git a/requirements.txt b/requirements.txt index 3cd44031..6a92bee2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,5 +10,5 @@ requests-cache rich==13.3.4 multiversx-sdk-core==0.7.1 -multiversx-sdk-network-providers==0.12.0 +multiversx-sdk-network-providers==0.12.1 multiversx-sdk-wallet==0.8.2 From 3c6e850d6c45dcfdb25e8943a0bdb9f4a4b01843 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 8 Nov 2023 11:42:06 +0200 Subject: [PATCH 59/62] fix relayed tx & add unit test --- .../tests/test_cli_transactions.py | 32 +++++++++++++++++++ multiversx_sdk_cli/transactions.py | 30 ++++++++++++++--- 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 multiversx_sdk_cli/tests/test_cli_transactions.py diff --git a/multiversx_sdk_cli/tests/test_cli_transactions.py b/multiversx_sdk_cli/tests/test_cli_transactions.py new file mode 100644 index 00000000..fda91c98 --- /dev/null +++ b/multiversx_sdk_cli/tests/test_cli_transactions.py @@ -0,0 +1,32 @@ +from pathlib import Path +from typing import Any + +from multiversx_sdk_cli.cli import main + +testdata_path = Path(__file__).parent / "testdata" + + +def test_relayed_v1_transaction(capsys: Any): + multi_user_pem = testdata_path / "multiple_addresses.pem" + address_index = 1 + + return_code = main([ + "tx", "new", + "--pem", str(multi_user_pem), + "--pem-index", str(address_index), + "--receiver", "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "--nonce", "198", + "--gas-limit", "60000000", + "--data", "getContractConfig", + "--version", "1", + "--chain", "T", + "--relay" + ]) + assert False if return_code else True + + relayed_tx = _read_stdout(capsys) + assert relayed_tx == "relayedTx@7b226e6f6e6365223a3139382c2273656e646572223a2267456e574f65576d6d413063306a6b71764d354241707a61644b46574e534f69417643575163776d4750673d222c227265636569766572223a22414141414141414141414141415141414141414141414141414141414141414141414141414141432f2f383d222c2276616c7565223a302c226761735072696365223a313030303030303030302c226761734c696d6974223a36303030303030302c2264617461223a225a3256305132397564484a68593352446232356d6157633d222c227369676e6174757265223a2239682b6e6742584f5536776674315464437368534d4b3454446a5a32794f74686336564c576e3478724d5a706248427738677a6c6659596d362b766b505258303764634a562b4745635462616a7049692b5a5a5942773d3d222c22636861696e4944223a2256413d3d222c2276657273696f6e223a317d" + + +def _read_stdout(capsys: Any) -> str: + return capsys.readouterr().out.strip() diff --git a/multiversx_sdk_cli/transactions.py b/multiversx_sdk_cli/transactions.py index 58e41622..5bad4004 100644 --- a/multiversx_sdk_cli/transactions.py +++ b/multiversx_sdk_cli/transactions.py @@ -148,12 +148,34 @@ def _send_transaction_and_wait_for_result(proxy: INetworkProvider, payload: ITra def tx_to_dictionary_as_inner(tx: Transaction) -> Dict[str, Any]: - dictionary = tx.__dict__ - dictionary["receiver"] = base64.b64encode(Address.new_from_bech32(tx.receiver).get_public_key()).decode() + dictionary: Dict[str, Any] = {} + + dictionary["nonce"] = tx.nonce dictionary["sender"] = base64.b64encode(Address.new_from_bech32(tx.sender).get_public_key()).decode() - dictionary["chainID"] = base64.b64encode(tx.chain_id.encode()).decode() - dictionary["signature"] = base64.b64encode(bytes(bytearray(tx.signature))).decode() + dictionary["receiver"] = base64.b64encode(Address.new_from_bech32(tx.receiver).get_public_key()).decode() dictionary["value"] = tx.amount + dictionary["gasPrice"] = tx.gas_price + dictionary["gasLimit"] = tx.gas_limit + dictionary["data"] = base64.b64encode(tx.data).decode() + dictionary["signature"] = base64.b64encode(tx.signature).decode() + dictionary["chainID"] = base64.b64encode(tx.chain_id.encode()).decode() + dictionary["version"] = tx.version + + if tx.options: + dictionary["options"] = tx.options + + if tx.guardian: + guardian = Address.new_from_bech32(tx.guardian).to_hex() + dictionary["guardian"] = base64.b64encode(bytes.fromhex(guardian)).decode() + + if tx.guardian_signature: + dictionary["guardianSignature"] = base64.b64encode(tx.guardian_signature).decode() + + if tx.sender_username: + dictionary["sndUserName"] = base64.b64encode(tx.sender_username.encode()).decode() + + if tx.receiver_username: + dictionary[f"rcvUserName"] = base64.b64encode(tx.receiver_username.encode()).decode() return dictionary From 61177f55928aa5b1987b42e8d8b93f7293d9a62a Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 8 Nov 2023 13:40:56 +0200 Subject: [PATCH 60/62] fix transaction serialization when cosignin with tcs --- multiversx_sdk_cli/cosign_transaction.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/multiversx_sdk_cli/cosign_transaction.py b/multiversx_sdk_cli/cosign_transaction.py index 26aada47..30a3ec79 100644 --- a/multiversx_sdk_cli/cosign_transaction.py +++ b/multiversx_sdk_cli/cosign_transaction.py @@ -1,6 +1,8 @@ from typing import Any, Dict import requests +from multiversx_sdk_network_providers.transactions import \ + transaction_to_dictionary from multiversx_sdk_cli.errors import GuardianServiceError from multiversx_sdk_cli.interfaces import ITransaction @@ -9,7 +11,7 @@ def cosign_transaction(transaction: ITransaction, service_url: str, guardian_code: str) -> ITransaction: payload = { "code": f"{guardian_code}", - "transaction": transaction.__dict__ + "transaction": transaction_to_dictionary(transaction) } url = f"{service_url}/sign-transaction" From 473291e27c488c78088c665add120b09a9fa62a2 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 8 Nov 2023 15:27:02 +0200 Subject: [PATCH 61/62] fixes after review --- multiversx_sdk_cli/dns.py | 6 +++--- multiversx_sdk_cli/transactions.py | 4 ++-- pyproject.toml | 6 +++--- requirements.txt | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/multiversx_sdk_cli/dns.py b/multiversx_sdk_cli/dns.py index 86ffb555..1485532a 100644 --- a/multiversx_sdk_cli/dns.py +++ b/multiversx_sdk_cli/dns.py @@ -7,8 +7,8 @@ from multiversx_sdk_cli.accounts import Account from multiversx_sdk_cli.constants import ADDRESS_ZERO_BECH32, DEFAULT_HRP from multiversx_sdk_cli.contracts import SmartContract -from multiversx_sdk_cli.transactions import (do_prepare_transaction, - tx_to_dictionary_as_inner) +from multiversx_sdk_cli.transactions import ( + do_prepare_transaction, tx_to_dictionary_as_inner_for_relayed_V1) MaxNumShards = 256 ShardIdentiferLen = 2 @@ -50,7 +50,7 @@ def register(args: Any): tx = do_prepare_transaction(args) if hasattr(args, "relay") and args.relay: - args.outfile.write(tx_to_dictionary_as_inner(tx)) + args.outfile.write(tx_to_dictionary_as_inner_for_relayed_V1(tx)) return cli_shared.send_or_simulate(tx, args) diff --git a/multiversx_sdk_cli/transactions.py b/multiversx_sdk_cli/transactions.py index 5bad4004..418a469d 100644 --- a/multiversx_sdk_cli/transactions.py +++ b/multiversx_sdk_cli/transactions.py @@ -147,7 +147,7 @@ def _send_transaction_and_wait_for_result(proxy: INetworkProvider, payload: ITra raise errors.KnownError("Took too long to get transaction.") -def tx_to_dictionary_as_inner(tx: Transaction) -> Dict[str, Any]: +def tx_to_dictionary_as_inner_for_relayed_V1(tx: Transaction) -> Dict[str, Any]: dictionary: Dict[str, Any] = {} dictionary["nonce"] = tx.nonce @@ -186,7 +186,7 @@ def _dict_to_json(dictionary: Dict[str, Any]) -> bytes: def compute_relayed_v1_data(tx: Transaction) -> str: - inner_dictionary = tx_to_dictionary_as_inner(tx) + inner_dictionary = tx_to_dictionary_as_inner_for_relayed_V1(tx) serialized = _dict_to_json(inner_dictionary) serialized_hex = serialized.hex() return f"relayedTx@{serialized_hex}" diff --git a/pyproject.toml b/pyproject.toml index b0e3f36d..979d699f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,9 +27,9 @@ dependencies = [ "semver", "requests-cache", "rich==13.3.4", - "multiversx-sdk-network-providers==0.12.0", - "multiversx-sdk-wallet==0.8.2,", - "multiversx-sdk-core==0.7.1" + "multiversx-sdk-network-providers<0.13.0", + "multiversx-sdk-wallet<0.9.0,", + "multiversx-sdk-core<0.8.0" ] [tool.hatch.build] diff --git a/requirements.txt b/requirements.txt index 6a92bee2..ea54e91b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,6 @@ semver requests-cache rich==13.3.4 -multiversx-sdk-core==0.7.1 -multiversx-sdk-network-providers==0.12.1 -multiversx-sdk-wallet==0.8.2 +multiversx-sdk-core<0.8.0 +multiversx-sdk-network-providers<0.13.0 +multiversx-sdk-wallet<0.9.0 From 8c2e17839e4f20132e6450916853008f4e3f7f1e Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Wed, 22 Nov 2023 10:10:18 +0200 Subject: [PATCH 62/62] bump version and update dependencies --- pyproject.toml | 8 ++++---- requirements.txt | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 979d699f..1b9477cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "multiversx-sdk-cli" -version = "9.0.0b1" +version = "9.0.0" authors = [ { name="MultiversX" }, ] @@ -27,9 +27,9 @@ dependencies = [ "semver", "requests-cache", "rich==13.3.4", - "multiversx-sdk-network-providers<0.13.0", - "multiversx-sdk-wallet<0.9.0,", - "multiversx-sdk-core<0.8.0" + "multiversx-sdk-network-providers>=0.12.0,<0.13.0", + "multiversx-sdk-wallet>=0.8.0,<0.9.0,", + "multiversx-sdk-core>=0.7.0,<0.8.0" ] [tool.hatch.build] diff --git a/requirements.txt b/requirements.txt index ea54e91b..028aa23d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,6 @@ semver requests-cache rich==13.3.4 -multiversx-sdk-core<0.8.0 -multiversx-sdk-network-providers<0.13.0 -multiversx-sdk-wallet<0.9.0 +multiversx-sdk-core>=0.7.0,<0.8.0 +multiversx-sdk-network-providers>=0.12.0,<0.13.0 +multiversx-sdk-wallet>=0.8.0,<0.9.0